fix(diagnostics): show masked API key and correct URL in request dumps for anthropic_messages mode - #55552
Conversation
…s for anthropic_messages mode For Anthropic-mode providers (MiniMax, Kimi, etc.), agent.client is None — the real client lives in agent._anthropic_client. The dump code read from agent.client.api_key, producing 'Bearer None' in the debug dump even though the actual HTTP request used the correct key. Also fix the dump URL: Anthropic SDK posts to /v1/messages, not /chat/completions. Fixes NousResearch#55539
Related: open PR #54221 ("fix(debug): show correct URL and API key in request dumps for all api_modes") fixes the same misleading |
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Clean diagnostics fix (2 files, +88 lines). Two issues addressed:
- Anthropic-mode providers store the client in
agent._anthropic_clientwithagent.client = None, causing debug dumps to showBearer None. Falls back toagent.api_key. - URL construction for anthropic_messages mode was missing the
/v1/messagespath.
Both fixes include dedicated tests that verify the masked key and correct URL.
Looks Good
- Correct fallback chain for API key extraction
- URL construction now handles all three API modes (chat_completions, codex_responses, anthropic_messages)
- Tests verify both the masked key and the URL for anthropic mode
- No security concerns (keys are masked in dumps)
Reviewed by Hermes Agent
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Good fix for API request debug dumps showing Bearer None for Anthropic-mode providers. The fallback to agent.api_key when agent.client is None (Anthropic mode) is correct. Also fixes the dump URL to use /v1/messages for Anthropic mode instead of always using /chat/completions.
Looks Good
- Correct fallback chain: client.api_key -> agent.api_key
- URL normalization matches the actual outbound endpoint per api_mode
- Good test coverage for both the masked key and correct URL
- Minimal surface area (2 files, 88 additions)
Reviewed by Hermes Agent
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the request-dump defect; current main still reads agent.client.api_key at agent/agent_runtime_helpers.py:1443-1457 even though Anthropic initialization sets agent.client = None at agent/agent_init.py:817-832.
Problems
- The new
agent.api_keyfallback can be stale after native Anthropic refresh.run_agent.py:4406-4416rebuilds withnew_tokenand updates only_anthropic_api_key. - Appending
/v1/messagestoagent.base_urlcan produce/v1/v1/messages:agent/anthropic_adapter.py:757-760strips/v1for the live SDK client, while native configured URLs are retained inhermes_cli/runtime_provider.py:435-443.
Suggested changes
- Prefer
_anthropic_api_keyforanthropic_messages, then fall back toapi_key, with a refreshed-token regression test. - Normalize a trailing
/v1before constructing the diagnostic Messages URL and test that configured form.
This is an automated hermes-sweeper review.
| # Fall back to ``agent.api_key`` (set by init_agent for all modes) | ||
| # so the dump shows a masked key instead of ``Bearer None``. | ||
| if not api_key: | ||
| api_key = getattr(agent, "api_key", None) |
There was a problem hiding this comment.
For anthropic_messages, prefer agent._anthropic_api_key before agent.api_key: native credential refresh rebuilds the live client and updates only _anthropic_api_key (run_agent.py:4406-4416), so this fallback can mask a stale rather than active credential.
| # stripped by the normalizer); Codex uses ``/responses``. | ||
| if agent.api_mode == "anthropic_messages": | ||
| _dump_url = f"{agent.base_url.rstrip('/')}/v1/messages" | ||
| elif agent.api_mode == "codex_responses": |
There was a problem hiding this comment.
Normalize a trailing /v1 before appending /v1/messages. The live Anthropic adapter strips that suffix (agent/anthropic_adapter.py:757-760), so a valid configured https://api.anthropic.com/v1 would otherwise be dumped as /v1/v1/messages.
What does this PR do?
Fixes the request debug dump (
request_dump_*.json) for Anthropic-mode providers (MiniMax, Kimi, etc.) whereagent.clientisNone. The dump previously readapi_keyfromagent.client(which isNonefor anthropic_messages mode), producing"Bearer None"in the Authorization header of the dump — even though the actual HTTP request used the correct key viaagent._anthropic_client. The dump also showed the wrong URL (/chat/completionsinstead of/v1/messages).Related Issue
Fixes #55539
Type of Change
Changes Made
agent/agent_runtime_helpers.py: Indump_api_request_debug(), fall back toagent.api_keywhenagent.clientisNone(Anthropic mode). Also build the dump URL based onapi_mode:/v1/messagesfor anthropic_messages,/responsesfor codex_responses,/chat/completionsotherwise.tests/run_agent/test_run_agent_codex_responses.py: Add two tests verifying the dump shows a masked key (not "None") and the correct/v1/messagesURL for anthropic_messages mode.How to Test
python -m pytest tests/run_agent/test_run_agent_codex_responses.py::test_dump_api_request_debug_anthropic_mode_shows_masked_key tests/run_agent/test_run_agent_codex_responses.py::test_dump_api_request_debug_anthropic_mode_shows_messages_url -xvsBearer sk-cp-ab...6789) and the URLhttps://api.minimaxi.com/anthropic/v1/messages.python -m pytest tests/run_agent/test_run_agent_codex_responses.py -k "dump_api_request" -xvs— all 5 should pass.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/A