// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.Buffers;
using OpenAI.Chat;
namespace Microsoft.Teams.AI.Models.OpenAI.Builders;
///
/// https://github.com/openai/openai-dotnet/blob/main/examples/Chat/Example04_FunctionCallingStreaming.cs#L18
///
[Obsolete("Microsoft.Teams.AI.Models.OpenAI is deprecated and will be removed by end of summer 2026.")]
public class StreamingChatToolCallsBuilder
{
private readonly Dictionary _indexToToolCallId = [];
private readonly Dictionary _indexToFunctionName = [];
private readonly Dictionary> _indexToFunctionArguments = [];
public void Append(StreamingChatToolCallUpdate toolCallUpdate)
{
// Keep track of which tool call ID belongs to this update index.
if (toolCallUpdate.ToolCallId is not null)
{
_indexToToolCallId[toolCallUpdate.Index] = toolCallUpdate.ToolCallId;
}
// Keep track of which function name belongs to this update index.
if (toolCallUpdate.FunctionName is not null)
{
_indexToFunctionName[toolCallUpdate.Index] = toolCallUpdate.FunctionName;
}
// Keep track of which function arguments belong to this update index,
// and accumulate the arguments as new updates arrive.
if (toolCallUpdate.FunctionArgumentsUpdate is not null && !toolCallUpdate.FunctionArgumentsUpdate.ToMemory().IsEmpty)
{
if (!_indexToFunctionArguments.TryGetValue(toolCallUpdate.Index, out SequenceBuilder? argumentsBuilder))
{
argumentsBuilder = new SequenceBuilder();
_indexToFunctionArguments[toolCallUpdate.Index] = argumentsBuilder;
}
argumentsBuilder.Append(toolCallUpdate.FunctionArgumentsUpdate);
}
}
public IReadOnlyList Build()
{
List toolCalls = [];
foreach (var kv in _indexToToolCallId)
{
ReadOnlySequence sequence = _indexToFunctionArguments[kv.Key].Build();
ChatToolCall toolCall = ChatToolCall.CreateFunctionToolCall(
id: kv.Value,
functionName: _indexToFunctionName[kv.Key],
functionArguments: BinaryData.FromBytes(sequence.ToArray()));
toolCalls.Add(toolCall);
}
return toolCalls;
}
}