hermes: normalize Codex response budgets
All checks were successful
Tests / Declarative: Post Actions passed: 246

This commit is contained in:
jenkins 2026-08-12 01:21:20 -03:00
parent 072542d116
commit edcb2935e4
3 changed files with 18 additions and 1 deletions

View File

@ -25,7 +25,7 @@ spec:
ai.bstein.dev/execution: Hermes Kanban with durable direct Codex and Claude Code CLI workers
ai.bstein.dev/model-policy: Jetson-assisted AUTO routing, low through xhigh, cross-provider fallback
ai.bstein.dev/placement: rpi5 preferred; Jetson deferred until state storage is available
ai.bstein.dev/config-rev: "20260811-switchyard-responses-output"
ai.bstein.dev/config-rev: "20260812-codex-budget-normalization"
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: hermes-agent
vault.hashicorp.com/agent-inject-secret-anthropic-token: kv/data/atlas/hermes/agent-tokens

View File

@ -124,6 +124,17 @@ def _validate_payload(payload: Any) -> dict[str, Any]:
payload["input"] = [response_input]
elif not isinstance(response_input, list) or not response_input:
raise ValueError("non-empty Responses input list required")
# Switchyard uses ``max_output_tokens`` to bound the tiny classifier call,
# but its Responses translation can also copy that internal option onto the
# selected provider request. The first-party subscription Codex endpoint
# does not accept any of the public API token-budget aliases. Let Codex use
# its own response budget instead of turning a healthy fallback into a 400.
for token_budget_key in (
"max_output_tokens",
"max_completion_tokens",
"max_tokens",
):
payload.pop(token_budget_key, None)
# Tenant conversations must not enter the owner's server-side history.
payload["store"] = False
payload["stream"] = True

View File

@ -525,10 +525,16 @@ def test_codex_broker_auth_and_request_contract(tmp_path: Path, monkeypatch):
"input": "route this chat turn",
"store": True,
"stream": False,
"max_output_tokens": 96,
"max_completion_tokens": 96,
"max_tokens": 96,
}
)
assert payload["store"] is False
assert payload["stream"] is True
assert "max_output_tokens" not in payload
assert "max_completion_tokens" not in payload
assert "max_tokens" not in payload
assert payload["input"] == [
{
"type": "message",