Describe Your Problem
When using the OpenAI Responses streaming API via the Symfony AI OpenAI bridge, assistant output can be duplicated.
This happens because messages with phase: "commentary" are currently handled the same way as phase: "final_answer". As a result, both are emitted as TextDelta, which leads to duplicated visible output.
Expected behavior
- Only
phase: "final_answer" should be emitted as TextDelta
phase: "commentary" should either:
- be ignored, or
- be mapped to
ThinkingDelta (similar to reasoning_summary_text)
Actual behavior
Both commentary and final_answer phases are treated as regular output text and emitted as TextDelta, causing duplicated responses in the final output.
Steps to reproduce
- Use the OpenAI Responses API with streaming enabled
- Trigger a response where the model emits both:
phase: "commentary"
phase: "final_answer"
- Observe that the same content is appended twice in the final output
Technical details
In ResultConverter::convertStream():
if (str_contains($type, 'output_text') && isset($event['delta'])) {
yield new TextDelta($event['delta']);
}
This logic does not differentiate between phases.
However, OpenAI emits response.output_text.delta for both:
The distinction is only available via:
event.item_id → response.output_item → phase
Suggested solution
Track phase per item_id using response.output_item.added events:
$itemPhases[$event['item']['id']] = $event['item']['phase'] ?? null;
Then update handling of response.output_text.delta:
$phase = $itemPhases[$event['item_id']] ?? null;
if ($phase === 'final_answer') {
yield new TextDelta($event['delta']);
}
if ($phase === 'commentary') {
// optionally map to ThinkingDelta or ignore
}
Also consider replacing:
str_contains($type, 'output_text')
with a stricter check:
$type === 'response.output_text.delta'
References
Notes
reasoning_summary_text.* is already correctly handled by the bridge
commentary is different: it is emitted as a normal message with a phase attribute
- This issue only affects streaming responses
Describe Your Problem
When using the OpenAI Responses streaming API via the Symfony AI OpenAI bridge, assistant output can be duplicated.
This happens because messages with
phase: "commentary"are currently handled the same way asphase: "final_answer". As a result, both are emitted asTextDelta, which leads to duplicated visible output.Expected behavior
phase: "final_answer"should be emitted asTextDeltaphase: "commentary"should either:ThinkingDelta(similar toreasoning_summary_text)Actual behavior
Both
commentaryandfinal_answerphases are treated as regular output text and emitted asTextDelta, causing duplicated responses in the final output.Steps to reproduce
phase: "commentary"phase: "final_answer"Technical details
In
ResultConverter::convertStream():This logic does not differentiate between phases.
However, OpenAI emits
response.output_text.deltafor both:commentaryfinal_answerThe distinction is only available via:
event.item_id → response.output_item → phaseSuggested solution
Track
phaseperitem_idusingresponse.output_item.addedevents:Then update handling of
response.output_text.delta:Also consider replacing:
with a stricter check:
References
phasefield):https://platform.openai.com/docs/api-reference/responses
Notes
reasoning_summary_text.*is already correctly handled by the bridgecommentaryis different: it is emitted as a normal message with aphaseattribute