Skip to main content

Messages and runs

Conversation activity, accepted runs and persisted messages have distinct identities. These rules apply across asynchronous sends, synchronous replies and state reads.

Required attachments​

Omitting the resolution mode skips content it cannot resolve. Use FILE_RESOLUTION_FAILURE_MODE_FAIL_GENERATION when answering without the file would be misleading. If omission is acceptable, your application should still tell the user when required context is unavailable rather than presenting a complete analysis.

Conversation activity and submitted-run outcomes​

Conversation activity answers whether a run is executing now. It does not answer whether a particular submitted question has finished. Keep those two states separate in the chat display:

State readDisplay and next action
activeRunning is trueShow current activity. For one outstanding turn at a time, keep another send disabled until the retained run is resolved.
activeRunning is absentNo run is currently active. Match the submitted run to its reply and terminal outcome before showing completion.

This distinction matters after a queued send or a lost connection: the conversation can be idle without providing a correlated outcome for that request. Preserve the request as unresolved and follow send reconciliation before offering a retry.

Interrupt policy​

Controls what happens when a user sends a new message while a generation run is already in progress. Use the full enum value in the wire format:

PolicyBehavior
INTERRUPT_POLICY_REJECT_NEWThe send fails immediately with an active-run error. The new message is not appended to history.
INTERRUPT_POLICY_CANCEL_ONGOINGThe active run is cancelled; the new run starts immediately. The cancelled run's response is marked interrupted: true.
INTERRUPT_POLICY_QUEUEThe message goes into a pending queue (not yet history). When the active run completes, messages drain FIFO — each dequeued message is re-evaluated against the current policy at that moment. The queue has no depth cap.
INTERRUPT_POLICY_IGNOREThe message is accepted but not persisted to history. The active run is unaffected and never sees it.

Run outcomes​

statusMeaning and next step
AGENT_STATUS_COMPLETEDThe run finished. Read the returned messages; check the assistant's finishReason to understand why the model stopped.
AGENT_STATUS_FAILED, AGENT_STATUS_CANCELLED, AGENT_STATUS_TIMED_OUTThe run ended unsuccessfully. Do not turn absent messages into a successful empty reply.
AGENT_STATUS_QUEUEDThe message was queued behind an in-flight run; this response does not contain its completed reply. Reconcile using the asynchronous polling recipe; the current queued-operation correlation is incomplete, so idle alone does not establish this request's outcome.
AGENT_STATUS_AWAITING_CLIENT_TOOLSExecute pendingClientTools and echo clientToolCursor when submitting results, following the client-tool loop.
AGENT_STATUS_ACTIVEThe bounded wait ended while the run was still going. Do not start another run. Reconcile the same run through get-conversation-state, preserving unknown state when correlation is unavailable; see also the tool recovery guidance.
absentNo status key at all. Treat the outcome as unknown and reconcile the same run. Do not assign an unrelated lastRunStatus to it.

COMPLETED, FAILED, CANCELLED, and TIMED_OUT are recognized terminal outcomes, each with the AGENT_STATUS_ prefix. Agent run status has no SUCCESS alias; the legacy alias belongs only to tool execution status. An absent or unrecognized value is an unknown outcome. Reconcile it with a bounded wait; it is not proof of success, failure or continued activity. See Run status and model finish reason.

status can be missing entirely

The field is omitted rather than sent as an empty string, so read it with a default — body.status ?? "" — not a presence check that throws. The reachable case is submit-client-tool-results-sync for a run that had already finished before your results arrived: the response carries runId and clientToolCursor and nothing else. This response does not establish success or failure. The run ended before this submission; consult a correlated outcome, and retain uncertainty if the most recent state now belongs to another run.

Failed responses and diagnostics​

Empty messages can be omitted. Do not require an inline error or failureReason to recognize this failure: an explanation is not guaranteed in this response. Other failures propagate as HTTP errors with an error body, so handle both non-success HTTP responses and unsuccessful run statuses. Immediate model validation failures are described in Model selection failures.

Conversation, run and message identities​

Field or identityMeaning
Conversation keyThe thread to read; it is not an access token
Accepted runIdThe generation operation returned by the send
activeRunIdThe run currently recorded as active on the conversation
Message sequenceThe persisted message's order within the conversation
Conversation activity sequenceAn activity update sequence, separate from message ordering
Tool-call IDThe complete call whose approval or result is being submitted

Message sequence values are JSON strings containing 64-bit integers. Keep them as strings for transport and use a 64-bit integer or big-integer type for numeric comparison; converting large values to floating point can change their order. An assistant message need not have the user message's sequence plus one: tool rounds and other messages can appear between them.

State reconciliation​

An absent or false activeRunning means the conversation has no recorded active run; false is normally omitted. lastRunStatus reports its latest recorded outcome, which can belong to a newer run. It does not provide a complete history of outcomes for concurrent or queued sends. Refresh state after disconnects and retain an unknown outcome when correlation is unavailable.

Persisted message reads​

Use returned persisted messages to refresh the display. While activeRunning is true, compare activeRunId with the accepted run. Once activity ends, lastRunStatus describes the latest run recorded on the conversation. It is not a receipt for every earlier send: a newer or concurrent run can replace it. Keep an unresolved outcome visible when you cannot correlate it.