Skip to main content

github_copilot_sdk/generated/
session_events.rs

1//! Auto-generated from session-events.schema.json — do not edit manually.
2
3#![allow(deprecated)]
4
5use std::collections::HashMap;
6
7use serde::{Deserialize, Serialize};
8
9use crate::types::{RequestId, SessionId};
10
11/// Identifies the kind of session event.
12#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub enum SessionEventType {
14    #[serde(rename = "session.start")]
15    SessionStart,
16    #[serde(rename = "session.resume")]
17    SessionResume,
18    #[serde(rename = "session.remote_steerable_changed")]
19    SessionRemoteSteerableChanged,
20    #[serde(rename = "session.error")]
21    SessionError,
22    #[serde(rename = "session.idle")]
23    SessionIdle,
24    #[serde(rename = "session.title_changed")]
25    SessionTitleChanged,
26    #[serde(rename = "session.schedule_created")]
27    SessionScheduleCreated,
28    #[serde(rename = "session.schedule_cancelled")]
29    SessionScheduleCancelled,
30    #[serde(rename = "session.schedule_rearmed")]
31    SessionScheduleRearmed,
32    #[serde(rename = "session.autopilot_objective_changed")]
33    SessionAutopilotObjectiveChanged,
34    #[serde(rename = "session.info")]
35    SessionInfo,
36    #[serde(rename = "session.warning")]
37    SessionWarning,
38    #[serde(rename = "session.model_change")]
39    SessionModelChange,
40    #[serde(rename = "session.mode_changed")]
41    SessionModeChanged,
42    #[serde(rename = "session.session_limits_changed")]
43    SessionSessionLimitsChanged,
44    #[serde(rename = "session.permissions_changed")]
45    SessionPermissionsChanged,
46    #[serde(rename = "session.plan_changed")]
47    SessionPlanChanged,
48    #[serde(rename = "session.todos_changed")]
49    SessionTodosChanged,
50    #[serde(rename = "session.workspace_file_changed")]
51    SessionWorkspaceFileChanged,
52    #[serde(rename = "session.handoff")]
53    SessionHandoff,
54    #[serde(rename = "session.truncation")]
55    SessionTruncation,
56    #[serde(rename = "session.snapshot_rewind")]
57    SessionSnapshotRewind,
58    #[serde(rename = "session.shutdown")]
59    SessionShutdown,
60    #[serde(rename = "session.usage_checkpoint")]
61    SessionUsageCheckpoint,
62    #[serde(rename = "session.context_changed")]
63    SessionContextChanged,
64    #[serde(rename = "session.usage_info")]
65    SessionUsageInfo,
66    #[serde(rename = "session.compaction_start")]
67    SessionCompactionStart,
68    #[serde(rename = "session.compaction_complete")]
69    SessionCompactionComplete,
70    #[serde(rename = "session.task_complete")]
71    SessionTaskComplete,
72    #[serde(rename = "user.message")]
73    UserMessage,
74    #[serde(rename = "pending_messages.modified")]
75    PendingMessagesModified,
76    #[serde(rename = "assistant.turn_start")]
77    AssistantTurnStart,
78    #[serde(rename = "assistant.intent")]
79    AssistantIntent,
80    #[serde(rename = "assistant.reasoning")]
81    AssistantReasoning,
82    #[serde(rename = "assistant.reasoning_delta")]
83    AssistantReasoningDelta,
84    #[serde(rename = "assistant.tool_call_delta")]
85    AssistantToolCallDelta,
86    #[serde(rename = "assistant.streaming_delta")]
87    AssistantStreamingDelta,
88    #[serde(rename = "assistant.message")]
89    AssistantMessage,
90    #[serde(rename = "assistant.message_start")]
91    AssistantMessageStart,
92    #[serde(rename = "assistant.message_delta")]
93    AssistantMessageDelta,
94    #[serde(rename = "assistant.turn_end")]
95    AssistantTurnEnd,
96    #[serde(rename = "assistant.idle")]
97    AssistantIdle,
98    #[serde(rename = "assistant.usage")]
99    AssistantUsage,
100    #[serde(rename = "model.call_failure")]
101    ModelCallFailure,
102    #[serde(rename = "abort")]
103    Abort,
104    #[serde(rename = "tool.user_requested")]
105    ToolUserRequested,
106    #[serde(rename = "tool.execution_start")]
107    ToolExecutionStart,
108    #[serde(rename = "tool.execution_partial_result")]
109    ToolExecutionPartialResult,
110    #[serde(rename = "tool.execution_progress")]
111    ToolExecutionProgress,
112    #[serde(rename = "tool.execution_complete")]
113    ToolExecutionComplete,
114    #[serde(rename = "skill.invoked")]
115    SkillInvoked,
116    #[serde(rename = "subagent.started")]
117    SubagentStarted,
118    #[serde(rename = "subagent.completed")]
119    SubagentCompleted,
120    #[serde(rename = "subagent.failed")]
121    SubagentFailed,
122    #[serde(rename = "subagent.selected")]
123    SubagentSelected,
124    #[serde(rename = "subagent.deselected")]
125    SubagentDeselected,
126    #[serde(rename = "hook.start")]
127    HookStart,
128    #[serde(rename = "hook.end")]
129    HookEnd,
130    #[serde(rename = "hook.progress")]
131    HookProgress,
132    ///
133    /// <div class="warning">
134    ///
135    /// **Experimental.** This type is part of an experimental wire-protocol surface
136    /// and may change or be removed in future SDK or CLI releases.
137    ///
138    /// </div>
139    #[serde(rename = "session.binary_asset")]
140    SessionBinaryAsset,
141    #[serde(rename = "system.message")]
142    SystemMessage,
143    #[serde(rename = "system.notification")]
144    SystemNotification,
145    #[serde(rename = "permission.requested")]
146    PermissionRequested,
147    #[serde(rename = "permission.completed")]
148    PermissionCompleted,
149    #[serde(rename = "user_input.requested")]
150    UserInputRequested,
151    #[serde(rename = "user_input.completed")]
152    UserInputCompleted,
153    #[serde(rename = "elicitation.requested")]
154    ElicitationRequested,
155    #[serde(rename = "elicitation.completed")]
156    ElicitationCompleted,
157    #[serde(rename = "sampling.requested")]
158    SamplingRequested,
159    #[serde(rename = "sampling.completed")]
160    SamplingCompleted,
161    #[serde(rename = "mcp.oauth_required")]
162    McpOauthRequired,
163    #[serde(rename = "mcp.oauth_completed")]
164    McpOauthCompleted,
165    #[serde(rename = "mcp.headers_refresh_required")]
166    McpHeadersRefreshRequired,
167    #[serde(rename = "mcp.headers_refresh_completed")]
168    McpHeadersRefreshCompleted,
169    #[serde(rename = "session.custom_notification")]
170    SessionCustomNotification,
171    #[serde(rename = "external_tool.requested")]
172    ExternalToolRequested,
173    #[serde(rename = "external_tool.completed")]
174    ExternalToolCompleted,
175    #[serde(rename = "command.queued")]
176    CommandQueued,
177    #[serde(rename = "command.execute")]
178    CommandExecute,
179    #[serde(rename = "command.completed")]
180    CommandCompleted,
181    #[serde(rename = "auto_mode_switch.requested")]
182    AutoModeSwitchRequested,
183    #[serde(rename = "auto_mode_switch.completed")]
184    AutoModeSwitchCompleted,
185    #[serde(rename = "session_limits_exhausted.requested")]
186    SessionLimitsExhaustedRequested,
187    #[serde(rename = "session_limits_exhausted.completed")]
188    SessionLimitsExhaustedCompleted,
189    #[serde(rename = "commands.changed")]
190    CommandsChanged,
191    #[serde(rename = "capabilities.changed")]
192    CapabilitiesChanged,
193    #[serde(rename = "exit_plan_mode.requested")]
194    ExitPlanModeRequested,
195    #[serde(rename = "exit_plan_mode.completed")]
196    ExitPlanModeCompleted,
197    #[serde(rename = "session.tools_updated")]
198    SessionToolsUpdated,
199    #[serde(rename = "session.background_tasks_changed")]
200    SessionBackgroundTasksChanged,
201    #[serde(rename = "session.skills_loaded")]
202    SessionSkillsLoaded,
203    #[serde(rename = "session.custom_agents_updated")]
204    SessionCustomAgentsUpdated,
205    #[serde(rename = "session.mcp_servers_loaded")]
206    SessionMcpServersLoaded,
207    #[serde(rename = "session.mcp_server_status_changed")]
208    SessionMcpServerStatusChanged,
209    #[serde(rename = "session.extensions_loaded")]
210    SessionExtensionsLoaded,
211    ///
212    /// <div class="warning">
213    ///
214    /// **Experimental.** This type is part of an experimental wire-protocol surface
215    /// and may change or be removed in future SDK or CLI releases.
216    ///
217    /// </div>
218    #[serde(rename = "session.canvas.opened")]
219    SessionCanvasOpened,
220    ///
221    /// <div class="warning">
222    ///
223    /// **Experimental.** This type is part of an experimental wire-protocol surface
224    /// and may change or be removed in future SDK or CLI releases.
225    ///
226    /// </div>
227    #[serde(rename = "session.canvas.registry_changed")]
228    SessionCanvasRegistryChanged,
229    ///
230    /// <div class="warning">
231    ///
232    /// **Experimental.** This type is part of an experimental wire-protocol surface
233    /// and may change or be removed in future SDK or CLI releases.
234    ///
235    /// </div>
236    #[serde(rename = "session.canvas.closed")]
237    SessionCanvasClosed,
238    ///
239    /// <div class="warning">
240    ///
241    /// **Experimental.** This type is part of an experimental wire-protocol surface
242    /// and may change or be removed in future SDK or CLI releases.
243    ///
244    /// </div>
245    #[serde(rename = "session.canvas.unavailable")]
246    SessionCanvasUnavailable,
247    ///
248    /// <div class="warning">
249    ///
250    /// **Experimental.** This type is part of an experimental wire-protocol surface
251    /// and may change or be removed in future SDK or CLI releases.
252    ///
253    /// </div>
254    #[serde(rename = "session.canvas.recorded")]
255    SessionCanvasRecorded,
256    ///
257    /// <div class="warning">
258    ///
259    /// **Experimental.** This type is part of an experimental wire-protocol surface
260    /// and may change or be removed in future SDK or CLI releases.
261    ///
262    /// </div>
263    #[serde(rename = "session.canvas.removed")]
264    SessionCanvasRemoved,
265    #[serde(rename = "session.extensions.attachments_pushed")]
266    SessionExtensionsAttachmentsPushed,
267    #[serde(rename = "mcp_app.tool_call_complete")]
268    McpAppToolCallComplete,
269    /// Unknown event type for forward compatibility.
270    #[default]
271    #[serde(other)]
272    Unknown,
273}
274
275/// Typed session event data, discriminated by the event `type` field.
276///
277/// Use with [`TypedSessionEvent`] for fully typed event handling.
278#[derive(Debug, Clone, Serialize, Deserialize)]
279#[serde(tag = "type", content = "data")]
280pub enum SessionEventData {
281    #[serde(rename = "session.start")]
282    SessionStart(SessionStartData),
283    #[serde(rename = "session.resume")]
284    SessionResume(SessionResumeData),
285    #[serde(rename = "session.remote_steerable_changed")]
286    SessionRemoteSteerableChanged(SessionRemoteSteerableChangedData),
287    #[serde(rename = "session.error")]
288    SessionError(SessionErrorData),
289    #[serde(rename = "session.idle")]
290    SessionIdle(SessionIdleData),
291    #[serde(rename = "session.title_changed")]
292    SessionTitleChanged(SessionTitleChangedData),
293    #[serde(rename = "session.schedule_created")]
294    SessionScheduleCreated(SessionScheduleCreatedData),
295    #[serde(rename = "session.schedule_cancelled")]
296    SessionScheduleCancelled(SessionScheduleCancelledData),
297    #[serde(rename = "session.schedule_rearmed")]
298    SessionScheduleRearmed(SessionScheduleRearmedData),
299    #[serde(rename = "session.autopilot_objective_changed")]
300    SessionAutopilotObjectiveChanged(SessionAutopilotObjectiveChangedData),
301    #[serde(rename = "session.info")]
302    SessionInfo(SessionInfoData),
303    #[serde(rename = "session.warning")]
304    SessionWarning(SessionWarningData),
305    #[serde(rename = "session.model_change")]
306    SessionModelChange(SessionModelChangeData),
307    #[serde(rename = "session.mode_changed")]
308    SessionModeChanged(SessionModeChangedData),
309    #[serde(rename = "session.session_limits_changed")]
310    SessionSessionLimitsChanged(SessionSessionLimitsChangedData),
311    #[serde(rename = "session.permissions_changed")]
312    SessionPermissionsChanged(SessionPermissionsChangedData),
313    #[serde(rename = "session.plan_changed")]
314    SessionPlanChanged(SessionPlanChangedData),
315    #[serde(rename = "session.todos_changed")]
316    SessionTodosChanged(SessionTodosChangedData),
317    #[serde(rename = "session.workspace_file_changed")]
318    SessionWorkspaceFileChanged(SessionWorkspaceFileChangedData),
319    #[serde(rename = "session.handoff")]
320    SessionHandoff(SessionHandoffData),
321    #[serde(rename = "session.truncation")]
322    SessionTruncation(SessionTruncationData),
323    #[serde(rename = "session.snapshot_rewind")]
324    SessionSnapshotRewind(SessionSnapshotRewindData),
325    #[serde(rename = "session.shutdown")]
326    SessionShutdown(SessionShutdownData),
327    #[serde(rename = "session.usage_checkpoint")]
328    SessionUsageCheckpoint(SessionUsageCheckpointData),
329    #[serde(rename = "session.context_changed")]
330    SessionContextChanged(SessionContextChangedData),
331    #[serde(rename = "session.usage_info")]
332    SessionUsageInfo(SessionUsageInfoData),
333    #[serde(rename = "session.compaction_start")]
334    SessionCompactionStart(SessionCompactionStartData),
335    #[serde(rename = "session.compaction_complete")]
336    SessionCompactionComplete(SessionCompactionCompleteData),
337    #[serde(rename = "session.task_complete")]
338    SessionTaskComplete(SessionTaskCompleteData),
339    #[serde(rename = "user.message")]
340    UserMessage(UserMessageData),
341    #[serde(rename = "pending_messages.modified")]
342    PendingMessagesModified(PendingMessagesModifiedData),
343    #[serde(rename = "assistant.turn_start")]
344    AssistantTurnStart(AssistantTurnStartData),
345    #[serde(rename = "assistant.intent")]
346    AssistantIntent(AssistantIntentData),
347    #[serde(rename = "assistant.reasoning")]
348    AssistantReasoning(AssistantReasoningData),
349    #[serde(rename = "assistant.reasoning_delta")]
350    AssistantReasoningDelta(AssistantReasoningDeltaData),
351    #[serde(rename = "assistant.tool_call_delta")]
352    AssistantToolCallDelta(AssistantToolCallDeltaData),
353    #[serde(rename = "assistant.streaming_delta")]
354    AssistantStreamingDelta(AssistantStreamingDeltaData),
355    #[serde(rename = "assistant.message")]
356    AssistantMessage(AssistantMessageData),
357    #[serde(rename = "assistant.message_start")]
358    AssistantMessageStart(AssistantMessageStartData),
359    #[serde(rename = "assistant.message_delta")]
360    AssistantMessageDelta(AssistantMessageDeltaData),
361    #[serde(rename = "assistant.turn_end")]
362    AssistantTurnEnd(AssistantTurnEndData),
363    #[serde(rename = "assistant.idle")]
364    AssistantIdle(AssistantIdleData),
365    #[serde(rename = "assistant.usage")]
366    AssistantUsage(AssistantUsageData),
367    #[serde(rename = "model.call_failure")]
368    ModelCallFailure(ModelCallFailureData),
369    #[serde(rename = "abort")]
370    Abort(AbortData),
371    #[serde(rename = "tool.user_requested")]
372    ToolUserRequested(ToolUserRequestedData),
373    #[serde(rename = "tool.execution_start")]
374    ToolExecutionStart(ToolExecutionStartData),
375    #[serde(rename = "tool.execution_partial_result")]
376    ToolExecutionPartialResult(ToolExecutionPartialResultData),
377    #[serde(rename = "tool.execution_progress")]
378    ToolExecutionProgress(ToolExecutionProgressData),
379    #[serde(rename = "tool.execution_complete")]
380    ToolExecutionComplete(ToolExecutionCompleteData),
381    #[serde(rename = "skill.invoked")]
382    SkillInvoked(SkillInvokedData),
383    #[serde(rename = "subagent.started")]
384    SubagentStarted(SubagentStartedData),
385    #[serde(rename = "subagent.completed")]
386    SubagentCompleted(SubagentCompletedData),
387    #[serde(rename = "subagent.failed")]
388    SubagentFailed(SubagentFailedData),
389    #[serde(rename = "subagent.selected")]
390    SubagentSelected(SubagentSelectedData),
391    #[serde(rename = "subagent.deselected")]
392    SubagentDeselected(SubagentDeselectedData),
393    #[serde(rename = "hook.start")]
394    HookStart(HookStartData),
395    #[serde(rename = "hook.end")]
396    HookEnd(HookEndData),
397    #[serde(rename = "hook.progress")]
398    HookProgress(HookProgressData),
399    #[serde(rename = "session.binary_asset")]
400    SessionBinaryAsset(SessionBinaryAssetData),
401    #[serde(rename = "system.message")]
402    SystemMessage(SystemMessageData),
403    #[serde(rename = "system.notification")]
404    SystemNotification(SystemNotificationData),
405    #[serde(rename = "permission.requested")]
406    PermissionRequested(PermissionRequestedData),
407    #[serde(rename = "permission.completed")]
408    PermissionCompleted(PermissionCompletedData),
409    #[serde(rename = "user_input.requested")]
410    UserInputRequested(UserInputRequestedData),
411    #[serde(rename = "user_input.completed")]
412    UserInputCompleted(UserInputCompletedData),
413    #[serde(rename = "elicitation.requested")]
414    ElicitationRequested(ElicitationRequestedData),
415    #[serde(rename = "elicitation.completed")]
416    ElicitationCompleted(ElicitationCompletedData),
417    #[serde(rename = "sampling.requested")]
418    SamplingRequested(SamplingRequestedData),
419    #[serde(rename = "sampling.completed")]
420    SamplingCompleted(SamplingCompletedData),
421    #[serde(rename = "mcp.oauth_required")]
422    McpOauthRequired(McpOauthRequiredData),
423    #[serde(rename = "mcp.oauth_completed")]
424    McpOauthCompleted(McpOauthCompletedData),
425    #[serde(rename = "mcp.headers_refresh_required")]
426    McpHeadersRefreshRequired(McpHeadersRefreshRequiredData),
427    #[serde(rename = "mcp.headers_refresh_completed")]
428    McpHeadersRefreshCompleted(McpHeadersRefreshCompletedData),
429    #[serde(rename = "session.custom_notification")]
430    SessionCustomNotification(SessionCustomNotificationData),
431    #[serde(rename = "external_tool.requested")]
432    ExternalToolRequested(ExternalToolRequestedData),
433    #[serde(rename = "external_tool.completed")]
434    ExternalToolCompleted(ExternalToolCompletedData),
435    #[serde(rename = "command.queued")]
436    CommandQueued(CommandQueuedData),
437    #[serde(rename = "command.execute")]
438    CommandExecute(CommandExecuteData),
439    #[serde(rename = "command.completed")]
440    CommandCompleted(CommandCompletedData),
441    #[serde(rename = "auto_mode_switch.requested")]
442    AutoModeSwitchRequested(AutoModeSwitchRequestedData),
443    #[serde(rename = "auto_mode_switch.completed")]
444    AutoModeSwitchCompleted(AutoModeSwitchCompletedData),
445    #[serde(rename = "session_limits_exhausted.requested")]
446    SessionLimitsExhaustedRequested(SessionLimitsExhaustedRequestedData),
447    #[serde(rename = "session_limits_exhausted.completed")]
448    SessionLimitsExhaustedCompleted(SessionLimitsExhaustedCompletedData),
449    #[serde(rename = "commands.changed")]
450    CommandsChanged(CommandsChangedData),
451    #[serde(rename = "capabilities.changed")]
452    CapabilitiesChanged(CapabilitiesChangedData),
453    #[serde(rename = "exit_plan_mode.requested")]
454    ExitPlanModeRequested(ExitPlanModeRequestedData),
455    #[serde(rename = "exit_plan_mode.completed")]
456    ExitPlanModeCompleted(ExitPlanModeCompletedData),
457    #[serde(rename = "session.tools_updated")]
458    SessionToolsUpdated(SessionToolsUpdatedData),
459    #[serde(rename = "session.background_tasks_changed")]
460    SessionBackgroundTasksChanged(SessionBackgroundTasksChangedData),
461    #[serde(rename = "session.skills_loaded")]
462    SessionSkillsLoaded(SessionSkillsLoadedData),
463    #[serde(rename = "session.custom_agents_updated")]
464    SessionCustomAgentsUpdated(SessionCustomAgentsUpdatedData),
465    #[serde(rename = "session.mcp_servers_loaded")]
466    SessionMcpServersLoaded(SessionMcpServersLoadedData),
467    #[serde(rename = "session.mcp_server_status_changed")]
468    SessionMcpServerStatusChanged(SessionMcpServerStatusChangedData),
469    #[serde(rename = "session.extensions_loaded")]
470    SessionExtensionsLoaded(SessionExtensionsLoadedData),
471    ///
472    /// <div class="warning">
473    ///
474    /// **Experimental.** This type is part of an experimental wire-protocol surface
475    /// and may change or be removed in future SDK or CLI releases.
476    ///
477    /// </div>
478    #[serde(rename = "session.canvas.opened")]
479    SessionCanvasOpened(SessionCanvasOpenedData),
480    ///
481    /// <div class="warning">
482    ///
483    /// **Experimental.** This type is part of an experimental wire-protocol surface
484    /// and may change or be removed in future SDK or CLI releases.
485    ///
486    /// </div>
487    #[serde(rename = "session.canvas.registry_changed")]
488    SessionCanvasRegistryChanged(SessionCanvasRegistryChangedData),
489    ///
490    /// <div class="warning">
491    ///
492    /// **Experimental.** This type is part of an experimental wire-protocol surface
493    /// and may change or be removed in future SDK or CLI releases.
494    ///
495    /// </div>
496    #[serde(rename = "session.canvas.closed")]
497    SessionCanvasClosed(SessionCanvasClosedData),
498    ///
499    /// <div class="warning">
500    ///
501    /// **Experimental.** This type is part of an experimental wire-protocol surface
502    /// and may change or be removed in future SDK or CLI releases.
503    ///
504    /// </div>
505    #[serde(rename = "session.canvas.unavailable")]
506    SessionCanvasUnavailable(SessionCanvasUnavailableData),
507    ///
508    /// <div class="warning">
509    ///
510    /// **Experimental.** This type is part of an experimental wire-protocol surface
511    /// and may change or be removed in future SDK or CLI releases.
512    ///
513    /// </div>
514    #[serde(rename = "session.canvas.recorded")]
515    SessionCanvasRecorded(SessionCanvasRecordedData),
516    ///
517    /// <div class="warning">
518    ///
519    /// **Experimental.** This type is part of an experimental wire-protocol surface
520    /// and may change or be removed in future SDK or CLI releases.
521    ///
522    /// </div>
523    #[serde(rename = "session.canvas.removed")]
524    SessionCanvasRemoved(SessionCanvasRemovedData),
525    #[serde(rename = "session.extensions.attachments_pushed")]
526    SessionExtensionsAttachmentsPushed(SessionExtensionsAttachmentsPushedData),
527    #[serde(rename = "mcp_app.tool_call_complete")]
528    McpAppToolCallComplete(McpAppToolCallCompleteData),
529}
530
531/// A session event with typed data payload.
532///
533/// The common event fields (id, timestamp, parentId, ephemeral, agentId)
534/// are available directly. The event-specific data is in the `payload`
535/// field as a [`SessionEventData`] enum.
536#[derive(Debug, Clone, Serialize, Deserialize)]
537#[serde(rename_all = "camelCase")]
538pub struct TypedSessionEvent {
539    /// Unique event identifier (UUID v4).
540    pub id: String,
541    /// ISO 8601 timestamp when the event was created.
542    pub timestamp: String,
543    /// ID of the preceding event in the chain.
544    #[serde(skip_serializing_if = "Option::is_none")]
545    pub parent_id: Option<String>,
546    /// When true, the event is transient and not persisted.
547    #[serde(skip_serializing_if = "Option::is_none")]
548    pub ephemeral: Option<bool>,
549    /// Sub-agent instance identifier. Absent for events from the root /
550    /// main agent and session-level events.
551    #[serde(skip_serializing_if = "Option::is_none")]
552    pub agent_id: Option<String>,
553    /// The typed event payload (discriminated by event type).
554    #[serde(flatten)]
555    pub payload: SessionEventData,
556}
557
558/// Working directory and git context at session start
559#[derive(Debug, Clone, Default, Serialize, Deserialize)]
560#[serde(rename_all = "camelCase")]
561pub struct WorkingDirectoryContext {
562    /// Base commit of current git branch at session start time
563    #[serde(skip_serializing_if = "Option::is_none")]
564    pub base_commit: Option<String>,
565    /// Current git branch name
566    #[serde(skip_serializing_if = "Option::is_none")]
567    pub branch: Option<String>,
568    /// Current working directory path
569    pub cwd: String,
570    /// Root directory of the git repository, resolved via git rev-parse
571    #[serde(skip_serializing_if = "Option::is_none")]
572    pub git_root: Option<String>,
573    /// Head commit of current git branch at session start time
574    #[serde(skip_serializing_if = "Option::is_none")]
575    pub head_commit: Option<String>,
576    /// Hosting platform type of the repository (github or ado)
577    #[serde(skip_serializing_if = "Option::is_none")]
578    pub host_type: Option<WorkingDirectoryContextHostType>,
579    /// Repository identifier derived from the git remote URL ("owner/name" for GitHub, "org/project/repo" for Azure DevOps)
580    #[serde(skip_serializing_if = "Option::is_none")]
581    pub repository: Option<String>,
582    /// Raw host string from the git remote URL (e.g. "github.com", "mycompany.ghe.com", "dev.azure.com")
583    #[serde(skip_serializing_if = "Option::is_none")]
584    pub repository_host: Option<String>,
585}
586
587/// Optional session limits.
588#[derive(Debug, Clone, Default, Serialize, Deserialize)]
589#[serde(rename_all = "camelCase")]
590pub struct SessionLimitsConfig {
591    /// Maximum AI Credits allowed across the session's current accounting window.
592    #[serde(skip_serializing_if = "Option::is_none")]
593    pub max_ai_credits: Option<f64>,
594}
595
596/// Session event "session.start". Session initialization metadata including context and configuration
597#[derive(Debug, Clone, Default, Serialize, Deserialize)]
598#[serde(rename_all = "camelCase")]
599pub struct SessionStartData {
600    /// Whether the session was already in use by another client at start time
601    #[serde(skip_serializing_if = "Option::is_none")]
602    pub already_in_use: Option<bool>,
603    /// Working directory and git context at session start
604    #[serde(skip_serializing_if = "Option::is_none")]
605    pub context: Option<WorkingDirectoryContext>,
606    /// Context tier selected at session creation time for models with tiered context pricing; null when no tier is selected (e.g., non-tiered model)
607    #[serde(skip_serializing_if = "Option::is_none")]
608    pub context_tier: Option<ContextTier>,
609    /// Version string of the Copilot application
610    pub copilot_version: String,
611    /// When set, identifies a parent session whose context this session continues — e.g., a detached headless rem-agent run launched on the parent's interactive shutdown. Telemetry from this session is reported under the parent's session_id.
612    #[serde(skip_serializing_if = "Option::is_none")]
613    pub detached_from_spawning_parent_session_id: Option<String>,
614    /// Identifier of the software producing the events (e.g., "copilot-agent")
615    pub producer: String,
616    /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
617    #[serde(skip_serializing_if = "Option::is_none")]
618    pub reasoning_effort: Option<String>,
619    /// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
620    #[serde(skip_serializing_if = "Option::is_none")]
621    pub reasoning_summary: Option<ReasoningSummary>,
622    /// Whether this session supports remote steering via GitHub
623    #[serde(skip_serializing_if = "Option::is_none")]
624    pub remote_steerable: Option<bool>,
625    /// Model selected at session creation time, if any
626    #[serde(skip_serializing_if = "Option::is_none")]
627    pub selected_model: Option<String>,
628    /// Unique identifier for the session
629    pub session_id: SessionId,
630    /// Session limits configured at session creation time, if any
631    #[serde(skip_serializing_if = "Option::is_none")]
632    pub session_limits: Option<SessionLimitsConfig>,
633    /// ISO 8601 timestamp when the session was created
634    pub start_time: String,
635    /// Output verbosity level used for model calls, if applicable (e.g. "low", "medium", "high")
636    #[serde(skip_serializing_if = "Option::is_none")]
637    pub verbosity: Option<Verbosity>,
638    /// Schema version number for the session event format
639    pub version: i64,
640}
641
642/// Session event "session.resume". Session resume metadata including current context and event count
643#[derive(Debug, Clone, Default, Serialize, Deserialize)]
644#[serde(rename_all = "camelCase")]
645pub struct SessionResumeData {
646    /// Whether the session was already in use by another client at resume time
647    #[serde(skip_serializing_if = "Option::is_none")]
648    pub already_in_use: Option<bool>,
649    /// Updated working directory and git context at resume time
650    #[serde(skip_serializing_if = "Option::is_none")]
651    pub context: Option<WorkingDirectoryContext>,
652    /// Context tier currently selected at resume time; null when no tier is active
653    #[serde(skip_serializing_if = "Option::is_none")]
654    pub context_tier: Option<ContextTier>,
655    /// When true, tool calls and permission requests left in flight by the previous session lifetime remain pending after resume and the agentic loop awaits their results. User sends are queued behind the pending work until all such requests reach a terminal state. When false (the default), any such tool calls and permission requests are immediately marked as interrupted on resume.
656    #[serde(skip_serializing_if = "Option::is_none")]
657    pub continue_pending_work: Option<bool>,
658    /// Total number of persisted events in the session at the time of resume
659    pub event_count: i64,
660    /// On-disk byte size of the session's persisted events.jsonl file at resume time; omitted when the file does not exist or cannot be stat'd
661    #[serde(skip_serializing_if = "Option::is_none")]
662    pub events_file_size_bytes: Option<i64>,
663    /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
664    #[serde(skip_serializing_if = "Option::is_none")]
665    pub reasoning_effort: Option<String>,
666    /// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
667    #[serde(skip_serializing_if = "Option::is_none")]
668    pub reasoning_summary: Option<ReasoningSummary>,
669    /// Whether this session supports remote steering via GitHub
670    #[serde(skip_serializing_if = "Option::is_none")]
671    pub remote_steerable: Option<bool>,
672    /// ISO 8601 timestamp when the session was resumed
673    pub resume_time: String,
674    /// Model currently selected at resume time
675    #[serde(skip_serializing_if = "Option::is_none")]
676    pub selected_model: Option<String>,
677    /// Session limits currently configured at resume time; null when no limits are active
678    #[serde(skip_serializing_if = "Option::is_none")]
679    pub session_limits: Option<SessionLimitsConfig>,
680    /// True when this resume attached to a session that the runtime already had running in-memory (for example, an extension joining a session another client was actively driving). False (or omitted) for cold resumes — the runtime had to reconstitute the session from its persisted event log.
681    #[serde(skip_serializing_if = "Option::is_none")]
682    pub session_was_active: Option<bool>,
683    /// Output verbosity level used for model calls, if applicable (e.g. "low", "medium", "high")
684    #[serde(skip_serializing_if = "Option::is_none")]
685    pub verbosity: Option<Verbosity>,
686}
687
688/// Session event "session.remote_steerable_changed". Notifies that the session's remote steering capability has changed
689#[derive(Debug, Clone, Default, Serialize, Deserialize)]
690#[serde(rename_all = "camelCase")]
691pub struct SessionRemoteSteerableChangedData {
692    /// Whether this session now supports remote steering via GitHub
693    pub remote_steerable: bool,
694}
695
696/// Session event "session.error". Error details for timeline display including message and optional diagnostic information
697#[derive(Debug, Clone, Default, Serialize, Deserialize)]
698#[serde(rename_all = "camelCase")]
699pub struct SessionErrorData {
700    /// Only set on `errorType: "rate_limit"`. When `true`, the runtime will follow this error with an `auto_mode_switch.requested` event (or silently switch if `continueOnAutoMode` is enabled). UI clients can use this flag to suppress duplicate rendering of the rate-limit error when they show their own auto-mode-switch prompt.
701    #[serde(skip_serializing_if = "Option::is_none")]
702    pub eligible_for_auto_switch: Option<bool>,
703    /// Fine-grained error code from the upstream provider, when available. For `errorType: "rate_limit"`, this is one of the `RateLimitErrorCode` values (e.g., `"user_weekly_rate_limited"`, `"user_global_rate_limited"`, `"rate_limited"`, `"user_model_rate_limited"`, `"integration_rate_limited"`). For `errorType: "quota"`, this is the CAPI quota error code (e.g., `"quota_exceeded"`, `"session_quota_exceeded"`, `"billing_not_configured"`).
704    #[serde(skip_serializing_if = "Option::is_none")]
705    pub error_code: Option<String>,
706    /// Category of error (e.g., "authentication", "authorization", "quota", "rate_limit", "context_limit", "query")
707    pub error_type: String,
708    /// Human-readable error message
709    pub message: String,
710    /// GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
711    #[serde(skip_serializing_if = "Option::is_none")]
712    pub provider_call_id: Option<String>,
713    /// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation
714    #[serde(skip_serializing_if = "Option::is_none")]
715    pub service_request_id: Option<String>,
716    /// Error stack trace, when available
717    #[serde(skip_serializing_if = "Option::is_none")]
718    pub stack: Option<String>,
719    /// HTTP status code from the upstream request, if applicable
720    #[serde(skip_serializing_if = "Option::is_none")]
721    pub status_code: Option<i32>,
722    /// Optional URL associated with this error that the user can open in a browser
723    #[serde(skip_serializing_if = "Option::is_none")]
724    pub url: Option<String>,
725}
726
727/// Session event "session.idle". Payload indicating the session is idle with no background agents or attached shell commands in flight
728#[derive(Debug, Clone, Default, Serialize, Deserialize)]
729#[serde(rename_all = "camelCase")]
730pub struct SessionIdleData {
731    /// True when the preceding agentic loop was cancelled via abort signal
732    #[serde(skip_serializing_if = "Option::is_none")]
733    pub aborted: Option<bool>,
734}
735
736/// Session event "session.title_changed". Session title change payload containing the new display title
737#[derive(Debug, Clone, Default, Serialize, Deserialize)]
738#[serde(rename_all = "camelCase")]
739pub struct SessionTitleChangedData {
740    /// The new display title for the session
741    pub title: String,
742}
743
744/// Session event "session.schedule_created". Scheduled prompt registered via /every or /after
745#[derive(Debug, Clone, Default, Serialize, Deserialize)]
746#[serde(rename_all = "camelCase")]
747pub struct SessionScheduleCreatedData {
748    /// Absolute fire time (epoch milliseconds) for a one-shot calendar schedule
749    #[serde(skip_serializing_if = "Option::is_none")]
750    pub at: Option<i64>,
751    /// 5-field cron expression for a recurring calendar schedule, evaluated in `tz`
752    #[serde(skip_serializing_if = "Option::is_none")]
753    pub cron: Option<String>,
754    /// Optional user-facing label shown in the timeline instead of the actual prompt (e.g. `/skill-name args` when the prompt is a skill invocation expansion)
755    #[serde(skip_serializing_if = "Option::is_none")]
756    pub display_prompt: Option<String>,
757    /// Sequential id assigned to the scheduled prompt within the session
758    pub id: i64,
759    /// Interval between ticks in milliseconds (relative-interval schedules)
760    #[serde(skip_serializing_if = "Option::is_none")]
761    pub interval_ms: Option<i64>,
762    /// Prompt text that gets enqueued on every tick
763    pub prompt: String,
764    /// Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`)
765    #[serde(skip_serializing_if = "Option::is_none")]
766    pub recurring: Option<bool>,
767    /// True for a self-paced (`dynamic`) schedule: no fixed cadence; the model arms each next run via the `manage_schedule` `wakeup` action. `nextRunAt` is model-controlled rather than auto-computed.
768    #[serde(skip_serializing_if = "Option::is_none")]
769    pub self_paced: Option<bool>,
770    /// IANA timezone the `cron` expression is evaluated in
771    #[serde(skip_serializing_if = "Option::is_none")]
772    pub tz: Option<String>,
773}
774
775/// Session event "session.schedule_cancelled". Scheduled prompt cancelled from the schedule manager dialog
776#[derive(Debug, Clone, Default, Serialize, Deserialize)]
777#[serde(rename_all = "camelCase")]
778pub struct SessionScheduleCancelledData {
779    /// Id of the scheduled prompt that was cancelled
780    pub id: i64,
781}
782
783/// Session event "session.schedule_rearmed". Self-paced schedule re-armed for its next run
784#[derive(Debug, Clone, Default, Serialize, Deserialize)]
785#[serde(rename_all = "camelCase")]
786pub struct SessionScheduleRearmedData {
787    /// Id of the self-paced schedule that was re-armed
788    pub id: i64,
789    /// Absolute time (epoch milliseconds) the model armed the next run to fire
790    pub next_run_at: i64,
791}
792
793/// Session event "session.autopilot_objective_changed". Autopilot objective state file operation details indicating what changed
794#[derive(Debug, Clone, Default, Serialize, Deserialize)]
795#[serde(rename_all = "camelCase")]
796pub struct SessionAutopilotObjectiveChangedData {
797    /// Current autopilot objective id, if one exists
798    #[serde(skip_serializing_if = "Option::is_none")]
799    pub id: Option<i64>,
800    /// The type of operation performed on the autopilot objective state file
801    pub operation: AutopilotObjectiveChangedOperation,
802    /// Current autopilot objective status, if one exists
803    #[serde(skip_serializing_if = "Option::is_none")]
804    pub status: Option<AutopilotObjectiveChangedStatus>,
805}
806
807/// Session event "session.info". Informational message for timeline display with categorization
808#[derive(Debug, Clone, Default, Serialize, Deserialize)]
809#[serde(rename_all = "camelCase")]
810pub struct SessionInfoData {
811    /// Category of informational message (e.g., "notification", "timing", "context_window", "mcp", "snapshot", "configuration", "authentication", "model")
812    pub info_type: String,
813    /// Human-readable informational message for display in the timeline
814    pub message: String,
815    /// Optional actionable tip displayed with this message
816    #[serde(skip_serializing_if = "Option::is_none")]
817    pub tip: Option<String>,
818    /// Optional URL associated with this message that the user can open in a browser
819    #[serde(skip_serializing_if = "Option::is_none")]
820    pub url: Option<String>,
821}
822
823/// Session event "session.warning". Warning message for timeline display with categorization
824#[derive(Debug, Clone, Default, Serialize, Deserialize)]
825#[serde(rename_all = "camelCase")]
826pub struct SessionWarningData {
827    /// Human-readable warning message for display in the timeline
828    pub message: String,
829    /// Optional URL associated with this warning that the user can open in a browser
830    #[serde(skip_serializing_if = "Option::is_none")]
831    pub url: Option<String>,
832    /// Category of warning (e.g., "subscription", "policy", "mcp")
833    pub warning_type: String,
834}
835
836/// Session event "session.model_change". Model change details including previous and new model identifiers
837#[derive(Debug, Clone, Default, Serialize, Deserialize)]
838#[serde(rename_all = "camelCase")]
839pub struct SessionModelChangeData {
840    /// Reason the change happened, when not user-initiated. Currently `"rate_limit_auto_switch"` for changes triggered by the auto-mode-switch rate-limit recovery path. UI clients can use this to render contextual copy.
841    #[serde(skip_serializing_if = "Option::is_none")]
842    pub cause: Option<String>,
843    /// Context tier after the model change; null explicitly clears a previously selected tier
844    #[serde(skip_serializing_if = "Option::is_none")]
845    pub context_tier: Option<ContextTier>,
846    /// Newly selected model identifier
847    pub new_model: String,
848    /// Model that was previously selected, if any
849    #[serde(skip_serializing_if = "Option::is_none")]
850    pub previous_model: Option<String>,
851    /// Reasoning effort level before the model change, if applicable
852    #[serde(skip_serializing_if = "Option::is_none")]
853    pub previous_reasoning_effort: Option<String>,
854    /// Reasoning summary mode before the model change, if applicable
855    #[serde(skip_serializing_if = "Option::is_none")]
856    pub previous_reasoning_summary: Option<ReasoningSummary>,
857    /// Output verbosity level before the model change, if applicable
858    #[serde(skip_serializing_if = "Option::is_none")]
859    pub previous_verbosity: Option<Verbosity>,
860    /// Reasoning effort level after the model change, if applicable
861    #[serde(skip_serializing_if = "Option::is_none")]
862    pub reasoning_effort: Option<String>,
863    /// Reasoning summary mode after the model change, if applicable
864    #[serde(skip_serializing_if = "Option::is_none")]
865    pub reasoning_summary: Option<ReasoningSummary>,
866    /// Output verbosity level after the model change, if applicable
867    #[serde(skip_serializing_if = "Option::is_none")]
868    pub verbosity: Option<Verbosity>,
869}
870
871/// Session event "session.mode_changed". Agent mode change details including previous and new modes
872#[derive(Debug, Clone, Default, Serialize, Deserialize)]
873#[serde(rename_all = "camelCase")]
874pub struct SessionModeChangedData {
875    /// The session mode the agent is operating in
876    pub new_mode: SessionMode,
877    /// The session mode the agent is operating in
878    pub previous_mode: SessionMode,
879}
880
881/// Session event "session.session_limits_changed". Session limits update details. Null clears the limits.
882#[derive(Debug, Clone, Default, Serialize, Deserialize)]
883#[serde(rename_all = "camelCase")]
884pub struct SessionSessionLimitsChangedData {
885    /// Current session limits, or null when no limits are active
886    pub session_limits: Option<SessionLimitsConfig>,
887}
888
889/// Session event "session.permissions_changed". Permissions change details carrying the aggregate allow-all transition.
890#[derive(Debug, Clone, Default, Serialize, Deserialize)]
891#[serde(rename_all = "camelCase")]
892pub struct SessionPermissionsChangedData {
893    /// Allow-all mode after the change
894    ///
895    /// <div class="warning">
896    ///
897    /// **Experimental.** This type is part of an experimental wire-protocol surface
898    /// and may change or be removed in future SDK or CLI releases.
899    ///
900    /// </div>
901    #[serde(skip_serializing_if = "Option::is_none")]
902    pub allow_all_permission_mode: Option<PermissionAllowAllMode>,
903    /// Aggregate allow-all flag after the change
904    pub allow_all_permissions: bool,
905    /// Allow-all mode before the change
906    ///
907    /// <div class="warning">
908    ///
909    /// **Experimental.** This type is part of an experimental wire-protocol surface
910    /// and may change or be removed in future SDK or CLI releases.
911    ///
912    /// </div>
913    #[serde(skip_serializing_if = "Option::is_none")]
914    pub previous_allow_all_permission_mode: Option<PermissionAllowAllMode>,
915    /// Aggregate allow-all flag before the change
916    pub previous_allow_all_permissions: bool,
917}
918
919/// Session event "session.plan_changed". Plan file operation details indicating what changed
920#[derive(Debug, Clone, Default, Serialize, Deserialize)]
921#[serde(rename_all = "camelCase")]
922pub struct SessionPlanChangedData {
923    /// The type of operation performed on the plan file
924    pub operation: PlanChangedOperation,
925}
926
927/// Session event "session.todos_changed". Signal-only event: the agent's todos or todo_deps table was written to. No payload — clients should call session.plan.readSqlTodosWithDependencies() to fetch the current state. Events arrive in order; clients can debounce on arrival if needed.
928#[derive(Debug, Clone, Default, Serialize, Deserialize)]
929#[serde(rename_all = "camelCase")]
930pub struct SessionTodosChangedData {}
931
932/// Session event "session.workspace_file_changed". Workspace file change details including path and operation type
933#[derive(Debug, Clone, Default, Serialize, Deserialize)]
934#[serde(rename_all = "camelCase")]
935pub struct SessionWorkspaceFileChangedData {
936    /// Whether the file was newly created or updated
937    pub operation: WorkspaceFileChangedOperation,
938    /// Relative path within the session workspace files directory
939    pub path: String,
940}
941
942/// Repository context for the handed-off session
943#[derive(Debug, Clone, Default, Serialize, Deserialize)]
944#[serde(rename_all = "camelCase")]
945pub struct HandoffRepository {
946    /// Git branch name, if applicable
947    #[serde(skip_serializing_if = "Option::is_none")]
948    pub branch: Option<String>,
949    /// Repository name
950    pub name: String,
951    /// Repository owner (user or organization)
952    pub owner: String,
953}
954
955/// Session event "session.handoff". Session handoff metadata including source, context, and repository information
956#[derive(Debug, Clone, Default, Serialize, Deserialize)]
957#[serde(rename_all = "camelCase")]
958pub struct SessionHandoffData {
959    /// Additional context information for the handoff
960    #[serde(skip_serializing_if = "Option::is_none")]
961    pub context: Option<String>,
962    /// ISO 8601 timestamp when the handoff occurred
963    pub handoff_time: String,
964    /// GitHub host URL for the source session (e.g., https://github.com or https://tenant.ghe.com)
965    #[serde(skip_serializing_if = "Option::is_none")]
966    pub host: Option<String>,
967    /// Session ID of the remote session being handed off
968    #[serde(skip_serializing_if = "Option::is_none")]
969    pub remote_session_id: Option<SessionId>,
970    /// Repository context for the handed-off session
971    #[serde(skip_serializing_if = "Option::is_none")]
972    pub repository: Option<HandoffRepository>,
973    /// Origin type of the session being handed off
974    pub source_type: HandoffSourceType,
975    /// Summary of the work done in the source session
976    #[serde(skip_serializing_if = "Option::is_none")]
977    pub summary: Option<String>,
978}
979
980/// Session event "session.truncation". Conversation truncation statistics including token counts and removed content metrics
981#[derive(Debug, Clone, Default, Serialize, Deserialize)]
982#[serde(rename_all = "camelCase")]
983pub struct SessionTruncationData {
984    /// Number of messages removed by truncation
985    pub messages_removed_during_truncation: i64,
986    /// Identifier of the component that performed truncation (e.g., "BasicTruncator")
987    pub performed_by: String,
988    /// Number of conversation messages after truncation
989    pub post_truncation_messages_length: i64,
990    /// Total tokens in conversation messages after truncation
991    pub post_truncation_tokens_in_messages: i64,
992    /// Number of conversation messages before truncation
993    pub pre_truncation_messages_length: i64,
994    /// Total tokens in conversation messages before truncation
995    pub pre_truncation_tokens_in_messages: i64,
996    /// Maximum token count for the model's context window
997    pub token_limit: i64,
998    /// Number of tokens removed by truncation
999    pub tokens_removed_during_truncation: i64,
1000}
1001
1002/// Session event "session.snapshot_rewind". Session rewind details including target event and count of removed events
1003#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1004#[serde(rename_all = "camelCase")]
1005pub struct SessionSnapshotRewindData {
1006    /// Number of events that were removed by the rewind
1007    pub events_removed: i64,
1008    /// Event ID that was rewound to; this event and all after it were removed
1009    pub up_to_event_id: String,
1010}
1011
1012/// Aggregate code change metrics for the session
1013#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1014#[serde(rename_all = "camelCase")]
1015pub struct ShutdownCodeChanges {
1016    /// List of file paths that were modified during the session
1017    pub files_modified: Vec<String>,
1018    /// Total number of lines added during the session
1019    pub lines_added: i64,
1020    /// Total number of lines removed during the session
1021    pub lines_removed: i64,
1022}
1023
1024/// Request count and cost metrics
1025#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1026#[serde(rename_all = "camelCase")]
1027pub struct ShutdownModelMetricRequests {
1028    /// Cumulative cost multiplier for requests to this model
1029    ///
1030    /// <div class="warning">
1031    ///
1032    /// **Experimental.** This type is part of an experimental wire-protocol surface
1033    /// and may change or be removed in future SDK or CLI releases.
1034    ///
1035    /// </div>
1036    #[serde(skip_serializing_if = "Option::is_none")]
1037    pub cost: Option<f64>,
1038    /// Total number of API requests made to this model
1039    ///
1040    /// <div class="warning">
1041    ///
1042    /// **Experimental.** This type is part of an experimental wire-protocol surface
1043    /// and may change or be removed in future SDK or CLI releases.
1044    ///
1045    /// </div>
1046    #[serde(skip_serializing_if = "Option::is_none")]
1047    pub count: Option<i64>,
1048}
1049
1050/// A token-type entry in a shutdown model metric, storing the accumulated token count.
1051#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1052#[serde(rename_all = "camelCase")]
1053pub struct ShutdownModelMetricTokenDetail {
1054    /// Accumulated token count for this token type
1055    pub token_count: i64,
1056}
1057
1058/// Token usage breakdown
1059#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1060#[serde(rename_all = "camelCase")]
1061pub struct ShutdownModelMetricUsage {
1062    /// Total tokens read from prompt cache across all requests
1063    pub cache_read_tokens: i64,
1064    /// Total tokens written to prompt cache across all requests
1065    pub cache_write_tokens: i64,
1066    /// Total input tokens consumed across all requests to this model
1067    pub input_tokens: i64,
1068    /// Total output tokens produced across all requests to this model
1069    pub output_tokens: i64,
1070    /// Total reasoning tokens produced across all requests to this model
1071    #[serde(skip_serializing_if = "Option::is_none")]
1072    pub reasoning_tokens: Option<i64>,
1073}
1074
1075/// Per-model shutdown metrics with request counts, token usage, nano-AI units, and token details.
1076#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1077#[serde(rename_all = "camelCase")]
1078pub struct ShutdownModelMetric {
1079    /// Request count and cost metrics
1080    pub requests: ShutdownModelMetricRequests,
1081    /// Token count details per type
1082    #[serde(skip_serializing_if = "Option::is_none")]
1083    pub token_details: Option<HashMap<String, ShutdownModelMetricTokenDetail>>,
1084    /// Accumulated nano-AI units cost for this model
1085    ///
1086    /// <div class="warning">
1087    ///
1088    /// **Experimental.** This type is part of an experimental wire-protocol surface
1089    /// and may change or be removed in future SDK or CLI releases.
1090    ///
1091    /// </div>
1092    #[serde(skip_serializing_if = "Option::is_none")]
1093    pub total_nano_aiu: Option<f64>,
1094    /// Token usage breakdown
1095    pub usage: ShutdownModelMetricUsage,
1096}
1097
1098/// A session-wide shutdown token-type entry storing the accumulated token count.
1099#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1100#[serde(rename_all = "camelCase")]
1101pub struct ShutdownTokenDetail {
1102    /// Accumulated token count for this token type
1103    pub token_count: i64,
1104}
1105
1106/// Session event "session.shutdown". Session termination metrics including usage statistics, code changes, and shutdown reason
1107#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1108#[serde(rename_all = "camelCase")]
1109pub struct SessionShutdownData {
1110    /// Aggregate code change metrics for the session
1111    pub code_changes: ShutdownCodeChanges,
1112    /// Non-system message token count at shutdown
1113    #[serde(skip_serializing_if = "Option::is_none")]
1114    pub conversation_tokens: Option<i64>,
1115    /// Model that was selected at the time of shutdown
1116    #[serde(skip_serializing_if = "Option::is_none")]
1117    pub current_model: Option<String>,
1118    /// Total tokens in context window at shutdown
1119    #[serde(skip_serializing_if = "Option::is_none")]
1120    pub current_tokens: Option<i64>,
1121    /// Error description when shutdownType is "error"
1122    #[serde(skip_serializing_if = "Option::is_none")]
1123    pub error_reason: Option<String>,
1124    /// On-disk byte size of the session's persisted events.jsonl file at shutdown time; omitted when the file does not exist or cannot be stat'd
1125    #[serde(skip_serializing_if = "Option::is_none")]
1126    pub events_file_size_bytes: Option<i64>,
1127    /// Per-model usage breakdown, keyed by model identifier
1128    pub model_metrics: HashMap<String, ShutdownModelMetric>,
1129    /// Unix timestamp (milliseconds) when the session started
1130    pub session_start_time: i64,
1131    /// Whether the session ended normally ("routine") or due to a crash/fatal error ("error")
1132    pub shutdown_type: ShutdownType,
1133    /// System message token count at shutdown
1134    #[serde(skip_serializing_if = "Option::is_none")]
1135    pub system_tokens: Option<i64>,
1136    /// Session-wide per-token-type accumulated token counts
1137    #[serde(skip_serializing_if = "Option::is_none")]
1138    pub token_details: Option<HashMap<String, ShutdownTokenDetail>>,
1139    /// Tool definitions token count at shutdown
1140    #[serde(skip_serializing_if = "Option::is_none")]
1141    pub tool_definitions_tokens: Option<i64>,
1142    /// Cumulative time spent in API calls during the session, in milliseconds
1143    pub total_api_duration_ms: i64,
1144    /// Session-wide accumulated nano-AI units cost
1145    ///
1146    /// <div class="warning">
1147    ///
1148    /// **Experimental.** This type is part of an experimental wire-protocol surface
1149    /// and may change or be removed in future SDK or CLI releases.
1150    ///
1151    /// </div>
1152    #[serde(skip_serializing_if = "Option::is_none")]
1153    pub total_nano_aiu: Option<f64>,
1154    /// Total number of premium API requests used during the session
1155    #[doc(hidden)]
1156    #[serde(skip_serializing_if = "Option::is_none")]
1157    pub(crate) total_premium_requests: Option<f64>,
1158}
1159
1160/// Session event "session.usage_checkpoint". Durable session usage checkpoint for reconstructing aggregate accounting on resume
1161#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1162#[serde(rename_all = "camelCase")]
1163pub struct SessionUsageCheckpointData {
1164    /// Session-wide accumulated nano-AI units cost at checkpoint time
1165    pub total_nano_aiu: f64,
1166    /// Total number of premium API requests used at checkpoint time
1167    #[doc(hidden)]
1168    #[serde(skip_serializing_if = "Option::is_none")]
1169    pub(crate) total_premium_requests: Option<f64>,
1170}
1171
1172/// Session event "session.context_changed". Updated working directory and git context after the change
1173#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1174#[serde(rename_all = "camelCase")]
1175pub struct SessionContextChangedData {
1176    /// Base commit of current git branch at session start time
1177    #[serde(skip_serializing_if = "Option::is_none")]
1178    pub base_commit: Option<String>,
1179    /// Current git branch name
1180    #[serde(skip_serializing_if = "Option::is_none")]
1181    pub branch: Option<String>,
1182    /// Current working directory path
1183    pub cwd: String,
1184    /// Root directory of the git repository, resolved via git rev-parse
1185    #[serde(skip_serializing_if = "Option::is_none")]
1186    pub git_root: Option<String>,
1187    /// Head commit of current git branch at session start time
1188    #[serde(skip_serializing_if = "Option::is_none")]
1189    pub head_commit: Option<String>,
1190    /// Hosting platform type of the repository (github or ado)
1191    #[serde(skip_serializing_if = "Option::is_none")]
1192    pub host_type: Option<WorkingDirectoryContextHostType>,
1193    /// Repository identifier derived from the git remote URL ("owner/name" for GitHub, "org/project/repo" for Azure DevOps)
1194    #[serde(skip_serializing_if = "Option::is_none")]
1195    pub repository: Option<String>,
1196    /// Raw host string from the git remote URL (e.g. "github.com", "mycompany.ghe.com", "dev.azure.com")
1197    #[serde(skip_serializing_if = "Option::is_none")]
1198    pub repository_host: Option<String>,
1199}
1200
1201/// Session event "session.usage_info". Current context window usage statistics including token and message counts
1202#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1203#[serde(rename_all = "camelCase")]
1204pub struct SessionUsageInfoData {
1205    /// Token count from non-system messages (user, assistant, tool)
1206    #[serde(skip_serializing_if = "Option::is_none")]
1207    pub conversation_tokens: Option<i64>,
1208    /// Current number of tokens in the context window
1209    pub current_tokens: i64,
1210    /// Whether this is the first usage_info event emitted in this session
1211    #[serde(skip_serializing_if = "Option::is_none")]
1212    pub is_initial: Option<bool>,
1213    /// Current number of messages in the conversation
1214    pub messages_length: i64,
1215    /// Token count from system message(s)
1216    #[serde(skip_serializing_if = "Option::is_none")]
1217    pub system_tokens: Option<i64>,
1218    /// Maximum token count for the model's context window
1219    pub token_limit: i64,
1220    /// Token count from tool definitions
1221    #[serde(skip_serializing_if = "Option::is_none")]
1222    pub tool_definitions_tokens: Option<i64>,
1223}
1224
1225/// Session event "session.compaction_start". Context window breakdown at the start of LLM-powered conversation compaction
1226#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1227#[serde(rename_all = "camelCase")]
1228pub struct SessionCompactionStartData {
1229    /// Token count from non-system messages (user, assistant, tool) at compaction start
1230    #[serde(skip_serializing_if = "Option::is_none")]
1231    pub conversation_tokens: Option<i64>,
1232    /// Model identifier used for compaction, when known
1233    #[serde(skip_serializing_if = "Option::is_none")]
1234    pub model: Option<String>,
1235    /// Token count from system message(s) at compaction start
1236    #[serde(skip_serializing_if = "Option::is_none")]
1237    pub system_tokens: Option<i64>,
1238    /// Token count from tool definitions at compaction start
1239    #[serde(skip_serializing_if = "Option::is_none")]
1240    pub tool_definitions_tokens: Option<i64>,
1241}
1242
1243/// Token usage detail for a single billing category
1244#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1245#[serde(rename_all = "camelCase")]
1246pub struct CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail {
1247    /// Number of tokens in this billing batch
1248    pub batch_size: i64,
1249    /// Cost per batch of tokens
1250    pub cost_per_batch: i64,
1251    /// Total token count for this entry
1252    pub token_count: i64,
1253    /// Token category (e.g., "input", "output")
1254    pub token_type: String,
1255}
1256
1257/// Per-request cost and usage data from the CAPI copilot_usage response field
1258#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1259#[serde(rename_all = "camelCase")]
1260pub(crate) struct CompactionCompleteCompactionTokensUsedCopilotUsage {
1261    /// Itemized token usage breakdown
1262    #[doc(hidden)]
1263    #[serde(skip_serializing_if = "Option::is_none")]
1264    pub(crate) token_details:
1265        Option<Vec<CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail>>,
1266    /// Total cost in nano-AI units for this request
1267    pub total_nano_aiu: f64,
1268}
1269
1270/// Token usage breakdown for the compaction LLM call (aligned with assistant.usage format)
1271#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1272#[serde(rename_all = "camelCase")]
1273pub struct CompactionCompleteCompactionTokensUsed {
1274    /// Cached input tokens reused in the compaction LLM call
1275    #[serde(skip_serializing_if = "Option::is_none")]
1276    pub cache_read_tokens: Option<i64>,
1277    /// Tokens written to prompt cache in the compaction LLM call
1278    #[serde(skip_serializing_if = "Option::is_none")]
1279    pub cache_write_tokens: Option<i64>,
1280    /// Per-request cost and usage data from the CAPI copilot_usage response field
1281    #[doc(hidden)]
1282    #[serde(skip_serializing_if = "Option::is_none")]
1283    pub(crate) copilot_usage: Option<CompactionCompleteCompactionTokensUsedCopilotUsage>,
1284    /// Duration of the compaction LLM call in milliseconds
1285    #[serde(skip_serializing_if = "Option::is_none")]
1286    pub duration: Option<i64>,
1287    /// Input tokens consumed by the compaction LLM call
1288    #[serde(skip_serializing_if = "Option::is_none")]
1289    pub input_tokens: Option<i64>,
1290    /// Model identifier used for the compaction LLM call
1291    #[serde(skip_serializing_if = "Option::is_none")]
1292    pub model: Option<String>,
1293    /// Output tokens produced by the compaction LLM call
1294    #[serde(skip_serializing_if = "Option::is_none")]
1295    pub output_tokens: Option<i64>,
1296}
1297
1298/// Session event "session.compaction_complete". Conversation compaction results including success status, metrics, and optional error details
1299#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1300#[serde(rename_all = "camelCase")]
1301pub struct SessionCompactionCompleteData {
1302    /// Checkpoint snapshot number created for recovery
1303    #[serde(skip_serializing_if = "Option::is_none")]
1304    pub checkpoint_number: Option<i64>,
1305    /// File path where the checkpoint was stored
1306    #[serde(skip_serializing_if = "Option::is_none")]
1307    pub checkpoint_path: Option<String>,
1308    /// Token usage breakdown for the compaction LLM call (aligned with assistant.usage format)
1309    #[serde(skip_serializing_if = "Option::is_none")]
1310    pub compaction_tokens_used: Option<CompactionCompleteCompactionTokensUsed>,
1311    /// Token count from non-system messages (user, assistant, tool) after compaction
1312    #[serde(skip_serializing_if = "Option::is_none")]
1313    pub conversation_tokens: Option<i64>,
1314    /// User-supplied focus instructions provided to a manual `/compact` invocation. Omitted for automatic compaction and for manual compaction with no focus text.
1315    #[serde(skip_serializing_if = "Option::is_none")]
1316    pub custom_instructions: Option<String>,
1317    /// Error message if compaction failed
1318    #[serde(skip_serializing_if = "Option::is_none")]
1319    pub error: Option<String>,
1320    /// Number of messages removed during compaction
1321    #[serde(skip_serializing_if = "Option::is_none")]
1322    pub messages_removed: Option<i64>,
1323    /// Total tokens in conversation after compaction
1324    #[serde(skip_serializing_if = "Option::is_none")]
1325    pub post_compaction_tokens: Option<i64>,
1326    /// Number of messages before compaction
1327    #[serde(skip_serializing_if = "Option::is_none")]
1328    pub pre_compaction_messages_length: Option<i64>,
1329    /// Total tokens in conversation before compaction
1330    #[serde(skip_serializing_if = "Option::is_none")]
1331    pub pre_compaction_tokens: Option<i64>,
1332    /// GitHub request tracing ID (x-github-request-id header) for the compaction LLM call
1333    #[serde(skip_serializing_if = "Option::is_none")]
1334    pub request_id: Option<RequestId>,
1335    /// Copilot service request ID (x-copilot-service-request-id header) for the compaction LLM call
1336    #[serde(skip_serializing_if = "Option::is_none")]
1337    pub service_request_id: Option<String>,
1338    /// For failed compaction only: the HTTP status code of the compaction LLM call failure, when it carried one. Absent for successful compaction and for failures without an HTTP status (e.g. an empty model response or a transport error).
1339    #[serde(skip_serializing_if = "Option::is_none")]
1340    pub status_code: Option<i64>,
1341    /// Whether compaction completed successfully
1342    pub success: bool,
1343    /// LLM-generated summary of the compacted conversation history
1344    #[serde(skip_serializing_if = "Option::is_none")]
1345    pub summary_content: Option<String>,
1346    /// Token count from system message(s) after compaction
1347    #[serde(skip_serializing_if = "Option::is_none")]
1348    pub system_tokens: Option<i64>,
1349    /// Number of tokens removed during compaction
1350    #[serde(skip_serializing_if = "Option::is_none")]
1351    pub tokens_removed: Option<i64>,
1352    /// Token count from tool definitions after compaction
1353    #[serde(skip_serializing_if = "Option::is_none")]
1354    pub tool_definitions_tokens: Option<i64>,
1355}
1356
1357/// Session event "session.task_complete". Task completion notification with summary from the agent
1358#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1359#[serde(rename_all = "camelCase")]
1360pub struct SessionTaskCompleteData {
1361    /// Whether the tool call succeeded. False when validation failed (e.g., invalid arguments)
1362    #[serde(skip_serializing_if = "Option::is_none")]
1363    pub success: Option<bool>,
1364    /// Summary of the completed task, provided by the agent
1365    #[serde(skip_serializing_if = "Option::is_none")]
1366    pub summary: Option<String>,
1367}
1368
1369/// Session event "user.message". Payload of `user.message` with displayed and model-transformed content, attachments, source/delivery metadata, mode, and telemetry IDs.
1370#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1371#[serde(rename_all = "camelCase")]
1372pub struct UserMessageData {
1373    /// The agent mode that was active when this message was sent
1374    #[serde(skip_serializing_if = "Option::is_none")]
1375    pub agent_mode: Option<UserMessageAgentMode>,
1376    /// Files, selections, or GitHub references attached to the message
1377    #[serde(skip_serializing_if = "Option::is_none")]
1378    pub attachments: Option<Vec<serde_json::Value>>,
1379    /// The user's message text as displayed in the timeline
1380    pub content: String,
1381    /// How this message was delivered to the agentic loop relative to loop state (idle-start vs. steering/queued while busy). The timing axis; combine with `source` (origin) for the full picture. Used for telemetry attribution.
1382    #[serde(skip_serializing_if = "Option::is_none")]
1383    pub delivery: Option<UserMessageDelivery>,
1384    /// CAPI interaction ID for correlating this user message with its turn
1385    #[serde(skip_serializing_if = "Option::is_none")]
1386    pub interaction_id: Option<String>,
1387    /// True when this user message was auto-injected by autopilot's continuation loop rather than typed by the user; used to distinguish autopilot-driven turns in telemetry.
1388    #[serde(skip_serializing_if = "Option::is_none")]
1389    pub is_autopilot_continuation: Option<bool>,
1390    /// Path-backed native document attachments that stayed on the tagged_files path flow because native upload could not read them or would exceed the request size limit
1391    #[serde(skip_serializing_if = "Option::is_none")]
1392    pub native_document_path_fallback_paths: Option<Vec<String>>,
1393    /// Parent agent task ID for background telemetry correlated to this user turn
1394    #[serde(skip_serializing_if = "Option::is_none")]
1395    pub parent_agent_task_id: Option<String>,
1396    /// Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user)
1397    #[serde(skip_serializing_if = "Option::is_none")]
1398    pub source: Option<String>,
1399    /// Normalized document MIME types that were sent natively instead of through tagged_files XML
1400    #[serde(skip_serializing_if = "Option::is_none")]
1401    pub supported_native_document_mime_types: Option<Vec<String>>,
1402    /// Transformed version of the message sent to the model, with XML wrapping, timestamps, and other augmentations for prompt caching
1403    #[serde(skip_serializing_if = "Option::is_none")]
1404    pub transformed_content: Option<String>,
1405}
1406
1407/// Session event "pending_messages.modified". Empty payload; the event signals that the pending message queue has changed
1408#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1409#[serde(rename_all = "camelCase")]
1410pub struct PendingMessagesModifiedData {}
1411
1412/// Session event "assistant.turn_start". Turn initialization metadata including identifier and interaction tracking
1413#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1414#[serde(rename_all = "camelCase")]
1415pub struct AssistantTurnStartData {
1416    /// CAPI interaction ID for correlating this turn with upstream telemetry
1417    #[serde(skip_serializing_if = "Option::is_none")]
1418    pub interaction_id: Option<String>,
1419    /// Model identifier used for this turn, when known
1420    #[serde(skip_serializing_if = "Option::is_none")]
1421    pub model: Option<String>,
1422    /// Identifier for this turn within the agentic loop, typically a stringified turn number
1423    pub turn_id: String,
1424}
1425
1426/// Session event "assistant.intent". Agent intent description for current activity or plan
1427#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1428#[serde(rename_all = "camelCase")]
1429pub struct AssistantIntentData {
1430    /// Short description of what the agent is currently doing or planning to do
1431    pub intent: String,
1432}
1433
1434/// Session event "assistant.reasoning". Assistant reasoning content for timeline display with complete thinking text
1435#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1436#[serde(rename_all = "camelCase")]
1437pub struct AssistantReasoningData {
1438    /// The complete extended thinking text from the model
1439    pub content: String,
1440    /// Unique identifier for this reasoning block
1441    pub reasoning_id: String,
1442}
1443
1444/// Session event "assistant.reasoning_delta". Streaming reasoning delta for incremental extended thinking updates
1445#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1446#[serde(rename_all = "camelCase")]
1447pub struct AssistantReasoningDeltaData {
1448    /// Incremental text chunk to append to the reasoning content
1449    pub delta_content: String,
1450    /// Reasoning block ID this delta belongs to, matching the corresponding assistant.reasoning event
1451    pub reasoning_id: String,
1452}
1453
1454/// Session event "assistant.tool_call_delta". Streaming tool-call input delta for incremental tool-call updates
1455#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1456#[serde(rename_all = "camelCase")]
1457pub struct AssistantToolCallDeltaData {
1458    /// Raw provider tool input fragment to append for this tool call. Function/tool-use providers stream serialized JSON argument text (so newlines inside JSON string values may appear as escaped `\n` until the accumulated JSON is parsed); custom tool calls stream raw custom input.
1459    pub input_delta: String,
1460    /// Tool call ID this delta belongs to, matching the corresponding assistant.message tool request
1461    pub tool_call_id: String,
1462    /// Name of the tool being invoked, when known from the stream
1463    #[serde(skip_serializing_if = "Option::is_none")]
1464    pub tool_name: Option<String>,
1465    /// Tool call type, when known from the stream
1466    #[serde(skip_serializing_if = "Option::is_none")]
1467    pub tool_type: Option<AssistantMessageToolRequestType>,
1468}
1469
1470/// Session event "assistant.streaming_delta". Streaming response progress with cumulative byte count
1471#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1472#[serde(rename_all = "camelCase")]
1473pub struct AssistantStreamingDeltaData {
1474    /// Cumulative total bytes received from the streaming response so far
1475    pub total_response_size_bytes: i64,
1476}
1477
1478/// A source that backs one or more cited spans in the assistant's response.
1479///
1480/// <div class="warning">
1481///
1482/// **Experimental.** This type is part of an experimental wire-protocol surface
1483/// and may change or be removed in future SDK or CLI releases.
1484///
1485/// </div>
1486#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1487#[serde(rename_all = "camelCase")]
1488pub struct CitationSource {
1489    /// Stable, turn-scoped identifier for this source, referenced by CitationReference.sourceId.
1490    pub id: String,
1491    /// File path relative to the agent's workspace root, when the source is a file.
1492    #[serde(skip_serializing_if = "Option::is_none")]
1493    pub path: Option<String>,
1494    /// The system that produced this citation.
1495    pub provider: CitationProvider,
1496    /// Human-readable title of the source.
1497    #[serde(skip_serializing_if = "Option::is_none")]
1498    pub title: Option<String>,
1499    /// URL of the source, when it is a web resource.
1500    #[serde(skip_serializing_if = "Option::is_none")]
1501    pub url: Option<String>,
1502}
1503
1504/// A single citation occurrence linking a span of generated text to a supporting source.
1505///
1506/// <div class="warning">
1507///
1508/// **Experimental.** This type is part of an experimental wire-protocol surface
1509/// and may change or be removed in future SDK or CLI releases.
1510///
1511/// </div>
1512#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1513#[serde(rename_all = "camelCase")]
1514pub struct CitationReference {
1515    /// The exact text from the source that supports the cited span, when provided by the model.
1516    #[serde(skip_serializing_if = "Option::is_none")]
1517    pub cited_text: Option<String>,
1518    /// Location within the source that supports the cited span, when the provider reports one.
1519    #[serde(skip_serializing_if = "Option::is_none")]
1520    pub location: Option<serde_json::Value>,
1521    /// Provider-native citation correlation data (e.g. Anthropic search_result_index / document_index), passed through opaquely for debugging and forward compatibility.
1522    #[serde(skip_serializing_if = "Option::is_none")]
1523    pub provider_metadata: Option<serde_json::Value>,
1524    /// Identifier of the CitationSource this reference points to (CitationSource.id).
1525    pub source_id: String,
1526}
1527
1528/// A contiguous span of generated assistant text and the source references that support it.
1529///
1530/// <div class="warning">
1531///
1532/// **Experimental.** This type is part of an experimental wire-protocol surface
1533/// and may change or be removed in future SDK or CLI releases.
1534///
1535/// </div>
1536#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1537#[serde(rename_all = "camelCase")]
1538pub struct CitationSpan {
1539    /// End offset of the cited span within the final assistant message content (UTF-16 code units, zero-based, exclusive).
1540    pub end_index: i64,
1541    /// The sources that support this span of generated text.
1542    pub references: Vec<CitationReference>,
1543    /// Start offset of the cited span within the final assistant message content (UTF-16 code units, zero-based, inclusive).
1544    pub start_index: i64,
1545}
1546
1547/// Provider-agnostic citations linking spans of the assistant's response to their supporting sources.
1548///
1549/// <div class="warning">
1550///
1551/// **Experimental.** This type is part of an experimental wire-protocol surface
1552/// and may change or be removed in future SDK or CLI releases.
1553///
1554/// </div>
1555#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1556#[serde(rename_all = "camelCase")]
1557pub struct Citations {
1558    /// Deduplicated set of sources referenced by the citation spans.
1559    pub sources: Vec<CitationSource>,
1560    /// Spans of generated text annotated with the sources that support them.
1561    pub spans: Vec<CitationSpan>,
1562}
1563
1564/// Neutral provider-tagged server-side tool-use payload (tool search, advisor) for verbatim round-tripping
1565///
1566/// <div class="warning">
1567///
1568/// **Experimental.** This type is part of an experimental wire-protocol surface
1569/// and may change or be removed in future SDK or CLI releases.
1570///
1571/// </div>
1572#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1573#[serde(rename_all = "camelCase")]
1574pub struct AssistantMessageServerTools {
1575    #[serde(skip_serializing_if = "Option::is_none")]
1576    pub advisor_model: Option<String>,
1577    #[serde(skip_serializing_if = "Option::is_none")]
1578    pub function_call_namespaces: Option<HashMap<String, String>>,
1579    #[serde(skip_serializing_if = "Option::is_none")]
1580    pub items: Option<Vec<serde_json::Value>>,
1581    pub provider: String,
1582    #[serde(skip_serializing_if = "Option::is_none")]
1583    pub raw_content_blocks: Option<Vec<serde_json::Value>>,
1584}
1585
1586/// A tool invocation request from the assistant
1587#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1588#[serde(rename_all = "camelCase")]
1589pub struct AssistantMessageToolRequest {
1590    /// Arguments to pass to the tool, format depends on the tool
1591    #[serde(skip_serializing_if = "Option::is_none")]
1592    pub arguments: Option<serde_json::Value>,
1593    /// Resolved intention summary describing what this specific call does
1594    #[serde(skip_serializing_if = "Option::is_none")]
1595    pub intention_summary: Option<String>,
1596    /// Name of the MCP server hosting this tool, when the tool is an MCP tool
1597    #[serde(skip_serializing_if = "Option::is_none")]
1598    pub mcp_server_name: Option<String>,
1599    /// Original tool name on the MCP server, when the tool is an MCP tool
1600    #[serde(skip_serializing_if = "Option::is_none")]
1601    pub mcp_tool_name: Option<String>,
1602    /// Name of the tool being invoked
1603    pub name: String,
1604    /// Unique identifier for this tool call
1605    pub tool_call_id: String,
1606    /// Human-readable display title for the tool
1607    #[serde(skip_serializing_if = "Option::is_none")]
1608    pub tool_title: Option<String>,
1609    /// Tool call type: "function" for standard tool calls, "custom" for grammar-based tool calls. Defaults to "function" when absent.
1610    #[serde(skip_serializing_if = "Option::is_none")]
1611    pub r#type: Option<AssistantMessageToolRequestType>,
1612}
1613
1614/// Session event "assistant.message". Assistant response containing text content, optional tool requests, and interaction metadata
1615#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1616#[serde(rename_all = "camelCase")]
1617pub struct AssistantMessageData {
1618    /// Provider's completion / response identifier; shared across all chunks of a single API call. Used to group multi-chunk assistant utterances.
1619    #[serde(skip_serializing_if = "Option::is_none")]
1620    pub api_call_id: Option<String>,
1621    /// Provider-agnostic citations linking spans of this message's content to the sources that support them. Experimental; only populated when citation emission is enabled.
1622    ///
1623    /// <div class="warning">
1624    ///
1625    /// **Experimental.** This type is part of an experimental wire-protocol surface
1626    /// and may change or be removed in future SDK or CLI releases.
1627    ///
1628    /// </div>
1629    #[serde(skip_serializing_if = "Option::is_none")]
1630    pub citations: Option<Citations>,
1631    /// The assistant's text response content
1632    pub content: String,
1633    /// Encrypted reasoning content from OpenAI models. Session-bound and stripped on resume.
1634    #[serde(skip_serializing_if = "Option::is_none")]
1635    pub encrypted_content: Option<String>,
1636    /// CAPI interaction ID for correlating this message with upstream telemetry
1637    #[serde(skip_serializing_if = "Option::is_none")]
1638    pub interaction_id: Option<String>,
1639    /// Unique identifier for this assistant message
1640    pub message_id: String,
1641    /// Model that produced this assistant message, if known
1642    #[serde(skip_serializing_if = "Option::is_none")]
1643    pub model: Option<String>,
1644    /// Actual output token count from the API response (completion_tokens), used for accurate token accounting
1645    #[serde(skip_serializing_if = "Option::is_none")]
1646    pub output_tokens: Option<i64>,
1647    /// Tool call ID of the parent tool invocation when this event originates from a sub-agent
1648    #[doc(hidden)]
1649    #[deprecated]
1650    #[serde(skip_serializing_if = "Option::is_none")]
1651    pub parent_tool_call_id: Option<String>,
1652    /// Generation phase for phased-output models (e.g., thinking vs. response phases)
1653    #[serde(skip_serializing_if = "Option::is_none")]
1654    pub phase: Option<String>,
1655    /// Opaque/encrypted extended thinking data from Anthropic models. Session-bound and stripped on resume.
1656    #[serde(skip_serializing_if = "Option::is_none")]
1657    pub reasoning_opaque: Option<String>,
1658    /// Readable reasoning text from the model's extended thinking
1659    #[serde(skip_serializing_if = "Option::is_none")]
1660    pub reasoning_text: Option<String>,
1661    /// OpenAI-compatible wire field the provider used for reasoning (e.g. reasoning_content/reasoning). Populated only when non-canonical, so the dialect round-trips across turns.
1662    #[serde(skip_serializing_if = "Option::is_none")]
1663    pub reasoning_wire_field: Option<String>,
1664    /// GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
1665    #[serde(skip_serializing_if = "Option::is_none")]
1666    pub request_id: Option<RequestId>,
1667    /// Neutral provider-tagged server-side tool-use payload (tool search, advisor) for verbatim round-tripping
1668    #[serde(skip_serializing_if = "Option::is_none")]
1669    pub server_tools: Option<AssistantMessageServerTools>,
1670    /// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation
1671    #[serde(skip_serializing_if = "Option::is_none")]
1672    pub service_request_id: Option<String>,
1673    /// Tool invocations requested by the assistant in this message
1674    #[serde(skip_serializing_if = "Option::is_none")]
1675    pub tool_requests: Option<Vec<AssistantMessageToolRequest>>,
1676    /// Identifier for the agent loop turn that produced this message, matching the corresponding assistant.turn_start event
1677    #[serde(skip_serializing_if = "Option::is_none")]
1678    pub turn_id: Option<String>,
1679}
1680
1681/// Session event "assistant.message_start". Streaming assistant message start metadata
1682#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1683#[serde(rename_all = "camelCase")]
1684pub struct AssistantMessageStartData {
1685    /// Message ID this start event belongs to, matching subsequent deltas and assistant.message
1686    pub message_id: String,
1687    /// Generation phase this message belongs to for phased-output models
1688    #[serde(skip_serializing_if = "Option::is_none")]
1689    pub phase: Option<String>,
1690}
1691
1692/// Session event "assistant.message_delta". Streaming assistant message delta for incremental response updates
1693#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1694#[serde(rename_all = "camelCase")]
1695pub struct AssistantMessageDeltaData {
1696    /// Incremental text chunk to append to the message content
1697    pub delta_content: String,
1698    /// Message ID this delta belongs to, matching the corresponding assistant.message event
1699    pub message_id: String,
1700    /// Tool call ID of the parent tool invocation when this event originates from a sub-agent
1701    #[doc(hidden)]
1702    #[deprecated]
1703    #[serde(skip_serializing_if = "Option::is_none")]
1704    pub parent_tool_call_id: Option<String>,
1705}
1706
1707/// Session event "assistant.turn_end". Turn completion metadata including the turn identifier
1708#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1709#[serde(rename_all = "camelCase")]
1710pub struct AssistantTurnEndData {
1711    /// Model identifier used for this turn, when known
1712    #[serde(skip_serializing_if = "Option::is_none")]
1713    pub model: Option<String>,
1714    /// Identifier of the turn that has ended, matching the corresponding assistant.turn_start event
1715    pub turn_id: String,
1716}
1717
1718/// Session event "assistant.idle". Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred
1719#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1720#[serde(rename_all = "camelCase")]
1721pub struct AssistantIdleData {
1722    /// True when the preceding agentic loop was cancelled via abort signal
1723    #[serde(skip_serializing_if = "Option::is_none")]
1724    pub aborted: Option<bool>,
1725}
1726
1727/// Token usage detail for a single billing category
1728#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1729#[serde(rename_all = "camelCase")]
1730pub struct AssistantUsageCopilotUsageTokenDetail {
1731    /// Number of tokens in this billing batch
1732    pub batch_size: i64,
1733    /// Cost per batch of tokens
1734    pub cost_per_batch: i64,
1735    /// Total token count for this entry
1736    pub token_count: i64,
1737    /// Token category (e.g., "input", "output")
1738    pub token_type: String,
1739}
1740
1741/// Per-request cost and usage data from the CAPI copilot_usage response field
1742#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1743#[serde(rename_all = "camelCase")]
1744pub struct AssistantUsageCopilotUsage {
1745    /// Itemized token usage breakdown
1746    #[doc(hidden)]
1747    #[serde(skip_serializing_if = "Option::is_none")]
1748    pub(crate) token_details: Option<Vec<AssistantUsageCopilotUsageTokenDetail>>,
1749    /// Total cost in nano-AI units for this request
1750    pub total_nano_aiu: f64,
1751}
1752
1753/// Internal per-quota snapshot for assistant usage, including entitlement, consumed requests, overage, reset date, and remaining quota.
1754#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1755#[serde(rename_all = "camelCase")]
1756pub(crate) struct AssistantUsageQuotaSnapshot {
1757    /// Total requests allowed by the entitlement
1758    #[doc(hidden)]
1759    pub(crate) entitlement_requests: i64,
1760    /// Whether the user currently has quota available for use
1761    #[doc(hidden)]
1762    #[serde(skip_serializing_if = "Option::is_none")]
1763    pub(crate) has_quota: Option<bool>,
1764    /// Whether the user has an unlimited usage entitlement
1765    #[doc(hidden)]
1766    pub(crate) is_unlimited_entitlement: bool,
1767    /// Number of additional usage requests made this period
1768    #[doc(hidden)]
1769    pub(crate) overage: f64,
1770    /// Whether additional usage is allowed when quota is exhausted
1771    #[doc(hidden)]
1772    pub(crate) overage_allowed_with_exhausted_quota: bool,
1773    /// Pay-as-you-go additional-usage budget cap in AI credits (1 credit = $0.01); present only when CAPI emits a finite value
1774    #[doc(hidden)]
1775    #[serde(skip_serializing_if = "Option::is_none")]
1776    pub(crate) overage_entitlement: Option<f64>,
1777    /// Percentage of quota remaining (0 to 100)
1778    #[doc(hidden)]
1779    pub(crate) remaining_percentage: f64,
1780    /// Date when the quota resets
1781    #[doc(hidden)]
1782    #[serde(skip_serializing_if = "Option::is_none")]
1783    pub(crate) reset_date: Option<String>,
1784    /// Whether this snapshot uses token-based billing (AI-credits allocation)
1785    #[doc(hidden)]
1786    #[serde(skip_serializing_if = "Option::is_none")]
1787    pub(crate) token_based_billing: Option<bool>,
1788    /// Whether usage is still permitted after quota exhaustion
1789    #[doc(hidden)]
1790    pub(crate) usage_allowed_with_exhausted_quota: bool,
1791    /// Number of requests already consumed
1792    #[doc(hidden)]
1793    pub(crate) used_requests: i64,
1794}
1795
1796/// Session event "assistant.usage". LLM API call usage metrics including tokens, costs, quotas, and billing information
1797#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1798#[serde(rename_all = "camelCase")]
1799pub struct AssistantUsageData {
1800    /// Completion ID from the model provider (e.g., chatcmpl-abc123)
1801    #[serde(skip_serializing_if = "Option::is_none")]
1802    pub api_call_id: Option<String>,
1803    /// API endpoint used for this model call, matching CAPI supported_endpoints vocabulary
1804    #[serde(skip_serializing_if = "Option::is_none")]
1805    pub api_endpoint: Option<AssistantUsageApiEndpoint>,
1806    /// Number of tokens read from prompt cache
1807    #[serde(skip_serializing_if = "Option::is_none")]
1808    pub cache_read_tokens: Option<i64>,
1809    /// Number of tokens written to prompt cache
1810    #[serde(skip_serializing_if = "Option::is_none")]
1811    pub cache_write_tokens: Option<i64>,
1812    /// Whether the model response was blocked or truncated by content filtering (finish_reason === 'content_filter'). For Anthropic models this corresponds to a 'refusal' stop reason.
1813    #[serde(skip_serializing_if = "Option::is_none")]
1814    pub content_filter_triggered: Option<bool>,
1815    /// Per-request cost and usage data from the CAPI copilot_usage response field
1816    #[serde(skip_serializing_if = "Option::is_none")]
1817    pub copilot_usage: Option<AssistantUsageCopilotUsage>,
1818    /// Model multiplier cost for billing purposes
1819    ///
1820    /// <div class="warning">
1821    ///
1822    /// **Experimental.** This type is part of an experimental wire-protocol surface
1823    /// and may change or be removed in future SDK or CLI releases.
1824    ///
1825    /// </div>
1826    #[serde(skip_serializing_if = "Option::is_none")]
1827    pub cost: Option<f64>,
1828    /// Duration of the API call in milliseconds
1829    #[serde(skip_serializing_if = "Option::is_none")]
1830    pub duration: Option<i64>,
1831    /// Finish reason reported by the model for this API call (e.g. "stop", "length", "tool_calls", "content_filter"). Normalized to OpenAI vocabulary; for Anthropic models a "refusal" stop reason maps to "content_filter".
1832    #[serde(skip_serializing_if = "Option::is_none")]
1833    pub finish_reason: Option<String>,
1834    /// What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls
1835    #[serde(skip_serializing_if = "Option::is_none")]
1836    pub initiator: Option<String>,
1837    /// Number of input tokens consumed
1838    #[serde(skip_serializing_if = "Option::is_none")]
1839    pub input_tokens: Option<i64>,
1840    /// Average inter-token latency in milliseconds. Only available for streaming requests
1841    #[serde(skip_serializing_if = "Option::is_none")]
1842    pub inter_token_latency_ms: Option<f64>,
1843    /// Model identifier used for this API call
1844    pub model: String,
1845    /// Number of output tokens produced
1846    #[serde(skip_serializing_if = "Option::is_none")]
1847    pub output_tokens: Option<i64>,
1848    /// Parent tool call ID when this usage originates from a sub-agent
1849    #[doc(hidden)]
1850    #[deprecated]
1851    #[serde(skip_serializing_if = "Option::is_none")]
1852    pub parent_tool_call_id: Option<String>,
1853    /// GitHub request tracing ID (x-github-request-id header) for server-side log correlation
1854    #[serde(skip_serializing_if = "Option::is_none")]
1855    pub provider_call_id: Option<String>,
1856    /// Per-quota resource usage snapshots, keyed by quota identifier
1857    #[doc(hidden)]
1858    #[serde(skip_serializing_if = "Option::is_none")]
1859    pub(crate) quota_snapshots: Option<HashMap<String, AssistantUsageQuotaSnapshot>>,
1860    /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
1861    #[serde(skip_serializing_if = "Option::is_none")]
1862    pub reasoning_effort: Option<String>,
1863    /// Number of output tokens used for reasoning (e.g., chain-of-thought)
1864    #[serde(skip_serializing_if = "Option::is_none")]
1865    pub reasoning_tokens: Option<i64>,
1866    /// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation
1867    #[serde(skip_serializing_if = "Option::is_none")]
1868    pub service_request_id: Option<String>,
1869    /// Time to first token in milliseconds. Only available for streaming requests
1870    #[serde(skip_serializing_if = "Option::is_none")]
1871    pub time_to_first_token_ms: Option<f64>,
1872}
1873
1874/// Content-free structural summary of the failing request for diagnosing malformed 4xx calls
1875#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1876#[serde(rename_all = "camelCase")]
1877pub struct ModelCallFailureRequestFingerprint {
1878    /// Total number of image content parts
1879    pub image_part_count: i64,
1880    /// Image parts whose media type cannot be determined (rejected by strict providers)
1881    pub image_parts_missing_media_type: i64,
1882    /// Role of the final message in the request
1883    #[serde(skip_serializing_if = "Option::is_none")]
1884    pub last_message_role: Option<String>,
1885    /// Total number of messages in the request
1886    pub message_count: i64,
1887    /// Tool calls whose name is missing or empty (rejected by strict providers)
1888    pub nameless_tool_call_count: i64,
1889    /// Total number of tool calls across assistant messages
1890    pub tool_call_count: i64,
1891    /// Number of "tool" result messages in the request
1892    pub tool_result_message_count: i64,
1893}
1894
1895/// Session event "model.call_failure". Failed LLM API call metadata for telemetry
1896#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1897#[serde(rename_all = "camelCase")]
1898pub struct ModelCallFailureData {
1899    /// Completion ID from the model provider (e.g., chatcmpl-abc123)
1900    #[serde(skip_serializing_if = "Option::is_none")]
1901    pub api_call_id: Option<String>,
1902    /// For HTTP 400 failures only: whether the response carried a structured CAPI error envelope (structured_error, a deterministic validation failure) or no error body (bodyless, the transient gateway/proxy signature). Absent for non-400 failures.
1903    #[serde(skip_serializing_if = "Option::is_none")]
1904    pub bad_request_kind: Option<ModelCallFailureBadRequestKind>,
1905    /// Duration of the failed API call in milliseconds
1906    #[serde(skip_serializing_if = "Option::is_none")]
1907    pub duration_ms: Option<i64>,
1908    /// For HTTP 400 failures only: the `code` from the CAPI error envelope (e.g. 'model_max_prompt_tokens_exceeded') identifying which deterministic validation failure occurred. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures.
1909    #[serde(skip_serializing_if = "Option::is_none")]
1910    pub error_code: Option<String>,
1911    /// Raw provider/runtime error message for restricted telemetry
1912    #[serde(skip_serializing_if = "Option::is_none")]
1913    pub error_message: Option<String>,
1914    /// For HTTP 400 failures only: the `type` from the CAPI error envelope (e.g. 'websocket_error'), a coarser companion to errorCode for envelopes that carry no code. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures.
1915    #[serde(skip_serializing_if = "Option::is_none")]
1916    pub error_type: Option<String>,
1917    /// What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls
1918    #[serde(skip_serializing_if = "Option::is_none")]
1919    pub initiator: Option<String>,
1920    /// Model identifier used for the failed API call
1921    #[serde(skip_serializing_if = "Option::is_none")]
1922    pub model: Option<String>,
1923    /// GitHub request tracing ID (x-github-request-id header) for server-side log correlation
1924    #[serde(skip_serializing_if = "Option::is_none")]
1925    pub provider_call_id: Option<String>,
1926    /// Per-quota usage snapshots parsed from the failed response's quota headers, keyed by quota identifier. Present when the error response carried quota headers (e.g. a 402 once the additional spend limit is reached) so the UI can refresh the quota display on failure.
1927    #[doc(hidden)]
1928    #[serde(skip_serializing_if = "Option::is_none")]
1929    pub(crate) quota_snapshots: Option<HashMap<String, AssistantUsageQuotaSnapshot>>,
1930    /// Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures.
1931    #[serde(skip_serializing_if = "Option::is_none")]
1932    pub request_fingerprint: Option<ModelCallFailureRequestFingerprint>,
1933    /// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation
1934    #[serde(skip_serializing_if = "Option::is_none")]
1935    pub service_request_id: Option<String>,
1936    /// Where the failed model call originated
1937    pub source: ModelCallFailureSource,
1938    /// HTTP status code from the failed request
1939    #[serde(skip_serializing_if = "Option::is_none")]
1940    pub status_code: Option<i32>,
1941}
1942
1943/// Session event "abort". Turn abort information including the reason for termination
1944#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1945#[serde(rename_all = "camelCase")]
1946pub struct AbortData {
1947    /// Finite reason code describing why the current turn was aborted
1948    pub reason: AbortReason,
1949}
1950
1951/// Session event "tool.user_requested". User-initiated tool invocation request with tool name and arguments
1952#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1953#[serde(rename_all = "camelCase")]
1954pub struct ToolUserRequestedData {
1955    /// Arguments for the tool invocation
1956    #[serde(skip_serializing_if = "Option::is_none")]
1957    pub arguments: Option<serde_json::Value>,
1958    /// Unique identifier for this tool call
1959    pub tool_call_id: String,
1960    /// Name of the tool the user wants to invoke
1961    pub tool_name: String,
1962}
1963
1964/// Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs.
1965#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1966#[serde(rename_all = "camelCase")]
1967pub struct ToolExecutionStartShellToolInfo {
1968    /// Whether the command includes a file write redirection (e.g., > or >>).
1969    pub has_write_file_redirection: bool,
1970    /// File paths the command may read or write, derived from the command at start time. Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires.
1971    pub possible_paths: Vec<String>,
1972}
1973
1974/// MCP Apps tool `_meta.ui` resource URI and visibility captured on `tool.execution_start`.
1975#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1976#[serde(rename_all = "camelCase")]
1977pub struct ToolExecutionStartToolDescriptionMetaUI {
1978    /// URI of the UI resource
1979    #[serde(skip_serializing_if = "Option::is_none")]
1980    pub resource_uri: Option<String>,
1981    /// Who can access this tool
1982    #[serde(skip_serializing_if = "Option::is_none")]
1983    pub visibility: Option<Vec<ToolExecutionStartToolDescriptionMetaUIVisibility>>,
1984}
1985
1986/// MCP Apps metadata for UI resource association
1987#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1988#[serde(rename_all = "camelCase")]
1989pub struct ToolExecutionStartToolDescriptionMeta {
1990    /// MCP Apps tool `_meta.ui` resource URI and visibility captured on `tool.execution_start`.
1991    #[serde(skip_serializing_if = "Option::is_none")]
1992    pub ui: Option<ToolExecutionStartToolDescriptionMetaUI>,
1993}
1994
1995/// Tool definition metadata, present for MCP tools with MCP Apps support
1996#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1997#[serde(rename_all = "camelCase")]
1998pub struct ToolExecutionStartToolDescription {
1999    /// MCP Apps metadata for UI resource association
2000    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
2001    pub meta: Option<ToolExecutionStartToolDescriptionMeta>,
2002    /// Tool description
2003    #[serde(skip_serializing_if = "Option::is_none")]
2004    pub description: Option<String>,
2005    /// Tool name
2006    pub name: String,
2007}
2008
2009/// Session event "tool.execution_start". Tool execution startup details including MCP server information when applicable
2010#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2011#[serde(rename_all = "camelCase")]
2012pub struct ToolExecutionStartData {
2013    /// Arguments passed to the tool
2014    #[serde(skip_serializing_if = "Option::is_none")]
2015    pub arguments: Option<serde_json::Value>,
2016    /// When true, the tool output should be displayed expanded (verbatim) in the CLI timeline
2017    #[serde(skip_serializing_if = "Option::is_none")]
2018    pub display_verbatim: Option<bool>,
2019    /// Name of the MCP server hosting this tool, when the tool is an MCP tool
2020    #[serde(skip_serializing_if = "Option::is_none")]
2021    pub mcp_server_name: Option<String>,
2022    /// Original tool name on the MCP server, when the tool is an MCP tool
2023    #[serde(skip_serializing_if = "Option::is_none")]
2024    pub mcp_tool_name: Option<String>,
2025    /// Model identifier that generated this tool call
2026    #[serde(skip_serializing_if = "Option::is_none")]
2027    pub model: Option<String>,
2028    /// Tool call ID of the parent tool invocation when this event originates from a sub-agent
2029    #[doc(hidden)]
2030    #[deprecated]
2031    #[serde(skip_serializing_if = "Option::is_none")]
2032    pub parent_tool_call_id: Option<String>,
2033    /// Shell-tool path hints derived from the command at start time for shell tools (bash/powershell/local_shell). Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. Absent for non-shell tools.
2034    #[serde(skip_serializing_if = "Option::is_none")]
2035    pub shell_tool_info: Option<ToolExecutionStartShellToolInfo>,
2036    /// Unique identifier for this tool call
2037    pub tool_call_id: String,
2038    /// Tool definition metadata, present for MCP tools with MCP Apps support
2039    #[serde(skip_serializing_if = "Option::is_none")]
2040    pub tool_description: Option<ToolExecutionStartToolDescription>,
2041    /// Name of the tool being executed
2042    pub tool_name: String,
2043    /// Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event
2044    #[serde(skip_serializing_if = "Option::is_none")]
2045    pub turn_id: Option<String>,
2046}
2047
2048/// Session event "tool.execution_partial_result". Streaming tool execution output for incremental result display
2049#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2050#[serde(rename_all = "camelCase")]
2051pub struct ToolExecutionPartialResultData {
2052    /// Incremental output chunk from the running tool
2053    pub partial_output: String,
2054    /// Tool call ID this partial result belongs to
2055    pub tool_call_id: String,
2056}
2057
2058/// Session event "tool.execution_progress". Tool execution progress notification with status message
2059#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2060#[serde(rename_all = "camelCase")]
2061pub struct ToolExecutionProgressData {
2062    /// Human-readable progress status message (e.g., from an MCP server)
2063    pub progress_message: String,
2064    /// Tool call ID this progress notification belongs to
2065    pub tool_call_id: String,
2066}
2067
2068/// Error details when the tool execution failed
2069#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2070#[serde(rename_all = "camelCase")]
2071pub struct ToolExecutionCompleteError {
2072    /// Machine-readable error code
2073    #[serde(skip_serializing_if = "Option::is_none")]
2074    pub code: Option<String>,
2075    /// Human-readable error message
2076    pub message: String,
2077}
2078
2079/// A source supplied by a tool that should be made available to the model as citable content.
2080///
2081/// <div class="warning">
2082///
2083/// **Experimental.** This type is part of an experimental wire-protocol surface
2084/// and may change or be removed in future SDK or CLI releases.
2085///
2086/// </div>
2087#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2088#[serde(rename_all = "camelCase")]
2089pub struct CitableSource {
2090    /// The source text made available to the model as citable content.
2091    pub content: String,
2092    /// Stable identifier for this source within the tool result. Used for deduplication and may be used by future provider integrations to correlate response citations back to the originating source.
2093    pub id: String,
2094    /// File path relative to the agent's workspace root, when the source is a file.
2095    #[serde(skip_serializing_if = "Option::is_none")]
2096    pub path: Option<String>,
2097    /// Human-readable title of the source.
2098    #[serde(skip_serializing_if = "Option::is_none")]
2099    pub title: Option<String>,
2100    /// URL of the source, when it is a web resource.
2101    #[serde(skip_serializing_if = "Option::is_none")]
2102    pub url: Option<String>,
2103}
2104
2105/// Plain text content block
2106#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2107#[serde(rename_all = "camelCase")]
2108pub struct ToolExecutionCompleteContentText {
2109    /// The text content
2110    pub text: String,
2111    /// Content block type discriminator
2112    pub r#type: ToolExecutionCompleteContentTextType,
2113}
2114
2115/// Deprecated for shell command exit metadata. Use ToolExecutionCompleteContentShellExit instead.
2116#[doc(hidden)]
2117#[deprecated]
2118#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2119#[serde(rename_all = "camelCase")]
2120pub struct ToolExecutionCompleteContentTerminal {
2121    /// Working directory where the command was executed
2122    #[serde(skip_serializing_if = "Option::is_none")]
2123    pub cwd: Option<String>,
2124    /// Process exit code, if the command has completed
2125    #[serde(skip_serializing_if = "Option::is_none")]
2126    pub exit_code: Option<i64>,
2127    /// Terminal/shell output text
2128    pub text: String,
2129    /// Content block type discriminator
2130    pub r#type: ToolExecutionCompleteContentTerminalType,
2131}
2132
2133/// Shell command exit metadata with optional output preview
2134#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2135#[serde(rename_all = "camelCase")]
2136pub struct ToolExecutionCompleteContentShellExit {
2137    /// Working directory where the shell command was executed
2138    #[serde(skip_serializing_if = "Option::is_none")]
2139    pub cwd: Option<String>,
2140    /// Exit code from the completed shell command
2141    pub exit_code: i64,
2142    /// Output associated with this shell command, if available. May be partial, truncated, or a preview; not guaranteed to be full output.
2143    #[serde(skip_serializing_if = "Option::is_none")]
2144    pub output_preview: Option<String>,
2145    /// Whether outputPreview is known to be incomplete or truncated
2146    #[serde(skip_serializing_if = "Option::is_none")]
2147    pub output_truncated: Option<bool>,
2148    /// Shell id, as assigned by Copilot runtime
2149    pub shell_id: String,
2150    /// Content block type discriminator
2151    pub r#type: ToolExecutionCompleteContentShellExitType,
2152}
2153
2154/// Image content block with base64-encoded data
2155#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2156#[serde(rename_all = "camelCase")]
2157pub struct ToolExecutionCompleteContentImage {
2158    /// Base64-encoded image data
2159    pub data: String,
2160    /// MIME type of the image (e.g., image/png, image/jpeg)
2161    pub mime_type: String,
2162    /// Content block type discriminator
2163    pub r#type: ToolExecutionCompleteContentImageType,
2164}
2165
2166/// Audio content block with base64-encoded data
2167#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2168#[serde(rename_all = "camelCase")]
2169pub struct ToolExecutionCompleteContentAudio {
2170    /// Base64-encoded audio data
2171    pub data: String,
2172    /// MIME type of the audio (e.g., audio/wav, audio/mpeg)
2173    pub mime_type: String,
2174    /// Content block type discriminator
2175    pub r#type: ToolExecutionCompleteContentAudioType,
2176}
2177
2178/// Icon image for a resource
2179#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2180#[serde(rename_all = "camelCase")]
2181pub struct ToolExecutionCompleteContentResourceLinkIcon {
2182    /// MIME type of the icon image
2183    #[serde(skip_serializing_if = "Option::is_none")]
2184    pub mime_type: Option<String>,
2185    /// Available icon sizes (e.g., ['16x16', '32x32'])
2186    #[serde(skip_serializing_if = "Option::is_none")]
2187    pub sizes: Option<Vec<String>>,
2188    /// URL or path to the icon image
2189    pub src: String,
2190    /// Theme variant this icon is intended for
2191    #[serde(skip_serializing_if = "Option::is_none")]
2192    pub theme: Option<ToolExecutionCompleteContentResourceLinkIconTheme>,
2193}
2194
2195/// Resource link content block referencing an external resource
2196#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2197#[serde(rename_all = "camelCase")]
2198pub struct ToolExecutionCompleteContentResourceLink {
2199    /// Human-readable description of the resource
2200    #[serde(skip_serializing_if = "Option::is_none")]
2201    pub description: Option<String>,
2202    /// Icons associated with this resource
2203    #[serde(skip_serializing_if = "Option::is_none")]
2204    pub icons: Option<Vec<ToolExecutionCompleteContentResourceLinkIcon>>,
2205    /// MIME type of the resource content
2206    #[serde(skip_serializing_if = "Option::is_none")]
2207    pub mime_type: Option<String>,
2208    /// Resource name identifier
2209    pub name: String,
2210    /// Size of the resource in bytes
2211    #[serde(skip_serializing_if = "Option::is_none")]
2212    pub size: Option<i64>,
2213    /// Human-readable display title for the resource
2214    #[serde(skip_serializing_if = "Option::is_none")]
2215    pub title: Option<String>,
2216    /// Content block type discriminator
2217    pub r#type: ToolExecutionCompleteContentResourceLinkType,
2218    /// URI identifying the resource
2219    pub uri: String,
2220}
2221
2222/// Embedded text resource contents identified by a URI, with an optional MIME type and a text payload.
2223#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2224#[serde(rename_all = "camelCase")]
2225pub struct EmbeddedTextResourceContents {
2226    /// MIME type of the text content
2227    #[serde(skip_serializing_if = "Option::is_none")]
2228    pub mime_type: Option<String>,
2229    /// Text content of the resource
2230    pub text: String,
2231    /// URI identifying the resource
2232    pub uri: String,
2233}
2234
2235/// Embedded binary resource contents identified by a URI, with an optional MIME type and a base64-encoded blob.
2236#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2237#[serde(rename_all = "camelCase")]
2238pub struct EmbeddedBlobResourceContents {
2239    /// Base64-encoded binary content of the resource
2240    pub blob: String,
2241    /// MIME type of the blob content
2242    #[serde(skip_serializing_if = "Option::is_none")]
2243    pub mime_type: Option<String>,
2244    /// URI identifying the resource
2245    pub uri: String,
2246}
2247
2248/// Embedded resource content block with inline text or binary data
2249#[derive(Debug, Clone, Serialize, Deserialize)]
2250#[serde(rename_all = "camelCase")]
2251pub struct ToolExecutionCompleteContentResource {
2252    /// The embedded resource contents, either text or base64-encoded binary
2253    pub resource: ToolExecutionCompleteContentResourceDetails,
2254    /// Content block type discriminator
2255    pub r#type: ToolExecutionCompleteContentResourceType,
2256}
2257
2258/// CSP domain allowlists for an MCP Apps UI resource, including connect, resource, frame, and base URI domains.
2259#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2260#[serde(rename_all = "camelCase")]
2261pub struct ToolExecutionCompleteUIResourceMetaUICsp {
2262    #[serde(skip_serializing_if = "Option::is_none")]
2263    pub base_uri_domains: Option<Vec<String>>,
2264    #[serde(skip_serializing_if = "Option::is_none")]
2265    pub connect_domains: Option<Vec<String>>,
2266    #[serde(skip_serializing_if = "Option::is_none")]
2267    pub frame_domains: Option<Vec<String>>,
2268    #[serde(skip_serializing_if = "Option::is_none")]
2269    pub resource_domains: Option<Vec<String>>,
2270}
2271
2272/// Marker object for camera permission on an MCP Apps UI resource.
2273#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2274#[serde(rename_all = "camelCase")]
2275pub struct ToolExecutionCompleteUIResourceMetaUIPermissionsCamera {}
2276
2277/// Marker object for clipboard-write permission on an MCP Apps UI resource.
2278#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2279#[serde(rename_all = "camelCase")]
2280pub struct ToolExecutionCompleteUIResourceMetaUIPermissionsClipboardWrite {}
2281
2282/// Marker object for geolocation permission on an MCP Apps UI resource.
2283#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2284#[serde(rename_all = "camelCase")]
2285pub struct ToolExecutionCompleteUIResourceMetaUIPermissionsGeolocation {}
2286
2287/// Marker object for microphone permission on an MCP Apps UI resource.
2288#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2289#[serde(rename_all = "camelCase")]
2290pub struct ToolExecutionCompleteUIResourceMetaUIPermissionsMicrophone {}
2291
2292/// Browser permission metadata for an MCP Apps UI resource, including camera, microphone, geolocation, and clipboard-write.
2293#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2294#[serde(rename_all = "camelCase")]
2295pub struct ToolExecutionCompleteUIResourceMetaUIPermissions {
2296    /// Marker object for camera permission on an MCP Apps UI resource.
2297    #[serde(skip_serializing_if = "Option::is_none")]
2298    pub camera: Option<ToolExecutionCompleteUIResourceMetaUIPermissionsCamera>,
2299    /// Marker object for clipboard-write permission on an MCP Apps UI resource.
2300    #[serde(skip_serializing_if = "Option::is_none")]
2301    pub clipboard_write: Option<ToolExecutionCompleteUIResourceMetaUIPermissionsClipboardWrite>,
2302    /// Marker object for geolocation permission on an MCP Apps UI resource.
2303    #[serde(skip_serializing_if = "Option::is_none")]
2304    pub geolocation: Option<ToolExecutionCompleteUIResourceMetaUIPermissionsGeolocation>,
2305    /// Marker object for microphone permission on an MCP Apps UI resource.
2306    #[serde(skip_serializing_if = "Option::is_none")]
2307    pub microphone: Option<ToolExecutionCompleteUIResourceMetaUIPermissionsMicrophone>,
2308}
2309
2310/// MCP Apps UI resource metadata for a completed tool result, including CSP, permissions, domain, and border preference.
2311#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2312#[serde(rename_all = "camelCase")]
2313pub struct ToolExecutionCompleteUIResourceMetaUI {
2314    /// CSP domain allowlists for an MCP Apps UI resource, including connect, resource, frame, and base URI domains.
2315    #[serde(skip_serializing_if = "Option::is_none")]
2316    pub csp: Option<ToolExecutionCompleteUIResourceMetaUICsp>,
2317    #[serde(skip_serializing_if = "Option::is_none")]
2318    pub domain: Option<String>,
2319    /// Browser permission metadata for an MCP Apps UI resource, including camera, microphone, geolocation, and clipboard-write.
2320    #[serde(skip_serializing_if = "Option::is_none")]
2321    pub permissions: Option<ToolExecutionCompleteUIResourceMetaUIPermissions>,
2322    #[serde(skip_serializing_if = "Option::is_none")]
2323    pub prefers_border: Option<bool>,
2324}
2325
2326/// Resource-level UI metadata (CSP, permissions, visual preferences)
2327#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2328#[serde(rename_all = "camelCase")]
2329pub struct ToolExecutionCompleteUIResourceMeta {
2330    /// MCP Apps UI resource metadata for a completed tool result, including CSP, permissions, domain, and border preference.
2331    #[serde(skip_serializing_if = "Option::is_none")]
2332    pub ui: Option<ToolExecutionCompleteUIResourceMetaUI>,
2333}
2334
2335/// MCP Apps UI resource content for rendering in a sandboxed iframe
2336#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2337#[serde(rename_all = "camelCase")]
2338pub struct ToolExecutionCompleteUIResource {
2339    /// Resource-level UI metadata (CSP, permissions, visual preferences)
2340    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
2341    pub meta: Option<ToolExecutionCompleteUIResourceMeta>,
2342    /// Base64-encoded HTML content
2343    #[serde(skip_serializing_if = "Option::is_none")]
2344    pub blob: Option<String>,
2345    /// MIME type of the content
2346    pub mime_type: String,
2347    /// HTML content as a string
2348    #[serde(skip_serializing_if = "Option::is_none")]
2349    pub text: Option<String>,
2350    /// The ui:// URI of the resource
2351    pub uri: String,
2352}
2353
2354/// Tool execution result on success
2355#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2356#[serde(rename_all = "camelCase")]
2357pub struct ToolExecutionCompleteResult {
2358    /// Model-facing binary results (base64 inline or size-omitted markers) sent to the LLM for this tool call
2359    ///
2360    /// <div class="warning">
2361    ///
2362    /// **Experimental.** This type is part of an experimental wire-protocol surface
2363    /// and may change or be removed in future SDK or CLI releases.
2364    ///
2365    /// </div>
2366    #[serde(skip_serializing_if = "Option::is_none")]
2367    pub binary_results_for_llm: Option<Vec<serde_json::Value>>,
2368    /// Provider-neutral source material this tool makes available to the model as citable content. Persisted so it survives session resume. Experimental.
2369    ///
2370    /// <div class="warning">
2371    ///
2372    /// **Experimental.** This type is part of an experimental wire-protocol surface
2373    /// and may change or be removed in future SDK or CLI releases.
2374    ///
2375    /// </div>
2376    #[serde(skip_serializing_if = "Option::is_none")]
2377    pub citable_sources: Option<Vec<CitableSource>>,
2378    /// Concise tool result text sent to the LLM for chat completion, potentially truncated for token efficiency
2379    pub content: String,
2380    /// Structured content blocks (text, images, audio, resources) returned by the tool in their native format
2381    #[serde(skip_serializing_if = "Option::is_none")]
2382    pub contents: Option<Vec<ToolExecutionCompleteContent>>,
2383    /// Full detailed tool result for UI/timeline display, preserving complete content such as diffs. Falls back to content when absent.
2384    #[serde(skip_serializing_if = "Option::is_none")]
2385    pub detailed_content: Option<String>,
2386    /// Structured content (arbitrary JSON) returned verbatim by the MCP tool
2387    #[serde(skip_serializing_if = "Option::is_none")]
2388    pub structured_content: Option<serde_json::Value>,
2389    /// MCP Apps UI resource content for rendering in a sandboxed iframe
2390    #[serde(skip_serializing_if = "Option::is_none")]
2391    pub ui_resource: Option<ToolExecutionCompleteUIResource>,
2392}
2393
2394/// MCP Apps tool `_meta.ui` resource URI and visibility captured on `tool.execution_complete`.
2395#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2396#[serde(rename_all = "camelCase")]
2397pub struct ToolExecutionCompleteToolDescriptionMetaUI {
2398    /// URI of the UI resource
2399    #[serde(skip_serializing_if = "Option::is_none")]
2400    pub resource_uri: Option<String>,
2401    /// Who can access this tool
2402    #[serde(skip_serializing_if = "Option::is_none")]
2403    pub visibility: Option<Vec<ToolExecutionCompleteToolDescriptionMetaUIVisibility>>,
2404}
2405
2406/// MCP Apps metadata for UI resource association
2407#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2408#[serde(rename_all = "camelCase")]
2409pub struct ToolExecutionCompleteToolDescriptionMeta {
2410    /// MCP Apps tool `_meta.ui` resource URI and visibility captured on `tool.execution_complete`.
2411    #[serde(skip_serializing_if = "Option::is_none")]
2412    pub ui: Option<ToolExecutionCompleteToolDescriptionMetaUI>,
2413}
2414
2415/// Tool definition metadata, present for MCP tools with MCP Apps support
2416#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2417#[serde(rename_all = "camelCase")]
2418pub struct ToolExecutionCompleteToolDescription {
2419    /// MCP Apps metadata for UI resource association
2420    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
2421    pub meta: Option<ToolExecutionCompleteToolDescriptionMeta>,
2422    /// Tool description
2423    #[serde(skip_serializing_if = "Option::is_none")]
2424    pub description: Option<String>,
2425    /// Tool name
2426    pub name: String,
2427}
2428
2429/// Session event "tool.execution_complete". Tool execution completion results including success status, detailed output, and error information
2430#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2431#[serde(rename_all = "camelCase")]
2432pub struct ToolExecutionCompleteData {
2433    /// Error details when the tool execution failed
2434    #[serde(skip_serializing_if = "Option::is_none")]
2435    pub error: Option<ToolExecutionCompleteError>,
2436    /// CAPI interaction ID for correlating this tool execution with upstream telemetry
2437    #[serde(skip_serializing_if = "Option::is_none")]
2438    pub interaction_id: Option<String>,
2439    /// Whether this tool call was explicitly requested by the user rather than the assistant
2440    #[serde(skip_serializing_if = "Option::is_none")]
2441    pub is_user_requested: Option<bool>,
2442    /// Model identifier that generated this tool call
2443    #[serde(skip_serializing_if = "Option::is_none")]
2444    pub model: Option<String>,
2445    /// Tool call ID of the parent tool invocation when this event originates from a sub-agent
2446    #[doc(hidden)]
2447    #[deprecated]
2448    #[serde(skip_serializing_if = "Option::is_none")]
2449    pub parent_tool_call_id: Option<String>,
2450    /// Tool execution result on success
2451    #[serde(skip_serializing_if = "Option::is_none")]
2452    pub result: Option<ToolExecutionCompleteResult>,
2453    /// Whether this tool execution ran inside a sandbox container
2454    #[serde(skip_serializing_if = "Option::is_none")]
2455    pub sandboxed: Option<bool>,
2456    /// Whether the tool execution completed successfully
2457    pub success: bool,
2458    /// Unique identifier for the completed tool call
2459    pub tool_call_id: String,
2460    /// Tool definition metadata, present for MCP tools with MCP Apps support
2461    #[serde(skip_serializing_if = "Option::is_none")]
2462    pub tool_description: Option<ToolExecutionCompleteToolDescription>,
2463    /// Tool-specific telemetry data (e.g., CodeQL check counts, grep match counts)
2464    #[serde(skip_serializing_if = "Option::is_none")]
2465    pub tool_telemetry: Option<HashMap<String, serde_json::Value>>,
2466    /// Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event
2467    #[serde(skip_serializing_if = "Option::is_none")]
2468    pub turn_id: Option<String>,
2469}
2470
2471/// Session event "skill.invoked". Skill invocation details including content, allowed tools, and plugin metadata
2472#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2473#[serde(rename_all = "camelCase")]
2474pub struct SkillInvokedData {
2475    /// Tool names that should be auto-approved when this skill is active
2476    #[serde(skip_serializing_if = "Option::is_none")]
2477    pub allowed_tools: Option<Vec<String>>,
2478    /// Full content of the skill file, injected into the conversation for the model
2479    pub content: String,
2480    /// Description of the skill from its SKILL.md frontmatter
2481    #[serde(skip_serializing_if = "Option::is_none")]
2482    pub description: Option<String>,
2483    /// Model identifier active when the skill was invoked, when known
2484    #[serde(skip_serializing_if = "Option::is_none")]
2485    pub model: Option<String>,
2486    /// Name of the invoked skill
2487    pub name: String,
2488    /// File path to the SKILL.md definition
2489    pub path: String,
2490    /// Name of the plugin this skill originated from, when applicable
2491    #[serde(skip_serializing_if = "Option::is_none")]
2492    pub plugin_name: Option<String>,
2493    /// Version of the plugin this skill originated from, when applicable
2494    #[serde(skip_serializing_if = "Option::is_none")]
2495    pub plugin_version: Option<String>,
2496    /// Source identifier for where the skill was discovered. Known values include: project (workspace skill), inherited (parent-directory skill), personal-copilot (~/.copilot/skills), personal-agents (~/.agents/skills), custom (configured directory), plugin (installed plugin), builtin (bundled runtime skill), and remote (org/enterprise skill)
2497    #[serde(skip_serializing_if = "Option::is_none")]
2498    pub source: Option<String>,
2499    /// What triggered the skill invocation: `user-invoked` (explicit user action, such as via a slash command or UI affordance), `agent-invoked` (agent requested the skill), or `context-load` (loaded as part of another context, such as preloading skills configured on a custom agent or subagent)
2500    #[serde(skip_serializing_if = "Option::is_none")]
2501    pub trigger: Option<SkillInvokedTrigger>,
2502}
2503
2504/// Session event "subagent.started". Sub-agent startup details including parent tool call and agent information
2505#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2506#[serde(rename_all = "camelCase")]
2507pub struct SubagentStartedData {
2508    /// Description of what the sub-agent does
2509    pub agent_description: String,
2510    /// Human-readable display name of the sub-agent
2511    pub agent_display_name: String,
2512    /// Internal name of the sub-agent
2513    pub agent_name: String,
2514    /// Model the sub-agent will run with, when known at start.
2515    #[serde(skip_serializing_if = "Option::is_none")]
2516    pub model: Option<String>,
2517    /// Tool call ID of the parent tool invocation that spawned this sub-agent
2518    pub tool_call_id: String,
2519}
2520
2521/// Session event "subagent.completed". Sub-agent completion details for successful execution
2522#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2523#[serde(rename_all = "camelCase")]
2524pub struct SubagentCompletedData {
2525    /// Human-readable display name of the sub-agent
2526    pub agent_display_name: String,
2527    /// Internal name of the sub-agent
2528    pub agent_name: String,
2529    /// Wall-clock duration of the sub-agent execution in milliseconds
2530    #[serde(skip_serializing_if = "Option::is_none")]
2531    pub duration_ms: Option<i64>,
2532    /// Model used by the sub-agent
2533    #[serde(skip_serializing_if = "Option::is_none")]
2534    pub model: Option<String>,
2535    /// Tool call ID of the parent tool invocation that spawned this sub-agent
2536    pub tool_call_id: String,
2537    /// Total tokens (input + output) consumed by the sub-agent
2538    #[serde(skip_serializing_if = "Option::is_none")]
2539    pub total_tokens: Option<i64>,
2540    /// Total number of tool calls made by the sub-agent
2541    #[serde(skip_serializing_if = "Option::is_none")]
2542    pub total_tool_calls: Option<i64>,
2543}
2544
2545/// Session event "subagent.failed". Sub-agent failure details including error message and agent information
2546#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2547#[serde(rename_all = "camelCase")]
2548pub struct SubagentFailedData {
2549    /// Human-readable display name of the sub-agent
2550    pub agent_display_name: String,
2551    /// Internal name of the sub-agent
2552    pub agent_name: String,
2553    /// Wall-clock duration of the sub-agent execution in milliseconds
2554    #[serde(skip_serializing_if = "Option::is_none")]
2555    pub duration_ms: Option<i64>,
2556    /// Error message describing why the sub-agent failed
2557    pub error: String,
2558    /// Model selected for the sub-agent, when known
2559    #[serde(skip_serializing_if = "Option::is_none")]
2560    pub model: Option<String>,
2561    /// Tool call ID of the parent tool invocation that spawned this sub-agent
2562    pub tool_call_id: String,
2563    /// Total tokens (input + output) consumed before the sub-agent failed
2564    #[serde(skip_serializing_if = "Option::is_none")]
2565    pub total_tokens: Option<i64>,
2566    /// Total number of tool calls made before the sub-agent failed
2567    #[serde(skip_serializing_if = "Option::is_none")]
2568    pub total_tool_calls: Option<i64>,
2569}
2570
2571/// Session event "subagent.selected". Custom agent selection details including name and available tools
2572#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2573#[serde(rename_all = "camelCase")]
2574pub struct SubagentSelectedData {
2575    /// Human-readable display name of the selected custom agent
2576    pub agent_display_name: String,
2577    /// Internal name of the selected custom agent
2578    pub agent_name: String,
2579    /// List of tool names available to this agent, or null for all tools
2580    pub tools: Option<Vec<String>>,
2581}
2582
2583/// Session event "subagent.deselected". Empty payload; the event signals that the custom agent was deselected, returning to the default agent
2584#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2585#[serde(rename_all = "camelCase")]
2586pub struct SubagentDeselectedData {}
2587
2588/// Session event "hook.start". Hook invocation start details including type and input data
2589#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2590#[serde(rename_all = "camelCase")]
2591pub struct HookStartData {
2592    /// Unique identifier for this hook invocation
2593    pub hook_invocation_id: String,
2594    /// Type of hook being invoked (e.g., "preToolUse", "postToolUse", "sessionStart")
2595    pub hook_type: String,
2596    /// Input data passed to the hook
2597    #[serde(skip_serializing_if = "Option::is_none")]
2598    pub input: Option<serde_json::Value>,
2599}
2600
2601/// Error details when the hook failed
2602#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2603#[serde(rename_all = "camelCase")]
2604pub struct HookEndError {
2605    /// Human-readable error message
2606    pub message: String,
2607    /// Source label of the hook that errored (e.g. the plugin it was loaded from), when known
2608    #[serde(skip_serializing_if = "Option::is_none")]
2609    pub source: Option<String>,
2610    /// Error stack trace, when available
2611    #[serde(skip_serializing_if = "Option::is_none")]
2612    pub stack: Option<String>,
2613}
2614
2615/// Session event "hook.end". Hook invocation completion details including output, success status, and error information
2616#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2617#[serde(rename_all = "camelCase")]
2618pub struct HookEndData {
2619    /// Error details when the hook failed
2620    #[serde(skip_serializing_if = "Option::is_none")]
2621    pub error: Option<HookEndError>,
2622    /// Identifier matching the corresponding hook.start event
2623    pub hook_invocation_id: String,
2624    /// Type of hook that was invoked (e.g., "preToolUse", "postToolUse", "sessionStart")
2625    pub hook_type: String,
2626    /// Output data produced by the hook
2627    #[serde(skip_serializing_if = "Option::is_none")]
2628    pub output: Option<serde_json::Value>,
2629    /// Whether the hook completed successfully
2630    pub success: bool,
2631}
2632
2633/// Session event "hook.progress". Ephemeral progress update from a running hook process
2634#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2635#[serde(rename_all = "camelCase")]
2636pub struct HookProgressData {
2637    /// Human-readable progress message from the hook process
2638    pub message: String,
2639    /// When true, this status message replaces the previous temporary one instead of accumulating
2640    #[serde(skip_serializing_if = "Option::is_none")]
2641    pub temporary: Option<bool>,
2642}
2643
2644/// Session event "session.binary_asset". Canonical bytes for a content-addressed binary asset shared by reference across events
2645#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2646#[serde(rename_all = "camelCase")]
2647pub struct SessionBinaryAssetData {
2648    /// Content-addressed id for this binary asset (e.g. "sha256:...").
2649    pub asset_id: String,
2650    /// Decoded byte length of the binary asset
2651    pub byte_length: i64,
2652    /// Base64-encoded binary data
2653    pub data: String,
2654    /// Human-readable description of the binary data
2655    #[serde(skip_serializing_if = "Option::is_none")]
2656    pub description: Option<String>,
2657    /// Optional metadata from the producing tool.
2658    #[serde(skip_serializing_if = "Option::is_none")]
2659    pub metadata: Option<HashMap<String, serde_json::Value>>,
2660    /// MIME type of the binary asset
2661    pub mime_type: String,
2662    /// Binary asset type discriminator. Use "image" for images and "resource" otherwise.
2663    pub r#type: BinaryAssetType,
2664}
2665
2666/// Metadata about the prompt template and its construction
2667#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2668#[serde(rename_all = "camelCase")]
2669pub struct SystemMessageMetadata {
2670    /// Version identifier of the prompt template used
2671    #[serde(skip_serializing_if = "Option::is_none")]
2672    pub prompt_version: Option<String>,
2673    /// Template variables used when constructing the prompt
2674    #[serde(skip_serializing_if = "Option::is_none")]
2675    pub variables: Option<HashMap<String, serde_json::Value>>,
2676}
2677
2678/// Session event "system.message". System/developer instruction content with role and optional template metadata
2679#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2680#[serde(rename_all = "camelCase")]
2681pub struct SystemMessageData {
2682    /// The system or developer prompt text sent as model input
2683    pub content: String,
2684    /// Metadata about the prompt template and its construction
2685    #[serde(skip_serializing_if = "Option::is_none")]
2686    pub metadata: Option<SystemMessageMetadata>,
2687    /// Optional name identifier for the message source
2688    #[serde(skip_serializing_if = "Option::is_none")]
2689    pub name: Option<String>,
2690    /// Message role: "system" for system prompts, "developer" for developer-injected instructions
2691    pub role: SystemMessageRole,
2692}
2693
2694/// Session event "system.notification". System-generated notification for runtime events like background task completion
2695#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2696#[serde(rename_all = "camelCase")]
2697pub struct SystemNotificationData {
2698    /// The notification text, typically wrapped in <system_notification> XML tags
2699    pub content: String,
2700    /// Structured metadata identifying what triggered this notification
2701    pub kind: serde_json::Value,
2702}
2703
2704/// A parsed command identifier in a shell permission request, including whether it is read-only.
2705#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2706#[serde(rename_all = "camelCase")]
2707pub struct PermissionRequestShellCommand {
2708    /// Command identifier (e.g., executable name)
2709    pub identifier: String,
2710    /// Whether this command is read-only (no side effects)
2711    pub read_only: bool,
2712}
2713
2714/// A URL that may be accessed by a command in a shell permission request.
2715#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2716#[serde(rename_all = "camelCase")]
2717pub struct PermissionRequestShellPossibleUrl {
2718    /// URL that may be accessed by the command
2719    pub url: String,
2720}
2721
2722/// Shell command permission request
2723#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2724#[serde(rename_all = "camelCase")]
2725pub struct PermissionRequestShell {
2726    /// Whether the UI can offer session-wide approval for this command pattern
2727    pub can_offer_session_approval: bool,
2728    /// Parsed command identifiers found in the command text
2729    pub commands: Vec<PermissionRequestShellCommand>,
2730    /// The complete shell command text to be executed
2731    pub full_command_text: String,
2732    /// Whether the command includes a file write redirection (e.g., > or >>)
2733    pub has_write_file_redirection: bool,
2734    /// Human-readable description of what the command intends to do
2735    pub intention: String,
2736    /// Permission kind discriminator
2737    pub kind: PermissionRequestShellKind,
2738    /// File paths that may be read or written by the command
2739    pub possible_paths: Vec<String>,
2740    /// URLs that may be accessed by the command
2741    pub possible_urls: Vec<PermissionRequestShellPossibleUrl>,
2742    /// True when the model has requested to run this command outside the sandbox (it set requestSandboxBypass: true and the host opted in via sandbox.allowBypass). This is a request, not a grant: the command runs unsandboxed only if the user approves this permission request. Hosts should highlight the elevated risk in the approval UI.
2743    #[serde(skip_serializing_if = "Option::is_none")]
2744    pub request_sandbox_bypass: Option<bool>,
2745    /// Model-provided justification for the sandbox-bypass request. Only meaningful when requestSandboxBypass is true.
2746    #[serde(skip_serializing_if = "Option::is_none")]
2747    pub request_sandbox_bypass_reason: Option<String>,
2748    /// Tool call ID that triggered this permission request
2749    #[serde(skip_serializing_if = "Option::is_none")]
2750    pub tool_call_id: Option<String>,
2751    /// Optional warning message about risks of running this command
2752    #[serde(skip_serializing_if = "Option::is_none")]
2753    pub warning: Option<String>,
2754}
2755
2756/// File write permission request
2757#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2758#[serde(rename_all = "camelCase")]
2759pub struct PermissionRequestWrite {
2760    /// Whether the UI can offer session-wide approval for file write operations
2761    pub can_offer_session_approval: bool,
2762    /// Unified diff showing the proposed changes
2763    pub diff: String,
2764    /// Path of the file being written to
2765    pub file_name: String,
2766    /// Human-readable description of the intended file change
2767    pub intention: String,
2768    /// Permission kind discriminator
2769    pub kind: PermissionRequestWriteKind,
2770    /// Complete new file contents for newly created files
2771    #[serde(skip_serializing_if = "Option::is_none")]
2772    pub new_file_contents: Option<String>,
2773    /// True when a built-in file tool (apply_patch / str_replace_editor) asked to write a path the sandbox filesystem policy would block, and the host opted in via sandbox.allowBypass. This is a request, not a grant: the write happens unsandboxed only if the user approves this permission request. Hosts should highlight the elevated risk in the approval UI.
2774    #[serde(skip_serializing_if = "Option::is_none")]
2775    pub request_sandbox_bypass: Option<bool>,
2776    /// Justification for the sandbox-bypass request. Only meaningful when requestSandboxBypass is true.
2777    #[serde(skip_serializing_if = "Option::is_none")]
2778    pub request_sandbox_bypass_reason: Option<String>,
2779    /// Tool call ID that triggered this permission request
2780    #[serde(skip_serializing_if = "Option::is_none")]
2781    pub tool_call_id: Option<String>,
2782}
2783
2784/// File or directory read permission request
2785#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2786#[serde(rename_all = "camelCase")]
2787pub struct PermissionRequestRead {
2788    /// Human-readable description of why the file is being read
2789    pub intention: String,
2790    /// Permission kind discriminator
2791    pub kind: PermissionRequestReadKind,
2792    /// Path of the file or directory being read
2793    pub path: String,
2794    /// True when the model has requested to run this search outside the sandbox (it set requestSandboxBypass: true and the host opted in via sandbox.allowBypass). This is a request, not a grant: the search runs unsandboxed only if the user approves this permission request. Hosts should highlight the elevated risk in the approval UI.
2795    #[serde(skip_serializing_if = "Option::is_none")]
2796    pub request_sandbox_bypass: Option<bool>,
2797    /// Model-provided justification for the sandbox-bypass request. Only meaningful when requestSandboxBypass is true.
2798    #[serde(skip_serializing_if = "Option::is_none")]
2799    pub request_sandbox_bypass_reason: Option<String>,
2800    /// Tool call ID that triggered this permission request
2801    #[serde(skip_serializing_if = "Option::is_none")]
2802    pub tool_call_id: Option<String>,
2803}
2804
2805/// MCP tool invocation permission request
2806#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2807#[serde(rename_all = "camelCase")]
2808pub struct PermissionRequestMcp {
2809    /// Arguments to pass to the MCP tool
2810    #[serde(skip_serializing_if = "Option::is_none")]
2811    pub args: Option<serde_json::Value>,
2812    /// Permission kind discriminator
2813    pub kind: PermissionRequestMcpKind,
2814    /// Whether this MCP tool is read-only (no side effects)
2815    pub read_only: bool,
2816    /// Name of the MCP server providing the tool
2817    pub server_name: String,
2818    /// Tool call ID that triggered this permission request
2819    #[serde(skip_serializing_if = "Option::is_none")]
2820    pub tool_call_id: Option<String>,
2821    /// Internal name of the MCP tool
2822    pub tool_name: String,
2823    /// Human-readable title of the MCP tool
2824    pub tool_title: String,
2825}
2826
2827/// URL access permission request
2828#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2829#[serde(rename_all = "camelCase")]
2830pub struct PermissionRequestUrl {
2831    /// Human-readable description of why the URL is being accessed
2832    pub intention: String,
2833    /// Permission kind discriminator
2834    pub kind: PermissionRequestUrlKind,
2835    /// True when this URL fetch is requesting to bypass the sandbox network policy: either the model set requestSandboxBypass: true, or the tool re-issued the request as an interactive bypass after the network policy denied the approved URL (host opted in via sandbox.allowBypass). This is a request, not a grant: the fetch runs only if the user approves this permission request. Hosts should highlight the elevated risk in the approval UI.
2836    #[serde(skip_serializing_if = "Option::is_none")]
2837    pub request_sandbox_bypass: Option<bool>,
2838    /// Model-provided justification for the sandbox-bypass request. Only meaningful when requestSandboxBypass is true.
2839    #[serde(skip_serializing_if = "Option::is_none")]
2840    pub request_sandbox_bypass_reason: Option<String>,
2841    /// Tool call ID that triggered this permission request
2842    #[serde(skip_serializing_if = "Option::is_none")]
2843    pub tool_call_id: Option<String>,
2844    /// URL to be fetched
2845    pub url: String,
2846}
2847
2848/// Memory operation permission request
2849#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2850#[serde(rename_all = "camelCase")]
2851pub struct PermissionRequestMemory {
2852    /// Whether this is a store or vote memory operation
2853    #[serde(skip_serializing_if = "Option::is_none")]
2854    pub action: Option<PermissionRequestMemoryAction>,
2855    /// Source references for the stored fact (store only)
2856    #[serde(skip_serializing_if = "Option::is_none")]
2857    pub citations: Option<String>,
2858    /// Vote direction (vote only)
2859    #[serde(skip_serializing_if = "Option::is_none")]
2860    pub direction: Option<PermissionRequestMemoryDirection>,
2861    /// The fact being stored or voted on
2862    pub fact: String,
2863    /// Permission kind discriminator
2864    pub kind: PermissionRequestMemoryKind,
2865    /// Reason for the vote (vote only)
2866    #[serde(skip_serializing_if = "Option::is_none")]
2867    pub reason: Option<String>,
2868    /// Topic or subject of the memory (store only)
2869    #[serde(skip_serializing_if = "Option::is_none")]
2870    pub subject: Option<String>,
2871    /// Tool call ID that triggered this permission request
2872    #[serde(skip_serializing_if = "Option::is_none")]
2873    pub tool_call_id: Option<String>,
2874}
2875
2876/// Custom tool invocation permission request
2877#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2878#[serde(rename_all = "camelCase")]
2879pub struct PermissionRequestCustomTool {
2880    /// Arguments to pass to the custom tool
2881    #[serde(skip_serializing_if = "Option::is_none")]
2882    pub args: Option<serde_json::Value>,
2883    /// Permission kind discriminator
2884    pub kind: PermissionRequestCustomToolKind,
2885    /// Tool call ID that triggered this permission request
2886    #[serde(skip_serializing_if = "Option::is_none")]
2887    pub tool_call_id: Option<String>,
2888    /// Description of what the custom tool does
2889    pub tool_description: String,
2890    /// Name of the custom tool
2891    pub tool_name: String,
2892}
2893
2894/// Hook confirmation permission request
2895#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2896#[serde(rename_all = "camelCase")]
2897pub struct PermissionRequestHook {
2898    /// Optional message from the hook explaining why confirmation is needed
2899    #[serde(skip_serializing_if = "Option::is_none")]
2900    pub hook_message: Option<String>,
2901    /// Permission kind discriminator
2902    pub kind: PermissionRequestHookKind,
2903    /// Arguments of the tool call being gated
2904    #[serde(skip_serializing_if = "Option::is_none")]
2905    pub tool_args: Option<serde_json::Value>,
2906    /// Tool call ID that triggered this permission request
2907    #[serde(skip_serializing_if = "Option::is_none")]
2908    pub tool_call_id: Option<String>,
2909    /// Name of the tool the hook is gating
2910    pub tool_name: String,
2911}
2912
2913/// Extension management permission request
2914#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2915#[serde(rename_all = "camelCase")]
2916pub struct PermissionRequestExtensionManagement {
2917    /// Name of the extension being managed
2918    #[serde(skip_serializing_if = "Option::is_none")]
2919    pub extension_name: Option<String>,
2920    /// Permission kind discriminator
2921    pub kind: PermissionRequestExtensionManagementKind,
2922    /// The extension management operation (scaffold, reload)
2923    pub operation: String,
2924    /// Tool call ID that triggered this permission request
2925    #[serde(skip_serializing_if = "Option::is_none")]
2926    pub tool_call_id: Option<String>,
2927}
2928
2929/// Extension permission access request
2930#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2931#[serde(rename_all = "camelCase")]
2932pub struct PermissionRequestExtensionPermissionAccess {
2933    /// Capabilities the extension is requesting
2934    pub capabilities: Vec<String>,
2935    /// Name of the extension requesting permission access
2936    pub extension_name: String,
2937    /// Permission kind discriminator
2938    pub kind: PermissionRequestExtensionPermissionAccessKind,
2939    /// Tool call ID that triggered this permission request
2940    #[serde(skip_serializing_if = "Option::is_none")]
2941    pub tool_call_id: Option<String>,
2942}
2943
2944/// Auto-approval judge information attached to a permission request. Present (non-null) only when the session's allow-all mode is "auto"; its absence means auto mode was off and the judge did not evaluate the request. The `recommendation` conveys the judge's disposition for this request.
2945///
2946/// <div class="warning">
2947///
2948/// **Experimental.** This type is part of an experimental wire-protocol surface
2949/// and may change or be removed in future SDK or CLI releases.
2950///
2951/// </div>
2952#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2953#[serde(rename_all = "camelCase")]
2954pub struct PermissionAutoApproval {
2955    /// Human-readable reason for the judge's recommendation, when available.
2956    #[serde(skip_serializing_if = "Option::is_none")]
2957    pub reason: Option<String>,
2958    /// The auto-approval safety judge's outcome for this request.
2959    pub recommendation: AutoApprovalRecommendation,
2960}
2961
2962/// Shell command permission prompt
2963#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2964#[serde(rename_all = "camelCase")]
2965pub struct PermissionPromptRequestCommands {
2966    /// Auto-approval judge information for this request; present only when auto mode is enabled.
2967    ///
2968    /// <div class="warning">
2969    ///
2970    /// **Experimental.** This type is part of an experimental wire-protocol surface
2971    /// and may change or be removed in future SDK or CLI releases.
2972    ///
2973    /// </div>
2974    #[serde(skip_serializing_if = "Option::is_none")]
2975    pub auto_approval: Option<PermissionAutoApproval>,
2976    /// Whether the UI can offer session-wide approval for this command pattern
2977    pub can_offer_session_approval: bool,
2978    /// Command identifiers covered by this approval prompt
2979    pub command_identifiers: Vec<String>,
2980    /// The complete shell command text to be executed
2981    pub full_command_text: String,
2982    /// Human-readable description of what the command intends to do
2983    pub intention: String,
2984    /// Prompt kind discriminator
2985    pub kind: PermissionPromptRequestCommandsKind,
2986    /// Tool call ID that triggered this permission request
2987    #[serde(skip_serializing_if = "Option::is_none")]
2988    pub tool_call_id: Option<String>,
2989    /// Optional warning message about risks of running this command
2990    #[serde(skip_serializing_if = "Option::is_none")]
2991    pub warning: Option<String>,
2992}
2993
2994/// File write permission prompt
2995#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2996#[serde(rename_all = "camelCase")]
2997pub struct PermissionPromptRequestWrite {
2998    /// Auto-approval judge information for this request; present only when auto mode is enabled.
2999    ///
3000    /// <div class="warning">
3001    ///
3002    /// **Experimental.** This type is part of an experimental wire-protocol surface
3003    /// and may change or be removed in future SDK or CLI releases.
3004    ///
3005    /// </div>
3006    #[serde(skip_serializing_if = "Option::is_none")]
3007    pub auto_approval: Option<PermissionAutoApproval>,
3008    /// Whether the UI can offer session-wide approval for file write operations
3009    pub can_offer_session_approval: bool,
3010    /// Unified diff showing the proposed changes
3011    pub diff: String,
3012    /// Path of the file being written to
3013    pub file_name: String,
3014    /// Human-readable description of the intended file change
3015    pub intention: String,
3016    /// Prompt kind discriminator
3017    pub kind: PermissionPromptRequestWriteKind,
3018    /// Complete new file contents for newly created files
3019    #[serde(skip_serializing_if = "Option::is_none")]
3020    pub new_file_contents: Option<String>,
3021    /// Tool call ID that triggered this permission request
3022    #[serde(skip_serializing_if = "Option::is_none")]
3023    pub tool_call_id: Option<String>,
3024}
3025
3026/// File read permission prompt
3027#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3028#[serde(rename_all = "camelCase")]
3029pub struct PermissionPromptRequestRead {
3030    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3031    ///
3032    /// <div class="warning">
3033    ///
3034    /// **Experimental.** This type is part of an experimental wire-protocol surface
3035    /// and may change or be removed in future SDK or CLI releases.
3036    ///
3037    /// </div>
3038    #[serde(skip_serializing_if = "Option::is_none")]
3039    pub auto_approval: Option<PermissionAutoApproval>,
3040    /// Human-readable description of why the file is being read
3041    pub intention: String,
3042    /// Prompt kind discriminator
3043    pub kind: PermissionPromptRequestReadKind,
3044    /// Path of the file or directory being read
3045    pub path: String,
3046    /// Tool call ID that triggered this permission request
3047    #[serde(skip_serializing_if = "Option::is_none")]
3048    pub tool_call_id: Option<String>,
3049}
3050
3051/// MCP tool invocation permission prompt
3052#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3053#[serde(rename_all = "camelCase")]
3054pub struct PermissionPromptRequestMcp {
3055    /// Arguments to pass to the MCP tool
3056    #[serde(skip_serializing_if = "Option::is_none")]
3057    pub args: Option<serde_json::Value>,
3058    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3059    ///
3060    /// <div class="warning">
3061    ///
3062    /// **Experimental.** This type is part of an experimental wire-protocol surface
3063    /// and may change or be removed in future SDK or CLI releases.
3064    ///
3065    /// </div>
3066    #[serde(skip_serializing_if = "Option::is_none")]
3067    pub auto_approval: Option<PermissionAutoApproval>,
3068    /// Prompt kind discriminator
3069    pub kind: PermissionPromptRequestMcpKind,
3070    /// Name of the MCP server providing the tool
3071    pub server_name: String,
3072    /// Tool call ID that triggered this permission request
3073    #[serde(skip_serializing_if = "Option::is_none")]
3074    pub tool_call_id: Option<String>,
3075    /// Internal name of the MCP tool
3076    pub tool_name: String,
3077    /// Human-readable title of the MCP tool
3078    pub tool_title: String,
3079}
3080
3081/// URL access permission prompt
3082#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3083#[serde(rename_all = "camelCase")]
3084pub struct PermissionPromptRequestUrl {
3085    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3086    ///
3087    /// <div class="warning">
3088    ///
3089    /// **Experimental.** This type is part of an experimental wire-protocol surface
3090    /// and may change or be removed in future SDK or CLI releases.
3091    ///
3092    /// </div>
3093    #[serde(skip_serializing_if = "Option::is_none")]
3094    pub auto_approval: Option<PermissionAutoApproval>,
3095    /// Human-readable description of why the URL is being accessed
3096    pub intention: String,
3097    /// Prompt kind discriminator
3098    pub kind: PermissionPromptRequestUrlKind,
3099    /// True when this URL fetch is requesting to bypass the sandbox network policy: either the model set requestSandboxBypass: true, or the tool re-issued the request as an interactive bypass after the network policy denied the approved URL (host opted in via sandbox.allowBypass). This is a request, not a grant: the fetch runs only if the user approves this permission request. Hosts should highlight the elevated risk in the approval UI.
3100    #[serde(skip_serializing_if = "Option::is_none")]
3101    pub request_sandbox_bypass: Option<bool>,
3102    /// Model-provided justification for the sandbox-bypass request. Only meaningful when requestSandboxBypass is true.
3103    #[serde(skip_serializing_if = "Option::is_none")]
3104    pub request_sandbox_bypass_reason: Option<String>,
3105    /// Tool call ID that triggered this permission request
3106    #[serde(skip_serializing_if = "Option::is_none")]
3107    pub tool_call_id: Option<String>,
3108    /// URL to be fetched
3109    pub url: String,
3110}
3111
3112/// Memory operation permission prompt
3113#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3114#[serde(rename_all = "camelCase")]
3115pub struct PermissionPromptRequestMemory {
3116    /// Whether this is a store or vote memory operation
3117    #[serde(skip_serializing_if = "Option::is_none")]
3118    pub action: Option<PermissionRequestMemoryAction>,
3119    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3120    ///
3121    /// <div class="warning">
3122    ///
3123    /// **Experimental.** This type is part of an experimental wire-protocol surface
3124    /// and may change or be removed in future SDK or CLI releases.
3125    ///
3126    /// </div>
3127    #[serde(skip_serializing_if = "Option::is_none")]
3128    pub auto_approval: Option<PermissionAutoApproval>,
3129    /// Source references for the stored fact (store only)
3130    #[serde(skip_serializing_if = "Option::is_none")]
3131    pub citations: Option<String>,
3132    /// Vote direction (vote only)
3133    #[serde(skip_serializing_if = "Option::is_none")]
3134    pub direction: Option<PermissionRequestMemoryDirection>,
3135    /// The fact being stored or voted on
3136    pub fact: String,
3137    /// Prompt kind discriminator
3138    pub kind: PermissionPromptRequestMemoryKind,
3139    /// Reason for the vote (vote only)
3140    #[serde(skip_serializing_if = "Option::is_none")]
3141    pub reason: Option<String>,
3142    /// Topic or subject of the memory (store only)
3143    #[serde(skip_serializing_if = "Option::is_none")]
3144    pub subject: Option<String>,
3145    /// Tool call ID that triggered this permission request
3146    #[serde(skip_serializing_if = "Option::is_none")]
3147    pub tool_call_id: Option<String>,
3148}
3149
3150/// Custom tool invocation permission prompt
3151#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3152#[serde(rename_all = "camelCase")]
3153pub struct PermissionPromptRequestCustomTool {
3154    /// Arguments to pass to the custom tool
3155    #[serde(skip_serializing_if = "Option::is_none")]
3156    pub args: Option<serde_json::Value>,
3157    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3158    ///
3159    /// <div class="warning">
3160    ///
3161    /// **Experimental.** This type is part of an experimental wire-protocol surface
3162    /// and may change or be removed in future SDK or CLI releases.
3163    ///
3164    /// </div>
3165    #[serde(skip_serializing_if = "Option::is_none")]
3166    pub auto_approval: Option<PermissionAutoApproval>,
3167    /// Prompt kind discriminator
3168    pub kind: PermissionPromptRequestCustomToolKind,
3169    /// Tool call ID that triggered this permission request
3170    #[serde(skip_serializing_if = "Option::is_none")]
3171    pub tool_call_id: Option<String>,
3172    /// Description of what the custom tool does
3173    pub tool_description: String,
3174    /// Name of the custom tool
3175    pub tool_name: String,
3176}
3177
3178/// Path access permission prompt
3179#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3180#[serde(rename_all = "camelCase")]
3181pub struct PermissionPromptRequestPath {
3182    /// Underlying permission kind that needs path approval
3183    pub access_kind: PermissionPromptRequestPathAccessKind,
3184    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3185    ///
3186    /// <div class="warning">
3187    ///
3188    /// **Experimental.** This type is part of an experimental wire-protocol surface
3189    /// and may change or be removed in future SDK or CLI releases.
3190    ///
3191    /// </div>
3192    #[serde(skip_serializing_if = "Option::is_none")]
3193    pub auto_approval: Option<PermissionAutoApproval>,
3194    /// Prompt kind discriminator
3195    pub kind: PermissionPromptRequestPathKind,
3196    /// File paths that require explicit approval
3197    pub paths: Vec<String>,
3198    /// Tool call ID that triggered this permission request
3199    #[serde(skip_serializing_if = "Option::is_none")]
3200    pub tool_call_id: Option<String>,
3201}
3202
3203/// Hook confirmation permission prompt
3204#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3205#[serde(rename_all = "camelCase")]
3206pub struct PermissionPromptRequestHook {
3207    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3208    ///
3209    /// <div class="warning">
3210    ///
3211    /// **Experimental.** This type is part of an experimental wire-protocol surface
3212    /// and may change or be removed in future SDK or CLI releases.
3213    ///
3214    /// </div>
3215    #[serde(skip_serializing_if = "Option::is_none")]
3216    pub auto_approval: Option<PermissionAutoApproval>,
3217    /// Optional message from the hook explaining why confirmation is needed
3218    #[serde(skip_serializing_if = "Option::is_none")]
3219    pub hook_message: Option<String>,
3220    /// Prompt kind discriminator
3221    pub kind: PermissionPromptRequestHookKind,
3222    /// Arguments of the tool call being gated
3223    #[serde(skip_serializing_if = "Option::is_none")]
3224    pub tool_args: Option<serde_json::Value>,
3225    /// Tool call ID that triggered this permission request
3226    #[serde(skip_serializing_if = "Option::is_none")]
3227    pub tool_call_id: Option<String>,
3228    /// Name of the tool the hook is gating
3229    pub tool_name: String,
3230}
3231
3232/// Extension management permission prompt
3233#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3234#[serde(rename_all = "camelCase")]
3235pub struct PermissionPromptRequestExtensionManagement {
3236    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3237    ///
3238    /// <div class="warning">
3239    ///
3240    /// **Experimental.** This type is part of an experimental wire-protocol surface
3241    /// and may change or be removed in future SDK or CLI releases.
3242    ///
3243    /// </div>
3244    #[serde(skip_serializing_if = "Option::is_none")]
3245    pub auto_approval: Option<PermissionAutoApproval>,
3246    /// Name of the extension being managed
3247    #[serde(skip_serializing_if = "Option::is_none")]
3248    pub extension_name: Option<String>,
3249    /// Prompt kind discriminator
3250    pub kind: PermissionPromptRequestExtensionManagementKind,
3251    /// The extension management operation (scaffold, reload)
3252    pub operation: String,
3253    /// Tool call ID that triggered this permission request
3254    #[serde(skip_serializing_if = "Option::is_none")]
3255    pub tool_call_id: Option<String>,
3256}
3257
3258/// Extension permission access prompt
3259#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3260#[serde(rename_all = "camelCase")]
3261pub struct PermissionPromptRequestExtensionPermissionAccess {
3262    /// Auto-approval judge information for this request; present only when auto mode is enabled.
3263    ///
3264    /// <div class="warning">
3265    ///
3266    /// **Experimental.** This type is part of an experimental wire-protocol surface
3267    /// and may change or be removed in future SDK or CLI releases.
3268    ///
3269    /// </div>
3270    #[serde(skip_serializing_if = "Option::is_none")]
3271    pub auto_approval: Option<PermissionAutoApproval>,
3272    /// Capabilities the extension is requesting
3273    pub capabilities: Vec<String>,
3274    /// Name of the extension requesting permission access
3275    pub extension_name: String,
3276    /// Prompt kind discriminator
3277    pub kind: PermissionPromptRequestExtensionPermissionAccessKind,
3278    /// Tool call ID that triggered this permission request
3279    #[serde(skip_serializing_if = "Option::is_none")]
3280    pub tool_call_id: Option<String>,
3281}
3282
3283/// Session event "permission.requested". Permission request notification requiring client approval with request details
3284#[derive(Debug, Clone, Serialize, Deserialize)]
3285#[serde(rename_all = "camelCase")]
3286pub struct PermissionRequestedData {
3287    /// Details of the permission being requested
3288    pub permission_request: PermissionRequest,
3289    /// Derived user-facing permission prompt details for UI consumers
3290    #[serde(skip_serializing_if = "Option::is_none")]
3291    pub prompt_request: Option<PermissionPromptRequest>,
3292    /// Unique identifier for this permission request; used to respond via session.respondToPermission()
3293    pub request_id: RequestId,
3294    /// When true, this permission was already resolved by a permissionRequest hook and requires no client action
3295    #[serde(skip_serializing_if = "Option::is_none")]
3296    pub resolved_by_hook: Option<bool>,
3297}
3298
3299/// Permission response variant indicating the request was approved without persisting an approval rule.
3300#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3301#[serde(rename_all = "camelCase")]
3302pub struct PermissionApproved {
3303    /// The permission request was approved
3304    pub kind: PermissionApprovedKind,
3305}
3306
3307/// Session-scoped tool-approval rule for specific shell command identifiers.
3308#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3309#[serde(rename_all = "camelCase")]
3310pub struct UserToolSessionApprovalCommands {
3311    /// Command identifiers approved by the user
3312    pub command_identifiers: Vec<String>,
3313    /// Command approval kind
3314    pub kind: UserToolSessionApprovalCommandsKind,
3315}
3316
3317/// Session-scoped tool-approval rule for read-only filesystem operations.
3318#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3319#[serde(rename_all = "camelCase")]
3320pub struct UserToolSessionApprovalRead {
3321    /// Read approval kind
3322    pub kind: UserToolSessionApprovalReadKind,
3323}
3324
3325/// Session-scoped tool-approval rule for filesystem write operations.
3326#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3327#[serde(rename_all = "camelCase")]
3328pub struct UserToolSessionApprovalWrite {
3329    /// Write approval kind
3330    pub kind: UserToolSessionApprovalWriteKind,
3331}
3332
3333/// Session-scoped tool-approval rule for an MCP server tool, or all tools on the server when `toolName` is null.
3334#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3335#[serde(rename_all = "camelCase")]
3336pub struct UserToolSessionApprovalMcp {
3337    /// MCP tool approval kind
3338    pub kind: UserToolSessionApprovalMcpKind,
3339    /// MCP server name
3340    pub server_name: String,
3341    /// Optional MCP tool name, or null for all tools on the server
3342    pub tool_name: Option<String>,
3343}
3344
3345/// Session-scoped tool-approval rule for writes to long-term memory.
3346#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3347#[serde(rename_all = "camelCase")]
3348pub struct UserToolSessionApprovalMemory {
3349    /// Memory approval kind
3350    pub kind: UserToolSessionApprovalMemoryKind,
3351}
3352
3353/// Session-scoped tool-approval rule for a custom tool, keyed by tool name.
3354#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3355#[serde(rename_all = "camelCase")]
3356pub struct UserToolSessionApprovalCustomTool {
3357    /// Custom tool approval kind
3358    pub kind: UserToolSessionApprovalCustomToolKind,
3359    /// Custom tool name
3360    pub tool_name: String,
3361}
3362
3363/// Session-scoped tool-approval rule for extension-management operations, optionally narrowed by operation.
3364#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3365#[serde(rename_all = "camelCase")]
3366pub struct UserToolSessionApprovalExtensionManagement {
3367    /// Extension management approval kind
3368    pub kind: UserToolSessionApprovalExtensionManagementKind,
3369    /// Optional operation identifier
3370    #[serde(skip_serializing_if = "Option::is_none")]
3371    pub operation: Option<String>,
3372}
3373
3374/// Session-scoped tool-approval rule for an extension's permission-gated capability access, keyed by extension name.
3375#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3376#[serde(rename_all = "camelCase")]
3377pub struct UserToolSessionApprovalExtensionPermissionAccess {
3378    /// Extension name
3379    pub extension_name: String,
3380    /// Extension permission access approval kind
3381    pub kind: UserToolSessionApprovalExtensionPermissionAccessKind,
3382}
3383
3384/// Permission response variant that approves a request and remembers the provided approval for the rest of the session.
3385#[derive(Debug, Clone, Serialize, Deserialize)]
3386#[serde(rename_all = "camelCase")]
3387pub struct PermissionApprovedForSession {
3388    /// The approval to add as a session-scoped rule
3389    pub approval: UserToolSessionApproval,
3390    /// Approved and remembered for the rest of the session
3391    pub kind: PermissionApprovedForSessionKind,
3392}
3393
3394/// Permission response variant that approves a request and persists the provided approval to a project location key.
3395#[derive(Debug, Clone, Serialize, Deserialize)]
3396#[serde(rename_all = "camelCase")]
3397pub struct PermissionApprovedForLocation {
3398    /// The approval to persist for this location
3399    pub approval: UserToolSessionApproval,
3400    /// Approved and persisted for this project location
3401    pub kind: PermissionApprovedForLocationKind,
3402    /// The location key (git root or cwd) to persist the approval to
3403    pub location_key: String,
3404}
3405
3406/// Permission response variant indicating the request was cancelled before use, with an optional reason.
3407#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3408#[serde(rename_all = "camelCase")]
3409pub struct PermissionCancelled {
3410    /// The permission request was cancelled before a response was used
3411    pub kind: PermissionCancelledKind,
3412    /// Optional explanation of why the request was cancelled
3413    #[serde(skip_serializing_if = "Option::is_none")]
3414    pub reason: Option<String>,
3415}
3416
3417/// A permission approval or denial rule matched against a tool request, identified by a rule kind with an optional argument value.
3418#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3419#[serde(rename_all = "camelCase")]
3420pub struct PermissionRule {
3421    /// Argument value matched against the request, or null when the rule kind has no argument (e.g. 'read', 'write', 'memory').
3422    pub argument: Option<String>,
3423    /// The rule kind, such as Shell or GitHubMCP
3424    pub kind: String,
3425}
3426
3427/// Permission response variant denied because matching approval rules explicitly blocked the request.
3428#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3429#[serde(rename_all = "camelCase")]
3430pub struct PermissionDeniedByRules {
3431    /// Denied because approval rules explicitly blocked it
3432    pub kind: PermissionDeniedByRulesKind,
3433    /// Rules that denied the request
3434    pub rules: Vec<PermissionRule>,
3435}
3436
3437/// Permission response variant denied because no approval rule matched and user confirmation was unavailable.
3438#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3439#[serde(rename_all = "camelCase")]
3440pub struct PermissionDeniedNoApprovalRuleAndCouldNotRequestFromUser {
3441    /// Denied because no approval rule matched and user confirmation was unavailable
3442    pub kind: PermissionDeniedNoApprovalRuleAndCouldNotRequestFromUserKind,
3443}
3444
3445/// Permission response variant denied in an interactive user prompt, with optional feedback and force-reject flag.
3446#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3447#[serde(rename_all = "camelCase")]
3448pub struct PermissionDeniedInteractivelyByUser {
3449    /// Optional feedback from the user explaining the denial
3450    #[serde(skip_serializing_if = "Option::is_none")]
3451    pub feedback: Option<String>,
3452    /// Whether to force-reject the current agent turn
3453    #[serde(skip_serializing_if = "Option::is_none")]
3454    pub force_reject: Option<bool>,
3455    /// Denied by the user during an interactive prompt
3456    pub kind: PermissionDeniedInteractivelyByUserKind,
3457}
3458
3459/// Permission response variant denying a path under content exclusion policy, with the path and message.
3460#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3461#[serde(rename_all = "camelCase")]
3462pub struct PermissionDeniedByContentExclusionPolicy {
3463    /// Denied by the organization's content exclusion policy
3464    pub kind: PermissionDeniedByContentExclusionPolicyKind,
3465    /// Human-readable explanation of why the path was excluded
3466    pub message: String,
3467    /// File path that triggered the exclusion
3468    pub path: String,
3469}
3470
3471/// Permission response variant denied by a permission-request hook, with optional message and interrupt flag.
3472#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3473#[serde(rename_all = "camelCase")]
3474pub struct PermissionDeniedByPermissionRequestHook {
3475    /// Whether to interrupt the current agent turn
3476    #[serde(skip_serializing_if = "Option::is_none")]
3477    pub interrupt: Option<bool>,
3478    /// Denied by a permission request hook registered by an extension or plugin
3479    pub kind: PermissionDeniedByPermissionRequestHookKind,
3480    /// Optional message from the hook explaining the denial
3481    #[serde(skip_serializing_if = "Option::is_none")]
3482    pub message: Option<String>,
3483}
3484
3485/// Session event "permission.completed". Permission request completion notification signaling UI dismissal
3486#[derive(Debug, Clone, Serialize, Deserialize)]
3487#[serde(rename_all = "camelCase")]
3488pub struct PermissionCompletedData {
3489    /// Request ID of the resolved permission request; clients should dismiss any UI for this request
3490    pub request_id: RequestId,
3491    /// The result of the permission request
3492    pub result: PermissionResult,
3493    /// Optional tool call ID associated with this permission prompt; clients may use it to correlate UI created from tool-scoped prompts
3494    #[serde(skip_serializing_if = "Option::is_none")]
3495    pub tool_call_id: Option<String>,
3496}
3497
3498/// Session event "user_input.requested". User input request notification with question and optional predefined choices
3499#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3500#[serde(rename_all = "camelCase")]
3501pub struct UserInputRequestedData {
3502    /// Whether the user can provide a free-form text response in addition to predefined choices
3503    #[serde(skip_serializing_if = "Option::is_none")]
3504    pub allow_freeform: Option<bool>,
3505    /// Predefined choices for the user to select from, if applicable
3506    #[serde(skip_serializing_if = "Option::is_none")]
3507    pub choices: Option<Vec<String>>,
3508    /// The question or prompt to present to the user
3509    pub question: String,
3510    /// Unique identifier for this input request; used to respond via session.respondToUserInput()
3511    pub request_id: RequestId,
3512    /// The LLM-assigned tool call ID that triggered this request; used by remote UIs to correlate responses
3513    #[serde(skip_serializing_if = "Option::is_none")]
3514    pub tool_call_id: Option<String>,
3515}
3516
3517/// Session event "user_input.completed". User input request completion with the user's response
3518#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3519#[serde(rename_all = "camelCase")]
3520pub struct UserInputCompletedData {
3521    /// The user's answer to the input request
3522    #[serde(skip_serializing_if = "Option::is_none")]
3523    pub answer: Option<String>,
3524    /// Request ID of the resolved user input request; clients should dismiss any UI for this request
3525    pub request_id: RequestId,
3526    /// Whether the answer was typed as free-form text rather than selected from choices
3527    #[serde(skip_serializing_if = "Option::is_none")]
3528    pub was_freeform: Option<bool>,
3529}
3530
3531/// JSON Schema describing the form fields to present to the user (form mode only)
3532#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3533#[serde(rename_all = "camelCase")]
3534pub struct ElicitationRequestedSchema {
3535    /// Form field definitions, keyed by field name
3536    pub properties: HashMap<String, serde_json::Value>,
3537    /// List of required field names
3538    #[serde(skip_serializing_if = "Option::is_none")]
3539    pub required: Option<Vec<String>>,
3540    /// Schema type indicator (always 'object')
3541    pub r#type: ElicitationRequestedSchemaType,
3542}
3543
3544/// Session event "elicitation.requested". Elicitation request; may be form-based (structured input) or URL-based (browser redirect)
3545#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3546#[serde(rename_all = "camelCase")]
3547pub struct ElicitationRequestedData {
3548    /// The source that initiated the request (MCP server name, or absent for agent-initiated)
3549    #[serde(skip_serializing_if = "Option::is_none")]
3550    pub elicitation_source: Option<String>,
3551    /// Message describing what information is needed from the user
3552    pub message: String,
3553    /// Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
3554    #[serde(skip_serializing_if = "Option::is_none")]
3555    pub mode: Option<ElicitationRequestedMode>,
3556    /// JSON Schema describing the form fields to present to the user (form mode only)
3557    #[serde(skip_serializing_if = "Option::is_none")]
3558    pub requested_schema: Option<ElicitationRequestedSchema>,
3559    /// Unique identifier for this elicitation request; used to respond via session.respondToElicitation()
3560    pub request_id: RequestId,
3561    /// Tool call ID from the LLM completion; used to correlate with CompletionChunk.toolCall.id for remote UIs
3562    #[serde(skip_serializing_if = "Option::is_none")]
3563    pub tool_call_id: Option<String>,
3564    /// URL to open in the user's browser (url mode only)
3565    #[serde(skip_serializing_if = "Option::is_none")]
3566    pub url: Option<String>,
3567}
3568
3569/// Session event "elicitation.completed". Elicitation request completion with the user's response
3570#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3571#[serde(rename_all = "camelCase")]
3572pub struct ElicitationCompletedData {
3573    /// The user action: "accept" (submitted form), "decline" (explicitly refused), or "cancel" (dismissed)
3574    #[serde(skip_serializing_if = "Option::is_none")]
3575    pub action: Option<ElicitationCompletedAction>,
3576    /// The submitted form data when action is 'accept'; keys match the requested schema fields
3577    #[serde(skip_serializing_if = "Option::is_none")]
3578    pub content: Option<HashMap<String, serde_json::Value>>,
3579    /// Request ID of the resolved elicitation request; clients should dismiss any UI for this request
3580    pub request_id: RequestId,
3581}
3582
3583/// Session event "sampling.requested". Sampling request from an MCP server; contains the server name and a requestId for correlation
3584#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3585#[serde(rename_all = "camelCase")]
3586pub struct SamplingRequestedData {
3587    /// The JSON-RPC request ID from the MCP protocol
3588    pub mcp_request_id: serde_json::Value,
3589    /// Unique identifier for this sampling request; used to respond via session.respondToSampling()
3590    pub request_id: RequestId,
3591    /// Name of the MCP server that initiated the sampling request
3592    pub server_name: String,
3593}
3594
3595/// Session event "sampling.completed". Sampling request completion notification signaling UI dismissal
3596#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3597#[serde(rename_all = "camelCase")]
3598pub struct SamplingCompletedData {
3599    /// Request ID of the resolved sampling request; clients should dismiss any UI for this request
3600    pub request_id: RequestId,
3601}
3602
3603/// Static OAuth client configuration, if the server specifies one
3604#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3605#[serde(rename_all = "camelCase")]
3606pub struct McpOauthRequiredStaticClientConfig {
3607    /// OAuth client ID for the server
3608    pub client_id: String,
3609    /// Optional OAuth client secret for confidential static clients, when the runtime can resolve one
3610    #[serde(skip_serializing_if = "Option::is_none")]
3611    pub client_secret: Option<String>,
3612    /// Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server).
3613    #[serde(skip_serializing_if = "Option::is_none")]
3614    pub grant_type: Option<McpOauthRequiredStaticClientConfigGrantType>,
3615    /// Whether this is a public OAuth client
3616    #[serde(skip_serializing_if = "Option::is_none")]
3617    pub public_client: Option<bool>,
3618}
3619
3620/// OAuth WWW-Authenticate parameters parsed from an MCP auth challenge
3621#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3622#[serde(rename_all = "camelCase")]
3623pub struct McpOauthWWWAuthenticateParams {
3624    /// OAuth error from the WWW-Authenticate error parameter, if present
3625    #[serde(skip_serializing_if = "Option::is_none")]
3626    pub error: Option<String>,
3627    /// Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter, if present
3628    #[serde(skip_serializing_if = "Option::is_none")]
3629    pub resource_metadata_url: Option<String>,
3630    /// Requested OAuth scopes from the WWW-Authenticate scope parameter, if present
3631    #[serde(skip_serializing_if = "Option::is_none")]
3632    pub scope: Option<String>,
3633}
3634
3635/// Session event "mcp.oauth_required". OAuth authentication request for an MCP server
3636#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3637#[serde(rename_all = "camelCase")]
3638pub struct McpOauthRequiredData {
3639    /// Why the runtime is requesting host-provided OAuth credentials.
3640    pub reason: McpOauthRequestReason,
3641    /// Unique identifier for this OAuth request; used to respond via session.mcp.oauth.handlePendingRequest
3642    pub request_id: RequestId,
3643    /// Raw OAuth protected-resource metadata document fetched for the MCP server, if available
3644    #[serde(skip_serializing_if = "Option::is_none")]
3645    pub resource_metadata: Option<String>,
3646    /// Display name of the MCP server that requires OAuth
3647    pub server_name: String,
3648    /// URL of the MCP server that requires OAuth
3649    pub server_url: String,
3650    /// Static OAuth client configuration, if the server specifies one
3651    #[serde(skip_serializing_if = "Option::is_none")]
3652    pub static_client_config: Option<McpOauthRequiredStaticClientConfig>,
3653    /// OAuth WWW-Authenticate parameters parsed from the auth challenge, if available
3654    #[serde(skip_serializing_if = "Option::is_none")]
3655    pub www_authenticate_params: Option<McpOauthWWWAuthenticateParams>,
3656}
3657
3658/// Session event "mcp.oauth_completed". MCP OAuth request completion notification
3659#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3660#[serde(rename_all = "camelCase")]
3661pub struct McpOauthCompletedData {
3662    /// How the pending OAuth request was completed
3663    pub outcome: McpOauthCompletionOutcome,
3664    /// Request ID of the resolved OAuth request
3665    pub request_id: RequestId,
3666}
3667
3668/// Session event "mcp.headers_refresh_required". Dynamic headers refresh request for a remote MCP server
3669#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3670#[serde(rename_all = "camelCase")]
3671pub struct McpHeadersRefreshRequiredData {
3672    /// Why dynamic headers are being requested.
3673    pub reason: McpHeadersRefreshRequiredReason,
3674    /// Unique identifier for this headers refresh request; used to respond via session.mcp.headers.handlePendingHeadersRefreshRequest()
3675    pub request_id: RequestId,
3676    /// Display name of the remote MCP server requesting headers
3677    pub server_name: String,
3678    /// URL of the remote MCP server requesting headers
3679    pub server_url: String,
3680}
3681
3682/// Session event "mcp.headers_refresh_completed". MCP headers refresh request completion notification
3683#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3684#[serde(rename_all = "camelCase")]
3685pub struct McpHeadersRefreshCompletedData {
3686    /// How the pending MCP headers refresh request resolved.
3687    pub outcome: McpHeadersRefreshCompletedOutcome,
3688    /// Request ID of the resolved headers refresh request
3689    pub request_id: RequestId,
3690}
3691
3692/// Session event "session.custom_notification". Opaque custom notification data. Consumers may branch on source and name, but payload semantics are source-defined.
3693#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3694#[serde(rename_all = "camelCase")]
3695pub struct SessionCustomNotificationData {
3696    /// Source-defined custom notification name
3697    pub name: String,
3698    /// Source-defined JSON payload for the custom notification
3699    pub payload: serde_json::Value,
3700    /// Namespace for the custom notification producer
3701    pub source: String,
3702    /// Optional source-defined string identifiers describing the payload subject
3703    #[serde(skip_serializing_if = "Option::is_none")]
3704    pub subject: Option<HashMap<String, String>>,
3705    /// Optional source-defined payload schema version
3706    #[serde(skip_serializing_if = "Option::is_none")]
3707    pub version: Option<i64>,
3708}
3709
3710/// Session event "external_tool.requested". External tool invocation request for client-side tool execution
3711#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3712#[serde(rename_all = "camelCase")]
3713pub struct ExternalToolRequestedData {
3714    /// Arguments to pass to the external tool
3715    #[serde(skip_serializing_if = "Option::is_none")]
3716    pub arguments: Option<serde_json::Value>,
3717    /// Unique identifier for this request; used to respond via session.respondToExternalTool()
3718    pub request_id: RequestId,
3719    /// Session ID that this external tool request belongs to
3720    pub session_id: SessionId,
3721    /// Tool call ID assigned to this external tool invocation
3722    pub tool_call_id: String,
3723    /// Name of the external tool to invoke
3724    pub tool_name: String,
3725    /// W3C Trace Context traceparent header for the execute_tool span
3726    #[serde(skip_serializing_if = "Option::is_none")]
3727    pub traceparent: Option<String>,
3728    /// W3C Trace Context tracestate header for the execute_tool span
3729    #[serde(skip_serializing_if = "Option::is_none")]
3730    pub tracestate: Option<String>,
3731    /// Active session working directory, when known.
3732    #[serde(skip_serializing_if = "Option::is_none")]
3733    pub working_directory: Option<String>,
3734}
3735
3736/// Session event "external_tool.completed". External tool completion notification signaling UI dismissal
3737#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3738#[serde(rename_all = "camelCase")]
3739pub struct ExternalToolCompletedData {
3740    /// Request ID of the resolved external tool request; clients should dismiss any UI for this request
3741    pub request_id: RequestId,
3742}
3743
3744/// Session event "command.queued". Queued slash command dispatch request for client execution
3745#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3746#[serde(rename_all = "camelCase")]
3747pub struct CommandQueuedData {
3748    /// The slash command text to be executed (e.g., /help, /clear)
3749    pub command: String,
3750    /// Unique identifier for this request; used to respond via session.respondToQueuedCommand()
3751    pub request_id: RequestId,
3752}
3753
3754/// Session event "command.execute". Registered command dispatch request routed to the owning client
3755#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3756#[serde(rename_all = "camelCase")]
3757pub struct CommandExecuteData {
3758    /// Raw argument string after the command name
3759    pub args: String,
3760    /// The full command text (e.g., /deploy production)
3761    pub command: String,
3762    /// Command name without leading /
3763    pub command_name: String,
3764    /// Unique identifier; used to respond via session.commands.handlePendingCommand()
3765    pub request_id: RequestId,
3766}
3767
3768/// Session event "command.completed". Queued command completion notification signaling UI dismissal
3769#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3770#[serde(rename_all = "camelCase")]
3771pub struct CommandCompletedData {
3772    /// Request ID of the resolved command request; clients should dismiss any UI for this request
3773    pub request_id: RequestId,
3774}
3775
3776/// Session event "auto_mode_switch.requested". Auto mode switch request notification requiring user approval
3777#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3778#[serde(rename_all = "camelCase")]
3779pub struct AutoModeSwitchRequestedData {
3780    /// The rate limit error code that triggered this request
3781    #[serde(skip_serializing_if = "Option::is_none")]
3782    pub error_code: Option<String>,
3783    /// Unique identifier for this request; used to respond via session.respondToAutoModeSwitch()
3784    pub request_id: RequestId,
3785    /// Seconds until the rate limit resets, when known. Lets clients render a humanized reset time alongside the prompt.
3786    #[serde(skip_serializing_if = "Option::is_none")]
3787    pub retry_after_seconds: Option<i64>,
3788}
3789
3790/// Session event "auto_mode_switch.completed". Auto mode switch completion notification
3791#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3792#[serde(rename_all = "camelCase")]
3793pub struct AutoModeSwitchCompletedData {
3794    /// Request ID of the resolved request; clients should dismiss any UI for this request
3795    pub request_id: RequestId,
3796    /// The user's auto-mode-switch choice
3797    pub response: AutoModeSwitchResponse,
3798}
3799
3800/// Session event "session_limits_exhausted.requested". Session limit exhaustion notification requiring user action.
3801#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3802#[serde(rename_all = "camelCase")]
3803pub struct SessionLimitsExhaustedRequestedData {
3804    /// Configured max AI Credits for the current accounting window.
3805    pub max_ai_credits: f64,
3806    /// Unique identifier for this request; used to respond via session.ui.handlePendingSessionLimitsExhausted().
3807    pub request_id: RequestId,
3808    /// AI Credits already consumed in the current accounting window.
3809    pub used_ai_credits: f64,
3810}
3811
3812/// The user's selected action for an exhausted session limit.
3813#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3814#[serde(rename_all = "camelCase")]
3815pub struct SessionLimitsExhaustedResponse {
3816    /// Action selected by the user.
3817    pub action: SessionLimitsExhaustedResponseAction,
3818    /// AI Credits to add to the current max when action is 'add'.
3819    #[serde(skip_serializing_if = "Option::is_none")]
3820    pub additional_ai_credits: Option<f64>,
3821    /// New absolute max AI Credits when action is 'set'.
3822    #[serde(skip_serializing_if = "Option::is_none")]
3823    pub max_ai_credits: Option<f64>,
3824}
3825
3826/// Session event "session_limits_exhausted.completed". Session limit exhaustion prompt completion notification.
3827#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3828#[serde(rename_all = "camelCase")]
3829pub struct SessionLimitsExhaustedCompletedData {
3830    /// Request ID of the resolved request; clients should dismiss any UI for this request.
3831    pub request_id: RequestId,
3832    /// The user's selected session-limit action.
3833    pub response: SessionLimitsExhaustedResponse,
3834}
3835
3836/// A single slash command available in the session, as listed by the `commands.changed` event.
3837#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3838#[serde(rename_all = "camelCase")]
3839pub struct CommandsChangedCommand {
3840    /// Optional human-readable command description.
3841    #[serde(skip_serializing_if = "Option::is_none")]
3842    pub description: Option<String>,
3843    /// Slash command name without the leading slash.
3844    pub name: String,
3845}
3846
3847/// Session event "commands.changed". SDK command registration change notification
3848#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3849#[serde(rename_all = "camelCase")]
3850pub struct CommandsChangedData {
3851    /// Current list of registered SDK commands
3852    pub commands: Vec<CommandsChangedCommand>,
3853}
3854
3855/// UI capability changes
3856#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3857#[serde(rename_all = "camelCase")]
3858pub struct CapabilitiesChangedUI {
3859    /// Whether canvas rendering is now supported
3860    #[serde(skip_serializing_if = "Option::is_none")]
3861    pub canvases: Option<bool>,
3862    /// Whether elicitation is now supported
3863    #[serde(skip_serializing_if = "Option::is_none")]
3864    pub elicitation: Option<bool>,
3865    /// Whether MCP Apps (SEP-1865) UI passthrough is now supported
3866    #[serde(skip_serializing_if = "Option::is_none")]
3867    pub mcp_apps: Option<bool>,
3868}
3869
3870/// Session event "capabilities.changed". Session capability change notification
3871#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3872#[serde(rename_all = "camelCase")]
3873pub struct CapabilitiesChangedData {
3874    /// UI capability changes
3875    #[serde(skip_serializing_if = "Option::is_none")]
3876    pub ui: Option<CapabilitiesChangedUI>,
3877}
3878
3879/// Session event "exit_plan_mode.requested". Plan approval request with plan content and available user actions
3880#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3881#[serde(rename_all = "camelCase")]
3882pub struct ExitPlanModeRequestedData {
3883    /// Available actions the user can take
3884    pub actions: Vec<ExitPlanModeAction>,
3885    /// Full content of the plan file
3886    pub plan_content: String,
3887    /// Recommended action to preselect for the user
3888    pub recommended_action: ExitPlanModeAction,
3889    /// Unique identifier for this request; used to respond via session.respondToExitPlanMode()
3890    pub request_id: RequestId,
3891    /// Summary of the plan that was created
3892    pub summary: String,
3893}
3894
3895/// Session event "exit_plan_mode.completed". Plan mode exit completion with the user's approval decision and optional feedback
3896#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3897#[serde(rename_all = "camelCase")]
3898pub struct ExitPlanModeCompletedData {
3899    /// Whether the plan was approved by the user
3900    #[serde(skip_serializing_if = "Option::is_none")]
3901    pub approved: Option<bool>,
3902    /// Whether edits should be auto-approved without confirmation
3903    #[serde(skip_serializing_if = "Option::is_none")]
3904    pub auto_approve_edits: Option<bool>,
3905    /// Free-form feedback from the user if they requested changes to the plan
3906    #[serde(skip_serializing_if = "Option::is_none")]
3907    pub feedback: Option<String>,
3908    /// Request ID of the resolved exit plan mode request; clients should dismiss any UI for this request
3909    pub request_id: RequestId,
3910    /// Action selected by the user
3911    #[serde(skip_serializing_if = "Option::is_none")]
3912    pub selected_action: Option<ExitPlanModeAction>,
3913}
3914
3915/// Session event "session.tools_updated". Payload of `session.tools_updated` identifying the model whose resolved tools were updated.
3916#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3917#[serde(rename_all = "camelCase")]
3918pub struct SessionToolsUpdatedData {
3919    /// Identifier of the model the resolved tools apply to.
3920    pub model: String,
3921}
3922
3923/// Session event "session.background_tasks_changed". Empty payload for `session.background_tasks_changed`, indicating background task state changed.
3924#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3925#[serde(rename_all = "camelCase")]
3926pub struct SessionBackgroundTasksChangedData {}
3927
3928/// A single resolved skill in `session.skills_loaded`, including source, invocability, enabled state, path, and argument hint.
3929#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3930#[serde(rename_all = "camelCase")]
3931pub struct SkillsLoadedSkill {
3932    /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field
3933    #[serde(skip_serializing_if = "Option::is_none")]
3934    pub argument_hint: Option<String>,
3935    /// Description of what the skill does
3936    pub description: String,
3937    /// Whether the skill is currently enabled
3938    pub enabled: bool,
3939    /// Unique identifier for the skill
3940    pub name: String,
3941    /// Absolute path to the skill file, if available
3942    #[serde(skip_serializing_if = "Option::is_none")]
3943    pub path: Option<String>,
3944    /// Source location type (e.g., project, personal-copilot, plugin, builtin)
3945    pub source: SkillSource,
3946    /// Whether the skill can be invoked by the user as a slash command
3947    pub user_invocable: bool,
3948}
3949
3950/// Session event "session.skills_loaded". Payload of `session.skills_loaded` listing resolved skill metadata.
3951#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3952#[serde(rename_all = "camelCase")]
3953pub struct SessionSkillsLoadedData {
3954    /// Array of resolved skill metadata
3955    pub skills: Vec<SkillsLoadedSkill>,
3956}
3957
3958/// A single loaded custom agent in `session.custom_agents_updated`, with identity, source, tools, invocability, and model override.
3959#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3960#[serde(rename_all = "camelCase")]
3961pub struct CustomAgentsUpdatedAgent {
3962    /// Description of what the agent does
3963    pub description: String,
3964    /// Human-readable display name
3965    pub display_name: String,
3966    /// Unique identifier for the agent
3967    pub id: String,
3968    /// Model override for this agent, if set
3969    #[serde(skip_serializing_if = "Option::is_none")]
3970    pub model: Option<String>,
3971    /// Internal name of the agent
3972    pub name: String,
3973    /// Source location: user, project, inherited, remote, or plugin
3974    pub source: String,
3975    /// List of tool names available to this agent, or null when all tools are available
3976    pub tools: Option<Vec<String>>,
3977    /// Whether the agent can be selected by the user
3978    pub user_invocable: bool,
3979}
3980
3981/// Session event "session.custom_agents_updated". Payload of `session.custom_agents_updated` with loaded custom agents plus non-fatal warnings and fatal errors.
3982#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3983#[serde(rename_all = "camelCase")]
3984pub struct SessionCustomAgentsUpdatedData {
3985    /// Array of loaded custom agent metadata
3986    pub agents: Vec<CustomAgentsUpdatedAgent>,
3987    /// Fatal errors from agent loading
3988    pub errors: Vec<String>,
3989    /// Non-fatal warnings from agent loading
3990    pub warnings: Vec<String>,
3991}
3992
3993/// A single MCP server status summary in `session.mcp_servers_loaded`, including name, status, source, transport, and plugin metadata.
3994#[derive(Debug, Clone, Default, Serialize, Deserialize)]
3995#[serde(rename_all = "camelCase")]
3996pub struct McpServersLoadedServer {
3997    /// Error message if the server failed to connect
3998    #[serde(skip_serializing_if = "Option::is_none")]
3999    pub error: Option<String>,
4000    /// Server name (config key)
4001    pub name: String,
4002    /// Name of the plugin that supplied the effective MCP server config, only when source is plugin
4003    #[serde(skip_serializing_if = "Option::is_none")]
4004    pub plugin_name: Option<String>,
4005    /// Version of the plugin that supplied the effective MCP server config, only when source is plugin
4006    #[serde(skip_serializing_if = "Option::is_none")]
4007    pub plugin_version: Option<String>,
4008    /// Configuration source: user, workspace, plugin, or builtin
4009    #[serde(skip_serializing_if = "Option::is_none")]
4010    pub source: Option<McpServerSource>,
4011    /// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
4012    pub status: McpServerStatus,
4013    /// Transport mechanism: stdio, http, sse (deprecated), or memory (in-process MCP server)
4014    #[serde(skip_serializing_if = "Option::is_none")]
4015    pub transport: Option<McpServerTransport>,
4016}
4017
4018/// Session event "session.mcp_servers_loaded". Payload of `session.mcp_servers_loaded` listing MCP server status summaries.
4019#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4020#[serde(rename_all = "camelCase")]
4021pub struct SessionMcpServersLoadedData {
4022    /// Array of MCP server status summaries
4023    pub servers: Vec<McpServersLoadedServer>,
4024}
4025
4026/// Session event "session.mcp_server_status_changed". Payload of `session.mcp_server_status_changed` for one MCP server's status and optional failure error.
4027#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4028#[serde(rename_all = "camelCase")]
4029pub struct SessionMcpServerStatusChangedData {
4030    /// Error message if the server entered a failed state
4031    #[serde(skip_serializing_if = "Option::is_none")]
4032    pub error: Option<String>,
4033    /// Name of the MCP server whose status changed
4034    pub server_name: String,
4035    /// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
4036    pub status: McpServerStatus,
4037}
4038
4039/// A single extension discovered by `session.extensions_loaded`, including qualified ID, source, and current status.
4040#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4041#[serde(rename_all = "camelCase")]
4042pub struct ExtensionsLoadedExtension {
4043    /// Source-qualified extension ID (e.g., 'project:my-ext', 'user:auth-helper', 'plugin:my-plugin:my-ext')
4044    pub id: String,
4045    /// Extension name (directory name)
4046    pub name: String,
4047    /// Discovery source
4048    pub source: ExtensionsLoadedExtensionSource,
4049    /// Current status: running, disabled, failed, or starting
4050    pub status: ExtensionsLoadedExtensionStatus,
4051}
4052
4053/// Session event "session.extensions_loaded". Payload of `session.extensions_loaded` listing discovered extensions and their statuses.
4054#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4055#[serde(rename_all = "camelCase")]
4056pub struct SessionExtensionsLoadedData {
4057    /// Array of discovered extensions and their status
4058    pub extensions: Vec<ExtensionsLoadedExtension>,
4059}
4060
4061/// Session event "session.canvas.opened". Payload of `session.canvas.opened` with canvas instance and provider IDs plus optional title, status, URL, and input.
4062///
4063/// <div class="warning">
4064///
4065/// **Experimental.** This type is part of an experimental wire-protocol surface
4066/// and may change or be removed in future SDK or CLI releases.
4067///
4068/// </div>
4069#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4070#[serde(rename_all = "camelCase")]
4071pub struct SessionCanvasOpenedData {
4072    /// Provider-local canvas identifier
4073    pub canvas_id: String,
4074    /// Owning provider identifier
4075    pub extension_id: String,
4076    /// Owning extension display name, when available
4077    #[serde(skip_serializing_if = "Option::is_none")]
4078    pub extension_name: Option<String>,
4079    /// Input supplied when the instance was opened
4080    #[serde(skip_serializing_if = "Option::is_none")]
4081    pub input: Option<serde_json::Value>,
4082    /// Stable caller-supplied canvas instance identifier
4083    pub instance_id: String,
4084    /// Provider-supplied status text
4085    #[serde(skip_serializing_if = "Option::is_none")]
4086    pub status: Option<String>,
4087    /// Rendered title
4088    #[serde(skip_serializing_if = "Option::is_none")]
4089    pub title: Option<String>,
4090    /// URL for web-rendered canvases
4091    #[serde(skip_serializing_if = "Option::is_none")]
4092    pub url: Option<String>,
4093}
4094
4095/// A single action within a canvas declaration, with its name, optional description, and optional input schema.
4096///
4097/// <div class="warning">
4098///
4099/// **Experimental.** This type is part of an experimental wire-protocol surface
4100/// and may change or be removed in future SDK or CLI releases.
4101///
4102/// </div>
4103#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4104#[serde(rename_all = "camelCase")]
4105pub struct CanvasRegistryChangedCanvasAction {
4106    /// Action description
4107    #[serde(skip_serializing_if = "Option::is_none")]
4108    pub description: Option<String>,
4109    /// JSON Schema for action input
4110    #[serde(skip_serializing_if = "Option::is_none")]
4111    pub input_schema: Option<serde_json::Value>,
4112    /// Action name
4113    pub name: String,
4114}
4115
4116/// A single canvas declaration in `session.canvas.registry_changed`, including provider IDs, display metadata, input schema, and actions.
4117///
4118/// <div class="warning">
4119///
4120/// **Experimental.** This type is part of an experimental wire-protocol surface
4121/// and may change or be removed in future SDK or CLI releases.
4122///
4123/// </div>
4124#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4125#[serde(rename_all = "camelCase")]
4126pub struct CanvasRegistryChangedCanvas {
4127    /// Actions the agent or host may invoke
4128    #[serde(skip_serializing_if = "Option::is_none")]
4129    pub actions: Option<Vec<CanvasRegistryChangedCanvasAction>>,
4130    /// Provider-local canvas identifier
4131    pub canvas_id: String,
4132    /// Short, single-sentence description shown to the agent in canvas catalogs.
4133    pub description: String,
4134    /// Human-readable canvas name
4135    pub display_name: String,
4136    /// Owning provider identifier
4137    pub extension_id: String,
4138    /// Owning extension display name, when available
4139    #[serde(skip_serializing_if = "Option::is_none")]
4140    pub extension_name: Option<String>,
4141    /// JSON Schema for canvas open input
4142    #[serde(skip_serializing_if = "Option::is_none")]
4143    pub input_schema: Option<serde_json::Value>,
4144}
4145
4146/// Session event "session.canvas.registry_changed". Payload of `session.canvas.registry_changed` listing the canvas declarations currently available.
4147///
4148/// <div class="warning">
4149///
4150/// **Experimental.** This type is part of an experimental wire-protocol surface
4151/// and may change or be removed in future SDK or CLI releases.
4152///
4153/// </div>
4154#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4155#[serde(rename_all = "camelCase")]
4156pub struct SessionCanvasRegistryChangedData {
4157    /// Canvas declarations currently available
4158    pub canvases: Vec<CanvasRegistryChangedCanvas>,
4159}
4160
4161/// Session event "session.canvas.closed". Payload of `session.canvas.closed` with the closed canvas instance ID, provider ID, and canvas ID.
4162///
4163/// <div class="warning">
4164///
4165/// **Experimental.** This type is part of an experimental wire-protocol surface
4166/// and may change or be removed in future SDK or CLI releases.
4167///
4168/// </div>
4169#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4170#[serde(rename_all = "camelCase")]
4171pub struct SessionCanvasClosedData {
4172    /// Provider-local canvas identifier
4173    pub canvas_id: String,
4174    /// Owning provider identifier
4175    pub extension_id: String,
4176    /// Stable caller-supplied identifier of the canvas instance that was closed
4177    pub instance_id: String,
4178}
4179
4180/// Session event "session.canvas.unavailable". Transient signal that an open canvas instance's provider has dropped (for example the extension is reloading mid-session). The host should keep the panel mounted and surface a reconnecting affordance rather than tearing it down; a subsequent `session.canvas.opened` for the same instanceId clears the affordance once the provider reconnects with a fresh url. Ephemeral and never persisted, so it is never replayed on cold resume.
4181///
4182/// <div class="warning">
4183///
4184/// **Experimental.** This type is part of an experimental wire-protocol surface
4185/// and may change or be removed in future SDK or CLI releases.
4186///
4187/// </div>
4188#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4189#[serde(rename_all = "camelCase")]
4190pub struct SessionCanvasUnavailableData {
4191    /// Provider-local canvas identifier
4192    pub canvas_id: String,
4193    /// Owning provider identifier
4194    pub extension_id: String,
4195    /// Stable caller-supplied identifier of the canvas instance whose provider became unavailable
4196    pub instance_id: String,
4197}
4198
4199/// Session event "session.canvas.recorded". Durable record that a canvas instance is open, used to restore open canvases on cold session resume. Intentionally omits the transient url and availability.
4200///
4201/// <div class="warning">
4202///
4203/// **Experimental.** This type is part of an experimental wire-protocol surface
4204/// and may change or be removed in future SDK or CLI releases.
4205///
4206/// </div>
4207#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4208#[serde(rename_all = "camelCase")]
4209pub struct SessionCanvasRecordedData {
4210    /// Provider-local canvas identifier
4211    pub canvas_id: String,
4212    /// Owning provider identifier
4213    pub extension_id: String,
4214    /// Input supplied when the instance was opened
4215    #[serde(skip_serializing_if = "Option::is_none")]
4216    pub input: Option<serde_json::Value>,
4217    /// Stable caller-supplied canvas instance identifier
4218    pub instance_id: String,
4219    /// Rendered title
4220    #[serde(skip_serializing_if = "Option::is_none")]
4221    pub title: Option<String>,
4222}
4223
4224/// Session event "session.canvas.removed". Durable record that a canvas instance was closed, superseding a prior instance_recorded during resume replay.
4225///
4226/// <div class="warning">
4227///
4228/// **Experimental.** This type is part of an experimental wire-protocol surface
4229/// and may change or be removed in future SDK or CLI releases.
4230///
4231/// </div>
4232#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4233#[serde(rename_all = "camelCase")]
4234pub struct SessionCanvasRemovedData {
4235    /// Provider-local canvas identifier
4236    pub canvas_id: String,
4237    /// Owning provider identifier
4238    pub extension_id: String,
4239    /// Stable caller-supplied identifier of the canvas instance that was closed
4240    pub instance_id: String,
4241}
4242
4243/// Session event "session.extensions.attachments_pushed". Payload of `session.extensions.attachments_pushed` with extension-contributed attachments for the next send.
4244#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4245#[serde(rename_all = "camelCase")]
4246pub struct SessionExtensionsAttachmentsPushedData {
4247    /// Attachments contributed by an extension; the host should surface these as composer pills and forward them via the next session.send call.
4248    pub attachments: Vec<serde_json::Value>,
4249}
4250
4251/// Set when the underlying tools/call threw an error before returning a CallToolResult
4252#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4253#[serde(rename_all = "camelCase")]
4254pub struct McpAppToolCallCompleteError {
4255    /// Human-readable error message
4256    pub message: String,
4257}
4258
4259/// MCP App tool `_meta.ui` resource URI and SEP-1865 visibility captured with an `mcp_app.tool_call_complete` result.
4260#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4261#[serde(rename_all = "camelCase")]
4262pub struct McpAppToolCallCompleteToolMetaUI {
4263    /// `ui://` URI declared by the tool's `_meta.ui.resourceUri`
4264    #[serde(skip_serializing_if = "Option::is_none")]
4265    pub resource_uri: Option<String>,
4266    /// Tool visibility per SEP-1865 (typically a subset of `["model","app"]`)
4267    #[serde(skip_serializing_if = "Option::is_none")]
4268    pub visibility: Option<Vec<String>>,
4269}
4270
4271/// The tool's `_meta.ui` block at the time of the call, so consumers can decide whether to forward the result to the model without re-listing tools.
4272#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4273#[serde(rename_all = "camelCase")]
4274pub struct McpAppToolCallCompleteToolMeta {
4275    /// MCP App tool `_meta.ui` resource URI and SEP-1865 visibility captured with an `mcp_app.tool_call_complete` result.
4276    #[serde(skip_serializing_if = "Option::is_none")]
4277    pub ui: Option<McpAppToolCallCompleteToolMetaUI>,
4278}
4279
4280/// Session event "mcp_app.tool_call_complete". MCP App view called a tool on a connected MCP server (SEP-1865)
4281#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4282#[serde(rename_all = "camelCase")]
4283pub struct McpAppToolCallCompleteData {
4284    /// Arguments passed to the tool by the app view, if any
4285    #[serde(skip_serializing_if = "Option::is_none")]
4286    pub arguments: Option<HashMap<String, serde_json::Value>>,
4287    /// Wall-clock duration of the underlying tools/call in milliseconds
4288    pub duration_ms: f64,
4289    /// Set when the underlying tools/call threw an error before returning a CallToolResult
4290    #[serde(skip_serializing_if = "Option::is_none")]
4291    pub error: Option<McpAppToolCallCompleteError>,
4292    /// Standard MCP CallToolResult returned by the server. Present whether or not the call set isError.
4293    #[serde(skip_serializing_if = "Option::is_none")]
4294    pub result: Option<HashMap<String, serde_json::Value>>,
4295    /// Name of the MCP server hosting the tool
4296    pub server_name: String,
4297    /// True when the call completed without throwing AND the MCP CallToolResult did not set isError
4298    pub success: bool,
4299    /// The tool's `_meta.ui` block at the time of the call, so consumers can decide whether to forward the result to the model without re-listing tools.
4300    #[serde(skip_serializing_if = "Option::is_none")]
4301    pub tool_meta: Option<McpAppToolCallCompleteToolMeta>,
4302    /// MCP tool name that was invoked
4303    pub tool_name: String,
4304}
4305
4306/// Hosting platform type of the repository (github or ado)
4307#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4308pub enum WorkingDirectoryContextHostType {
4309    /// Repository is hosted on GitHub.
4310    #[serde(rename = "github")]
4311    GitHub,
4312    /// Repository is hosted on Azure DevOps.
4313    #[serde(rename = "ado")]
4314    Ado,
4315    /// Unknown variant for forward compatibility.
4316    #[default]
4317    #[serde(other)]
4318    Unknown,
4319}
4320
4321/// Allowed values for the `ContextTier` enumeration.
4322#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4323pub enum ContextTier {
4324    /// Default context tier with standard context window size.
4325    #[serde(rename = "default")]
4326    Default,
4327    /// Extended context tier with a larger context window.
4328    #[serde(rename = "long_context")]
4329    LongContext,
4330    /// Unknown variant for forward compatibility.
4331    #[default]
4332    #[serde(other)]
4333    Unknown,
4334}
4335
4336/// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
4337#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4338pub enum ReasoningSummary {
4339    /// Do not request reasoning summaries from the model.
4340    #[serde(rename = "none")]
4341    None,
4342    /// Request a concise summary of the model's reasoning.
4343    #[serde(rename = "concise")]
4344    Concise,
4345    /// Request a detailed summary of the model's reasoning.
4346    #[serde(rename = "detailed")]
4347    Detailed,
4348    /// Unknown variant for forward compatibility.
4349    #[default]
4350    #[serde(other)]
4351    Unknown,
4352}
4353
4354/// Output verbosity level used for supported model calls (e.g. "low", "medium", "high")
4355#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4356pub enum Verbosity {
4357    /// A terse response was requested.
4358    #[serde(rename = "low")]
4359    Low,
4360    /// A medium amount of response detail was requested.
4361    #[serde(rename = "medium")]
4362    Medium,
4363    /// A more detailed response was requested.
4364    #[serde(rename = "high")]
4365    High,
4366    /// Unknown variant for forward compatibility.
4367    #[default]
4368    #[serde(other)]
4369    Unknown,
4370}
4371
4372/// The type of operation performed on the autopilot objective state file
4373#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4374pub enum AutopilotObjectiveChangedOperation {
4375    /// Autopilot objective state file was created for a new objective.
4376    #[serde(rename = "create")]
4377    Create,
4378    /// Autopilot objective state file was updated for an existing objective.
4379    #[serde(rename = "update")]
4380    Update,
4381    /// Autopilot objective state file was deleted or cleared.
4382    #[serde(rename = "delete")]
4383    Delete,
4384    /// Unknown variant for forward compatibility.
4385    #[default]
4386    #[serde(other)]
4387    Unknown,
4388}
4389
4390/// Current autopilot objective status, if one exists
4391#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4392pub enum AutopilotObjectiveChangedStatus {
4393    /// Objective is active and can drive autopilot continuations.
4394    #[serde(rename = "active")]
4395    Active,
4396    /// Objective is paused and will not drive autopilot continuations.
4397    #[serde(rename = "paused")]
4398    Paused,
4399    /// Legacy objective state indicating the previous continuation cap was reached.
4400    #[serde(rename = "cap_reached")]
4401    CapReached,
4402    /// Objective was completed by the agent.
4403    #[serde(rename = "completed")]
4404    Completed,
4405    /// Unknown variant for forward compatibility.
4406    #[default]
4407    #[serde(other)]
4408    Unknown,
4409}
4410
4411/// The session mode the agent is operating in
4412#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4413pub enum SessionMode {
4414    /// The agent is responding interactively to the user.
4415    #[serde(rename = "interactive")]
4416    Interactive,
4417    /// The agent is preparing a plan before making changes.
4418    #[serde(rename = "plan")]
4419    Plan,
4420    /// The agent is working autonomously toward task completion.
4421    #[serde(rename = "autopilot")]
4422    Autopilot,
4423    /// Unknown variant for forward compatibility.
4424    #[default]
4425    #[serde(other)]
4426    Unknown,
4427}
4428
4429/// Allow-all mode for the session.
4430///
4431/// <div class="warning">
4432///
4433/// **Experimental.** This type is part of an experimental wire-protocol surface
4434/// and may change or be removed in future SDK or CLI releases.
4435///
4436/// </div>
4437#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4438pub enum PermissionAllowAllMode {
4439    /// Permission requests follow the normal approval flow.
4440    #[serde(rename = "off")]
4441    Off,
4442    /// Tool, path, and URL permission requests are automatically approved.
4443    #[serde(rename = "on")]
4444    On,
4445    /// Permission requests follow the normal approval flow with an LLM advisory recommendation attached; clients may choose to auto-approve requests the judge evaluated as acceptable.
4446    #[serde(rename = "auto")]
4447    Auto,
4448    /// Unknown variant for forward compatibility.
4449    #[default]
4450    #[serde(other)]
4451    Unknown,
4452}
4453
4454/// The type of operation performed on the plan file
4455#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4456pub enum PlanChangedOperation {
4457    /// The plan file was created.
4458    #[serde(rename = "create")]
4459    Create,
4460    /// The plan file was updated.
4461    #[serde(rename = "update")]
4462    Update,
4463    /// The plan file was deleted.
4464    #[serde(rename = "delete")]
4465    Delete,
4466    /// Unknown variant for forward compatibility.
4467    #[default]
4468    #[serde(other)]
4469    Unknown,
4470}
4471
4472/// Whether the file was newly created or updated
4473#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4474pub enum WorkspaceFileChangedOperation {
4475    /// The workspace file was created.
4476    #[serde(rename = "create")]
4477    Create,
4478    /// The workspace file was updated.
4479    #[serde(rename = "update")]
4480    Update,
4481    /// Unknown variant for forward compatibility.
4482    #[default]
4483    #[serde(other)]
4484    Unknown,
4485}
4486
4487/// Origin type of the session being handed off
4488#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4489pub enum HandoffSourceType {
4490    /// The handoff originated from a remote session.
4491    #[serde(rename = "remote")]
4492    Remote,
4493    /// The handoff originated from a local session.
4494    #[serde(rename = "local")]
4495    Local,
4496    /// Unknown variant for forward compatibility.
4497    #[default]
4498    #[serde(other)]
4499    Unknown,
4500}
4501
4502/// Whether the session ended normally ("routine") or due to a crash/fatal error ("error")
4503#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4504pub enum ShutdownType {
4505    /// The session ended normally.
4506    #[serde(rename = "routine")]
4507    Routine,
4508    /// The session ended because of a crash or fatal error.
4509    #[serde(rename = "error")]
4510    Error,
4511    /// Unknown variant for forward compatibility.
4512    #[default]
4513    #[serde(other)]
4514    Unknown,
4515}
4516
4517/// The agent mode that was active when this message was sent
4518#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4519pub enum UserMessageAgentMode {
4520    /// The agent is responding interactively to the user.
4521    #[serde(rename = "interactive")]
4522    Interactive,
4523    /// The agent is preparing a plan before making changes.
4524    #[serde(rename = "plan")]
4525    Plan,
4526    /// The agent is working autonomously toward task completion.
4527    #[serde(rename = "autopilot")]
4528    Autopilot,
4529    /// The agent is in shell-focused UI mode.
4530    #[serde(rename = "shell")]
4531    Shell,
4532    /// Unknown variant for forward compatibility.
4533    #[default]
4534    #[serde(other)]
4535    Unknown,
4536}
4537
4538/// How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn.
4539#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4540pub enum UserMessageDelivery {
4541    /// Delivered while the loop was idle; starts its own run immediately (a human's fresh turn, or a system notification waking an idle agent).
4542    #[serde(rename = "idle")]
4543    Idle,
4544    /// Injected into the current in-flight run while the agent was busy (immediate mode).
4545    #[serde(rename = "steering")]
4546    Steering,
4547    /// Enqueued while the agent was busy; processed as its own run afterward.
4548    #[serde(rename = "queued")]
4549    Queued,
4550    /// Unknown variant for forward compatibility.
4551    #[default]
4552    #[serde(other)]
4553    Unknown,
4554}
4555
4556/// Tool call type: "function" for standard tool calls, "custom" for grammar-based tool calls. Defaults to "function" when absent.
4557#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4558pub enum AssistantMessageToolRequestType {
4559    /// Standard function-style tool call.
4560    #[serde(rename = "function")]
4561    Function,
4562    /// Custom grammar-based tool call.
4563    #[serde(rename = "custom")]
4564    Custom,
4565    /// Unknown variant for forward compatibility.
4566    #[default]
4567    #[serde(other)]
4568    Unknown,
4569}
4570
4571/// The system that produced a citation.
4572///
4573/// <div class="warning">
4574///
4575/// **Experimental.** This type is part of an experimental wire-protocol surface
4576/// and may change or be removed in future SDK or CLI releases.
4577///
4578/// </div>
4579#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4580pub enum CitationProvider {
4581    /// Citation produced by an Anthropic (Claude) model response.
4582    #[serde(rename = "anthropic")]
4583    Anthropic,
4584    /// Citation produced by an OpenAI model response.
4585    #[serde(rename = "openai")]
4586    Openai,
4587    /// Citation synthesized client-side by the runtime from tool output.
4588    #[serde(rename = "client")]
4589    Client,
4590    /// Unknown variant for forward compatibility.
4591    #[default]
4592    #[serde(other)]
4593    Unknown,
4594}
4595
4596/// API endpoint used for this model call, matching CAPI supported_endpoints vocabulary
4597#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4598pub enum AssistantUsageApiEndpoint {
4599    /// Chat Completions API endpoint.
4600    #[serde(rename = "/chat/completions")]
4601    ChatCompletions,
4602    /// Anthropic Messages API endpoint.
4603    #[serde(rename = "/v1/messages")]
4604    V1Messages,
4605    /// Responses API endpoint.
4606    #[serde(rename = "/responses")]
4607    Responses,
4608    /// WebSocket Responses API endpoint.
4609    #[serde(rename = "ws:/responses")]
4610    WsResponses,
4611    /// Unknown variant for forward compatibility.
4612    #[default]
4613    #[serde(other)]
4614    Unknown,
4615}
4616
4617/// For HTTP 400 failures only: whether the response carried a structured CAPI error envelope (structured_error, a deterministic validation failure) or no error body (bodyless, the transient gateway/proxy signature). Absent for non-400 failures.
4618#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4619pub enum ModelCallFailureBadRequestKind {
4620    /// The 400 response carried no error body (transient gateway/proxy signature).
4621    #[serde(rename = "bodyless")]
4622    Bodyless,
4623    /// The 400 response carried a structured CAPI error envelope (deterministic validation failure).
4624    #[serde(rename = "structured_error")]
4625    StructuredError,
4626    /// Unknown variant for forward compatibility.
4627    #[default]
4628    #[serde(other)]
4629    Unknown,
4630}
4631
4632/// Where the failed model call originated
4633#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4634pub enum ModelCallFailureSource {
4635    /// Model call from the top-level agent.
4636    #[serde(rename = "top_level")]
4637    TopLevel,
4638    /// Model call from a sub-agent.
4639    #[serde(rename = "subagent")]
4640    Subagent,
4641    /// Model call from MCP sampling.
4642    #[serde(rename = "mcp_sampling")]
4643    McpSampling,
4644    /// Unknown variant for forward compatibility.
4645    #[default]
4646    #[serde(other)]
4647    Unknown,
4648}
4649
4650/// Finite reason code describing why the current turn was aborted
4651#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4652pub enum AbortReason {
4653    /// The local user requested the abort, for example by pressing Ctrl+C in the CLI.
4654    #[serde(rename = "user_initiated")]
4655    UserInitiated,
4656    /// A remote command requested the abort.
4657    #[serde(rename = "remote_command")]
4658    RemoteCommand,
4659    /// An MCP server delivered a user.abort notification.
4660    #[serde(rename = "user_abort")]
4661    UserAbort,
4662    /// Unknown variant for forward compatibility.
4663    #[default]
4664    #[serde(other)]
4665    Unknown,
4666}
4667
4668/// Allowed values for the `ToolExecutionStartToolDescriptionMetaUIVisibility` enumeration.
4669#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4670pub enum ToolExecutionStartToolDescriptionMetaUIVisibility {
4671    /// Tool is callable by the model (LLM tool surface)
4672    #[serde(rename = "model")]
4673    Model,
4674    /// Tool is callable by the MCP App view (iframe) via session.mcp.apps.callTool
4675    #[serde(rename = "app")]
4676    App,
4677    /// Unknown variant for forward compatibility.
4678    #[default]
4679    #[serde(other)]
4680    Unknown,
4681}
4682
4683/// Content block type discriminator
4684#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4685pub enum ToolExecutionCompleteContentTextType {
4686    #[serde(rename = "text")]
4687    #[default]
4688    Text,
4689}
4690
4691/// Content block type discriminator
4692#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4693pub enum ToolExecutionCompleteContentTerminalType {
4694    #[serde(rename = "terminal")]
4695    #[default]
4696    Terminal,
4697}
4698
4699/// Content block type discriminator
4700#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4701pub enum ToolExecutionCompleteContentShellExitType {
4702    #[serde(rename = "shell_exit")]
4703    #[default]
4704    ShellExit,
4705}
4706
4707/// Content block type discriminator
4708#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4709pub enum ToolExecutionCompleteContentImageType {
4710    #[serde(rename = "image")]
4711    #[default]
4712    Image,
4713}
4714
4715/// Content block type discriminator
4716#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4717pub enum ToolExecutionCompleteContentAudioType {
4718    #[serde(rename = "audio")]
4719    #[default]
4720    Audio,
4721}
4722
4723/// Theme variant this icon is intended for
4724#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4725pub enum ToolExecutionCompleteContentResourceLinkIconTheme {
4726    /// Icon intended for light themes.
4727    #[serde(rename = "light")]
4728    Light,
4729    /// Icon intended for dark themes.
4730    #[serde(rename = "dark")]
4731    Dark,
4732    /// Unknown variant for forward compatibility.
4733    #[default]
4734    #[serde(other)]
4735    Unknown,
4736}
4737
4738/// Content block type discriminator
4739#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4740pub enum ToolExecutionCompleteContentResourceLinkType {
4741    #[serde(rename = "resource_link")]
4742    #[default]
4743    ResourceLink,
4744}
4745
4746/// The embedded resource contents, either text or base64-encoded binary
4747#[derive(Debug, Clone, Serialize, Deserialize)]
4748#[serde(untagged)]
4749pub enum ToolExecutionCompleteContentResourceDetails {
4750    EmbeddedTextResourceContents(EmbeddedTextResourceContents),
4751    EmbeddedBlobResourceContents(EmbeddedBlobResourceContents),
4752}
4753
4754/// Content block type discriminator
4755#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4756pub enum ToolExecutionCompleteContentResourceType {
4757    #[serde(rename = "resource")]
4758    #[default]
4759    Resource,
4760}
4761
4762/// A content block within a tool result, which may be text, terminal output, image, audio, or a resource
4763#[derive(Debug, Clone, Serialize, Deserialize)]
4764#[serde(untagged)]
4765pub enum ToolExecutionCompleteContent {
4766    Text(ToolExecutionCompleteContentText),
4767    Terminal(ToolExecutionCompleteContentTerminal),
4768    ShellExit(ToolExecutionCompleteContentShellExit),
4769    Image(ToolExecutionCompleteContentImage),
4770    Audio(ToolExecutionCompleteContentAudio),
4771    ResourceLink(ToolExecutionCompleteContentResourceLink),
4772    Resource(ToolExecutionCompleteContentResource),
4773}
4774
4775/// Allowed values for the `ToolExecutionCompleteToolDescriptionMetaUIVisibility` enumeration.
4776#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4777pub enum ToolExecutionCompleteToolDescriptionMetaUIVisibility {
4778    /// Tool is callable by the model (LLM tool surface)
4779    #[serde(rename = "model")]
4780    Model,
4781    /// Tool is callable by the MCP App view (iframe) via session.mcp.apps.callTool
4782    #[serde(rename = "app")]
4783    App,
4784    /// Unknown variant for forward compatibility.
4785    #[default]
4786    #[serde(other)]
4787    Unknown,
4788}
4789
4790/// What triggered the skill invocation: `user-invoked` (explicit user action, such as via a slash command or UI affordance), `agent-invoked` (agent requested the skill), or `context-load` (loaded as part of another context, such as preloading skills configured on a custom agent or subagent)
4791#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4792pub enum SkillInvokedTrigger {
4793    /// Skill invocation requested explicitly by the user, such as via a slash command or UI affordance.
4794    #[serde(rename = "user-invoked")]
4795    UserInvoked,
4796    /// Skill invocation requested by the agent.
4797    #[serde(rename = "agent-invoked")]
4798    AgentInvoked,
4799    /// Skill content loaded as part of another context, such as a configured custom agent or subagent.
4800    #[serde(rename = "context-load")]
4801    ContextLoad,
4802    /// Unknown variant for forward compatibility.
4803    #[default]
4804    #[serde(other)]
4805    Unknown,
4806}
4807
4808/// Binary asset type discriminator. Use "image" for images and "resource" otherwise.
4809#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4810pub enum BinaryAssetType {
4811    /// Binary image data.
4812    #[serde(rename = "image")]
4813    Image,
4814    /// Other binary resource data.
4815    #[serde(rename = "resource")]
4816    Resource,
4817    /// Unknown variant for forward compatibility.
4818    #[default]
4819    #[serde(other)]
4820    Unknown,
4821}
4822
4823/// Message role: "system" for system prompts, "developer" for developer-injected instructions
4824#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4825pub enum SystemMessageRole {
4826    /// System prompt message.
4827    #[serde(rename = "system")]
4828    System,
4829    /// Developer instruction message.
4830    #[serde(rename = "developer")]
4831    Developer,
4832    /// Unknown variant for forward compatibility.
4833    #[default]
4834    #[serde(other)]
4835    Unknown,
4836}
4837
4838/// Permission kind discriminator
4839#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4840pub enum PermissionRequestShellKind {
4841    #[serde(rename = "shell")]
4842    #[default]
4843    Shell,
4844}
4845
4846/// Permission kind discriminator
4847#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4848pub enum PermissionRequestWriteKind {
4849    #[serde(rename = "write")]
4850    #[default]
4851    Write,
4852}
4853
4854/// Permission kind discriminator
4855#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4856pub enum PermissionRequestReadKind {
4857    #[serde(rename = "read")]
4858    #[default]
4859    Read,
4860}
4861
4862/// Permission kind discriminator
4863#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4864pub enum PermissionRequestMcpKind {
4865    #[serde(rename = "mcp")]
4866    #[default]
4867    Mcp,
4868}
4869
4870/// Permission kind discriminator
4871#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4872pub enum PermissionRequestUrlKind {
4873    #[serde(rename = "url")]
4874    #[default]
4875    Url,
4876}
4877
4878/// Whether this is a store or vote memory operation
4879#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4880pub enum PermissionRequestMemoryAction {
4881    /// Store a new memory.
4882    #[serde(rename = "store")]
4883    Store,
4884    /// Vote on an existing memory.
4885    #[serde(rename = "vote")]
4886    Vote,
4887    /// Unknown variant for forward compatibility.
4888    #[default]
4889    #[serde(other)]
4890    Unknown,
4891}
4892
4893/// Vote direction (vote only)
4894#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4895pub enum PermissionRequestMemoryDirection {
4896    /// Vote that the memory is useful or accurate.
4897    #[serde(rename = "upvote")]
4898    Upvote,
4899    /// Vote that the memory is incorrect or outdated.
4900    #[serde(rename = "downvote")]
4901    Downvote,
4902    /// Unknown variant for forward compatibility.
4903    #[default]
4904    #[serde(other)]
4905    Unknown,
4906}
4907
4908/// Permission kind discriminator
4909#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4910pub enum PermissionRequestMemoryKind {
4911    #[serde(rename = "memory")]
4912    #[default]
4913    Memory,
4914}
4915
4916/// Permission kind discriminator
4917#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4918pub enum PermissionRequestCustomToolKind {
4919    #[serde(rename = "custom-tool")]
4920    #[default]
4921    CustomTool,
4922}
4923
4924/// Permission kind discriminator
4925#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4926pub enum PermissionRequestHookKind {
4927    #[serde(rename = "hook")]
4928    #[default]
4929    Hook,
4930}
4931
4932/// Permission kind discriminator
4933#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4934pub enum PermissionRequestExtensionManagementKind {
4935    #[serde(rename = "extension-management")]
4936    #[default]
4937    ExtensionManagement,
4938}
4939
4940/// Permission kind discriminator
4941#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4942pub enum PermissionRequestExtensionPermissionAccessKind {
4943    #[serde(rename = "extension-permission-access")]
4944    #[default]
4945    ExtensionPermissionAccess,
4946}
4947
4948/// Details of the permission being requested
4949#[derive(Debug, Clone, Serialize, Deserialize)]
4950#[serde(untagged)]
4951pub enum PermissionRequest {
4952    Shell(PermissionRequestShell),
4953    Write(PermissionRequestWrite),
4954    Read(PermissionRequestRead),
4955    Mcp(PermissionRequestMcp),
4956    Url(PermissionRequestUrl),
4957    Memory(PermissionRequestMemory),
4958    CustomTool(PermissionRequestCustomTool),
4959    Hook(PermissionRequestHook),
4960    ExtensionManagement(PermissionRequestExtensionManagement),
4961    ExtensionPermissionAccess(PermissionRequestExtensionPermissionAccess),
4962}
4963
4964/// Outcome of the auto-approval safety judge for a permission request. Present only when auto mode is enabled; its absence means the judge did not evaluate the request (auto mode was off).
4965///
4966/// <div class="warning">
4967///
4968/// **Experimental.** This type is part of an experimental wire-protocol surface
4969/// and may change or be removed in future SDK or CLI releases.
4970///
4971/// </div>
4972#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4973pub enum AutoApprovalRecommendation {
4974    /// The judge evaluated the request and recommends automatically approving it.
4975    #[serde(rename = "approve")]
4976    Approve,
4977    /// The judge evaluated the request and does not recommend auto-approving it; explicit approval is required. Whether that means prompting, denying, or something else is the consumer's decision.
4978    #[serde(rename = "requireApproval")]
4979    RequireApproval,
4980    /// Auto mode is enabled, but this request category is never auto-approvable (for example, sandbox-bypass requests), so the judge was not consulted.
4981    #[serde(rename = "excluded")]
4982    Excluded,
4983    /// The judge was consulted but did not return a usable recommendation, so the request requires explicit approval.
4984    #[serde(rename = "error")]
4985    Error,
4986    /// Unknown variant for forward compatibility.
4987    #[default]
4988    #[serde(other)]
4989    Unknown,
4990}
4991
4992/// Prompt kind discriminator
4993#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
4994pub enum PermissionPromptRequestCommandsKind {
4995    #[serde(rename = "commands")]
4996    #[default]
4997    Commands,
4998}
4999
5000/// Prompt kind discriminator
5001#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5002pub enum PermissionPromptRequestWriteKind {
5003    #[serde(rename = "write")]
5004    #[default]
5005    Write,
5006}
5007
5008/// Prompt kind discriminator
5009#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5010pub enum PermissionPromptRequestReadKind {
5011    #[serde(rename = "read")]
5012    #[default]
5013    Read,
5014}
5015
5016/// Prompt kind discriminator
5017#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5018pub enum PermissionPromptRequestMcpKind {
5019    #[serde(rename = "mcp")]
5020    #[default]
5021    Mcp,
5022}
5023
5024/// Prompt kind discriminator
5025#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5026pub enum PermissionPromptRequestUrlKind {
5027    #[serde(rename = "url")]
5028    #[default]
5029    Url,
5030}
5031
5032/// Prompt kind discriminator
5033#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5034pub enum PermissionPromptRequestMemoryKind {
5035    #[serde(rename = "memory")]
5036    #[default]
5037    Memory,
5038}
5039
5040/// Prompt kind discriminator
5041#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5042pub enum PermissionPromptRequestCustomToolKind {
5043    #[serde(rename = "custom-tool")]
5044    #[default]
5045    CustomTool,
5046}
5047
5048/// Underlying permission kind that needs path approval
5049#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5050pub enum PermissionPromptRequestPathAccessKind {
5051    /// Read access to a filesystem path.
5052    #[serde(rename = "read")]
5053    Read,
5054    /// Shell command access involving a filesystem path.
5055    #[serde(rename = "shell")]
5056    Shell,
5057    /// Write access to a filesystem path.
5058    #[serde(rename = "write")]
5059    Write,
5060    /// Unknown variant for forward compatibility.
5061    #[default]
5062    #[serde(other)]
5063    Unknown,
5064}
5065
5066/// Prompt kind discriminator
5067#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5068pub enum PermissionPromptRequestPathKind {
5069    #[serde(rename = "path")]
5070    #[default]
5071    Path,
5072}
5073
5074/// Prompt kind discriminator
5075#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5076pub enum PermissionPromptRequestHookKind {
5077    #[serde(rename = "hook")]
5078    #[default]
5079    Hook,
5080}
5081
5082/// Prompt kind discriminator
5083#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5084pub enum PermissionPromptRequestExtensionManagementKind {
5085    #[serde(rename = "extension-management")]
5086    #[default]
5087    ExtensionManagement,
5088}
5089
5090/// Prompt kind discriminator
5091#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5092pub enum PermissionPromptRequestExtensionPermissionAccessKind {
5093    #[serde(rename = "extension-permission-access")]
5094    #[default]
5095    ExtensionPermissionAccess,
5096}
5097
5098/// Derived user-facing permission prompt details for UI consumers
5099#[derive(Debug, Clone, Serialize, Deserialize)]
5100#[serde(untagged)]
5101pub enum PermissionPromptRequest {
5102    Commands(PermissionPromptRequestCommands),
5103    Write(PermissionPromptRequestWrite),
5104    Read(PermissionPromptRequestRead),
5105    Mcp(PermissionPromptRequestMcp),
5106    Url(PermissionPromptRequestUrl),
5107    Memory(PermissionPromptRequestMemory),
5108    CustomTool(PermissionPromptRequestCustomTool),
5109    Path(PermissionPromptRequestPath),
5110    Hook(PermissionPromptRequestHook),
5111    ExtensionManagement(PermissionPromptRequestExtensionManagement),
5112    ExtensionPermissionAccess(PermissionPromptRequestExtensionPermissionAccess),
5113}
5114
5115/// The permission request was approved
5116#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5117pub enum PermissionApprovedKind {
5118    #[serde(rename = "approved")]
5119    #[default]
5120    Approved,
5121}
5122
5123/// Command approval kind
5124#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5125pub enum UserToolSessionApprovalCommandsKind {
5126    #[serde(rename = "commands")]
5127    #[default]
5128    Commands,
5129}
5130
5131/// Read approval kind
5132#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5133pub enum UserToolSessionApprovalReadKind {
5134    #[serde(rename = "read")]
5135    #[default]
5136    Read,
5137}
5138
5139/// Write approval kind
5140#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5141pub enum UserToolSessionApprovalWriteKind {
5142    #[serde(rename = "write")]
5143    #[default]
5144    Write,
5145}
5146
5147/// MCP tool approval kind
5148#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5149pub enum UserToolSessionApprovalMcpKind {
5150    #[serde(rename = "mcp")]
5151    #[default]
5152    Mcp,
5153}
5154
5155/// Memory approval kind
5156#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5157pub enum UserToolSessionApprovalMemoryKind {
5158    #[serde(rename = "memory")]
5159    #[default]
5160    Memory,
5161}
5162
5163/// Custom tool approval kind
5164#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5165pub enum UserToolSessionApprovalCustomToolKind {
5166    #[serde(rename = "custom-tool")]
5167    #[default]
5168    CustomTool,
5169}
5170
5171/// Extension management approval kind
5172#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5173pub enum UserToolSessionApprovalExtensionManagementKind {
5174    #[serde(rename = "extension-management")]
5175    #[default]
5176    ExtensionManagement,
5177}
5178
5179/// Extension permission access approval kind
5180#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5181pub enum UserToolSessionApprovalExtensionPermissionAccessKind {
5182    #[serde(rename = "extension-permission-access")]
5183    #[default]
5184    ExtensionPermissionAccess,
5185}
5186
5187/// The approval to add as a session-scoped rule
5188#[derive(Debug, Clone, Serialize, Deserialize)]
5189#[serde(untagged)]
5190pub enum UserToolSessionApproval {
5191    Commands(UserToolSessionApprovalCommands),
5192    Read(UserToolSessionApprovalRead),
5193    Write(UserToolSessionApprovalWrite),
5194    Mcp(UserToolSessionApprovalMcp),
5195    Memory(UserToolSessionApprovalMemory),
5196    CustomTool(UserToolSessionApprovalCustomTool),
5197    ExtensionManagement(UserToolSessionApprovalExtensionManagement),
5198    ExtensionPermissionAccess(UserToolSessionApprovalExtensionPermissionAccess),
5199}
5200
5201/// Approved and remembered for the rest of the session
5202#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5203pub enum PermissionApprovedForSessionKind {
5204    #[serde(rename = "approved-for-session")]
5205    #[default]
5206    ApprovedForSession,
5207}
5208
5209/// Approved and persisted for this project location
5210#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5211pub enum PermissionApprovedForLocationKind {
5212    #[serde(rename = "approved-for-location")]
5213    #[default]
5214    ApprovedForLocation,
5215}
5216
5217/// The permission request was cancelled before a response was used
5218#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5219pub enum PermissionCancelledKind {
5220    #[serde(rename = "cancelled")]
5221    #[default]
5222    Cancelled,
5223}
5224
5225/// Denied because approval rules explicitly blocked it
5226#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5227pub enum PermissionDeniedByRulesKind {
5228    #[serde(rename = "denied-by-rules")]
5229    #[default]
5230    DeniedByRules,
5231}
5232
5233/// Denied because no approval rule matched and user confirmation was unavailable
5234#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5235pub enum PermissionDeniedNoApprovalRuleAndCouldNotRequestFromUserKind {
5236    #[serde(rename = "denied-no-approval-rule-and-could-not-request-from-user")]
5237    #[default]
5238    DeniedNoApprovalRuleAndCouldNotRequestFromUser,
5239}
5240
5241/// Denied by the user during an interactive prompt
5242#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5243pub enum PermissionDeniedInteractivelyByUserKind {
5244    #[serde(rename = "denied-interactively-by-user")]
5245    #[default]
5246    DeniedInteractivelyByUser,
5247}
5248
5249/// Denied by the organization's content exclusion policy
5250#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5251pub enum PermissionDeniedByContentExclusionPolicyKind {
5252    #[serde(rename = "denied-by-content-exclusion-policy")]
5253    #[default]
5254    DeniedByContentExclusionPolicy,
5255}
5256
5257/// Denied by a permission request hook registered by an extension or plugin
5258#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5259pub enum PermissionDeniedByPermissionRequestHookKind {
5260    #[serde(rename = "denied-by-permission-request-hook")]
5261    #[default]
5262    DeniedByPermissionRequestHook,
5263}
5264
5265/// The result of the permission request
5266#[derive(Debug, Clone, Serialize, Deserialize)]
5267#[serde(untagged)]
5268pub enum PermissionResult {
5269    Approved(PermissionApproved),
5270    ApprovedForSession(PermissionApprovedForSession),
5271    ApprovedForLocation(PermissionApprovedForLocation),
5272    Cancelled(PermissionCancelled),
5273    DeniedByRules(PermissionDeniedByRules),
5274    DeniedNoApprovalRuleAndCouldNotRequestFromUser(
5275        PermissionDeniedNoApprovalRuleAndCouldNotRequestFromUser,
5276    ),
5277    DeniedInteractivelyByUser(PermissionDeniedInteractivelyByUser),
5278    DeniedByContentExclusionPolicy(PermissionDeniedByContentExclusionPolicy),
5279    DeniedByPermissionRequestHook(PermissionDeniedByPermissionRequestHook),
5280}
5281
5282/// Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
5283#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5284pub enum ElicitationRequestedMode {
5285    /// Structured form-based elicitation.
5286    #[serde(rename = "form")]
5287    Form,
5288    /// Browser URL-based elicitation.
5289    #[serde(rename = "url")]
5290    Url,
5291    /// Unknown variant for forward compatibility.
5292    #[default]
5293    #[serde(other)]
5294    Unknown,
5295}
5296
5297/// Schema type indicator (always 'object')
5298#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5299pub enum ElicitationRequestedSchemaType {
5300    #[serde(rename = "object")]
5301    #[default]
5302    Object,
5303}
5304
5305/// The user action: "accept" (submitted form), "decline" (explicitly refused), or "cancel" (dismissed)
5306#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5307pub enum ElicitationCompletedAction {
5308    /// The user submitted the requested form.
5309    #[serde(rename = "accept")]
5310    Accept,
5311    /// The user explicitly declined the request.
5312    #[serde(rename = "decline")]
5313    Decline,
5314    /// The user dismissed the request.
5315    #[serde(rename = "cancel")]
5316    Cancel,
5317    /// Unknown variant for forward compatibility.
5318    #[default]
5319    #[serde(other)]
5320    Unknown,
5321}
5322
5323/// Reason the runtime is requesting host-provided MCP OAuth credentials
5324#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5325pub enum McpOauthRequestReason {
5326    /// Initial credentials are required before connecting to the MCP server.
5327    #[serde(rename = "initial")]
5328    Initial,
5329    /// The current host-provided credential was rejected and a replacement is requested.
5330    #[serde(rename = "refresh")]
5331    Refresh,
5332    /// The server requires a new host authorization flow before continuing.
5333    #[serde(rename = "reauth")]
5334    Reauth,
5335    /// The server requires a credential with additional scope or audience.
5336    #[serde(rename = "upscope")]
5337    Upscope,
5338    /// Unknown variant for forward compatibility.
5339    #[default]
5340    #[serde(other)]
5341    Unknown,
5342}
5343
5344/// Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server).
5345#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5346pub enum McpOauthRequiredStaticClientConfigGrantType {
5347    #[serde(rename = "client_credentials")]
5348    #[default]
5349    ClientCredentials,
5350}
5351
5352/// How the pending MCP OAuth request was completed
5353#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5354pub enum McpOauthCompletionOutcome {
5355    /// The request completed with a token-backed OAuth provider.
5356    #[serde(rename = "token")]
5357    Token,
5358    /// The request completed without an OAuth provider.
5359    #[serde(rename = "cancelled")]
5360    Cancelled,
5361    /// Unknown variant for forward compatibility.
5362    #[default]
5363    #[serde(other)]
5364    Unknown,
5365}
5366
5367/// Why dynamic headers are being requested.
5368#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5369pub enum McpHeadersRefreshRequiredReason {
5370    /// The transport is making its first dynamic header request for this server.
5371    #[serde(rename = "startup")]
5372    Startup,
5373    /// The previously cached dynamic headers expired.
5374    #[serde(rename = "ttl-expired")]
5375    TtlExpired,
5376    /// The server returned 401 and stale dynamic headers were invalidated.
5377    #[serde(rename = "auth-failed")]
5378    AuthFailed,
5379    /// Unknown variant for forward compatibility.
5380    #[default]
5381    #[serde(other)]
5382    Unknown,
5383}
5384
5385/// How the pending MCP headers refresh request resolved.
5386#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5387pub enum McpHeadersRefreshCompletedOutcome {
5388    /// The host supplied dynamic headers.
5389    #[serde(rename = "headers")]
5390    Headers,
5391    /// The host responded with no dynamic headers.
5392    #[serde(rename = "none")]
5393    None,
5394    /// No response arrived within the bounded window.
5395    #[serde(rename = "timeout")]
5396    Timeout,
5397    /// Unknown variant for forward compatibility.
5398    #[default]
5399    #[serde(other)]
5400    Unknown,
5401}
5402
5403/// The user's auto-mode-switch choice
5404#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5405pub enum AutoModeSwitchResponse {
5406    /// Switch models for this request.
5407    #[serde(rename = "yes")]
5408    Yes,
5409    /// Switch models now and keep using the replacement automatically.
5410    #[serde(rename = "yes_always")]
5411    YesAlways,
5412    /// Do not switch models.
5413    #[serde(rename = "no")]
5414    No,
5415    /// Unknown variant for forward compatibility.
5416    #[default]
5417    #[serde(other)]
5418    Unknown,
5419}
5420
5421/// User action selected for an exhausted session limit.
5422#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5423pub enum SessionLimitsExhaustedResponseAction {
5424    /// Increase the current max by an exact AI Credits amount.
5425    #[serde(rename = "add")]
5426    Add,
5427    /// Set a new absolute max AI Credits value.
5428    #[serde(rename = "set")]
5429    Set,
5430    /// Remove the current session limit.
5431    #[serde(rename = "unset")]
5432    Unset,
5433    /// Leave the limit unchanged and cancel the blocked model request.
5434    #[serde(rename = "cancel")]
5435    Cancel,
5436    /// Unknown variant for forward compatibility.
5437    #[default]
5438    #[serde(other)]
5439    Unknown,
5440}
5441
5442/// Exit plan mode action
5443#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5444pub enum ExitPlanModeAction {
5445    /// Exit plan mode without starting implementation.
5446    #[serde(rename = "exit_only")]
5447    ExitOnly,
5448    /// Exit plan mode and continue in interactive mode.
5449    #[serde(rename = "interactive")]
5450    Interactive,
5451    /// Exit plan mode and continue autonomously.
5452    #[serde(rename = "autopilot")]
5453    Autopilot,
5454    /// Exit plan mode and continue with parallel autonomous workers.
5455    #[serde(rename = "autopilot_fleet")]
5456    AutopilotFleet,
5457    /// Unknown variant for forward compatibility.
5458    #[default]
5459    #[serde(other)]
5460    Unknown,
5461}
5462
5463/// Source location type (e.g., project, personal-copilot, plugin, builtin)
5464#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5465pub enum SkillSource {
5466    /// Skill defined in the current project's skill directories.
5467    #[serde(rename = "project")]
5468    Project,
5469    /// Skill discovered from a parent directory in the current workspace tree.
5470    #[serde(rename = "inherited")]
5471    Inherited,
5472    /// Skill defined in the user's Copilot skill directory.
5473    #[serde(rename = "personal-copilot")]
5474    PersonalCopilot,
5475    /// Skill defined in the user's personal agents skill directory.
5476    #[serde(rename = "personal-agents")]
5477    PersonalAgents,
5478    /// Skill provided by an installed plugin.
5479    #[serde(rename = "plugin")]
5480    Plugin,
5481    /// Skill loaded from a configured custom skill directory.
5482    #[serde(rename = "custom")]
5483    Custom,
5484    /// Skill bundled with the runtime.
5485    #[serde(rename = "builtin")]
5486    Builtin,
5487    /// Unknown variant for forward compatibility.
5488    #[default]
5489    #[serde(other)]
5490    Unknown,
5491}
5492
5493/// Configuration source: user, workspace, plugin, or builtin
5494#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5495pub enum McpServerSource {
5496    /// Server configured in the user's global MCP configuration.
5497    #[serde(rename = "user")]
5498    User,
5499    /// Server configured by the current workspace.
5500    #[serde(rename = "workspace")]
5501    Workspace,
5502    /// Server contributed by an installed plugin.
5503    #[serde(rename = "plugin")]
5504    Plugin,
5505    /// Server bundled with the runtime.
5506    #[serde(rename = "builtin")]
5507    Builtin,
5508    /// Unknown variant for forward compatibility.
5509    #[default]
5510    #[serde(other)]
5511    Unknown,
5512}
5513
5514/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
5515#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5516pub enum McpServerStatus {
5517    /// The server is connected and available.
5518    #[serde(rename = "connected")]
5519    Connected,
5520    /// The server failed to connect or initialize.
5521    #[serde(rename = "failed")]
5522    Failed,
5523    /// The server requires authentication before it can connect.
5524    #[serde(rename = "needs-auth")]
5525    NeedsAuth,
5526    /// The server connection is still being established.
5527    #[serde(rename = "pending")]
5528    Pending,
5529    /// The server is configured but disabled.
5530    #[serde(rename = "disabled")]
5531    Disabled,
5532    /// The server is not configured for this session.
5533    #[serde(rename = "not_configured")]
5534    NotConfigured,
5535    /// Unknown variant for forward compatibility.
5536    #[default]
5537    #[serde(other)]
5538    Unknown,
5539}
5540
5541/// Transport mechanism: stdio, http, sse (deprecated), or memory (in-process MCP server)
5542#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5543pub enum McpServerTransport {
5544    /// Server communicates over stdio with a local child process.
5545    #[serde(rename = "stdio")]
5546    Stdio,
5547    /// Server communicates over streamable HTTP.
5548    #[serde(rename = "http")]
5549    Http,
5550    /// Server communicates over Server-Sent Events (deprecated).
5551    #[serde(rename = "sse")]
5552    Sse,
5553    /// Server is backed by an in-memory runtime implementation.
5554    #[serde(rename = "memory")]
5555    Memory,
5556    /// Unknown variant for forward compatibility.
5557    #[default]
5558    #[serde(other)]
5559    Unknown,
5560}
5561
5562/// Discovery source
5563#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5564pub enum ExtensionsLoadedExtensionSource {
5565    /// Extension discovered from the current project.
5566    #[serde(rename = "project")]
5567    Project,
5568    /// Extension discovered from the user's extension directory.
5569    #[serde(rename = "user")]
5570    User,
5571    /// Extension contributed by an installed plugin.
5572    #[serde(rename = "plugin")]
5573    Plugin,
5574    /// Extension discovered from the current session's state directory.
5575    #[serde(rename = "session")]
5576    Session,
5577    /// Unknown variant for forward compatibility.
5578    #[default]
5579    #[serde(other)]
5580    Unknown,
5581}
5582
5583/// Current status: running, disabled, failed, or starting
5584#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
5585pub enum ExtensionsLoadedExtensionStatus {
5586    /// The extension process is running.
5587    #[serde(rename = "running")]
5588    Running,
5589    /// The extension is installed but disabled.
5590    #[serde(rename = "disabled")]
5591    Disabled,
5592    /// The extension failed to start or crashed.
5593    #[serde(rename = "failed")]
5594    Failed,
5595    /// The extension process is starting.
5596    #[serde(rename = "starting")]
5597    Starting,
5598    /// Unknown variant for forward compatibility.
5599    #[default]
5600    #[serde(other)]
5601    Unknown,
5602}