Skip to main content

ahp_types/
actions.rs

1// Generated from types/*.ts — do not edit.
2//
3// Regenerate with: npm run generate:rust
4
5#![allow(missing_docs)]
6
7#[allow(unused_imports)]
8use crate::common::{AnyValue, JsonObject, StringOrMarkdown, Uri};
9#[allow(unused_imports)]
10use serde::{Deserialize, Serialize};
11#[allow(unused_imports)]
12use serde_repr::{Deserialize_repr, Serialize_repr};
13
14use crate::state::{
15    AgentInfo, AgentSelection, Changeset, ChangesetFile, ChangesetOperation,
16    ChangesetOperationStatus, ChangesetStatus, ConfirmationOption, Customization, ErrorInfo,
17    McpServerState, Message, ModelSelection, PendingMessageKind, ResponsePart, SessionActiveClient,
18    SessionInputAnswer, SessionInputRequest, SessionInputResponseKind, TerminalClaim, TerminalInfo,
19    ToolCallCancellationReason, ToolCallConfirmationReason, ToolCallContributor, ToolCallResult,
20    ToolDefinition, ToolResultContent, UsageInfo,
21};
22
23// ─── ActionType ──────────────────────────────────────────────────────
24
25/// Discriminant values for all state actions.
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
27pub enum ActionType {
28    #[serde(rename = "root/agentsChanged")]
29    RootAgentsChanged,
30    #[serde(rename = "root/activeSessionsChanged")]
31    RootActiveSessionsChanged,
32    #[serde(rename = "session/ready")]
33    SessionReady,
34    #[serde(rename = "session/creationFailed")]
35    SessionCreationFailed,
36    #[serde(rename = "session/turnStarted")]
37    SessionTurnStarted,
38    #[serde(rename = "session/delta")]
39    SessionDelta,
40    #[serde(rename = "session/responsePart")]
41    SessionResponsePart,
42    #[serde(rename = "session/toolCallStart")]
43    SessionToolCallStart,
44    #[serde(rename = "session/toolCallDelta")]
45    SessionToolCallDelta,
46    #[serde(rename = "session/toolCallReady")]
47    SessionToolCallReady,
48    #[serde(rename = "session/toolCallConfirmed")]
49    SessionToolCallConfirmed,
50    #[serde(rename = "session/toolCallComplete")]
51    SessionToolCallComplete,
52    #[serde(rename = "session/toolCallResultConfirmed")]
53    SessionToolCallResultConfirmed,
54    #[serde(rename = "session/toolCallContentChanged")]
55    SessionToolCallContentChanged,
56    #[serde(rename = "session/turnComplete")]
57    SessionTurnComplete,
58    #[serde(rename = "session/turnCancelled")]
59    SessionTurnCancelled,
60    #[serde(rename = "session/error")]
61    SessionError,
62    #[serde(rename = "session/titleChanged")]
63    SessionTitleChanged,
64    #[serde(rename = "session/usage")]
65    SessionUsage,
66    #[serde(rename = "session/reasoning")]
67    SessionReasoning,
68    #[serde(rename = "session/modelChanged")]
69    SessionModelChanged,
70    #[serde(rename = "session/agentChanged")]
71    SessionAgentChanged,
72    #[serde(rename = "session/serverToolsChanged")]
73    SessionServerToolsChanged,
74    #[serde(rename = "session/activeClientChanged")]
75    SessionActiveClientChanged,
76    #[serde(rename = "session/activeClientToolsChanged")]
77    SessionActiveClientToolsChanged,
78    #[serde(rename = "session/pendingMessageSet")]
79    SessionPendingMessageSet,
80    #[serde(rename = "session/pendingMessageRemoved")]
81    SessionPendingMessageRemoved,
82    #[serde(rename = "session/queuedMessagesReordered")]
83    SessionQueuedMessagesReordered,
84    #[serde(rename = "session/inputRequested")]
85    SessionInputRequested,
86    #[serde(rename = "session/inputAnswerChanged")]
87    SessionInputAnswerChanged,
88    #[serde(rename = "session/inputCompleted")]
89    SessionInputCompleted,
90    #[serde(rename = "session/customizationsChanged")]
91    SessionCustomizationsChanged,
92    #[serde(rename = "session/customizationToggled")]
93    SessionCustomizationToggled,
94    #[serde(rename = "session/customizationUpdated")]
95    SessionCustomizationUpdated,
96    #[serde(rename = "session/customizationRemoved")]
97    SessionCustomizationRemoved,
98    #[serde(rename = "session/mcpServerStateChanged")]
99    SessionMcpServerStateChanged,
100    #[serde(rename = "session/truncated")]
101    SessionTruncated,
102    #[serde(rename = "session/isReadChanged")]
103    SessionIsReadChanged,
104    #[serde(rename = "session/isArchivedChanged")]
105    SessionIsArchivedChanged,
106    #[serde(rename = "session/activityChanged")]
107    SessionActivityChanged,
108    #[serde(rename = "session/changesetsChanged")]
109    SessionChangesetsChanged,
110    #[serde(rename = "session/configChanged")]
111    SessionConfigChanged,
112    #[serde(rename = "session/metaChanged")]
113    SessionMetaChanged,
114    #[serde(rename = "changeset/statusChanged")]
115    ChangesetStatusChanged,
116    #[serde(rename = "changeset/fileSet")]
117    ChangesetFileSet,
118    #[serde(rename = "changeset/fileRemoved")]
119    ChangesetFileRemoved,
120    #[serde(rename = "changeset/operationsChanged")]
121    ChangesetOperationsChanged,
122    #[serde(rename = "changeset/operationStatusChanged")]
123    ChangesetOperationStatusChanged,
124    #[serde(rename = "changeset/cleared")]
125    ChangesetCleared,
126    #[serde(rename = "root/terminalsChanged")]
127    RootTerminalsChanged,
128    #[serde(rename = "root/configChanged")]
129    RootConfigChanged,
130    #[serde(rename = "terminal/data")]
131    TerminalData,
132    #[serde(rename = "terminal/input")]
133    TerminalInput,
134    #[serde(rename = "terminal/resized")]
135    TerminalResized,
136    #[serde(rename = "terminal/claimed")]
137    TerminalClaimed,
138    #[serde(rename = "terminal/titleChanged")]
139    TerminalTitleChanged,
140    #[serde(rename = "terminal/cwdChanged")]
141    TerminalCwdChanged,
142    #[serde(rename = "terminal/exited")]
143    TerminalExited,
144    #[serde(rename = "terminal/cleared")]
145    TerminalCleared,
146    #[serde(rename = "terminal/commandDetectionAvailable")]
147    TerminalCommandDetectionAvailable,
148    #[serde(rename = "terminal/commandExecuted")]
149    TerminalCommandExecuted,
150    #[serde(rename = "terminal/commandFinished")]
151    TerminalCommandFinished,
152    #[serde(rename = "resourceWatch/changed")]
153    ResourceWatchChanged,
154}
155
156// ─── Action Envelope ─────────────────────────────────────────────────
157
158/// Identifies the client that originally dispatched an action.
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
160#[serde(rename_all = "camelCase")]
161pub struct ActionOrigin {
162    pub client_id: String,
163    pub client_seq: i64,
164}
165
166/// Every action is wrapped in an `ActionEnvelope`.
167///
168/// The envelope identifies the channel the action belongs to (e.g.
169/// `ahp-root://` for root actions, the session URI for session actions, the
170/// terminal URI for terminal actions). Individual action payloads carry only
171/// fields that are intrinsic to the action; the channel comes from the
172/// envelope so that any subscribable resource can route its actions uniformly.
173#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
174#[serde(rename_all = "camelCase")]
175pub struct ActionEnvelope {
176    /// Channel URI this action belongs to.
177    pub channel: Uri,
178    pub action: StateAction,
179    pub server_seq: u64,
180    pub origin: Option<ActionOrigin>,
181    #[serde(default, skip_serializing_if = "Option::is_none")]
182    pub rejection_reason: Option<String>,
183}
184
185// ─── Action Payloads ─────────────────────────────────────────────────
186
187/// Fired when available agent backends or their models change.
188#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
189#[serde(rename_all = "camelCase")]
190pub struct RootAgentsChangedAction {
191    /// Updated agent list
192    pub agents: Vec<AgentInfo>,
193}
194
195/// Fired when the number of active sessions changes.
196#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
197#[serde(rename_all = "camelCase")]
198pub struct RootActiveSessionsChangedAction {
199    /// Current count of active sessions
200    pub active_sessions: i64,
201}
202
203/// Fired when agent-host configuration values change.
204///
205/// By default, the reducer merges the new values into `state.config.values`.
206/// Set `replace` to `true` to replace all values instead of merging.
207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
208#[serde(rename_all = "camelCase")]
209pub struct RootConfigChangedAction {
210    /// Updated config values
211    pub config: JsonObject,
212    /// When `true`, replaces all config values instead of merging
213    #[serde(default, skip_serializing_if = "Option::is_none")]
214    pub replace: Option<bool>,
215}
216
217/// Session backend initialized successfully.
218#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
219#[serde(rename_all = "camelCase")]
220pub struct SessionReadyAction {}
221
222/// Session backend failed to initialize.
223#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
224#[serde(rename_all = "camelCase")]
225pub struct SessionCreationFailedAction {
226    /// Error details
227    pub error: ErrorInfo,
228}
229
230/// A new message has been sent to the agent, and a new turn starts.
231///
232/// A client is only allowed to send {@link MessageKind.User} messages.
233#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
234#[serde(rename_all = "camelCase")]
235pub struct SessionTurnStartedAction {
236    /// Turn identifier
237    pub turn_id: String,
238    /// The new message
239    pub message: Message,
240    /// If this turn was auto-started from a queued message, the ID of that message
241    #[serde(default, skip_serializing_if = "Option::is_none")]
242    pub queued_message_id: Option<String>,
243}
244
245/// Streaming text chunk from the assistant, appended to a specific response part.
246///
247/// The server MUST first emit a `session/responsePart` to create the target
248/// part (markdown or reasoning), then use this action to append text to it.
249#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
250#[serde(rename_all = "camelCase")]
251pub struct SessionDeltaAction {
252    /// Turn identifier
253    pub turn_id: String,
254    /// Identifier of the response part to append to
255    pub part_id: String,
256    /// Text chunk
257    pub content: String,
258}
259
260/// Structured content appended to the response.
261#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
262#[serde(rename_all = "camelCase")]
263pub struct SessionResponsePartAction {
264    /// Turn identifier
265    pub turn_id: String,
266    /// Response part (markdown or content ref)
267    pub part: ResponsePart,
268}
269
270/// A tool call begins — parameters are streaming from the LM.
271///
272/// The server sets {@link ToolCallContributor | `contributor`} to identify
273/// the origin of the tool. For client-provided tools, the named client is
274/// responsible for executing the tool once it reaches the `running` state
275/// and dispatching `session/toolCallComplete`. For MCP-served tools, the
276/// server executes the call against the named `McpServerCustomization`.
277#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
278#[serde(rename_all = "camelCase")]
279pub struct SessionToolCallStartAction {
280    /// Turn identifier
281    pub turn_id: String,
282    /// Tool call identifier
283    pub tool_call_id: String,
284    /// Additional provider-specific metadata for this tool call.
285    ///
286    /// Clients MAY look for well-known keys here to provide enhanced UI.
287    /// For example, a `ptyTerminal` key with `{ input: string; output: string }`
288    /// indicates the tool operated on a terminal (both `input` and `output` may
289    /// contain escape sequences).
290    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
291    pub meta: Option<JsonObject>,
292    /// Internal tool name (for debugging/logging)
293    pub tool_name: String,
294    /// Human-readable tool name
295    pub display_name: String,
296    /// Reference to the contributor of the tool being called. Absent for
297    /// server-side tools that are not contributed by a client or MCP server.
298    #[serde(default, skip_serializing_if = "Option::is_none")]
299    pub contributor: Option<ToolCallContributor>,
300}
301
302/// Streaming partial parameters for a tool call.
303#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
304#[serde(rename_all = "camelCase")]
305pub struct SessionToolCallDeltaAction {
306    /// Turn identifier
307    pub turn_id: String,
308    /// Tool call identifier
309    pub tool_call_id: String,
310    /// Additional provider-specific metadata for this tool call.
311    ///
312    /// Clients MAY look for well-known keys here to provide enhanced UI.
313    /// For example, a `ptyTerminal` key with `{ input: string; output: string }`
314    /// indicates the tool operated on a terminal (both `input` and `output` may
315    /// contain escape sequences).
316    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
317    pub meta: Option<JsonObject>,
318    /// Partial parameter content to append
319    pub content: String,
320    /// Updated progress message
321    #[serde(default, skip_serializing_if = "Option::is_none")]
322    pub invocation_message: Option<StringOrMarkdown>,
323}
324
325/// Tool call parameters are complete, or a running tool requires re-confirmation.
326///
327/// When dispatched for a `streaming` tool call, transitions to `pending-confirmation`
328/// or directly to `running` if `confirmed` is set.
329///
330/// When dispatched for a `running` tool call (e.g. mid-execution permission needed),
331/// transitions back to `pending-confirmation`. The `invocationMessage` and `_meta`
332/// SHOULD be updated to describe the specific confirmation needed. Clients use the
333/// standard `session/toolCallConfirmed` flow to approve or deny.
334///
335/// For client-provided tools, the server typically sets `confirmed` to
336/// `'not-needed'` so the tool transitions directly to `running`, where the
337/// owning client can begin execution immediately.
338#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
339#[serde(rename_all = "camelCase")]
340pub struct SessionToolCallReadyAction {
341    /// Turn identifier
342    pub turn_id: String,
343    /// Tool call identifier
344    pub tool_call_id: String,
345    /// Additional provider-specific metadata for this tool call.
346    ///
347    /// Clients MAY look for well-known keys here to provide enhanced UI.
348    /// For example, a `ptyTerminal` key with `{ input: string; output: string }`
349    /// indicates the tool operated on a terminal (both `input` and `output` may
350    /// contain escape sequences).
351    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
352    pub meta: Option<JsonObject>,
353    /// Message describing what the tool will do or what confirmation is needed
354    pub invocation_message: StringOrMarkdown,
355    /// Raw tool input
356    #[serde(default, skip_serializing_if = "Option::is_none")]
357    pub tool_input: Option<String>,
358    /// Short title for the confirmation prompt (e.g. `"Run in terminal"`, `"Write file"`)
359    #[serde(default, skip_serializing_if = "Option::is_none")]
360    pub confirmation_title: Option<StringOrMarkdown>,
361    /// File edits that this tool call will perform, for preview before confirmation
362    #[serde(default, skip_serializing_if = "Option::is_none")]
363    pub edits: Option<AnyValue>,
364    /// Whether the agent host allows the client to edit the tool's input parameters before confirming
365    #[serde(default, skip_serializing_if = "Option::is_none")]
366    pub editable: Option<bool>,
367    /// If set, the tool was auto-confirmed and transitions directly to `running`
368    #[serde(default, skip_serializing_if = "Option::is_none")]
369    pub confirmed: Option<ToolCallConfirmationReason>,
370    /// Options the server offers for this confirmation. When present, the client
371    /// SHOULD render these instead of a plain approve/deny UI. Each option
372    /// belongs to a {@link ConfirmationOptionGroup} so the client can still
373    /// categorise the choices.
374    #[serde(default, skip_serializing_if = "Option::is_none")]
375    pub options: Option<Vec<ConfirmationOption>>,
376}
377
378/// Client approves or denies a pending tool call (merged approved + denied variants).
379#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
380#[serde(rename_all = "camelCase")]
381pub struct SessionToolCallConfirmedAction {
382    pub turn_id: String,
383    pub tool_call_id: String,
384    /// Additional provider-specific metadata for this tool call.
385    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
386    pub meta: Option<JsonObject>,
387    /// Whether the tool call was approved.
388    pub approved: bool,
389    /// How the tool was confirmed (present when approved).
390    #[serde(default, skip_serializing_if = "Option::is_none")]
391    pub confirmed: Option<ToolCallConfirmationReason>,
392    /// Why the tool was cancelled (present when denied).
393    #[serde(default, skip_serializing_if = "Option::is_none")]
394    pub reason: Option<ToolCallCancellationReason>,
395    /// Edited tool input parameters, if the client modified them before confirming.
396    #[serde(default, skip_serializing_if = "Option::is_none")]
397    pub edited_tool_input: Option<String>,
398    /// What the user suggested doing instead (present when denied).
399    #[serde(default, skip_serializing_if = "Option::is_none")]
400    pub user_suggestion: Option<Message>,
401    /// Explanation for the denial.
402    #[serde(default, skip_serializing_if = "Option::is_none")]
403    pub reason_message: Option<StringOrMarkdown>,
404    /// ID of the selected confirmation option, if the server provided options.
405    #[serde(default, skip_serializing_if = "Option::is_none")]
406    pub selected_option_id: Option<String>,
407}
408
409/// Tool execution finished. Transitions to `completed` or `pending-result-confirmation`
410/// if `requiresResultConfirmation` is `true`.
411///
412/// For client-provided tools (where `toolClientId` is set on the tool call state),
413/// the owning client dispatches this action with the execution result. The server
414/// SHOULD reject this action if the dispatching client does not match `toolClientId`.
415///
416/// Servers waiting on a client tool call MAY time out after a reasonable duration
417/// if the implementing client disconnects or becomes unresponsive, and dispatch
418/// this action with `result.success = false` and an appropriate error.
419#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
420#[serde(rename_all = "camelCase")]
421pub struct SessionToolCallCompleteAction {
422    /// Turn identifier
423    pub turn_id: String,
424    /// Tool call identifier
425    pub tool_call_id: String,
426    /// Additional provider-specific metadata for this tool call.
427    ///
428    /// Clients MAY look for well-known keys here to provide enhanced UI.
429    /// For example, a `ptyTerminal` key with `{ input: string; output: string }`
430    /// indicates the tool operated on a terminal (both `input` and `output` may
431    /// contain escape sequences).
432    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
433    pub meta: Option<JsonObject>,
434    /// Execution result
435    pub result: ToolCallResult,
436    /// If true, the result requires client approval before finalizing
437    #[serde(default, skip_serializing_if = "Option::is_none")]
438    pub requires_result_confirmation: Option<bool>,
439}
440
441/// Client approves or denies a tool's result.
442///
443/// If `approved` is `false`, the tool transitions to `cancelled` with reason `result-denied`.
444#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
445#[serde(rename_all = "camelCase")]
446pub struct SessionToolCallResultConfirmedAction {
447    /// Turn identifier
448    pub turn_id: String,
449    /// Tool call identifier
450    pub tool_call_id: String,
451    /// Additional provider-specific metadata for this tool call.
452    ///
453    /// Clients MAY look for well-known keys here to provide enhanced UI.
454    /// For example, a `ptyTerminal` key with `{ input: string; output: string }`
455    /// indicates the tool operated on a terminal (both `input` and `output` may
456    /// contain escape sequences).
457    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
458    pub meta: Option<JsonObject>,
459    /// Whether the result was approved
460    pub approved: bool,
461}
462
463/// Turn finished — the assistant is idle.
464#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
465#[serde(rename_all = "camelCase")]
466pub struct SessionTurnCompleteAction {
467    /// Turn identifier
468    pub turn_id: String,
469}
470
471/// Turn was aborted; server stops processing.
472#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
473#[serde(rename_all = "camelCase")]
474pub struct SessionTurnCancelledAction {
475    /// Turn identifier
476    pub turn_id: String,
477}
478
479/// Error during turn processing.
480#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
481#[serde(rename_all = "camelCase")]
482pub struct SessionErrorAction {
483    /// Turn identifier
484    pub turn_id: String,
485    /// Error details
486    pub error: ErrorInfo,
487}
488
489/// Session title updated. Fired by the server when the title is auto-generated
490/// from conversation, or dispatched by a client to rename a session.
491#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
492#[serde(rename_all = "camelCase")]
493pub struct SessionTitleChangedAction {
494    /// New title
495    pub title: String,
496}
497
498/// Token usage report for a turn.
499#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
500#[serde(rename_all = "camelCase")]
501pub struct SessionUsageAction {
502    /// Turn identifier
503    pub turn_id: String,
504    /// Token usage data
505    pub usage: UsageInfo,
506}
507
508/// Reasoning/thinking text from the model, appended to a specific reasoning response part.
509///
510/// The server MUST first emit a `session/responsePart` to create the target
511/// reasoning part, then use this action to append text to it.
512#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
513#[serde(rename_all = "camelCase")]
514pub struct SessionReasoningAction {
515    /// Turn identifier
516    pub turn_id: String,
517    /// Identifier of the reasoning response part to append to
518    pub part_id: String,
519    /// Reasoning text chunk
520    pub content: String,
521}
522
523/// Model changed for this session.
524#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
525#[serde(rename_all = "camelCase")]
526pub struct SessionModelChangedAction {
527    /// New model selection
528    pub model: ModelSelection,
529}
530
531/// Custom agent selection changed for this session.
532///
533/// Omitting `agent` (or setting it to `undefined`) clears the selection and
534/// resets the session to no selected custom agent (provider default behavior).
535///
536/// When a turn is currently active, the server MUST defer the change until
537/// the active turn completes, then apply it for the next turn (same rule as
538/// {@link SessionModelChangedAction | `session/modelChanged`}).
539#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
540#[serde(rename_all = "camelCase")]
541pub struct SessionAgentChangedAction {
542    /// New agent selection, or `undefined` to clear the selection and reset the
543    /// session to no selected custom agent.
544    #[serde(default, skip_serializing_if = "Option::is_none")]
545    pub agent: Option<AgentSelection>,
546}
547
548/// The read state of the session changed.
549///
550/// Dispatched by a client to mark a session as read (e.g. after viewing it)
551/// or unread (e.g. after new activity since the client last looked at it).
552#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
553#[serde(rename_all = "camelCase")]
554pub struct SessionIsReadChangedAction {
555    /// Whether the session has been read
556    pub is_read: bool,
557}
558
559/// The archived state of the session changed.
560///
561/// Dispatched by a client to archive a session (e.g. the task is
562/// complete) or to unarchive it.
563#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
564#[serde(rename_all = "camelCase")]
565pub struct SessionIsArchivedChangedAction {
566    /// Whether the session is archived
567    pub is_archived: bool,
568}
569
570/// The activity description of the session changed.
571///
572/// Dispatched by the server to indicate what the session is currently doing
573/// (e.g. running a tool, thinking). Clear activity by setting it to `undefined`.
574#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
575#[serde(rename_all = "camelCase")]
576pub struct SessionActivityChangedAction {
577    /// Human-readable description of current activity, or `undefined` to clear
578    #[serde(default, skip_serializing_if = "Option::is_none")]
579    pub activity: Option<String>,
580}
581
582/// The {@link Changeset | catalogue of changesets} the agent host
583/// advertises for this session changed. Replaces
584/// {@link SessionState.changesets | `state.changesets`} entirely
585/// (full-replacement semantics) — set to `undefined` to clear the
586/// catalogue.
587///
588/// Producers dispatch this whenever entries are added or removed. The
589/// fan-out happens through this action so observers see catalogue
590/// mutations in the same {@link ChangesetAction | per-changeset} action
591/// stream they already follow for file-level updates.
592#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
593#[serde(rename_all = "camelCase")]
594pub struct SessionChangesetsChangedAction {
595    /// New catalogue, or `undefined` to clear it
596    #[serde(default, skip_serializing_if = "Option::is_none")]
597    pub changesets: Option<Vec<Changeset>>,
598}
599
600/// Server tools for this session have changed.
601///
602/// Full-replacement semantics: the `tools` array replaces the previous `serverTools` entirely.
603#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
604#[serde(rename_all = "camelCase")]
605pub struct SessionServerToolsChangedAction {
606    /// Updated server tools list (full replacement)
607    pub tools: Vec<ToolDefinition>,
608}
609
610/// The active client for this session has changed.
611///
612/// A client dispatches this action with its own `SessionActiveClient` to claim
613/// the active role, or with `null` to release it. The server SHOULD reject if
614/// another client is already active. The server SHOULD automatically dispatch
615/// this action with `activeClient: null` when the active client disconnects.
616#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
617#[serde(rename_all = "camelCase")]
618pub struct SessionActiveClientChangedAction {
619    /// The new active client, or `null` to unset
620    #[serde(default, skip_serializing_if = "Option::is_none")]
621    pub active_client: Option<SessionActiveClient>,
622}
623
624/// The active client's tool list has changed.
625///
626/// Full-replacement semantics: the `tools` array replaces the active client's
627/// previous tools entirely. The server SHOULD reject if the dispatching client
628/// is not the current active client.
629#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
630#[serde(rename_all = "camelCase")]
631pub struct SessionActiveClientToolsChangedAction {
632    /// Updated client tools list (full replacement)
633    pub tools: Vec<ToolDefinition>,
634}
635
636/// A pending message was set (upsert semantics: creates or replaces).
637///
638/// For steering messages, this always replaces the single steering message.
639/// For queued messages, if a message with the given `id` already exists it is
640/// updated in place; otherwise it is appended to the queue. If the session is
641/// idle when a queued message is set, the server SHOULD immediately consume it
642/// and start a new turn.
643///
644/// A client is only allowed to send {@link MessageKind.User} messages.
645#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
646#[serde(rename_all = "camelCase")]
647pub struct SessionPendingMessageSetAction {
648    /// Whether this is a steering or queued message
649    pub kind: PendingMessageKind,
650    /// Unique identifier for this pending message
651    pub id: String,
652    /// The message content
653    pub message: Message,
654}
655
656/// A pending message was removed (steering or queued).
657///
658/// Dispatched by clients to cancel a pending message, or by the server when
659/// it consumes a message (e.g. starting a turn from a queued message or
660/// injecting a steering message into the current turn).
661#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
662#[serde(rename_all = "camelCase")]
663pub struct SessionPendingMessageRemovedAction {
664    /// Whether this is a steering or queued message
665    pub kind: PendingMessageKind,
666    /// Identifier of the pending message to remove
667    pub id: String,
668}
669
670/// Reorder the queued messages.
671///
672/// The `order` array contains the IDs of queued messages in their new
673/// desired order. IDs not present in the current queue are ignored.
674/// Queued messages whose IDs are absent from `order` are appended at
675/// the end in their original relative order (so a client with a stale
676/// view of the queue never silently drops messages).
677#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
678#[serde(rename_all = "camelCase")]
679pub struct SessionQueuedMessagesReorderedAction {
680    /// Queued message IDs in the desired order
681    pub order: Vec<String>,
682}
683
684/// A session requested input from the user.
685///
686/// Full-request upsert semantics: the `request` replaces any existing request
687/// with the same `id`, or is appended if it is new. Answer drafts are preserved
688/// unless `request.answers` is provided.
689#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
690#[serde(rename_all = "camelCase")]
691pub struct SessionInputRequestedAction {
692    /// Input request to create or replace
693    pub request: SessionInputRequest,
694}
695
696/// A client updated, submitted, skipped, or removed a single in-progress answer.
697///
698/// Dispatching with `answer: undefined` removes that question's answer draft.
699#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
700#[serde(rename_all = "camelCase")]
701pub struct SessionInputAnswerChangedAction {
702    /// Input request identifier
703    pub request_id: String,
704    /// Question identifier within the input request
705    pub question_id: String,
706    /// Updated answer, or `undefined` to clear an answer draft
707    #[serde(default, skip_serializing_if = "Option::is_none")]
708    pub answer: Option<SessionInputAnswer>,
709}
710
711/// A client accepted, declined, or cancelled a session input request.
712///
713/// If accepted, the server uses `answers` (when provided) plus the request's
714/// synced answer state to resume the blocked operation.
715#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
716#[serde(rename_all = "camelCase")]
717pub struct SessionInputCompletedAction {
718    /// Input request identifier
719    pub request_id: String,
720    /// Completion outcome
721    pub response: SessionInputResponseKind,
722    /// Optional final answer replacement, keyed by question ID
723    #[serde(default, skip_serializing_if = "Option::is_none")]
724    pub answers: Option<std::collections::HashMap<String, SessionInputAnswer>>,
725}
726
727/// The session's customizations have changed.
728///
729/// Full-replacement semantics: the `customizations` array replaces the
730/// previous `customizations` entirely.
731#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
732#[serde(rename_all = "camelCase")]
733pub struct SessionCustomizationsChangedAction {
734    /// Updated customization list (full replacement).
735    pub customizations: Vec<Customization>,
736}
737
738/// A client toggled a container customization on or off.
739///
740/// Targets a top-level container (plugin or directory) by `id`. Only
741/// containers have an `enabled` flag; children are always active when
742/// their container is enabled. Is a no-op when no matching container is
743/// found.
744#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
745#[serde(rename_all = "camelCase")]
746pub struct SessionCustomizationToggledAction {
747    /// The id of the container to toggle.
748    pub id: String,
749    /// Whether to enable or disable the container.
750    pub enabled: bool,
751}
752
753/// Upserts a top-level customization (plugin or directory).
754///
755/// The reducer locates the existing entry by `customization.id`:
756///
757/// - If found, the entry is replaced entirely with `customization`,
758///   including its `children` array. To preserve existing children, the
759///   host must include them on the payload.
760/// - If not found, the entry is appended.
761#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
762#[serde(rename_all = "camelCase")]
763pub struct SessionCustomizationUpdatedAction {
764    /// The customization to upsert (matched by `customization.id`).
765    pub customization: Customization,
766}
767
768/// Removes a customization by id.
769///
770/// Searches every container and its children for the entry. If the entry
771/// is a container, its children are removed with it. Is a no-op when no
772/// matching id is found.
773#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
774#[serde(rename_all = "camelCase")]
775pub struct SessionCustomizationRemovedAction {
776    /// The id of the customization to remove.
777    pub id: String,
778}
779
780/// Updates the runtime fields of an existing
781/// {@link McpServerCustomization} — narrow alternative to
782/// {@link SessionCustomizationUpdatedAction} for the high-frequency
783/// `starting` ↔ `ready` ↔ `authRequired` transitions.
784///
785/// Locates the target entry by `id`, searching both the top-level
786/// customization list and the `children` array of every container.
787/// Replaces the entry's {@link McpServerCustomization.state | `state`}
788/// and {@link McpServerCustomization.channel | `channel`}
789/// (full-replacement semantics: omit `channel` to clear an existing
790/// channel URI). Other fields of the customization are preserved.
791///
792/// Is a no-op when no matching `McpServerCustomization` is found. To
793/// update any other field (name, icons, `mcpApp` capabilities, etc.) use
794/// {@link SessionCustomizationUpdatedAction} instead.
795///
796/// When the transition is to {@link McpServerStatus.AuthRequired}
797/// because of a request issued mid-turn, the host SHOULD also raise
798/// {@link SessionStatus.InputNeeded} on the session — see
799/// {@link McpServerAuthRequiredState} for the rationale.
800#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
801#[serde(rename_all = "camelCase")]
802pub struct SessionMcpServerStateChangedAction {
803    /// The id of the {@link McpServerCustomization} to update.
804    pub id: String,
805    /// The new lifecycle state.
806    pub state: McpServerState,
807    /// Updated `mcp://` side-channel URI. Full-replacement: omit to clear
808    /// an existing channel (typical when leaving
809    /// {@link McpServerStatus.Ready | `Ready`}).
810    #[serde(default, skip_serializing_if = "Option::is_none")]
811    pub channel: Option<Uri>,
812}
813
814/// Truncates a session's history. If `turnId` is provided, all turns after that
815/// turn are removed and the specified turn is kept. If `turnId` is omitted, all
816/// turns are removed.
817///
818/// If there is an active turn it is silently dropped and the session status
819/// returns to `idle`.
820///
821/// Common use-case: truncate old data then dispatch a new
822/// `session/turnStarted` with an edited message.
823#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
824#[serde(rename_all = "camelCase")]
825pub struct SessionTruncatedAction {
826    /// Keep turns up to and including this turn. Omit to clear all turns.
827    #[serde(default, skip_serializing_if = "Option::is_none")]
828    pub turn_id: Option<String>,
829}
830
831/// Client changed a mutable config value mid-session.
832///
833/// Only properties with `sessionMutable: true` in the config schema may be
834/// changed. The server validates and broadcasts the action; the reducer merges
835/// the new values into `state.config.values`.
836#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
837#[serde(rename_all = "camelCase")]
838pub struct SessionConfigChangedAction {
839    /// Updated config values
840    pub config: JsonObject,
841    /// When `true`, replaces all config values instead of merging
842    #[serde(default, skip_serializing_if = "Option::is_none")]
843    pub replace: Option<bool>,
844}
845
846/// The session's `_meta` side-channel changed. Replaces `state._meta`
847/// entirely (full-replacement semantics). Producers SHOULD merge any
848/// keys they wish to preserve into the new value before dispatching.
849#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
850#[serde(rename_all = "camelCase")]
851pub struct SessionMetaChangedAction {
852    /// New `_meta` payload, or `undefined` to clear it
853    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
854    pub meta: Option<JsonObject>,
855}
856
857/// Partial content produced while a tool is still executing.
858///
859/// Replaces the `content` array on the running tool call state. Clients can
860/// use this to display live feedback (e.g. a terminal reference) before the
861/// tool completes.
862///
863/// For client-provided tools (where `toolClientId` is set on the tool call state),
864/// the owning client dispatches this action to stream intermediate content while
865/// executing. The server SHOULD reject this action if the dispatching client does
866/// not match `toolClientId`.
867#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
868#[serde(rename_all = "camelCase")]
869pub struct SessionToolCallContentChangedAction {
870    /// Turn identifier
871    pub turn_id: String,
872    /// Tool call identifier
873    pub tool_call_id: String,
874    /// Additional provider-specific metadata for this tool call.
875    ///
876    /// Clients MAY look for well-known keys here to provide enhanced UI.
877    /// For example, a `ptyTerminal` key with `{ input: string; output: string }`
878    /// indicates the tool operated on a terminal (both `input` and `output` may
879    /// contain escape sequences).
880    #[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
881    pub meta: Option<JsonObject>,
882    /// The current partial content for the running tool call
883    pub content: Vec<ToolResultContent>,
884}
885
886/// The {@link ChangesetState.status} for this changeset transitioned (e.g.
887/// `computing → ready`). The error payload is set together with `status`
888/// whenever it transitions to {@link ChangesetStatus.Error | Error}.
889#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
890#[serde(rename_all = "camelCase")]
891pub struct ChangesetStatusChangedAction {
892    /// New computation lifecycle status.
893    pub status: ChangesetStatus,
894    /// Cause when `status === ChangesetStatus.Error`; otherwise omitted.
895    #[serde(default, skip_serializing_if = "Option::is_none")]
896    pub error: Option<ErrorInfo>,
897}
898
899/// Upsert a {@link ChangesetFile} in the changeset — adds a new entry, or
900/// replaces an existing one identified by {@link ChangesetFile.id}.
901#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
902#[serde(rename_all = "camelCase")]
903pub struct ChangesetFileSetAction {
904    /// The new or replacement file entry.
905    pub file: ChangesetFile,
906}
907
908/// Remove a {@link ChangesetFile} from the changeset by its id.
909///
910/// Typically dispatched when a file is reverted, staged out, or otherwise
911/// no longer in scope (e.g. a renamed file is replaced by a new entry).
912#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
913#[serde(rename_all = "camelCase")]
914pub struct ChangesetFileRemovedAction {
915    /// The {@link ChangesetFile.id} of the file to remove.
916    pub file_id: String,
917}
918
919/// The set of operations available on this changeset changed. Full
920/// replacement semantics: `operations` replaces the previous list (or
921/// removes it entirely when `operations` is `undefined`).
922#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
923#[serde(rename_all = "camelCase")]
924pub struct ChangesetOperationsChangedAction {
925    /// Updated operation list. Pass `undefined` to clear all operations.
926    #[serde(default, skip_serializing_if = "Option::is_none")]
927    pub operations: Option<Vec<ChangesetOperation>>,
928}
929
930/// The {@link ChangesetOperation.status} for a single operation transitioned
931/// (e.g. `idle → running → idle`, or `running → error`). The error payload
932/// is set together with `status` whenever it transitions to
933/// {@link ChangesetOperationStatus.Error | Error}, and cleared on any other
934/// transition.
935///
936/// Targets one operation by its {@link ChangesetOperation.id}. If no
937/// operation with that id is currently present in the changeset, the action
938/// is a no-op. Use {@link ChangesetOperationsChangedAction} to add, remove,
939/// or otherwise replace the operation list itself.
940#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
941#[serde(rename_all = "camelCase")]
942pub struct ChangesetOperationStatusChangedAction {
943    /// The {@link ChangesetOperation.id} whose status changed.
944    pub operation_id: String,
945    /// New execution status.
946    pub status: ChangesetOperationStatus,
947    /// Cause when `status === ChangesetOperationStatus.Error`; otherwise omitted.
948    #[serde(default, skip_serializing_if = "Option::is_none")]
949    pub error: Option<ErrorInfo>,
950}
951
952/// Drop every file from the changeset.
953///
954/// Two cases use this:
955/// 1. The underlying source moved (branch switched, fork point invalidated,
956///    …) and the server is recomputing from scratch — subsequent
957///    {@link ChangesetFileSetAction} entries will repopulate it.
958/// 2. The owning session has ended and the URI is becoming
959///    un-subscribable — the server will unsubscribe all clients shortly
960///    after dispatching this action.
961///
962/// Clients SHOULD release any references on receipt and SHOULD NOT
963/// distinguish the two cases from the action alone — instead, react to
964/// the corresponding session-level lifecycle signal (e.g.
965/// `root/sessionRemoved`) for the "going away" case.
966#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
967#[serde(rename_all = "camelCase")]
968pub struct ChangesetClearedAction {}
969
970/// Fired when the list of known terminals changes.
971///
972/// Full-replacement semantics: the `terminals` array replaces the previous
973/// `terminals` entirely.
974#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
975#[serde(rename_all = "camelCase")]
976pub struct RootTerminalsChangedAction {
977    /// Updated terminal list (full replacement)
978    pub terminals: Vec<TerminalInfo>,
979}
980
981/// Terminal output data (pty → client direction).
982///
983/// Appends `data` to the terminal's `content` in the reducer.
984///
985/// `terminal/data` and `terminal/input` are intentionally separate actions
986/// because standard write-ahead reconciliation is not safe for terminal I/O.
987/// A pty is a stateful, mutable process — optimistically applying input or
988/// predicting output would produce incorrect state. Instead, `terminal/input`
989/// is a side-effect-only action (client → server → pty), and `terminal/data`
990/// is server-authoritative output (pty → server → client).
991#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
992#[serde(rename_all = "camelCase")]
993pub struct TerminalDataAction {
994    /// Output data (may contain ANSI escape sequences)
995    pub data: String,
996}
997
998/// Keyboard input sent to the terminal process (client → pty direction).
999///
1000/// This is a side-effect-only action: the server forwards the data to the
1001/// terminal's pty. The reducer treats this as a no-op since `terminal/data`
1002/// actions will reflect any resulting output.
1003///
1004/// See `terminal/data` for why these two actions are kept separate.
1005#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1006#[serde(rename_all = "camelCase")]
1007pub struct TerminalInputAction {
1008    /// Input data to send to the pty
1009    pub data: String,
1010}
1011
1012/// Terminal dimensions changed.
1013///
1014/// Dispatchable by clients to request a resize, or by the server to inform
1015/// clients of the actual terminal dimensions.
1016#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1017#[serde(rename_all = "camelCase")]
1018pub struct TerminalResizedAction {
1019    /// Terminal width in columns
1020    pub cols: i64,
1021    /// Terminal height in rows
1022    pub rows: i64,
1023}
1024
1025/// Terminal claim changed. A client or session transfers ownership of the terminal.
1026///
1027/// The server SHOULD reject if the dispatching client does not currently hold
1028/// the claim.
1029#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1030#[serde(rename_all = "camelCase")]
1031pub struct TerminalClaimedAction {
1032    /// The new claim
1033    pub claim: TerminalClaim,
1034}
1035
1036/// Terminal title changed.
1037///
1038/// Fired by the server when the terminal process updates its title (e.g. via
1039/// escape sequences), or dispatched by a client to rename a terminal.
1040#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1041#[serde(rename_all = "camelCase")]
1042pub struct TerminalTitleChangedAction {
1043    /// New terminal title
1044    pub title: String,
1045}
1046
1047/// Terminal working directory changed.
1048#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1049#[serde(rename_all = "camelCase")]
1050pub struct TerminalCwdChangedAction {
1051    /// New working directory
1052    pub cwd: Uri,
1053}
1054
1055/// Terminal process exited.
1056#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1057#[serde(rename_all = "camelCase")]
1058pub struct TerminalExitedAction {
1059    /// Process exit code. `undefined` if the process was killed without an exit code.
1060    #[serde(default, skip_serializing_if = "Option::is_none")]
1061    pub exit_code: Option<i64>,
1062}
1063
1064/// Terminal scrollback buffer cleared.
1065#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1066#[serde(rename_all = "camelCase")]
1067pub struct TerminalClearedAction {}
1068
1069/// Shell integration has loaded and the terminal now supports command
1070/// detection. The server dispatches this when shell integration becomes
1071/// available (which may happen asynchronously after the terminal is created).
1072///
1073/// Clients MUST NOT assume command detection is available until this action
1074/// (or `terminal/commandExecuted`) has been received.
1075#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1076#[serde(rename_all = "camelCase")]
1077pub struct TerminalCommandDetectionAvailableAction {}
1078
1079/// A command has been submitted to the shell and is now executing.
1080/// All subsequent `terminal/data` actions (until the matching
1081/// `terminal/commandFinished`) constitute this command's output.
1082#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1083#[serde(rename_all = "camelCase")]
1084pub struct TerminalCommandExecutedAction {
1085    /// Stable identifier for this command, scoped to the terminal URI.
1086    /// Allows correlating `commandExecuted` → `commandFinished` pairs.
1087    pub command_id: String,
1088    /// The command line text that was submitted
1089    pub command_line: String,
1090    /// Unix timestamp (ms) of when the command started executing, as measured
1091    /// on the server.
1092    pub timestamp: i64,
1093}
1094
1095/// A command has finished executing.
1096///
1097/// The sequence of `terminal/data` actions between the preceding
1098/// `terminal/commandExecuted` (same `commandId`) and this action constitutes
1099/// the complete output of the command.
1100#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1101#[serde(rename_all = "camelCase")]
1102pub struct TerminalCommandFinishedAction {
1103    /// Matches the `commandId` from the corresponding `commandExecuted`
1104    pub command_id: String,
1105    /// Shell exit code. `undefined` if the shell did not report one.
1106    #[serde(default, skip_serializing_if = "Option::is_none")]
1107    pub exit_code: Option<i64>,
1108    /// Wall-clock duration of the command in milliseconds, as measured by the
1109    /// shell integration script on the server side.
1110    #[serde(default, skip_serializing_if = "Option::is_none")]
1111    pub duration_ms: Option<i64>,
1112}
1113
1114/// A batch of resource changes observed by the watcher.
1115///
1116/// Watch events are coalesced into batches by the server to keep the
1117/// action stream tractable; an empty `changes.items` list MUST NOT be
1118/// dispatched. The reducer does not retain change history — these
1119/// actions exist purely to deliver events to subscribers, who consume
1120/// them directly off the action stream and apply their own logic.
1121#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1122#[serde(rename_all = "camelCase")]
1123pub struct ResourceWatchChangedAction {
1124    /// The set of changes in this batch, wrapped for forward compatibility.
1125    pub changes: AnyValue,
1126}
1127
1128// ─── StateAction Union ───────────────────────────────────────────────
1129
1130/// Discriminated union of every state action.
1131#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1132#[serde(tag = "type")]
1133pub enum StateAction {
1134    #[serde(rename = "root/agentsChanged")]
1135    RootAgentsChanged(RootAgentsChangedAction),
1136    #[serde(rename = "root/activeSessionsChanged")]
1137    RootActiveSessionsChanged(RootActiveSessionsChangedAction),
1138    #[serde(rename = "root/configChanged")]
1139    RootConfigChanged(RootConfigChangedAction),
1140    #[serde(rename = "session/ready")]
1141    SessionReady(SessionReadyAction),
1142    #[serde(rename = "session/creationFailed")]
1143    SessionCreationFailed(SessionCreationFailedAction),
1144    #[serde(rename = "session/turnStarted")]
1145    SessionTurnStarted(SessionTurnStartedAction),
1146    #[serde(rename = "session/delta")]
1147    SessionDelta(SessionDeltaAction),
1148    #[serde(rename = "session/responsePart")]
1149    SessionResponsePart(SessionResponsePartAction),
1150    #[serde(rename = "session/toolCallStart")]
1151    SessionToolCallStart(SessionToolCallStartAction),
1152    #[serde(rename = "session/toolCallDelta")]
1153    SessionToolCallDelta(SessionToolCallDeltaAction),
1154    #[serde(rename = "session/toolCallReady")]
1155    SessionToolCallReady(SessionToolCallReadyAction),
1156    #[serde(rename = "session/toolCallConfirmed")]
1157    SessionToolCallConfirmed(SessionToolCallConfirmedAction),
1158    #[serde(rename = "session/toolCallComplete")]
1159    SessionToolCallComplete(SessionToolCallCompleteAction),
1160    #[serde(rename = "session/toolCallResultConfirmed")]
1161    SessionToolCallResultConfirmed(SessionToolCallResultConfirmedAction),
1162    #[serde(rename = "session/turnComplete")]
1163    SessionTurnComplete(SessionTurnCompleteAction),
1164    #[serde(rename = "session/turnCancelled")]
1165    SessionTurnCancelled(SessionTurnCancelledAction),
1166    #[serde(rename = "session/error")]
1167    SessionError(SessionErrorAction),
1168    #[serde(rename = "session/titleChanged")]
1169    SessionTitleChanged(SessionTitleChangedAction),
1170    #[serde(rename = "session/usage")]
1171    SessionUsage(SessionUsageAction),
1172    #[serde(rename = "session/reasoning")]
1173    SessionReasoning(SessionReasoningAction),
1174    #[serde(rename = "session/modelChanged")]
1175    SessionModelChanged(SessionModelChangedAction),
1176    #[serde(rename = "session/agentChanged")]
1177    SessionAgentChanged(SessionAgentChangedAction),
1178    #[serde(rename = "session/isReadChanged")]
1179    SessionIsReadChanged(SessionIsReadChangedAction),
1180    #[serde(rename = "session/isArchivedChanged")]
1181    SessionIsArchivedChanged(SessionIsArchivedChangedAction),
1182    #[serde(rename = "session/activityChanged")]
1183    SessionActivityChanged(SessionActivityChangedAction),
1184    #[serde(rename = "session/changesetsChanged")]
1185    SessionChangesetsChanged(SessionChangesetsChangedAction),
1186    #[serde(rename = "session/serverToolsChanged")]
1187    SessionServerToolsChanged(SessionServerToolsChangedAction),
1188    #[serde(rename = "session/activeClientChanged")]
1189    SessionActiveClientChanged(SessionActiveClientChangedAction),
1190    #[serde(rename = "session/activeClientToolsChanged")]
1191    SessionActiveClientToolsChanged(SessionActiveClientToolsChangedAction),
1192    #[serde(rename = "session/pendingMessageSet")]
1193    SessionPendingMessageSet(SessionPendingMessageSetAction),
1194    #[serde(rename = "session/pendingMessageRemoved")]
1195    SessionPendingMessageRemoved(SessionPendingMessageRemovedAction),
1196    #[serde(rename = "session/queuedMessagesReordered")]
1197    SessionQueuedMessagesReordered(SessionQueuedMessagesReorderedAction),
1198    #[serde(rename = "session/inputRequested")]
1199    SessionInputRequested(SessionInputRequestedAction),
1200    #[serde(rename = "session/inputAnswerChanged")]
1201    SessionInputAnswerChanged(SessionInputAnswerChangedAction),
1202    #[serde(rename = "session/inputCompleted")]
1203    SessionInputCompleted(SessionInputCompletedAction),
1204    #[serde(rename = "session/customizationsChanged")]
1205    SessionCustomizationsChanged(SessionCustomizationsChangedAction),
1206    #[serde(rename = "session/customizationToggled")]
1207    SessionCustomizationToggled(SessionCustomizationToggledAction),
1208    #[serde(rename = "session/customizationUpdated")]
1209    SessionCustomizationUpdated(Box<SessionCustomizationUpdatedAction>),
1210    #[serde(rename = "session/customizationRemoved")]
1211    SessionCustomizationRemoved(SessionCustomizationRemovedAction),
1212    #[serde(rename = "session/mcpServerStateChanged")]
1213    SessionMcpServerStateChanged(Box<SessionMcpServerStateChangedAction>),
1214    #[serde(rename = "session/truncated")]
1215    SessionTruncated(SessionTruncatedAction),
1216    #[serde(rename = "session/configChanged")]
1217    SessionConfigChanged(SessionConfigChangedAction),
1218    #[serde(rename = "session/metaChanged")]
1219    SessionMetaChanged(SessionMetaChangedAction),
1220    #[serde(rename = "session/toolCallContentChanged")]
1221    SessionToolCallContentChanged(SessionToolCallContentChangedAction),
1222    #[serde(rename = "changeset/statusChanged")]
1223    ChangesetStatusChanged(ChangesetStatusChangedAction),
1224    #[serde(rename = "changeset/fileSet")]
1225    ChangesetFileSet(ChangesetFileSetAction),
1226    #[serde(rename = "changeset/fileRemoved")]
1227    ChangesetFileRemoved(ChangesetFileRemovedAction),
1228    #[serde(rename = "changeset/operationsChanged")]
1229    ChangesetOperationsChanged(ChangesetOperationsChangedAction),
1230    #[serde(rename = "changeset/operationStatusChanged")]
1231    ChangesetOperationStatusChanged(ChangesetOperationStatusChangedAction),
1232    #[serde(rename = "changeset/cleared")]
1233    ChangesetCleared(ChangesetClearedAction),
1234    #[serde(rename = "root/terminalsChanged")]
1235    RootTerminalsChanged(RootTerminalsChangedAction),
1236    #[serde(rename = "terminal/data")]
1237    TerminalData(TerminalDataAction),
1238    #[serde(rename = "terminal/input")]
1239    TerminalInput(TerminalInputAction),
1240    #[serde(rename = "terminal/resized")]
1241    TerminalResized(TerminalResizedAction),
1242    #[serde(rename = "terminal/claimed")]
1243    TerminalClaimed(TerminalClaimedAction),
1244    #[serde(rename = "terminal/titleChanged")]
1245    TerminalTitleChanged(TerminalTitleChangedAction),
1246    #[serde(rename = "terminal/cwdChanged")]
1247    TerminalCwdChanged(TerminalCwdChangedAction),
1248    #[serde(rename = "terminal/exited")]
1249    TerminalExited(TerminalExitedAction),
1250    #[serde(rename = "terminal/cleared")]
1251    TerminalCleared(TerminalClearedAction),
1252    #[serde(rename = "terminal/commandDetectionAvailable")]
1253    TerminalCommandDetectionAvailable(TerminalCommandDetectionAvailableAction),
1254    #[serde(rename = "terminal/commandExecuted")]
1255    TerminalCommandExecuted(TerminalCommandExecutedAction),
1256    #[serde(rename = "terminal/commandFinished")]
1257    TerminalCommandFinished(TerminalCommandFinishedAction),
1258    #[serde(rename = "resourceWatch/changed")]
1259    ResourceWatchChanged(ResourceWatchChangedAction),
1260    /// Unknown or future variant — preserved as raw JSON for round-trip fidelity.
1261    /// Reducers treat this as a no-op.
1262    #[serde(untagged)]
1263    Unknown(serde_json::Value),
1264}