You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
suppress duplicate named side-effect tool calls in the same upstream response when canonical arguments match but the model emits a new call_id
keep existing replay-burst behavior across response IDs and still allow intentional repeats after an intervening side-effect boundary
update HTTP/WebSocket coverage so duplicate side-effect calls produce a retryable stream_incomplete instead of silently executing twice
Tests
uv run ruff format tests/unit/test_proxy_tool_call_dedupe.py tests/unit/test_proxy_utils.py tests/integration/test_proxy_websocket_responses.py
uv run ruff check app/modules/proxy/tool_call_dedupe.py tests/unit/test_proxy_tool_call_dedupe.py tests/unit/test_proxy_utils.py tests/integration/test_proxy_websocket_responses.py
uv run pytest -q tests/unit/test_proxy_utils.py::test_stream_responses_suppresses_same_response_http_tool_calls_with_distinct_call_ids tests/unit/test_proxy_utils.py::test_process_upstream_websocket_text_suppresses_same_response_distinct_tool_call_ids tests/unit/test_proxy_tool_call_dedupe.py tests/unit/test_proxy_http_bridge.py -k 'duplicate or tool_call or replay' tests/integration/test_proxy_websocket_responses.py -k 'duplicate or tool_call or replay'
The flat-call part of this is a real spec-compliance fix: openspec/specs/responses-api-compat/spec.md ("Same-response side-effect tool-call replays are suppressed") already mandates that a changed call_id alone must not make a same-response replay distinct, and main currently violates that for sequential flat calls. But as written the new check overreaches into identity-scoped calls:
P1 — collapses distinct namespaced/code-mode call identities. The new same-response check (app/modules/proxy/tool_call_dedupe.py:140) runs before identity_scoped_call is computed at line 149, and same_response_argument_key deliberately zeroes the call_id slot. So two collaboration.spawn_agent custom_tool_calls in one response with identical input and different call_ids — the exact scenario the "Namespaced side-effect replay dedupe preserves call identity" requirement pins down ("Calls with different namespaces or different nonblank call IDs MUST remain distinct, even when their names and canonical arguments match"; scenario "Distinct namespaced spawns use identical arguments") — now suppress the second spawn and convert the whole turn into a stream_incomplete failure. Same for code-mode exec with identical source and distinct call_ids (2026-07-12 harden delta: "without collapsing distinct call identities"). Since the client retry will regenerate the same two spawns, this is a deterministic retry loop for legit multi-agent v2 parallel spawns. CI is green only because downstream same-response distinct-call_id coverage exists for flat calls, not namespaced ones. Fix: move the check below line 149 and gate it on not identity_scoped_call (identity-scoped calls already get cross-response protection via retained call_id), and add a downstream test mirroring the spec scenario.
P3 — burst clear also drops response-scoped parallel_tool_use keys._clear_downstream_side_effect_burst_keys (line 202) pops every response-scoped key with a None call_id, which includes the per-tool_use keys written by _mark_duplicate_parallel_tool_call_downstream_event. On the response-scoped WS path, parallel([exec X]) -> exec Y -> parallel([exec X]) in one response previously trimmed the second X; now it executes twice. If the intervening-boundary reset is meant to apply to parallel batches too, fine, but it should be deliberate.
P3 — the intervening-boundary carve-out itself is new semantics. The canonical requirement says forward only the first event, with no boundary exception; the burst reset is a reasonable refinement but deserves a small openspec delta modifying that requirement rather than shipping as silent drift (that drift is how main ended up out of spec here in the first place).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
call_idstream_incompleteinstead of silently executing twiceTests
uv run ruff format tests/unit/test_proxy_tool_call_dedupe.py tests/unit/test_proxy_utils.py tests/integration/test_proxy_websocket_responses.pyuv run ruff check app/modules/proxy/tool_call_dedupe.py tests/unit/test_proxy_tool_call_dedupe.py tests/unit/test_proxy_utils.py tests/integration/test_proxy_websocket_responses.pyuv run pytest -q tests/unit/test_proxy_utils.py::test_stream_responses_suppresses_same_response_http_tool_calls_with_distinct_call_ids tests/unit/test_proxy_utils.py::test_process_upstream_websocket_text_suppresses_same_response_distinct_tool_call_ids tests/unit/test_proxy_tool_call_dedupe.py tests/unit/test_proxy_http_bridge.py -k 'duplicate or tool_call or replay' tests/integration/test_proxy_websocket_responses.py -k 'duplicate or tool_call or replay'