mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-24 05:41:40 +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
|
|
@ -382,7 +382,28 @@ _AI_GATEWAY_HEADERS = {
|
||||||
# Nous Portal extra_body for product attribution.
|
# Nous Portal extra_body for product attribution.
|
||||||
# Callers should pass this as extra_body in chat.completions.create()
|
# Callers should pass this as extra_body in chat.completions.create()
|
||||||
# when the auxiliary client is backed by Nous Portal.
|
# when the auxiliary client is backed by Nous Portal.
|
||||||
NOUS_EXTRA_BODY = {"tags": ["product=hermes-agent", "client=aux"]}
|
#
|
||||||
|
# The tags are computed from agent.portal_tags so the client= marker stays
|
||||||
|
# in lockstep with hermes_cli.__version__ across every Portal call site
|
||||||
|
# (main loop, aux, compression, web_extract). Do not inline a literal here;
|
||||||
|
# see agent/portal_tags.py for the rationale.
|
||||||
|
from agent.portal_tags import nous_portal_tags as _nous_portal_tags
|
||||||
|
|
||||||
|
|
||||||
|
def _nous_extra_body() -> dict:
|
||||||
|
"""Return a fresh Nous Portal ``extra_body`` dict.
|
||||||
|
|
||||||
|
Computed at call time so a hot-reloaded ``hermes_cli.__version__`` is
|
||||||
|
reflected without restarting long-running processes.
|
||||||
|
"""
|
||||||
|
return {"tags": _nous_portal_tags()}
|
||||||
|
|
||||||
|
|
||||||
|
# Backwards-compatible module attribute. Some callers (tests, third-party
|
||||||
|
# plugins) read ``NOUS_EXTRA_BODY`` directly; keep it as a snapshot of the
|
||||||
|
# current tags. Callers that need the freshest value should call
|
||||||
|
# ``_nous_extra_body()`` or import ``nous_portal_tags`` directly.
|
||||||
|
NOUS_EXTRA_BODY = _nous_extra_body()
|
||||||
|
|
||||||
# Set at resolve time — True if the auxiliary client points to Nous Portal
|
# Set at resolve time — True if the auxiliary client points to Nous Portal
|
||||||
auxiliary_is_nous: bool = False
|
auxiliary_is_nous: bool = False
|
||||||
|
|
@ -3437,7 +3458,7 @@ def get_auxiliary_extra_body() -> dict:
|
||||||
Includes Nous Portal product tags when the auxiliary client is backed
|
Includes Nous Portal product tags when the auxiliary client is backed
|
||||||
by Nous Portal. Returns empty dict otherwise.
|
by Nous Portal. Returns empty dict otherwise.
|
||||||
"""
|
"""
|
||||||
return dict(NOUS_EXTRA_BODY) if auxiliary_is_nous else {}
|
return _nous_extra_body() if auxiliary_is_nous else {}
|
||||||
|
|
||||||
|
|
||||||
def auxiliary_max_tokens_param(value: int) -> dict:
|
def auxiliary_max_tokens_param(value: int) -> dict:
|
||||||
|
|
@ -4026,7 +4047,7 @@ def _build_call_kwargs(
|
||||||
# Provider-specific extra_body
|
# Provider-specific extra_body
|
||||||
merged_extra = dict(extra_body or {})
|
merged_extra = dict(extra_body or {})
|
||||||
if provider == "nous" or auxiliary_is_nous:
|
if provider == "nous" or auxiliary_is_nous:
|
||||||
merged_extra.setdefault("tags", []).extend(NOUS_EXTRA_BODY["tags"])
|
merged_extra.setdefault("tags", []).extend(_nous_portal_tags())
|
||||||
if merged_extra:
|
if merged_extra:
|
||||||
kwargs["extra_body"] = merged_extra
|
kwargs["extra_body"] = merged_extra
|
||||||
|
|
||||||
|
|
|
||||||
64
agent/portal_tags.py
Normal file
64
agent/portal_tags.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
"""Centralized Nous Portal request tags.
|
||||||
|
|
||||||
|
Every Hermes request that hits the Nous Portal — main agent loop, auxiliary
|
||||||
|
client (compression / titles / vision / web_extract / session_search / etc.),
|
||||||
|
and any future code path — must carry the same product-attribution tags so
|
||||||
|
Nous can attribute usage to Hermes Agent and bucket it by client release.
|
||||||
|
|
||||||
|
Tag shape (sent in OpenAI-compatible ``extra_body['tags']``):
|
||||||
|
|
||||||
|
[
|
||||||
|
"product=hermes-agent",
|
||||||
|
"client=hermes-client-v<__version__>",
|
||||||
|
]
|
||||||
|
|
||||||
|
The version is sourced live from ``hermes_cli.__version__`` so it auto-aligns
|
||||||
|
to whatever release is installed; the release script
|
||||||
|
(``scripts/release.py``) regex-bumps that single string, and every Portal
|
||||||
|
request picks up the new tag on the next process start.
|
||||||
|
|
||||||
|
Why one helper instead of inlining the literal at each site:
|
||||||
|
* Four call sites (main loop profile, aux client, run_agent compression
|
||||||
|
fallback, web_tools fallback) used to drift apart — see PR #24194 which
|
||||||
|
only got the aux site, leaving the main loop sending a different tag set.
|
||||||
|
* Tests should assert the same tag list everywhere; centralizing makes that
|
||||||
|
assertion a one-liner against this module.
|
||||||
|
|
||||||
|
Do NOT pre-compute these as module-level constants in the consumers. The
|
||||||
|
version can change at runtime (editable installs, hot-reload tooling), and
|
||||||
|
``hermes_cli.__version__`` is the canonical source of truth.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
def _hermes_version() -> str:
|
||||||
|
"""Return the current Hermes release version, e.g. ``"0.13.0"``.
|
||||||
|
|
||||||
|
Falls back to ``"unknown"`` if ``hermes_cli`` cannot be imported (should
|
||||||
|
never happen in a real install — guarded for defensive testing).
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from hermes_cli import __version__
|
||||||
|
return __version__
|
||||||
|
except Exception:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
|
||||||
|
def hermes_client_tag() -> str:
|
||||||
|
"""Return the ``client=...`` tag for Nous Portal requests.
|
||||||
|
|
||||||
|
Format: ``client=hermes-client-v<MAJOR>.<MINOR>.<PATCH>``.
|
||||||
|
"""
|
||||||
|
return f"client=hermes-client-v{_hermes_version()}"
|
||||||
|
|
||||||
|
|
||||||
|
def nous_portal_tags() -> List[str]:
|
||||||
|
"""Return the canonical list of Nous Portal product tags.
|
||||||
|
|
||||||
|
Always returns a fresh list so callers can mutate it freely
|
||||||
|
(e.g. ``merged_extra.setdefault("tags", []).extend(nous_portal_tags())``).
|
||||||
|
"""
|
||||||
|
return ["product=hermes-agent", hermes_client_tag()]
|
||||||
|
|
@ -307,7 +307,7 @@ def judge_goal(
|
||||||
return "continue", "empty response (nothing to evaluate)", False
|
return "continue", "empty response (nothing to evaluate)", False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from agent.auxiliary_client import get_text_auxiliary_client
|
from agent.auxiliary_client import get_auxiliary_extra_body, get_text_auxiliary_client
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.debug("goal judge: auxiliary client import failed: %s", exc)
|
logger.debug("goal judge: auxiliary client import failed: %s", exc)
|
||||||
return "continue", "auxiliary client unavailable", False
|
return "continue", "auxiliary client unavailable", False
|
||||||
|
|
@ -336,6 +336,7 @@ def judge_goal(
|
||||||
temperature=0,
|
temperature=0,
|
||||||
max_tokens=200,
|
max_tokens=200,
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
|
extra_body=get_auxiliary_extra_body() or None,
|
||||||
)
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.info("goal judge: API call failed (%s) — falling through to continue", exc)
|
logger.info("goal judge: API call failed (%s) — falling through to continue", exc)
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ def specify_task(
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from agent.auxiliary_client import get_text_auxiliary_client
|
from agent.auxiliary_client import get_auxiliary_extra_body, get_text_auxiliary_client
|
||||||
except Exception as exc: # pragma: no cover — import smoke test
|
except Exception as exc: # pragma: no cover — import smoke test
|
||||||
logger.debug("specify: auxiliary client import failed: %s", exc)
|
logger.debug("specify: auxiliary client import failed: %s", exc)
|
||||||
return SpecifyOutcome(task_id, False, "auxiliary client unavailable")
|
return SpecifyOutcome(task_id, False, "auxiliary client unavailable")
|
||||||
|
|
@ -187,6 +187,7 @@ def specify_task(
|
||||||
temperature=0.3,
|
temperature=0.3,
|
||||||
max_tokens=1500,
|
max_tokens=1500,
|
||||||
timeout=timeout or 120,
|
timeout=timeout or 120,
|
||||||
|
extra_body=get_auxiliary_extra_body() or None,
|
||||||
)
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from agent.portal_tags import nous_portal_tags
|
||||||
from providers import register_provider
|
from providers import register_provider
|
||||||
from providers.base import ProviderProfile
|
from providers.base import ProviderProfile
|
||||||
|
|
||||||
|
|
@ -12,7 +13,7 @@ class NousProfile(ProviderProfile):
|
||||||
def build_extra_body(
|
def build_extra_body(
|
||||||
self, *, session_id: str | None = None, **context
|
self, *, session_id: str | None = None, **context
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
return {"tags": ["product=hermes-agent"]}
|
return {"tags": nous_portal_tags()}
|
||||||
|
|
||||||
def build_api_kwargs_extras(
|
def build_api_kwargs_extras(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
|
|
@ -11542,7 +11542,8 @@ class AIAgent:
|
||||||
"effort": "medium"
|
"effort": "medium"
|
||||||
}
|
}
|
||||||
if _is_nous:
|
if _is_nous:
|
||||||
summary_extra_body["tags"] = ["product=hermes-agent"]
|
from agent.portal_tags import nous_portal_tags as _portal_tags
|
||||||
|
summary_extra_body["tags"] = _portal_tags()
|
||||||
|
|
||||||
if self.api_mode == "codex_responses":
|
if self.api_mode == "codex_responses":
|
||||||
codex_kwargs = self._build_api_kwargs(api_messages)
|
codex_kwargs = self._build_api_kwargs(api_messages)
|
||||||
|
|
|
||||||
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):
|
def test_nous_tags(self, transport):
|
||||||
|
from agent.portal_tags import nous_portal_tags
|
||||||
from providers import get_provider_profile
|
from providers import get_provider_profile
|
||||||
profile = get_provider_profile("nous")
|
profile = get_provider_profile("nous")
|
||||||
msgs = [{"role": "user", "content": "Hi"}]
|
msgs = [{"role": "user", "content": "Hi"}]
|
||||||
kw = transport.build_kwargs(model="gpt-4o", messages=msgs, provider_profile=profile)
|
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):
|
def test_reasoning_default(self, transport):
|
||||||
msgs = [{"role": "user", "content": "Hi"}]
|
msgs = [{"role": "user", "content": "Hi"}]
|
||||||
|
|
|
||||||
|
|
@ -273,12 +273,13 @@ class TestRequestOverridesParity:
|
||||||
|
|
||||||
def test_extra_body_override_merges_with_provider_body(self, transport):
|
def test_extra_body_override_merges_with_provider_body(self, transport):
|
||||||
"""Override extra_body merges WITH provider extra_body, not replaces."""
|
"""Override extra_body merges WITH provider extra_body, not replaces."""
|
||||||
|
from agent.portal_tags import nous_portal_tags
|
||||||
kw = transport.build_kwargs(
|
kw = transport.build_kwargs(
|
||||||
model="hermes-3", messages=_msgs(), tools=None,
|
model="hermes-3", messages=_msgs(), tools=None,
|
||||||
provider_profile=get_provider_profile("nous"),
|
provider_profile=get_provider_profile("nous"),
|
||||||
request_overrides={"extra_body": {"custom": True}},
|
request_overrides={"extra_body": {"custom": True}},
|
||||||
)
|
)
|
||||||
assert kw["extra_body"]["tags"] == ["product=hermes-agent"] # from profile
|
assert kw["extra_body"]["tags"] == nous_portal_tags() # from profile
|
||||||
assert kw["extra_body"]["custom"] is True # from override
|
assert kw["extra_body"]["custom"] is True # from override
|
||||||
|
|
||||||
def test_top_level_override(self, transport):
|
def test_top_level_override(self, transport):
|
||||||
|
|
|
||||||
|
|
@ -210,9 +210,10 @@ class TestOpenRouterProfile:
|
||||||
|
|
||||||
class TestNousProfile:
|
class TestNousProfile:
|
||||||
def test_tags(self):
|
def test_tags(self):
|
||||||
|
from agent.portal_tags import nous_portal_tags
|
||||||
p = get_provider_profile("nous")
|
p = get_provider_profile("nous")
|
||||||
body = p.build_extra_body()
|
body = p.build_extra_body()
|
||||||
assert body["tags"] == ["product=hermes-agent"]
|
assert body["tags"] == nous_portal_tags()
|
||||||
|
|
||||||
def test_auth_type(self):
|
def test_auth_type(self):
|
||||||
p = get_provider_profile("nous")
|
p = get_provider_profile("nous")
|
||||||
|
|
|
||||||
|
|
@ -165,13 +165,14 @@ class TestNousParity:
|
||||||
"""Nous: product tags, reasoning, omit when disabled."""
|
"""Nous: product tags, reasoning, omit when disabled."""
|
||||||
|
|
||||||
def test_tags(self, transport):
|
def test_tags(self, transport):
|
||||||
|
from agent.portal_tags import nous_portal_tags
|
||||||
kw = transport.build_kwargs(
|
kw = transport.build_kwargs(
|
||||||
model="hermes-3-llama-3.1-405b",
|
model="hermes-3-llama-3.1-405b",
|
||||||
messages=_simple_messages(),
|
messages=_simple_messages(),
|
||||||
tools=None,
|
tools=None,
|
||||||
provider_profile=get_provider_profile("nous"),
|
provider_profile=get_provider_profile("nous"),
|
||||||
)
|
)
|
||||||
assert kw["extra_body"]["tags"] == ["product=hermes-agent"]
|
assert kw["extra_body"]["tags"] == nous_portal_tags()
|
||||||
|
|
||||||
def test_reasoning_omitted_when_disabled(self, transport):
|
def test_reasoning_omitted_when_disabled(self, transport):
|
||||||
"""Nous special case: reasoning omitted entirely when disabled."""
|
"""Nous special case: reasoning omitted entirely when disabled."""
|
||||||
|
|
|
||||||
|
|
@ -343,11 +343,12 @@ class TestBuildApiKwargsAIGateway:
|
||||||
|
|
||||||
class TestBuildApiKwargsNousPortal:
|
class TestBuildApiKwargsNousPortal:
|
||||||
def test_includes_nous_product_tags(self, monkeypatch):
|
def test_includes_nous_product_tags(self, monkeypatch):
|
||||||
|
from agent.portal_tags import nous_portal_tags
|
||||||
agent = _make_agent(monkeypatch, "nous", base_url="https://inference-api.nousresearch.com/v1")
|
agent = _make_agent(monkeypatch, "nous", base_url="https://inference-api.nousresearch.com/v1")
|
||||||
messages = [{"role": "user", "content": "hi"}]
|
messages = [{"role": "user", "content": "hi"}]
|
||||||
kwargs = agent._build_api_kwargs(messages)
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
extra = kwargs.get("extra_body", {})
|
extra = kwargs.get("extra_body", {})
|
||||||
assert extra.get("tags") == ["product=hermes-agent"]
|
assert extra.get("tags") == nous_portal_tags()
|
||||||
|
|
||||||
def test_uses_chat_completions_format(self, monkeypatch):
|
def test_uses_chat_completions_format(self, monkeypatch):
|
||||||
agent = _make_agent(monkeypatch, "nous", base_url="https://inference-api.nousresearch.com/v1")
|
agent = _make_agent(monkeypatch, "nous", base_url="https://inference-api.nousresearch.com/v1")
|
||||||
|
|
|
||||||
|
|
@ -593,7 +593,8 @@ def _resolve_web_extract_auxiliary(model: Optional[str] = None) -> tuple[Optiona
|
||||||
extra_body: Dict[str, Any] = {}
|
extra_body: Dict[str, Any] = {}
|
||||||
if client is not None and _is_nous_auxiliary_client(client):
|
if client is not None and _is_nous_auxiliary_client(client):
|
||||||
from agent.auxiliary_client import get_auxiliary_extra_body
|
from agent.auxiliary_client import get_auxiliary_extra_body
|
||||||
extra_body = get_auxiliary_extra_body() or {"tags": ["product=hermes-agent"]}
|
from agent.portal_tags import nous_portal_tags
|
||||||
|
extra_body = get_auxiliary_extra_body() or {"tags": nous_portal_tags()}
|
||||||
|
|
||||||
return client, effective_model, extra_body
|
return client, effective_model, extra_body
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue