Python: Centralize tool result parsing in FunctionTool.invoke() (#3854)

* Centralize tool result parsing in FunctionTool.invoke()

- Add parse_result static method to FunctionTool that converts raw
  function return values to strings at invocation time
- Add result_parser parameter to FunctionTool and @tool decorator
  for custom parsing
- Remove prepare_function_call_results from all 9 consumer files
  and from the public API
- Update MCPTool to parse MCP types directly to strings via
  _parse_tool_result_from_mcp and _parse_prompt_result_from_mcp
- Change MCPTool parse_tool_results/parse_prompt_results type from
  Literal[True] | Callable | None to Callable | None
- Remove ReturnT type parameter from FunctionTool (now single
  generic ArgsT since invoke() always returns str)
- Update all subclass signatures and docstrings

Fixes #1147

* Fix test_mcp_tool_call_tool_with_meta_integration for string results

The test was still accessing result[0].additional_properties but
invoke() now returns a string, not a list of Content objects.

* Fix SIM108 lint: use binary operator for output assignment

* Fix bedrock: use FunctionTool.parse_result instead of str() fallback

str(result) turns None into literal 'None' and dicts into Python reprs
with single quotes, breaking JSON parsing. Use the shared parse_result
which handles None as '' and serializes via json.dumps.

* updated lock

* updates from feedback
This commit is contained in:
Eduard van Valkenburg
2026-02-12 14:49:42 +01:00
committed by GitHub
Unverified
parent 6000b737e9
commit 8ed50009c6
31 changed files with 486 additions and 452 deletions
@@ -499,7 +499,7 @@ class GitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
return copilot_tools
def _tool_to_copilot_tool(self, ai_func: FunctionTool[Any, Any]) -> CopilotTool:
def _tool_to_copilot_tool(self, ai_func: FunctionTool[Any]) -> CopilotTool:
"""Convert an FunctionTool to a Copilot SDK tool."""
async def handler(invocation: ToolInvocation) -> ToolResult: