Skip to main content
The environment supplies the agent’s core tools. Custom tools are functions from your own code: the agent calls one mid-run, your process executes it, and the run continues with the result.

With the SDKs

Pass your functions via tools. Python derives the schema from the signature and docstring. TypeScript declares it with tool(). The SDK runs the whole loop.
  • Functions may be sync or async. Exceptions reach the agent as tool errors and don’t crash the run.
  • Tools run in the process that polls the session: only while your program waits on run_session / runSession, or on a handle’s wait_for_completion / waitForCompletion with the same tools.
  • Execution is at-least-once: if posting a result fails and the wait retries, the tool may run again. Make side-effecting tools idempotent.

Over the raw API

1

Declare the tools at session create

Declare the tools when creating the session, inline on the agent or via the agent.tools override for a registered agent:
Session create body
2

Detect the pending call

Long-poll changes for an ActiveStateChangeEvent whose data.state is "awaiting_tool_results". Its data.pending_tool_calls lists each pending call as a { tool_name, args, id } object:
Pending tool call event
3

Post the result

Execute the call and post the result, echoing the pending call back as tool_req:
Send several at once with {"type": "batch", "results": [...]}. Report a failure as an error_event instead of a tool_result. It carries error, origin (both required), and the echoed tool_req:
Tool error report
The agent resumes once every pending call has a result. Calls still unresolved when the run ends (for example on max_time_s) fail with a model-visible error. Posting to a finished session returns 409.
Related: Two-factor authentication (a built-in tool for one-time codes), Watch and steer sessions