Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f364876
Pick up changes to tool naming
trangevi Aug 13, 2024
afb3c25
Test/sample fixes
trangevi Aug 13, 2024
e5a9b77
TSP commit
trangevi Aug 14, 2024
65a55c8
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Aug 14, 2024
bf629a5
Update with recent typespec changes. Re-record tests
trangevi Aug 23, 2024
bab6b9d
Add embedding client and associated changes
trangevi Aug 29, 2024
7071138
Add samples. Regenerate apiview
trangevi Aug 30, 2024
762f437
Add test for user agent
trangevi Sep 16, 2024
e04113e
Updates to flatten Choices array
trangevi Sep 23, 2024
1db2dfc
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Sep 25, 2024
2b0bcd7
Pick up changes from tsp
trangevi Sep 25, 2024
c2a1f72
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Sep 25, 2024
c3d996e
Finally got tool streaming working!
trangevi Oct 3, 2024
b8fe531
regenerate after changes
trangevi Oct 3, 2024
b417e4e
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Oct 3, 2024
9f4fb2f
up
Oct 8, 2024
a6cb31f
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Oct 9, 2024
4c8ed0d
Merge fixes. Removing test recordings
trangevi Oct 10, 2024
920be7a
Rename sample files
trangevi Oct 10, 2024
b600294
Add handling to pass both auth headers in every request
trangevi Oct 10, 2024
7e20f3e
Add handling for image files for chat completions
trangevi Oct 11, 2024
652596c
Regen code and api
trangevi Oct 11, 2024
cacdc03
Update spellchecker
trangevi Oct 11, 2024
02ef186
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Oct 11, 2024
37e36fb
Update snippets
trangevi Oct 11, 2024
df9b796
Update sample names/pointers
trangevi Oct 15, 2024
c19fb2d
Update test recordings asset pointer
trangevi Oct 15, 2024
b861fcf
Rename some enum values
trangevi Oct 18, 2024
bf2143d
Update Apiview
trangevi Oct 18, 2024
8215877
Merge branch 'main' into trangevi/ai-inference-sdk
trangevi Oct 18, 2024
6e961ca
Regenerated
trangevi Oct 18, 2024
d617623
Changelog update
trangevi Oct 21, 2024
c8c7759
Changelog update
trangevi Oct 22, 2024
3584458
Update hopefull release date
trangevi Oct 23, 2024
b4dc0e6
Remove extraParams. Add more samples
trangevi Oct 24, 2024
8a031ac
Missed change to apiview
trangevi Oct 24, 2024
176b9d7
Snippet fixes
trangevi Oct 24, 2024
3b1fb6f
Update release date
trangevi Oct 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Finally got tool streaming working!
Signed-off-by: Travis Angevine <[email protected]>
  • Loading branch information
trangevi committed Oct 3, 2024
commit c3d996e5534b23576b6fefee0c2b2d4a9df9fbc6
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using Azure.Core;

namespace Azure.AI.Inference
Expand Down Expand Up @@ -32,6 +33,16 @@ public partial class ChatCompletionsOptions
/// <summary> A value indicating whether chat completions should be streamed for this request. </summary>
internal bool? InternalShouldStreamResponse { get; set; }

/// <summary>
/// The collection of context messages associated with this chat completions request.
/// Typical usage begins with a chat message for the System role that provides instructions for
/// the behavior of the assistant, followed by alternating messages between the User and
/// Assistant roles.
/// Please note <see cref="ChatRequestMessage"/> is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes.
/// The available derived classes include <see cref="ChatRequestAssistantMessage"/>, <see cref="ChatRequestSystemMessage"/>, <see cref="ChatRequestToolMessage"/> and <see cref="ChatRequestUserMessage"/>.
/// </summary>
public IList<ChatRequestMessage> Messages { get; set; }

/// <summary> Initializes a new instance of <see cref="ChatCompletionsOptions"/>. </summary>
public ChatCompletionsOptions()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.AI.Inference
{
public partial class ChatCompletionsToolCall
Expand All @@ -22,5 +24,30 @@ public string Arguments
get => Function.Arguments;
set => Function.Arguments = value;
}

