|
1 | 1 | """Functions/Tools definition.""" |
2 | 2 |
|
3 | 3 | import asyncio |
| 4 | +import json |
4 | 5 | import logging |
5 | 6 |
|
6 | 7 | from langchain_core.messages import ToolMessage |
@@ -40,7 +41,7 @@ async def execute_tool_call( |
40 | 41 | """Execute a tool call and return the output and status.""" |
41 | 42 | try: |
42 | 43 | tool = get_tool_by_name(tool_name, all_mcp_tools) |
43 | | - tool_output = await tool.arun(tool_args) # type: ignore [attr-defined] |
| 44 | + tool_output = await tool.arun(_jsonify(tool_args)) # type: ignore [attr-defined] |
44 | 45 | status = "success" |
45 | 46 | logger.debug( |
46 | 47 | "Tool: %s | Args: %s | Output: %s", tool_name, tool_args, tool_output |
@@ -100,3 +101,26 @@ async def execute_tool_calls( |
100 | 101 | tool_messages = await asyncio.gather(*tasks) |
101 | 102 |
|
102 | 103 | return tool_messages |
| 104 | + |
| 105 | + |
| 106 | +def _jsonify(args: dict) -> dict: |
| 107 | + """Convert to JSON.""" |
| 108 | + res = {} |
| 109 | + for key, value in args.items(): |
| 110 | + if isinstance(value, str) and _maybe_json(value): |
| 111 | + # If a value looks like json |
| 112 | + try: |
| 113 | + # convert to json |
| 114 | + res[key] = json.loads(value) |
| 115 | + except json.JSONDecodeError: |
| 116 | + # conversion fails, use a string |
| 117 | + res[key] = value |
| 118 | + else: |
| 119 | + res[key] = value |
| 120 | + return res |
| 121 | + |
| 122 | + |
| 123 | +def _maybe_json(value: str) -> bool: |
| 124 | + """Check if a string looks like JSON.""" |
| 125 | + stripped = value.strip() |
| 126 | + return stripped.startswith(("[", "{")) |
0 commit comments