//! Auto-generated from session-events.schema.json — do not edit manually.
#![allow(deprecated)]
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::types::{RequestId, SessionId};
/// Identifies the kind of session event.
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum SessionEventType {
#[serde(rename = "session.start")]
SessionStart,
#[serde(rename = "session.resume")]
SessionResume,
#[serde(rename = "session.remote_steerable_changed")]
SessionRemoteSteerableChanged,
#[serde(rename = "session.error")]
SessionError,
#[serde(rename = "session.idle")]
SessionIdle,
#[serde(rename = "session.title_changed")]
SessionTitleChanged,
#[serde(rename = "session.schedule_created")]
SessionScheduleCreated,
#[serde(rename = "session.schedule_cancelled")]
SessionScheduleCancelled,
#[serde(rename = "session.schedule_rearmed")]
SessionScheduleRearmed,
#[serde(rename = "session.autopilot_objective_changed")]
SessionAutopilotObjectiveChanged,
#[serde(rename = "session.info")]
SessionInfo,
#[serde(rename = "session.warning")]
SessionWarning,
#[serde(rename = "session.model_change")]
SessionModelChange,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.auto_tier_recommendation")]
SessionAutoTierRecommendation,
#[serde(rename = "session.auto_tier_switch_failed")]
SessionAutoTierSwitchFailed,
#[serde(rename = "session.mode_changed")]
SessionModeChanged,
#[serde(rename = "session.mode_notice_delivered")]
SessionModeNoticeDelivered,
#[serde(rename = "session.session_limits_changed")]
SessionSessionLimitsChanged,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.permissions_changed")]
SessionPermissionsChanged,
#[serde(rename = "session.plan_changed")]
SessionPlanChanged,
#[serde(rename = "session.todos_changed")]
SessionTodosChanged,
#[serde(rename = "session.workspace_file_changed")]
SessionWorkspaceFileChanged,
#[serde(rename = "session.handoff")]
SessionHandoff,
#[serde(rename = "session.truncation")]
SessionTruncation,
#[serde(rename = "session.snapshot_rewind")]
SessionSnapshotRewind,
#[serde(rename = "session.shutdown")]
SessionShutdown,
#[serde(rename = "session.usage_checkpoint")]
SessionUsageCheckpoint,
#[serde(rename = "session.context_changed")]
SessionContextChanged,
#[serde(rename = "session.usage_info")]
SessionUsageInfo,
#[serde(rename = "session.context_cleared")]
SessionContextCleared,
#[serde(rename = "session.compaction_start")]
SessionCompactionStart,
#[serde(rename = "session.compaction_complete")]
SessionCompactionComplete,
#[serde(rename = "session.task_complete")]
SessionTaskComplete,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.completion_receipt")]
SessionCompletionReceipt,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_route_started")]
SessionFusionRouteStarted,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_route_failed")]
SessionFusionRouteFailed,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_resolved")]
SessionFusionResolved,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_completed")]
SessionFusionCompleted,
#[serde(rename = "user.message")]
UserMessage,
#[serde(rename = "pending_messages.modified")]
PendingMessagesModified,
#[serde(rename = "assistant.turn_start")]
AssistantTurnStart,
#[serde(rename = "assistant.turn_retry")]
AssistantTurnRetry,
#[serde(rename = "agent.interrupted")]
AgentInterrupted,
#[serde(rename = "assistant.intent")]
AssistantIntent,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_started")]
AssistantFusionPhaseStarted,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_activity")]
AssistantFusionPhaseActivity,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_completed")]
AssistantFusionPhaseCompleted,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_failed")]
AssistantFusionPhaseFailed,
#[serde(rename = "assistant.server_tool_progress")]
AssistantServerToolProgress,
#[serde(rename = "assistant.reasoning")]
AssistantReasoning,
#[serde(rename = "assistant.reasoning_delta")]
AssistantReasoningDelta,
#[serde(rename = "assistant.tool_call_delta")]
AssistantToolCallDelta,
#[serde(rename = "assistant.streaming_delta")]
AssistantStreamingDelta,
#[serde(rename = "assistant.message")]
AssistantMessage,
#[serde(rename = "assistant.message_start")]
AssistantMessageStart,
#[serde(rename = "assistant.message_delta")]
AssistantMessageDelta,
#[serde(rename = "assistant.turn_end")]
AssistantTurnEnd,
#[serde(rename = "assistant.idle")]
AssistantIdle,
#[serde(rename = "assistant.usage")]
AssistantUsage,
#[serde(rename = "prompt_cache_break")]
PromptCacheBreak,
#[serde(rename = "model.call_failure")]
ModelCallFailure,
#[serde(rename = "model.call_finished")]
ModelCallFinished,
#[serde(rename = "model.call_start")]
ModelCallStart,
#[serde(rename = "abort")]
Abort,
#[serde(rename = "tool.user_requested")]
ToolUserRequested,
#[serde(rename = "tool.execution_start")]
ToolExecutionStart,
#[serde(rename = "tool.execution_partial_result")]
ToolExecutionPartialResult,
#[serde(rename = "tool.execution_progress")]
ToolExecutionProgress,
#[serde(rename = "tool.execution_complete")]
ToolExecutionComplete,
#[serde(rename = "tool_search.activated")]
ToolSearchActivated,
#[serde(rename = "skill.invoked")]
SkillInvoked,
#[serde(rename = "sandbox.decision")]
SandboxDecision,
#[serde(rename = "subagent.started")]
SubagentStarted,
#[serde(rename = "subagent.configured")]
SubagentConfigured,
#[serde(rename = "subagent.completed")]
SubagentCompleted,
#[serde(rename = "subagent.failed")]
SubagentFailed,
#[serde(rename = "subagent.selected")]
SubagentSelected,
#[serde(rename = "subagent.deselected")]
SubagentDeselected,
#[serde(rename = "hook.start")]
HookStart,
#[serde(rename = "hook.end")]
HookEnd,
#[serde(rename = "hook.progress")]
HookProgress,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.binary_asset")]
SessionBinaryAsset,
#[serde(rename = "system.message")]
SystemMessage,
#[serde(rename = "system.notification")]
SystemNotification,
#[serde(rename = "permission.requested")]
PermissionRequested,
#[serde(rename = "permission.completed")]
PermissionCompleted,
#[serde(rename = "user_input.requested")]
UserInputRequested,
#[serde(rename = "user_input.completed")]
UserInputCompleted,
#[serde(rename = "elicitation.requested")]
ElicitationRequested,
#[serde(rename = "elicitation.completed")]
ElicitationCompleted,
#[serde(rename = "sampling.requested")]
SamplingRequested,
#[serde(rename = "sampling.completed")]
SamplingCompleted,
#[serde(rename = "mcp.oauth_required")]
McpOauthRequired,
#[serde(rename = "mcp.oauth_completed")]
McpOauthCompleted,
#[serde(rename = "mcp.headers_refresh_required")]
McpHeadersRefreshRequired,
#[serde(rename = "mcp.headers_refresh_completed")]
McpHeadersRefreshCompleted,
#[serde(rename = "session.custom_notification")]
SessionCustomNotification,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "ui.ephemeral_query")]
UiEphemeralQuery,
#[serde(rename = "external_tool.requested")]
ExternalToolRequested,
#[serde(rename = "external_tool.completed")]
ExternalToolCompleted,
#[serde(rename = "command.queued")]
CommandQueued,
#[serde(rename = "command.execute")]
CommandExecute,
#[serde(rename = "command.completed")]
CommandCompleted,
#[serde(rename = "auto_mode_switch.requested")]
AutoModeSwitchRequested,
#[serde(rename = "auto_mode_switch.completed")]
AutoModeSwitchCompleted,
#[serde(rename = "session_limits_exhausted.requested")]
SessionLimitsExhaustedRequested,
#[serde(rename = "session_limits_exhausted.completed")]
SessionLimitsExhaustedCompleted,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.auto_mode_resolved")]
SessionAutoModeResolved,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.managed_settings_resolved")]
SessionManagedSettingsResolved,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.managed_settings_enforced")]
SessionManagedSettingsEnforced,
#[serde(rename = "commands.changed")]
CommandsChanged,
#[serde(rename = "capabilities.changed")]
CapabilitiesChanged,
#[serde(rename = "exit_plan_mode.requested")]
ExitPlanModeRequested,
#[serde(rename = "exit_plan_mode.completed")]
ExitPlanModeCompleted,
#[serde(rename = "session.tools_updated")]
SessionToolsUpdated,
#[serde(rename = "session.background_tasks_changed")]
SessionBackgroundTasksChanged,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "factory.run_updated")]
FactoryRunUpdated,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "factory.run_started")]
FactoryRunStarted,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "factory.run_settled")]
FactoryRunSettled,
#[serde(rename = "session.skills_loaded")]
SessionSkillsLoaded,
#[serde(rename = "session.custom_agents_updated")]
SessionCustomAgentsUpdated,
#[serde(rename = "session.mcp_servers_loaded")]
SessionMcpServersLoaded,
#[serde(rename = "session.mcp_server_status_changed")]
SessionMcpServerStatusChanged,
#[serde(rename = "session.mcp_server_removed")]
SessionMcpServerRemoved,
#[serde(rename = "session.mcp_server_needs_reconnect")]
SessionMcpServerNeedsReconnect,
#[serde(rename = "mcp.tools.list_changed")]
McpToolsListChanged,
#[serde(rename = "mcp.resources.list_changed")]
McpResourcesListChanged,
#[serde(rename = "mcp.prompts.list_changed")]
McpPromptsListChanged,
#[serde(rename = "session.extensions_loaded")]
SessionExtensionsLoaded,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.opened")]
SessionCanvasOpened,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.registry_changed")]
SessionCanvasRegistryChanged,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.closed")]
SessionCanvasClosed,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.unavailable")]
SessionCanvasUnavailable,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.recorded")]
SessionCanvasRecorded,
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.removed")]
SessionCanvasRemoved,
#[serde(rename = "session.extensions.attachments_pushed")]
SessionExtensionsAttachmentsPushed,
#[serde(rename = "mcp_app.tool_call_complete")]
McpAppToolCallComplete,
/// Unknown event type for forward compatibility.
#[default]
#[serde(other)]
Unknown,
}
/// Typed session event data, discriminated by the event `type` field.
///
/// Use with [`TypedSessionEvent`] for fully typed event handling.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "data")]
pub enum SessionEventData {
#[serde(rename = "session.start")]
SessionStart(SessionStartData),
#[serde(rename = "session.resume")]
SessionResume(SessionResumeData),
#[serde(rename = "session.remote_steerable_changed")]
SessionRemoteSteerableChanged(SessionRemoteSteerableChangedData),
#[serde(rename = "session.error")]
SessionError(SessionErrorData),
#[serde(rename = "session.idle")]
SessionIdle(SessionIdleData),
#[serde(rename = "session.title_changed")]
SessionTitleChanged(SessionTitleChangedData),
#[serde(rename = "session.schedule_created")]
SessionScheduleCreated(SessionScheduleCreatedData),
#[serde(rename = "session.schedule_cancelled")]
SessionScheduleCancelled(SessionScheduleCancelledData),
#[serde(rename = "session.schedule_rearmed")]
SessionScheduleRearmed(SessionScheduleRearmedData),
#[serde(rename = "session.autopilot_objective_changed")]
SessionAutopilotObjectiveChanged(SessionAutopilotObjectiveChangedData),
#[serde(rename = "session.info")]
SessionInfo(SessionInfoData),
#[serde(rename = "session.warning")]
SessionWarning(SessionWarningData),
#[serde(rename = "session.model_change")]
SessionModelChange(SessionModelChangeData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.auto_tier_recommendation")]
SessionAutoTierRecommendation(SessionAutoTierRecommendationData),
#[serde(rename = "session.auto_tier_switch_failed")]
SessionAutoTierSwitchFailed(SessionAutoTierSwitchFailedData),
#[serde(rename = "session.mode_changed")]
SessionModeChanged(SessionModeChangedData),
#[serde(rename = "session.mode_notice_delivered")]
SessionModeNoticeDelivered(SessionModeNoticeDeliveredData),
#[serde(rename = "session.session_limits_changed")]
SessionSessionLimitsChanged(SessionSessionLimitsChangedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.permissions_changed")]
SessionPermissionsChanged(SessionPermissionsChangedData),
#[serde(rename = "session.plan_changed")]
SessionPlanChanged(SessionPlanChangedData),
#[serde(rename = "session.todos_changed")]
SessionTodosChanged(SessionTodosChangedData),
#[serde(rename = "session.workspace_file_changed")]
SessionWorkspaceFileChanged(SessionWorkspaceFileChangedData),
#[serde(rename = "session.handoff")]
SessionHandoff(SessionHandoffData),
#[serde(rename = "session.truncation")]
SessionTruncation(SessionTruncationData),
#[serde(rename = "session.snapshot_rewind")]
SessionSnapshotRewind(SessionSnapshotRewindData),
#[serde(rename = "session.shutdown")]
SessionShutdown(SessionShutdownData),
#[serde(rename = "session.usage_checkpoint")]
SessionUsageCheckpoint(SessionUsageCheckpointData),
#[serde(rename = "session.context_changed")]
SessionContextChanged(SessionContextChangedData),
#[serde(rename = "session.usage_info")]
SessionUsageInfo(SessionUsageInfoData),
#[serde(rename = "session.context_cleared")]
SessionContextCleared(SessionContextClearedData),
#[serde(rename = "session.compaction_start")]
SessionCompactionStart(SessionCompactionStartData),
#[serde(rename = "session.compaction_complete")]
SessionCompactionComplete(SessionCompactionCompleteData),
#[serde(rename = "session.task_complete")]
SessionTaskComplete(SessionTaskCompleteData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.completion_receipt")]
SessionCompletionReceipt(SessionCompletionReceiptData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_route_started")]
SessionFusionRouteStarted(SessionFusionRouteStartedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_route_failed")]
SessionFusionRouteFailed(SessionFusionRouteFailedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_resolved")]
SessionFusionResolved(SessionFusionResolvedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.fusion_completed")]
SessionFusionCompleted(SessionFusionCompletedData),
#[serde(rename = "user.message")]
UserMessage(UserMessageData),
#[serde(rename = "pending_messages.modified")]
PendingMessagesModified(PendingMessagesModifiedData),
#[serde(rename = "assistant.turn_start")]
AssistantTurnStart(AssistantTurnStartData),
#[serde(rename = "assistant.turn_retry")]
AssistantTurnRetry(AssistantTurnRetryData),
#[serde(rename = "agent.interrupted")]
AgentInterrupted(AgentInterruptedData),
#[serde(rename = "assistant.intent")]
AssistantIntent(AssistantIntentData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_started")]
AssistantFusionPhaseStarted(AssistantFusionPhaseStartedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_activity")]
AssistantFusionPhaseActivity(AssistantFusionPhaseActivityData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_completed")]
AssistantFusionPhaseCompleted(AssistantFusionPhaseCompletedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "assistant.fusion_phase_failed")]
AssistantFusionPhaseFailed(AssistantFusionPhaseFailedData),
#[serde(rename = "assistant.server_tool_progress")]
AssistantServerToolProgress(AssistantServerToolProgressData),
#[serde(rename = "assistant.reasoning")]
AssistantReasoning(AssistantReasoningData),
#[serde(rename = "assistant.reasoning_delta")]
AssistantReasoningDelta(AssistantReasoningDeltaData),
#[serde(rename = "assistant.tool_call_delta")]
AssistantToolCallDelta(AssistantToolCallDeltaData),
#[serde(rename = "assistant.streaming_delta")]
AssistantStreamingDelta(AssistantStreamingDeltaData),
#[serde(rename = "assistant.message")]
AssistantMessage(AssistantMessageData),
#[serde(rename = "assistant.message_start")]
AssistantMessageStart(AssistantMessageStartData),
#[serde(rename = "assistant.message_delta")]
AssistantMessageDelta(AssistantMessageDeltaData),
#[serde(rename = "assistant.turn_end")]
AssistantTurnEnd(AssistantTurnEndData),
#[serde(rename = "assistant.idle")]
AssistantIdle(AssistantIdleData),
#[serde(rename = "assistant.usage")]
AssistantUsage(AssistantUsageData),
#[serde(rename = "prompt_cache_break")]
PromptCacheBreak(PromptCacheBreakData),
#[serde(rename = "model.call_failure")]
ModelCallFailure(ModelCallFailureData),
#[serde(rename = "model.call_finished")]
ModelCallFinished(ModelCallFinishedData),
#[serde(rename = "model.call_start")]
ModelCallStart(ModelCallStartData),
#[serde(rename = "abort")]
Abort(AbortData),
#[serde(rename = "tool.user_requested")]
ToolUserRequested(ToolUserRequestedData),
#[serde(rename = "tool.execution_start")]
ToolExecutionStart(ToolExecutionStartData),
#[serde(rename = "tool.execution_partial_result")]
ToolExecutionPartialResult(ToolExecutionPartialResultData),
#[serde(rename = "tool.execution_progress")]
ToolExecutionProgress(ToolExecutionProgressData),
#[serde(rename = "tool.execution_complete")]
ToolExecutionComplete(ToolExecutionCompleteData),
#[serde(rename = "tool_search.activated")]
ToolSearchActivated(ToolSearchActivatedData),
#[serde(rename = "skill.invoked")]
SkillInvoked(SkillInvokedData),
#[serde(rename = "sandbox.decision")]
SandboxDecision(SandboxDecisionData),
#[serde(rename = "subagent.started")]
SubagentStarted(SubagentStartedData),
#[serde(rename = "subagent.configured")]
SubagentConfigured(SubagentConfiguredData),
#[serde(rename = "subagent.completed")]
SubagentCompleted(SubagentCompletedData),
#[serde(rename = "subagent.failed")]
SubagentFailed(SubagentFailedData),
#[serde(rename = "subagent.selected")]
SubagentSelected(SubagentSelectedData),
#[serde(rename = "subagent.deselected")]
SubagentDeselected(SubagentDeselectedData),
#[serde(rename = "hook.start")]
HookStart(HookStartData),
#[serde(rename = "hook.end")]
HookEnd(HookEndData),
#[serde(rename = "hook.progress")]
HookProgress(HookProgressData),
#[serde(rename = "session.binary_asset")]
SessionBinaryAsset(SessionBinaryAssetData),
#[serde(rename = "system.message")]
SystemMessage(SystemMessageData),
#[serde(rename = "system.notification")]
SystemNotification(SystemNotificationData),
#[serde(rename = "permission.requested")]
PermissionRequested(PermissionRequestedData),
#[serde(rename = "permission.completed")]
PermissionCompleted(PermissionCompletedData),
#[serde(rename = "user_input.requested")]
UserInputRequested(UserInputRequestedData),
#[serde(rename = "user_input.completed")]
UserInputCompleted(UserInputCompletedData),
#[serde(rename = "elicitation.requested")]
ElicitationRequested(ElicitationRequestedData),
#[serde(rename = "elicitation.completed")]
ElicitationCompleted(ElicitationCompletedData),
#[serde(rename = "sampling.requested")]
SamplingRequested(SamplingRequestedData),
#[serde(rename = "sampling.completed")]
SamplingCompleted(SamplingCompletedData),
#[serde(rename = "mcp.oauth_required")]
McpOauthRequired(McpOauthRequiredData),
#[serde(rename = "mcp.oauth_completed")]
McpOauthCompleted(McpOauthCompletedData),
#[serde(rename = "mcp.headers_refresh_required")]
McpHeadersRefreshRequired(McpHeadersRefreshRequiredData),
#[serde(rename = "mcp.headers_refresh_completed")]
McpHeadersRefreshCompleted(McpHeadersRefreshCompletedData),
#[serde(rename = "session.custom_notification")]
SessionCustomNotification(SessionCustomNotificationData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "ui.ephemeral_query")]
UiEphemeralQuery(UiEphemeralQueryData),
#[serde(rename = "external_tool.requested")]
ExternalToolRequested(ExternalToolRequestedData),
#[serde(rename = "external_tool.completed")]
ExternalToolCompleted(ExternalToolCompletedData),
#[serde(rename = "command.queued")]
CommandQueued(CommandQueuedData),
#[serde(rename = "command.execute")]
CommandExecute(CommandExecuteData),
#[serde(rename = "command.completed")]
CommandCompleted(CommandCompletedData),
#[serde(rename = "auto_mode_switch.requested")]
AutoModeSwitchRequested(AutoModeSwitchRequestedData),
#[serde(rename = "auto_mode_switch.completed")]
AutoModeSwitchCompleted(AutoModeSwitchCompletedData),
#[serde(rename = "session_limits_exhausted.requested")]
SessionLimitsExhaustedRequested(SessionLimitsExhaustedRequestedData),
#[serde(rename = "session_limits_exhausted.completed")]
SessionLimitsExhaustedCompleted(SessionLimitsExhaustedCompletedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.auto_mode_resolved")]
SessionAutoModeResolved(SessionAutoModeResolvedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.managed_settings_resolved")]
SessionManagedSettingsResolved(SessionManagedSettingsResolvedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.managed_settings_enforced")]
SessionManagedSettingsEnforced(SessionManagedSettingsEnforcedData),
#[serde(rename = "commands.changed")]
CommandsChanged(CommandsChangedData),
#[serde(rename = "capabilities.changed")]
CapabilitiesChanged(CapabilitiesChangedData),
#[serde(rename = "exit_plan_mode.requested")]
ExitPlanModeRequested(ExitPlanModeRequestedData),
#[serde(rename = "exit_plan_mode.completed")]
ExitPlanModeCompleted(ExitPlanModeCompletedData),
#[serde(rename = "session.tools_updated")]
SessionToolsUpdated(SessionToolsUpdatedData),
#[serde(rename = "session.background_tasks_changed")]
SessionBackgroundTasksChanged(SessionBackgroundTasksChangedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "factory.run_updated")]
FactoryRunUpdated(FactoryRunUpdatedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "factory.run_started")]
FactoryRunStarted(FactoryRunStartedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "factory.run_settled")]
FactoryRunSettled(FactoryRunSettledData),
#[serde(rename = "session.skills_loaded")]
SessionSkillsLoaded(SessionSkillsLoadedData),
#[serde(rename = "session.custom_agents_updated")]
SessionCustomAgentsUpdated(SessionCustomAgentsUpdatedData),
#[serde(rename = "session.mcp_servers_loaded")]
SessionMcpServersLoaded(SessionMcpServersLoadedData),
#[serde(rename = "session.mcp_server_status_changed")]
SessionMcpServerStatusChanged(SessionMcpServerStatusChangedData),
#[serde(rename = "session.mcp_server_removed")]
SessionMcpServerRemoved(SessionMcpServerRemovedData),
#[serde(rename = "session.mcp_server_needs_reconnect")]
SessionMcpServerNeedsReconnect(SessionMcpServerNeedsReconnectData),
#[serde(rename = "mcp.tools.list_changed")]
McpToolsListChanged(McpToolsListChangedData),
#[serde(rename = "mcp.resources.list_changed")]
McpResourcesListChanged(McpResourcesListChangedData),
#[serde(rename = "mcp.prompts.list_changed")]
McpPromptsListChanged(McpPromptsListChangedData),
#[serde(rename = "session.extensions_loaded")]
SessionExtensionsLoaded(SessionExtensionsLoadedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.opened")]
SessionCanvasOpened(SessionCanvasOpenedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.registry_changed")]
SessionCanvasRegistryChanged(SessionCanvasRegistryChangedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.closed")]
SessionCanvasClosed(SessionCanvasClosedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.unavailable")]
SessionCanvasUnavailable(SessionCanvasUnavailableData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.recorded")]
SessionCanvasRecorded(SessionCanvasRecordedData),
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(rename = "session.canvas.removed")]
SessionCanvasRemoved(SessionCanvasRemovedData),
#[serde(rename = "session.extensions.attachments_pushed")]
SessionExtensionsAttachmentsPushed(SessionExtensionsAttachmentsPushedData),
#[serde(rename = "mcp_app.tool_call_complete")]
McpAppToolCallComplete(McpAppToolCallCompleteData),
}
/// A session event with typed data payload.
///
/// The common event fields (id, timestamp, parentId, ephemeral, agentId)
/// are available directly. The event-specific data is in the `payload`
/// field as a [`SessionEventData`] enum.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TypedSessionEvent {
/// Unique event identifier (UUID v4).
pub id: String,
/// ISO 8601 timestamp when the event was created.
pub timestamp: String,
/// ID of the preceding event in the chain.
#[serde(skip_serializing_if = "Option::is_none")]
pub parent_id: Option,
/// When true, the event is transient and not persisted.
#[serde(skip_serializing_if = "Option::is_none")]
pub ephemeral: Option,
/// Sub-agent instance identifier. Absent for events from the root /
/// main agent and session-level events.
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_id: Option,
/// The typed event payload (discriminated by event type).
#[serde(flatten)]
pub payload: SessionEventData,
}
/// Working directory and git context at session start
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkingDirectoryContext {
/// Base commit of current git branch at session start time
#[serde(skip_serializing_if = "Option::is_none")]
pub base_commit: Option,
/// Current git branch name
#[serde(skip_serializing_if = "Option::is_none")]
pub branch: Option,
/// Current working directory path
pub cwd: String,
/// Root directory of the git repository, resolved via git rev-parse
#[serde(skip_serializing_if = "Option::is_none")]
pub git_root: Option,
/// Head commit of current git branch at session start time
#[serde(skip_serializing_if = "Option::is_none")]
pub head_commit: Option,
/// Hosting platform type of the repository (github or ado)
#[serde(skip_serializing_if = "Option::is_none")]
pub host_type: Option,
/// Set on the immediate preliminary event of a working-directory change, before the git context is resolved. A settled follow-up event (enriched with git context, or cwd-only for a non-repository) is always emitted afterward, so observers may defer to it. Absent on standalone/final events (e.g. relay context changes).
#[serde(skip_serializing_if = "Option::is_none")]
pub pending_git_context: Option,
/// Repository identifier derived from the git remote URL ("owner/name" for GitHub, "org/project/repo" for Azure DevOps)
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option,
/// Raw host string from the git remote URL (e.g. "github.com", "mycompany.ghe.com", "dev.azure.com")
#[serde(skip_serializing_if = "Option::is_none")]
pub repository_host: Option,
}
/// Per-session configuration for the built-in GitHub MCP server
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GitHubMcpToolConfig {
/// Additional GitHub MCP tools requested by the session
#[serde(skip_serializing_if = "Option::is_none")]
pub additional_tools: Option>,
/// Additional GitHub MCP toolsets requested by the session
#[serde(skip_serializing_if = "Option::is_none")]
pub additional_toolsets: Option>,
/// Whether to use the read-write endpoint and request all toolsets
#[serde(skip_serializing_if = "Option::is_none")]
pub enable_all_tools: Option,
/// Whether to request the GitHub MCP insiders build
#[serde(skip_serializing_if = "Option::is_none")]
pub enable_insiders_mode: Option,
}
/// Optional session limits.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionLimitsConfig {
/// Maximum AI Credits allowed across the session's current accounting window.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_ai_credits: Option,
}
/// Session event "session.start". Session initialization metadata including context and configuration
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionStartData {
/// Whether the session was already in use by another client at start time
#[serde(skip_serializing_if = "Option::is_none")]
pub already_in_use: Option,
/// Auto routing preference selected at session creation time
#[serde(skip_serializing_if = "Option::is_none")]
pub auto_tier: Option,
/// Working directory and git context at session start
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option,
/// Context tier selected at session creation time for models with tiered context pricing; null when no tier is selected (e.g., non-tiered model)
#[serde(skip_serializing_if = "Option::is_none")]
pub context_tier: Option,
/// Version string of the Copilot application
pub copilot_version: String,
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub detached_from_spawning_parent_session_id: Option,
/// Per-session GitHub MCP override persisted for cold resume
#[serde(skip_serializing_if = "Option::is_none")]
pub github_mcp_tool_config: Option,
/// Identifier of the software producing the events (e.g., "copilot-agent")
pub producer: String,
/// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_summary: Option,
/// Whether this session supports remote steering via GitHub
#[serde(skip_serializing_if = "Option::is_none")]
pub remote_steerable: Option,
/// Model selected at session creation time, if any
#[serde(skip_serializing_if = "Option::is_none")]
pub selected_model: Option,
/// Unique identifier for the session
pub session_id: SessionId,
/// Session limits configured at session creation time, if any
#[serde(skip_serializing_if = "Option::is_none")]
pub session_limits: Option,
/// ISO 8601 timestamp when the session was created
pub start_time: String,
/// Output verbosity level used for model calls, if applicable (e.g. "low", "medium", "high")
#[serde(skip_serializing_if = "Option::is_none")]
pub verbosity: Option,
/// Schema version number for the session event format
pub version: i64,
}
/// Session event "session.resume". Session resume metadata including current context and event count
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionResumeData {
/// Whether the session was already in use by another client at resume time
#[serde(skip_serializing_if = "Option::is_none")]
pub already_in_use: Option,
/// Auto routing preference active at resume time
#[serde(skip_serializing_if = "Option::is_none")]
pub auto_tier: Option,
/// Updated working directory and git context at resume time
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option,
/// Context tier currently selected at resume time; null when no tier is active
#[serde(skip_serializing_if = "Option::is_none")]
pub context_tier: Option,
/// 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 or omitted, pending work is normally marked as interrupted unless the resume passively joined live work owned by another client; sessionWasActive distinguishes that case.
#[serde(skip_serializing_if = "Option::is_none")]
pub continue_pending_work: Option,
/// Total number of persisted events in the session at the time of resume
pub event_count: i64,
/// 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
#[serde(skip_serializing_if = "Option::is_none")]
pub events_file_size_bytes: Option,
/// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_summary: Option,
/// Whether this session supports remote steering via GitHub
#[serde(skip_serializing_if = "Option::is_none")]
pub remote_steerable: Option,
/// ISO 8601 timestamp when the session was resumed
pub resume_time: String,
/// Model currently selected at resume time
#[serde(skip_serializing_if = "Option::is_none")]
pub selected_model: Option,
/// Session limits currently configured at resume time; null when no limits are active
#[serde(skip_serializing_if = "Option::is_none")]
pub session_limits: Option,
/// True when this resume passively joined a session that already had live work running in the runtime - an agent turn, a native queue run, a queued resume continuation, or an in-flight send (for example, an extension joining a session another client was actively driving). False (or omitted) when the session had no live work or when the resume explicitly abandoned pending work, including cold resumes and suspended sessions that remain resident in memory.
#[serde(skip_serializing_if = "Option::is_none")]
pub session_was_active: Option,
/// Output verbosity level used for model calls, if applicable (e.g. "low", "medium", "high")
#[serde(skip_serializing_if = "Option::is_none")]
pub verbosity: Option,
}
/// Session event "session.remote_steerable_changed". Notifies that the session's remote steering capability has changed
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionRemoteSteerableChangedData {
/// Whether this session now supports remote steering via GitHub
pub remote_steerable: bool,
}
/// Session event "session.error". Error details for timeline display including message and optional diagnostic information
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionErrorData {
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub eligible_for_auto_switch: Option,
/// 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"`).
#[serde(skip_serializing_if = "Option::is_none")]
pub error_code: Option,
/// Category of error (e.g., "authentication", "authorization", "quota", "rate_limit", "context_limit", "query")
pub error_type: String,
/// Human-readable error message
pub message: String,
/// GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
#[serde(skip_serializing_if = "Option::is_none")]
pub provider_call_id: Option,
/// What the user must do to recover, when the runtime knows of an action. The `message` never names a client affordance, so a client that offers one — a slash command, a settings pane, a link — renders it from this value.
#[serde(skip_serializing_if = "Option::is_none")]
pub remediation: Option,
/// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation
#[serde(skip_serializing_if = "Option::is_none")]
pub service_request_id: Option,
/// Error stack trace, when available
#[serde(skip_serializing_if = "Option::is_none")]
pub stack: Option,
/// HTTP status code from the upstream request, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub status_code: Option,
/// Optional URL associated with this error that the user can open in a browser
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option,
}
/// Session event "session.idle". Payload indicating the session is idle with no background agents or attached shell commands in flight
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionIdleData {
/// True when the preceding agentic loop was cancelled via abort signal
#[serde(skip_serializing_if = "Option::is_none")]
pub aborted: Option,
/// The session mode the agent was operating in when it went idle, when the mode is known. Lets turn-scoped consumers distinguish an autopilot continuation boundary (where the agent keeps working after this idle) from a genuine turn completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option,
}
/// Session event "session.title_changed". Session title change payload containing the new display title
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionTitleChangedData {
/// The new display title for the session
pub title: String,
}
/// Session event "session.schedule_created". Scheduled prompt registered via /every or /after
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionScheduleCreatedData {
/// Absolute fire time (epoch milliseconds) for a one-shot calendar schedule
#[serde(skip_serializing_if = "Option::is_none")]
pub at: Option,
/// 5-field cron expression for a recurring calendar schedule, evaluated in `tz`
#[serde(skip_serializing_if = "Option::is_none")]
pub cron: Option,
/// 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)
#[serde(skip_serializing_if = "Option::is_none")]
pub display_prompt: Option,
/// Sequential id assigned to the scheduled prompt within the session
pub id: i64,
/// Interval between ticks in milliseconds (relative-interval schedules)
#[serde(skip_serializing_if = "Option::is_none")]
pub interval_ms: Option,
/// Who created the schedule (`user` or `model`). Persisted so a resumed session keeps gating non-user schedules from firing skills that opted out of model invocation. Absent on entries created before this field existed; a missing origin fails closed (treated the same as a non-user origin), so such a schedule may not resolve a `disable-model-invocation` skill.
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option,
/// Prompt text that gets enqueued on every tick
pub prompt: String,
/// Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`)
#[serde(skip_serializing_if = "Option::is_none")]
pub recurring: Option,
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub self_paced: Option,
/// IANA timezone the `cron` expression is evaluated in
#[serde(skip_serializing_if = "Option::is_none")]
pub tz: Option,
}
/// Session event "session.schedule_cancelled". Scheduled prompt cancelled from the schedule manager dialog
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionScheduleCancelledData {
/// Id of the scheduled prompt that was cancelled
pub id: i64,
}
/// Session event "session.schedule_rearmed". Self-paced schedule re-armed for its next run
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionScheduleRearmedData {
/// Id of the self-paced schedule that was re-armed
pub id: i64,
/// Absolute time (epoch milliseconds) the model armed the next run to fire
pub next_run_at: i64,
}
/// Session event "session.autopilot_objective_changed". Autopilot objective state file operation details indicating what changed
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionAutopilotObjectiveChangedData {
/// Current autopilot objective id, if one exists
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option,
/// The type of operation performed on the autopilot objective state file
pub operation: AutopilotObjectiveChangedOperation,
/// Current autopilot objective status, if one exists
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option,
}
/// Session event "session.info". Informational message for timeline display with categorization
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionInfoData {
/// Category of informational message (e.g., "notification", "timing", "context_window", "mcp", "snapshot", "configuration", "authentication", "model")
pub info_type: String,
/// Human-readable informational message for display in the timeline
pub message: String,
/// Optional actionable tip displayed with this message
#[serde(skip_serializing_if = "Option::is_none")]
pub tip: Option,
/// Optional URL associated with this message that the user can open in a browser
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option,
}
/// Session event "session.warning". Warning message for timeline display with categorization
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionWarningData {
/// Human-readable warning message for display in the timeline
pub message: String,
/// What the user must do to recover, when the runtime knows of an action. The `message` never names a client affordance, so a client that offers one — a slash command, a settings pane, a link — renders it from this value.
#[serde(skip_serializing_if = "Option::is_none")]
pub remediation: Option,
/// Optional URL associated with this warning that the user can open in a browser
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option,
/// Category of warning (e.g., "subscription", "policy", "mcp")
pub warning_type: String,
}
/// Session event "session.model_change". Model change details including previous and new model identifiers
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionModelChangeData {
/// Committed Auto preference after the model configuration change, when applicable.
#[serde(skip_serializing_if = "Option::is_none")]
pub auto_tier: Option,
/// Reason the change happened, when not user-initiated. `"rate_limit_auto_switch"` for changes triggered by the auto-mode-switch rate-limit recovery path, or `"refusal_fallback"` when the active model declined a request (content refusal) and the runtime switched to the configured refusal-fallback model. UI clients can use this to render contextual copy.
#[serde(skip_serializing_if = "Option::is_none")]
pub cause: Option,
/// Context tier after the model change; null explicitly clears a previously selected tier
#[serde(skip_serializing_if = "Option::is_none")]
pub context_tier: Option,
/// Newly selected model identifier
pub new_model: String,
/// Previously committed Auto preference, when one was explicitly selected.
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_auto_tier: Option,
/// Model that was previously selected, if any
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_model: Option,
/// Reasoning effort level before the model change, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_reasoning_effort: Option,
/// Reasoning summary mode before the model change, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_reasoning_summary: Option,
/// Output verbosity level before the model change, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_verbosity: Option,
/// Reasoning effort level after the model change, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Reasoning summary mode after the model change, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_summary: Option,
/// Origin of the effective model change, when known.
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option,
/// Output verbosity level after the model change, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub verbosity: Option,
}
/// Session event "session.auto_tier_recommendation". Live-only Auto preference recommendation from Copilot API after a successful Auto model call.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionAutoTierRecommendationData {
/// Recommended Auto preference.
pub recommended_auto_tier: RecommendedAutoTier,
}
/// Session event "session.auto_tier_switch_failed". A transient Auto preference failure emitted when the runtime cannot mint or accept a usable model and token pair. The previously effective preference remains active, so SDK clients can surface a non-blocking failure without changing their committed-tier state. This event is ephemeral and is not persisted or replayed on resume.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionAutoTierSwitchFailedData {
/// Auto preference that remains effective after the failed request.
#[serde(skip_serializing_if = "Option::is_none")]
pub effective_auto_tier: Option,
/// Low-cardinality failure outcome reported by Auto resolution.
pub reason: AutoTierSwitchFailureReason,
/// Auto preference that failed to activate, or null when returning to provider-default routing failed.
pub requested_auto_tier: Option,
}
/// Session event "session.mode_changed". Agent mode change details including previous and new modes
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionModeChangedData {
/// The session mode the agent is operating in
pub new_mode: SessionMode,
/// The session mode the agent is operating in
pub previous_mode: SessionMode,
}
/// Session event "session.mode_notice_delivered". Records that a mode transition notice reached the model so cache-stable mode tools can remain offered across resume.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionModeNoticeDeliveredData {
/// Model-visible transition notice persisted for a mid-turn delivery
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option,
/// Mode established by the delivered transition notice
pub mode: SessionMode,
}
/// Session event "session.session_limits_changed". Session limits update details. Null clears the limits.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionSessionLimitsChangedData {
/// Current session limits, or null when no limits are active
pub session_limits: Option,
}
/// Session event "session.permissions_changed". Permission-mode transition details.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionPermissionsChangedData {
/// Explicit LLM judge model override used by assisted mode; omitted when the provider default applies
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub assisted_approval_model: Option,
/// Permission mode after the change
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option,
/// Permission mode before the change
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_mode: Option,
}
/// Session event "session.plan_changed". Plan file operation details indicating what changed
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionPlanChangedData {
/// The type of operation performed on the plan file
pub operation: PlanChangedOperation,
}
/// 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.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionTodosChangedData {}
/// Session event "session.workspace_file_changed". Workspace file change details including path and operation type
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionWorkspaceFileChangedData {
/// Whether the file was newly created or updated
pub operation: WorkspaceFileChangedOperation,
/// Relative path within the session workspace files directory
pub path: String,
}
/// Repository context for the handed-off session
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct HandoffRepository {
/// Git branch name, if applicable
#[serde(skip_serializing_if = "Option::is_none")]
pub branch: Option,
/// Repository name
pub name: String,
/// Repository owner (user or organization)
pub owner: String,
}
/// Session event "session.handoff". Session handoff metadata including source, context, and repository information
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionHandoffData {
/// Additional context information for the handoff
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option,
/// ISO 8601 timestamp when the handoff occurred
pub handoff_time: String,
/// GitHub host URL for the source session (e.g., https://github.com or https://tenant.ghe.com)
#[serde(skip_serializing_if = "Option::is_none")]
pub host: Option,
/// Session ID of the remote session being handed off
#[serde(skip_serializing_if = "Option::is_none")]
pub remote_session_id: Option,
/// Repository context for the handed-off session
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option,
/// Origin type of the session being handed off
pub source_type: HandoffSourceType,
/// Summary of the work done in the source session
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option,
}
/// Session event "session.truncation". Conversation truncation statistics including token counts and removed content metrics
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionTruncationData {
/// Number of messages removed by truncation
pub messages_removed_during_truncation: i64,
/// Identifier of the component that performed truncation (e.g., "BasicTruncator")
pub performed_by: String,
/// Number of conversation messages after truncation
pub post_truncation_messages_length: i64,
/// Total tokens in conversation messages after truncation
pub post_truncation_tokens_in_messages: i64,
/// Number of conversation messages before truncation
pub pre_truncation_messages_length: i64,
/// Total tokens in conversation messages before truncation
pub pre_truncation_tokens_in_messages: i64,
/// Maximum token count for the model's context window
pub token_limit: i64,
/// Number of tokens removed by truncation
pub tokens_removed_during_truncation: i64,
}
/// Session event "session.snapshot_rewind". Session rewind details including target event and count of removed events
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionSnapshotRewindData {
/// Number of events that were removed by the rewind
pub events_removed: i64,
/// Event ID that was rewound to; this event and all after it were removed
pub up_to_event_id: String,
}
/// Request count and cost metrics
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownModelMetricRequests {
/// Cumulative cost multiplier for requests to this model
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub cost: Option,
/// Total number of API requests made to this model
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option,
}
/// A token-type entry in a shutdown model metric, storing the accumulated token count.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownModelMetricTokenDetail {
/// Accumulated token count for this token type
pub token_count: i64,
}
/// Token usage breakdown
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownModelMetricUsage {
/// Total tokens read from prompt cache across all requests
pub cache_read_tokens: i64,
/// Total tokens written to prompt cache across all requests
pub cache_write_tokens: i64,
/// Total input tokens consumed across all requests to this model
pub input_tokens: i64,
/// Total output tokens produced across all requests to this model
pub output_tokens: i64,
/// Total reasoning tokens produced across all requests to this model
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_tokens: Option,
}
/// Per-model shutdown metrics with request counts, token usage, nano-AI units, and token details.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownModelMetric {
/// Request count and cost metrics
pub requests: ShutdownModelMetricRequests,
/// Token count details per type
#[serde(skip_serializing_if = "Option::is_none")]
pub token_details: Option>,
/// Accumulated nano-AI units cost for this model
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub total_nano_aiu: Option,
/// Token usage breakdown
pub usage: ShutdownModelMetricUsage,
}
/// Usage attributed to one agent instance at session shutdown.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownAgentMetric {
/// Human-readable label for this subagent invocation, copied from the originating `subagent.started` event. For task-tool subagents this is the invocation's task description rather than the agent's configured display name, so group by `agentName` for stable per-agent labels.
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_display_name: Option,
/// Configured agent name, when this is a subagent
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_name: Option,
/// Per-model usage for this agent, keyed by model identifier
pub model_metrics: HashMap,
/// Time spent in model API calls by this agent, in milliseconds
pub total_api_duration_ms: i64,
/// Accumulated nano-AI units cost for this agent
pub total_nano_aiu: f64,
}
/// Aggregate code change metrics for the session
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownCodeChanges {
/// List of file paths that were modified during the session
pub files_modified: Vec,
/// Total number of lines added during the session
pub lines_added: i64,
/// Total number of lines removed during the session
pub lines_removed: i64,
}
/// A session-wide shutdown token-type entry storing the accumulated token count.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShutdownTokenDetail {
/// Accumulated token count for this token type
pub token_count: i64,
}
/// Session event "session.shutdown". Session termination metrics including usage statistics, code changes, and shutdown reason
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionShutdownData {
/// Per-agent usage breakdown, keyed by agent instance identifier. The main conversation uses the stable key `main`.
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_metrics: Option>,
/// Aggregate code change metrics for the session
pub code_changes: ShutdownCodeChanges,
/// Non-system message token count at shutdown
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_tokens: Option,
/// Model that was selected at the time of shutdown
#[serde(skip_serializing_if = "Option::is_none")]
pub current_model: Option,
/// Total tokens in context window at shutdown
#[serde(skip_serializing_if = "Option::is_none")]
pub current_tokens: Option,
/// Error description when shutdownType is "error"
#[serde(skip_serializing_if = "Option::is_none")]
pub error_reason: Option,
/// 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
#[serde(skip_serializing_if = "Option::is_none")]
pub events_file_size_bytes: Option,
/// Per-model usage breakdown, keyed by model identifier
pub model_metrics: HashMap,
/// Unix timestamp (milliseconds) when the session started
pub session_start_time: i64,
/// Whether the session ended normally ("routine") or due to a crash/fatal error ("error")
pub shutdown_type: ShutdownType,
/// System message token count at shutdown
#[serde(skip_serializing_if = "Option::is_none")]
pub system_tokens: Option,
/// Session-wide per-token-type accumulated token counts
#[serde(skip_serializing_if = "Option::is_none")]
pub token_details: Option>,
/// Tool definitions token count at shutdown
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_definitions_tokens: Option,
/// Cumulative time spent in API calls during the session, in milliseconds
pub total_api_duration_ms: i64,
/// Session-wide accumulated nano-AI units cost
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub total_nano_aiu: Option,
/// Total number of premium API requests used during the session
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) total_premium_requests: Option,
}
/// Internal prompt-cache expiration state for one model
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct UsageCheckpointModelCacheState {
/// Latest known prompt-cache expiration
pub cache_expires_at: String,
/// Retained cache lifetime in seconds, used to refresh expiration after a cache read
#[doc(hidden)]
pub(crate) cache_ttl_seconds: i64,
/// Model identifier associated with this cache state
pub model_id: String,
}
/// Session event "session.usage_checkpoint". Durable session usage checkpoint for reconstructing aggregate accounting on resume
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionUsageCheckpointData {
/// Internal per-model prompt-cache state used to restore expiration tracking on resume
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) model_cache_state: Option>,
/// Internal per-conversation prompt-cache-break detector baselines restored on resume
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) prompt_cache_break_state: Option>,
/// Session-wide accumulated nano-AI units cost at checkpoint time
pub total_nano_aiu: f64,
/// Total number of premium API requests used at checkpoint time
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) total_premium_requests: Option,
}
/// Session event "session.context_changed". Updated working directory and git context after the change
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionContextChangedData {
/// Base commit of current git branch at session start time
#[serde(skip_serializing_if = "Option::is_none")]
pub base_commit: Option,
/// Current git branch name
#[serde(skip_serializing_if = "Option::is_none")]
pub branch: Option,
/// Current working directory path
pub cwd: String,
/// Root directory of the git repository, resolved via git rev-parse
#[serde(skip_serializing_if = "Option::is_none")]
pub git_root: Option,
/// Head commit of current git branch at session start time
#[serde(skip_serializing_if = "Option::is_none")]
pub head_commit: Option,
/// Hosting platform type of the repository (github or ado)
#[serde(skip_serializing_if = "Option::is_none")]
pub host_type: Option,
/// Set on the immediate preliminary event of a working-directory change, before the git context is resolved. A settled follow-up event (enriched with git context, or cwd-only for a non-repository) is always emitted afterward, so observers may defer to it. Absent on standalone/final events (e.g. relay context changes).
#[serde(skip_serializing_if = "Option::is_none")]
pub pending_git_context: Option,
/// Repository identifier derived from the git remote URL ("owner/name" for GitHub, "org/project/repo" for Azure DevOps)
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option,
/// Raw host string from the git remote URL (e.g. "github.com", "mycompany.ghe.com", "dev.azure.com")
#[serde(skip_serializing_if = "Option::is_none")]
pub repository_host: Option,
}
/// Session event "session.usage_info". Current context window usage statistics including token and message counts
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionUsageInfoData {
/// Token count from non-system messages (user, assistant, tool)
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_tokens: Option,
/// Current number of tokens in the context window
pub current_tokens: i64,
/// Whether this is the first usage_info event emitted in this session
#[serde(skip_serializing_if = "Option::is_none")]
pub is_initial: Option,
/// Current number of messages in the conversation
pub messages_length: i64,
/// Token count from system message(s)
#[serde(skip_serializing_if = "Option::is_none")]
pub system_tokens: Option,
/// Maximum token count for the model's context window
pub token_limit: i64,
/// Token count from tool definitions
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_definitions_tokens: Option,
}
/// Session event "session.context_cleared". Context-cleared details emitted when the host clears the conversation (the session.history.clearContext RPC / Session.clearContextMessages)
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionContextClearedData {
/// Optional initial message set after clearing
#[serde(skip_serializing_if = "Option::is_none")]
pub initial_message: Option,
/// Number of conversation messages that were cleared
pub messages_cleared: i64,
}
/// Session event "session.compaction_start". Context window breakdown at the start of LLM-powered conversation compaction
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionCompactionStartData {
/// Token count from non-system messages (user, assistant, tool) at compaction start
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_tokens: Option,
/// Total context tokens (system + conversation + tool definitions) at compaction start, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub current_tokens: Option,
/// Model identifier used for compaction, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option,
/// Token count from system message(s) at compaction start
#[serde(skip_serializing_if = "Option::is_none")]
pub system_tokens: Option,
/// Model context window token limit the compaction is targeting, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub token_limit: Option,
/// Token count from tool definitions at compaction start
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_definitions_tokens: Option,
/// What initiated this compaction, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger: Option,
}
/// Token usage detail for a single billing category
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail {
/// Number of tokens in this billing batch
pub batch_size: i64,
/// Cost per batch of tokens
pub cost_per_batch: i64,
/// Model responsible for this billing entry
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option,
/// Total token count for this entry
pub token_count: i64,
/// Token category (e.g., "input", "output")
pub token_type: String,
}
/// Per-request cost and usage data from the CAPI copilot_usage response field
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct CompactionCompleteCompactionTokensUsedCopilotUsage {
/// Default billing model for token details that do not identify their own model
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) model: Option,
/// Itemized token usage breakdown
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) token_details:
Option>,
/// Total cost in nano-AI units for this request
pub total_nano_aiu: f64,
}
/// Token usage breakdown for the compaction LLM call (aligned with assistant.usage format)
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CompactionCompleteCompactionTokensUsed {
/// Cached input tokens reused in the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_read_tokens: Option,
/// Tokens written to prompt cache in the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_write_tokens: Option,
/// Per-request cost and usage data from the CAPI copilot_usage response field
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) copilot_usage: Option,
/// Duration of the compaction LLM call in milliseconds
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option,
/// Input tokens consumed by the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub input_tokens: Option,
/// Model identifier used for the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option,
/// Output tokens produced by the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub output_tokens: Option,
}
/// Session event "session.compaction_complete". Conversation compaction results including success status, metrics, and optional error details
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionCompactionCompleteData {
/// Authoritative active-factory reminder appended to the compacted context
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) active_factory_summary: Option,
/// Canonical model identifier used for model-specific behavior when replaying compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub behavior_model_id: Option,
/// Checkpoint snapshot number created for recovery
#[serde(skip_serializing_if = "Option::is_none")]
pub checkpoint_number: Option,
/// File path where the checkpoint was stored
#[serde(skip_serializing_if = "Option::is_none")]
pub checkpoint_path: Option,
/// Token usage breakdown for the compaction LLM call (aligned with assistant.usage format)
#[serde(skip_serializing_if = "Option::is_none")]
pub compaction_tokens_used: Option,
/// Token count from non-system messages (user, assistant, tool) after compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_tokens: Option,
/// User-supplied focus instructions provided to a manual `/compact` invocation. Omitted for automatic compaction and for manual compaction with no focus text.
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_instructions: Option,
/// Error message if compaction failed
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option,
/// Number of messages removed during compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub messages_removed: Option,
/// Total tokens in conversation after compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub post_compaction_tokens: Option,
/// Number of messages before compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub pre_compaction_messages_length: Option,
/// Total tokens in conversation before compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub pre_compaction_tokens: Option,
/// GitHub request tracing ID (x-github-request-id header) for the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub request_id: Option,
/// Copilot service request ID (x-copilot-service-request-id header) for the compaction LLM call
#[serde(skip_serializing_if = "Option::is_none")]
pub service_request_id: Option,
/// 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).
#[serde(skip_serializing_if = "Option::is_none")]
pub status_code: Option,
/// Whether compaction completed successfully
pub success: bool,
/// LLM-generated summary of the compacted conversation history
#[serde(skip_serializing_if = "Option::is_none")]
pub summary_content: Option,
/// Token count from system message(s) after compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub system_tokens: Option,
/// Model context window token limit the compaction was targeting, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub token_limit: Option,
/// Number of tokens removed during compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub tokens_removed: Option,
/// Token count from tool definitions after compaction
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_definitions_tokens: Option,
/// What initiated this compaction, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger: Option,
}
/// Session event "session.task_complete". Task completion notification with summary from the agent
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionTaskCompleteData {
/// Active autopilot objective ID evaluated by the completion reviewer
#[serde(skip_serializing_if = "Option::is_none")]
pub objective_id: Option,
/// Semantic completion decision. Absent on legacy events and invalid tool calls
#[serde(skip_serializing_if = "Option::is_none")]
pub outcome: Option,
/// Label-safe runtime rationale for the completion decision (e.g. a cancellation or pause/resume downgrade), when one applies. Reviewer-authored rationale is intentionally omitted here because this event has no IFC label channel; the reviewer's findings remain available through its own labeled sub-agent events
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option,
/// Whether the task was accepted as complete. False when validation failed or completion was rejected or blocked by the reviewer
#[serde(skip_serializing_if = "Option::is_none")]
pub success: Option,
/// Summary of the completed task, provided by the agent
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option,
}
/// Inclusive durable event range summarized by a completion receipt.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionReceiptEventRange {
/// Identifier of the assistant turn-end event that ends the covered exchange. Always equals the receipt's sourceEventId, so either field is a valid join key.
pub end_event_id: String,
/// Identifier of the user message that starts the covered exchange.
pub start_event_id: String,
}
/// Final structured tool completion in the covered event range.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionReceiptFinalTool {
/// Process exit code from a structured shell result, when available.
#[serde(skip_serializing_if = "Option::is_none")]
pub exit_code: Option,
/// Structured success or failure status from the tool completion event.
pub status: CompletionReceiptToolStatus,
/// Unique identifier of the completed tool call.
pub tool_call_id: String,
/// Tool name from the matching tool execution start event, when available.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_name: Option,
}
/// Session event "session.completion_receipt". Behavior-neutral record of structured runtime facts present when an agent completion decision is accepted.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionCompletionReceiptData {
/// One-based accepted completion receipt ordinal in the durable session history.
pub attempt: i64,
/// Inclusive durable event range summarized by this receipt.
pub event_range: CompletionReceiptEventRange,
/// Number of failed structured tool completions in the covered range.
pub failed_tool_count: i64,
/// Final structured tool completion in the covered range, when one exists.
#[serde(skip_serializing_if = "Option::is_none")]
pub final_tool: Option,
/// Version of the completion receipt payload.
pub schema_version: i64,
/// Identifier of the assistant turn-end event that supplied the accepted completion boundary. This is the receipt's idempotency key, and always equals eventRange.endEventId.
pub source_event_id: String,
/// Runtime reason the completion decision was accepted.
pub stop_reason: CompletionReceiptStopReason,
/// Number of successful structured tool completions in the covered range.
pub successful_tool_count: i64,
}
/// Session event "session.fusion_route_started". Experimental transient signal that HydraFusion routing has started for an eligible turn.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFusionRouteStartedData {
/// Identifier for this routing attempt before a durable Fusion turn exists.
pub attempt_id: String,
/// HydraFusion routing policy requested for the turn.
#[serde(skip_serializing_if = "Option::is_none")]
pub policy: Option,
/// Synthetic HydraFusion model selected for the session.
#[serde(skip_serializing_if = "Option::is_none")]
pub synthetic_model: Option,
/// Kind of turn being routed.
pub turn_kind: FusionTurnKind,
}
/// Session event "session.fusion_route_failed". Experimental durable HydraFusion routing failure and the deterministic concrete fallback selected for the turn.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFusionRouteFailedData {
/// Identifier of the routing attempt that failed.
pub attempt_id: String,
/// Provider or validation error detail, when available.
#[serde(skip_serializing_if = "Option::is_none")]
pub error_message: Option,
/// Concrete model selected as the deterministic fallback.
pub fallback_model: String,
/// HydraFusion routing policy requested for the turn.
pub policy: String,
/// Stable machine-readable reason for the routing failure.
pub reason: String,
/// Elapsed routing time in milliseconds before the failure.
#[serde(skip_serializing_if = "Option::is_none")]
pub routing_latency_ms: Option,
/// Synthetic HydraFusion model selected for the session.
pub synthetic_model: String,
}
/// Durable server recommendation for subsequent HydraFusion turns.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FusionFollowUpRecommendation {
/// Recommended routing action for the next compaction turn.
pub compaction_turn: FusionFollowUpAction,
/// Recommended routing action for the next user-message turn.
pub user_turn: FusionFollowUpAction,
}
/// Presentation-neutral phase planned for a HydraFusion turn.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FusionPhasePlanStep {
/// Whether the phase executes only when an earlier phase requests it.
pub conditional: bool,
/// Kind of phase that may execute.
pub kind: FusionPhaseKind,
/// Semantic role assigned to the phase.
pub role: String,
/// Conversation scope in which the phase executes.
pub scope: FusionConversationScope,
}
/// Validated HydraFusion routing capability scores.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FusionScores {
/// Code-generation capability score returned by the authenticated router.
pub code_gen: f64,
/// Debugging capability score returned by the authenticated router.
pub debugging: f64,
/// Reasoning capability score returned by the authenticated router.
pub reasoning: f64,
/// Tool-use capability score returned by the authenticated router.
pub tool_use: f64,
}
/// Session event "session.fusion_resolved". Experimental durable validated HydraFusion route and turn policy.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFusionResolvedData {
/// Version of the validated HydraFusion event contract.
pub contract_version: i64,
/// Concrete model used when the planned primary model cannot execute.
pub fallback_model: String,
/// Router recommendation controlling reuse or rerouting on later turns.
#[serde(skip_serializing_if = "Option::is_none")]
pub follow_up: Option,
/// Concrete model recommended for eligible follow-up turns.
pub follow_up_model: String,
/// Stable identifier for the resolved HydraFusion turn.
pub fusion_id: String,
/// Version of the executable model universe used for selection.
#[serde(skip_serializing_if = "Option::is_none")]
pub model_universe_version: Option,
/// Validated orchestration pattern selected for the turn.
pub pattern: FusionPattern,
/// Presentation-neutral phase plan for clients that render workflow progress.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[serde(skip_serializing_if = "Option::is_none")]
pub phase_plan: Option>,
/// Version of the validated execution-plan format.
#[serde(skip_serializing_if = "Option::is_none")]
pub plan_version: Option,
/// HydraFusion routing policy used to resolve the plan.
pub policy: String,
/// Version of the local routing policy.
#[serde(skip_serializing_if = "Option::is_none")]
pub policy_version: Option,
/// Concrete model selected for the primary solver phase.
pub primary_model: String,
/// Router implementation that supplied the plan.
#[serde(skip_serializing_if = "Option::is_none")]
pub route_source: Option,
/// Elapsed time in milliseconds required to resolve and validate the route.
#[serde(skip_serializing_if = "Option::is_none")]
pub routing_latency_ms: Option,
/// Identifier of the local policy rule that matched.
#[serde(skip_serializing_if = "Option::is_none")]
pub rule_id: Option,
/// Zero-based index of the local policy rule that matched.
#[serde(skip_serializing_if = "Option::is_none")]
pub rule_index: Option,
/// Human-readable name of the local policy rule that matched.
#[serde(skip_serializing_if = "Option::is_none")]
pub rule_name: Option,
/// Validated capability scores used to select the route.
#[serde(skip_serializing_if = "Option::is_none")]
pub scores: Option,
/// Concrete model selected for the review or judge phase, when required.
pub secondary_model: Option,
/// Synthetic HydraFusion model selected for the session.
pub synthetic_model: String,
/// Identifier of the session turn associated with the route.
pub turn_id: String,
}
/// Session event "session.fusion_completed". Experimental durable aggregate outcome of a HydraFusion turn.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFusionCompletedData {
/// Total cached input tokens reported across all phases.
pub cached_tokens: i64,
/// Total tokens written to prompt cache across all phases.
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_write_tokens: Option,
/// Idempotency identifier for the authoritative final commit.
pub commit_id: String,
/// Reason the turn used a degraded route, when applicable.
pub degraded_reason: Option,
/// Total elapsed execution time for the HydraFusion turn in milliseconds.
pub duration_ms: f64,
/// Concrete model that supplied the authoritative final content.
pub final_source_model: Option,
/// Phase whose output supplied the authoritative final content.
pub final_source_phase_id: Option,
/// Concrete model recommended for eligible follow-up turns.
pub follow_up_model: String,
/// Stable identifier for the completed HydraFusion turn.
pub fusion_id: String,
/// Total input tokens consumed across all phases.
pub input_tokens: i64,
/// Stable aggregate outcome of the HydraFusion turn.
pub outcome: String,
/// Total output tokens produced across all phases.
pub output_tokens: i64,
/// HydraFusion orchestration pattern executed for the turn.
pub pattern: FusionPattern,
/// Number of concrete phases attempted by the turn.
pub phase_count: i64,
/// Total concrete model requests made across all phases.
pub request_count: i64,
/// Synthetic HydraFusion model selected for the session.
pub synthetic_model: String,
/// Total normalized AI-unit cost reported across all phases, in nano-AIU.
pub total_nano_aiu: f64,
/// Identifier of the session turn associated with the completion.
pub turn_id: String,
}
/// Session event "user.message". Payload of `user.message` with displayed and model-transformed content, attachments, source/delivery metadata, mode, and telemetry IDs.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserMessageData {
/// The agent mode that was active when this message was sent
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_mode: Option,
/// Files, selections, or GitHub references attached to the message
#[serde(skip_serializing_if = "Option::is_none")]
pub attachments: Option>,
/// The user's message text as displayed in the timeline
pub content: String,
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery: Option,
/// CAPI interaction ID for correlating this user message with its turn
#[serde(skip_serializing_if = "Option::is_none")]
pub interaction_id: Option,
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub is_autopilot_continuation: Option,
/// Stable identity of the logical user message, matching the ID returned by send and retained by pending queue snapshots
#[serde(skip_serializing_if = "Option::is_none")]
pub message_id: Option,
/// 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
#[serde(skip_serializing_if = "Option::is_none")]
pub native_document_path_fallback_paths: Option>,
/// Parent agent task ID for background telemetry correlated to this user turn
#[serde(skip_serializing_if = "Option::is_none")]
pub parent_agent_task_id: Option,
/// Origin of this message, used for timeline filtering and attribution (e.g., `skill-pdf` for hidden skill injection or `agent-` for an inter-agent prompt)
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option,
/// Normalized document MIME types that were sent natively instead of through tagged_files XML
#[serde(skip_serializing_if = "Option::is_none")]
pub supported_native_document_mime_types: Option>,
/// Transformed version of the message sent to the model, with XML wrapping, timestamps, and other augmentations for prompt caching
#[serde(skip_serializing_if = "Option::is_none")]
pub transformed_content: Option,
/// The agent-loop turn ID that consumed this message; absent when no agent-loop turn consumed it
#[serde(skip_serializing_if = "Option::is_none")]
pub turn_id: Option,
}
/// Session event "pending_messages.modified". Empty payload; the event signals that the pending message queue has changed
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PendingMessagesModifiedData {}
/// Session event "assistant.turn_start". Turn initialization metadata including identifier and interaction tracking
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantTurnStartData {
/// CAPI interaction ID for correlating this turn with upstream telemetry
#[serde(skip_serializing_if = "Option::is_none")]
pub interaction_id: Option,
/// Model identifier used for this turn, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option,
/// Identifier for this turn within the agentic loop, typically a stringified turn number
pub turn_id: String,
}
/// Session event "assistant.turn_retry". Metadata for an additional model inference attempt within an existing assistant turn
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantTurnRetryData {
/// Model identifier used for this retry, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option,
/// Provider or runtime classification that caused the retry, when known
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option,
/// Identifier of the turn whose model inference is being retried
pub turn_id: String,
}
/// Session event "agent.interrupted". Metadata for work the user interrupted while the agent was running
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AgentInterruptedData {
/// What the agent was doing when the user interrupted it
pub activity: AgentInterruptedActivity,
/// For an interrupted model call: the provider endpoint the request targeted
#[serde(skip_serializing_if = "Option::is_none")]
pub api_endpoint: Option,
/// For an interrupted model call: whether the user interrupted before any token arrived or while the response was streaming
#[serde(skip_serializing_if = "Option::is_none")]
pub cancel_phase: Option,
/// How long the interrupted work had been running, in milliseconds
pub elapsed_ms: f64,
/// For an interrupted background-agent batch: how many background sub-agents the stop swept. Counts accepted cancellations, so an agent cancelled as a cascade of its interrupted parent is covered by that parent rather than counted again.
#[serde(skip_serializing_if = "Option::is_none")]
pub interrupted_agent_count: Option,
/// For an interrupted model call: the model the request targeted
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option,
/// For a mid-stream interrupt: the observed time to first observable output, in milliseconds. Deliberately distinct from the `ttftMs` reported on a successful model call, which measures time to first stream event.
#[serde(skip_serializing_if = "Option::is_none")]
pub output_ttft_ms: Option,
/// For an interrupted model call: the reasoning effort the request asked for
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Subset of `toolNames` whose tool metadata marks the tool name as safe to record unhashed in telemetry.
#[serde(skip_serializing_if = "Option::is_none")]
pub safe_tool_names: Option>,
/// Tool call identifiers that were still running
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_call_ids: Option>,
/// Names of the tools that were still running. More than one when the model requested a parallel fan-out.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_names: Option>,
/// For an interrupted model call: the transport the request used
#[serde(skip_serializing_if = "Option::is_none")]
pub transport: Option,
/// Zero-based agentic-loop iteration the interrupt landed in
pub turn: i64,
}
/// Session event "assistant.intent". Agent intent description for current activity or plan
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantIntentData {
/// Short description of what the agent is currently doing or planning to do
pub intent: String,
}
/// Session event "assistant.fusion_phase_started". Experimental transient HydraFusion phase/model/role signal.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantFusionPhaseStartedData {
/// Conversation scope in which the phase executes.
pub conversation_scope: FusionConversationScope,
/// Identifier of the HydraFusion turn containing the phase.
pub fusion_id: String,
/// Concrete model executing the phase.
pub model: String,
/// HydraFusion orchestration pattern containing the phase.
pub pattern: FusionPattern,
/// Stable identifier for the concrete phase.
pub phase_id: String,
/// Kind of phase being executed.
pub phase_kind: FusionPhaseKind,
/// Semantic role assigned to the phase.
pub role: String,
}
/// Session event "assistant.fusion_phase_activity". Experimental content-safe activity signal for a running HydraFusion phase.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantFusionPhaseActivityData {
/// Kind of real activity observed.
pub activity: FusionPhaseActivityKind,
/// Conversation scope in which the phase executes.
pub conversation_scope: FusionConversationScope,
/// Identifier of the HydraFusion turn containing the phase.
pub fusion_id: String,
/// HydraFusion orchestration pattern containing the phase.
pub pattern: FusionPattern,
/// Stable identifier for the concrete phase.
pub phase_id: String,
/// Kind of phase currently executing.
pub phase_kind: FusionPhaseKind,
/// Semantic role assigned to the phase.
pub role: String,
/// Opaque hashed correlation token for matching tool-started and tool-completed activity within this Fusion activity stream. It is not the tool call identifier exposed by tool lifecycle events.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_call_id: Option,
/// Cumulative private response bytes observed for this model call. The event never includes response text.
#[serde(skip_serializing_if = "Option::is_none")]
pub total_response_size_bytes: Option,
}
/// Internal durable terminal request staged by a HydraFusion phase until an idempotent final commit selects it.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct FusionStagedTerminal {
pub arguments: String,
pub assistant_message: serde_json::Value,
pub phase_id: String,
pub tool_call_id: String,
pub tool_name: String,
}
/// Aggregate concrete-model usage for one HydraFusion phase.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FusionPhaseUsage {
/// Total cached input tokens reported for the phase.
pub cached_tokens: i64,
/// Total tokens written to prompt cache during the phase.
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_write_tokens: Option,
/// Total input tokens consumed by the phase.
pub input_tokens: i64,
/// Total output tokens produced by the phase.
pub output_tokens: i64,
/// Number of concrete model requests made by the phase.
pub request_count: i64,
/// Total normalized AI-unit cost reported for the phase, in nano-AIU.
pub total_nano_aiu: f64,
}
/// Session event "assistant.fusion_phase_completed". Experimental durable HydraFusion phase output and lossless replay checkpoint.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantFusionPhaseCompletedData {
/// Provider-normalized textual output produced by the phase.
pub content: String,
/// Conversation scope in which the phase executed.
pub conversation_scope: FusionConversationScope,
/// Elapsed execution time for the phase in milliseconds.
pub duration_ms: f64,
/// Identifier of the HydraFusion turn containing the phase.
pub fusion_id: String,
/// Concrete model that executed the phase.
pub model: String,
/// Stable identifier for the completed phase.
pub phase_id: String,
/// Kind of phase that completed.
pub phase_kind: FusionPhaseKind,
/// Exact provider-normalized message used to reconstruct canonical model history.
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) projection_message: Option,
/// Projection action for the exact internal message.
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) projection_mode: Option,
/// Semantic role assigned to the completed phase.
pub role: String,
/// Terminal request held outside canonical state until selected by the final commit.
#[doc(hidden)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) staged_terminal: Option,
/// Durable outcome status of the phase.
pub status: FusionPhaseStatus,
/// Aggregate concrete-model usage consumed by the phase.
pub usage: FusionPhaseUsage,
/// Structured judge or critic verdict, when the phase produces one.
pub verdict: Option,
}
/// Session event "assistant.fusion_phase_failed". Experimental durable typed HydraFusion phase failure and degradation transition.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantFusionPhaseFailedData {
/// Conversation scope in which the phase executed.
pub conversation_scope: FusionConversationScope,
/// Identifier of the fallback phase used to continue the turn after degradation.
#[serde(skip_serializing_if = "Option::is_none")]
pub degraded_to_phase_id: Option,
/// Elapsed execution time before the phase failed, in milliseconds.
pub duration_ms: f64,
/// Provider or execution error detail, when available.
#[serde(skip_serializing_if = "Option::is_none")]
pub error_message: Option,
/// Identifier of the HydraFusion turn containing the phase.
pub fusion_id: String,
/// Concrete model that attempted the phase.
pub model: String,
/// Stable identifier for the failed phase.
pub phase_id: String,
/// Kind of phase that failed.
pub phase_kind: FusionPhaseKind,
/// Stable machine-readable reason for the phase failure.
pub reason: String,
/// Semantic role assigned to the failed phase.
pub role: String,
/// Durable outcome status of the phase.
pub status: FusionPhaseStatus,
/// Aggregate concrete-model usage consumed before the failure.
pub usage: FusionPhaseUsage,
}
/// Session event "assistant.server_tool_progress". Live progress signal for a provider-hosted server tool (e.g. hosted web search) while it runs, before the finalized serverTools envelope lands on the terminal assistant.message
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantServerToolProgressData {
/// Kind of hosted server tool that is running. Only `web_search` is emitted today.
pub kind: String,
/// Position of the hosted tool call in the response output. Stable across the call's lifecycle events (unlike the provider's per-event item id, which CAPI rotates), so the host keys the live in-progress row on it.
pub output_index: i64,
/// Lifecycle status of the hosted call: `in_progress`, `searching`, or `completed`.
pub status: String,
}
/// Session event "assistant.reasoning". Assistant reasoning content for timeline display with complete thinking text
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantReasoningData {
/// The complete extended thinking text from the model
pub content: String,
/// Unique identifier for this reasoning block
pub reasoning_id: String,
/// Per-request treatment/eligibility signal returned by the Copilot API in the `X-GitHub-Copilot-Request-TE` response header for the associated model call; `false` when the header was absent or unparseable.
#[serde(skip_serializing_if = "Option::is_none")]
pub rte: Option,
}
/// Session event "assistant.reasoning_delta". Streaming reasoning delta for incremental extended thinking updates
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantReasoningDeltaData {
/// Incremental text chunk to append to the reasoning content
pub delta_content: String,
/// Reasoning block ID this delta belongs to, matching the corresponding assistant.reasoning event
pub reasoning_id: String,
}
/// Session event "assistant.tool_call_delta". Streaming tool-call input delta for incremental tool-call updates
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantToolCallDeltaData {
/// 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.
pub input_delta: String,
/// Tool call ID this delta belongs to, matching the corresponding assistant.message tool request
pub tool_call_id: String,
/// Name of the tool being invoked, when known from the stream
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_name: Option,
/// Tool call type, when known from the stream
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_type: Option,
}
/// Session event "assistant.streaming_delta". Streaming response progress with cumulative byte count
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantStreamingDeltaData {
/// Cumulative total bytes received from the streaming response so far
pub total_response_size_bytes: i64,
}
/// A source that backs one or more cited spans in the assistant's response.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CitationSource {
/// Stable, turn-scoped identifier for this source, referenced by CitationReference.sourceId.
pub id: String,
/// File path relative to the agent's workspace root, when the source is a file.
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option,
/// The system that produced this citation.
pub provider: CitationProvider,
/// Human-readable title of the source.
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option,
/// URL of the source, when it is a web resource.
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option,
}
/// A single citation occurrence linking a span of generated text to a supporting source.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CitationReference {
/// The exact text from the source that supports the cited span, when provided by the model.
#[serde(skip_serializing_if = "Option::is_none")]
pub cited_text: Option,
/// Location within the source that supports the cited span, when the provider reports one.
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option,
/// Provider-native citation correlation data (e.g. Anthropic search_result_index / document_index), passed through opaquely for debugging and forward compatibility.
#[serde(skip_serializing_if = "Option::is_none")]
pub provider_metadata: Option,
/// Identifier of the CitationSource this reference points to (CitationSource.id).
pub source_id: String,
}
/// A contiguous span of generated assistant text and the source references that support it.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CitationSpan {
/// End offset of the cited span within the final assistant message content (UTF-16 code units, zero-based, exclusive).
pub end_index: i64,
/// The sources that support this span of generated text.
pub references: Vec,
/// Start offset of the cited span within the final assistant message content (UTF-16 code units, zero-based, inclusive).
pub start_index: i64,
}
/// Provider-agnostic citations linking spans of the assistant's response to their supporting sources.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Citations {
/// Deduplicated set of sources referenced by the citation spans.
pub sources: Vec,
/// Spans of generated text annotated with the sources that support them.
pub spans: Vec,
}
/// Experimental attribution linking an ordinary event to the HydraFusion turn, phase, and concrete source that produced it.
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FusionAttribution {
/// Idempotency identifier for the authoritative commit, when the event belongs to the selected output.
#[serde(skip_serializing_if = "Option::is_none")]
pub commit_id: Option,
/// Conversation scope in which the concrete phase executed.
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_scope: Option,
/// Stable identifier for the HydraFusion turn that produced the event.
pub fusion_id: String,
/// HydraFusion orchestration pattern selected for the turn.
pub pattern: String,
/// Identifier of the concrete phase that produced the event.
#[serde(skip_serializing_if = "Option::is_none")]
pub phase_id: Option,
/// Kind of concrete phase that produced the event.
#[serde(skip_serializing_if = "Option::is_none")]
pub phase_kind: Option,
/// HydraFusion routing policy used for the turn.
pub policy: String,
/// Semantic role assigned to the concrete phase.
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option,
/// Concrete model that produced the attributed event.
#[serde(skip_serializing_if = "Option::is_none")]
pub source_model: Option,
/// Phase whose output supplied the authoritative content, when different from the executing phase.
#[serde(skip_serializing_if = "Option::is_none")]
pub source_phase_id: Option,
/// Synthetic HydraFusion model selected for the session.
pub synthetic_model: String,
}
/// Neutral provider-tagged reasoning content blocks preserved verbatim for round-tripping
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantMessageReasoningBlocks {
/// Provider-native reasoning items or content blocks preserved verbatim, in order. A single response can carry several, and provider signatures or identifiers may depend on their exact content and ordering.
#[serde(skip_serializing_if = "Option::is_none")]
pub blocks: Option>,
/// Model provider that produced these reasoning blocks.
pub provider: String,
}
/// Neutral provider-tagged server-side tool-use payload (tool search, advisor) for verbatim round-tripping
///
///
///
/// **Experimental.** This type is part of an experimental wire-protocol surface
/// and may change or be removed in future SDK or CLI releases.
///
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantMessageServerTools {
/// Advisor model identifier associated with the server-tool payload.
#[serde(skip_serializing_if = "Option::is_none")]
pub advisor_model: Option,
/// Provider function-call namespaces keyed by function-call identifier.
#[serde(skip_serializing_if = "Option::is_none")]
pub function_call_namespaces: Option>,
/// Provider-native server-tool call and output items preserved verbatim for replay.
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option>,
/// Model provider that produced this server-tool payload.
pub provider: String,
/// Raw provider content blocks retained for verbatim round-tripping.
#[serde(skip_serializing_if = "Option::is_none")]
pub raw_content_blocks: Option>,
}
/// Hosted program that requested this client tool call
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantMessageToolRequestCaller {
/// Provider-assigned identifier for the hosted caller.
pub caller_id: String,
/// Kind of hosted caller that requested the client tool call.
pub r#type: AssistantMessageToolRequestCallerType,
}
/// A tool invocation request from the assistant
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssistantMessageToolRequest {
/// Arguments to pass to the tool, format depends on the tool
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option