error_kind instead of an opaque error string — so your agent can decide to retry, switch tools, or abort.
Backward compatible. All new parameters are optional. With no
timeout_ms and no cancel_token, execution delegates straight to the tool body — behaviour is unchanged.Quick Start
Add a hard deadline
Pass
timeout_ms (milliseconds) to execute_batch. A tool that runs longer is abandoned on a dedicated worker and returns a typed timeout result — the turn never hangs.Add a cancel token
Pass any The token is duck-typed:
threading.Event-like token. Signal it from another thread to short-circuit pending calls with a typed cancelled result.threading.Event (.is_set()) and InterruptController-like tokens (.is_cancelled / .cancelled) both work — no concrete import required.How It Works
Because Python threads can’t be force-killed, a timed-out tool’s worker is abandoned (not joined) and a typed result is returned immediately — the turn keeps moving. Both executors forwardtimeout_ms and cancel_token:
error_kind Reference
ToolResult.error_kind is a discriminated tag; ToolResult.structured_error is None on success and a discriminated dict on failure.
error_kind | Exception | result payload | Example structured_error |
|---|---|---|---|
timeout | ToolTimeoutError | {"error": "timeout", "timeout_ms": ..., "tool": ...} | {"error": true, "kind": "timeout", "type": "ToolTimeoutError", "message": "...", "tool": "search"} |
cancelled | ToolCancelledError | {"error": "cancelled", "tool": ...} | {"error": true, "kind": "cancelled", "type": "ToolCancelledError", "message": "...", "tool": "search"} |
error | the raised exception | "Error executing tool: ..." | {"error": true, "kind": "error", "type": "ValueError", "message": "...", "tool": "search"} |
Timeout, Cancel, or Both?
Config default via ToolExecutionConfig
Config default via ToolExecutionConfig
ToolExecutionConfig.timeout_ms is now consumed by the executor, so a configured default flows through to execute_batch without per-call wiring.Parallel batches
Parallel batches
ParallelToolCallExecutor enforces the same per-tool timeout inside each worker, so one hung tool resolves to a typed timeout result instead of blocking collection of the others.Related
Parallel Tool Calls
Run batched tool calls concurrently
Tool Progress
Stream incremental progress from slow tools
Deferred Tools
Hand back long-running work without blocking
Tools Overview
Build and register agent tools