/// <summary> Creates a new <see cref="ChatCompletionsToolCall"/> representing a function call made by the model. </summary>
/// <param name="toolCallId"> The ID of the tool call. </param>
/// <param name="functionName"> The name of the function that model is calling. </param>
/// <param name="functionArguments">
/// The arguments that model is calling the function with, which are generated by the model in JSON format.
/// Note that the model does not always generate valid JSON, and may hallucinate parameters not defined by your
/// function schema. Validate the arguments in your code before calling your function.
/// </param>
/// <exception cref="ArgumentNullException"> <paramref name="toolCallId"/>, <paramref name="functionName"/> or <paramref name="functionArguments"/> is null. </exception>
/// <exception cref="ArgumentException"> <paramref name="toolCallId"/>, <paramref name="functionName"/> or <paramref name="functionArguments"/> is an empty string, and was expected to be non-empty. </exception>
public static ChatCompletionsToolCall CreateFunctionToolCall(string toolCallId, string functionName, string functionArguments)
{
Argument.AssertNotNullOrEmpty(toolCallId, nameof(toolCallId));
Argument.AssertNotNullOrEmpty(functionName, nameof(functionName));
Argument.AssertNotNullOrEmpty(functionArguments, nameof(functionArguments));

FunctionCall function = new(functionName, functionArguments);

return new(
id: toolCallId,
type: ChatCompletionsToolCallType.Function,
function: function,
serializedAdditionalRawData: null);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;

namespace Azure.AI.Inference
{
/// <summary>
/// Represents an update to a single prompt completion when the service is streaming updates
/// using Server Sent Events (SSE).
/// Generally, `n` choices are generated per provided prompt with a default value of 1.
/// Token limits and other settings may limit the number of choices generated.
/// </summary>
public partial class StreamingChatChoiceUpdate
{
/// <summary> An update to the chat message for a given chat completions prompt. </summary>
public StreamingChatResponseMessageUpdate Delta { get; } = StreamingChatResponseMessageUpdate.Empty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal static List<StreamingChatCompletionsUpdate> DeserializeStreamingChatCom
string model = default;
DateTimeOffset created = default;
string systemFingerprint = null;
List<StreamingChoiceData> choiceEntries = new();
List<StreamingChatChoiceUpdate> choiceEntries = new();

foreach (JsonProperty property in element.EnumerateObject())
{
Expand Down Expand Up @@ -53,36 +53,33 @@ internal static List<StreamingChatCompletionsUpdate> DeserializeStreamingChatCom
{
foreach (JsonElement choiceElement in property.Value.EnumerateArray())
{
choiceEntries.Add(StreamingChoiceData.DeserializeStreamingChoiceData(choiceElement));
choiceEntries.Add(StreamingChatChoiceUpdate.DeserializeStreamingChatChoiceUpdate(choiceElement));
}
}
}

// If a chunk has no choices, we infer an empty one to aid traversal/expansion
if (choiceEntries.Count == 0)
{
choiceEntries.Add(StreamingChoiceData.Empty);
choiceEntries.Add(new StreamingChatChoiceUpdate());
}

// We inflate the possible combination of information into one StreamingChatCompletionsUpdate per tool
// call update per choice, inferring an empty item in cases where the dimension isn't populated.

List<StreamingChatCompletionsUpdate> results = new();

foreach (StreamingChoiceData choiceData in choiceEntries)
foreach (StreamingChatChoiceUpdate choiceData in choiceEntries)
{
foreach (StreamingToolCallUpdate toolCallUpdate in choiceData.Delta.ToolCallUpdates)
foreach (StreamingChatResponseToolCallUpdate toolCallUpdate in choiceData.Delta.ToolCalls)
{
results.Add(new(
id,
model,
created,
choiceData.Delta.Role,
choiceData.Delta.AuthorName,
choiceData.Delta.ContentUpdate,
choiceData.Delta.Content,
choiceData.FinishReason,
choiceData.Delta.FunctionName,
choiceData.Delta.FunctionArgumentsUpdate,
toolCallUpdate));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,65 +68,19 @@ public partial class StreamingChatCompletionsUpdate
/// </remarks>
public string ContentUpdate { get; }

/// <summary>
/// Gets the name of a function to be called.
/// </summary>
/// <remarks>
/// Corresponds to e.g. $.choices[0].delta.function_call.name in the underlying REST schema.
/// </remarks>
public string FunctionName { get; }

/// <summary>
/// Gets a function arguments fragment associated with this update.
/// </summary>
/// <remarks>
/// <para>
/// Corresponds to e.g. $.choices[0].delta.function_call.arguments in the underlying REST schema.
/// </para>
///
/// <para>
/// Each update contains only a small number of tokens. When presenting or reconstituting a full, streamed
/// arguments body, all <see cref="FunctionArgumentsUpdate"/> values for the same index should be combined.
/// </para>
///
/// <para>
/// As is the case for non-streaming <see cref="FunctionCall.Arguments"/>, the content provided for function
/// arguments is not guaranteed to be well-formed JSON or to contain expected data. Callers should validate
/// function arguments before using them.
/// </para>
/// </remarks>
public string FunctionArgumentsUpdate { get; }

/// <summary>
/// An incremental update payload for a tool call that is part of this response.
/// </summary>
/// <remarks>
/// <para>
/// Corresponds to e.g. $.choices[0].delta.tool_calls[0].index in the REST API schema.
/// Corresponds to e.g. $.choices[0].delta.tool_calls[0] in the REST API schema.
/// </para>
/// <para>
/// To differentiate between parallel streaming tool calls within a single streaming choice, use the value of the
/// <see cref="StreamingToolCallUpdate.ToolCallIndex"/> property.
/// </para>
/// <para>
/// Please note <see cref="StreamingToolCallUpdate"/> is the base class. According to the scenario, a derived class
/// of the base class might need to be assigned here, or this property needs to be casted to one of the possible
/// derived classes.
/// The available derived classes include: <see cref="StreamingFunctionToolCallUpdate"/>.
/// </para>
/// </remarks>
public StreamingToolCallUpdate ToolCallUpdate { get; }

/// <summary>
/// Gets an optional name associated with the role of the streamed Chat Completion, typically as previously
/// specified in a system message.
/// </summary>
/// <remarks>
/// <para>
/// Corresponds to e.g. $.choices[0].delta.name in the underlying REST schema.
/// <see cref="StreamingChatResponseToolCallUpdate.Id"/> property.
/// </para>
/// </remarks>
public string AuthorName { get; }
public StreamingChatResponseToolCallUpdate ToolCallUpdate { get; }

/// <summary>
/// Gets the <see cref="CompletionsFinishReason"/> associated with this update.
Expand All @@ -147,22 +101,16 @@ internal StreamingChatCompletionsUpdate(
string model,
DateTimeOffset created,
ChatRole? role = null,
string authorName = null,
string contentUpdate = null,
CompletionsFinishReason? finishReason = null,
string functionName = null,
string functionArgumentsUpdate = null,
StreamingToolCallUpdate toolCallUpdate = null)
StreamingChatResponseToolCallUpdate toolCallUpdate = null)
{
Id = id;
Model = model;
Created = created;
Role = role;
AuthorName = authorName;
ContentUpdate = contentUpdate;
FinishReason = finishReason;
FunctionName = functionName;
FunctionArgumentsUpdate = functionArgumentsUpdate;
ToolCallUpdate = toolCallUpdate;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.ClientModel.Primitives;
using System.Collections.Generic;
using System.Text.Json;
using Azure.Core;

namespace Azure.AI.Inference
{
public partial class StreamingChatResponseMessageUpdate : IUtf8JsonSerializable, IJsonModel<StreamingChatResponseMessageUpdate>
{
internal static StreamingChatResponseMessageUpdate DeserializeStreamingChatResponseMessageUpdate(JsonElement element, ModelReaderWriterOptions options = null)
{
options ??= ModelSerializationExtensions.WireOptions;

if (element.ValueKind == JsonValueKind.Null)
{
return null;
}
ChatRole? role = default;
string content = default;
List<StreamingChatResponseToolCallUpdate> toolCalls = new List<StreamingChatResponseToolCallUpdate>();
IDictionary<string, BinaryData> serializedAdditionalRawData = default;
Dictionary<string, BinaryData> rawDataDictionary = new Dictionary<string, BinaryData>();
foreach (var property in element.EnumerateObject())
{
if (property.NameEquals("role"u8))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
continue;
}
role = new ChatRole(property.Value.GetString());
continue;
}
if (property.NameEquals("content"u8))
{
content = property.Value.GetString();
continue;
}
if (property.NameEquals("tool_calls"u8))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
continue;
}
List<StreamingChatResponseToolCallUpdate> array = new List<StreamingChatResponseToolCallUpdate>();
foreach (var item in property.Value.EnumerateArray())
{
array.Add(StreamingChatResponseToolCallUpdate.DeserializeStreamingChatResponseToolCallUpdate(item, options));
}
toolCalls = array;
continue;
}
if (options.Format != "W")
{
rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText()));
}
}
serializedAdditionalRawData = rawDataDictionary;

if (toolCalls.Count == 0)
{
toolCalls.Add(null);
}

return new StreamingChatResponseMessageUpdate(role, content, toolCalls, serializedAdditionalRawData);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using static Azure.AI.Inference.StreamingChatCompletionsUpdate;

namespace Azure.AI.Inference
{
/// <summary> A representation of a chat message update as received in a streaming response. </summary>
public partial class StreamingChatResponseMessageUpdate
{
/// <summary>
/// The tool calls that must be resolved and have their outputs appended to subsequent input messages for the chat
/// completions request to resolve as configured.
/// </summary>
public IReadOnlyList<StreamingChatResponseToolCallUpdate> ToolCalls { get; set; } = new List<StreamingChatResponseToolCallUpdate>();

internal static StreamingChatResponseMessageUpdate Empty { get; } = new()
{
ToolCalls = new List<StreamingChatResponseToolCallUpdate>() { null },
};
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading