Neural Mastery
← Practice
Dispatch Tool Calls Without Crashing the Agenteasy

Dispatch Tool Calls Without Crashing the Agent

easy Build an Agent 10–15 min

Standard library only · runs in your browser

Tools fail all the time: a city with no data, a divide by zero, a tool name the model invented. A production dispatcher turns every one of those into an observation the model can read. It never raises one that kills the run.

Task

Implement dispatch(call), where call is {"tool": name, "arguments": {...}} (what stage 1 returns). Look the tool up in the provided TOOLS registry and always return a string:

  • Unknown tool: error: unknown tool 'NAME'. available tools: add, divide, get_weather, lookup_doc (names sorted, comma-separated)
  • Invalid arguments (use your stage-2 validate_arguments, provided below): error: invalid arguments for 'NAME': followed by the errors joined with ;
  • The tool raises: error: NAME raised ExceptionType: message
  • Success: the result itself if it's a string, otherwise json.dumps(result)

Function Signature

dispatch(call: dict) -> str

Examples

Example 1: Numeric result is serialized
Input: call = {'tool': 'add', 'arguments': {'a': 2, 'b': 3}}
Output: '5'
Example 2: String result is returned as-is
Input: call = {'tool': 'get_weather', 'arguments': {'city': 'Paris'}}
Output: '18C, light rain'
Example 3: Hallucinated tool name
Input: call = {'tool': 'search_web', 'arguments': {'query': 'x'}}
Output: 'error: unknown tool \'search_web\'. available tools: add, divide, get_weather, lookup_doc'
Example 4: A tool that raises
Input: call = {'tool': 'divide', 'arguments': {'a': 1, 'b': 0}}
Output: 'error: divide raised ZeroDivisionError: division by zero'

Constraints

  • Never let an exception escape `dispatch`.
  • Every return value is a `str`: the model only reads text.
  • `TOOLS[name]` is `{"fn": callable, "schema": dict}`, so call it as `fn(**arguments)`.
Python3Saved ✓
import json
import math
import re


def dispatch(call):
"""Run call["tool"] with call["arguments"]; always return a string observation."""
# Your code here
pass


# =============================================================================
# PROVIDED BELOW -- the sandbox and your earlier stages. Read it, don't edit it.
# =============================================================================
# ---------------------------------------------------------------------------
# The sandbox world your agent lives in (provided -- you don't edit this).
# Four deterministic tools, each with a JSON-Schema-style argument spec,
# exactly the shape you'd hand a real model's tool-calling API.
# ---------------------------------------------------------------------------
WEATHER = {"paris": "18C, light rain", "tokyo": "24C, clear", "lima": "16C, overcast"}
DOCS = {
"refund-policy": "Refunds are accepted within 30 days with a receipt.",
"shipping": "Standard shipping takes 3-5 business days.",
}


def add(a, b):
return a + b


def divide(a, b):
return a / b


def get_weather(city):
key = city.strip().lower()
Case 1: Numeric result is serialized
Input: call = {'tool': 'add', 'arguments': {'a': 2, 'b': 3}}
Expected: '5'
Case 2: String result is returned as-is
Input: call = {'tool': 'get_weather', 'arguments': {'city': 'Paris'}}
Expected: '18C, light rain'
Case 3: Hallucinated tool name
Input: call = {'tool': 'search_web', 'arguments': {'query': 'x'}}
Expected: 'error: unknown tool \'search_web\'. available tools: add, divide, get_weather, lookup_doc'
Case 4: A tool that raises
Input: call = {'tool': 'divide', 'arguments': {'a': 1, 'b': 0}}
Expected: 'error: divide raised ZeroDivisionError: division by zero'