mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-23 05:31:23 +00:00
fix: always send tenant headers in OpenViking _headers() when account/user are set
OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User headers for ROOT API key requests to tenant-scoped APIs. Previously the `!="default"` guard skipped these headers when account/user were the literal string "default", causing INVALID_ARGUMENT errors. Remove the `!="default"` guard so headers are sent whenever account/user are truthy. Empty strings are still correctly skipped since `""` is falsy. Update tests to reflect the new behavior: - test_viking_client_headers_send_tenant_when_default: asserts "default" headers ARE present - test_viking_client_headers_send_tenant_when_empty_falls_back_to_default: asserts "default" headers ARE present from constructor fallback Based on #21775 by @happy5318
This commit is contained in:
parent
c7e8add120
commit
8fb3e2d63a
2 changed files with 20 additions and 16 deletions
|
|
@ -100,18 +100,19 @@ class _VikingClient:
|
||||||
raise ImportError("httpx is required for OpenViking: pip install httpx")
|
raise ImportError("httpx is required for OpenViking: pip install httpx")
|
||||||
|
|
||||||
def _headers(self) -> dict:
|
def _headers(self) -> dict:
|
||||||
# Only send tenant headers when the user actually configured them.
|
# Always send tenant headers when account/user are configured.
|
||||||
# Legacy installs had account/user defaulted to the literal string
|
# OpenViking 0.3.x requires X-OpenViking-Account and X-OpenViking-User
|
||||||
# "default" — treat that as unset so authenticated remote servers
|
# for ROOT API key requests to tenant-scoped APIs — omitting them
|
||||||
# that derive tenancy from the Bearer key aren't overridden by a
|
# causes INVALID_ARGUMENT errors even when account="default".
|
||||||
# bogus tenant value.
|
# User-level keys can omit them (server derives tenancy from the key),
|
||||||
|
# but ROOT keys must always include them explicitly.
|
||||||
h = {
|
h = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-OpenViking-Agent": self._agent,
|
"X-OpenViking-Agent": self._agent,
|
||||||
}
|
}
|
||||||
if self._account and self._account != "default":
|
if self._account:
|
||||||
h["X-OpenViking-Account"] = self._account
|
h["X-OpenViking-Account"] = self._account
|
||||||
if self._user and self._user != "default":
|
if self._user:
|
||||||
h["X-OpenViking-User"] = self._user
|
h["X-OpenViking-User"] = self._user
|
||||||
if self._api_key:
|
if self._api_key:
|
||||||
h["X-API-Key"] = self._api_key
|
h["X-API-Key"] = self._api_key
|
||||||
|
|
|
||||||
|
|
@ -314,10 +314,11 @@ def test_viking_client_headers_include_bearer_when_api_key_set():
|
||||||
assert headers["Authorization"] == "Bearer test-key"
|
assert headers["Authorization"] == "Bearer test-key"
|
||||||
|
|
||||||
|
|
||||||
def test_viking_client_headers_omit_tenant_when_legacy_default():
|
def test_viking_client_headers_send_tenant_when_default():
|
||||||
# Existing installs have account/user set to the literal string "default".
|
# account/user set to the literal string "default". OpenViking 0.3.x
|
||||||
# Those should NOT be sent as headers — the server would interpret that
|
# requires X-OpenViking-Account and X-OpenViking-User for ROOT API key
|
||||||
# as a real tenant override and reject/misroute requests.
|
# requests to tenant-scoped APIs — omitting them causes
|
||||||
|
# INVALID_ARGUMENT errors even when account="default".
|
||||||
client = _VikingClient(
|
client = _VikingClient(
|
||||||
"https://example.com",
|
"https://example.com",
|
||||||
api_key="test-key",
|
api_key="test-key",
|
||||||
|
|
@ -326,13 +327,15 @@ def test_viking_client_headers_omit_tenant_when_legacy_default():
|
||||||
agent="hermes",
|
agent="hermes",
|
||||||
)
|
)
|
||||||
headers = client._headers()
|
headers = client._headers()
|
||||||
assert "X-OpenViking-Account" not in headers
|
assert headers["X-OpenViking-Account"] == "default"
|
||||||
assert "X-OpenViking-User" not in headers
|
assert headers["X-OpenViking-User"] == "default"
|
||||||
assert headers["X-OpenViking-Agent"] == "hermes"
|
assert headers["X-OpenViking-Agent"] == "hermes"
|
||||||
assert headers["Authorization"] == "Bearer test-key"
|
assert headers["Authorization"] == "Bearer test-key"
|
||||||
|
|
||||||
|
|
||||||
def test_viking_client_headers_omit_tenant_when_empty():
|
def test_viking_client_headers_send_tenant_when_empty_falls_back_to_default():
|
||||||
|
# Empty account/user strings fall back to "default" via the constructor.
|
||||||
|
# Headers are sent even for the default value — ROOT API keys need them.
|
||||||
client = _VikingClient(
|
client = _VikingClient(
|
||||||
"https://example.com",
|
"https://example.com",
|
||||||
api_key="",
|
api_key="",
|
||||||
|
|
@ -341,8 +344,8 @@ def test_viking_client_headers_omit_tenant_when_empty():
|
||||||
agent="hermes",
|
agent="hermes",
|
||||||
)
|
)
|
||||||
headers = client._headers()
|
headers = client._headers()
|
||||||
assert "X-OpenViking-Account" not in headers
|
assert headers["X-OpenViking-Account"] == "default"
|
||||||
assert "X-OpenViking-User" not in headers
|
assert headers["X-OpenViking-User"] == "default"
|
||||||
assert "Authorization" not in headers
|
assert "Authorization" not in headers
|
||||||
assert "X-API-Key" not in headers
|
assert "X-API-Key" not in headers
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue