Switch to JWT token for inference against Nous, falling back to old opaque token on failure.
This commit is contained in:
@@ -673,6 +673,8 @@ class TestGetTextAuxiliaryClient:
|
||||
def test_custom_endpoint_uses_codex_wrapper_when_runtime_requests_responses_api(self):
|
||||
with patch("agent.auxiliary_client._resolve_custom_runtime",
|
||||
return_value=("https://api.openai.com/v1", "sk-test", "codex_responses")), \
|
||||
patch("agent.auxiliary_client._read_nous_auth", return_value=None), \
|
||||
patch("agent.auxiliary_client._resolve_nous_runtime_api", return_value=None), \
|
||||
patch("agent.auxiliary_client._read_main_model", return_value="gpt-5.3-codex"), \
|
||||
patch("agent.auxiliary_client.OpenAI") as mock_openai:
|
||||
client, model = get_text_auxiliary_client()
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -14,6 +16,14 @@ def _write_auth_store(tmp_path, payload: dict) -> None:
|
||||
(hermes_home / "auth.json").write_text(json.dumps(payload, indent=2))
|
||||
|
||||
|
||||
def _jwt_with_claims(claims: dict) -> str:
|
||||
def _part(payload: dict) -> str:
|
||||
raw = json.dumps(payload, separators=(",", ":")).encode("utf-8")
|
||||
return base64.urlsafe_b64encode(raw).decode("ascii").rstrip("=")
|
||||
|
||||
return f"{_part({'alg': 'none', 'typ': 'JWT'})}.{_part(claims)}.sig"
|
||||
|
||||
|
||||
def test_fill_first_selection_skips_recently_exhausted_entry(tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
|
||||
_write_auth_store(
|
||||
@@ -510,6 +520,52 @@ def test_load_pool_migrates_nous_provider_state(tmp_path, monkeypatch):
|
||||
assert entry.agent_key == "agent-key"
|
||||
|
||||
|
||||
def test_load_pool_mirrors_nous_invoke_jwt_agent_key_runtime_api_key(tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
|
||||
expires_at = datetime.fromtimestamp(time.time() + 3600, tz=timezone.utc).isoformat()
|
||||
token = _jwt_with_claims({
|
||||
"sub": "test-user",
|
||||
"scope": ["inference:invoke", "inference:mint_agent_key"],
|
||||
"exp": int(time.time() + 3600),
|
||||
})
|
||||
_write_auth_store(
|
||||
tmp_path,
|
||||
{
|
||||
"version": 1,
|
||||
"active_provider": "nous",
|
||||
"providers": {
|
||||
"nous": {
|
||||
"portal_base_url": "https://portal.example.com",
|
||||
"inference_base_url": "https://inference.example.com/v1",
|
||||
"client_id": "hermes-cli",
|
||||
"token_type": "Bearer",
|
||||
"scope": "inference:invoke inference:mint_agent_key",
|
||||
"access_token": token,
|
||||
"refresh_token": "refresh-token",
|
||||
"expires_at": expires_at,
|
||||
"agent_key": token,
|
||||
"agent_key_expires_at": expires_at,
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
from agent.credential_pool import load_pool
|
||||
|
||||
pool = load_pool("nous")
|
||||
entry = pool.select()
|
||||
|
||||
assert entry is not None
|
||||
assert entry.source == "device_code"
|
||||
assert entry.agent_key == token
|
||||
assert entry.runtime_api_key == token
|
||||
|
||||
auth_payload = json.loads((tmp_path / "hermes" / "auth.json").read_text())
|
||||
pool_entry = auth_payload["credential_pool"]["nous"][0]
|
||||
assert pool_entry["agent_key"] == token
|
||||
assert pool_entry["agent_key_expires_at"] == expires_at
|
||||
|
||||
|
||||
def test_nous_pool_terminal_refresh_clears_tokens(tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
|
||||
monkeypatch.setenv("HERMES_SHARED_AUTH_DIR", str(tmp_path / "shared"))
|
||||
|
||||
Reference in New Issue
Block a user