Skip to content

fix(anthropic): tool_use/tool_result adjacency + OAuth claude-code/ UA (salvage #52145 #51948) - #268

Merged
hashbender merged 1 commit into
mainfrom
mirror/pr-56263
Jul 1, 2026
Merged

fix(anthropic): tool_use/tool_result adjacency + OAuth claude-code/ UA (salvage #52145 #51948)#268
hashbender merged 1 commit into
mainfrom
mirror/pr-56263

Conversation

@hashbender

Copy link
Copy Markdown
Owner

Summary

Batch salvage of two complementary agent/anthropic_adapter.py fixes, rebased onto current main. Both bugs confirmed still-present; disjoint regions, no conflict.

Fixes

NousResearch#52145 (@fsaad1984) — enforce tool_use/tool_result adjacency in _strip_orphaned_tool_blocks
The old logic collected tool_result ids across all user messages and kept any assistant tool_use whose id appeared anywhere. Anthropic requires each tool_use to have its tool_result in the immediately following user message — a stale match elsewhere in the transcript would keep a genuinely-orphaned tool_use and 400 the request. Rewritten to adjacency-checked two-pass logic: pass 1 strips a tool_use whose result isn't in the next user message; pass 2 removes results orphaned by pass 1.

NousResearch#51948 (@DhivinX) — OAuth UA claude-cli/claude-code/
Anthropic 404s the OAuth token endpoint for the claude-cli/ UA prefix (NousResearch#48534). Switched all three OAuth UA sites — build_anthropic_client (:820), refresh_anthropic_oauth_pure (:1048), run_hermes_oauth_login_pure (:1491) — to claude-code/.

Review follow-ups (mine)

A structured review of the salvage surfaced three test-quality issues, all fixed:

  • fix(adapter): enforce tool_use/tool_result adjacency in _strip_orphaned_tool_blocks NousResearch/hermes-agent#52145 shipped no behavior test. Added test_strips_tool_use_when_result_not_immediately_adjacent (the exact non-adjacent case the old global match got wrong) + an adjacent-pair control. Mutation-checked: reverting to a global match fails the non-adjacent test.
  • test_token_exchange_ua_prefix false-failed on a comment (naive whole-function substring). Scoped it to actual User-Agent header lines, matching its sibling.
  • test_token_refresh_ua_prefix was vacuous — it bound to a wrapper (_refresh_oauth_token) with no HTTP call, so its assert never ran. Retargeted at the real refresh site refresh_anthropic_oauth_pure. Mutation-checked: reverting :1048 now fails it.

Verification

  • All UA + adjacency + existing-orphan tests pass (10/10 for the touched surface).
  • Note: test_anthropic_adapter.py has ~15 pre-existing failures on current main in unrelated OAuth-token-resolution classes (TestResolveAnthropicToken / TestRefreshOauthToken / TestRunOauthSetupToken) — verified identical on clean origin/main with none of these changes applied. Not introduced by this PR.

Closes NousResearch#52145. Closes NousResearch#51948.

Co-authored-by: fsaad1984 38867992+fsaad1984@users.noreply.github.com
Co-authored-by: DhivinX 20087092+DhivinX@users.noreply.github.com


Mirror-of: NousResearch#56263
NousResearch#56263

@hashbender
hashbender merged commit ec8b722 into main Jul 1, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant