mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into feature-foundry-agents
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Shared.Diagnostics;
|
||||
|
||||
namespace Microsoft.Agents.AI;
|
||||
@@ -32,6 +33,7 @@ public class AgentRunOptions
|
||||
_ = Throw.IfNull(options);
|
||||
this.ContinuationToken = options.ContinuationToken;
|
||||
this.AllowBackgroundResponses = options.AllowBackgroundResponses;
|
||||
this.AdditionalProperties = options.AdditionalProperties?.Clone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,4 +76,18 @@ public class AgentRunOptions
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public bool? AllowBackgroundResponses { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets additional properties associated with these options.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An <see cref="AdditionalPropertiesDictionary"/> containing custom properties,
|
||||
/// or <see langword="null"/> if no additional properties are present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// Additional properties provide a way to include custom metadata or provider-specific
|
||||
/// information that doesn't fit into the standard options schema. This is useful for
|
||||
/// preserving implementation-specific details or extending the options with custom data.
|
||||
/// </remarks>
|
||||
public AdditionalPropertiesDictionary? AdditionalProperties { get; set; }
|
||||
}
|
||||
|
||||
@@ -18,7 +18,12 @@ public class AgentRunOptionsTests
|
||||
var options = new AgentRunOptions
|
||||
{
|
||||
ContinuationToken = new object(),
|
||||
AllowBackgroundResponses = true
|
||||
AllowBackgroundResponses = true,
|
||||
AdditionalProperties = new AdditionalPropertiesDictionary
|
||||
{
|
||||
["key1"] = "value1",
|
||||
["key2"] = 42
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
@@ -28,6 +33,10 @@ public class AgentRunOptionsTests
|
||||
Assert.NotNull(clone);
|
||||
Assert.Same(options.ContinuationToken, clone.ContinuationToken);
|
||||
Assert.Equal(options.AllowBackgroundResponses, clone.AllowBackgroundResponses);
|
||||
Assert.NotNull(clone.AdditionalProperties);
|
||||
Assert.NotSame(options.AdditionalProperties, clone.AdditionalProperties);
|
||||
Assert.Equal("value1", clone.AdditionalProperties["key1"]);
|
||||
Assert.Equal(42, clone.AdditionalProperties["key2"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -42,7 +51,12 @@ public class AgentRunOptionsTests
|
||||
var options = new AgentRunOptions
|
||||
{
|
||||
ContinuationToken = ResponseContinuationToken.FromBytes(new byte[] { 1, 2, 3 }),
|
||||
AllowBackgroundResponses = true
|
||||
AllowBackgroundResponses = true,
|
||||
AdditionalProperties = new AdditionalPropertiesDictionary
|
||||
{
|
||||
["key1"] = "value1",
|
||||
["key2"] = 42
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
@@ -54,5 +68,13 @@ public class AgentRunOptionsTests
|
||||
Assert.NotNull(deserialized);
|
||||
Assert.Equivalent(ResponseContinuationToken.FromBytes(new byte[] { 1, 2, 3 }), deserialized!.ContinuationToken);
|
||||
Assert.Equal(options.AllowBackgroundResponses, deserialized.AllowBackgroundResponses);
|
||||
Assert.NotNull(deserialized.AdditionalProperties);
|
||||
Assert.Equal(2, deserialized.AdditionalProperties.Count);
|
||||
Assert.True(deserialized.AdditionalProperties.TryGetValue("key1", out object? value1));
|
||||
Assert.IsType<JsonElement>(value1);
|
||||
Assert.Equal("value1", ((JsonElement)value1!).GetString());
|
||||
Assert.True(deserialized.AdditionalProperties.TryGetValue("key2", out object? value2));
|
||||
Assert.IsType<JsonElement>(value2);
|
||||
Assert.Equal(42, ((JsonElement)value2!).GetInt32());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ from mcp.client.websocket import websocket_client
|
||||
from mcp.shared.context import RequestContext
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.shared.session import RequestResponder
|
||||
from pydantic import BaseModel, create_model
|
||||
from pydantic import BaseModel, Field, create_model
|
||||
|
||||
from ._tools import AIFunction, HostedMCPSpecificApproval
|
||||
from ._types import ChatMessage, Contents, DataContent, Role, TextContent, UriContent
|
||||
@@ -224,13 +224,20 @@ def _get_input_model_from_mcp_tool(tool: types.Tool) -> type[BaseModel]:
|
||||
prop_details = json.loads(prop_details) if isinstance(prop_details, str) else prop_details
|
||||
|
||||
python_type = resolve_type(prop_details)
|
||||
description = prop_details.get("description", "")
|
||||
|
||||
# Create field definition for create_model
|
||||
if prop_name in required:
|
||||
field_definitions[prop_name] = (python_type, ...)
|
||||
field_definitions[prop_name] = (
|
||||
(python_type, Field(description=description)) if description else (python_type, ...)
|
||||
)
|
||||
else:
|
||||
default_value = prop_details.get("default", None)
|
||||
field_definitions[prop_name] = (python_type, default_value)
|
||||
field_definitions[prop_name] = (
|
||||
(python_type, Field(default=default_value, description=description))
|
||||
if description
|
||||
else (python_type, default_value)
|
||||
)
|
||||
|
||||
return create_model(f"{tool.name}_input", **field_definitions)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user