From 6430d67569f553a2a45241d98cee5794944565a7 Mon Sep 17 00:00:00 2001 From: Jonathan Troyer Date: Tue, 5 May 2026 08:40:27 -0700 Subject: [PATCH] fix(openrouter): use canonical X-Title attribution header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OpenRouter's dashboard attributes usage via the `X-Title` header. Hermes was sending `X-OpenRouter-Title`, which OpenRouter does not recognize, so Hermes usage showed up unlabeled. Rename to `X-Title` to match the canonical header (already used elsewhere in the same file via _AI_GATEWAY_HEADERS). Salvages the core fix from @JTroyerOvermatch's PR #13649. Dropped the PR's `HERMES_OPENROUTER_TITLE` / `HERMES_OPENROUTER_REFERER` env-var override plumbing per the '.env is for secrets only' policy — if per-deployment attribution is needed later it should go under `openrouter.title` / `openrouter.referer` in config.yaml instead. --- agent/auxiliary_client.py | 6 ++++-- tests/agent/test_openrouter_response_cache.py | 2 +- tests/run_agent/test_provider_attribution_headers.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index 3017e7703d..50f6f31fa5 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -259,10 +259,12 @@ _PROVIDERS_WITHOUT_VISION: frozenset = frozenset({ "kimi-coding-cn", }) -# OpenRouter app attribution headers (base — always sent) +# OpenRouter app attribution headers (base — always sent). +# `X-Title` is the canonical attribution header OpenRouter's dashboard +# reads; the previous `X-OpenRouter-Title` label was not recognized there. _OR_HEADERS_BASE = { "HTTP-Referer": "https://hermes-agent.nousresearch.com", - "X-OpenRouter-Title": "Hermes Agent", + "X-Title": "Hermes Agent", "X-OpenRouter-Categories": "productivity,cli-agent", } diff --git a/tests/agent/test_openrouter_response_cache.py b/tests/agent/test_openrouter_response_cache.py index 612ec34469..4bbbcc964d 100644 --- a/tests/agent/test_openrouter_response_cache.py +++ b/tests/agent/test_openrouter_response_cache.py @@ -19,7 +19,7 @@ class TestBuildOrHeaders: headers = build_or_headers(or_config={"response_cache": False}) assert headers["HTTP-Referer"] == "https://hermes-agent.nousresearch.com" - assert headers["X-OpenRouter-Title"] == "Hermes Agent" + assert headers["X-Title"] == "Hermes Agent" assert headers["X-OpenRouter-Categories"] == "productivity,cli-agent" def test_cache_enabled(self): diff --git a/tests/run_agent/test_provider_attribution_headers.py b/tests/run_agent/test_provider_attribution_headers.py index 2ce440741f..673a906cfb 100644 --- a/tests/run_agent/test_provider_attribution_headers.py +++ b/tests/run_agent/test_provider_attribution_headers.py @@ -24,7 +24,7 @@ def test_openrouter_base_url_applies_or_headers(mock_openai): headers = agent._client_kwargs["default_headers"] assert headers["HTTP-Referer"] == "https://hermes-agent.nousresearch.com" - assert headers["X-OpenRouter-Title"] == "Hermes Agent" + assert headers["X-Title"] == "Hermes Agent" @patch("run_agent.OpenAI")