diff --git a/packages/uipath/src/uipath/agent/models/agent.py b/packages/uipath/src/uipath/agent/models/agent.py index 385a37e7c..09c6f2dd0 100644 --- a/packages/uipath/src/uipath/agent/models/agent.py +++ b/packages/uipath/src/uipath/agent/models/agent.py @@ -454,6 +454,22 @@ def datafabric_entity_identifiers(self) -> list[str]: return [] +class McpToolTaskSupport(str, CaseInsensitiveEnum): + """Whether an MCP tool may be invoked as a task (MCP 2025-11-25 ``execution.taskSupport``).""" + + FORBIDDEN = "forbidden" + OPTIONAL = "optional" + REQUIRED = "required" + + +class AgentMcpToolExecution(BaseCfg): + """Execution metadata for an MCP tool, mirroring the MCP tool's ``execution`` object.""" + + task_support: McpToolTaskSupport = Field( + default=McpToolTaskSupport.FORBIDDEN, alias="taskSupport" + ) + + class AgentMcpTool(BaseCfg): """Agent MCP tool model.""" @@ -464,6 +480,9 @@ class AgentMcpTool(BaseCfg): argument_properties: Dict[str, AgentToolArgumentProperties] = Field( {}, alias="argumentProperties" ) + # MCP 2025-11-25 task support, when the snapshot/server provides it. Absent for older + # snapshots, in which case the tool is treated as not task-augmentable. + execution: Optional[AgentMcpToolExecution] = Field(None, alias="execution") class DynamicToolsMode(str, CaseInsensitiveEnum): diff --git a/packages/uipath/tests/agent/models/test_agent.py b/packages/uipath/tests/agent/models/test_agent.py index c324d4e7e..cafd40e87 100644 --- a/packages/uipath/tests/agent/models/test_agent.py +++ b/packages/uipath/tests/agent/models/test_agent.py @@ -32,6 +32,7 @@ AgentIxpExtractionResourceConfig, AgentIxpVsEscalationResourceConfig, AgentMcpResourceConfig, + AgentMcpTool, AgentMessageRole, AgentNumberOperator, AgentNumberRule, @@ -52,6 +53,7 @@ BatchTransformWebSearchGrounding, CitationMode, DeepRagFileExtension, + McpToolTaskSupport, StandardRecipient, TaskTitleType, TextBuilderTaskTitle, @@ -2034,6 +2036,30 @@ def test_mcp_resource_with_output_schema(self): assert tool2.output_schema is not None assert "content" in tool2.output_schema["properties"] + def test_mcp_tool_parses_execution_task_support(self): + """AgentMcpTool carries the MCP execution.taskSupport signal when present.""" + tool = AgentMcpTool.model_validate( + { + "name": "invoke-process", + "description": "Run a long-running process", + "inputSchema": {"type": "object", "properties": {}}, + "execution": {"taskSupport": "optional"}, + } + ) + assert tool.execution is not None + assert tool.execution.task_support == McpToolTaskSupport.OPTIONAL + + def test_mcp_tool_without_execution_defaults_to_none(self): + """Older snapshots without execution leave it unset (treated as not task-augmentable).""" + tool = AgentMcpTool.model_validate( + { + "name": "echo", + "description": "Echo", + "inputSchema": {"type": "object", "properties": {}}, + } + ) + assert tool.execution is None + @pytest.mark.parametrize( "recipient_type_int,value,expected_type", [