With the SDKs
Pass your functions viatools. 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’swait_for_completion/waitForCompletionwith the sametools. - 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
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
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
Post the result
Execute the call and post the result, echoing the pending call back as Send several at once with The agent resumes once every pending call has a result. Calls still unresolved when the run ends (for example on
tool_req:{"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
max_time_s) fail with a model-visible error. Posting to a finished session returns 409.