fix(agent): pin hermes-agent and hermes-webui to release tags - #68
Conversation
Both install paths tracked moving branches: agent/Dockerfile defaulted to
`main`/`master`, and setup-agent.sh's ensure_clone passed no ref at all, so it
took whatever the default branch HEAD happened to be that day. An upstream
commit could therefore change what the agent image contains, and break it, with
no change on our side — precisely the failure mode the `mcp>=1.0,<2` pin four
lines below exists to prevent, left wide open one layer up.
Pinned to the current release pair:
hermes-agent v2026.8.18 -> e624e9f
hermes-webui v0.52.76 -> 3c9304a
This is a behaviour change, not a no-op: both branches had already moved past
their latest tag (main was 1f234a1, master was 63a562f), so this rolls the
runtime back from branch HEAD to the tagged release.
Both files are changed together on purpose. Pinning only the Dockerfile would
have left host installs on branch HEAD and container installs on a tag, so a
bug would reproduce on one path and not the other — the Dockerfile comment
already claimed the two tracked each other, and that claim was false.
ensure_clone still returns early when a checkout exists, so an install that
predates pinning keeps its current ref; silently deleting a user's agent
directory to change a version is not this script's call. The message now says
so instead of implying the ref was applied.
Verified: both tags clone at the expected SHAs with pyproject.toml and
requirements.txt present; setup-agent.sh passes bash -n.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Re-review findings — this supersedes the "required before merge" box in the PR bodyTwo things surfaced on a second pass. One nearly blocked this PR and turned out fine; the other reverses the merge recommendation. 1. The MCP SDK question — checked, and it's safe
It's safe, but not for the reason the pin assumes. This version added a compatibility shim: def mcp_field(obj, snake: str, camel: str, default=None):
"""Read an MCP model field across the 1.x -> 2.x field rename.
mcp 2.0 renamed every model field to snake_case and kept the camelCase
spelling only as a *serialization* alias — pydantic aliases do not apply
to attribute access, so ``getattr(result, "isError", False)`` returns the
default on 2.x rather than raising. That turns a rename into silent wrong
behaviour: failed tool calls read as successful..."""Hermes reads both spellings now, so either SDK generation works. Worth noting the consequence: 2. Upstream moves 167 commits/day — which makes this pin more urgent, not riskierI originally flagged the rollback (branch HEAD → tag) as a risk needing a smoke test before merge. That had the dependency backwards, and this measurement is why:
Revised recommendation: merge this (after #67, so the retry protects these clones too), then run the agent smoke test against the now-reproducible image — where a failure is debuggable and a pass is meaningful. Follow-ups, not blockers
Also verified clean
|
Follow-up to #67, which fixed the transient half of the agent build's fragility. This fixes the silent half.
Problem
Both install paths tracked moving branches:
agent/DockerfileAGENT_RUNTIME_REF=main,AGENT_API_REF=masterscripts/self-host/setup-agent.shgit clone --depth 1 "$repo"— no ref at allAn upstream commit can therefore change what the agent image contains, and break it, with no change on our side. That is precisely the failure mode the
mcp>=1.0,<2pin four lines below in the same file exists to prevent — left wide open one layer up.CLAUDE.mdalready states the rule ("PINNED for reproducibility ... Bump deliberately and re-validate"); this repo just wasn't following it.Change
Pinned to the current release pair:
This is a behaviour change, not a no-op. Both branches had already moved past their latest tag —
mainwas at1f234a1,masterat63a562f— so this rolls the runtime back from branch HEAD to the tagged release. Reviewers should weigh that deliberately rather than read "pinning" as cosmetic.Both files change together on purpose. Pinning only the Dockerfile would leave host installs on branch HEAD and container installs on a tag, so a bug would reproduce on one path and not the other. The Dockerfile comment already asserted the two tracked each other — that assertion was false, and this makes it true.
ensure_clonestill returns early when a checkout already exists, so an install predating this keeps its current ref. Silently deleting a user's agent directory to change a version isn't this script's call — but the message now says the ref was left alone instead of implying it was applied.Verification
pyproject.tomlandrequirements.txtpresentsetup-agent.shpassesbash -ndocker compose buildgreen — proves the pinned refs buildThat last box is the important one. Per
CLAUDE.md's own anti-patterns, "a dashboard that is HTML and long proves nothing" and presence ≠ compatibility: a greendocker compose buildproves these refs compile and install, not that the agent answers. Since this moves the runtime to a different commit than what's been running, someone should confirm the Agent tab returns a real answer (not "I'm blocked") against a pinned image before this lands. I can't run that from here.Ordering note
Independent of #67 — different lines of
agent/Dockerfile, no conflict expected — but #67 should land first so the retry protects these clones too.🤖 Generated with Claude Code