diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatCompletion.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatCompletion.cs index 2cebeb71c27..689bca9c4da 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatCompletion.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatCompletion.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Text; using System.Text.Json.Serialization; using Microsoft.Shared.Diagnostics; @@ -85,8 +86,26 @@ public ChatMessage Message public AdditionalPropertiesDictionary? AdditionalProperties { get; set; } /// - public override string ToString() => - Choices is { Count: > 0 } choices ? string.Join(Environment.NewLine, choices) : string.Empty; + public override string ToString() + { + if (Choices.Count == 1) + { + return Choices[0].ToString(); + } + + StringBuilder sb = new(); + for (int i = 0; i < Choices.Count; i++) + { + if (i > 0) + { + _ = sb.AppendLine().AppendLine(); + } + + _ = sb.Append("Choice ").Append(i).AppendLine(":").Append(Choices[i]); + } + + return sb.ToString(); + } /// Creates an array of instances that represent this . /// An array of instances that may be used to represent this . diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatMessage.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatMessage.cs index ccbc1cae97b..6370319704b 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatMessage.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatMessage.cs @@ -95,5 +95,6 @@ public IList Contents public AdditionalPropertiesDictionary? AdditionalProperties { get; set; } /// - public override string ToString() => Text ?? string.Empty; + public override string ToString() => + string.Concat(Contents.OfType()); } diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs index f63381c5757..9978e0f29b7 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/StreamingChatCompletionUpdate.cs @@ -116,5 +116,6 @@ public IList Contents public string? ModelId { get; set; } /// - public override string ToString() => Text ?? string.Empty; + public override string ToString() => + string.Concat(Contents.OfType()); } diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatCompletionTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatCompletionTests.cs index 35184f3ee5a..15134782bd7 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatCompletionTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatCompletionTests.cs @@ -168,6 +168,40 @@ public void JsonSerialization_Roundtrips() Assert.Equal("value", ((JsonElement)value!).GetString()); } + [Fact] + public void ToString_OneChoice_OutputsChatMessageToString() + { + ChatCompletion completion = new( + [ + new ChatMessage(ChatRole.Assistant, "This is a test." + Environment.NewLine + "It's multiple lines.") + ]); + + Assert.Equal(completion.Choices[0].Text, completion.ToString()); + } + + [Fact] + public void ToString_MultipleChoices_OutputsAllChoicesWithPrefix() + { + ChatCompletion completion = new( + [ + new ChatMessage(ChatRole.Assistant, "This is a test." + Environment.NewLine + "It's multiple lines."), + new ChatMessage(ChatRole.Assistant, "So is" + Environment.NewLine + " this."), + new ChatMessage(ChatRole.Assistant, "And this."), + ]); + + Assert.Equal( + "Choice 0:" + Environment.NewLine + + completion.Choices[0] + Environment.NewLine + Environment.NewLine + + + "Choice 1:" + Environment.NewLine + + completion.Choices[1] + Environment.NewLine + Environment.NewLine + + + "Choice 2:" + Environment.NewLine + + completion.Choices[2], + + completion.ToString()); + } + [Fact] public void ToStreamingChatCompletionUpdates_SingleChoice() { 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 31336e70674..d1325b89bb7 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatMessageTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatMessageTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using Xunit; @@ -91,7 +92,7 @@ public void Constructor_RoleList_PropsRoundtrip(int messageCount) } Assert.Equal("text-0", message.Text); - Assert.Equal("text-0", message.ToString()); + Assert.Equal(string.Concat(Enumerable.Range(0, messageCount).Select(i => $"text-{i}")), message.ToString()); } Assert.Null(message.AuthorName); @@ -134,13 +135,13 @@ public void Text_GetSet_UsesFirstTextContent() TextContent textContent = Assert.IsType(message.Contents[3]); Assert.Equal("text-1", textContent.Text); Assert.Equal("text-1", message.Text); - Assert.Equal("text-1", message.ToString()); + Assert.Equal("text-1text-2", message.ToString()); message.Text = "text-3"; Assert.Equal("text-3", message.Text); Assert.Equal("text-3", message.Text); Assert.Same(textContent, message.Contents[3]); - Assert.Equal("text-3", message.ToString()); + Assert.Equal("text-3text-2", message.ToString()); } [Fact] diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/StreamingChatCompletionUpdateTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/StreamingChatCompletionUpdateTests.cs index f90f799c6f9..a54ca225a98 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/StreamingChatCompletionUpdateTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/StreamingChatCompletionUpdateTests.cs @@ -103,13 +103,13 @@ public void Text_GetSet_UsesFirstTextContent() TextContent textContent = Assert.IsType(update.Contents[3]); Assert.Equal("text-1", textContent.Text); Assert.Equal("text-1", update.Text); - Assert.Equal("text-1", update.ToString()); + Assert.Equal("text-1text-2", update.ToString()); update.Text = "text-3"; Assert.Equal("text-3", update.Text); Assert.Equal("text-3", update.Text); Assert.Same(textContent, update.Contents[3]); - Assert.Equal("text-3", update.ToString()); + Assert.Equal("text-3text-2", update.ToString()); } [Fact]