From d59bd20765cf42017665d37520a02fdfd459400a Mon Sep 17 00:00:00 2001 From: Giles Odigwe <79032838+giles17@users.noreply.github.com> Date: Tue, 11 Nov 2025 11:43:26 -0800 Subject: [PATCH 1/2] Python: Fix MCP Tool Parameter Descriptions Not Propagated to LLMs (#1978) * mcp tool description fix * small fix --- python/packages/core/agent_framework/_mcp.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/python/packages/core/agent_framework/_mcp.py b/python/packages/core/agent_framework/_mcp.py index 50f6a91c2e..873b7f04cc 100644 --- a/python/packages/core/agent_framework/_mcp.py +++ b/python/packages/core/agent_framework/_mcp.py @@ -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) From 180f82373b113e5f5a7f5992795c62108777c025 Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Tue, 11 Nov 2025 17:00:59 -0300 Subject: [PATCH 2/2] .NET: Allow extending agent run options via additional properties (#1872) * Allow extending agent run options via additional properties This mirrors the M.E.AI model in ChatOptions.AdditionalProperties which is very useful when building functionality pipelines. Fixes https://github.com/microsoft/agent-framework/issues/1815 * Expand XML documentation Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add AdditionalProperties tests to AgentRunOptions Co-authored-by: kzu <169707+kzu@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: kzu <169707+kzu@users.noreply.github.com> --- .../AgentRunOptions.cs | 16 ++++++++++++ .../AgentRunOptionsTests.cs | 26 +++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunOptions.cs b/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunOptions.cs index c6a64915cf..7262979207 100644 --- a/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunOptions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunOptions.cs @@ -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(); } /// @@ -74,4 +76,18 @@ public class AgentRunOptions /// /// public bool? AllowBackgroundResponses { get; set; } + + /// + /// Gets or sets additional properties associated with these options. + /// + /// + /// An containing custom properties, + /// or if no additional properties are present. + /// + /// + /// 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. + /// + public AdditionalPropertiesDictionary? AdditionalProperties { get; set; } } diff --git a/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunOptionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunOptionsTests.cs index 40901a4969..32560949fb 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunOptionsTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunOptionsTests.cs @@ -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(value1); + Assert.Equal("value1", ((JsonElement)value1!).GetString()); + Assert.True(deserialized.AdditionalProperties.TryGetValue("key2", out object? value2)); + Assert.IsType(value2); + Assert.Equal(42, ((JsonElement)value2!).GetInt32()); } }