refactor(anthropic): extract 7 helpers from convert_messages_to_anthropic (rebased #23968)#27784
Conversation
Split convert_messages_to_anthropic (complexity 79) into 7 focused helpers: - _convert_assistant_message — assistant msg to content blocks - _convert_tool_message_to_result — tool msg to tool_result + merge - _convert_user_message — user msg validation + conversion - _strip_orphaned_tool_blocks — orphan tool_use + tool_result removal - _merge_consecutive_roles — role alternation enforcement - _manage_thinking_signatures — strip/preserve/downgrade by endpoint - _evict_old_screenshots — keep only 3 most recent images Main function complexity: 79 → 10 (below C901 threshold). Zero logic changes — pure extraction. Net -4 lines (refactor itself); +45/-17 follow-up polish for annotation tightening (List[Dict] → List[Dict[str, Any]]), restored rationale comments in _manage_thinking_signatures (third-party endpoint examples, NousResearch#13848/NousResearch#16748 issue refs, redacted_thinking 'data'-as-signature note), and "Mutates ``result`` in place." docstring lines on the four mutating helpers.
65c4e3d to
9b322b5
Compare
There was a problem hiding this comment.
Pull request overview
Pure-extraction refactor of convert_messages_to_anthropic in agent/anthropic_adapter.py, splitting a single ~185-statement / C=79 function into seven single-responsibility helpers. Logic is preserved; only structure changes.
Changes:
- Extract
_convert_assistant_message,_convert_tool_message_to_result,_convert_user_message,_strip_orphaned_tool_blocks,_merge_consecutive_roles,_manage_thinking_signatures,_evict_old_screenshots. - Reduce
convert_messages_to_anthropicto a top-level dispatch loop followed by sequential helper calls. - Net −4 LOC; max cyclomatic complexity in the file drops from 79 to 18.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Merged via #30386 (9d61408). Your commit was cherry-picked onto current |
Summary
Refactor of
convert_messages_to_anthropicinagent/anthropic_adapter.py— the largest cyclomatic-complexity hotspot in the file (originally 185 statements, 90 branches, C=79). Extracts 7 single-responsibility helpers, trims net −4 LOC.Cherry-pick of #23968 rebased onto current
origin/main. Cherry-pick was clean —agent/anthropic_adapter.pyhad 4 commits land since the original branch point but none touchedconvert_messages_to_anthropicor its sibling helpers, so no conflict resolution was needed.Closes part of #23972 (Phase 2 tracker). The 4 codex_responses_adapter refactor PRs from that tracker (#23951/#23952/#23954/#23957) were closed today because their LOC accounting was net positive — this PR is the lone Phase 2 win that drops both LOC and max complexity.
Honest accounting
anthropic_adapter.pyconvert_messages_to_anthropiccyclomaticThe violation-count regression is real and worth calling out: splitting one C=79 function into 1 helper-at-<10 + 4 helpers at C=12/13/15/18 makes ruff flag MORE individual functions even though the max complexity drops 77%. By rule-count alone, this is a regression. By the actual goal of the C901 rule (find untestable monolithic functions), it's a clear win — each of the 4 new helpers is short enough to read in one screen and individually testable.
The original PR description in #23968 overclaimed "79→10". The honest number is "79→18 max, spread across 4 still-complex helpers".
What changed structurally
convert_messages_to_anthropicpreviously did all of the following in one function:tool_resultblocksAfter: top-level walks/dispatches, 7 extracted helpers handle (2)-(6). Helper signatures:
Each helper takes its inputs explicitly. The four mutating helpers (
_convert_tool_message_to_result,_strip_orphaned_tool_blocks,_manage_thinking_signatures,_evict_old_screenshots) updateresultin place — the original code did the same inline, so semantics are preserved._merge_consecutive_rolesreturns a new list; the caller rebindsresult = _merge_consecutive_roles(result).Test plan
git cherry-pick b8e47ab16no conflicts)tests/agent/test_anthropic_adapter.py: 136 pass, 14 failTestResolveAnthropicToken*/TestResolveWithRefresh/TestRunOauthSetupTokenOAuth-credential tests that fail identically onorigin/main(verified against current HEAD). None touchconvert_messages_to_anthropic.-k "convert or message or strip or merge or thinking or tool_result or orphan or signature or screenshot or evict": 53/53 pass.tests/agent/ -k anthropic: 296 passed, 14 failed (same 14 OAuth tests, no other regressions).py_compile.compileclean onanthropic_adapter.pyruff checkclean onanthropic_adapter.py(only the pre-existing complexity warnings remain, which are exactly what this PR addresses)Worth shipping
Yes — net-negative LOC + 77% reduction in max-function complexity + each helper individually testable. The raw violation-count regression is a quirk of how ruff counts (one function above threshold becomes four functions above threshold even though they're each meaningfully smaller). The original 185-statement function was the kind of thing the C901 rule exists to catch; now it isn't.