Spaces:
Sleeping
Sleeping
Download src/executor.py from FlyingNunchucks/07-tool-using-agent: direct link, hf CLI and curl.
- Browser
- Download file 4.91 kB
-
https://huggingface.co/spaces/FlyingNunchucks/07-tool-using-agent/resolve/main/src/executor.py
- Command line
-
hf download hf://spaces/FlyingNunchucks/07-tool-using-agent/src/executor.py
-
curl -L -o executor.py https://huggingface.co/spaces/FlyingNunchucks/07-tool-using-agent/resolve/main/src/executor.py
4.91 kB
| from datetime import datetime, timezone | |
| from time import perf_counter | |
| from typing import Any, Dict | |
| from src.schemas import ToolAuthorization, ToolCall, ToolResult | |
| from src.tool_registry import TOOL_REGISTRY, get_tool | |
| def _validate_arguments( | |
| tool_name: str, | |
| arguments: Dict[str, Any], | |
| ) -> None: | |
| """Validate arguments against the application-owned tool schema.""" | |
| if tool_name not in TOOL_REGISTRY: | |
| raise ValueError( | |
| f"Tool '{tool_name}' is not registered." | |
| ) | |
| schema = TOOL_REGISTRY[tool_name]["parameters"] | |
| properties = schema.get("properties", {}) | |
| required = schema.get("required", []) | |
| allow_additional = schema.get( | |
| "additionalProperties", | |
| True, | |
| ) | |
| for required_argument in required: | |
| if required_argument not in arguments: | |
| raise ValueError( | |
| f"Missing required argument " | |
| f"'{required_argument}' for tool " | |
| f"'{tool_name}'." | |
| ) | |
| if not allow_additional: | |
| unknown_arguments = ( | |
| set(arguments.keys()) - set(properties.keys()) | |
| ) | |
| if unknown_arguments: | |
| unknown = ", ".join( | |
| sorted(unknown_arguments) | |
| ) | |
| raise ValueError( | |
| f"Unexpected argument(s) for tool " | |
| f"'{tool_name}': {unknown}" | |
| ) | |
| python_types = { | |
| "string": str, | |
| "integer": int, | |
| "number": (int, float), | |
| "boolean": bool, | |
| "object": dict, | |
| "array": list, | |
| } | |
| for argument_name, argument_value in arguments.items(): | |
| parameter_schema = properties.get(argument_name) | |
| if not parameter_schema: | |
| continue | |
| expected_type_name = parameter_schema.get("type") | |
| if not expected_type_name: | |
| continue | |
| expected_python_type = python_types.get( | |
| expected_type_name | |
| ) | |
| if expected_python_type is None: | |
| continue | |
| if not isinstance( | |
| argument_value, | |
| expected_python_type, | |
| ): | |
| raise TypeError( | |
| f"Argument '{argument_name}' for tool " | |
| f"'{tool_name}' must be of type " | |
| f"'{expected_type_name}'." | |
| ) | |
| def authorize_tool_call(call: ToolCall) -> ToolAuthorization: | |
| """Decide whether a model-proposed tool call may execute.""" | |
| try: | |
| _validate_arguments( | |
| tool_name=call.tool_name, | |
| arguments=call.arguments, | |
| ) | |
| except Exception as exc: | |
| return ToolAuthorization( | |
| call_id=call.call_id, | |
| tool_name=call.tool_name, | |
| status="blocked", | |
| reason=f"{type(exc).__name__}: {exc}", | |
| ) | |
| return ToolAuthorization( | |
| call_id=call.call_id, | |
| tool_name=call.tool_name, | |
| status="approved", | |
| reason=( | |
| "Tool is registered and arguments match the approved schema." | |
| ), | |
| ) | |
| def execute_authorized_tool( | |
| call: ToolCall, | |
| authorization: ToolAuthorization, | |
| ) -> ToolResult: | |
| """Execute only a previously authorized call and normalize its result.""" | |
| started_at = datetime.now(timezone.utc) | |
| timer_start = perf_counter() | |
| if authorization.call_id != call.call_id: | |
| raise ValueError("Authorization call_id does not match tool call.") | |
| if authorization.tool_name != call.tool_name: | |
| raise ValueError("Authorization tool_name does not match tool call.") | |
| if authorization.status == "blocked": | |
| completed_at = datetime.now(timezone.utc) | |
| duration_ms = (perf_counter() - timer_start) * 1000 | |
| return ToolResult( | |
| call_id=call.call_id, | |
| tool_name=call.tool_name, | |
| status="blocked", | |
| output=None, | |
| error=authorization.reason, | |
| started_at=started_at, | |
| completed_at=completed_at, | |
| duration_ms=round(duration_ms, 3), | |
| ) | |
| try: | |
| tool = get_tool(call.tool_name) | |
| output = tool(**call.arguments) | |
| status = "success" | |
| error = None | |
| except Exception as exc: | |
| output = None | |
| status = "error" | |
| error = f"{type(exc).__name__}: {exc}" | |
| completed_at = datetime.now(timezone.utc) | |
| duration_ms = (perf_counter() - timer_start) * 1000 | |
| return ToolResult( | |
| call_id=call.call_id, | |
| tool_name=call.tool_name, | |
| status=status, | |
| output=output, | |
| error=error, | |
| started_at=started_at, | |
| completed_at=completed_at, | |
| duration_ms=round(duration_ms, 3), | |
| ) | |
| def execute_tool(call: ToolCall) -> ToolResult: | |
| """Authorize and execute one tool call through the controlled boundary.""" | |
| authorization = authorize_tool_call(call) | |
| return execute_authorized_tool( | |
| call=call, | |
| authorization=authorization, | |
| ) | |