Overview
run() returns a handle, not a completed report. Save its ID and poll the run.
typescript
const result = await agent.wait(savedRunId);
if (result.status === 'completed') {
console.log(result.report?.markdown);
console.log(result.structured_output);
} else {
console.log('Run did not complete:', result.status);
}python
result = agent.wait(saved_run_id)
if result.get("status") == "completed":
print(result.get("report"))
else:
print("Run did not complete:", result.get("status"))Terminal statuses
| Status | What to do |
|---|---|
| completed | Read the report and any structured output |
| failed | Inspect the run before deciding whether to retry |
| cancelled | Treat the requested work as unfinished |
| blocked | Inspect the run for required action |
Optional report fields may be absent. Do not assume every terminal run includes a usable report.
Resume after a timeout
Use getRun(savedRunId) in TypeScript or get_run(saved_run_id) in Python to inspect the current state. Call wait again to continue polling the same run. This does not create another run.
Cancellation
The TypeScript SDK exposes cancelRun(id). Aborting an HTTP request or polling loop does not call this endpoint. Python exposes cancel_run(id) with the same explicit cancellation behavior.
Structured output
Pass outputSchema in TypeScript or output_schema in Python when submitting a run or batch. Successful responses can include structured_output alongside report. Customer-defined schemas, plans, and output keys are preserved; only resource envelopes are normalized to SDK names such as id. A run ID can be used to retrieve its full report from a batch or campaign row.
Pagination
typescript
let cursor: string | undefined;
do {
const page = await client.listRuns({ cursor, limit: 50 });
for (const run of page.items) console.log(run.id, run.status);
cursor = page.next_cursor ?? undefined;
} while (cursor);python
cursor = None
while True:
page = client.list_runs(cursor=cursor, limit=50)
for run in page["items"]:
print(run["id"], run["status"])
cursor = page.get("next_cursor")
if not cursor:
breakUse the same cursor pattern for batch and campaign lists and campaign portfolios. Cursors are opaque; do not construct them yourself. Agent and catalog lists use their own response envelopes instead of this cursor pattern.