mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
feat(nous): unified client=hermes-client-v<version> tag on every Portal request (#24779)
Some checks failed
Deploy Site / deploy-vercel (push) Waiting to run
Deploy Site / deploy-docs (push) Waiting to run
Docker Build and Publish / build-amd64 (push) Waiting to run
Docker Build and Publish / build-arm64 (push) Waiting to run
Docker Build and Publish / merge (push) Blocked by required conditions
Docker Build and Publish / move-latest (push) Blocked by required conditions
Lint (ruff + ty) / ruff + ty diff (push) Waiting to run
Lint (ruff + ty) / ruff enforcement (blocking) (push) Waiting to run
Lint (ruff + ty) / Windows footguns (blocking) (push) Waiting to run
Nix / nix (macos-latest) (push) Waiting to run
Nix / nix (ubuntu-latest) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / e2e (push) Waiting to run
OSV-Scanner / Scan lockfiles (push) Has been cancelled
uv.lock check / uv lock --check (push) Has been cancelled
Some checks failed
Deploy Site / deploy-vercel (push) Waiting to run
Deploy Site / deploy-docs (push) Waiting to run
Docker Build and Publish / build-amd64 (push) Waiting to run
Docker Build and Publish / build-arm64 (push) Waiting to run
Docker Build and Publish / merge (push) Blocked by required conditions
Docker Build and Publish / move-latest (push) Blocked by required conditions
Lint (ruff + ty) / ruff + ty diff (push) Waiting to run
Lint (ruff + ty) / ruff enforcement (blocking) (push) Waiting to run
Lint (ruff + ty) / Windows footguns (blocking) (push) Waiting to run
Nix / nix (macos-latest) (push) Waiting to run
Nix / nix (ubuntu-latest) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / e2e (push) Waiting to run
OSV-Scanner / Scan lockfiles (push) Has been cancelled
uv.lock check / uv lock --check (push) Has been cancelled
* feat(nous): unified client=hermes-client-v<version> tag on every Portal request Every Hermes request to Nous Portal now carries the same client=hermes-client-v<__version__> tag (e.g. client=hermes-client-v0.13.0 on this release), sourced live from hermes_cli.__version__. The release script's regex bump auto-aligns it on every release. Centralized in agent/portal_tags.py and wired into all four call sites: - NousProfile.build_extra_body (main agent loop, every chat completion) - auxiliary_client.NOUS_EXTRA_BODY + _build_call_kwargs (aux client) - run_agent.py compression-summary fallback path - tools/web_tools.py web_extract fallback Replaces the client=aux marker added in #24194 with the unified version tag. Tests assert against the helper output (invariant) rather than the literal string, so they don't need updating on every release. * feat(nous): cover /goal judge and kanban specify aux paths Two aux-using surfaces bypassed call_llm by invoking client.chat.completions.create() directly without extra_body, so they were missing the unified Portal client tag: - hermes_cli/goals.py — /goal standing-goal judge - hermes_cli/kanban_specify.py — kanban triage specifier Both now pass extra_body=get_auxiliary_extra_body() or None so they inherit the version tag when the aux client points at Nous Portal, and emit nothing otherwise (no tag leak to OpenRouter/Anthropic auxes).
This commit is contained in:
parent
b06e999302
commit
486b692ddd
13 changed files with 169 additions and 13 deletions
61
tests/agent/test_portal_tags.py
Normal file
61
tests/agent/test_portal_tags.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
"""Tests for agent.portal_tags — Nous Portal request tag contract."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def test_hermes_client_tag_includes_current_version():
|
||||
"""The client tag must reflect hermes_cli.__version__ verbatim."""
|
||||
from hermes_cli import __version__
|
||||
from agent.portal_tags import hermes_client_tag
|
||||
|
||||
assert hermes_client_tag() == f"client=hermes-client-v{__version__}"
|
||||
|
||||
|
||||
def test_hermes_client_tag_format():
|
||||
"""The client tag has the exact shape Nous Portal expects."""
|
||||
from agent.portal_tags import hermes_client_tag
|
||||
|
||||
tag = hermes_client_tag()
|
||||
assert tag.startswith("client=hermes-client-v")
|
||||
# No spaces, no commas — single tag value
|
||||
assert " " not in tag
|
||||
assert "," not in tag
|
||||
|
||||
|
||||
def test_nous_portal_tags_contains_product_and_client():
|
||||
"""Every Nous Portal request gets BOTH the product tag and the version tag."""
|
||||
from agent.portal_tags import hermes_client_tag, nous_portal_tags
|
||||
|
||||
tags = nous_portal_tags()
|
||||
assert "product=hermes-agent" in tags
|
||||
assert hermes_client_tag() in tags
|
||||
assert len(tags) == 2
|
||||
|
||||
|
||||
def test_nous_portal_tags_returns_fresh_list():
|
||||
"""Callers mutate the returned list; we must not share state across calls."""
|
||||
from agent.portal_tags import nous_portal_tags
|
||||
|
||||
a = nous_portal_tags()
|
||||
a.append("client=test-mutation")
|
||||
b = nous_portal_tags()
|
||||
assert "client=test-mutation" not in b
|
||||
|
||||
|
||||
def test_auxiliary_client_nous_extra_body_uses_helper():
|
||||
"""auxiliary_client.NOUS_EXTRA_BODY must match the canonical helper output."""
|
||||
from agent.auxiliary_client import NOUS_EXTRA_BODY
|
||||
from agent.portal_tags import nous_portal_tags
|
||||
|
||||
assert NOUS_EXTRA_BODY == {"tags": nous_portal_tags()}
|
||||
|
||||
|
||||
def test_nous_provider_profile_uses_helper():
|
||||
"""The Nous provider profile (main agent loop) must use the canonical tags."""
|
||||
from agent.portal_tags import nous_portal_tags
|
||||
from providers import get_provider_profile
|
||||
|
||||
profile = get_provider_profile("nous")
|
||||
assert profile is not None
|
||||
body = profile.build_extra_body()
|
||||
assert body["tags"] == nous_portal_tags()
|
||||
|
|
@ -147,11 +147,12 @@ class TestChatCompletionsBuildKwargs:
|
|||
]
|
||||
|
||||
def test_nous_tags(self, transport):
|
||||
from agent.portal_tags import nous_portal_tags
|
||||
from providers import get_provider_profile
|
||||
profile = get_provider_profile("nous")
|
||||
msgs = [{"role": "user", "content": "Hi"}]
|
||||
kw = transport.build_kwargs(model="gpt-4o", messages=msgs, provider_profile=profile)
|
||||
assert kw["extra_body"]["tags"] == ["product=hermes-agent"]
|
||||
assert kw["extra_body"]["tags"] == nous_portal_tags()
|
||||
|
||||
def test_reasoning_default(self, transport):
|
||||
msgs = [{"role": "user", "content": "Hi"}]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue