From 651546f3a0c296b5a581bfa4a472f5bb50ba28cc Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 21 Oct 2024 21:51:57 -0400 Subject: [PATCH] Remove AIContent.ModelId, add StreamingChatCompletionUpdate.ModelId (#5535) --- .../StreamingChatCompletionUpdate.cs | 3 +++ .../Contents/AIContent.cs | 5 ----- .../AzureAIInferenceChatClient.cs | 12 +++--------- .../OllamaChatClient.cs | 9 +++++---- .../OpenAIChatClient.cs | 19 ++++++------------- .../ChatCompletion/CachingChatClient.cs | 7 +++---- .../ChatCompletion/OpenTelemetryChatClient.cs | 2 +- .../ChatCompletion/ChatMessageTests.cs | 12 ------------ .../Contents/AIContentTests.cs | 5 ----- .../Contents/DataContentTests{T}.cs | 1 - .../Contents/FunctionCallContentTests..cs | 10 ++-------- .../Contents/FunctionResultContentTests.cs | 6 ------ .../Contents/TextContentTests.cs | 5 ----- .../Contents/UsageContentTests.cs | 2 -- .../AzureAIInferenceChatClientTests.cs | 4 ++-- .../OllamaChatClientTests.cs | 2 +- .../OpenAIChatClientTests.cs | 4 ++-- .../DistributedCachingChatClientTest.cs | 5 +---- 18 files changed, 29 insertions(+), 84 deletions(-) diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs index 8192e017f7e..278d875258a 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs @@ -91,6 +91,9 @@ public IList Contents /// Gets or sets the finish reason for the operation. public ChatFinishReason? FinishReason { get; set; } + /// Gets or sets the model ID using in the creation of the chat completion of which this update is a part. + public string? ModelId { get; set; } + /// public override string ToString() => Text ?? string.Empty; } diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/AIContent.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/AIContent.cs index 456ee4940c2..29fd405b947 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/AIContent.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/AIContent.cs @@ -32,11 +32,6 @@ protected AIContent() [JsonIgnore] public object? RawRepresentation { get; set; } - /// - /// Gets or sets the model ID used to generate the content. - /// - public string? ModelId { get; set; } - /// Gets or sets additional properties for the content. public AdditionalPropertiesDictionary? AdditionalProperties { get; set; } } diff --git a/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs b/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs index 784e0388a1b..23d98dfd4bb 100644 --- a/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs @@ -97,7 +97,6 @@ public async Task CompleteAsync( if (toolCall is ChatCompletionsFunctionToolCall ftc && !string.IsNullOrWhiteSpace(ftc.Name)) { FunctionCallContent callContent = ParseCallContentFromJsonString(ftc.Arguments, toolCall.Id, ftc.Name); - callContent.ModelId = response.Model; callContent.RawRepresentation = toolCall; returnMessage.Contents.Add(callContent); @@ -109,7 +108,6 @@ public async Task CompleteAsync( { returnMessage.Contents.Add(new TextContent(choice.Message.Content) { - ModelId = response.Model, RawRepresentation = choice.Message }); } @@ -173,6 +171,7 @@ public async IAsyncEnumerable CompleteStreamingAs CompletionId = chatCompletionUpdate.Id, CreatedAt = chatCompletionUpdate.Created, FinishReason = finishReason, + ModelId = modelId, RawRepresentation = chatCompletionUpdate, Role = streamedRole, }; @@ -180,10 +179,7 @@ public async IAsyncEnumerable CompleteStreamingAs // Transfer over content update items. if (chatCompletionUpdate.ContentUpdate is string update) { - completionUpdate.Contents.Add(new TextContent(update) - { - ModelId = modelId, - }); + completionUpdate.Contents.Add(new TextContent(update)); } // Transfer over tool call updates. @@ -218,6 +214,7 @@ public async IAsyncEnumerable CompleteStreamingAs CompletionId = completionId, CreatedAt = createdAt, FinishReason = finishReason, + ModelId = modelId, Role = streamedRole, }; @@ -230,9 +227,6 @@ public async IAsyncEnumerable CompleteStreamingAs fci.Arguments?.ToString() ?? string.Empty, fci.CallId!, fci.Name!); - - callContent.ModelId = modelId; - completionUpdate.Contents.Add(callContent); } } diff --git a/src/Libraries/Microsoft.Extensions.AI.Ollama/OllamaChatClient.cs b/src/Libraries/Microsoft.Extensions.AI.Ollama/OllamaChatClient.cs index 22ff6db6dab..d37a0a3f85c 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Ollama/OllamaChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Ollama/OllamaChatClient.cs @@ -125,24 +125,25 @@ public async IAsyncEnumerable CompleteStreamingAs continue; } + string? modelId = chunk.Model ?? Metadata.ModelId; + StreamingChatCompletionUpdate update = new() { Role = chunk.Message?.Role is not null ? new ChatRole(chunk.Message.Role) : null, CreatedAt = DateTimeOffset.TryParse(chunk.CreatedAt, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTimeOffset createdAt) ? createdAt : null, AdditionalProperties = ParseOllamaChatResponseProps(chunk), FinishReason = ToFinishReason(chunk), + ModelId = modelId, }; - string? modelId = chunk.Model ?? Metadata.ModelId; - if (chunk.Message is { } message) { - update.Contents.Add(new TextContent(message.Content) { ModelId = modelId }); + update.Contents.Add(new TextContent(message.Content)); } if (ParseOllamaChatResponseUsage(chunk) is { } usage) { - update.Contents.Add(new UsageContent(usage) { ModelId = modelId }); + update.Contents.Add(new UsageContent(usage)); } yield return update; diff --git a/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs b/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs index 50c9b43c58b..d97011b3e27 100644 --- a/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs @@ -111,7 +111,7 @@ public async Task CompleteAsync( // Populate its content from those in the OpenAI response content. foreach (ChatMessageContentPart contentPart in response.Content) { - if (ToAIContent(contentPart, response.Model) is AIContent aiContent) + if (ToAIContent(contentPart) is AIContent aiContent) { returnMessage.Contents.Add(aiContent); } @@ -125,7 +125,6 @@ public async Task CompleteAsync( if (!string.IsNullOrWhiteSpace(toolCall.FunctionName)) { var callContent = ParseCallContentFromBinaryData(toolCall.FunctionArguments, toolCall.Id, toolCall.FunctionName); - callContent.ModelId = response.Model; callContent.RawRepresentation = toolCall; returnMessage.Contents.Add(callContent); @@ -214,6 +213,7 @@ public async IAsyncEnumerable CompleteStreamingAs CompletionId = chatCompletionUpdate.CompletionId, CreatedAt = chatCompletionUpdate.CreatedAt, FinishReason = finishReason, + ModelId = modelId, RawRepresentation = chatCompletionUpdate, Role = streamedRole, }; @@ -239,7 +239,7 @@ public async IAsyncEnumerable CompleteStreamingAs { foreach (ChatMessageContentPart contentPart in chatCompletionUpdate.ContentUpdate) { - if (ToAIContent(contentPart, modelId) is AIContent aiContent) + if (ToAIContent(contentPart) is AIContent aiContent) { completionUpdate.Contents.Add(aiContent); } @@ -292,10 +292,7 @@ public async IAsyncEnumerable CompleteStreamingAs // TODO: Add support for prompt token details (e.g. cached tokens) once it's exposed in OpenAI library. - completionUpdate.Contents.Add(new UsageContent(usageDetails) - { - ModelId = modelId - }); + completionUpdate.Contents.Add(new UsageContent(usageDetails)); } // Now yield the item. @@ -310,6 +307,7 @@ public async IAsyncEnumerable CompleteStreamingAs CompletionId = completionId, CreatedAt = createdAt, FinishReason = finishReason, + ModelId = modelId, Role = streamedRole, }; @@ -322,9 +320,6 @@ public async IAsyncEnumerable CompleteStreamingAs fci.Arguments?.ToString() ?? string.Empty, fci.CallId!, fci.Name!); - - callContent.ModelId = modelId; - completionUpdate.Contents.Add(callContent); } } @@ -531,9 +526,8 @@ private sealed class OpenAIChatToolJson /// Creates an from a . /// The content part to convert into a content. - /// The model ID. /// The constructed , or null if the content part could not be converted. - private static AIContent? ToAIContent(ChatMessageContentPart contentPart, string? modelId) + private static AIContent? ToAIContent(ChatMessageContentPart contentPart) { AIContent? aiContent = null; @@ -564,7 +558,6 @@ private sealed class OpenAIChatToolJson (additionalProperties ??= [])[nameof(contentPart.Refusal)] = refusal; } - aiContent.ModelId = modelId; aiContent.AdditionalProperties = additionalProperties; aiContent.RawRepresentation = contentPart; } diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/CachingChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/CachingChatClient.cs index a12061a1028..ad620346172 100644 --- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/CachingChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/CachingChatClient.cs @@ -130,7 +130,6 @@ next.Contents[0] is not TextContent || TextContent coalescedContent = new(null) // will patch the text after examining all items in the run { AdditionalProperties = textContent.AdditionalProperties?.Clone(), - ModelId = textContent.ModelId, }; StreamingChatCompletionUpdate coalesced = new() @@ -141,6 +140,7 @@ next.Contents[0] is not TextContent || Contents = [coalescedContent], CreatedAt = update.CreatedAt, FinishReason = update.FinishReason, + ModelId = update.ModelId, Role = update.Role, // Explicitly don't include RawRepresentation. It's not applicable if one update ends up being used @@ -160,16 +160,15 @@ next.Contents[0] is not TextContent || StreamingChatCompletionUpdate next = capturedItems[i]; capturedItems[i] = null!; - TextContent nextContent = (TextContent)next.Contents[0]; + var nextContent = (TextContent)next.Contents[0]; _ = coalescedText.Append(nextContent.Text); coalesced.AuthorName ??= next.AuthorName; coalesced.CompletionId ??= next.CompletionId; coalesced.CreatedAt ??= next.CreatedAt; coalesced.FinishReason ??= next.FinishReason; + coalesced.ModelId ??= next.ModelId; coalesced.Role ??= next.Role; - - coalescedContent.ModelId ??= nextContent.ModelId; } // Complete the coalescing by patching the text of the coalesced node. diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs index 46e26bea181..905e756e246 100644 --- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs @@ -230,7 +230,7 @@ private static ChatCompletion ComposeStreamingUpdatesIntoChatCompletion( finishReason ??= update.FinishReason; role ??= update.Role; items.AddRange(update.Contents); - modelId ??= update.Contents.FirstOrDefault(c => c.ModelId is not null)?.ModelId; + modelId ??= update.ModelId; } messages.Add(new ChatMessage(role ?? ChatRole.Assistant, items)); diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatMessageTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatMessageTests.cs index e05e0d0ef47..31336e70674 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatMessageTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatMessageTests.cs @@ -262,32 +262,26 @@ public void ItCanBeSerializeAndDeserialized() [ new TextContent("content-1") { - ModelId = "model-1", AdditionalProperties = new() { ["metadata-key-1"] = "metadata-value-1" } }, new ImageContent(new Uri("https://fake-random-test-host:123"), "mime-type/2") { - ModelId = "model-2", AdditionalProperties = new() { ["metadata-key-2"] = "metadata-value-2" } }, new DataContent(new BinaryData(new[] { 1, 2, 3 }, options: TestJsonSerializerContext.Default.Options), "mime-type/3") { - ModelId = "model-3", AdditionalProperties = new() { ["metadata-key-3"] = "metadata-value-3" } }, new AudioContent(new BinaryData(new[] { 3, 2, 1 }, options: TestJsonSerializerContext.Default.Options), "mime-type/4") { - ModelId = "model-4", AdditionalProperties = new() { ["metadata-key-4"] = "metadata-value-4" } }, new ImageContent(new BinaryData(new[] { 2, 1, 3 }, options: TestJsonSerializerContext.Default.Options), "mime-type/5") { - ModelId = "model-5", AdditionalProperties = new() { ["metadata-key-5"] = "metadata-value-5" } }, new TextContent("content-6") { - ModelId = "model-6", AdditionalProperties = new() { ["metadata-key-6"] = "metadata-value-6" } }, new FunctionCallContent("function-id", "plugin-name-function-name", new Dictionary { ["parameter"] = "argument" }), @@ -317,7 +311,6 @@ public void ItCanBeSerializeAndDeserialized() var textContent = deserializedMessage.Contents[0] as TextContent; Assert.NotNull(textContent); Assert.Equal("content-1-override", textContent.Text); - Assert.Equal("model-1", textContent.ModelId); Assert.NotNull(textContent.AdditionalProperties); Assert.Single(textContent.AdditionalProperties); Assert.Equal("metadata-value-1", textContent.AdditionalProperties["metadata-key-1"]?.ToString()); @@ -325,7 +318,6 @@ public void ItCanBeSerializeAndDeserialized() var imageContent = deserializedMessage.Contents[1] as ImageContent; Assert.NotNull(imageContent); Assert.Equal("https://fake-random-test-host:123/", imageContent.Uri); - Assert.Equal("model-2", imageContent.ModelId); Assert.Equal("mime-type/2", imageContent.MediaType); Assert.NotNull(imageContent.AdditionalProperties); Assert.Single(imageContent.AdditionalProperties); @@ -334,7 +326,6 @@ public void ItCanBeSerializeAndDeserialized() var dataContent = deserializedMessage.Contents[2] as DataContent; Assert.NotNull(dataContent); Assert.True(dataContent.Data!.Value.Span.SequenceEqual(new BinaryData(new[] { 1, 2, 3 }, TestJsonSerializerContext.Default.Options))); - Assert.Equal("model-3", dataContent.ModelId); Assert.Equal("mime-type/3", dataContent.MediaType); Assert.NotNull(dataContent.AdditionalProperties); Assert.Single(dataContent.AdditionalProperties); @@ -343,7 +334,6 @@ public void ItCanBeSerializeAndDeserialized() var audioContent = deserializedMessage.Contents[3] as AudioContent; Assert.NotNull(audioContent); Assert.True(audioContent.Data!.Value.Span.SequenceEqual(new BinaryData(new[] { 3, 2, 1 }, TestJsonSerializerContext.Default.Options))); - Assert.Equal("model-4", audioContent.ModelId); Assert.Equal("mime-type/4", audioContent.MediaType); Assert.NotNull(audioContent.AdditionalProperties); Assert.Single(audioContent.AdditionalProperties); @@ -352,7 +342,6 @@ public void ItCanBeSerializeAndDeserialized() imageContent = deserializedMessage.Contents[4] as ImageContent; Assert.NotNull(imageContent); Assert.True(imageContent.Data?.Span.SequenceEqual(new BinaryData(new[] { 2, 1, 3 }, TestJsonSerializerContext.Default.Options))); - Assert.Equal("model-5", imageContent.ModelId); Assert.Equal("mime-type/5", imageContent.MediaType); Assert.NotNull(imageContent.AdditionalProperties); Assert.Single(imageContent.AdditionalProperties); @@ -361,7 +350,6 @@ public void ItCanBeSerializeAndDeserialized() textContent = deserializedMessage.Contents[5] as TextContent; Assert.NotNull(textContent); Assert.Equal("content-6", textContent.Text); - Assert.Equal("model-6", textContent.ModelId); Assert.NotNull(textContent.AdditionalProperties); Assert.Single(textContent.AdditionalProperties); Assert.Equal("metadata-value-6", textContent.AdditionalProperties["metadata-key-6"]?.ToString()); diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/AIContentTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/AIContentTests.cs index ece02f017bb..027fd61649c 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/AIContentTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/AIContentTests.cs @@ -12,7 +12,6 @@ public void Constructor_PropsDefault() { DerivedAIContent c = new(); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); } @@ -26,10 +25,6 @@ public void Constructor_PropsRoundtrip() c.RawRepresentation = raw; Assert.Same(raw, c.RawRepresentation); - Assert.Null(c.ModelId); - c.ModelId = "modelId"; - Assert.Equal("modelId", c.ModelId); - Assert.Null(c.AdditionalProperties); AdditionalPropertiesDictionary props = new() { { "key", "value" } }; c.AdditionalProperties = props; diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/DataContentTests{T}.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/DataContentTests{T}.cs index ea3017cf7ea..b34f6da0255 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/DataContentTests{T}.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/DataContentTests{T}.cs @@ -192,7 +192,6 @@ public void Deserialize_MatchesExpectedData() Assert.Equal([0x01, 0x02, 0x03, 0x04], content.Data!.Value.ToArray()); Assert.Equal("text/plain", content.MediaType); Assert.True(content.ContainsData); - Assert.Equal("gpt-4", content.ModelId); Assert.Equal("value", content.AdditionalProperties!["key"]!.ToString()); } diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs index 50ca205197d..49ff719f8b5 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs @@ -21,7 +21,6 @@ public void Constructor_PropsDefault() FunctionCallContent c = new("callId1", "name"); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.Equal("callId1", c.CallId); @@ -39,7 +38,6 @@ public void Constructor_ArgumentsRoundtrip() FunctionCallContent c = new("id", "name", args); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.Equal("name", c.Name); @@ -57,10 +55,6 @@ public void Constructor_PropsRoundtrip() c.RawRepresentation = raw; Assert.Same(raw, c.RawRepresentation); - Assert.Null(c.ModelId); - c.ModelId = "modelId"; - Assert.Equal("modelId", c.ModelId); - Assert.Null(c.AdditionalProperties); AdditionalPropertiesDictionary props = new() { { "key", "value" } }; c.AdditionalProperties = props; @@ -322,8 +316,8 @@ public static void CreateFromParsedArguments_ObjectJsonInput_ReturnsElementArgum [InlineData(typeof(NotSupportedException))] public static void CreateFromParsedArguments_ParseException_HasExpectedHandling(Type exceptionType) { - Exception exc = (Exception)Activator.CreateInstance(exceptionType)!; - FunctionCallContent content = FunctionCallContent.CreateFromParsedArguments(exc, "callId", "functionName", ThrowingParser); + var exc = (Exception)Activator.CreateInstance(exceptionType)!; + var content = FunctionCallContent.CreateFromParsedArguments(exc, "callId", "functionName", ThrowingParser); Assert.Equal("functionName", content.Name); Assert.Equal("callId", content.CallId); diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionResultContentTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionResultContentTests.cs index 10a23c69596..ef3382b430e 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionResultContentTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionResultContentTests.cs @@ -16,7 +16,6 @@ public void Constructor_PropsDefault() Assert.Equal("callId1", c.CallId); Assert.Equal("functionName", c.Name); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.Null(c.Result); Assert.Null(c.Exception); @@ -27,7 +26,6 @@ public void Constructor_String_PropsRoundtrip() { FunctionResultContent c = new("id", "name", "result"); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.Equal("name", c.Name); Assert.Equal("id", c.CallId); @@ -45,10 +43,6 @@ public void Constructor_PropsRoundtrip() c.RawRepresentation = raw; Assert.Same(raw, c.RawRepresentation); - Assert.Null(c.ModelId); - c.ModelId = "modelId"; - Assert.Equal("modelId", c.ModelId); - Assert.Null(c.AdditionalProperties); AdditionalPropertiesDictionary props = new() { { "key", "value" } }; c.AdditionalProperties = props; diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/TextContentTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/TextContentTests.cs index d1ba5e83bc9..456867a2649 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/TextContentTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/TextContentTests.cs @@ -15,7 +15,6 @@ public void Constructor_String_PropsDefault(string? text) { TextContent c = new(text); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.Equal(text, c.Text); } @@ -30,10 +29,6 @@ public void Constructor_PropsRoundtrip() c.RawRepresentation = raw; Assert.Same(raw, c.RawRepresentation); - Assert.Null(c.ModelId); - c.ModelId = "modelId"; - Assert.Equal("modelId", c.ModelId); - Assert.Null(c.AdditionalProperties); AdditionalPropertiesDictionary props = new() { { "key", "value" } }; c.AdditionalProperties = props; diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/UsageContentTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/UsageContentTests.cs index 109bdc8120e..2314cd66f93 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/UsageContentTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/UsageContentTests.cs @@ -19,7 +19,6 @@ public void Constructor_Parameterless_PropsDefault() { UsageContent c = new(); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.NotNull(c.Details); @@ -37,7 +36,6 @@ public void Constructor_UsageDetails_PropsRoundtrip() UsageContent c = new(details); Assert.Null(c.RawRepresentation); - Assert.Null(c.ModelId); Assert.Null(c.AdditionalProperties); Assert.Same(details, c.Details); diff --git a/test/Libraries/Microsoft.Extensions.AI.AzureAIInference.Tests/AzureAIInferenceChatClientTests.cs b/test/Libraries/Microsoft.Extensions.AI.AzureAIInference.Tests/AzureAIInferenceChatClientTests.cs index be628c13d0d..474ead54baf 100644 --- a/test/Libraries/Microsoft.Extensions.AI.AzureAIInference.Tests/AzureAIInferenceChatClientTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.AzureAIInference.Tests/AzureAIInferenceChatClientTests.cs @@ -201,7 +201,7 @@ public async Task BasicRequestResponse_Streaming() { Assert.Equal("chatcmpl-ADxFKtX6xIwdWRN42QvBj2u1RZpCK", updates[i].CompletionId); Assert.Equal(createdAt, updates[i].CreatedAt); - Assert.All(updates[i].Contents, u => Assert.Equal("gpt-4o-mini-2024-07-18", u.ModelId)); + Assert.Equal("gpt-4o-mini-2024-07-18", updates[i].ModelId); Assert.Equal(ChatRole.Assistant, updates[i].Role); Assert.Equal(i < 10 ? 1 : 0, updates[i].Contents.Count); Assert.Equal(i < 10 ? null : ChatFinishReason.Stop, updates[i].FinishReason); @@ -516,7 +516,7 @@ public async Task FunctionCallContent_Streaming() { Assert.Equal("chatcmpl-ADymNiWWeqCJqHNFXiI1QtRcLuXcl", updates[i].CompletionId); Assert.Equal(createdAt, updates[i].CreatedAt); - Assert.All(updates[i].Contents, u => Assert.Equal("gpt-4o-mini-2024-07-18", u.ModelId)); + Assert.Equal("gpt-4o-mini-2024-07-18", updates[i].ModelId); Assert.Equal(ChatRole.Assistant, updates[i].Role); Assert.Equal(i < 7 ? null : ChatFinishReason.ToolCalls, updates[i].FinishReason); } diff --git a/test/Libraries/Microsoft.Extensions.AI.Ollama.Tests/OllamaChatClientTests.cs b/test/Libraries/Microsoft.Extensions.AI.Ollama.Tests/OllamaChatClientTests.cs index b09947337ed..22fa54391cc 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Ollama.Tests/OllamaChatClientTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Ollama.Tests/OllamaChatClientTests.cs @@ -172,7 +172,7 @@ public async Task BasicRequestResponse_Streaming() { Assert.Equal(i < updates.Count - 1 ? 1 : 2, updates[i].Contents.Count); Assert.Equal(ChatRole.Assistant, updates[i].Role); - Assert.All(updates[i].Contents, u => Assert.Equal("llama3.1", u.ModelId)); + Assert.Equal("llama3.1", updates[i].ModelId); Assert.Equal(createdAts[i], updates[i].CreatedAt); Assert.Equal(i < updates.Count - 1 ? null : ChatFinishReason.Length, updates[i].FinishReason); } diff --git a/test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIChatClientTests.cs b/test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIChatClientTests.cs index adc245c58e8..5175740dc5a 100644 --- a/test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIChatClientTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIChatClientTests.cs @@ -247,7 +247,7 @@ public async Task BasicRequestResponse_Streaming() { Assert.Equal("chatcmpl-ADxFKtX6xIwdWRN42QvBj2u1RZpCK", updates[i].CompletionId); Assert.Equal(createdAt, updates[i].CreatedAt); - Assert.All(updates[i].Contents, u => Assert.Equal("gpt-4o-mini-2024-07-18", u.ModelId)); + Assert.Equal("gpt-4o-mini-2024-07-18", updates[i].ModelId); Assert.Equal(ChatRole.Assistant, updates[i].Role); Assert.NotNull(updates[i].AdditionalProperties); Assert.Equal("fp_f85bea6784", updates[i].AdditionalProperties![nameof(OpenAI.Chat.ChatCompletion.SystemFingerprint)]); @@ -565,7 +565,7 @@ public async Task FunctionCallContent_Streaming() { Assert.Equal("chatcmpl-ADymNiWWeqCJqHNFXiI1QtRcLuXcl", updates[i].CompletionId); Assert.Equal(createdAt, updates[i].CreatedAt); - Assert.All(updates[i].Contents, u => Assert.Equal("gpt-4o-mini-2024-07-18", u.ModelId)); + Assert.Equal("gpt-4o-mini-2024-07-18", updates[i].ModelId); Assert.Equal(ChatRole.Assistant, updates[i].Role); Assert.NotNull(updates[i].AdditionalProperties); Assert.Equal("fp_f85bea6784", updates[i].AdditionalProperties![nameof(OpenAI.Chat.ChatCompletion.SystemFingerprint)]); diff --git a/test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/DistributedCachingChatClientTest.cs b/test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/DistributedCachingChatClientTest.cs index 158c55aee7a..7f6ca20915e 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/DistributedCachingChatClientTest.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/DistributedCachingChatClientTest.cs @@ -330,7 +330,7 @@ public async Task StreamingCoalescingPropagatesMetadataAsync() List expectedCompletion = [ new() { Role = ChatRole.Assistant, Contents = [new TextContent("Hello")] }, - new() { Role = ChatRole.Assistant, Contents = [new TextContent(" world, ") { ModelId = "some model" }] }, + new() { Role = ChatRole.Assistant, Contents = [new TextContent(" world, ")] }, new() { Role = ChatRole.Assistant, @@ -338,7 +338,6 @@ public async Task StreamingCoalescingPropagatesMetadataAsync() [ new TextContent("how ") { - ModelId = "some other model", AdditionalProperties = new() { ["a"] = "b", ["c"] = "d" }, } ] @@ -386,7 +385,6 @@ public async Task StreamingCoalescingPropagatesMetadataAsync() var content = Assert.IsType(Assert.Single(item.Contents)); Assert.Equal("Hello world, how are you?", content.Text); - Assert.Equal("some model", content.ModelId); } [Fact] @@ -717,7 +715,6 @@ private static void AssertCompletionsEqual(ChatCompletion expected, ChatCompleti { var expectedItem = expected.Choices[i].Contents[itemIndex]; var actualItem = actual.Choices[i].Contents[itemIndex]; - Assert.Equal(expectedItem.ModelId, actualItem.ModelId); Assert.IsType(expectedItem.GetType(), actualItem); if (expectedItem is FunctionCallContent expectedFcc)