Skip to content

fix(hermes): unwrap known routers; fail closed on unknown models - #1039

Merged
iamtoruk merged 12 commits into
getagentseal:mainfrom
avs-io:fix/hermes-glm53-pr-links
Aug 19, 2026
Merged

iamtoruk merged 12 commits into
getagentseal:mainfrom
avs-io:fix/hermes-glm53-pr-links

Conversation

@avs-io

@avs-io avs-io commented Aug 19, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Hermes sessions were wrong in three classes, not three ids:

  1. Routed model ids. Token-plan / OmniRoute / Cline wrap the same model as cp/cline-pass/…, omniroute:cp/…, cmd/…. A missing LiteLLM row then showed $0 and "unpriced."
  2. App vs folder. The root Hermes profile became project default. $HOME is not a project.
  3. PR spend. Only Claude pr-link journal events created Pull request rows. A first scrape of every tool dump then smeared one session across dozens of URLs.

Change

  • Peel allowlisted routing prefixes (omniroute:, cp/, cline-pass/, cline-free/, cmd/, antigravity/, xiaomi/) and price the remaining id. Explicit glm-5.3 / GLM-5.3 alias only. Unknown glm-5.4 and unknown provider/org/model stay unpriced.
  • Project from git root or a real cwd, never $HOME or a profile name. Last-resort project is hermes. source=acp stays Hermes — ACP is a transport; this DB has no Buzz client field.
  • Capture https://github.com/org/repo/pull/N from user and assistant text only, including punctuation-wrapped URLs. Ignore tool dumps. Hermes parse version bumped so old cache rows reparse.

User impact

Cline Pass / OmniRoute spellings of a known model get a ~ estimate instead of $0. Future GLM minors and unknown namespaces stay unpriced instead of inheriting 5.2. Hermes Desktop/CLI/ACP spend groups as Hermes. Pull requests can show Hermes work that actually named a PR.

Subscription usage is still an estimate, not an invoice. Models with no LiteLLM row and no explicit alias (kimi-k3, mimo-v2.5-pro) stay unpriced.

Preservation and out of scope

Testing

  • npx vitest run tests/models.test.ts tests/providers/hermes.test.ts: 173 passed.
  • Independent Extra High (gpt-5.6-sol / xhigh) review held the previous class commit; this commit addresses the HOLD items it named.

Residual

PR links in assistant-quoted tool dumps can still false-positive. Relative pull/N is not captured. Cache retraction is "reparse after version bump," not a durable-source rewrite.

avs-io added 4 commits August 19, 2026 18:06
GLM-5.3 is missing from LiteLLM, so Hermes/Cline sessions priced at $0.
Alias it to the glm-5p2 sibling and keep the display name GLM-5.3.

The root Hermes profile was shown as project "default". Use "hermes"
for that profile only; named profiles and cwd inference are unchanged.

Scan Hermes transcripts for https GitHub pull URLs and attach them so
the Pull requests page can attribute those sessions.
Hermes stores Cline Pass as cp/cline-pass/glm-5.3. One prefix strip
leaves cline-pass/glm-5.3, which missed the bare glm-5.3 alias and
stayed $0. Price the last path segment through the same aliases.
Tool dumps (gh pr list, changelog grep) were smearing one session
across dozens of pull URLs. Capture links from user and assistant
text only.
Price any OmniRoute/Cline/cmd/antigravity wrapper by peeling prefixes
and, for GLM 5.x, falling back to the newest priced sibling. Do not
require a new alias per model id.

Classify Hermes sessions by surface and workspace: ACP is the Buzz
app; project comes from git root or a real cwd, never $HOME or a
profile name.
@avs-io avs-io changed the title fix(hermes): price glm-5.3, label default as hermes, capture PR links fix(hermes): unwrap routed model ids and classify ACP as Buzz Aug 19, 2026
Extra High review held #1039. Stop pricing every future glm-5.x as 5.2,
stop collapsing unknown provider/org/model trees onto a priced leaf, and
stop calling ACP Buzz — source=acp is a transport and the DB has no
client field. Strip trailing punctuation on PR URLs and bump the Hermes
parse version so old cache rows reparse.
@avs-io avs-io changed the title fix(hermes): unwrap routed model ids and classify ACP as Buzz fix(hermes): unwrap known routers; fail closed on unknown models Aug 19, 2026
avs-io and others added 6 commits August 19, 2026 20:19
Extra High held #1039 again. An unknown provider/model still became a
bare-model price via getCanonicalName's first-segment strip. Relative
cwd values like '.' could inherit the invoking repo. PR scrape treated
fenced dumps and other repos as attribution.

Peel only known vendor/router namespaces. Require an absolute
platform path before a Hermes cwd is a workspace. Ignore fenced URLs
and, when a git root exists, keep only that repo's pull links.
Bump the Hermes parse version so old cache rows reparse.
Extra High held 91754c5. z-ai/glm-5.2 went unpriced (Cline's real
vendor spelling). Forward-slash UNC became a workspace on POSIX.
PR matching used basename, so evil/codeburn collided. Tilde fences
were still scanned.

Add z-ai to known namespaces. Reject // UNC on POSIX. Attribute
PRs only when origin yields owner/repo. Strip ``` and ~~~ fences.
Bump Hermes parse version to v4.
…atalog

The hand-written KNOWN_NAMESPACES set dropped pricing for vendor prefixes
LiteLLM itself indexes: x-ai/, nousresearch/, zhipu/, litellm_proxy/ and
openai_like/ all priced on main and went unpriced here. Derive the set from
the loaded pricing keys instead, so a vendor the catalog knows is never lost
to a stale list, and keep only the spellings no catalog carries as explicit
extras: the routing wrappers, the client-side kimi/ and mimo/ prefixes, and
the litellm_proxy/ + openai_like/ routes. Local runners are excluded on
purpose, so an unlisted ollama tag cannot strip down to a priced cloud row.

xiaomi/ stops being a routing wrapper: it is the namespace LiteLLM prices
MiMo under, and BUILTIN_ALIASES maps the bare MiMo ids INTO it, so peeling
pulled against the alias. It stays known via the derived set.

Also: a user price override for a bare id now wins over the catalog row a
routed spelling of it would otherwise hit, and a namespaced GLM-5.3 is no
longer LABELLED GLM-5.2 by the sibling alias it prices through.

Tests assert the allowlist through a price override on a synthetic id, so
they cannot rot with the snapshot; the glm-5.4 assertion that pinned on the
snapshot NOT carrying a model is dropped.
githubOwnerRepoFromRoot re-read .git/config once per session, so every
session in the same repo paid for the same two syscalls. Memoize it per repo
root for the life of the process.

The prLinks plumbing from a provider call through the session cache into the
session summary had no test above the provider boundary; add one that runs
the real parseAllSessions pipeline against a temp HERMES_HOME. It fails
against the pre-change parser.
@iamtoruk
iamtoruk merged commit 7862aab into getagentseal:main Aug 19, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants