# Tool calls under streaming: wait for output_item.done
With `stream=True`, a function call does not arrive as one object. It arrives as
a run of events, and the only safe moment to parse `arguments` is the end.
## What the event stream looks like
- `response.output_item.added` announces a function_call item with an empty
arguments string.
- A series of delta events append fragments to `arguments`.
- `response.output_item.done` carries the item with the complete `arguments`
JSON string. Parse it here, and only here.
Parsing any earlier delta is the bug: the JSON is truncated mid-string and
`JSON.parse` / `json.loads` throws, or worse, parses a prefix into a wrong
object.
## The correct pattern (both SDKs)
1. Stream with `stream=True`. Accumulate nothing for tool calls except routing
`response.output_text.delta` events to the UI.
2. On `response.output_item.done` with `type == "function_call"`, parse
`item.arguments` (now complete) and run your tool-loop step.
3. Make the follow-up `responses.create` call non-streaming (or start a second
stream) with the appended `function_call_output` items. Do not try to continue
the same stream object; it is finished.
## Check before you ship
- Test with a tool whose arguments are long (a paragraph of text). Short
arguments fit in one delta and hide the bug; long ones expose it.
- Assert your code has no JSON parse call inside the delta-event branch. Grep for
it; the parse must live only in the done-event branch.