/** * @license * Copyright 2026 Google LLC * SPDX-License-Identifier: Apache-2.0 */ /** * SDKMessage — the JSONL line format the CLI emits to stdout. * * Single source of truth for both the CLI (which writes them) and the SDK * (which parses them). CLI-side zod schemas in * `@google/gemini-cli-core/protocol/schemas` are kept aligned via * `satisfies z.ZodType<...>` against these types. */ import type { BetaMessage, BetaRawMessageStreamEvent, MessageParam, UUID, SDKAssistantMessageError, FastModeState, ApiKeySource, ModelUsage, NonNullableUsage, PluginInfo, SDKStatus } from './common.js'; import type { PermissionMode } from './permissions.js'; import type { MemoryConsumptionResult, MemoryGenerationResult } from './memory.js'; import type { SDKGoalSnapshot } from './control.js'; export type SDKAssistantMessage = { type: 'assistant'; message: BetaMessage; parent_tool_use_id: string | null; /** * Present when qodercli synthesized this Assistant message from an API * failure rather than a model response. Embedded hosts can use the marker to * avoid rendering duplicate error text when the terminal Result already * provides a structured error surface. */ isApiErrorMessage?: true; /** Qoder model request ID, present only when explicitly enabled in the CLI. */ request_id?: string; error?: SDKAssistantMessageError; /** * Present when an interrupt truncated the model stream before a stop reason * arrived. The final content block may end mid-token. */ aborted?: true; uuid: UUID; session_id: string; }; export type SDKToolNonExecutionKind = 'user-rejected' | 'permission-rule' | 'automode-blocked' | 'automode-unavailable' | 'automode-parsing-error' | 'interrupted' | 'cancelled'; /** * Display-only metadata for a tool result whose tool did not run to * completion. This wrapper-level field is never part of the model message. */ export type SDKToolResultMeta = { id: string; non_execution_kind: SDKToolNonExecutionKind; user_feedback?: string; }; export type SDKUserMessage = { type: 'user'; message: MessageParam; parent_tool_use_id: string | null; custom_context?: Record; file_attachments?: SDKFileAttachment[]; isSynthetic?: boolean; tool_use_result?: unknown; tool_result_meta?: SDKToolResultMeta[]; /** * Delivery priority. `next` is the default; `now` interrupts the active * turn, while `later` waits for the session to become idle. */ priority?: 'now' | 'next' | 'later'; /** * When false, do not start an assistant turn while the session is idle. * Delivery still follows `priority`: `next` can inject at a safe boundary, * `later` waits for idle, and `now` interrupts the active turn. */ shouldQuery?: boolean; timestamp?: string; uuid?: UUID; session_id?: string; }; export type SDKUserMessageReplay = { type: 'user'; message: MessageParam; parent_tool_use_id: string | null; file_attachments?: SDKFileAttachment[]; isSynthetic?: boolean; tool_use_result?: unknown; tool_result_meta?: SDKToolResultMeta[]; /** * Delivery priority. `next` is the default; `now` interrupts the active * turn, while `later` waits for the session to become idle. */ priority?: 'now' | 'next' | 'later'; /** * When false, do not start an assistant turn while the session is idle. * Delivery still follows `priority`: `next` can inject at a safe boundary, * `later` waits for idle, and `now` interrupts the active turn. */ shouldQuery?: boolean; timestamp?: string; uuid: UUID; session_id: string; isReplay: true; }; export type SDKResultSuccess = { type: 'result'; subtype: 'success'; duration_ms: number; duration_api_ms: number; is_error: boolean; num_turns: number; result: string; stop_reason: string | null; total_cost_usd: number; /** Session-cumulative Qoder credits. Added by newer CLI versions. */ total_credits?: number; usage: NonNullableUsage; modelUsage: Record; permission_denials: SDKPermissionDenial[]; error_code?: number; deferred_tool_use?: unknown; terminal_reason?: string | null; fast_mode_state?: FastModeState; uuid: UUID; session_id: string; }; export type SDKResultError = { type: 'result'; subtype: 'error_during_execution' | 'error_max_turns' | 'error_max_budget_usd'; duration_ms: number; duration_api_ms: number; is_error: boolean; num_turns: number; stop_reason: string | null; total_cost_usd: number; /** Session-cumulative Qoder credits. Added by newer CLI versions. */ total_credits?: number; usage: NonNullableUsage; modelUsage: Record; permission_denials: SDKPermissionDenial[]; errors: string[]; error_code?: number; terminal_reason?: string | null; fast_mode_state?: FastModeState; uuid: UUID; session_id: string; }; export type SDKFileAttachment = { file_id: string; relative_path: string; }; export type SDKResultMessage = SDKResultSuccess | SDKResultError; export type SDKSystemMessage = { type: 'system'; subtype: 'init'; agents?: string[]; apiKeySource: ApiKeySource; qodercli_version: string; /** * Wire protocol version (`WIRE_PROTOCOL_VERSION` from `src/protocol/version.ts`). * * Optional for backward compatibility with older CLIs that predate the * handshake — the SDK falls back to a warning when absent. New CLI * builds always emit this field. */ protocol_version?: string; cwd: string; tools: string[]; mcp_servers: Array<{ name: string; status: string; }>; model: string; permissionMode: PermissionMode; slash_commands: string[]; output_style: string; skills: string[]; plugins: PluginInfo[]; /** * Open protocol capability set advertised by the CLI. * * Consumers must check the capability required by each behavior and ignore * unknown values. */ capabilities?: string[]; fast_mode_state?: FastModeState; uuid: UUID; session_id: string; }; export type SDKPartialAssistantMessage = { type: 'stream_event'; event: BetaRawMessageStreamEvent; parent_tool_use_id: string | null; uuid: UUID; session_id: string; }; export type SDKCompactBoundaryMessage = { type: 'system'; subtype: 'compact_boundary'; compact_metadata: { trigger: 'manual' | 'auto'; pre_tokens: number; preserved_segment?: { head_uuid: UUID; anchor_uuid: UUID; tail_uuid: UUID; }; }; uuid: UUID; session_id: string; }; export type SDKStatusMessage = { type: 'system'; subtype: 'status'; status: SDKStatus; permissionMode?: PermissionMode; uuid: UUID; session_id: string; }; export type SDKAPIRetryMessage = { type: 'system'; subtype: 'api_retry'; attempt: number; max_retries: number; retry_delay_ms: number; error_status: number | null; error: SDKAssistantMessageError; uuid: UUID; session_id: string; }; /** Model capacity queue progress emitted while qodercli waits and retries. */ export type SDKModelQueueStatusMessage = { type: 'system'; subtype: 'model_queue_status'; status: 'queued' | 'ready'; request_id: string; request_set_id: string; model_key: string; queue_type?: string; queue_count?: number; wait_time_ms?: number; queue_wait_elapsed_ms?: number; queue_max_wait_ms?: number; service_available?: boolean; uuid: UUID; session_id: string; }; /** Progress emitted for an SDK-initiated side question. */ export type SDKControlRequestProgressMessage = { type: 'system'; subtype: 'control_request_progress'; request_id: string; status: 'started' | 'api_retry'; attempt?: number; max_retries?: number; retry_delay_ms?: number; error_status?: number | null; uuid: UUID; session_id: string; }; export type SDKHookStartedMessage = { type: 'system'; subtype: 'hook_started'; hook_id: string; hook_name: string; hook_event: string; uuid: UUID; session_id: string; }; export type SDKHookProgressMessage = { type: 'system'; subtype: 'hook_progress'; hook_id: string; hook_name: string; hook_event: string; stdout: string; stderr: string; output: string; uuid: UUID; session_id: string; }; export type SDKHookResponseMessage = { type: 'system'; subtype: 'hook_response'; hook_id: string; hook_name: string; hook_event: string; output: string; stdout: string; stderr: string; exit_code?: number; outcome: 'success' | 'error' | 'cancelled'; uuid: UUID; session_id: string; }; export type SDKTaskNotificationMessage = { type: 'system'; subtype: 'task_notification'; task_id: string; tool_use_id?: string; status: 'completed' | 'failed' | 'stopped'; output_file: string; summary: string; usage?: { total_tokens?: number; tool_uses: number; duration_ms: number; }; uuid: UUID; session_id: string; }; export type SDKTaskStartedMessage = { type: 'system'; subtype: 'task_started'; task_id: string; tool_use_id?: string; description: string; subagent_type?: string; task_type?: string; workflow_name?: string; prompt?: string; /** Final tool set available to the subagent after policy filtering. */ tools?: string[]; uuid: UUID; session_id: string; }; export type SDKTaskProgressMessage = { type: 'system'; subtype: 'task_progress'; task_id: string; tool_use_id?: string; description: string; usage?: { total_tokens?: number; tool_uses: number; duration_ms: number; }; last_tool_name?: string; subagent_type?: string; summary?: string; uuid: UUID; session_id: string; }; export type SDKTaskUpdatedMessage = { type: 'system'; subtype: 'task_updated'; task_id: string; /** Wire-safe task fields that changed. Consumers merge this patch. */ patch: { status?: 'pending' | 'running' | 'completed' | 'failed' | 'killed' | 'paused'; description?: string; end_time?: number; total_paused_ms?: number; error?: string; is_backgrounded?: boolean; }; uuid: UUID; session_id: string; }; export type SDKBackgroundTasksChangedMessage = { type: 'system'; subtype: 'background_tasks_changed'; /** * Every live background task after the change. This has REPLACE semantics: * consumers replace their current background task set with this payload. */ tasks: Array<{ task_id: string; task_type: string; description: string; }>; uuid: UUID; session_id: string; }; /** * Goal state changed (created / redirected / transitioned / budget update). * Requires the CLI `goal_v1` capability. */ export type SDKGoalUpdatedMessage = { type: 'system'; subtype: 'goal_updated'; goal: SDKGoalSnapshot; /** Why the goal changed, e.g. 'safety-limit' or 'blocked'. */ reason?: string; uuid: UUID; session_id: string; }; /** Goal was cleared. Requires the CLI `goal_v1` capability. */ export type SDKGoalClearedMessage = { type: 'system'; subtype: 'goal_cleared'; goal_id: string; reason?: string; uuid: UUID; session_id: string; }; export type SDKSessionStateChangedMessage = { type: 'system'; subtype: 'session_state_changed'; state: 'idle' | 'running' | 'requires_action'; uuid: UUID; session_id: string; }; /** * Session title update. Emitted only when the host negotiated support. * (Was missing on the SDK side before protocol extraction.) */ export type SDKSessionTitleChangedMessage = { type: 'system'; subtype: 'session_title_changed'; title: string; source: 'ai' | 'custom'; revision: number; uuid: UUID; session_id: string; }; export type SDKFilesPersistedEvent = { type: 'system'; subtype: 'files_persisted'; files: Array<{ filename: string; file_id: string; }>; failed: Array<{ filename: string; error: string; }>; processed_at: string; uuid: UUID; session_id: string; }; export type SDKElicitationCompleteMessage = { type: 'system'; subtype: 'elicitation_complete'; mcp_server_name: string; elicitation_id: string; uuid: UUID; session_id: string; }; export type SDKPromptSuggestionMessage = { type: 'prompt_suggestion'; suggestion: string; uuid: UUID; session_id: string; }; export type SDKCloudAgentEventMessage = { type: 'cloud_agent_event'; event: string; id?: string; data: unknown; uuid: UUID; session_id: string; }; export type SDKMemoryGenerationMessage = { type: 'system'; subtype: 'memory_generation'; result: MemoryGenerationResult; uuid: UUID; session_id: string; }; export type SDKMemoryConsumptionMessage = { type: 'system'; subtype: 'memory_consumption'; result: MemoryConsumptionResult; uuid: UUID; session_id: string; }; export type SDKPermissionDenial = { tool_name: string; tool_use_id: string; tool_input: Record; message?: string; decision_reason_type?: SDKPermissionDeniedReasonType; decision_reason?: string; }; export type SDKPermissionDeniedReasonType = 'rule' | 'mode' | 'subcommandResults' | 'permissionPromptTool' | 'hook' | 'asyncAgent' | 'workingDir' | 'safetyCheck' | 'classifier' | 'other'; export type SDKPermissionDeniedMessage = { type: 'system'; subtype: 'permission_denied'; tool_name: string; tool_use_id: string; message: string; uuid: UUID; session_id: string; agent_id?: string; decision_reason_type?: SDKPermissionDeniedReasonType; decision_reason?: string; }; export type SDKMessage = SDKAssistantMessage | SDKUserMessage | SDKUserMessageReplay | SDKResultMessage | SDKSystemMessage | SDKPermissionDeniedMessage | SDKPartialAssistantMessage | SDKCompactBoundaryMessage | SDKStatusMessage | SDKAPIRetryMessage | SDKModelQueueStatusMessage | SDKControlRequestProgressMessage | SDKHookStartedMessage | SDKHookProgressMessage | SDKHookResponseMessage | SDKTaskNotificationMessage | SDKTaskStartedMessage | SDKTaskProgressMessage | SDKTaskUpdatedMessage | SDKBackgroundTasksChangedMessage | SDKSessionStateChangedMessage | SDKGoalUpdatedMessage | SDKGoalClearedMessage | SDKSessionTitleChangedMessage | SDKFilesPersistedEvent | SDKElicitationCompleteMessage | SDKPromptSuggestionMessage | SDKCloudAgentEventMessage | SDKMemoryGenerationMessage | SDKMemoryConsumptionMessage;