Function Call Dispatcher
The dispatcher is where the harness pays for every promise the schema made. Timeouts, retries, dedupe, error mapping. All on one seam. Wrap a tool handler in a per-call timeout that returns a typed error instead of hanging the loop. Apply exponential backoff retry with jitter and a maximum attempt count. Deduplicate retries on an idempotency key so a retry that races with a slow original does not run twice. Map handler exceptions and transport faults onto a single error envelope the harness loop already understands. Bound parallel dispatch with a concurrency limit so a fan-out of forty tool calls does not exhaust the event loop. Between the harness loop (lesson twenty) and the tool registry (lesson twenty-one). The transport (lesson twenty-two) feeds the loop. The loop hands a tool call to the dispatcher. The dispatcher calls the registry, runs the handler, and returns either a result or a JSON-RPC-shaped error envelope. The dispatcher is the only layer that knows about timers, retries, and idempotency. The loop does not. The registry does not. The handler does not. That isolation is the point. Each tool has a default timeout. The registry record carries timeoutms. The dispatcher overrides it from a per-call override when the harness passes one. We use asyncio.waitfor. On timeout, the handler task is cancelled and the dispatcher returns…
Function Call Dispatcher: The dispatcher is where the harness pays for every promise the schema made. Timeouts, retries, dedupe, error mapping. All on one seam.
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.