Skip to content

Commit c7edc1c

Browse files
committed
Simpfliy Responses streaming handling
1 parent 3645ccc commit c7edc1c

File tree

1 file changed

+19
-47
lines changed

1 file changed

+19
-47
lines changed

src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ internal static async IAsyncEnumerable<ChatResponseUpdate> FromOpenAIStreamingRe
198198
string? modelId = null;
199199
string? lastMessageId = null;
200200
ChatRole? lastRole = null;
201-
Dictionary<int, MessageResponseItem> outputIndexToMessages = [];
202-
Dictionary<int, FunctionCallResponseItem>? functionCallItems = null;
201+
bool anyFunctions = false;
203202

204203
await foreach (var streamingUpdate in streamingResponseUpdates.WithCancellation(cancellationToken).ConfigureAwait(false))
205204
{
@@ -229,75 +228,48 @@ ChatResponseUpdate CreateUpdate(AIContent? content = null) =>
229228
var update = CreateUpdate(ToUsageDetails(completedUpdate.Response) is { } usage ? new UsageContent(usage) : null);
230229
update.FinishReason =
231230
ToFinishReason(completedUpdate.Response?.IncompleteStatusDetails?.Reason) ??
232-
(functionCallItems is not null ? ChatFinishReason.ToolCalls :
231+
(anyFunctions ? ChatFinishReason.ToolCalls :
233232
ChatFinishReason.Stop);
234233
yield return update;
235234
break;
236235
}
237236

238237
case StreamingResponseOutputItemAddedUpdate outputItemAddedUpdate:
238+
lastMessageId = outputItemAddedUpdate.Item.Id;
239239
switch (outputItemAddedUpdate.Item)
240240
{
241241
case MessageResponseItem mri:
242-
outputIndexToMessages[outputItemAddedUpdate.OutputIndex] = mri;
242+
lastRole = ToChatRole(mri.Role);
243243
break;
244244

245245
case FunctionCallResponseItem fcri:
246-
(functionCallItems ??= [])[outputItemAddedUpdate.OutputIndex] = fcri;
246+
anyFunctions = true;
247+
lastRole = ChatRole.Assistant;
247248
break;
248249
}
249250

250251
goto default;
251252

252-
case StreamingResponseOutputItemDoneUpdate outputItemDoneUpdate:
253-
_ = outputIndexToMessages.Remove(outputItemDoneUpdate.OutputIndex);
254-
255-
if (outputItemDoneUpdate.Item is MessageResponseItem item &&
256-
item.Content is { Count: > 0 } content &&
257-
content.Any(c => c.OutputTextAnnotations is { Count: > 0 }))
258-
{
259-
AIContent annotatedContent = new();
260-
foreach (var c in content)
261-
{
262-
PopulateAnnotations(c, annotatedContent);
263-
}
264-
265-
yield return CreateUpdate(annotatedContent);
266-
break;
267-
}
268-
269-
goto default;
270-
271253
case StreamingResponseOutputTextDeltaUpdate outputTextDeltaUpdate:
272-
{
273-
_ = outputIndexToMessages.TryGetValue(outputTextDeltaUpdate.OutputIndex, out MessageResponseItem? messageItem);
274-
lastMessageId = messageItem?.Id;
275-
lastRole = ToChatRole(messageItem?.Role);
276-
277254
yield return CreateUpdate(new TextContent(outputTextDeltaUpdate.Delta));
278255
break;
279-
}
280-
281-
case StreamingResponseFunctionCallArgumentsDoneUpdate functionCallOutputDoneUpdate:
282-
{
283-
if (functionCallItems?.TryGetValue(functionCallOutputDoneUpdate.OutputIndex, out FunctionCallResponseItem? callInfo) is true)
284-
{
285-
_ = functionCallItems.Remove(functionCallOutputDoneUpdate.OutputIndex);
286-
287-
var fcc = OpenAIClientExtensions.ParseCallContent(
288-
functionCallOutputDoneUpdate.FunctionArguments.ToString(),
289-
callInfo.CallId,
290-
callInfo.FunctionName);
291256

292-
lastMessageId = callInfo.Id;
293-
lastRole = ChatRole.Assistant;
257+
case StreamingResponseOutputItemDoneUpdate outputItemDoneUpdate when outputItemDoneUpdate.Item is FunctionCallResponseItem fcri:
258+
yield return CreateUpdate(OpenAIClientExtensions.ParseCallContent(fcri.FunctionArguments.ToString(), fcri.CallId, fcri.FunctionName));
259+
break;
294260

295-
yield return CreateUpdate(fcc);
296-
break;
261+
case StreamingResponseOutputItemDoneUpdate outputItemDoneUpdate when
262+
outputItemDoneUpdate.Item is MessageResponseItem mri &&
263+
mri.Content is { Count: > 0 } content &&
264+
content.Any(c => c.OutputTextAnnotations is { Count: > 0 }):
265+
AIContent annotatedContent = new();
266+
foreach (var c in content)
267+
{
268+
PopulateAnnotations(c, annotatedContent);
297269
}
298270

299-
goto default;
300-
}
271+
yield return CreateUpdate(annotatedContent);
272+
break;
301273

302274
case StreamingResponseErrorUpdate errorUpdate:
303275
yield return CreateUpdate(new ErrorContent(errorUpdate.Message)

0 commit comments

Comments
 (0)