// Generated from types/*.ts — do not edit. // Regenerate with: npm run generate:typescript /** * Chat Channel Actions — Mutations of an `ahp-chat:` channel's state. * * @module channels-chat/actions */ import { ActionType } from '../common/actions.js'; import type { StringOrMarkdown, FileEdit, UsageInfo, URI } from '../common/state.js'; import type { McpAuthRequirement } from '../channels-session/state.js'; import type { Message, ResponsePart, ToolCallResult, ToolResultContent, ChatInputAnswer, ChatInputRequest, ChatInputResponseKind, ConfirmationOption, ErrorResponsePart, ToolCallContributor, ToolCallRiskAssessment, ToolInput, Turn, } from './state.js'; import { ToolCallConfirmationReason, ToolCallCancellationReason, PendingMessageKind, } from './state.js'; // ─── Tool Call Action Base ─────────────────────────────────────────────────── /** * Base interface for all tool-call-scoped actions, carrying the common turn * and tool call identifiers. The owning chat URI is identified by the * enclosing {@link ActionEnvelope}'s `channel` field. * * @category Chat Actions */ interface ToolCallActionBase { /** Turn identifier */ turnId: string; /** Tool call identifier */ toolCallId: string; /** * Additional provider-specific metadata for this tool call. * * Clients MAY look for well-known keys here to provide enhanced UI. * For example, a `ptyTerminal` key with `{ input: string; output: string }` * indicates the tool operated on a terminal (both `input` and `output` may * contain escape sequences). */ _meta?: Record; } // ─── Chat Actions ─────────────────────────────────────────────────────────── /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatTurnStartedAction { type: ActionType.ChatTurnStarted; /** Turn identifier */ turnId: string; /** ISO 8601 timestamp when this turn started. */ startedAt: string; /** The new message */ message: Message; /** If this turn was auto-started from a queued message, the ID of that message */ queuedMessageId?: string; /** * 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. */ _meta?: Record; } /** * Streaming text chunk from the assistant, appended to a specific response part. * * The server MUST first emit a `chat/responsePart` to create the target * markdown part, then use this action to append text to it. * * @category Chat Actions * @version 1 */ export interface ChatDeltaAction { type: ActionType.ChatDelta; /** Turn identifier */ turnId: string; /** Identifier of the response part to append to */ partId: string; /** Text chunk */ content: string; /** * 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. */ _meta?: Record; } /** * Structured content appended to the response. * * An {@link ErrorResponsePart} MUST be appended with {@link ChatErrorAction} * instead so adding the part and ending the turn are one atomic transition. * * @category Chat Actions * @version 1 */ export interface ChatResponsePartAction { type: ActionType.ChatResponsePart; /** Turn identifier */ turnId: string; /** Response part to append; error parts are ignored. */ part: ResponsePart; /** * 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. */ _meta?: Record; } /** * 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`. * * @category Chat Actions * @version 1 */ export interface ChatToolCallStartAction extends ToolCallActionBase { type: ActionType.ChatToolCallStart; /** Internal tool name (for debugging/logging) */ toolName: string; /** Human-readable tool name */ displayName: string; /** Human-readable description of what the tool invocation intends to do */ intention?: string; /** * Reference to the contributor of the tool being called. Absent for * server-side tools that are not contributed by a client or MCP server. */ contributor?: ToolCallContributor; } /** * Streaming partial parameters for a tool call. * * @category Chat Actions * @version 1 */ export interface ChatToolCallDeltaAction extends ToolCallActionBase { type: ActionType.ChatToolCallDelta; /** Partial parameter content to append, if provided by the host. */ content?: string; /** Updated progress message */ invocationMessage?: StringOrMarkdown; } /** * 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. * * @category Chat Actions * @version 1 */ export interface ChatToolCallReadyAction extends ToolCallActionBase { type: ActionType.ChatToolCallReady; /** * Final contributor metadata. MUST NOT change execution ownership established * at `chat/toolCallStart`; a client contributor must keep the same `clientId`. */ contributor?: ToolCallContributor; /** * Final human-readable description of what the tool invocation intends to do. * When present, replaces the provisional intention from `chat/toolCallStart`. */ intention?: string; /** Message describing what the tool will do or what confirmation is needed */ invocationMessage: StringOrMarkdown; /** Final tool input */ toolInput?: ToolInput; /** Short title for the confirmation prompt (e.g. `"Run in terminal"`, `"Write file"`) */ confirmationTitle?: StringOrMarkdown; /** Risk assessment that informed the confirmation requirement. */ riskAssessment?: ToolCallRiskAssessment; /** File edits that this tool call will perform, for preview before confirmation */ edits?: { items: FileEdit[] }; /** Whether the agent host allows the client to edit the tool's input parameters before confirming */ editable?: boolean; /** If set, the tool was auto-confirmed and transitions directly to `running` */ confirmed?: ToolCallConfirmationReason; /** * 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. */ options?: ConfirmationOption[]; } /** * Client approves a pending tool call. The tool transitions to `running`. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatToolCallApprovedAction extends ToolCallActionBase { type: ActionType.ChatToolCallConfirmed; /** The tool call was approved */ approved: true; /** How the tool was confirmed */ confirmed: ToolCallConfirmationReason; /** * Edited tool input parameters, if the client modified them before confirming. * * For inline `toolInput`, the reducer replaces the state value directly. * For referenced input, the host MUST replace the resource contents before * echoing the accepted action. */ editedToolInput?: string; /** ID of the selected confirmation option, if the server provided options */ selectedOptionId?: string; } /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatToolCallDeniedAction extends ToolCallActionBase { type: ActionType.ChatToolCallConfirmed; /** The tool call was denied */ approved: false; /** Why the tool was cancelled */ reason: ToolCallCancellationReason.Denied | ToolCallCancellationReason.Skipped; /** What the user suggested doing instead */ userSuggestion?: Message; /** Optional explanation for the denial */ reasonMessage?: StringOrMarkdown; /** ID of the selected confirmation option, if the server provided options */ selectedOptionId?: string; } /** * Client confirms or denies a pending tool call. * * @category Chat Actions * @version 1 * @clientDispatchable */ export type ChatToolCallConfirmedAction = | ChatToolCallApprovedAction | ChatToolCallDeniedAction; /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatToolCallCompleteAction extends ToolCallActionBase { type: ActionType.ChatToolCallComplete; /** Execution result */ result: ToolCallResult; /** If true, the result requires client approval before finalizing */ requiresResultConfirmation?: boolean; } /** * Client approves or denies a tool's result. * * If `approved` is `false`, the tool transitions to `cancelled` with reason `result-denied`. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatToolCallResultConfirmedAction extends ToolCallActionBase { type: ActionType.ChatToolCallResultConfirmed; /** Whether the result was approved */ approved: boolean; } /** * 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`. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatToolCallContentChangedAction extends ToolCallActionBase { type: ActionType.ChatToolCallContentChanged; /** The current partial content for the running tool call */ content: ToolResultContent[]; } /** * 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}. * * @category Chat Actions * @version 1 */ export interface ChatToolCallAuthRequiredAction extends ToolCallActionBase { type: ActionType.ChatToolCallAuthRequired; /** The authentication challenge blocking this invocation. */ auth: McpAuthRequirement; } /** * 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. * * @category Chat Actions * @version 1 */ export interface ChatToolCallAuthResolvedAction extends ToolCallActionBase { type: ActionType.ChatToolCallAuthResolved; } /** * Turn finished — the assistant is idle. * * @category Chat Actions * @version 1 */ export interface ChatTurnCompleteAction { type: ActionType.ChatTurnComplete; /** Turn identifier */ turnId: string; /** * 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. */ duration: number; /** * 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. */ _meta?: Record; } /** * Turn was aborted; server stops processing. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatTurnCancelledAction { type: ActionType.ChatTurnCancelled; /** Turn identifier */ turnId: string; /** * 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. */ duration: number; /** * 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. */ _meta?: Record; } /** * Error during turn processing. * * @category Chat Actions * @version 1 */ export interface ChatErrorAction { type: ActionType.ChatError; /** Turn identifier */ turnId: string; /** * 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. */ duration: number; /** * Error part to append to the response stream before finalizing the turn. * Its optional `resumable` flag indicates whether the turn can be resumed. */ part: ErrorResponsePart; /** * 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. */ _meta?: Record; } /** * Resumes the latest errored turn without adding another message. * * The turn MUST be the latest turn, its state MUST be `error`, and its final * response part MUST be a resumable error. The reducer reopens the same turn * with its existing message, response parts, and usage intact. The host then * resumes the provider's execution for that turn. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatTurnResumeAction { type: ActionType.ChatTurnResume; /** Identifier of the errored turn. */ turnId: string; } /** * 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. * * @category Chat Actions * @version 1 */ export interface ChatActivityChangedAction { type: ActionType.ChatActivityChanged; /** Human-readable description of current activity; omit or set `undefined` to clear */ activity?: string; } /** * 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}. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatWorkingDirectorySetAction { type: ActionType.ChatWorkingDirectorySet; /** The working directory to add to this chat's subset. */ directory: URI; } /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatWorkingDirectoryRemovedAction { type: ActionType.ChatWorkingDirectoryRemoved; /** The working directory to remove from this chat's subset. */ directory: URI; } /** * Token usage report for a turn. * * @category Chat Actions * @version 1 */ export interface ChatUsageAction { type: ActionType.ChatUsage; /** Turn identifier */ turnId: string; /** Token usage data */ usage: UsageInfo; /** * 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. */ _meta?: Record; } /** * 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. * * @category Chat Actions * @version 1 */ export interface ChatReasoningAction { type: ActionType.ChatReasoning; /** Turn identifier */ turnId: string; /** Identifier of the reasoning response part to append to */ partId: string; /** Reasoning text chunk */ content: string; /** * 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. */ _meta?: Record; } // ─── Truncation ────────────────────────────────────────────────────────────── /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatTruncatedAction { type: ActionType.ChatTruncated; /** Keep turns up to and including this turn. Omit to clear all turns. */ turnId?: string; } /** * 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. * * @category Chat Actions * @version 1 */ export interface ChatTurnsLoadedAction { type: ActionType.ChatTurnsLoaded; /** Older completed turns loaded into the state, ordered oldest-first. */ turns: Turn[]; /** Opaque cursor for loading the next older page, if one remains. */ turnsNextCursor?: string; } // ─── Pending Message Actions ───────────────────────────────────────────────── /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatPendingMessageSetAction { type: ActionType.ChatPendingMessageSet; /** Whether this is a steering or queued message */ kind: PendingMessageKind; /** Unique identifier for this pending message */ id: string; /** The message content */ message: Message; } /** * 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). * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatPendingMessageRemovedAction { type: ActionType.ChatPendingMessageRemoved; /** Whether this is a steering or queued message */ kind: PendingMessageKind; /** Identifier of the pending message to remove */ id: string; } /** * 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). * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatQueuedMessagesReorderedAction { type: ActionType.ChatQueuedMessagesReordered; /** Queued message IDs in the desired order */ order: string[]; } // ─── Draft Actions ─────────────────────────────────────────────────────────── /** * 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. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatDraftChangedAction { type: ActionType.ChatDraftChanged; /** New draft message, or `undefined` to clear it */ draft?: Message; } // ─── Session Input Actions ────────────────────────────────────────────────── /** * 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. * * @category Chat Actions * @version 1 */ export interface ChatInputRequestedAction { type: ActionType.ChatInputRequested; /** Input request to create or replace */ request: ChatInputRequest; } /** * A client updated, submitted, skipped, or removed a single in-progress answer. * * Dispatching with `answer: undefined` removes that question's answer draft. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatInputAnswerChangedAction { type: ActionType.ChatInputAnswerChanged; /** Input request identifier */ requestId: string; /** Question identifier within the input request */ questionId: string; /** Updated answer, or `undefined` to clear an answer draft */ answer?: ChatInputAnswer; } /** * 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}. * * @category Chat Actions * @version 1 * @clientDispatchable */ export interface ChatInputCompletedAction { type: ActionType.ChatInputCompleted; /** Input request identifier */ requestId: string; /** Completion outcome */ response: ChatInputResponseKind; /** Optional final answer replacement, keyed by question ID */ answers?: Record; } export type ChatAction = | ChatTurnStartedAction | ChatDeltaAction | ChatResponsePartAction | ChatToolCallStartAction | ChatToolCallDeltaAction | ChatToolCallReadyAction | ChatToolCallConfirmedAction | ChatToolCallCompleteAction | ChatToolCallResultConfirmedAction | ChatToolCallContentChangedAction | ChatToolCallAuthRequiredAction | ChatToolCallAuthResolvedAction | ChatTurnCompleteAction | ChatTurnCancelledAction | ChatErrorAction | ChatTurnResumeAction | ChatActivityChangedAction | ChatWorkingDirectorySetAction | ChatWorkingDirectoryRemovedAction | ChatUsageAction | ChatReasoningAction | ChatTruncatedAction | ChatTurnsLoadedAction | ChatPendingMessageSetAction | ChatPendingMessageRemovedAction | ChatQueuedMessagesReorderedAction | ChatDraftChangedAction | ChatInputRequestedAction | ChatInputAnswerChangedAction | ChatInputCompletedAction ;