Bug: A Responses API tool call announced but never completed is dropped, and the turn mislabelled no_response_body
I maintainer di solito rispondono entro 1 giorno
Una pull request collegata è già stata integrata.
- #1419 di @evaline-ju — integrata
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 65/100
Direzione di ricerca
Start in core/plugins/inferenceparser/plugin.go, where InferenceParser.OnResponseFrame handles the Responses API frames and the terminal arm records pctx.Skip("no_response_body"). Read the existing Anthropic test TestInferenceParser_AnthropicMessages_StreamToolUseOnlyIsNotASkip for the expected handling of truncated arguments. Done means the four-shape table in the issue holds, with the added-only case returning one call with empty arguments and the duplicate-added case still returning one call.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What happens
When a Responses API stream emits response.output_item.added for a tool call but the stream ends before the matching response.output_item.done — a turn cancelled in that window — the call is lost entirely. The turn then also gets mislabelled as having carried no response body.
Measured against main (c8415388) by feeding frames through InferenceParser.OnResponseFrame:
| Frame shape | Result on main |
|---|---|
added → done(incomplete) → terminal |
1 call, partial args "const r = await" |
added → done(in_progress), no terminal |
1 call, partial args |
added only, stream cut |
0 calls ← this bug |
Two of the three shapes are fine and should stay as they are: keeping truncated arguments is what the Anthropic dialect in this same package does deliberately — TestInferenceParser_AnthropicMessages_StreamToolUseOnlyIsNotASkip pins "Arguments stay as the model left them — truncated, not discarded".
Why the mislabelling matters more than the missing call
InferenceParser's terminal arm records pctx.Skip("no_response_body") when Completion, FinishReason, TotalTokens and ToolCalls are all empty (core/plugins/inferenceparser/plugin.go, the "Tool calls count as a body" guard). A turn cancelled mid-tool-call has no completion text, no finish reason and no usage block — so with the call dropped too, all four are empty and the row is labelled as carrying nothing, when it demonstrably started a tool call. The guard's own comment says that outcome is what it exists to prevent; it just cannot see a call that was never recorded.
Fix
Track a tool call from response.output_item.added (call_id + name, no arguments yet), and have response.output_item.done fill in the arguments on that same entry rather than appending a second one. An id-keyed lookup is needed so a call seen on both events is not double-counted.
Add no status-based exclusion. This is the part worth stating explicitly, because it was tried and was wrong — see #1331, which excluded items whose status was incomplete/in_progress and thereby dropped calls main keeps, regressing two shapes to fix one. The concern behind it (truncated arguments presented as complete) is already answered: shape 1 sets FinishReason: "incomplete", which is the signal a consumer should read.
Expected result — strictly additive, nothing else changes:
| Shape | Before | After |
|---|---|---|
| added → done(incomplete) | 1, partial | 1, partial (unchanged) |
| added → done(in_progress) | 1, partial | 1, partial (unchanged) |
| added only | 0 | 1, empty args |
| normal complete call | 1, full | 1, full (unchanged) |
Tests worth having
- One per row of that table, asserting the count AND the arguments, so a future change that blanks the partial-argument rows fails loudly.
- A duplicate-
addedguard case: twoaddedevents for onecall_idmust not yield two calls. - A
done-with-no-addedcase (not expected on live traffic, but the fallback should not drop the call). - A
function_call-typed case alongsidecustom_tool_call, since #1331's review found both arms could be individually deleted with the suite staying green.
Severity
Low. It needs a cancellation landing in the window between added and done, which is narrow — Codex emits custom_tool_call_input.delta events in between, so the window is real but small. Filed because it is now a well-understood small fix rather than an open question.
Context: #1331 (closed, has the full analysis), #942, #1239.
Assisted-By: Claude (Anthropic AI) [email protected]
- Lingua principale
- Go
- Stelle
- 16
- Fork
- 41
- Merge medio
- 11h 23m
- PR unite (30g)
- 275
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di rossoctl/cortex
-
UI shows costs for all sessions even when drilled into a sessionForse già presa @esnible l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
rossoctl/cortex#1116 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Support mTLS for Session APIAperta
Difficoltà 5/5 Più di una settimana Idoneità per principianti 22/100
I maintainer di solito rispondono entro 1 giorno
-
Add a coding-agent demo with cpex policy enforcementForse già presa @araujof l’ha presa 1 giorno fa. Aperta
rossoctl/cortex#1428 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Release cortex-cpex binaries and add installer supportForse già presa @araujof l’ha presa 1 giorno fa. Aperta
rossoctl/cortex#1427 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Update the hr-cpex demo for CPEX 0.3Forse già presa @araujof l’ha presa 1 giorno fa. Aperta
rossoctl/cortex#1426 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di rossoctl/cortex
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 81/100
apache/rocketmq-dashboard#6895 ·
I maintainer di solito rispondono entro 3 giorni
-
agent-butler-finding chore
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
jordansmall/spindrift#5466 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 87/100
777genius/agent-notifications#490 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
devantler-tech/ksail#7836 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
keyxmakerx/Chronicle#1469 ·
I maintainer di solito rispondono entro 1 giorno