Update OpenAIResponsesChatClient to handle streaming code interpreter content#7267
Update OpenAIResponsesChatClient to handle streaming code interpreter content#7267stephentoub wants to merge 2 commits intodotnet:mainfrom
Conversation
… content Right now it outputs it but in a bulk fashion only at the end of the response item. This makes it yield the deltas instead.
There was a problem hiding this comment.
Pull request overview
This PR updates the OpenAI Responses chat client to handle streaming code interpreter content by yielding deltas incrementally rather than emitting the code in bulk only at the end of the response. This enables real-time streaming of code generation, improving the user experience.
Changes:
- Added streaming support for code interpreter delta updates, creating
CodeInterpreterToolCallContentfor each delta as it arrives - Extracted the Python media type string into a reusable constant (
PythonMediaType) - Added comprehensive test coverage to verify delta streaming behavior and proper coalescing of deltas into final responses
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs |
Added handling for StreamingResponseCodeInterpreterCallCodeDeltaUpdate to yield deltas incrementally; inlined code interpreter content creation logic (removing helper method); updated OutputItemDone handler to only yield result content (assuming deltas handled the call content) |
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIClientExtensions.cs |
Extracted Python media type string into a constant PythonMediaType |
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIAssistantsChatClient.cs |
Updated to use the new PythonMediaType constant |
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientTests.cs |
Updated existing tests with exact code assertions; added new comprehensive test CodeInterpreterTool_Streaming_YieldsCodeDeltas to verify streaming delta behavior and proper coalescing |
| message.Contents.Add(new CodeInterpreterToolResultContent | ||
| { | ||
| CallId = cicri.Id, | ||
| Outputs = cicri.Outputs is { Count: > 0 } outputs ? outputs.Select<CodeInterpreterCallOutput, AIContent?>(o => | ||
| o switch | ||
| { | ||
| CodeInterpreterCallImageOutput cicio => new UriContent(cicio.ImageUri, OpenAIClientExtensions.ImageUriToMediaType(cicio.ImageUri)) { RawRepresentation = cicio }, | ||
| CodeInterpreterCallLogsOutput ciclo => new TextContent(ciclo.Logs) { RawRepresentation = ciclo }, | ||
| _ => null, | ||
| }).OfType<AIContent>().ToList() : null, | ||
| RawRepresentation = cicri, | ||
| }); |
There was a problem hiding this comment.
The logic for creating CodeInterpreterToolResultContent with output mapping is duplicated between the non-streaming path (lines 235-246) and the streaming path (lines 471-482). Consider extracting this into a helper method to reduce duplication and improve maintainability. This would ensure that any future changes to the output mapping logic only need to be made in one place.
Right now it outputs it but in a bulk fashion only at the end of the response item. This makes it yield the deltas instead.
Microsoft Reviewers: Open in CodeFlow