mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: AgentDefinition extensions method simplification (#1967)
* Update extensions methods that accepts AgentDefinition type to not be restrictive * Update Unit Tests * Revert yarn/package-lock * Revert yarn/package-lock * Address copilot feedback
This commit is contained in:
committed by
GitHub
Unverified
parent
5a8c8fe634
commit
d55b15903d
@@ -279,8 +279,8 @@ public static class AgentsClientExtensions
|
||||
return CreateAIAgent(
|
||||
agentsClient,
|
||||
name,
|
||||
new PromptAgentDefinition(model) { Instructions = instructions },
|
||||
tools,
|
||||
new PromptAgentDefinition(model) { Instructions = instructions },
|
||||
creationOptions,
|
||||
clientFactory,
|
||||
openAIClientOptions,
|
||||
@@ -323,8 +323,8 @@ public static class AgentsClientExtensions
|
||||
return CreateAIAgentAsync(
|
||||
agentsClient,
|
||||
name,
|
||||
new PromptAgentDefinition(model) { Instructions = instructions },
|
||||
tools,
|
||||
new PromptAgentDefinition(model) { Instructions = instructions },
|
||||
creationOptions,
|
||||
clientFactory,
|
||||
openAIClientOptions,
|
||||
@@ -450,31 +450,106 @@ public static class AgentsClientExtensions
|
||||
/// <param name="agentsClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
|
||||
/// <param name="name">The name for the agent.</param>
|
||||
/// <param name="agentDefinition">The definition that specifies the configuration and behavior of the agent to create. Cannot be <see langword="null"/>.</param>
|
||||
/// <param name="tools">The tools to use when interacting with the agent, this is required when using prompt agent definitions with tools.</param>
|
||||
/// <param name="creationOptions">Settings that control the creation of the agent.</param>
|
||||
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
|
||||
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
|
||||
/// <param name="requireInvocableTools">This defaults to true and indicates whether to enforce the presence of invocable tools when the AIAgent is created with an agent definition that uses them. Setting this to false will require manual handling of in-proc tool invocations by the caller.</param>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentsClient"/> or <paramref name="agentDefinition"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>When using prompt agent definitions with tools the parameter <paramref name="tools"/> needs to be provided.</remarks>
|
||||
/// <remarks>
|
||||
/// When using this extension method with a <see cref="PromptAgentDefinition"/> the tools are only declarative and not invocable.
|
||||
/// Invocation of any in-process tools will need to be handled manually.
|
||||
/// </remarks>
|
||||
public static ChatClientAgent CreateAIAgent(
|
||||
this AgentsClient agentsClient,
|
||||
string name,
|
||||
AgentDefinition agentDefinition,
|
||||
IList<AITool>? tools = null,
|
||||
AgentVersionCreationOptions? creationOptions = null,
|
||||
Func<IChatClient, IChatClient>? clientFactory = null,
|
||||
OpenAIClientOptions? openAIClientOptions = null,
|
||||
bool requireInvocableTools = true,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(agentsClient);
|
||||
Throw.IfNullOrWhitespace(name);
|
||||
Throw.IfNull(agentDefinition);
|
||||
|
||||
ValidateUsingToolsParameter(agentDefinition, tools);
|
||||
var tools = (agentDefinition as PromptAgentDefinition)?.Tools.Select(t => t.AsAITool()).ToList();
|
||||
|
||||
return CreateAIAgent(
|
||||
agentsClient,
|
||||
name,
|
||||
tools,
|
||||
agentDefinition,
|
||||
creationOptions,
|
||||
clientFactory,
|
||||
openAIClientOptions,
|
||||
requireInvocableTools: false,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously creates a new AI agent using the specified agent definition and optional configuration
|
||||
/// parameters.
|
||||
/// </summary>
|
||||
/// <param name="agentsClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
|
||||
/// <param name="name">The name for the agent.</param>
|
||||
/// <param name="agentDefinition">The definition that specifies the configuration and behavior of the agent to create. Cannot be <see langword="null"/>.</param>
|
||||
/// <param name="agentVersionCreationOptions">Settings that control the creation of the agent.</param>
|
||||
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
|
||||
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentsClient"/> or <paramref name="agentDefinition"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// When using this extension method with a <see cref="PromptAgentDefinition"/> the tools are only declarative and not invocable.
|
||||
/// Invocation of any in-process tools will need to be handled manually.
|
||||
/// </remarks>
|
||||
public static Task<ChatClientAgent> CreateAIAgentAsync(
|
||||
this AgentsClient agentsClient,
|
||||
string name,
|
||||
AgentDefinition agentDefinition,
|
||||
AgentVersionCreationOptions? agentVersionCreationOptions = null,
|
||||
Func<IChatClient, IChatClient>? clientFactory = null,
|
||||
OpenAIClientOptions? openAIClientOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhitespace(name);
|
||||
Throw.IfNull(agentsClient);
|
||||
Throw.IfNull(agentDefinition);
|
||||
|
||||
var tools = (agentDefinition as PromptAgentDefinition)?.Tools.Select(t => t.AsAITool()).ToList();
|
||||
|
||||
return CreateAIAgentAsync(
|
||||
agentsClient,
|
||||
name,
|
||||
tools,
|
||||
agentDefinition,
|
||||
agentVersionCreationOptions,
|
||||
clientFactory,
|
||||
openAIClientOptions,
|
||||
requireInvocableTools: false,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
#region Private
|
||||
|
||||
private static ChatClientAgent CreateAIAgent(
|
||||
this AgentsClient agentsClient,
|
||||
string name,
|
||||
IList<AITool>? tools,
|
||||
AgentDefinition agentDefinition,
|
||||
AgentVersionCreationOptions? creationOptions,
|
||||
Func<IChatClient, IChatClient>? clientFactory,
|
||||
OpenAIClientOptions? openAIClientOptions,
|
||||
bool requireInvocableTools,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Throw.IfNull(agentsClient);
|
||||
Throw.IfNullOrWhitespace(name);
|
||||
Throw.IfNull(agentDefinition);
|
||||
|
||||
tools ??= (agentDefinition as PromptAgentDefinition)?.Tools.Select(t => t.AsAITool()).ToList();
|
||||
|
||||
ApplyToolsToAgentDefinition(agentDefinition, tools, requireInvocableTools);
|
||||
|
||||
AgentVersion agentVersion = agentsClient.CreateAgentVersion(name, agentDefinition, creationOptions, cancellationToken).Value;
|
||||
@@ -488,38 +563,23 @@ public static class AgentsClientExtensions
|
||||
requireInvocableTools);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously creates a new AI agent using the specified agent definition and optional configuration
|
||||
/// parameters.
|
||||
/// </summary>
|
||||
/// <param name="agentsClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
|
||||
/// <param name="name">The name for the agent.</param>
|
||||
/// <param name="agentDefinition">The definition that specifies the configuration and behavior of the agent to create. Cannot be <see langword="null"/>.</param>
|
||||
/// <param name="tools">The tools to use when interacting with the agent. This is required when using prompt agent definitions with tools.</param>
|
||||
/// <param name="agentVersionCreationOptions">Settings that control the creation of the agent.</param>
|
||||
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
|
||||
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
|
||||
/// <param name="requireInvocableTools">This defaults to true and indicates whether to enforce the presence of invocable tools when the AIAgent is created with an agent definition that uses them. Setting this to false will require manual handling of in-proc tool invocations by the caller.</param>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentsClient"/> or <paramref name="agentDefinition"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>When using prompt agent definitions with tools the parameter <paramref name="tools"/> needs to be provided.</remarks>
|
||||
public static async Task<ChatClientAgent> CreateAIAgentAsync(
|
||||
private static async Task<ChatClientAgent> CreateAIAgentAsync(
|
||||
this AgentsClient agentsClient,
|
||||
string name,
|
||||
IList<AITool>? tools,
|
||||
AgentDefinition agentDefinition,
|
||||
IList<AITool>? tools = null,
|
||||
AgentVersionCreationOptions? agentVersionCreationOptions = null,
|
||||
Func<IChatClient, IChatClient>? clientFactory = null,
|
||||
OpenAIClientOptions? openAIClientOptions = null,
|
||||
bool requireInvocableTools = true,
|
||||
CancellationToken cancellationToken = default)
|
||||
AgentVersionCreationOptions? agentVersionCreationOptions,
|
||||
Func<IChatClient, IChatClient>? clientFactory,
|
||||
OpenAIClientOptions? openAIClientOptions,
|
||||
bool requireInvocableTools,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Throw.IfNullOrWhitespace(name);
|
||||
Throw.IfNull(agentsClient);
|
||||
Throw.IfNull(agentDefinition);
|
||||
|
||||
ValidateUsingToolsParameter(agentDefinition, tools);
|
||||
tools ??= (agentDefinition as PromptAgentDefinition)?.Tools.Select(t => t.AsAITool()).ToList();
|
||||
|
||||
ApplyToolsToAgentDefinition(agentDefinition, tools, requireInvocableTools);
|
||||
|
||||
AgentVersion agentVersion = await agentsClient.CreateAgentVersionAsync(name, agentDefinition, agentVersionCreationOptions, cancellationToken).ConfigureAwait(false);
|
||||
@@ -533,8 +593,6 @@ public static class AgentsClientExtensions
|
||||
requireInvocableTools);
|
||||
}
|
||||
|
||||
#region Private
|
||||
|
||||
/// <summary>This method creates an <see cref="ChatClientAgent"/> with the specified ChatClientAgentOptions.</summary>
|
||||
private static ChatClientAgent CreateChatClientAgent(
|
||||
AgentsClient agentsClient,
|
||||
@@ -608,7 +666,8 @@ public static class AgentsClientExtensions
|
||||
var matchingTool = tools?.FirstOrDefault(t =>
|
||||
requireInvocableTools
|
||||
? t is AIFunction tf && functionTool.FunctionName == tf.Name // When invocable tools are required, match only AIFunction.
|
||||
: t is AIFunctionDeclaration tfd && functionTool.FunctionName == tfd.Name); // Otherwise, matching only AIFunctionDeclaration is sufficient.
|
||||
: (t is AIFunctionDeclaration tfd && functionTool.FunctionName == tfd.Name) ? true // When not required, match AIFunctionDeclaration OR
|
||||
: (t.GetService<FunctionTool>() is FunctionTool ft && functionTool.FunctionName == ft.FunctionName)); // Match a FunctionTool converted AsAITool.
|
||||
|
||||
if (matchingTool is null)
|
||||
{
|
||||
@@ -680,20 +739,6 @@ public static class AgentsClientExtensions
|
||||
return agentOptions;
|
||||
}
|
||||
|
||||
/// <summary>When creating agents, validates the <paramref name="tools"/> parameter is used instead of providing via <see cref="PromptAgentDefinition"/>.</summary>
|
||||
/// <exception cref="ArgumentException">The <paramref name="tools"/> parameter should be used instead of <see cref="PromptAgentDefinition.Tools"/>.</exception>
|
||||
/// <remarks>
|
||||
/// Because <see cref="PromptAgentDefinition.Tools"/> doesn't support in-proc tools (only declarative/definitions),
|
||||
/// the <paramref name="tools"/> parameter needs to be the single source of truth for tools, and must be provided when using tools.
|
||||
/// </remarks>
|
||||
private static void ValidateUsingToolsParameter(AgentDefinition agentDefinition, IList<AITool>? tools)
|
||||
{
|
||||
if (agentDefinition is PromptAgentDefinition { Tools.Count: > 0 })
|
||||
{
|
||||
throw new ArgumentException("When creating agents with prompt agent definitions use the dedicated tools parameter to provide the necessary tools instead of PromptAgentDefinition.Tools.", nameof(tools));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>For already created agent versions, retrieve the definition and validate the tools parameter.</summary>
|
||||
/// <exception cref="ArgumentException"><see cref="PromptAgentDefinition.Tools"/> cannot be used. The <paramref name="tools"/> parameter should be used instead.</exception>
|
||||
/// <remarks>
|
||||
@@ -734,9 +779,11 @@ public static class AgentsClientExtensions
|
||||
foreach (var tool in tools)
|
||||
{
|
||||
// Ensure that any AIFunctions provided are In-Proc, not just the declarations.
|
||||
if (requireInvocableTools && tool is AIFunctionDeclaration and not AIFunction)
|
||||
if (requireInvocableTools && tool is not AIFunction && (
|
||||
tool.GetService<FunctionTool>() is not null // Declarative FunctionTool converted as AsAITool()
|
||||
|| tool is AIFunctionDeclaration)) // AIFunctionDeclaration type
|
||||
{
|
||||
throw new InvalidOperationException("When providing functions, they need to be invokable AIFunctions and not non-invokable AIFunctionDeclarations. AIFunctions can be created correctly using AIFunctionFactory.Create");
|
||||
throw new InvalidOperationException("When providing functions, they need to be invokable AIFunctions. AIFunctions can be created correctly using AIFunctionFactory.Create");
|
||||
}
|
||||
|
||||
promptAgentDefinition.Tools.Add(
|
||||
|
||||
+213
-173
@@ -5,6 +5,7 @@ using System.ClientModel;
|
||||
using System.ClientModel.Primitives;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -867,41 +868,17 @@ public sealed class AgentsClientExtensionsTests
|
||||
#region Tool Validation Tests
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent throws ArgumentException when agent definition contains inline tools.
|
||||
/// Verify that CreateAIAgent creates an agent successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithInlineToolsInDefinition_ThrowsArgumentException()
|
||||
public void CreateAIAgent_WithDefinition_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
AgentsClient client = this.CreateTestAgentsClient();
|
||||
var definition = new PromptAgentDefinition("test-model");
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("inline_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<ArgumentException>(() =>
|
||||
client.CreateAIAgent("test-agent", definition));
|
||||
|
||||
Assert.Contains("dedicated tools parameter", exception.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent with requireInvocableTools=true enforces invocable tools.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithRequireInvocableToolsTrue_EnforcesInvocableTools()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "test", "test_function", "A test function")
|
||||
};
|
||||
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, tools);
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools, requireInvocableTools: true);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -909,17 +886,37 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent with requireInvocableTools=false allows declarative functions.
|
||||
/// Verify that CreateAIAgent without tools parameter creates an agent successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithRequireInvocableToolsFalse_AllowsDeclarativeFunctions()
|
||||
public void CreateAIAgent_WithoutToolsParameter_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.IsType<ChatClientAgent>(agent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent without tools in definition creates an agent successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithoutToolsInDefinition_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definition);
|
||||
|
||||
// Act - should not throw even without tools when requireInvocableTools is false
|
||||
var agent = client.CreateAIAgent("test-agent", definition, requireInvocableTools: false);
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -927,43 +924,23 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent throws ArgumentException when agent definition has tools but none provided as parameter.
|
||||
/// Verify that CreateAIAgent uses tools from the definition when no separate tools parameter is provided.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithDefinitionToolsButNoToolsParameter_ThrowsArgumentException()
|
||||
public void CreateAIAgent_WithDefinitionTools_UsesDefinitionTools()
|
||||
{
|
||||
// Arrange
|
||||
AgentsClient client = this.CreateTestAgentsClient();
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
// Add a function tool to the definition to simulate a tool requirement
|
||||
// Add a function tool to the definition
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("required_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<ArgumentException>(() =>
|
||||
client.CreateAIAgent("test-agent", definition, tools: null, requireInvocableTools: true));
|
||||
|
||||
Assert.Contains("dedicated tools parameter", exception.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent with tools parameter applies tools to the agent definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithToolsParameter_AppliesToolsToDefinition()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model");
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "test", "test_function", "A test function")
|
||||
};
|
||||
|
||||
var agentDefinitionResponse = GeneratePromptDefinitionResponse(definition, tools);
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: agentDefinitionResponse);
|
||||
// Create a response definition with the same tool
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList());
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -974,9 +951,30 @@ public sealed class AgentsClientExtensionsTests
|
||||
{
|
||||
Assert.NotEmpty(promptDef.Tools);
|
||||
Assert.Single(promptDef.Tools);
|
||||
Assert.Equal("required_tool", (promptDef.Tools.First() as FunctionTool)?.FunctionName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent without tools creates an agent successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithoutTools_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model");
|
||||
|
||||
var agentDefinitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: agentDefinitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.IsType<ChatClientAgent>(agent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that GetAIAgent with inline tools in agent definition throws ArgumentException.
|
||||
/// </summary>
|
||||
@@ -1032,25 +1030,22 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent with parameter tools creates an agent successfully.
|
||||
/// Verify that CreateAIAgent with tools in definition creates an agent successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithParameterTools_CreatesAgentSuccessfully()
|
||||
public void CreateAIAgent_WithDefinitionTools_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "result", "create_tool", "A tool for creation")
|
||||
};
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
|
||||
// Simulate agent definition response with the tools
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, tools);
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList());
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1065,31 +1060,28 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent creates an agent successfully when provided with a mix of custom and hosted tools.
|
||||
/// Verify that CreateAIAgent creates an agent successfully when definition has a mix of custom and hosted tools.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithMixedTools_CreatesAgentSuccessfully()
|
||||
public void CreateAIAgent_WithMixedToolsInDefinition_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "result", "create_tool", "A tool for creation"),
|
||||
new HostedWebSearchTool(),
|
||||
new HostedFileSearchTool(),
|
||||
};
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
definition.Tools.Add(new HostedWebSearchTool().GetService<ResponseTool>() ?? new HostedWebSearchTool().AsOpenAIResponseTool());
|
||||
definition.Tools.Add(new HostedFileSearchTool().GetService<ResponseTool>() ?? new HostedFileSearchTool().AsOpenAIResponseTool());
|
||||
|
||||
// Simulate agent definition response with the tools
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
foreach (var tool in tools)
|
||||
foreach (var tool in definition.Tools)
|
||||
{
|
||||
definitionResponse.Tools.Add(tool.GetService<ResponseTool>() ?? tool.AsOpenAIResponseTool());
|
||||
definitionResponse.Tools.Add(tool);
|
||||
}
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1104,10 +1096,10 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that CreateAIAgent accepts tools provided as ResponseTool instances and correctly converts them to AITool instances, resulting in successful agent creation.
|
||||
/// Verifies that CreateAIAgent uses tools from definition when they are ResponseTool instances, resulting in successful agent creation.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithResponseToolsAsAITools_CreatesAgentSuccessfully()
|
||||
public void CreateAIAgent_WithResponseToolsInDefinition_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
@@ -1123,33 +1115,25 @@ public sealed class AgentsClientExtensionsTests
|
||||
["structured-1"] = BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString())
|
||||
}, false);
|
||||
|
||||
ResponseTool openAIResponseTool = (ResponseTool)new AzureAISearchAgentTool(new());
|
||||
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "result", "create_tool", "A tool for creation"),
|
||||
((ResponseTool)AgentTool.CreateBingCustomSearchTool(new BingCustomSearchToolParameters([new BingCustomSearchConfiguration("connection-id", "instance-name")]))).AsAITool(),
|
||||
((ResponseTool)AgentTool.CreateBrowserAutomationTool(new BrowserAutomationToolParameters(new BrowserAutomationToolConnectionParameters("id")))).AsAITool(),
|
||||
AgentTool.CreateA2ATool(new Uri("https://test-uri.microsoft.com")).AsAITool(),
|
||||
((ResponseTool)AgentTool.CreateBingGroundingTool(new BingGroundingSearchToolParameters([new BingGroundingSearchConfiguration("connection-id")]))).AsAITool(),
|
||||
((ResponseTool)AgentTool.CreateMicrosoftFabricTool(fabricParameters)).AsAITool(),
|
||||
((ResponseTool)AgentTool.CreateOpenApiTool(new OpenApiFunctionDefinition("name", BinaryData.FromString(OpenAPISpec), new OpenApiAnonymousAuthDetails()))).AsAITool(),
|
||||
((ResponseTool)AgentTool.CreateSharepointTool(sharepointParameters)).AsAITool(),
|
||||
((ResponseTool)AgentTool.CreateStructuredOutputsTool(structuredOutputs)).AsAITool(),
|
||||
|
||||
// Workaround the bug with the AgentTool.CreateAzureAISearchTool() extension
|
||||
// Using the extension method AgentTool.CreateAzureAISearchTool() fails serialization,
|
||||
// TODO: Revert back once bug fix is applied: https://github.com/Azure/azure-sdk-for-net/pull/53656
|
||||
((ResponseTool)new AzureAISearchAgentTool(new())).AsAITool()
|
||||
};
|
||||
// Add tools to the definition
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateBingCustomSearchTool(new BingCustomSearchToolParameters([new BingCustomSearchConfiguration("connection-id", "instance-name")])));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateBrowserAutomationTool(new BrowserAutomationToolParameters(new BrowserAutomationToolConnectionParameters("id"))));
|
||||
definition.Tools.Add(AgentTool.CreateA2ATool(new Uri("https://test-uri.microsoft.com")));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateBingGroundingTool(new BingGroundingSearchToolParameters([new BingGroundingSearchConfiguration("connection-id")])));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateMicrosoftFabricTool(fabricParameters));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateOpenApiTool(new OpenApiFunctionDefinition("name", BinaryData.FromString(OpenAPISpec), new OpenApiAnonymousAuthDetails())));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateSharepointTool(sharepointParameters));
|
||||
definition.Tools.Add((ResponseTool)AgentTool.CreateStructuredOutputsTool(structuredOutputs));
|
||||
definition.Tools.Add((ResponseTool)new AzureAISearchAgentTool(new()));
|
||||
|
||||
// Generate agent definition response with the tools
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, tools);
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList());
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1199,21 +1183,18 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgentAsync with tools parameter creates an agent.
|
||||
/// Verify that CreateAIAgentAsync with tools in definition creates an agent.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAIAgentAsync_WithToolsParameter_CreatesAgentAsync()
|
||||
public async Task CreateAIAgentAsync_WithDefinitionTools_CreatesAgentAsync()
|
||||
{
|
||||
// Arrange
|
||||
AgentsClient client = this.CreateTestAgentsClient();
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "async_result", "async_tool", "An async tool")
|
||||
};
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("async_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", definition, tools: tools);
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1246,10 +1227,10 @@ public sealed class AgentsClientExtensionsTests
|
||||
#region Declarative Function Handling Tests
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent throws InvalidOperationException when provided with non-invocable AIFunctionDeclaration when requireInvocableTools=true.
|
||||
/// Verify that CreateAIAgent accepts declarative functions from definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithDeclarativeFunctionAndRequireInvocableTrue_ThrowsInvalidOperationException()
|
||||
public void CreateAIAgent_WithDeclarativeFunctionInDefinition_AcceptsDeclarativeFunction()
|
||||
{
|
||||
// Arrange
|
||||
AgentsClient client = this.CreateTestAgentsClient();
|
||||
@@ -1259,38 +1240,11 @@ public sealed class AgentsClientExtensionsTests
|
||||
using var doc = JsonDocument.Parse("{}");
|
||||
var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement);
|
||||
|
||||
var tools = new List<AITool> { declarativeFunction };
|
||||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(() =>
|
||||
client.CreateAIAgent("test-agent", definition, tools: tools, requireInvocableTools: true));
|
||||
|
||||
Assert.Contains("invokable AIFunctions", exception.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent accepts declarative functions when requireInvocableTools=false.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithDeclarativeFunctionAndRequireInvocableFalse_AcceptsDeclarativeFunction()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
// Create a declarative function (not invocable) using AIFunctionFactory.CreateDeclaration
|
||||
using var doc = JsonDocument.Parse("{}");
|
||||
var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement);
|
||||
|
||||
var tools = new List<AITool> { declarativeFunction };
|
||||
|
||||
// Generate response with the declarative function
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definitionResponse.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
// Add to definition
|
||||
definition.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools, requireInvocableTools: false);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1298,10 +1252,104 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgentAsync throws InvalidOperationException when provided with non-invocable AIFunctionDeclaration when requireInvocableTools=true.
|
||||
/// Verify that CreateAIAgent accepts declarative functions from definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAIAgentAsync_WithDeclarativeFunctionAndRequireInvocableTrue_ThrowsInvalidOperationExceptionAsync()
|
||||
public void CreateAIAgent_WithDeclarativeFunctionFromDefinition_AcceptsDeclarativeFunction()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
// Create a declarative function (not invocable) using AIFunctionFactory.CreateDeclaration
|
||||
using var doc = JsonDocument.Parse("{}");
|
||||
var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement);
|
||||
|
||||
// Add to definition
|
||||
definition.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
// Generate response with the declarative function
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definitionResponse.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.IsType<ChatClientAgent>(agent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgent accepts FunctionTools from definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithFunctionToolsInDefinition_AcceptsDeclarativeFunction()
|
||||
{
|
||||
// Arrange
|
||||
var functionTool = ResponseTool.CreateFunctionTool(
|
||||
functionName: "get_user_name",
|
||||
functionParameters: BinaryData.FromString("{}"),
|
||||
strictModeEnabled: false,
|
||||
functionDescription: "Gets the user's name, as used for friendly address."
|
||||
);
|
||||
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definition.Tools.Add(functionTool);
|
||||
|
||||
// Generate response with the declarative function
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definitionResponse.Tools.Add(functionTool);
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.IsType<ChatClientAgent>(agent);
|
||||
var definitionFromAgent = Assert.IsType<PromptAgentDefinition>(agent.GetService<AgentVersion>()?.Definition);
|
||||
Assert.Single(definitionFromAgent.Tools);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgentAsync accepts FunctionTools from definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAIAgentAsync_WithFunctionToolsInDefinition_AcceptsDeclarativeFunctionAsync()
|
||||
{
|
||||
// Arrange
|
||||
var functionTool = ResponseTool.CreateFunctionTool(
|
||||
functionName: "get_user_name",
|
||||
functionParameters: BinaryData.FromString("{}"),
|
||||
strictModeEnabled: false,
|
||||
functionDescription: "Gets the user's name, as used for friendly address."
|
||||
);
|
||||
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definition.Tools.Add(functionTool);
|
||||
|
||||
// Generate response with the declarative function
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definitionResponse.Tools.Add(functionTool);
|
||||
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.IsType<ChatClientAgent>(agent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgentAsync accepts declarative functions from definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAIAgentAsync_WithDeclarativeFunctionFromDefinition_AcceptsDeclarativeFunctionAsync()
|
||||
{
|
||||
// Arrange
|
||||
AgentsClient client = this.CreateTestAgentsClient();
|
||||
@@ -1311,20 +1359,22 @@ public sealed class AgentsClientExtensionsTests
|
||||
using var doc = JsonDocument.Parse("{}");
|
||||
var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement);
|
||||
|
||||
var tools = new List<AITool> { declarativeFunction };
|
||||
// Add to definition
|
||||
definition.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
// Act & Assert
|
||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
client.CreateAIAgentAsync("test-agent", definition, tools: tools, requireInvocableTools: true));
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", definition);
|
||||
|
||||
Assert.Contains("invokable AIFunctions", exception.Message);
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.IsType<ChatClientAgent>(agent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that CreateAIAgentAsync accepts declarative functions when requireInvocableTools=false.
|
||||
/// Verify that CreateAIAgentAsync accepts declarative functions from definition.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAIAgentAsync_WithDeclarativeFunctionAndRequireInvocableFalse_AcceptsDeclarativeFunctionAsync()
|
||||
public async Task CreateAIAgentAsync_WithDeclarativeFunctionInDefinition_AcceptsDeclarativeFunctionAsync()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
@@ -1333,7 +1383,8 @@ public sealed class AgentsClientExtensionsTests
|
||||
using var doc = JsonDocument.Parse("{}");
|
||||
var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement);
|
||||
|
||||
var tools = new List<AITool> { declarativeFunction };
|
||||
// Add to definition
|
||||
definition.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
// Generate response with the declarative function
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
@@ -1342,7 +1393,7 @@ public sealed class AgentsClientExtensionsTests
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", definition, tools: tools, requireInvocableTools: false);
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1354,23 +1405,19 @@ public sealed class AgentsClientExtensionsTests
|
||||
#region Options Generation Validation Tests
|
||||
|
||||
/// <summary>
|
||||
/// Verify that ChatClientAgentOptions are generated correctly with proper tool matching.
|
||||
/// Verify that ChatClientAgentOptions are generated correctly without tools.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_GeneratesCorrectChatClientAgentOptions()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "result", "test_tool", "A test tool")
|
||||
};
|
||||
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, tools);
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent("test-agent", definition, tools: tools);
|
||||
var agent = client.CreateAIAgent("test-agent", definition);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1560,26 +1607,21 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that agent created with tools and clientFactory is created successfully.
|
||||
/// Verify that agent created with clientFactory is created successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateAIAgent_WithToolsAndClientFactory_CreatesAgentSuccessfully()
|
||||
public void CreateAIAgent_WithClientFactory_CreatesAgentSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
var tools = new List<AITool>
|
||||
{
|
||||
AIFunctionFactory.Create(() => "test", "test_tool", "A test tool")
|
||||
};
|
||||
|
||||
var agentDefinitionResponse = GeneratePromptDefinitionResponse(definition, tools);
|
||||
var agentDefinitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AgentsClient client = this.CreateTestAgentsClient(agentName: "test-agent", agentDefinitionResponse: agentDefinitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = client.CreateAIAgent(
|
||||
"test-agent",
|
||||
definition,
|
||||
tools: tools,
|
||||
clientFactory: (innerClient) => new TestChatClient(innerClient));
|
||||
|
||||
// Assert
|
||||
@@ -1588,11 +1630,6 @@ public sealed class AgentsClientExtensionsTests
|
||||
Assert.NotNull(wrappedClient);
|
||||
var agentVersion = agent.GetService<AgentVersion>();
|
||||
Assert.NotNull(agentVersion);
|
||||
if (agentVersion.Definition is PromptAgentDefinition promptDef)
|
||||
{
|
||||
Assert.NotEmpty(promptDef.Tools);
|
||||
Assert.Single(promptDef.Tools);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1824,12 +1861,15 @@ public sealed class AgentsClientExtensionsTests
|
||||
}
|
||||
}
|
||||
|
||||
private static PromptAgentDefinition GeneratePromptDefinitionResponse(PromptAgentDefinition inputDefinition, List<AITool> tools)
|
||||
private static PromptAgentDefinition GeneratePromptDefinitionResponse(PromptAgentDefinition inputDefinition, List<AITool>? tools)
|
||||
{
|
||||
var definitionResponse = new PromptAgentDefinition(inputDefinition.Model) { Instructions = inputDefinition.Instructions };
|
||||
foreach (var tool in tools)
|
||||
if (tools is not null)
|
||||
{
|
||||
definitionResponse.Tools.Add(tool.GetService<ResponseTool>() ?? tool.AsOpenAIResponseTool());
|
||||
foreach (var tool in tools)
|
||||
{
|
||||
definitionResponse.Tools.Add(tool.GetService<ResponseTool>() ?? tool.AsOpenAIResponseTool());
|
||||
}
|
||||
}
|
||||
|
||||
return definitionResponse;
|
||||
|
||||
Reference in New Issue
Block a user