diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props index aca7a136ddf8..ea8f5087563b 100644 --- a/dotnet/Directory.Packages.props +++ b/dotnet/Directory.Packages.props @@ -2,10 +2,12 @@ true 1.22.0 - 1.22.0-alpha - 9.0.0-preview.9.24525.1 + 1.45.0 + $(MicrosoftSemanticKernelStableVersion)-preview + $(MicrosoftSemanticKernelStableVersion)-alpha + 9.3.0-preview.1.25161.3 9.0.0 - 9.0.0 + 9.0.3 9.0.0 9.0.0 9.0.1 @@ -18,7 +20,7 @@ - + @@ -27,9 +29,10 @@ - + + @@ -100,18 +103,18 @@ - - - - - - + + + + + + - + @@ -127,7 +130,7 @@ - + diff --git a/dotnet/src/AutoGen.Core/Function/FunctionAttribute.cs b/dotnet/src/AutoGen.Core/Function/FunctionAttribute.cs index 9367f5c6f297..644c899c153f 100644 --- a/dotnet/src/AutoGen.Core/Function/FunctionAttribute.cs +++ b/dotnet/src/AutoGen.Core/Function/FunctionAttribute.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; +using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.AI; @@ -69,36 +71,48 @@ public class FunctionContract /// public string? ReturnDescription { get; set; } - public static implicit operator FunctionContract(AIFunctionMetadata metadata) + public static implicit operator FunctionContract(AIFunction function) { - return new FunctionContract + var openapiScheme = function.JsonSchema; + var parameters = new List(); + string[] isRequiredProperties = []; + if (openapiScheme.TryGetProperty("required", out var requiredElement)) { - Namespace = metadata.AdditionalProperties.ContainsKey(NamespaceKey) ? metadata.AdditionalProperties[NamespaceKey] as string : null, - ClassName = metadata.AdditionalProperties.ContainsKey(ClassNameKey) ? metadata.AdditionalProperties[ClassNameKey] as string : null, - Name = metadata.Name, - Description = metadata.Description, - Parameters = metadata.Parameters?.Select(p => (FunctionParameterContract)p).ToList(), - ReturnType = metadata.ReturnParameter.ParameterType, - ReturnDescription = metadata.ReturnParameter.Description, - }; - } + isRequiredProperties = requiredElement.Deserialize() ?? []; + } - public static implicit operator AIFunctionMetadata(FunctionContract contract) - { - return new AIFunctionMetadata(contract.Name) + var parameterList = function.UnderlyingMethod?.GetParameters() ?? Array.Empty(); + + if (openapiScheme.TryGetProperty("properties", out var propertiesElement)) { - Description = contract.Description, - ReturnParameter = new AIFunctionReturnParameterMetadata() + var properties = propertiesElement.Deserialize>() ?? new Dictionary(); + foreach (var property in properties) { - Description = contract.ReturnDescription, - ParameterType = contract.ReturnType, - }, - AdditionalProperties = new Dictionary - { - [NamespaceKey] = contract.Namespace, - [ClassNameKey] = contract.ClassName, - }, - Parameters = [.. contract.Parameters?.Select(p => (AIFunctionParameterMetadata)p)!], + var parameterType = parameterList.FirstOrDefault(p => p.Name == property.Key)?.ParameterType; + var parameter = new FunctionParameterContract + { + Name = property.Key, + ParameterType = parameterType, // TODO: Need to get the type from the schema + IsRequired = isRequiredProperties.Contains(property.Key), + }; + if (property.Value.TryGetProperty("description", out var descriptionElement)) + { + parameter.Description = descriptionElement.GetString(); + } + if (property.Value.TryGetProperty("default", out var defaultValueElement)) + { + parameter.DefaultValue = defaultValueElement.Deserialize(); + } + parameters.Add(parameter); + } + } + return new FunctionContract + { + Namespace = function.AdditionalProperties.ContainsKey(NamespaceKey) ? function.AdditionalProperties[NamespaceKey] as string : null, + ClassName = function.AdditionalProperties.ContainsKey(ClassNameKey) ? function.AdditionalProperties[ClassNameKey] as string : null, + Name = function.Name, + Description = function.Description, + Parameters = parameters, }; } } @@ -132,29 +146,4 @@ public class FunctionParameterContract /// The default value of the parameter. /// public object? DefaultValue { get; set; } - - // convert to/from FunctionParameterMetadata - public static implicit operator FunctionParameterContract(AIFunctionParameterMetadata metadata) - { - return new FunctionParameterContract - { - Name = metadata.Name, - Description = metadata.Description, - ParameterType = metadata.ParameterType, - IsRequired = metadata.IsRequired, - DefaultValue = metadata.DefaultValue, - }; - } - - public static implicit operator AIFunctionParameterMetadata(FunctionParameterContract contract) - { - return new AIFunctionParameterMetadata(contract.Name!) - { - DefaultValue = contract.DefaultValue, - Description = contract.Description, - IsRequired = contract.IsRequired, - ParameterType = contract.ParameterType, - HasDefaultValue = contract.DefaultValue != null, - }; - } } diff --git a/dotnet/src/AutoGen.Core/Middleware/FunctionCallMiddleware.cs b/dotnet/src/AutoGen.Core/Middleware/FunctionCallMiddleware.cs index 266155316c81..3c68e95457f1 100644 --- a/dotnet/src/AutoGen.Core/Middleware/FunctionCallMiddleware.cs +++ b/dotnet/src/AutoGen.Core/Middleware/FunctionCallMiddleware.cs @@ -53,9 +53,9 @@ public FunctionCallMiddleware( public FunctionCallMiddleware(IEnumerable functions, string? name = null) { this.Name = name ?? nameof(FunctionCallMiddleware); - this.functions = functions.Select(f => (FunctionContract)f.Metadata).ToArray(); + this.functions = functions.Select(f => (FunctionContract)f).ToArray(); - this.functionMap = functions.Select(f => (f.Metadata.Name, this.AIToolInvokeWrapper(f.InvokeAsync))).ToDictionary(f => f.Name, f => f.Item2); + this.functionMap = functions.Select(f => (f.Name, this.AIToolInvokeWrapper(f.InvokeAsync))).ToDictionary(f => f.Name, f => f.Item2); } public string? Name { get; } diff --git a/dotnet/src/AutoGen.DotnetInteractive/DotnetInteractiveKernelBuilder.cs b/dotnet/src/AutoGen.DotnetInteractive/DotnetInteractiveKernelBuilder.cs index 98b3e547d7d2..8d1f5ec8fa31 100644 --- a/dotnet/src/AutoGen.DotnetInteractive/DotnetInteractiveKernelBuilder.cs +++ b/dotnet/src/AutoGen.DotnetInteractive/DotnetInteractiveKernelBuilder.cs @@ -14,9 +14,7 @@ public static InProccessDotnetInteractiveKernelBuilder CreateEmptyInProcessKerne public static InProccessDotnetInteractiveKernelBuilder CreateDefaultInProcessKernelBuilder() { - return new InProccessDotnetInteractiveKernelBuilder() - .AddCSharpKernel() - .AddFSharpKernel(); + return new InProccessDotnetInteractiveKernelBuilder(); } #endif diff --git a/dotnet/src/AutoGen.SemanticKernel/SemanticKernelChatCompletionAgent.cs b/dotnet/src/AutoGen.SemanticKernel/SemanticKernelChatCompletionAgent.cs index 947807806976..2744bfdce00b 100644 --- a/dotnet/src/AutoGen.SemanticKernel/SemanticKernelChatCompletionAgent.cs +++ b/dotnet/src/AutoGen.SemanticKernel/SemanticKernelChatCompletionAgent.cs @@ -26,8 +26,9 @@ public SemanticKernelChatCompletionAgent(ChatCompletionAgent chatCompletionAgent public async Task GenerateReplyAsync(IEnumerable messages, GenerateReplyOptions? options = null, CancellationToken cancellationToken = default) { - ChatMessageContent[] reply = await _chatCompletionAgent - .InvokeAsync(BuildChatHistory(messages), cancellationToken: cancellationToken) + var agentThread = new ChatHistoryAgentThread(BuildChatHistory(messages)); + var reply = await _chatCompletionAgent + .InvokeAsync(agentThread, cancellationToken: cancellationToken) .ToArrayAsync(cancellationToken: cancellationToken); return reply.Length > 1 diff --git a/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Messages.cs b/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Messages.cs index 97e1d5b7628a..74edaf3e010c 100644 --- a/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Messages.cs +++ b/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Messages.cs @@ -124,7 +124,7 @@ public enum Type /// The to wrap. /// A instance wrapping the . /// - /// Thrown if the is not a or . + /// Thrown if the is not a or . /// public static MultiModalData CheckTypeAndCreate(AIContent item) { @@ -132,7 +132,7 @@ public static MultiModalData CheckTypeAndCreate(AIContent item) { return new MultiModalData(text); } - else if (item is ImageContent image) + else if (item is DataContent image) { return new MultiModalData(image); } @@ -163,10 +163,10 @@ public MultiModalData(TextContent textContent) } /// - /// Initializes a new instance of the with an . + /// Initializes a new instance of the with an . /// /// The image to wrap. - public MultiModalData(ImageContent image) + public MultiModalData(DataContent image) { ContentType = Type.Image; AIContent = image; @@ -254,12 +254,12 @@ public void AddRange(IEnumerable textItems) } /// - /// Adds a range of to the message. + /// Adds a range of to the message. /// /// The items to add. - public void AddRange(IEnumerable images) + public void AddRange(IEnumerable images) { - foreach (ImageContent image in images) + foreach (DataContent image in images) { this.Add(image); } @@ -287,7 +287,7 @@ public void Add(string text) /// Adds a to the message. /// /// The image to add. - public void Add(ImageContent image) + public void Add(DataContent image) { this.Content.Add(new(image)); } @@ -374,7 +374,7 @@ public void Insert(int index, TextContent text) } /// - public void Insert(int index, ImageContent image) + public void Insert(int index, DataContent image) { this.Content.Insert(index, new(image)); } @@ -610,7 +610,7 @@ public static Microsoft.Extensions.AI.ChatMessage Flatten(this Microsoft.Extensi { contentBuilder.AppendLine(textContent.Text); } - else if (content is ImageContent) + else if (content is DataContent) { contentBuilder.AppendLine("[Image]"); } diff --git a/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Tools.cs b/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Tools.cs index 1c0c276b7bbf..893c3392bc82 100644 --- a/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Tools.cs +++ b/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Tools.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Tools.cs -using System.ComponentModel; using System.Reflection; using Microsoft.Extensions.AI; @@ -10,37 +9,6 @@ namespace Microsoft.AutoGen.AgentChat.Abstractions; // TODO: This likely should live as a "Component" in an Agent-building ClassLib? // It seems like it could have applicability beyond AgentChat. -public static class ReflectionExtensions -{ - public static AIFunctionParameterMetadata ToAIFunctionMetadata(this ParameterInfo pi) - { - return new AIFunctionParameterMetadata(pi.Name!) - { - Description = pi.GetCustomAttribute()?.Description, - - ParameterType = pi.ParameterType, - - HasDefaultValue = pi.HasDefaultValue, - IsRequired = !pi.HasDefaultValue, - DefaultValue = pi.DefaultValue, - - // Schema = JSONSchema of type - }; - } - - public static AIFunctionReturnParameterMetadata ToAIFunctionReturnMetadata(this ParameterInfo rpi) - { - return new AIFunctionReturnParameterMetadata - { - Description = rpi.GetCustomAttribute()?.Description, - - ParameterType = rpi.ParameterType - - //Schema = JSONSchema of type - }; - } -} - public class ParameterSchema(string name, Type type, bool isRequired = false, object? defaultValue = default) { public string Name { get; } = name; @@ -54,15 +22,6 @@ public static implicit operator ParameterSchema(ParameterInfo parameterInfo) Type parameterType = parameterInfo.ParameterType; return ParameterSchema.Create(parameterType, parameterInfo.Name!, parameterInfo.HasDefaultValue, parameterInfo.DefaultValue); } - - public static implicit operator ParameterSchema(AIFunctionParameterMetadata parameterMetadata) - { - Type parameterType = parameterMetadata.ParameterType!; // TODO: Deal with missing ParameterTypes - return ParameterSchema.Create(parameterType, - parameterMetadata.Name, - parameterMetadata.IsRequired, - parameterMetadata.DefaultValue); - } } // TODO: Can this be obviated by AIFunctionParameter? @@ -86,7 +45,6 @@ public interface ITool public string Description { get; } public IEnumerable Parameters { get; } - public Type ReturnType { get; } // TODO: State serialization @@ -136,18 +94,15 @@ public class AIFunctionTool(AIFunction aiFunction) : ITool public AIFunction AIFunction { get; } = aiFunction; /// - public string Name => this.AIFunction.Metadata.Name; + public string Name => this.AIFunction.Name; /// - public string Description => this.AIFunction.Metadata.Description; + public string Description => this.AIFunction.Description; /// - public IEnumerable Parameters => from rawParameter in this.AIFunction.Metadata.Parameters + public IEnumerable Parameters => from rawParameter in this.AIFunction.UnderlyingMethod!.GetParameters() select (ParameterSchema)rawParameter; - /// - public Type ReturnType => this.AIFunction.Metadata.ReturnParameter.ParameterType!; // TODO: Deal with missing return types - /// public Task ExecuteAsync(IEnumerable parameters, CancellationToken cancellationToken = default) => this.ExecuteAsync(parameters, cancellationToken); @@ -164,23 +119,6 @@ public class CallableTool(string name, string description, Delegate callable) { internal static AIFunction CreateAIFunction(string name, string description, Delegate callable) { - MethodInfo methodInfo = callable.Method; - - IEnumerable parameters = - from parameterInfo in methodInfo.GetParameters() - select parameterInfo.ToAIFunctionMetadata(); - - AIFunctionReturnParameterMetadata returnParameter = methodInfo.ReturnParameter.ToAIFunctionReturnMetadata(); - - AIFunctionFactoryCreateOptions createOptions = new() - { - Name = name, - Description = description, - Parameters = parameters.ToList(), - ReturnParameter = returnParameter, - // SerializerOptions = TODO: How do we maintain consistency with Python? - }; - - return AIFunctionFactory.Create(callable, createOptions); + return AIFunctionFactory.Create(callable, name: name, description: description); } } diff --git a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs index d3dc100012eb..8e753766b316 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs @@ -26,19 +26,19 @@ public abstract class InferenceAgent( { protected IChatClient ChatClient { get; } = client; private ILogger>? Logger => _logger as ILogger>; - private Task CompleteAsync( + private Task CompleteAsync( IList chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default) { - return ChatClient.CompleteAsync(chatMessages, options, cancellationToken); + return ChatClient.GetResponseAsync(chatMessages, options, cancellationToken); } - private IAsyncEnumerable CompleteStreamingAsync( + private IAsyncEnumerable CompleteStreamingAsync( IList chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default) { - return ChatClient.CompleteStreamingAsync(chatMessages, options, cancellationToken); + return ChatClient.GetStreamingResponseAsync(chatMessages, options, cancellationToken); } } diff --git a/dotnet/src/Microsoft.AutoGen/Extensions/MEAI/ServiceCollectionChatCompletionExtensions.cs b/dotnet/src/Microsoft.AutoGen/Extensions/MEAI/ServiceCollectionChatCompletionExtensions.cs index 114562993c29..2b398ac28478 100644 --- a/dotnet/src/Microsoft.AutoGen/Extensions/MEAI/ServiceCollectionChatCompletionExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Extensions/MEAI/ServiceCollectionChatCompletionExtensions.cs @@ -41,12 +41,13 @@ public static IServiceCollection AddOllamaChatClient( Func? builder = null) { uri ??= new Uri("http://localhost:11434"); - return services.AddChatClient(pipeline => + services.AddChatClient(service => { - builder?.Invoke(pipeline); - var httpClient = pipeline.Services.GetService() ?? new(); - return pipeline.Use(new OllamaChatClient(uri, modelName, httpClient)); + var httpClient = service.GetService() ?? new(); + return new OllamaChatClient(uri, modelName, httpClient); }); + + return services; } public static IServiceCollection AddOpenAIChatClient( this IHostApplicationBuilder hostBuilder, @@ -81,16 +82,17 @@ public static IServiceCollection AddOpenAIChatClient( Uri? endpoint = null, Func? builder = null) { - return services + services .AddSingleton(_ => endpoint is null ? new OpenAIClient(apiKey) : new AzureOpenAIClient(endpoint, new ApiKeyCredential(apiKey))) - .AddChatClient(pipeline => + .AddChatClient(service => { - builder?.Invoke(pipeline); - var openAiClient = pipeline.Services.GetRequiredService(); - return pipeline.Use(openAiClient.AsChatClient(modelOrDeploymentName)); + var openAiClient = service.GetRequiredService(); + return openAiClient.AsChatClient(modelOrDeploymentName); }); + + return services; } public static IServiceCollection AddAzureChatClient( this IHostApplicationBuilder hostBuilder, @@ -109,12 +111,10 @@ public static IServiceCollection AddAzureChatClient( } var endpoint = $"{serviceName}:Endpoint" ?? throw new InvalidOperationException($"No endpoint was specified for the Azure Inference Chat Client"); var endpointUri = string.IsNullOrEmpty(endpoint) ? null : new Uri(endpoint); - return hostBuilder.Services.AddChatClient(pipeline => - { - builder?.Invoke(pipeline); - var token = Environment.GetEnvironmentVariable("GH_TOKEN") ?? throw new InvalidOperationException("No model access token was found in the environment variable GH_TOKEN"); - return pipeline.Use(new ChatCompletionsClient( - endpointUri, new AzureKeyCredential(token)).AsChatClient(modelOrDeploymentName)); - }); + var token = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? throw new InvalidOperationException("No model access token was found in the environment variable AZURE_OPENAI_API_KEY"); + var chatClient = new ChatCompletionsClient(endpointUri, new AzureKeyCredential(token)).AsChatClient(modelOrDeploymentName); + hostBuilder.Services.AddChatClient(chatClient); + + return hostBuilder.Services; } } diff --git a/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.approved.txt b/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.approved.txt index 5b113c3f65ab..78c374f63d8e 100644 --- a/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.approved.txt +++ b/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.approved.txt @@ -12,6 +12,12 @@ "ImageUri": null, "ImageBytes": null, "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, "ImageDetailLevel": null, "Refusal": null } @@ -31,6 +37,12 @@ "ImageUri": null, "ImageBytes": null, "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, "ImageDetailLevel": null, "Refusal": null } @@ -57,6 +69,12 @@ "ImageUri": null, "ImageBytes": null, "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, "ImageDetailLevel": null, "Refusal": null } @@ -78,6 +96,12 @@ "ImageUri": "https://example.com/image.png", "ImageBytes": null, "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, "ImageDetailLevel": null, "Refusal": null } @@ -104,6 +128,12 @@ "ImageUri": null, "ImageBytes": null, "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, "ImageDetailLevel": null, "Refusal": null }, @@ -113,6 +143,12 @@ "ImageUri": "https://example.com/image.png", "ImageBytes": null, "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, "ImageDetailLevel": null, "Refusal": null } diff --git a/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.received.txt b/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.received.txt new file mode 100644 index 000000000000..78c374f63d8e --- /dev/null +++ b/dotnet/test/AutoGen.OpenAI.Tests/ApprovalTests/OpenAIMessageTests.BasicMessageTest.received.txt @@ -0,0 +1,260 @@ +[ + { + "OriginalMessage": "TextMessage(system, You are a helpful AI assistant, )", + "ConvertedMessages": [ + { + "Name": null, + "Role": "system", + "Content": [ + { + "Kind": 0, + "Text": "You are a helpful AI assistant", + "ImageUri": null, + "ImageBytes": null, + "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, + "ImageDetailLevel": null, + "Refusal": null + } + ] + } + ] + }, + { + "OriginalMessage": "TextMessage(user, Hello, user)", + "ConvertedMessages": [ + { + "Role": "user", + "Content": [ + { + "Kind": 0, + "Text": "Hello", + "ImageUri": null, + "ImageBytes": null, + "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, + "ImageDetailLevel": null, + "Refusal": null + } + ], + "Name": "user", + "MultiModaItem": [ + { + "Type": "Text", + "Text": "Hello" + } + ] + } + ] + }, + { + "OriginalMessage": "TextMessage(assistant, How can I help you?, assistant)", + "ConvertedMessages": [ + { + "Role": "assistant", + "Content": [ + { + "Kind": 0, + "Text": "How can I help you?", + "ImageUri": null, + "ImageBytes": null, + "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, + "ImageDetailLevel": null, + "Refusal": null + } + ], + "Name": "assistant", + "TooCall": [] + } + ] + }, + { + "OriginalMessage": "ImageMessage(user, https://example.com/image.png, user)", + "ConvertedMessages": [ + { + "Role": "user", + "Content": [ + { + "Kind": 2, + "Text": null, + "ImageUri": "https://example.com/image.png", + "ImageBytes": null, + "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, + "ImageDetailLevel": null, + "Refusal": null + } + ], + "Name": "user", + "MultiModaItem": [ + { + "Type": "Image", + "ImageUrl": "https://example.com/image.png" + } + ] + } + ] + }, + { + "OriginalMessage": "MultiModalMessage(assistant, user)\n\tTextMessage(user, Hello, user)\n\tImageMessage(user, https://example.com/image.png, user)", + "ConvertedMessages": [ + { + "Role": "user", + "Content": [ + { + "Kind": 0, + "Text": "Hello", + "ImageUri": null, + "ImageBytes": null, + "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, + "ImageDetailLevel": null, + "Refusal": null + }, + { + "Kind": 2, + "Text": null, + "ImageUri": "https://example.com/image.png", + "ImageBytes": null, + "ImageBytesMediaType": null, + "InputAudioBytes": null, + "InputAudioFormat": null, + "FileId": null, + "FileBytes": null, + "FileBytesMediaType": null, + "Filename": null, + "ImageDetailLevel": null, + "Refusal": null + } + ], + "Name": "user", + "MultiModaItem": [ + { + "Type": "Text", + "Text": "Hello" + }, + { + "Type": "Image", + "ImageUrl": "https://example.com/image.png" + } + ] + } + ] + }, + { + "OriginalMessage": "ToolCallMessage(assistant)\n\tToolCall(test, test, )", + "ConvertedMessages": [ + { + "Role": "assistant", + "Content": [], + "Name": null, + "TooCall": [ + { + "Type": "Function", + "Name": "test", + "Arguments": "dGVzdA==", + "Id": "test" + } + ] + } + ] + }, + { + "OriginalMessage": "ToolCallResultMessage(user)\n\tToolCall(test, test, result)", + "ConvertedMessages": [ + { + "Role": "tool", + "Content": "result", + "ToolCallId": "test" + } + ] + }, + { + "OriginalMessage": "ToolCallResultMessage(user)\n\tToolCall(result, test, test)\n\tToolCall(result, test, test)", + "ConvertedMessages": [ + { + "Role": "tool", + "Content": "test", + "ToolCallId": "result_0" + }, + { + "Role": "tool", + "Content": "test", + "ToolCallId": "result_1" + } + ] + }, + { + "OriginalMessage": "ToolCallMessage(assistant)\n\tToolCall(test, test, )\n\tToolCall(test, test, )", + "ConvertedMessages": [ + { + "Role": "assistant", + "Content": [], + "Name": null, + "TooCall": [ + { + "Type": "Function", + "Name": "test", + "Arguments": "dGVzdA==", + "Id": "test_0" + }, + { + "Type": "Function", + "Name": "test", + "Arguments": "dGVzdA==", + "Id": "test_1" + } + ] + } + ] + }, + { + "OriginalMessage": "AggregateMessage(assistant)\n\tToolCallMessage(assistant)\n\tToolCall(test, test, )\n\tToolCallResultMessage(assistant)\n\tToolCall(test, test, result)", + "ConvertedMessages": [ + { + "Role": "assistant", + "Content": [], + "Name": null, + "TooCall": [ + { + "Type": "Function", + "Name": "test", + "Arguments": "dGVzdA==", + "Id": "test" + } + ] + }, + { + "Role": "tool", + "Content": "result", + "ToolCallId": "test" + } + ] + } +] \ No newline at end of file diff --git a/dotnet/test/AutoGen.Tests/Function/FunctionTests.cs b/dotnet/test/AutoGen.Tests/Function/FunctionTests.cs index adb97e1c5327..b8024e0a360e 100644 --- a/dotnet/test/AutoGen.Tests/Function/FunctionTests.cs +++ b/dotnet/test/AutoGen.Tests/Function/FunctionTests.cs @@ -60,7 +60,7 @@ public async Task CreateGetWeatherFunctionFromAIFunctionFactoryAsync() GetWeatherAsyncStatic, ]; - var functionContracts = availableDelegates.Select(function => (FunctionContract)AIFunctionFactory.Create(function).Metadata).ToList(); + var functionContracts = availableDelegates.Select(function => (FunctionContract)AIFunctionFactory.Create(function)).ToList(); // Verify the function contracts functionContracts.Should().HaveCount(4); diff --git a/dotnet/test/AutoGen.Tests/Orchestrator/RolePlayOrchestratorTests.cs b/dotnet/test/AutoGen.Tests/Orchestrator/RolePlayOrchestratorTests.cs index 256d704cc4c4..521cd711a5e9 100644 --- a/dotnet/test/AutoGen.Tests/Orchestrator/RolePlayOrchestratorTests.cs +++ b/dotnet/test/AutoGen.Tests/Orchestrator/RolePlayOrchestratorTests.cs @@ -18,7 +18,6 @@ using AutoGen.OpenAI; using AutoGen.OpenAI.Extension; using Azure.AI.Inference; -using Azure.AI.OpenAI; using FluentAssertions; using Moq; using OpenAI; @@ -217,21 +216,6 @@ public async Task ItUseCandidatesFromWorflowAsync() speaker.Should().Be(bob); } - [ApiKeyFact("AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_DEPLOY_NAME")] - public async Task GPT_3_5_CoderReviewerRunnerTestAsync() - { - var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable."); - var key = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? throw new Exception("Please set AZURE_OPENAI_API_KEY environment variable."); - var deployName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOY_NAME") ?? throw new Exception("Please set AZURE_OPENAI_DEPLOY_NAME environment variable."); - var openaiClient = new AzureOpenAIClient(new Uri(endpoint), new System.ClientModel.ApiKeyCredential(key)); - var openAIChatAgent = new OpenAIChatAgent( - chatClient: openaiClient.GetChatClient(deployName), - name: "assistant") - .RegisterMessageConnector(); - - await CoderReviewerRunnerTestAsync(openAIChatAgent); - } - [ApiKeyFact("OPENAI_API_KEY")] public async Task GPT_4o_CoderReviewerRunnerTestAsync() { diff --git a/dotnet/test/AutoGen.Tests/SingleAgentTest.cs b/dotnet/test/AutoGen.Tests/SingleAgentTest.cs index 8611714c351d..2f014236c403 100644 --- a/dotnet/test/AutoGen.Tests/SingleAgentTest.cs +++ b/dotnet/test/AutoGen.Tests/SingleAgentTest.cs @@ -20,11 +20,11 @@ public SingleAgentTest(ITestOutputHelper output) _output = output; } - private ILLMConfig CreateAzureOpenAIGPT35TurboConfig() + private ILLMConfig CreateAzureOpenAIGPT4oMiniConfig() { var key = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? throw new ArgumentException("AZURE_OPENAI_API_KEY is not set"); var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new ArgumentException("AZURE_OPENAI_ENDPOINT is not set"); - var deployName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOY_NAME") ?? throw new ArgumentException("AZURE_OPENAI_DEPLOY_NAME is not set"); + var deployName = "gpt-4o-mini"; return new AzureOpenAIConfig(endpoint, deployName, key); } @@ -37,7 +37,7 @@ private ILLMConfig CreateOpenAIGPT4VisionConfig() [ApiKeyFact("AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_DEPLOY_NAME")] public async Task AssistantAgentFunctionCallTestAsync() { - var config = this.CreateAzureOpenAIGPT35TurboConfig(); + var config = this.CreateAzureOpenAIGPT4oMiniConfig(); var llmConfig = new ConversableAgentConfig { @@ -77,7 +77,7 @@ public async Task AssistantAgentDefaultReplyTestAsync() [ApiKeyFact("AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_DEPLOY_NAME")] public async Task AssistantAgentFunctionCallSelfExecutionTestAsync() { - var config = this.CreateAzureOpenAIGPT35TurboConfig(); + var config = this.CreateAzureOpenAIGPT4oMiniConfig(); var llmConfig = new ConversableAgentConfig { FunctionContracts = new[] diff --git a/dotnet/test/AutoGen.Tests/TwoAgentTest.cs b/dotnet/test/AutoGen.Tests/TwoAgentTest.cs index 8ba4a3fedbd8..ed24dabef3bf 100644 --- a/dotnet/test/AutoGen.Tests/TwoAgentTest.cs +++ b/dotnet/test/AutoGen.Tests/TwoAgentTest.cs @@ -32,7 +32,7 @@ public async Task TwoAgentWeatherChatTestAsync() { var key = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? throw new ArgumentException("AZURE_OPENAI_API_KEY is not set"); var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new ArgumentException("AZURE_OPENAI_ENDPOINT is not set"); - var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOY_NAME") ?? throw new ArgumentException("AZURE_OPENAI_DEPLOY_NAME is not set"); + var deploymentName = "gpt-4o-mini"; var config = new AzureOpenAIConfig(endpoint, deploymentName, key); var assistant = new AssistantAgent(