Summary
agent/context_compressor.py::_sanitize_tool_pairs (line 2168, called at line 2981) is a parallel reimplementation of the orphaned-tool-pair repair logic that lives in agent/agent_runtime_helpers.py (repair_message_sequence / sanitize_api_messages). The two have drifted: the agent_runtime_helpers sanitizers now deduplicate tool_call_ids (added in #58350 for #58327), but the compressor's _sanitize_tool_pairs does not.
This is the same class of divergence previously flagged for whitespace handling in #55845 (compressor's copy lacked the .strip() normalization that agent_runtime_helpers had).
Not a live bug today
This is a defense-in-depth / maintainability item, not a correctness hole. Compressor output re-enters the main agent loop and passes through sanitize_api_messages (agent/conversation_loop.py:895) before any provider call, so a duplicate tool_call_id the compressor emits or re-emits is still deduplicated downstream before it reaches a strict provider (DeepSeek). No user-facing failure is expected on current main.
Why fix it anyway
Proposed direction
Have context_compressor._sanitize_tool_pairs delegate to the canonical helpers in agent_runtime_helpers.py (repair_message_sequence and/or the dedup pass from sanitize_api_messages) rather than reimplementing orphan/pair logic. If the compressor needs a variant (e.g. it operates on the compressed window rather than the full API payload), extract the shared invariant into one reusable function both call, so dedup/whitespace/orphan handling can never drift again.
References
Summary
agent/context_compressor.py::_sanitize_tool_pairs(line 2168, called at line 2981) is a parallel reimplementation of the orphaned-tool-pair repair logic that lives inagent/agent_runtime_helpers.py(repair_message_sequence/sanitize_api_messages). The two have drifted: theagent_runtime_helperssanitizers now deduplicatetool_call_ids (added in #58350 for #58327), but the compressor's_sanitize_tool_pairsdoes not.This is the same class of divergence previously flagged for whitespace handling in #55845 (compressor's copy lacked the
.strip()normalization thatagent_runtime_helpershad).Not a live bug today
This is a defense-in-depth / maintainability item, not a correctness hole. Compressor output re-enters the main agent loop and passes through
sanitize_api_messages(agent/conversation_loop.py:895) before any provider call, so a duplicatetool_call_idthe compressor emits or re-emits is still deduplicated downstream before it reaches a strict provider (DeepSeek). No user-facing failure is expected on currentmain.Why fix it anyway
Proposed direction
Have
context_compressor._sanitize_tool_pairsdelegate to the canonical helpers inagent_runtime_helpers.py(repair_message_sequenceand/or the dedup pass fromsanitize_api_messages) rather than reimplementing orphan/pair logic. If the compressor needs a variant (e.g. it operates on the compressed window rather than the full API payload), extract the shared invariant into one reusable function both call, so dedup/whitespace/orphan handling can never drift again.References
agent/agent_runtime_helpers.py:2488-2529)agent/context_compressor.py:2168, invoked at:2981