Spaces:
Paused
Paused
| import asyncio | |
| import json | |
| import os | |
| import time | |
| from typing import Any, Dict, List, Optional, Set | |
| def tool_get_current_time(params: Dict[str, Any]) -> Dict[str, Any]: | |
| return {"current_time": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())} | |
| def tool_echo(params: Dict[str, Any]) -> Dict[str, Any]: | |
| return {"echo": params} | |
| def tool_sum(params: Dict[str, Any]) -> Dict[str, Any]: | |
| values = params.get("values") | |
| if isinstance(values, list): | |
| try: | |
| total = sum(float(v) for v in values) | |
| except Exception: | |
| total = None | |
| else: | |
| total = None | |
| return {"sum": total, "count": len(values) if isinstance(values, list) else 0} | |
| FUNCTION_REGISTRY = { | |
| "get_current_time": tool_get_current_time, | |
| "echo": tool_echo, | |
| "sum": tool_sum, | |
| } | |
| # Runtime-allowed tool names from incoming requests (OpenAI tools array) | |
| _ALLOWED_RUNTIME_TOOLS: Set[str] = set() | |
| _runtime_mcp_endpoint: Optional[str] = None | |
| def register_runtime_tools( | |
| tools: Optional[List[Dict[str, Any]]], mcp_endpoint: Optional[str] = None | |
| ) -> None: | |
| """Register tool names declared in the request as allowed. | |
| The server may delegate unknown tools to MCP if configured. | |
| """ | |
| # Reset per-request registry to avoid leakage across requests | |
| global _runtime_mcp_endpoint | |
| _ALLOWED_RUNTIME_TOOLS.clear() | |
| _runtime_mcp_endpoint = None | |
| if not tools: | |
| return | |
| try: | |
| for t in tools: | |
| name = None | |
| fn = t.get("function") if "function" in t else t | |
| if isinstance(fn, dict): | |
| name = fn.get("name") or t.get("name") | |
| else: | |
| name = t.get("name") | |
| if name: | |
| _ALLOWED_RUNTIME_TOOLS.add(str(name)) | |
| # Detect per-tool endpoint extension | |
| ext_ep = ( | |
| t.get("x-mcp-endpoint") | |
| or t.get("x_mcp_endpoint") | |
| or ( | |
| isinstance(t.get("function"), dict) | |
| and t["function"].get("x-mcp-endpoint") | |
| ) | |
| or None | |
| ) | |
| if ext_ep and not mcp_endpoint: | |
| mcp_endpoint = ext_ep | |
| # Capture per-request MCP endpoint if provided (explicit or via tool extension) | |
| if mcp_endpoint: | |
| _runtime_mcp_endpoint = mcp_endpoint | |
| except Exception: | |
| # be forgiving on malformed tools | |
| pass | |
| async def execute_tool_call(name: str, arguments_json: str) -> str: | |
| """Execute registered tools and return stringified result. Unknown tools return descriptive errors. | |
| Fully asynchronous: built-in functions execute directly; MCP path uses async httpx client. | |
| """ | |
| try: | |
| params = json.loads(arguments_json or "{}") | |
| except Exception: | |
| params = {} | |
| func = FUNCTION_REGISTRY.get(name) | |
| if not func: | |
| # If tool is not built-in but declared, try MCP adapter if configured (env or per-request) | |
| if name in _ALLOWED_RUNTIME_TOOLS: | |
| try: | |
| from api_utils.mcp_adapter import ( | |
| execute_mcp_tool, | |
| execute_mcp_tool_with_endpoint, | |
| ) | |
| if _runtime_mcp_endpoint: | |
| return await execute_mcp_tool_with_endpoint( | |
| _runtime_mcp_endpoint, name, params | |
| ) | |
| if os.environ.get("MCP_HTTP_ENDPOINT"): | |
| return await execute_mcp_tool(name, params) | |
| except asyncio.CancelledError: | |
| raise | |
| except Exception as e: | |
| return json.dumps( | |
| {"error": f"MCP execution failed: {e}"}, ensure_ascii=False | |
| ) | |
| return json.dumps( | |
| {"error": f"Unknown tool: {name}", "arguments": params}, ensure_ascii=False | |
| ) | |
| try: | |
| result = func(params) | |
| return json.dumps(result, ensure_ascii=False) | |
| except Exception as e: | |
| return json.dumps({"error": f"Execution failed: {e}"}, ensure_ascii=False) | |