Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.SemanticKernel.Agents.OpenAI.Internal;
using Microsoft.SemanticKernel.ChatCompletion;
using OpenAI.Assistants;
using OpenAI.Responses;

Expand Down Expand Up @@ -44,7 +45,7 @@ public static IEnumerable<ThreadInitializationMessage> ToThreadInitializationMes
public static ResponseItem ToResponseItem(this ChatMessageContent message)
{
var items = message.Items;
IEnumerable<ResponseContentPart> contentParts = items.Select(item => item.ToResponseContentPart());
IEnumerable<ResponseContentPart> contentParts = items.Select(item => item.ToResponseContentPart(message.Role == AuthorRole.Assistant ? message.Role : null));
return message.Role.Label.ToUpperInvariant() switch
{
"SYSTEM" => ResponseItem.CreateSystemMessageItem(contentParts),
Expand Down
11 changes: 8 additions & 3 deletions dotnet/src/Agents/OpenAI/Extensions/KernelContentExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using Microsoft.SemanticKernel.ChatCompletion;
using OpenAI.Responses;

namespace Microsoft.SemanticKernel.Agents.OpenAI;
Expand All @@ -10,20 +11,24 @@ namespace Microsoft.SemanticKernel.Agents.OpenAI;
/// </summary>
internal static class KernelContentExtensions
{
internal static ResponseContentPart ToResponseContentPart(this KernelContent content)
internal static ResponseContentPart ToResponseContentPart(this KernelContent content, AuthorRole? role = null)
{
return content switch
{
TextContent textContent => textContent.ToResponseContentPart(),
TextContent textContent => textContent.ToResponseContentPart(role),
ImageContent imageContent => imageContent.ToResponseContentPart(),
BinaryContent binaryContent => binaryContent.ToResponseContentPart(),
FileReferenceContent fileReferenceContent => fileReferenceContent.ToResponseContentPart(),
_ => throw new NotSupportedException($"Unsupported content type {content.GetType().Name}. Cannot convert to {nameof(ResponseContentPart)}.")
};
}

internal static ResponseContentPart ToResponseContentPart(this TextContent content)
internal static ResponseContentPart ToResponseContentPart(this TextContent content, AuthorRole? role = null)
{
if (role is not null && role == AuthorRole.Assistant)
{
return ResponseContentPart.CreateOutputTextPart(content.Text, []);
}
return ResponseContentPart.CreateInputTextPart(content.Text);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,14 @@ public void VerifyToResponseItemWithUserChatMessageContent(string roleLabel)
Assert.Equal(role.Label.ToUpperInvariant(), messageResponseItem.Role.ToString().ToUpperInvariant());
Assert.Equal(4, messageResponseItem.Content.Count);

// Validate TextContent conversion - should create InputText part
var textContent = messageResponseItem.Content.FirstOrDefault(p => p.Kind == ResponseContentPartKind.InputText);
// Determine expected kind for text content based on role
var expectedTextKind = roleLabel.Equals("assistant", StringComparison.OrdinalIgnoreCase)
? ResponseContentPartKind.OutputText
: ResponseContentPartKind.InputText;

// Validate TextContent conversion - should create appropriate Input/OutputText part
var textContent = messageResponseItem.Content.FirstOrDefault(p => p.Kind == expectedTextKind);
Assert.NotNull(textContent);
//Assert.IsType<>(textContent);
Assert.Equal("What is in this image?", textContent.Text);

// Validate ImageContent conversion - should create InputImage part
Expand Down
Loading