Skip to content

Requested replies and decisions

Use this reference with the complete developer tour and Python types. The example at the end runs after the tour setup.

Open an independent requested decision for each selected recipient.

ask_batch(self, targets: list[dict[str, str]], request: dict[str, Any], *, key: str | None=None, **options: Any)
Parameter Type and default Usage
targets list[dict[str, str]] (required) Explicit targets for a private batch or shared chat. These have different audience semantics.
request dict[str, Any] (required) Nested requested-decision input or canonical request in a batch result.
key str | None (default None) Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation.
**options keyword fields (default optional) Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism.

Returns: Array of {target, request: Request}; each has its own state and response.

Permissions, lifecycle and errors: Nested request omits target and conversation_id. All-or-nothing creation does not mean all-or-nothing decisions. A saved key recovers the same requests.

Working Python example. Input/output fields are in the types reference.

Ask for a durable, typed final answer, approval or task result.

ask(self, *, target: dict[str, str] | None=None, title: str='', key: str | None=None, **options: Any)
Parameter Type and default Usage
target dict[str, str] | None (default None) Target kind and stable ID. Choose a new target or an existing conversation, not both.
title str (default ‘’) Optional short label. A normal message does not require a title.
key str | None (default None) Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation.
**options keyword fields (default optional) Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism.

Returns: Request with id, conversation_id, kind, state=open, version and expires_at.

Permissions, lifecycle and errors: kind defaults to question. Question, approval and task have different allowed outcomes. Normal follow-up messages do not close it. Ordinary communication has no implicit deadline. Bound action approvals default to seven days. An explicit expiry must be within ninety days.

Working Python example. Input/output fields are in the types reference.

Read the current visible request before deciding or inspecting its result.

get_request(self, request_id: str)
Parameter Type and default Usage
request_id str (required) Canonical durable request ID. This is not a worker delivery ID.

Returns: Request, including optional response and current version.

Permissions, lifecycle and errors: A 404 can mean not visible. Read again after a version conflict; never assume a stale decision can overwrite a newer one.

Working Python example. Input/output fields are in the types reference.

Record an authorized final typed decision using the current version.

respond(self, request_id: str, outcome: str, *, version: int, answer: Any=None)
Parameter Type and default Usage
request_id str (required) Canonical durable request ID. This is not a worker delivery ID.
outcome str (required) Typed final result: answered; approved/denied; or completed/failed/rejected according to request kind.
version int (required) Current optimistic-concurrency version. Read the object before a guarded change; a stale version conflicts.
answer Any (default None) JSON response value; for choices, the selected exact string.

Returns: Updated Request, including response and terminal state.

Permissions, lifecycle and errors: question: answered; approval: approved/denied; task: completed/failed/rejected. A choice answer must match an offered choice. A competing or stale decision conflicts.

Working Python example. Input/output fields are in the types reference.

Poll until a request leaves open, without blocking the server’s work.

wait(self, request_id: str, timeout: float | None=None, interval: float=1)
Parameter Type and default Usage
request_id str (required) Canonical durable request ID. This is not a worker delivery ID.
timeout float | None (default None) Python local timeout in seconds. Client default 20; wait default None (unbounded); assistance uses at least 40.
interval float (default 1) Python wait polling interval in seconds; default 1.

Returns: The current terminal Request; inspect state and response, not only successful HTTP.

Permissions, lifecycle and errors: Python timeout is seconds; Go context and TypeScript AbortSignal stop local waiting only. Omitted Python timeout waits indefinitely. Cancel explicitly to withdraw a request.

Working Python example. Input/output fields are in the types reference.

Withdraw your own open request with its current version.

cancel(self, request_id: str, version: int)
Parameter Type and default Usage
request_id str (required) Canonical durable request ID. This is not a worker delivery ID.
version int (required) Current optimistic-concurrency version. Read the object before a guarded change; a stale version conflicts.

Returns: Request with state=cancelled.

Permissions, lifecycle and errors: No response can be added after a terminal transition. Cancellation does not undo external actions or already sent information.

Working Python example. Input/output fields are in the types reference.

Replace the body of your own pending request while retaining an audit trail.

replace_request(self, request_id: str, version: int, body: str, *, key: str | None=None, mentions: list[dict[str, Any]] | None=None)
Parameter Type and default Usage
request_id str (required) Canonical durable request ID. This is not a worker delivery ID.
version int (required) Current optimistic-concurrency version. Read the object before a guarded change; a stale version conflicts.
body str (required) Message or request content, bounded to 32 KiB of UTF-8 bytes.
key str | None (default None) Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation.
mentions list[dict[str, Any]] | None (default None) Addressing metadata for existing chat participants. It does not narrow audience or grant authority.

Returns: {previous: Request, replacement: Request}; use replacement.id for future decisions.

Permissions, lifecycle and errors: The old request is superseded. Keep the operation key for retries. Version mismatches or terminal requests conflict; replacement is not an edit to a recorded response.

Working Python example. Input/output fields are in the types reference.

Declare or clear an agent’s dependency on a reply from one other agent.

set_request_blocking(self, request_id: str, blocking: bool)
Parameter Type and default Usage
request_id str (required) Canonical durable request ID. This is not a worker delivery ID.
blocking bool (required) Explicit requester-declared agent dependency. Ordinary pending questions are not automatically blocking.

Returns: Updated Request with blocking true or false.

Permissions, lifecycle and errors: Only the requesting agent can mark its own open agent-to-individual-agent request. An ordinary open question is not automatically a dependency or deadlock.

Working Python example. Input/output fields are in the types reference.

Run this region after the shared setup. Assertions check the returned data; the full tour is a runnable program.

request = builder.ask(target=target, body='Which region contains order 241?', choices=['EU', 'US'], key=run_id + '/ask')
assert request['expires_at'].startswith('9999-') # Ordinary communication has no implicit deadline.
current = billing.get_request(request['id'])
billing.respond(request['id'], 'answered', version=current['version'], answer='EU')
assert builder.wait(request['id'], timeout=5)['response']['answer'] == 'EU'
pending = builder.ask(target=target, body='Check order 243 as well.')
replacement = builder.replace_request(pending['id'], pending['version'], 'Check orders 243 and 244.', key=run_id + '/replace')
revised = replacement['replacement']
assert builder.cancel(revised['id'], revised['version'])['state'] == 'cancelled'
batched = owner.ask_batch(targets, {'body': 'Is staging available?'}, key=run_id + '/ask-batch')
assert len(batched) == 2
blocking = builder.ask(target=target, body='I need the ledger before continuing.')
assert builder.set_request_blocking(blocking['id'], True)['blocking']
builder.set_request_blocking(blocking['id'], False)

Read this page as Markdown