Chat Channel
Reference for the ahp-chat:/<uuid> channel — per-chat state, the turn lifecycle, tool-call state machine, attachments, pending messages, and input requests. A chat belongs to a session (see Session Channel); a session may contain multiple chats. See Chat Channel specification for the wire-level overview.
JSON Schema: state.schema.json
State Types
ChatState
Full state for a single chat, loaded when a client subscribes to the chat's URI.
The lightweight catalog representation of a chat is {@link ChatSummary}, carried in {@link SessionState.chats | SessionState.chats}. ChatStatedenormalizes every {@link ChatSummary} field directly onto itself so subscribers receive one flat object instead of having to merge a nested summary sub-object. Producers MUST keep the two representations consistent: any change to the inlined fields below SHOULD also be announced on the parent session via the matching {@link SessionChatUpdatedAction | session/chatUpdated} action.
| Field | Type | Required | Description |
|---|---|---|---|
resource | URI | Yes | Chat URI |
title | string | Yes | Chat title |
status | SessionStatus | Yes | Current chat status (reuses SessionStatus shape) |
activity | string | No | Human-readable description of what the chat is currently doing |
modifiedAt | string | Yes | Last modification timestamp (ISO 8601, e.g. "2025-03-10T18:42:03.123Z") |
origin | ChatOrigin | No | How this chat came into existence |
interactivity | ChatInteractivity | No | How the user can interact with this chat. See {@link ChatInteractivity}. Supports agent-team patterns where worker chats are read-only or hidden. Absence defaults to {@link ChatInteractivity.Full} for backward compatibility. |
workingDirectories | URI[] | No | The subset of the session's {@link SessionState.workingDirectories | workingDirectories} that this chat's agent has tool access to. Every entry MUST be present in the owning session's workingDirectories; servers MUST reject a chat/workingDirectorySet action that violates this constraint.When absent, the chat inherits the full session set. When present but empty (not recommended), the chat has no working-directory tool access at all. Dispatch chat/workingDirectorySet / chat/workingDirectoryRemoved to update the subset on a running chat. |
turns | Turn[] | Yes | Completed turns |
turnsNextCursor | string | No | Cursor for loading older completed turns into this chat state. Presence means turns is a tail window and more historical turns are available. Pass this opaque cursor to fetchTurns; the host MUST insert the loaded turns into state and update or clear this cursor before responding. Absence means the state contains all retained turns. |
activeTurn | ActiveTurn | No | Currently in-progress turn |
steeringMessage | PendingMessage | No | Message to inject into the current turn at a convenient point |
queuedMessages | PendingMessage[] | No | Messages to send automatically as new turns after the current turn finishes |
draft | Message | No | The user's in-progress draft input for this chat — the message they are composing but have not sent yet, including its {@link Message.model | model} / {@link Message.agent | agent} selection and attachments. Clients MAY periodically sync their local input state into this field so a draft survives reloads and is visible to other clients viewing the same chat. Eager syncing is not required — clients SHOULD debounce and MAY sync only at convenient points. When presenting input UI for an existing chat, clients SHOULD use any draft to initialize their input state. Cleared (set to undefined) once the message is sent. |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this chat. |
ChatSummary
Lightweight catalog entry for a chat, carried in {@link SessionState.chats | SessionState.chats}. The full conversation lives in {@link ChatState}, which inlines (denormalizes) every field below.
| Field | Type | Required | Description |
|---|---|---|---|
resource | URI | Yes | Chat URI |
title | string | Yes | Chat title |
status | SessionStatus | Yes | Current chat status (reuses SessionStatus shape) |
activity | string | No | Human-readable description of what the chat is currently doing |
modifiedAt | string | Yes | Last modification timestamp (ISO 8601, e.g. "2025-03-10T18:42:03.123Z") |
origin | ChatOrigin | No | How this chat came into existence |
interactivity | ChatInteractivity | No | How the user can interact with this chat. See {@link ChatInteractivity}. Supports agent-team patterns where worker chats are read-only or hidden. Absence defaults to {@link ChatInteractivity.Full} for backward compatibility. |
workingDirectories | URI[] | No | The subset of the session's working directories this chat uses. See {@link ChatState.workingDirectories} for the full semantics. |
ChatOriginKind
Discriminant for {@link ChatOrigin} — how a chat came into existence.
| Member | Value | Description |
|---|---|---|
User | 'user' | User created the chat explicitly (e.g. via the host UI). |
Fork | 'fork' | Forked from an existing chat at a specific turn. |
SideChat | 'sideChat' | Created as an independent side conversation from a specific turn. |
Tool | 'tool' | Spawned by a tool call running in another chat (e.g. a sub-agent delegation). |
SideChatSelection
Immutable selected-text snapshot captured when a side chat is created.
The host records this exact text when it accepts createChat; later changes to the source chat do not alter it.
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Exact selected-text snapshot captured at createChat acceptance.MUST be non-empty. |
responsePartId | string | No | Optional provenance for the response part that contained {@link text} when the host took the snapshot. Advisory only: this is not a live range or offset and MUST NOT be used to recompute text. |
ChatOrigin
How a chat came into existence. Clients MAY use it to render contextual UI (parent indicators, fork markers, "spawned by tool" badges).
Fork and side-chat origins both carry a stable top-level turnId alongside their discriminated kind value instead of snapshotting whether that turn was active or historical at creation time. Consumers resolve the identifier against the source chat's current activeTurn or retained turns as needed.
When a host accepts side-chat creation from the source chat's current active turn, it snapshots the retained history plus that turn's current user message and any partial assistant response already available. Later source-turn deltas do not retroactively change the created side chat's starting context, and once the source turn completes it is still referenced by the same turnId. Side-chat origins MAY also retain an immutable {@link SideChatSelection | selected-text snapshot} captured at acceptance time; any responsePartId there is provenance only, not a range.
The tool variant records a tool-spawned worker from the worker's side: its chat/toolCallId identify the spawning tool call in the parent chat. This is the canonical record of the spawn relationship. The same edge is surfaced from the parent's side by {@link ToolResultSubagentContent}, whose resource is this chat's URI; hosts MUST keep the two consistent.
{ kind: ChatOriginKind.User } | { kind: ChatOriginKind.Fork; chat: URI; turnId: string } | { kind: ChatOriginKind.SideChat; chat: URI; turnId: string; selection?: SideChatSelection } | { kind: ChatOriginKind.Tool; chat: URI; toolCallId: string }
ChatInteractivity
How a user can interact with a chat.
Full— user can send messages and watch (default when absent)ReadOnly— user can watch but not send messages (e.g. agent team workers)Hidden— internal worker not shown in UI at all
Supports the agent-team pattern where a lead chat is fully interactive and worker chats are read-only (visible for observability) or hidden (internal implementation detail). The harness sets this based on the chat's role; the UI uses it to show appropriate controls.
| Member | Value | Description |
|---|---|---|
Full | 'full' | User can send messages and watch (default when absent) |
ReadOnly | 'read-only' | User can watch but not send messages |
Hidden | 'hidden' | Internal worker not shown in UI at all |
PendingMessageKind
Discriminant for pending message kinds.
| Member | Value | Description |
|---|---|---|
Steering | 'steering' | Injected into the current turn at a convenient point |
Queued | 'queued' | Sent automatically as a new turn after the current turn finishes |
PendingMessage
A message queued for future delivery to the agent.
Steering messages are injected into the current turn mid-flight. Queued messages are automatically started as new turns after the current turn naturally finishes.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this pending message |
message | Message | The message that will start the next turn |
ChatInputResponseKind
How a client completed an input request.
| Member | Value |
|---|---|
Accept | 'accept' |
Decline | 'decline' |
Cancel | 'cancel' |
ChatInputQuestionKind
Question/input control kind.
| Member | Value |
|---|---|
Text | 'text' |
Number | 'number' |
Integer | 'integer' |
Boolean | 'boolean' |
SingleSelect | 'single-select' |
MultiSelect | 'multi-select' |
ChatInputOption
A choice in a select-style question.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Stable option identifier; for MCP enum values this is the enum string |
label | string | Yes | Display label |
description | string | No | Optional secondary text |
recommended | boolean | No | Whether this option is the recommended/default choice |
ChatInputTextQuestion
Text question within a chat input request.
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputQuestionKind.Text | Yes | |
format | string | No | Format hint for text questions, such as email, uri, date, or date-time |
min | number | No | Minimum string length |
max | number | No | Maximum string length |
defaultValue | string | No | Default text |
ChatInputNumberQuestion
Numeric question within a chat input request.
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputQuestionKind.Number | ChatInputQuestionKind.Integer | Yes | |
min | number | No | Minimum value |
max | number | No | Maximum value |
defaultValue | number | No | Default numeric value |
ChatInputBooleanQuestion
Boolean question within a chat input request.
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputQuestionKind.Boolean | Yes | |
defaultValue | boolean | No | Default boolean value |
ChatInputSingleSelectQuestion
Single-select question within a chat input request.
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputQuestionKind.SingleSelect | Yes | |
options | ChatInputOption[] | Yes | Options the user may select from |
allowFreeformInput | boolean | No | Whether the user may enter text instead of selecting an option |
ChatInputMultiSelectQuestion
Multi-select question within a chat input request.
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputQuestionKind.MultiSelect | Yes | |
options | ChatInputOption[] | Yes | Options the user may select from |
allowFreeformInput | boolean | No | Whether the user may enter text in addition to selecting options |
min | number | No | Minimum selected item count |
max | number | No | Maximum selected item count |
ChatInputQuestion
One question within a chat input request.
ChatInputTextQuestion | ChatInputNumberQuestion | ChatInputBooleanQuestion | ChatInputSingleSelectQuestion | ChatInputMultiSelectQuestion
ChatInputRequest
The request payload carried by an {@link InputRequestResponsePart}.
The server creates or replaces the containing response part with chat/inputRequested. Clients sync drafts with chat/inputAnswerChanged and submit responses with chat/inputCompleted.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Stable request identifier |
message | string | No | Display message for the request as a whole |
url | URI | No | URL the user should review or open, for URL-style elicitations |
questions | ChatInputQuestion[] | No | Ordered questions to ask the user |
answers | Record<string, ChatInputAnswer> | No | Current draft or submitted answers, keyed by question ID |
ChatInputAnswerValueKind
Answer value kind.
| Member | Value |
|---|---|
Text | 'text' |
Number | 'number' |
Boolean | 'boolean' |
Selected | 'selected' |
SelectedMany | 'selected-many' |
ChatInputTextAnswerValue
Value captured for one answer.
| Field | Type | Description |
|---|---|---|
kind | ChatInputAnswerValueKind.Text | |
value | string |
ChatInputNumberAnswerValue
| Field | Type | Description |
|---|---|---|
kind | ChatInputAnswerValueKind.Number | |
value | number |
ChatInputBooleanAnswerValue
| Field | Type | Description |
|---|---|---|
kind | ChatInputAnswerValueKind.Boolean | |
value | boolean |
ChatInputSelectedAnswerValue
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputAnswerValueKind.Selected | Yes | |
value | string | Yes | |
freeformValues | string[] | No | Free-form text entered instead of selecting an option |
ChatInputSelectedManyAnswerValue
| Field | Type | Required | Description |
|---|---|---|---|
kind | ChatInputAnswerValueKind.SelectedMany | Yes | |
value | string[] | Yes | |
freeformValues | string[] | No | Free-form text entered in addition to selected options |
ChatInputAnswerValue
ChatInputTextAnswerValue | ChatInputNumberAnswerValue | ChatInputBooleanAnswerValue | ChatInputSelectedAnswerValue | ChatInputSelectedManyAnswerValue
ChatInputAnswered
| Field | Type | Description |
|---|---|---|
state | ChatInputAnswerState.Draft | ChatInputAnswerState.Submitted | Answer state |
value | ChatInputAnswerValue | Answer value |
ChatInputSkipped
| Field | Type | Required | Description |
|---|---|---|---|
state | ChatInputAnswerState.Skipped | Yes | Answer state |
freeformValues | string[] | No | Free-form reason or value captured while skipping, if any |
ChatInputAnswerState
Answer lifecycle state.
| Member | Value |
|---|---|
Draft | 'draft' |
Submitted | 'submitted' |
Skipped | 'skipped' |
ChatInputAnswer
Draft, submitted, or skipped answer for one question.
ChatInputAnswered | ChatInputSkipped
TurnState
How a turn ended.
| Member | Value |
|---|---|
Complete | 'complete' |
Cancelled | 'cancelled' |
Error | 'error' |
MessageAttachmentKind
Discriminant for {@link MessageAttachment} variants.
| Member | Value | Description |
|---|---|---|
Simple | 'simple' | A simple, opaque attachment whose representation is described by the producer. |
EmbeddedResource | 'embeddedResource' | An attachment whose data is embedded inline as a base64 string. |
Resource | 'resource' | An attachment that references a resource by URI. |
Annotations | 'annotations' | An attachment that references annotations on an annotations channel. |
Chat | 'chat' | An attachment that references a bounded transcript from another chat. |
Turn
A completed request/response cycle.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Turn identifier |
startedAt | string | No | ISO 8601 timestamp when this turn started. |
duration | number | No | Turn duration in milliseconds. |
message | Message | Yes | The message that initiated the turn |
responseParts | ResponsePart[] | Yes | All response content in stream order: text, tool calls, reasoning, and content refs. Consumers should derive display text by concatenating markdown parts, and find tool calls by filtering for ToolCall parts. |
usage | UsageInfo | undefined | Yes | Token usage info |
state | TurnState | Yes | How the turn ended |
error | ErrorInfo | No | Error details if state is 'error' |
ActiveTurn
An in-progress turn — the assistant is actively streaming.
| Field | Type | Description |
|---|---|---|
id | string | Turn identifier |
startedAt | string | ISO 8601 timestamp when this turn started. |
message | Message | The message that initiated the turn |
responseParts | ResponsePart[] | All response content in stream order: text, tool calls, reasoning, and content refs. Tool call parts include pendingPermissions when permissions are awaiting user approval. |
usage | UsageInfo | undefined | Token usage info |
MessageKind
Discriminant for {@link MessageOrigin} — identifies who produced a message.
| Member | Value | Description |
|---|---|---|
User | 'user' | Sent directly by the user. |
Agent | 'agent' | Produced by the agent itself rather than the user — for example, an agent that seeds the first message of a chat it spawned. |
Tool | 'tool' | Produced by a tool rather than the user — for example, a tool that spawns a worker chat whose first message carries a seed prompt. |
SystemNotification | 'systemNotification' | A system-generated notification rather than a direct user message. |
MessageOrigin
Identifies the origin of a {@link Message} — who produced it. For the message that initiates a turn ({@link Turn.message}), this is also the origin of the turn; for steering or queued messages it is just the origin of that message.
| Field | Type | Description |
|---|---|---|
kind | MessageKind | The kind of actor that produced the message. |
Message
A message that initiates or steers a turn. Messages can originate from the user, the agent, a tool, or be system-generated (see {@link MessageOrigin}).
Attachments MAY be referenced inside {@link Message.text} via their {@link MessageAttachmentBase.range} field. Attachments without a range are still associated with the message but do not correspond to a specific span in the text.
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Message text |
origin | MessageOrigin | Yes | The origin of the message |
attachments | MessageAttachment[] | No | File/selection attachments |
model | ModelSelection | No | The model this message was, or will be, sent with. For historic user/agent messages this records the model actually used, so a client editing or resending the message can retain that selection. For a {@link ChatState.draft | draft} it carries the model the user picked for the message they are composing. Absent means the agent host's default model applies. |
agent | AgentSelection | No | The custom agent this message was, or will be, sent with. For historic messages this records the agent actually used; for a {@link ChatState.draft | draft} it carries the agent the user picked. Absent means no custom agent — the provider's default behavior applies. |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this message. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry context that does not fit any other field. Mirrors the MCP _meta convention. |
MessageAttachmentBase
Common fields shared by all {@link MessageAttachment} variants.
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | A human-readable label for the attachment (e.g. the filename of a file attachment). Used for display in UI. |
range | TextRange | No | If defined, the range in {@link Message.text} that references this attachment. This is a text range, not a byte range. |
displayKind | string | No | Advisory display hint for clients rendering this attachment. Recognized values include: - 'image': the attachment is an image - 'document': the attachment is a textual document - 'symbol': the attachment is a code symbol (e.g. a function or class) - 'directory': the attachment is a folder - 'selection': the attachment is a selection within a documentImplementations MAY provide additional values; clients SHOULD fall back to a reasonable default when an unknown value is encountered. |
_meta | Record<string, unknown> | No | Additional implementation-defined metadata for the attachment. If the attachment was produced by the completions command, the client MUST preserve every property of _meta originally returned by the agent host when sending the user message containing the accepted completion. |
SimpleMessageAttachment
A simple, opaque attachment whose model representation is described by the producer.
| Field | Type | Required | Description |
|---|---|---|---|
type | MessageAttachmentKind.Simple | Yes | Discriminant |
modelRepresentation | string | No | Representation of the attachment as it should be shown to the model. If the attachment was produced by the client, this property MUST be defined so the agent host can correctly interpret the attachment. This property MAY be omitted when the attachment originated from a completions response. |
MessageEmbeddedResourceAttachment
An attachment whose data is embedded inline as a base64 string.
Use this for small binary payloads (e.g. a pasted image) that should be delivered with the user message itself rather than fetched separately.
| Field | Type | Required | Description |
|---|---|---|---|
type | MessageAttachmentKind.EmbeddedResource | Yes | Discriminant |
data | string | Yes | Base64-encoded binary data |
contentType | string | Yes | Content MIME type (e.g. "image/png", "application/pdf") |
selection | TextSelection | No | Optional selection within the attached textual resource. Only meaningful for textual resources. |
MessageResourceAttachment
An attachment that references a resource by URI. The content is not delivered inline; consumers can fetch it via resourceRead when needed.
| Field | Type | Required | Description |
|---|---|---|---|
type | MessageAttachmentKind.Resource | Yes | Discriminant |
selection | TextSelection | No | Optional selection within the referenced textual resource. Only meaningful for textual resources. |
MessageAnnotationsAttachment
An attachment that references annotations on a session's annotations channel (see {@link AnnotationsState}).
When {@link annotationIds} is omitted the attachment references every annotation on the channel; when present it references only the listed {@link Annotation.id | annotation ids}.
| Field | Type | Required | Description |
|---|---|---|---|
type | MessageAttachmentKind.Annotations | Yes | Discriminant |
resource | URI | Yes | The annotations channel URI (typically ahp-session:/<uuid>/annotations). Matches {@link AnnotationsSummary.resource}. |
annotationIds | string[] | No | Specific {@link Annotation.id | annotation ids} to reference. When omitted, the attachment references all annotations on the channel. |
MessageChatAttachment
An attachment that references a chat transcript through a fixed completed turn.
The referenced chat MAY belong to a different session than the message's chat. The attachment's model representation identifies the chat in a way that hosts can resolve regardless of the session that owns it.
When endTurn is omitted, the host MUST resolve and pin the referenced chat's latest completed turn when accepting the message. This lets clients attach a chat without knowing its turn identifiers. When provided, endTurn MUST reference a completed, retained turn. The host resolves the transcript from its first retained turn through the pinned turn, inclusive. Later turns do not change the context represented by an already-sent attachment.
When the referenced chat has no completed retained turns, the resolved transcript is empty and hosts MUST NOT reject the attachment on that basis.
Hosts MUST NOT recursively expand chat attachments found inside the referenced transcript. Clients SHOULD keep rendering label if the referenced chat is later pruned, and treat opening resource as best-effort.
| Field | Type | Required | Description |
|---|---|---|---|
type | MessageAttachmentKind.Chat | Yes | Discriminant |
resource | URI | Yes | URI of the referenced chat. |
endTurn | string | No | Last completed turn included in the referenced transcript. When omitted, the host pins the latest completed turn when accepting the message. |
MessageAttachment
An attachment associated with a {@link Message}.
SimpleMessageAttachment | MessageEmbeddedResourceAttachment | MessageResourceAttachment | MessageAnnotationsAttachment | MessageChatAttachment
ResponsePartKind
Discriminant for response part types.
| Member | Value |
|---|---|
Markdown | 'markdown' |
ContentRef | 'contentRef' |
ToolCall | 'toolCall' |
Reasoning | 'reasoning' |
SystemNotification | 'systemNotification' |
InputRequest | 'inputRequest' |
MarkdownResponsePart
| Field | Type | Description |
|---|---|---|
kind | ResponsePartKind.Markdown | Discriminant |
id | string | Part identifier, used by chat/delta to target this part for content appends |
content | string | Markdown content |
ResourceReponsePart
A content part that's a reference to large content stored outside the state tree.
| Field | Type | Description |
|---|---|---|
kind | ResponsePartKind.ContentRef | Discriminant |
ToolCallResponsePart
A tool call represented as a response part.
Tool calls are part of the response stream, interleaved with text and reasoning. The toolCall.toolCallId serves as the part identifier for actions that target this part.
| Field | Type | Description |
|---|---|---|
kind | ResponsePartKind.ToolCall | Discriminant |
toolCall | ToolCallState | Full tool call lifecycle state |
ReasoningResponsePart
Reasoning/thinking content from the model.
| Field | Type | Description |
|---|---|---|
kind | ResponsePartKind.Reasoning | Discriminant |
id | string | Part identifier, used by chat/reasoning to target this part for content appends |
content | string | Accumulated reasoning text |
ResponsePart
MarkdownResponsePart | ResourceReponsePart | ToolCallResponsePart | ReasoningResponsePart | SystemNotificationResponsePart | InputRequestResponsePart
InputRequestResponsePart
A live or resolved input request (elicitation) in the turn response stream.
The server inserts the part with chat/inputRequested. While {@link response} is absent, clients can update answer drafts with chat/inputAnswerChanged and submit a response with chat/inputCompleted. Completion updates this part in place so its stream position is stable and the full interaction remains durable and backfillable via fetchTurns.
If the turn ends without a submitted response, the unresolved part remains in the completed turn transcript with {@link response} absent.
| Field | Type | Required | Description |
|---|---|---|---|
kind | ResponsePartKind.InputRequest | Yes | Discriminant |
request | ChatInputRequest | Yes | The request, carrying its id, message, url, questions, and current draft or submitted answers. |
response | ChatInputResponseKind | No | How the request was resolved. Absent until a client submits accept, decline, or cancel with chat/inputCompleted. |
SystemNotificationResponsePart
A system notification surfaced as part of the response stream.
System notifications are messages authored by the agent harness that need to be visible to both the agent (for situational awareness) and the user (for transcript continuity). Examples include "background subagent X completed" or "task Y was cancelled".
| Field | Type | Required | Description |
|---|---|---|---|
kind | ResponsePartKind.SystemNotification | Yes | Discriminant |
content | StringOrMarkdown | Yes | The text of the system notification |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this notification. A host MAY attach a machine-readable descriptor of what triggered the notification so clients can categorize, icon, group, filter, or localize it without parsing content. Clients MAY look for well-known keys here to provide enhanced UI, and MUST render coherently from content alone when _meta is absent or unrecognized. |
ToolCallStatus
Status of a tool call in the lifecycle state machine.
| Member | Value | Description |
|---|---|---|
Streaming | 'streaming' | |
PendingConfirmation | 'pending-confirmation' | |
Running | 'running' | |
AuthRequired | 'auth-required' | Running paused because the MCP server backing this call needs authentication (typically step-up auth for insufficient scope, surfacing mid-execution). See {@link ToolCallAuthRequiredState}. |
PendingResultConfirmation | 'pending-result-confirmation' | |
Completed | 'completed' | |
Cancelled | 'cancelled' |
ToolCallConfirmationReason
How a tool call was confirmed for execution.
NotNeeded— No confirmation required (auto-approved)UserAction— User explicitly approvedSetting— Approved by a persistent user setting
| Member | Value |
|---|---|
NotNeeded | 'not-needed' |
UserAction | 'user-action' |
Setting | 'setting' |
ToolCallRiskAssessmentKind
Identifies a model judge as the source of a confirmation requirement.
| Member | Value |
|---|---|
Judge | 'judge' |
ToolCallRiskAssessmentStatus
Lifecycle status of an asynchronous model-judge confirmation decision.
| Member | Value |
|---|---|
Loading | 'loading' |
Complete | 'complete' |
ToolCallRiskAssessmentLoadingState
The model judge is still evaluating the tool call.
| Field | Type | Description |
|---|---|---|
status | ToolCallRiskAssessmentStatus.Loading |
ToolCallRiskAssessmentCompleteState
The model judge has completed its evaluation.
| Field | Type | Description |
|---|---|---|
status | ToolCallRiskAssessmentStatus.Complete | |
reason | StringOrMarkdown | |
safety | number | The judge's normalized safety score, where 0 is unsafe and 1 is safe. |
ToolCallRiskAssessment
ToolCallRiskAssessmentLoadingState | ToolCallRiskAssessmentCompleteState
ToolCallCancellationReason
Why a tool call was cancelled.
| Member | Value |
|---|---|
Denied | 'denied' |
Skipped | 'skipped' |
ResultDenied | 'result-denied' |
ConfirmationOptionKind
Whether a confirmation option represents an approval or denial action.
| Member | Value |
|---|---|
Approve | 'approve' |
Deny | 'deny' |
ConfirmationOption
A confirmation option that the server offers for a tool call awaiting approval. Allows richer choices beyond simple approve/deny — for example, "Approve in this Session" or "Deny with reason."
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the option, returned in the confirmed action |
label | string | Yes | Human-readable label displayed to the user |
kind | ConfirmationOptionKind | Yes | Whether this option represents an approval or denial |
group | number | No | Logical group number for visual categorisation. Clients SHOULD display options in the order they are defined and MAY use differing group numbers to insert dividers between logical clusters of options. |
ToolCallContributorKind
| Member | Value |
|---|---|
Client | 'client' |
MCP | 'mcp' |
ToolCallClientContributor
| Field | Type | Description |
|---|---|---|
kind | ToolCallContributorKind.Client | |
clientId | string | If this tool is provided by a client, the clientId of the owning client. Absent for server-side tools.When set, the identified client is responsible for executing the tool and dispatching chat/toolCallComplete with the result. |
ToolCallMcpContributor
| Field | Type | Description |
|---|---|---|
kind | ToolCallContributorKind.MCP | |
customizationId | string | Customization ID of the corresponding MCP server in {@link SessionState.customizations}. |
ToolCallContributor
ToolCallClientContributor | ToolCallMcpContributor
ToolCallResult
Tool execution result details, available after execution completes.
| Field | Type | Required | Description |
|---|---|---|---|
success | boolean | Yes | Whether the tool succeeded |
pastTenseMessage | StringOrMarkdown | Yes | Past-tense description of what the tool did |
content | ToolResultContent[] | No | Unstructured result content blocks. This mirrors the content field of MCP CallToolResult. |
structuredContent | Record<string, unknown> | No | Optional structured result object. This mirrors the structuredContent field of MCP CallToolResult. |
error | | No | Error details if the tool failed |
ToolCallStreamingState
LM is streaming the tool call parameters.
| Field | Type | Required | Description |
|---|---|---|---|
status | ToolCallStatus.Streaming | Yes | |
partialInput | string | No | Partial parameters accumulated so far |
invocationMessage | StringOrMarkdown | No | Progress message shown while parameters are streaming |
ToolCallPendingConfirmationState
Parameters are complete, or a running tool requires re-confirmation (e.g. a mid-execution permission check).
| Field | Type | Required | Description |
|---|---|---|---|
status | ToolCallStatus.PendingConfirmation | Yes | |
confirmationTitle | StringOrMarkdown | No | Short title for the confirmation prompt (e.g. "Run in terminal", "Write file") |
riskAssessment | ToolCallRiskAssessment | No | Risk assessment that informed the confirmation requirement. |
edits | | No | File edits that this tool call will perform, for preview before confirmation |
editable | boolean | No | Whether the agent host allows the client to edit the tool's input parameters before confirming |
options | ConfirmationOption[] | No | Options the server offers for this confirmation. When present, the client SHOULD render these instead of a plain approve/deny UI. Each option belongs to a {@link ConfirmationOptionGroup} so the client can still categorise the choices. |
ToolCallRunningState
Tool is actively executing.
| Field | Type | Required | Description |
|---|---|---|---|
status | ToolCallStatus.Running | Yes | |
content | ToolResultContent[] | No | Partial content produced while the tool is still executing. For example, a terminal content block lets clients subscribe to live output before the tool completes. |
ToolCallAuthRequiredState
A running tool call is paused because the MCP server backing it needs authentication — most commonly {@link McpAuthRequirement.reason | insufficientScope} step-up auth triggered by the tools/call request itself. Only ever reached from {@link ToolCallRunningState}, and normally returns there once authenticated: running → auth-required → running → …. A client MAY instead cancel the invocation without authenticating by dispatching a chat/toolCallComplete with a failed result, always moving straight to {@link ToolCallCompletedState} — requiresResultConfirmation is ignored on this path, so it can never enter {@link ToolCallPendingResultConfirmationState}. A successful result dispatched from this state is invalid and MUST be rejected/ignored as a no-op by the reducer, since execution never resumed after the challenge.
This is the tool-call-level counterpart to {@link McpServerAuthRequiredState} — that state means the MCP server cannot serve any request; this one means this specific invocation is waiting on the same kind of challenge. The two are dispatched independently and MAY be true at the same time, or not: an insufficientScope challenge triggered by a single tool call, for example, need not block the whole server.
Because the challenge is always resolved by pushing a token via the existing authenticate command, this state can only originate from a tool call {@link ToolCallContributorKind.MCP | contributed by an MCP server} — contributor is narrowed accordingly (unlike the optional, multi-kind contributor on other tool call states).
| Field | Type | Required | Description |
|---|---|---|---|
status | ToolCallStatus.AuthRequired | Yes | |
contributor | ToolCallMcpContributor | Yes | The MCP server that contributed this tool call — always MCP, never a client tool. |
auth | McpAuthRequirement | Yes | The authentication challenge blocking this invocation. |
content | ToolResultContent[] | No | Partial content produced before the call paused for authentication. |
ToolCallPendingResultConfirmationState
Tool finished executing, waiting for client to approve the result.
| Field | Type | Description |
|---|---|---|
status | ToolCallStatus.PendingResultConfirmation |
ToolCallCompletedState
Tool completed successfully or with an error.
| Field | Type | Description |
|---|---|---|
status | ToolCallStatus.Completed |
ToolCallCancelledState
Tool call was cancelled before execution.
| Field | Type | Required | Description |
|---|---|---|---|
status | ToolCallStatus.Cancelled | Yes | |
reason | ToolCallCancellationReason | Yes | Why the tool was cancelled |
reasonMessage | StringOrMarkdown | No | Optional message explaining the cancellation |
userSuggestion | Message | No | What the user suggested doing instead |
selectedOption | ConfirmationOption | No | The confirmation option the user selected, if confirmation options were provided |
ToolCallState
Discriminated union of all tool call lifecycle states.
See the state model guide for the full state machine diagram.
ToolCallStreamingState | ToolCallPendingConfirmationState | ToolCallRunningState | ToolCallAuthRequiredState | ToolCallPendingResultConfirmationState | ToolCallCompletedState | ToolCallCancelledState
ToolCallConfirmationState
The two tool-call states that block on a client confirmation: parameter confirmation before execution ({@link ToolCallPendingConfirmationState}) and result confirmation after execution ({@link ToolCallPendingResultConfirmationState}).
{@link ToolCallAuthRequiredState} is intentionally not part of this union: it doesn't block on a chat/toolCallConfirmed-style client decision, it blocks on the client completing an OAuth flow and calling authenticate. See {@link SessionToolAuthenticationRequest} for its session-level surfacing.
Surfaced at the session level by {@link SessionToolConfirmationRequest}.
ToolCallPendingConfirmationState | ToolCallPendingResultConfirmationState
ToolResultContentType
Discriminant for tool result content types.
| Member | Value |
|---|---|
Text | 'text' |
EmbeddedResource | 'embeddedResource' |
Resource | 'resource' |
FileEdit | 'fileEdit' |
Terminal | 'terminal' |
Subagent | 'subagent' |
ToolResultTextContent
Text content in a tool result.
Mirrors MCP TextContent.
| Field | Type | Description |
|---|---|---|
type | ToolResultContentType.Text | |
text | string | The text content |
ToolResultEmbeddedResourceContent
Base64-encoded binary content embedded in a tool result.
Mirrors MCP EmbeddedResource for inline binary data.
| Field | Type | Description |
|---|---|---|
type | ToolResultContentType.EmbeddedResource | |
data | string | Base64-encoded data |
contentType | string | Content type (e.g. "image/png", "application/pdf") |
ToolResultResourceContent
A reference to a resource stored outside the tool result.
Wraps {@link ContentRef} for lazy-loading large results.
| Field | Type | Description |
|---|---|---|
type | ToolResultContentType.Resource |
ToolResultFileEditContent
Describes a file modification performed by a tool.
| Field | Type | Description |
|---|---|---|
type | ToolResultContentType.FileEdit |
ToolResultTerminalContent
A reference to a terminal whose output is relevant to this tool result.
Clients can subscribe to the terminal's URI to stream its output in real time, providing live feedback while a tool is executing.
When the command exits, {@link result} is filled in on the completed result, retaining the outcome for clients that did not subscribe. This records the command's exit, not the terminal's — the terminal may keep running afterwards.
| Field | Type | Required | Description |
|---|---|---|---|
type | ToolResultContentType.Terminal | Yes | |
resource | URI | Yes | Terminal URI (subscribable for full terminal state) |
title | string | Yes | Display title for the terminal content |
isPty | boolean | No | Whether this terminal-style resource is backed by a pseudoterminal. When false, output is plain text and clients do not need to parse VT sequences. |
result | TerminalCommandResult | No | Outcome of the command, present once it has exited. |
TerminalCommandResult
Outcome of a command run in a terminal-style tool, filled in on {@link ToolResultTerminalContent.result} once the command exits.
| Field | Type | Required | Description |
|---|---|---|---|
exitCode | number | No | Exit code from the completed command, if reported by the runtime |
preview | string | No | Preview of the command's output, for clients that are not subscribed to the terminal or that arrive after it is disposed. When isPty is true the preview may contain VT sequences; when false it is plain text. |
truncated | boolean | No | Whether preview is known to be incomplete or truncated |
ToolResultSubagentContent
A reference, embedded in a tool result, to a worker chat spawned by the tool call (a sub-agent delegation), referenced by a chat URI (ahp-chat:/...).
This is the spawning tool call's forward view of the worker. The worker chat records the same edge in reverse via its {@link ChatOrigin} (kind: 'tool'), whose toolCallId identifies the tool call that emitted this content.
| Field | Type | Required | Description |
|---|---|---|---|
type | ToolResultContentType.Subagent | Yes | |
resource | URI | Yes | Worker chat URI (subscribable for full chat state) |
title | string | Yes | Display title for the subagent |
agentName | string | No | Internal agent name |
description | string | No | Human-readable description of the subagent's task |
ToolResultContent
Content block in a tool result.
Mirrors the content blocks in MCP CallToolResult.content, plus ToolResultResourceContent for lazy-loading large results, ToolResultFileEditContent for file edit diffs, ToolResultTerminalContent for live terminal output and command completion metadata, and ToolResultSubagentContent for tool-spawned worker chats (AHP extensions).
ToolResultTextContent | ToolResultEmbeddedResourceContent | ToolResultResourceContent | ToolResultFileEditContent | ToolResultTerminalContent | ToolResultSubagentContent
Actions
Mutate ChatState. Scoped to a chat URI via the enclosing ActionEnvelope.channel.
JSON Schema: actions.schema.json
chat/turnStarted
A new message has been sent to the agent, and a new turn starts.
A client is only allowed to send {@link MessageKind.User} messages.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatTurnStarted | Yes | |
turnId | string | Yes | Turn identifier |
startedAt | string | Yes | ISO 8601 timestamp when this turn started. |
message | Message | Yes | The new message |
queuedMessageId | string | No | If this turn was auto-started from a queued message, the ID of that message |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/delta
Streaming text chunk from the assistant, appended to a specific response part.
The server MUST first emit a chat/responsePart to create the target part (markdown or reasoning), then use this action to append text to it.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatDelta | Yes | |
turnId | string | Yes | Turn identifier |
partId | string | Yes | Identifier of the response part to append to |
content | string | Yes | Text chunk |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/responsePart
Structured content appended to the response.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatResponsePart | Yes | |
turnId | string | Yes | Turn identifier |
part | ResponsePart | Yes | Response part (markdown or content ref) |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/toolCallStart
A tool call begins — parameters are streaming from the LM.
The server sets {@link ToolCallContributor | contributor} to identify the origin of the tool. For client-provided tools, the named client is responsible for executing the tool once it reaches the running state and dispatching chat/toolCallComplete. For MCP-served tools, the server executes the call against the named McpServerCustomization.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatToolCallStart | Yes | |
toolName | string | Yes | Internal tool name (for debugging/logging) |
displayName | string | Yes | Human-readable tool name |
intention | string | No | Human-readable description of what the tool invocation intends to do |
contributor | ToolCallContributor | No | Reference to the contributor of the tool being called. Absent for server-side tools that are not contributed by a client or MCP server. |
chat/toolCallDelta
Streaming partial parameters for a tool call.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatToolCallDelta | Yes | |
content | string | Yes | Partial parameter content to append |
invocationMessage | StringOrMarkdown | No | Updated progress message |
chat/toolCallReady
Tool call parameters are complete, or a running tool requires re-confirmation.
When dispatched for a streaming tool call, transitions to pending-confirmation or directly to running if confirmed is set.
When dispatched for a running tool call (e.g. mid-execution permission needed), transitions back to pending-confirmation. The invocationMessage and _meta SHOULD be updated to describe the specific confirmation needed. Clients use the standard chat/toolCallConfirmed flow to approve or deny.
For client-provided tools, the server typically sets confirmed to 'not-needed' so the tool transitions directly to running, where the owning client can begin execution immediately.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatToolCallReady | Yes | |
contributor | ToolCallContributor | No | Final contributor metadata. MUST NOT change execution ownership established at chat/toolCallStart; a client contributor must keep the same clientId. |
intention | string | No | Final human-readable description of what the tool invocation intends to do. When present, replaces the provisional intention from chat/toolCallStart. |
invocationMessage | StringOrMarkdown | Yes | Message describing what the tool will do or what confirmation is needed |
toolInput | string | No | Raw tool input |
confirmationTitle | StringOrMarkdown | No | Short title for the confirmation prompt (e.g. "Run in terminal", "Write file") |
riskAssessment | ToolCallRiskAssessment | No | Risk assessment that informed the confirmation requirement. |
edits | | No | File edits that this tool call will perform, for preview before confirmation |
editable | boolean | No | Whether the agent host allows the client to edit the tool's input parameters before confirming |
confirmed | ToolCallConfirmationReason | No | If set, the tool was auto-confirmed and transitions directly to running |
options | ConfirmationOption[] | No | Options the server offers for this confirmation. When present, the client SHOULD render these instead of a plain approve/deny UI. Each option belongs to a {@link ConfirmationOptionGroup} so the client can still categorise the choices. |
chat/toolCallConfirmed (approved)
Client approves a pending tool call. The tool transitions to running.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatToolCallConfirmed | Yes | |
approved | true | Yes | The tool call was approved |
confirmed | ToolCallConfirmationReason | Yes | How the tool was confirmed |
editedToolInput | string | No | Edited tool input parameters, if the client modified them before confirming |
selectedOptionId | string | No | ID of the selected confirmation option, if the server provided options |
chat/toolCallConfirmed (denied)
Client denies a pending tool call. The tool transitions to cancelled.
For client-provided tools, the owning client MUST dispatch this if it does not recognize the tool or cannot execute it.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatToolCallConfirmed | Yes | |
approved | false | Yes | The tool call was denied |
reason | ToolCallCancellationReason.Denied | ToolCallCancellationReason.Skipped | Yes | Why the tool was cancelled |
userSuggestion | Message | No | What the user suggested doing instead |
reasonMessage | StringOrMarkdown | No | Optional explanation for the denial |
selectedOptionId | string | No | ID of the selected confirmation option, if the server provided options |
ChatToolCallConfirmedAction
Client confirms or denies a pending tool call.
ChatToolCallApprovedAction | ChatToolCallDeniedAction
chat/toolCallComplete
Tool execution finished. Transitions to completed or pending-result-confirmation if requiresResultConfirmation is true.
For client-provided tools (whose tool call state carries a client ToolCallContributor with a clientId), the owning client dispatches this action with the execution result. The server SHOULD reject this action if the dispatching client does not match the contributor's clientId.
Servers waiting on a client tool call MAY time out after a reasonable duration if the implementing client disconnects or becomes unresponsive, and dispatch this action with result.success = false and an appropriate error.
A client MAY also dispatch this action with a failed result ( result.success: false) for a tool call currently in auth-required status, to cancel that invocation without completing the pending MCP authentication challenge. This always transitions the tool call straight to completed, preserving the fields it had before pausing for auth; requiresResultConfirmation is ignored for this transition; the cancellation can never enter pending-result-confirmation, since there is no real result to review.
A successful result (result.success: true) is invalid for a tool call in auth-required status — execution never resumed after the challenge, so there's nothing that could have produced it. The reducer MUST reject/ignore it as a no-op, leaving the tool call in auth-required. The client must resolve the auth challenge (chat/toolCallAuthResolved) before completing successfully.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatToolCallComplete | Yes | |
result | ToolCallResult | Yes | Execution result |
requiresResultConfirmation | boolean | No | If true, the result requires client approval before finalizing |
chat/toolCallResultConfirmed
Client approves or denies a tool's result.
If approved is false, the tool transitions to cancelled with reason result-denied.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatToolCallResultConfirmed | |
approved | boolean | Whether the result was approved |
chat/toolCallContentChanged
Partial content produced while a tool is still executing.
Replaces the content array on the running tool call state. Clients can use this to display live feedback (e.g. a terminal reference) before the tool completes.
For client-provided tools (whose tool call state carries a client ToolCallContributor with a clientId), the owning client dispatches this action to stream intermediate content while executing. The server SHOULD reject this action if the dispatching client does not match the contributor's clientId.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatToolCallContentChanged | |
content | ToolResultContent[] | The current partial content for the running tool call |
chat/toolCallAuthRequired
A running tool call is paused pending MCP authentication. Transitions the tool call from running to auth-required.
The server dispatches this when the MCP server backing the call responds with a 401/403 challenge mid-execution (see {@link McpAuthRequirement.reason | insufficientScope}). The host SHOULD pair this with session/inputNeededSet (kind toolAuthentication) so the block is visible at the session-summary level, mirroring {@link McpServerAuthRequiredState}'s own InputNeeded guidance.
Only valid for tool calls contributed by an MCP server — the reducer is a no-op if the tool call's contributor is not {@link ToolCallContributorKind.MCP | MCP-kind}.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatToolCallAuthRequired | |
auth | McpAuthRequirement | The authentication challenge blocking this invocation. |
chat/toolCallAuthResolved
The authentication challenge blocking a tool call has been resolved (the client pushed a token via authenticate and the host validated it). Transitions the tool call from auth-required back to running, preserving the fields it had before pausing.
The host SHOULD remove the corresponding session/inputNeededSet entry (kind toolAuthentication) once this is dispatched.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatToolCallAuthResolved |
chat/turnComplete
Turn finished — the assistant is idle.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatTurnComplete | Yes | |
turnId | string | Yes | Turn identifier |
duration | number | Yes | Elapsed turn duration in milliseconds, measured by the producer's own clock. Clients MUST NOT derive this by subtracting timestamps — cross- client clocks may differ — and MUST treat it as opaque, producer-supplied data. |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/turnCancelled
Turn was aborted; server stops processing.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatTurnCancelled | Yes | |
turnId | string | Yes | Turn identifier |
duration | number | Yes | Elapsed turn duration in milliseconds, measured by the producer's own clock. Clients MUST NOT derive this by subtracting timestamps — cross- client clocks may differ — and MUST treat it as opaque, producer-supplied data. |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/error
Error during turn processing.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatError | Yes | |
turnId | string | Yes | Turn identifier |
duration | number | Yes | Elapsed turn duration in milliseconds, measured by the producer's own clock. Clients MUST NOT derive this by subtracting timestamps — cross- client clocks may differ — and MUST treat it as opaque, producer-supplied data. |
error | ErrorInfo | Yes | Error details |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/activityChanged
The activity description of this chat changed.
Dispatched by the server to indicate what the chat is currently doing (e.g. running a tool, thinking). Clear activity by omitting it or setting it to undefined. Producers SHOULD also update the parent session's chat catalog with session/chatUpdated so ChatSummary.activity stays in sync.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatActivityChanged | Yes | |
activity | string | No | Human-readable description of current activity; omit or set undefined to clear |
chat/workingDirectorySet
A working directory was added to this chat's {@link ChatState.workingDirectories} subset.
Membership semantics keyed by the directory URI: the reducer appends directory when the chat's subset does not already contain it (creating the subset if absent) and is a no-op when it is already present. directory MUST be one of the owning session's {@link SessionState.workingDirectories}; a host MUST reject a directory that is not. Only valid when the agent advertises {@link AgentCapabilities.multipleWorkingDirectories}.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatWorkingDirectorySet | |
directory | URI | The working directory to add to this chat's subset. |
chat/workingDirectoryRemoved
A working directory was removed from this chat's {@link ChatState.workingDirectories} subset.
Removes directory from the chat's subset; a no-op when it is not present. Idempotent, mirroring session/workingDirectoryRemoved. Only affects the chat's subset — the directory remains in the session's set.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatWorkingDirectoryRemoved | |
directory | URI | The working directory to remove from this chat's subset. |
chat/usage
Token usage report for a turn.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatUsage | Yes | |
turnId | string | Yes | Turn identifier |
usage | UsageInfo | Yes | Token usage data |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/reasoning
Reasoning/thinking text from the model, appended to a specific reasoning response part.
The server MUST first emit a chat/responsePart to create the target reasoning part, then use this action to append text to it.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatReasoning | Yes | |
turnId | string | Yes | Turn identifier |
partId | string | Yes | Identifier of the reasoning response part to append to |
content | string | Yes | Reasoning text chunk |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this action. Clients MAY look for well-known keys here to provide enhanced UI, and agent hosts MAY use it to carry per-event context that does not fit any other field — for example, attributing the event to a specific agent (such as a sub-agent acting within the turn). Mirrors the MCP _meta convention. |
chat/truncated
Truncates a session's history. If turnId is provided, all turns after that turn are removed and the specified turn is kept. If turnId is omitted, all turns are removed.
If there is an active turn it is silently dropped and the chat status returns to idle.
Common use-case: truncate old data then dispatch a new chat/turnStarted with an edited message.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatTruncated | Yes | |
turnId | string | No | Keep turns up to and including this turn. Omit to clear all turns. |
chat/turnsLoaded
Loads older completed turns into this chat's state.
Hosts dispatch this before responding to fetchTurns, and before applying any operation that references a turn older than the currently loaded window. turns is ordered oldest-first and is prepended to the current turns window. turnsNextCursor replaces the state's cursor; omit it when all retained turns are now loaded.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatTurnsLoaded | Yes | |
turns | Turn[] | Yes | Older completed turns loaded into the state, ordered oldest-first. |
turnsNextCursor | string | No | Opaque cursor for loading the next older page, if one remains. |
chat/pendingMessageSet
A pending message was set (upsert semantics: creates or replaces).
For steering messages, this always replaces the single steering message. For queued messages, if a message with the given id already exists it is updated in place; otherwise it is appended to the queue. If the chat is idle when a queued message is set, the server SHOULD immediately consume it and start a new turn.
A client is only allowed to send {@link MessageKind.User} messages.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatPendingMessageSet | |
kind | PendingMessageKind | Whether this is a steering or queued message |
id | string | Unique identifier for this pending message |
message | Message | The message content |
chat/pendingMessageRemoved
A pending message was removed (steering or queued).
Dispatched by clients to cancel a pending message, or by the server when it consumes a message (e.g. starting a turn from a queued message or injecting a steering message into the current turn).
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatPendingMessageRemoved | |
kind | PendingMessageKind | Whether this is a steering or queued message |
id | string | Identifier of the pending message to remove |
chat/queuedMessagesReordered
Reorder the queued messages.
The order array contains the IDs of queued messages in their new desired order. IDs not present in the current queue are ignored. Queued messages whose IDs are absent from order are appended at the end in their original relative order (so a client with a stale view of the queue never silently drops messages).
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatQueuedMessagesReordered | |
order | string[] | Queued message IDs in the desired order |
chat/draftChanged
The chat's draft input changed.
Clients MAY periodically sync their local input state — the message the user is composing, including its {@link Message.model | model} / {@link Message.agent | agent} selection and attachments — into the chat's {@link ChatState.draft | draft} so it survives reloads and is visible to other clients viewing the same chat. Eager syncing is not required; clients SHOULD debounce and MAY sync only at convenient points. Set draft to undefined to clear it (e.g. once the message is sent).
A client is only allowed to draft {@link MessageKind.User} messages.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatDraftChanged | Yes | |
draft | Message | No | New draft message, or undefined to clear it |
chat/inputRequested
A session requested input from the user.
Creates an unresolved {@link InputRequestResponsePart} in the active turn, or replaces the unresolved part with the same request id. Answer drafts are preserved unless request.answers is provided.
| Field | Type | Description |
|---|---|---|
type | ActionType.ChatInputRequested | |
request | ChatInputRequest | Input request to create or replace |
chat/inputAnswerChanged
A client updated, submitted, skipped, or removed a single in-progress answer.
Dispatching with answer: undefined removes that question's answer draft.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatInputAnswerChanged | Yes | |
requestId | string | Yes | Input request identifier |
questionId | string | Yes | Question identifier within the input request |
answer | ChatInputAnswer | No | Updated answer, or undefined to clear an answer draft |
chat/inputCompleted
A client submitted an accept, decline, or cancel response to an input request.
If accepted, the server uses answers (when provided) plus the request's synced answer state to resume the blocked operation. The reducer records the response and final answers on the existing {@link InputRequestResponsePart}.
| Field | Type | Required | Description |
|---|---|---|---|
type | ActionType.ChatInputCompleted | Yes | |
requestId | string | Yes | Input request identifier |
response | ChatInputResponseKind | Yes | Completion outcome |
answers | Record<string, ChatInputAnswer> | No | Optional final answer replacement, keyed by question ID |
ChatAction
ChatTurnStartedAction | ChatDeltaAction | ChatResponsePartAction | ChatToolCallStartAction | ChatToolCallDeltaAction | ChatToolCallReadyAction | ChatToolCallConfirmedAction | ChatToolCallCompleteAction | ChatToolCallResultConfirmedAction | ChatToolCallContentChangedAction | ChatToolCallAuthRequiredAction | ChatToolCallAuthResolvedAction | ChatTurnCompleteAction | ChatTurnCancelledAction | ChatErrorAction | ChatActivityChangedAction | ChatWorkingDirectorySetAction | ChatWorkingDirectoryRemovedAction | ChatUsageAction | ChatReasoningAction | ChatTruncatedAction | ChatTurnsLoadedAction | ChatPendingMessageSetAction | ChatPendingMessageRemovedAction | ChatQueuedMessagesReorderedAction | ChatDraftChangedAction | ChatInputRequestedAction | ChatInputAnswerChangedAction | ChatInputCompletedAction
Commands
JSON Schema: commands.schema.json
createChat
Creates a new chat within a session.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | URI | Yes | Session URI containing the new chat. |
chat | URI | Yes | Chat URI (client-chosen, e.g. ahp-chat:/<uuid>). |
initialMessage | Message | No | Optional initial message for the new chat. |
source | ChatSource | No | Optional source chat and source turn. The source chat MUST belong to this session. Clients MUST only request kind: "fork" when the selected agent advertises capabilities.multipleChats.fork, and kind: "sideChat" when the selected agent advertises capabilities.multipleChats.sideChat. Both source forms carry a stable top-level turnId. Forks target completed turns. Side chats also carry a stable turnId, which the host resolves against the source chat's current active turn or retained history. If it resolves to the active turn, the host snapshots the currently available partial response when accepting createChat. When source.kind === "sideChat" and source.selection is present, the host also snapshots and preserves that exact selected text in the created chat's origin; any responsePartId there is provenance only, not a live range. |
workingDirectories | URI[] | No | Initial working-directory subset for this chat. Every entry MUST be present in the owning session's workingDirectories; the server MUST reject any entry that is not. When absent, the chat inherits the full session set. Forked chats (those whose source.kind is "fork") inherit the source chat's workingDirectories; this field is ignored for forks.A client MUST NOT supply this field unless the agent advertises {@link AgentCapabilities.multipleWorkingDirectories}. |
Result: null on success.
disposeChat
Disposes a chat and cleans up server-side resources.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
No parameters.
Result: null on success.