跳到正文
FunCoding

搜索

搜索文档、智能体、博客、Skill 和 MCP

TypeScript SDK 参考:消息类型

Agent SDK TypeScript 的 SDKMessage 联合类型及 SDKAssistantMessage、SDKUserMessage、SDKResultMessage(含诊断字段、user_message_uuid、startup_failure_reason)、SDKSystemMessage、权限拒绝、上下文用量、消息来源 origin 等的字段说明。

本页是 TypeScript Agent SDK 参考的第三部分:query() 产出的各种消息类型。Options 与 Query 见「选项与类型」,hook 类型见「hook 类型」。

SDKMessage

查询返回的所有可能消息的联合类型。

type SDKMessage =
  | SDKAssistantMessage
  | SDKUserMessage
  | SDKUserMessageReplay
  | SDKResultMessage
  | SDKSystemMessage
  | SDKPartialAssistantMessage
  | SDKCompactBoundaryMessage
  | SDKStatusMessage
  | SDKLocalCommandOutputMessage
  | SDKHookStartedMessage
  | SDKHookProgressMessage
  | SDKHookResponseMessage
  | SDKPluginInstallMessage
  | SDKToolProgressMessage
  | SDKAuthStatusMessage
  | SDKTaskNotificationMessage
  | SDKTaskStartedMessage
  | SDKTaskProgressMessage
  | SDKTaskUpdatedMessage
  | SDKBackgroundTasksChangedMessage
  | SDKThinkingTokensMessage
  | SDKSessionStateChangedMessage
  | SDKWorkerShuttingDownMessage
  | SDKCommandsChangedMessage
  | SDKNotificationMessage
  | SDKFilesPersistedEvent
  | SDKToolUseSummaryMessage
  | SDKMemoryRecallMessage
  | SDKRateLimitEvent
  | SDKElicitationCompleteMessage
  | SDKPermissionDeniedMessage
  | SDKPromptSuggestionMessage
  | SDKAPIRetryMessage
  | SDKMirrorErrorMessage
  | SDKInformationalMessage
  | SDKConversationResetMessage;

SDKAssistantMessage

助手响应消息。

type SDKAssistantMessage = {
  type: "assistant";
  uuid: UUID;
  session_id: string;
  message: BetaMessage; // 来自 Anthropic SDK
  parent_tool_use_id: string | null;
  error?: SDKAssistantMessageError;
  aborted?: true;
  timestamp?: string;
  context_usage?: SDKContextUsage;
  user_message_uuid?: string;
  user_message_uuids?: string[];
  resume_reason?: string;
};

message 字段是来自 Anthropic SDK 的 BetaMessage,包含 id、content、model、stop_reason 和 usage 等字段。SDKAssistantMessageError 是下列之一:'authentication_failed'、'oauth_org_not_allowed'、'account_on_hold'、'billing_error'、'rate_limit'、'overloaded'、'invalid_request'、'model_not_found'、'server_error'、'max_output_tokens'、'cloud_credential_error' 或 'unknown'。其中四个值的含义比名字所示更多:

  • 'model_not_found':所选模型不存在,或对你的账号或部署不可用
  • 'overloaded':API 因服务器容量满返回 529,区别于针对你的配额的 429 即 'rate_limit'
  • 'account_on_hold':你的账号处于冻结状态
  • 'cloud_credential_error':Claude Code 无法在它运行的机器上获得可用的 AWS 或 Google Cloud 凭据,所以没有请求到达云提供商。通常的原因是该机器上的云登录已过期或从未完成,不过凭据服务短暂不可达也会报告同样的值(需要 TypeScript Agent SDK v0.3.267 及以上,它捆绑 Claude Code v2.1.267)

aborted 为 true 表示中断或中止在流完成前截断了助手消息:消息没有 stop_reason,内容可能停在词语中间;正常完成的消息上该字段不存在(需要 Agent SDK v0.3.214 及以上)。Claude Code 把 user_message_uuid 和 user_message_uuids 设在轮次的第一条助手消息上;Claude Code 重新运行被重启打断的轮次时,带有这些字段的重跑助手消息也带 resume_reason。timestamp 是消息内容在产生它的进程上完成生成的 ISO 8601 时间,取自那台机器的时钟,所以只用于显示,不要据此给消息排序;一个 API 轮次可能产生共享同一个 message.id 的多条助手消息,每条有自己的 timestamp;字段缺失时回退到你收到消息的时间。context_usage 是 /context 报告的结构化副本,类型为 SDKContextUsage(需要 Agent SDK v0.3.232 及以上):当你把 /context 作为提示发送时,Claude Code 把报告作为 message.content 里是 markdown 表格的助手消息交付,并把 context_usage 附在同一条消息上;Claude Code 不在任何其他助手消息上设置该字段,更早的版本交付 /context 表格时不带它。

SDKUserMessage

用户输入消息。

type SDKUserMessage = {
  type: "user";
  uuid?: UUID;
  session_id?: string;
  message: MessageParam; // 来自 Anthropic SDK
  pasted_content?: MessageParam["content"][];
  parent_tool_use_id: string | null;
  isSynthetic?: boolean;
  shouldQuery?: boolean;
  client_composed?: true;
  tool_use_result?: unknown;
  origin?: SDKMessageOrigin;
  inline_pastes?: string[];
};

把 pasted_content 设为用户粘贴(而不是键入)到你的提示界面里的内容,每次粘贴一项,每项是字符串或内容块数组。Claude Code 按顺序把每项的文本追加到键入文本之后,并可能用 <pasted_content> 标签包裹每次粘贴;文本以外的块被忽略,所以图片和文档要放在 message.content 里(需要 Agent SDK v0.3.277 及以上)。设 shouldQuery 或 client_composed 可改变 Claude Code 处理你发送的消息的方式:

  • shouldQuery:设为 false 把消息追加进记录而不触发助手轮次;消息被保留,并合并进下一条触发轮次的用户消息。用它注入上下文(如你在带外运行的命令的输出),而不为它花费一次模型调用。
  • client_composed:设为 true 让 Claude Code 按原样交付消息文本,此时 Claude Code 不展开 @path 或 @server:resource 提及,也不把以 / 开头的文本当作命令运行。verbatimPrompts 选项开启时,SDK 在每条消息上设该字段(需要 TypeScript Agent SDK v0.3.280 及以上和 Claude Code v2.1.248 及以上)。

在携带 tool_result 块的消息上,tool_use_result 是该工具的结构化输出对象,而不是发给模型的文本。它的形状取决于匹配的 tool_use 块所指的工具,所以字段类型是 unknown,内置的形状列在「工具与权限类型」里。对 Agent 工具,tool_use_result 是 AgentOutput;在 completed 结果上,content 持有子智能体的报告,不含 Claude Code 追加到 tool_result 文本里的智能体 ID 和用量尾部,所以要从 tool_use_result 渲染而不是解析那段文本。对结果含 resource_link 块的 MCP 工具,tool_use_result 是带有 SDKMcpResourceLink 条目的 resourceLinks 数组的对象;Claude 把每个链接作为 tool_result 块里的一行文本收到,所以要读 resourceLinks 来渲染服务器返回的文件,而不是解析那段文本;结果没有链接时以及子智能体的结果上,Claude Code 省略 resourceLinks,每个结果最多保留 50 个链接。设 inline_pastes 告诉 Claude Code message.content 的哪些部分是用户粘贴而不是键入的,每次粘贴一个字符串,提示文本保持在用户放置的位置;Claude Code 可能把每个列出的粘贴就地用 <pasted_content> 标签包裹,让 Claude 能把粘贴的材料与用户自己的话区分开,只有提示最后一个文本块里的粘贴才会被包裹(需要 TypeScript Agent SDK v0.3.280 及以上)。

SDKUserMessageReplay

带必需 UUID 的重放用户消息。

type SDKUserMessageReplay = {
  type: "user";
  uuid: UUID;
  session_id: string;
  message: MessageParam;
  parent_tool_use_id: string | null;
  isSynthetic?: boolean;
  client_composed?: true;
  tool_use_result?: unknown;
  origin?: SDKMessageOrigin;
  isReplay: true;
};

从会话外部注入的用户轮次(其 origin 的 kind 是 peer 或 channel),不论是在活动轮次期间交付还是在会话空闲时开启了新轮次,都以重放的形式到达流。v2.1.207 之前,会话空闲时交付的注入轮次不在流上产生消息,只在重新读取记录时才出现。

SDKResultMessage

最终结果消息。

type SDKResultMessage =
  | {
      type: "result";
      subtype: "success";
      uuid: UUID;
      session_id: string;
      duration_ms: number;
      duration_api_ms: number;
      is_error: boolean;
      api_error_status?: number | null;
      num_turns: number;
      result: string;
      stop_reason: string | null;
      ttft_ms?: number;
      ttft_stream_ms?: number;
      user_message_uuid?: string;
      user_message_uuids?: string[];
      resume_reason?: string;
      local_command?: string;
      request_sent_wall_ms?: number;
      first_content_frame_ms?: number;
      first_stream_post_ms?: number;
      first_stream_post_ack_ms?: number;
      first_stream_post_wall_ms?: number;
      total_cost_usd: number;
      usage: NonNullableUsage;
      modelUsage: { [modelName: string]: ModelUsage };
      permission_denials: SDKPermissionDenial[];
      queued_turn_count?: number;
      structured_output?: unknown;
      deferred_tool_use?: { id: string; name: string; input: Record<string, unknown> };
      terminal_reason?: TerminalReason;
      result_index?: number;
      fast_mode_state?: FastModeState;
      fast_mode_disabled_reason?: FastModeDisabledReason;
      origin?: SDKMessageOrigin;
    }
  | {
      type: "result";
      subtype:
        | "error_max_turns"
        | "error_during_execution"
        | "error_max_budget_usd"
        | "error_max_structured_output_retries";
      uuid: UUID;
      session_id: string;
      duration_ms: number;
      duration_api_ms: number;
      is_error: boolean;
      num_turns: number;
      stop_reason: string | null;
      total_cost_usd: number;
      usage: NonNullableUsage;
      modelUsage: { [modelName: string]: ModelUsage };
      permission_denials: SDKPermissionDenial[];
      queued_turn_count?: number;
      errors: string[];
      startup_failure_reason?: SDKStartupFailureReason;
      user_message_uuid?: string;
      user_message_uuids?: string[];
      resume_reason?: string;
      terminal_reason?: TerminalReason;
      result_index?: number;
      fast_mode_state?: FastModeState;
      fast_mode_disabled_reason?: FastModeDisabledReason;
      origin?: SDKMessageOrigin;
    };

结果上有若干字段在 subtype 之外携带诊断细节:

  • api_error_status:终止对话的 API 错误的 HTTP 状态码;轮次没有 API 错误地结束时缺失或为 null。
  • ttft_ms:首 token 时间(毫秒),在第一条完整助手消息到达时测量;只在 success 分支上存在。
  • ttft_stream_ms:直到第一个 message_start 流事件(响应流打开时)的毫秒数;低于 ttft_ms,两者之差是流式传输第一条消息所花的时间;只在 success 分支上存在。
  • user_message_uuid:该轮次所应答的、你发送的消息的 uuid;哪些结果带它见下。
  • user_message_uuids:该轮次里 Claude Code 应答的、你发送的每条消息的 uuid。
  • resume_reason:Claude Code 在重启打断之后重新运行该轮次的原因;两个分支上都有,且只出现在这样的重跑上。
  • local_command:该轮次分发的命令名,出现在由命令完成而没有进入智能体循环的轮次(如 /compact)的 success 结果上。名字被折叠为小写字母和下划线,所以 /reload-plugins 报告 reload_plugins;MCP 服务器提供的命令和内置的 /mcp 报告 mcp;你自己定义的命令报告 custom;从不包含参数;进入了智能体循环的每个轮次上都不存在。
  • request_sent_wall_ms:Claude Code 分发 API 请求时的 epoch 毫秒数,用于与服务端时间戳连接;只与 user_message_uuid 一起出现,在 is_error 为 false、轮次发出了 API 请求的 success 结果上。
  • first_content_frame_ms:直到第一个 content_block_start 或 content_block_delta 流事件的毫秒数(思考块也算内容);只在 is_error 为 false 的 success 分支上存在(需要 Agent SDK v0.3.260 及以上)。
  • first_stream_post_ms、first_stream_post_ack_ms、first_stream_post_wall_ms:上传轮次第一个流事件的计时。Claude Code 只在它流式传给 claude.ai 的会话(如云端会话)里记录它们,query() 产出的结果不带它们(需要 Agent SDK v0.3.260 及以上)。
  • usage:只含主智能体循环,不含子智能体和辅助模型调用,在流式输入会话里按轮次;做 token/成本核算时优先用 modelUsage。
  • modelUsage:本次 query() 调用期间经查询管道发出的每个模型调用的按模型总计,包括主循环、子智能体,以及压缩和 Workflow 智能体等内部调用;管道之外的辅助调用(如权限分类器和 token 计数请求)被排除;恢复会话的调用还会计入从会话先前调用还原的按模型总计;在流式输入会话里总计跨轮次累计。
  • total_cost_usd:累计的估算美元成本,涵盖与 modelUsage 相同的调用并在相同的点重置;恢复会话的调用也计入还原的总数;这是估算,不是账单(准确性注意事项见「跟踪成本与用量」)。
  • queued_turn_count:Claude Code 产生结果时仍在等待的、你以 origin: { kind: "human" } 发送的消息数。
  • result_index:该结果在本次运行交付顺序里的位置,从 0 起算进程写出的每个结果;两个分支上都有;写入失败的结果仍占用它的编号,所以序列里的缺口表示有结果丢失(需要 Agent SDK v0.3.268 及以上)。
  • startup_failure_reason:Claude Code 为什么拒绝启动,出现在它在已知启动失败时退出之前写出的 error_during_execution 结果上(需要 Agent SDK v0.3.274 及以上)。
  • terminal_reason:循环为何结束,取值之一:"completed"、"max_turns"、"tool_deferred"、"aborted_streaming"、"aborted_tools"、"hook_stopped"、"stop_hook_prevented"、"background_requested"、"blocking_limit"、"rapid_refill_breaker"、"prompt_too_long"、"image_error"、"model_error"、"api_error"、"malformed_tool_use_exhausted"、"budget_exhausted"、"structured_output_retry_exhausted"、"tool_deferred_unavailable" 或 "turn_setup_failed"。
  • fast_mode_state:"on"、"off" 或 "cooldown" 之一。
  • fast_mode_disabled_reason:快速模式此刻为何不可用;没有东西阻止快速模式时缺失,不过请求仍可能以标准速度运行;在快速模式速率限制之后的冷却期间,Claude Code 报告 fast_mode_state: "cooldown" 且不带原因代码,冷却到期时重新启用快速模式(需要 Claude Code v2.1.219 及以上)。

用原因代码在你自己的界面里解释快速模式为什么关闭,而不是重新推导可用性:

原因代码含义
free账号没有快速模式要求的付费订阅或用量额度
preference组织已禁用快速模式
extra_usage_disabled账号的用量额度已关闭
network_error可用性检查无法访问 api.anthropic.com
unknownClaude Code 无法确定可用性
not_first_party会话使用的是 Anthropic API 之外的提供商
disabled_by_env设了 CLAUDE_CODE_DISABLE_FAST_MODE
model_not_allowed快速模式的 Opus 模型不在组织的 availableModels 允许列表里
sdk_opt_in_required会话没有选择加入快速模式:在 settings 选项里或通过 applyFlagSettings() 传 fastMode: true
pending可用性检查尚未完成

同一对字段也出现在 SDKSystemMessage 和 SDKControlInitializeResponse 上,所以你能在第一个轮次之前就读到快速模式状态。origin 字段转发触发该结果的用户消息的 SDKMessageOrigin。SDK 注入合成的后续轮次(如为一个完成的后台任务)时,产生的 SDKResultMessage 带 origin: { kind: "task-notification" };触发器已触发的例程和来自你其他会话的服务端验证消息也以这个 kind 到达,各带「任务通知 subkind」里描述的 subkind。检查 kind 来区分回答你自己提示的结果和这些结果。多个后台任务完成一起排队时,Claude Code 可以在一个轮次里回答它们而不是每个一轮;每个完成仍产生自己的、带该 origin 的结果;Claude Code 一起回答的完成里,除最后一个外都按顺序产生 num_turns: 0 的空结果,最后一个的结果携带回答它们全部的那个轮次;在任何用户轮次之前发出的结果(如启动错误)上该字段不存在。PreToolUse hook 返回 permissionDecision: "defer" 时,结果带 stop_reason: "tool_deferred",deferred_tool_use 携带待处理工具的 id、name 和 input;读取该字段在你自己的界面里呈现请求,然后用同一个 session_id 恢复以继续(完整往返见「推迟工具调用」)。

user_message_uuid

该轮次所应答的 SDKUserMessage 的 uuid,原样回传,让你能把 Claude Code 的回复与你发送的消息匹配。只有你在消息上设了 uuid,Claude Code 才会回传;该字段在 SDKUserMessage 上是可选的,传给 query() 的字符串提示不带 uuid。一个轮次应答你的哪条消息取决于轮次如何开始:

  • 你发送的普通消息(没有 isSynthetic: true 的):轮次在整个运行期间应答该消息。你把几条消息挨得很近地发出时,Claude Code 可以把它们合并成一个轮次,此时该字段只携带最后一条消息的 uuid;要把回复匹配到任何被合并的消息,用 user_message_uuids。
  • 你以 isSynthetic: true 发送的消息:轮次起初应答该消息;如果 Claude Code 在工具调用之间拾取了你的一条普通消息,从那时起轮次应答被拾取的消息。回传合成消息的 uuid 需要 Agent SDK v0.3.265 及以上,更早的版本在合成轮次上什么都不回传。
  • Claude Code 在 CLAUDE_CODE_RESUME_INTERRUPTED_TURN 下为重跑被打断的轮次而生成的提示:当被打断轮次的最后一个提示是你发送的普通消息(不论它开启了轮次还是在轮次期间被拾取),重跑起初应答该消息;resume_reason 区分重跑的帧与被打断那次尝试的帧;最后一个提示不是你的普通消息时,重跑起初不应答你的任何消息。
  • Claude Code 自己生成的任何其他提示:轮次起初不应答你的任何消息,其帧不带回传;如果 Claude Code 在工具调用之间拾取了你的一条普通消息,从那时起该轮次应答该消息(拾取回传需要 Agent SDK v0.3.265 及以上)。

Claude Code 在三种帧上回传所应答消息的 uuid:结果——应答了你发送的消息的轮次的每个结果(Agent SDK v0.3.265 及以上,每个这样的结果都带它;v0.3.265 之前,由普通消息开启的轮次的 success 结果在该轮次没有发出 API 请求或以推迟的工具调用结束时缺它;v0.3.246 之前,错误结果也缺它;v0.3.216 之前每个结果都缺它);轮次的第一个回复——第一条助手消息,开启 includePartialMessages 时则是 event.type 不是 ping 的第一个流事件,让你能在结果到达前绑定回复;轮次什么都不流式输出时,Claude Code 改把它设在第一条助手消息上(第一回复回传需要 Agent SDK v0.3.246 及以上;轮次所应答的消息在轮次中途改变时,变化后的第一个回复也带该字段,需要 v0.3.265 及以上);轮次的每个 thinking_tokens 帧——让你无需等待轮次的第一个回复就能把思考进度归属到你发送的消息(需要 Agent SDK v0.3.260 及以上)。Claude Code 在这些情况下省略该字段:第一个回复之外的回复帧;子智能体帧;不应答你任何消息或应答你发送的没有 uuid 的消息的轮次;不应答你发送的任何消息的结果(如工作进程崩溃后的归零结果)。

user_message_uuids

该轮次里 Claude Code 应答的、你发送的每条消息的 uuid。你把几条消息挨得很近地发出时,Claude Code 可以把它们合并成一个轮次,此时 user_message_uuid 只点名最后一条;要把回复匹配到任何被合并的消息,在这个列表里任何位置找该消息的 uuid(需要 Agent SDK v0.3.259 及以上)。Claude Code 在每个带 user_message_uuid 字段的回复帧和结果上同时设置该列表;列表总是包含 user_message_uuid 且最多 64 项;Claude Code 在轮次运行时拾取你发送的普通消息时,会把该消息的 uuid 加入结果的列表;当第一个回复或结果带 user_message_uuid 而没有该列表时,说明它来自较早的 Claude Code 版本,要回退到单个字段。

resume_reason

Claude Code 为什么在重启之后重跑该轮次。Claude Code 把该字段设在它在 CLAUDE_CODE_RESUME_INTERRUPTED_TURN 下重跑的轮次上,让你能把重跑的回复和结果与被打断那次尝试的区分开(需要 Agent SDK v0.3.268 及以上)。设在两种帧上:重跑的结果——success 和 error 分支上都有,不论结果是否带 user_message_uuid;重跑的回复帧——带 user_message_uuid 的那些。值是命名重跑原因的简短小写标记,如 interrupted_turn;其他每个轮次上该字段不存在。

queued_turn_count

Claude Code 产生结果时,仍在命令队列里等待的、你以 origin: { kind: "human" } 发送的消息数(需要 Agent SDK v0.3.242 及以上)。0 和字段缺失告诉你什么:0——Claude Code 不统计你不带该 origin 发送的消息,也不统计任务通知,所以后面仍可能跟着一个轮次;缺失——Claude Code 在崩溃或致命启动错误之后发出的最终结果省略该字段,并可能带归零的总计。

startup_failure_reason

Claude Code 为什么拒绝启动,让你的应用能提供修复办法而不是重试。Claude Code 把它设在已知启动失败时退出前写出的 error_during_execution 结果上;该结果携带归零的总计,其 errors 数组携带与 stderr 相同的文本;其他每个结果上该字段不存在(需要 Agent SDK v0.3.274 及以上)。在 env 里把 CLAUDE_CODE_STARTUP_FAILURE_RESULTS 设为 1,可为每个 SDKStartupFailureReason 值都收到该结果;没有该变量时,Claude Code 只为下面这些失败写结果,其余以 stderr 输出、非零退出而没有结果消息结束:Claude Code 因为无法让会话回到它的 worktree 而停止的恢复(worktree_unverified 或 worktree_resume_refused);被拒绝的、对后台会话所持对话的 continue(session_held_by_background;对这类对话被拒绝的 resume,只有设了该变量时才写结果)。

type SDKStartupFailureReason =
  | "org_pin_api_key_conflict"
  | "provider_not_allowed"
  | "org_verify_failed"
  | "org_pin_mismatch"
  | "managed_settings_invalid"
  | "remote_settings_required_unavailable"
  | "gateway_signin_required"
  | "gateway_access_denied"
  | "proxy_invalid"
  | "temp_dir_unusable"
  | "cwd_unavailable"
  | "shell_tool_missing"
  | "session_held_by_background"
  | "worktree_resume_refused"
  | "worktree_unverified"
  | "cli_version_too_old"
  | "bypass_root";
值是什么阻止了会话
org_pin_api_key_conflict托管设置要求第一方或 Cloud 网关登录,而配置的却是 Anthropic API key、auth 令牌或 apiKeyHelper
provider_not_allowed托管设置列出了这台机器可使用的 API 提供商,而会话设置的是未列出的提供商,或设置没有固定的端点(需要 Claude Code v2.1.285 及以上)
org_verify_failed无法对照固定值验证登录所属的组织,例如因网络失败或令牌被撤销
org_pin_mismatch登录属于固定值不允许的组织
managed_settings_invalid无法读取托管策略设置、固定值没有点名任何组织,或托管的模型限制没给 Default 选项留下任何被允许的模型
remote_settings_required_unavailable无法加载组织要求的托管设置
gateway_signin_requiredCloud 网关结束了这次登录
gateway_access_denied对 Cloud 网关的托管设置请求返回 403(网关的排障表涵盖这种情况)
proxy_invalid某个代理设置不是完整的 URL
temp_dir_unusable每用户临时目录不安全或无法创建
cwd_unavailable工作目录被删除、移动或无法读取
shell_tool_missing在 Windows 上没有可用的 shell 工具:缺 Git Bash,且 PowerShell 缺失或被 CLAUDE_CODE_USE_POWERSHELL_TOOL 关闭
session_held_by_background要恢复或继续的对话正作为后台会话运行
worktree_resume_refused会话的 worktree 没通过安全检查,或恢复是从它内部发起的;errors 说明再次运行同样的恢复是否会不带 worktree 继续
worktree_unverified此刻无法验证会话的 worktree,重试可能成功
cli_version_too_old该 Claude Code 版本低于 Anthropic 要求的最低版本
bypass_root以 root 运行时请求了绕过权限模式

SDKSystemMessage

系统初始化消息。

type SDKSystemMessage = {
  type: "system";
  subtype: "init";
  uuid: UUID;
  session_id: string;
  agents?: string[];
  apiKeySource: ApiKeySource;
  betas?: string[];
  claude_code_version: string;
  cwd: string;
  tools: string[];
  mcp_servers: {
    name: string;
    status: string;
    source?: string;
  }[];
  model: string;
  permissionMode: PermissionMode;
  slash_commands: string[];
  terminal_slash_commands?: string[];
  output_style: string;
  skills: string[];
  plugins: { name: string; path: string }[];
  plugin_errors?: {
    plugin: string;
    type: string;
    message: string;
    path?: string;
  }[];
  fast_mode_state?: FastModeState;
  fast_mode_disabled_reason?: FastModeDisabledReason;
  effort?: "low" | "medium" | "high" | "xhigh" | "max" | null;
  capabilities?: string[];
};

fast_mode_state 报告会话的快速模式状态;有东西阻止快速模式时,fast_mode_disabled_reason 点名阻止它的检查(需要 Claude Code v2.1.219 及以上;原因代码和含义见结果消息上的 fast_mode_disabled_reason)。terminal_slash_commands 点名 slash_commands 里界面绑定到本地终端的条目(如 exit);你可以像发送 slash_commands 里任何其他条目一样发送它们,该字段的存在是让远程或移动客户端能在命令菜单里隐藏它们;字段仅在非空时出现(需要 Agent SDK v0.3.229 及以上)。每个 mcp_servers 条目上的 source 是服务器定义来自哪里,取值同 McpServerStatus 的 source(需要 Agent SDK v0.3.274 及以上)。effort 是 Claude Code 在会话下一个请求上发送的努力级别,不发送时为 null;Claude Code 只在发给 Remote Control 客户端的 init 消息上设置该字段,从你的应用读取的 init 消息里省略它(需要 Agent SDK v0.3.234 及以上)。

capabilities 数组点名这个 CLI 实现的协议行为,让你能做功能检测而不是比较 claude_code_version 字符串;它是开放集合:忽略你不认识的值,检查你所依赖行为对应的那个具体能力;该字段需要 Claude Code v2.1.205 及以上,更早的 CLI 上不存在。

能力含义
interrupt_receipt_v1interrupt() 以列出中断到达时待处理消息的 SDKControlInterruptResponse 回执解析
interrupt_cancel_queued_v1interrupt 控制请求遵从 cancel_queued: true,取消回执本会列在 still_queued 下的消息,并改把它们列在 cancelled 下(需要 Claude Code v2.1.219 及以上)

plugin_errors 数组列出插件加载失败。一个条目描述的要么是没有加载且不在 plugins 里的插件,要么是加载了但缺少某一部分(如它的 hooks 文件)的插件;没有失败时省略该键(SDKSystemMessage 在 Agent SDK v0.3.283 及以上声明 plugin_errors)。当你的 plugins 选项里的某个目录或归档本身加载失败(例如路径不存在或清单无效)时,条目的 plugin 字段持有 inline[0] 这样的位置标记而不是插件名,要按其 path 字段把这样的条目与你的选项匹配。每个 plugin_errors 条目的字段:

字段类型说明
pluginstring失败插件的 ID,或插件目录或归档本身加载失败时的位置标记如 inline[0]
typestring来自开放集合的错误类别,如 path-not-found 或 manifest-validation-error;对你不认识的值要当作一般失败处理
messagestring描述失败的显示文本
pathstring只在插件目录或归档本身加载失败时出现;它的绝对路径,来自你 plugins 选项的相对路径按 cwd 选项解析

SDKPartialAssistantMessage

流式部分消息(仅当 includePartialMessages 为 true 时)。parent_tool_use_id 字段总是 null:流事件只为主会话发出。要做子智能体归属,用带 parent_tool_use_id 的完整消息,或开启 forwardSubagentText 以完整消息的形式接收子智能体的文本和思考。

type SDKPartialAssistantMessage = {
  type: "stream_event";
  event: BetaRawMessageStreamEvent; // 来自 Anthropic SDK
  parent_tool_use_id: string | null;
  uuid: UUID;
  session_id: string;
  ttft_ms?: number; // 首 token 时间(毫秒),只出现在 message_start 事件上
  user_message_uuid?: string;
  user_message_uuids?: string[];
  resume_reason?: string;
};

Claude Code 把 user_message_uuid 和 user_message_uuids 设在轮次的第一个非 ping 流事件上,并在轮次所应答的消息改变时再次设置,条件见 user_message_uuid;Claude Code 重跑被重启打断的轮次时,带这些字段的重跑流事件也带 resume_reason。

SDKCompactBoundaryMessage

表示对话压缩边界的消息。

type SDKCompactBoundaryMessage = {
  type: "system";
  subtype: "compact_boundary";
  uuid: UUID;
  session_id: string;
  compact_metadata: {
    trigger: "manual" | "auto";
    pre_tokens: number;
  };
};

SDKInformationalMessage

循环发出的通用文本横幅,携带警告、通知,以及 Claude Code 提出的其他非错误状态行,还有 hook 反馈(如 UserPromptSubmit hook 的阻止原因)。在 Claude Code v2.1.227 及以上,hook 的 systemMessage 可以作为这条消息到达,每行以 hook 名作前缀,如 PostToolUse:Bash says:;各事件的输出如何呈现,见 hooks 页上该事件的章节。要把 content 按纯文本、以给定的 level 渲染。

type SDKInformationalMessage = {
  type: "system";
  subtype: "informational";
  content: string;
  level: "info" | "notice" | "suggestion" | "warning";
  tool_use_id?: string;
  prevent_continuation?: boolean;
  uuid: UUID;
  session_id: string;
};

SDKWorkerShuttingDownMessage

在工作进程优雅拆除时发出,让远程客户端能显示工作进程为何退出,而不必等心跳超时。reason 是宿主 CLI 设置的简短 snake_case 字符串,如 "host_exit" 或 "remote_control_disabled"。只在实时流式时对它采取行动;恢复的会话会重放这条消息的过往实例,这种情况下要忽略它们。

type SDKWorkerShuttingDownMessage = {
  type: "system";
  subtype: "worker_shutting_down";
  reason: string;
  uuid: UUID;
  session_id: string;
};

SDKPluginInstallMessage

插件安装进度事件。设了 CLAUDE_CODE_SYNC_PLUGIN_INSTALL 时发出,让你的 Agent SDK 应用能在第一个轮次之前跟踪市场插件的安装。started 和 completed 状态括起整体安装;installed 和 failed 状态报告单个市场并包含 name。

type SDKPluginInstallMessage = {
  type: "system";
  subtype: "plugin_install";
  status: "started" | "installed" | "failed" | "completed";
  name?: string;
  error?: string;
  uuid: UUID;
  session_id: string;
};

SDKPermissionDeniedMessage

权限系统不经交互式提示就拒绝工具调用时发出的流事件。用它在你的界面里即时渲染拒绝,而不是只观察随后的 is_error 工具结果。它报告哪些拒绝取决于运行如何处理权限提示:

  • 有 canUseTool 回调且为默认 permissionPrompts: 'host':权限提示去你的回调,该事件报告 Claude Code 自己决定、没有调用回调的拒绝。
  • 两者都没有:裸的 -p 运行,或既没设 canUseTool 也没设 permissionPromptToolName 的 query(),拒绝任何本会提示的工具调用,该事件报告这些拒绝以及 Claude Code 自己决定的拒绝(v2.1.223 之前,没有回调的运行里 Claude Code 不发出该事件)。
  • 有 MCP 提示工具(用 permissionPromptToolName 或 --permission-prompt-tool 标志设置)且为默认 permissionPrompts: 'host':Claude Code 根本不发出该事件,连它自己决定的规则拒绝也不发。
  • permissionPrompts: 'none':Claude Code 拒绝本会提示的调用,即使同时设了 canUseTool 或 MCP 提示工具,该事件报告这些拒绝以及 Claude Code 自己决定的拒绝(需要 Claude Code v2.1.259 及以上)。

在每种配置下,该事件都跳过在 PreToolUse hook 路径上决定的拒绝,不论是 hook 自己拒绝了调用,还是拒绝规则覆盖了 hook 的允许或询问决定。该事件也是尽力而为的:偶尔 Claude Code 记录了拒绝却没有发出该事件,所以结果消息上的 permission_denials 才是权威记录。

type SDKPermissionDeniedMessage = {
  type: "system";
  subtype: "permission_denied";
  tool_name: string;
  tool_use_id: string;
  agent_id?: string;
  decision_reason_type?: string;
  decision_reason?: string;
  message: string;
  uuid: UUID;
  session_id: string;
};
字段类型说明
tool_namestring被拒绝的工具名
tool_use_idstring该拒绝所应答的 tool_use 块的 ID
agent_idstring被拒绝的调用源自子智能体内部时的子智能体 ID;与 can_use_tool 上的字段对应,用于宿主侧路由
decision_reason_typestring做出决定的组件的判别值,如 "rule"、"mode"、"classifier" 或 "asyncAgent"
decision_reasonstring来自做出决定的组件的人类可读原因(如有)
messagestring在 tool_result 里返回给模型的拒绝消息

SDKPermissionDenial

被拒绝的工具使用的信息。

type SDKPermissionDenial = {
  tool_name: string;
  tool_use_id: string;
  tool_input: Record<string, unknown>;
};

SDKContextUsage

/context 报告的结构化形式,作为交付 /context 结果的 SDKAssistantMessage 上的 context_usage 携带(Agent SDK v0.3.232 及以上导出该类型)。与 SDKControlGetContextUsageResponse 不同,它只携带渲染用量拆解所需的数据,没有 color 和 gridRows 这样的显示字段。Claude Code 用不出现在消息流里的 token 计数 API 请求计算该报告。

type SDKContextUsage = {
  model: string;
  total_tokens: number;
  raw_max_tokens: number;
  percentage: number;
  over_limit?: {
    tokens_over: number;
    kind: "hard_limit" | "compaction_window";
  };
  categories: SDKContextUsageCategory[];
  mcp_tools: {
    name: string;
    server_name: string;
    tokens: number;
  }[];
  memory_files: {
    path: string;
    type: string;
    tokens: number;
  }[];
  agents: {
    agent_type: string;
    source: string;
    tokens: number;
  }[];
  skills?: {
    name: string;
    source: string;
    plugin_name?: string;
    tokens: number;
  }[];
};

从 model 到 over_limit 的字段描述整个会话,集合字段把 token 归属到各个条目:

字段类型说明
modelstringClaude Code 为其计算用量的主循环模型,不是子智能体的
total_tokensnumberClaude Code 对使用中 token 数的估算;不钳到窗口,所以会话超过限制时它可以超过 raw_max_tokens
raw_max_tokensnumber模型的上下文窗口,或适用时更低的自动压缩窗口(如你设置的,或 Claude Code 对某些 1M token 窗口模型应用的 200K 边界);Claude Code 以该窗口衡量 total_tokens
percentagenumbertotal_tokens 占 raw_max_tokens 的四舍五入百分比,所以会话超过限制时可超过 100
over_limitobject仅当 total_tokens 超过 raw_max_tokens 时出现;tokens_over 是超出量,kind 说明 Claude Code 如何解析窗口
categoriesSDKContextUsageCategory[]按类别用量拆解的每一行一项
mcp_toolsobject[]归属到每个 MCP 工具的 token,带其线上名(如 mcp__linear__create_issue)和 server_name
memory_filesobject[]归属到每个已加载记忆文件的 token,带其 path,type 里是 Project 或 User 这类来源标签
agentsobject[]归属到每个自定义子智能体定义的 token,带 projectSettings、userSettings 或 plugin 这类来源标识;不列内置子智能体
skillsobject[]归属到 skill 列表里每个 skill 的 token,带来源标识,对插件 skill 还有 plugin_name 里的插件名;没有 skill 贡献 token 时不存在

over_limit.kind 记录 Claude Code 如何解析窗口,而不是 API 是否接受下一个请求:hard_limit——窗口是 Claude Code 认为的模型自身限制,超过它 API 就拒绝请求;compaction_window——窗口是压缩策略的窗口,可能与也可能与模型的限制不一致。Claude Code 以增量方式演进该类型,把新数据作为可选字段添加,而不是重塑现有字段;读取你认识的字段,忽略你不认识的。

SDKContextUsageCategory

/context 按类别用量拆解的一行。

type SDKContextUsageCategory = {
  name: string;
  tokens: number;
  kind: "used" | "free" | "buffer" | "deferred";
};

name 是该行按 /context 打印的显示名(如 Messages),要按 kind 而不是名字给行分类;tokens 是该行的 token 数,行可以是零 token;kind 表示该行代表什么:used——占用上下文窗口的内容;free——剩余窗口;buffer——压缩预留;deferred——Claude Code 放在窗口外、排除在用量计算之外的工具 schema,列出供了解。

SDKMessageOrigin

用户角色消息的来源。它作为 origin 出现在 SDKUserMessage 上,并被转发到对应的 SDKResultMessage 上,使你能分辨是什么触发了某个轮次。

type SDKMessageOrigin =
  | { kind: "human" }
  | { kind: "channel"; server: string }
  | {
      kind: "peer";
      from: string;
      fromMode?: "bypass" | "prompting";
      name?: string;
      fromSession?: string;
      senderTaskId?: string;
      body?: string;
      verifiedPeerPid?: number;
    }
  | {
      kind: "task-notification";
      subkind?: "scheduled-trigger" | "peer-send-message";
      fireReason?: string;
    }
  | { kind: "coordinator" }
  | { kind: "auto-continuation" }
  | { kind: "unclassified" };
kind含义
human来自最终用户的直接输入。如果你的应用把用户键入的内容作为用户消息转发,要显式把它的 origin 设为 { kind: "human" }:Claude Code 把没有 origin 的用户消息视为未归属,要求人类键入提示的检查(如 ultracode 工作流关键词)不接受它(v2.1.210 之前,Claude Code 把用户消息上缺失的 origin 当作人类输入)
channel在频道上到达的消息;server 是来源 MCP 服务器名
peer来自另一个智能体的消息:进程内的队友,或跨会话的对等方(你的另一个 Claude Code 会话);各字段语义和信任模型见「对等来源字段」
task-notification为没有新用户提示而到达的投递(如完成的后台任务)注入的合成轮次;你的应用声明为计划运行的提示也带这个 kind;可选的 subkind 标出是什么引发了通知,见「任务通知 subkind」
coordinator来自智能体团队里团队协调者的消息
auto-continuation会话没有新的用户输入而继续时注入的合成轮次,如触发后续提示的命令结果
unclassified来源无法确定的注入轮次(需要 Claude Code v2.1.223 及以上):Claude Code 收到 isSynthetic: true 的 SDKUserMessage 且无法把它归入任何其他 kind 时,在消息到达时设置这个 kind,并向模型把该轮次表述为非用户来源而不是当作人类输入;你的应用不应设置这个值

任务通知 subkind

Claude Code 把任务通知交付进会话时,如果 Anthropic 服务器验证了该通知来自哪里,就在通知的 origin 上设置 subkind;当你的应用自己把消息声明为计划运行时也设置它(需要 TypeScript Agent SDK v0.3.280 及以上)。subkind 需要 Claude Code v2.1.213 及以上,取两个值之一:

  • scheduled-trigger:通知是例程存储的提示,因例程的某个触发器触发而交付:它的计划、它的 API 触发器、它的 GitHub 触发器,或 Run now;你的应用声明为计划运行的提示也带这个值。Claude Code 向模型把这些表述为会话被分配的任务,使用与其他任务通知不同的提示。
  • peer-send-message:通知是你的另一个会话用云端会话互相发消息所用的服务端 send_message 工具(不是跨会话的 SendMessage 工具)发来的消息,并且 Anthropic 服务器验证了两个会话属于同一个私有会话组(需要 Claude Code v2.1.224 及以上);服务器没有以这种方式验证的 send_message 投递没有 subkind。

其他每个任务通知都没有 subkind,包括交付进会话的 PR 活动和已完成任务这样的后台事件。来自跨会话 SendMessage 工具的消息根本不是任务通知:不论来自同一机器上的会话,还是经 Anthropic 服务器来自另一台机器,Claude Code 都给它们 kind: "peer" 和对等来源字段。fireReason 说明 scheduled-trigger 通知为何触发,是简短的小写标记,如 scheduled、manual、retry、catch_up 或 api;Anthropic 服务器在例程的投递上设置它,你的应用在声明计划运行时设置它;两者都没发送时缺失(需要 TypeScript Agent SDK v0.3.280 及以上)。

声明计划运行:如果你的应用按自己的计划运行提示,要声明每次运行,让 Claude Code 向模型把该轮次表述为计划任务而不是来自用户的实时输入。启动会话时在 env 里把 CLAUDE_CODE_HOST_SCHEDULED_RUN 设为 1,然后发送该次运行的 SDKUserMessage,带 origin: { kind: "task-notification", subkind: "scheduled-trigger", fireReason: "scheduled" } 且不带 isSynthetic。在没有该变量启动的进程里,Claude Code 忽略这个声明。

对等来源字段

peer 来源标识哪个智能体发送了消息:用 SendMessage 发给 main 的进程内队友,或跨会话的对等方(你的另一个 Claude Code 会话)。跨会话对等方在 macOS 和 Linux 上需要 Claude Code v2.1.224 及以上(原生 Windows 的要求见跨会话消息的可用性);跨会话对等方可以在同一机器上运行,也可以在你的另一台机器上或云端运行,此时它的消息经 Remote Control 到达。

  • from:队友的名字,或跨会话对等方的发送者地址;对单向的跨机器消息,发送者没有回复地址,from 是 "unknown"。该值由发送者撰写,已验证的身份是 verifiedPeerPid。
  • fromMode:发送会话的权限类别 bypass 或 prompting,由在你的会话之间中继对等消息的宿主(如桌面应用)声明;Claude Code 在接收会话应用入站控制时读取它(需要 Agent SDK v0.3.234 及以上)。
  • senderTaskId:队友的任务 ID;跨会话对等方没有。
  • name:发送者的显示名,经 Claude Code 规范化:去掉 Unicode 控制、格式、代理对以及行或段分隔符码位,再修剪并把结果限制在 64 个码位内,超出加省略号(需要 Claude Code v2.1.205 及以上)。
  • body:去掉对等信封后解码的消息正文,与模型看到的字节完全一致;队友消息总有;对跨会话对等方,仅当轮次恰好是 Claude Code 构成的一个对等信封时才有。渲染 name 和 body,而不要重新解析消息文本(需要 Claude Code v2.1.205 及以上)。
  • fromSession:发送者的宿主可打开的会话 ID,由发送者的宿主设置,让你的界面能链接回发送会话;与 from 一样由发送者断言:只把它用作导航目标,不要当作发送者身份的证明(需要 Claude Code v2.1.216 及以上)。
  • verifiedPeerPid:连接到该会话跨会话消息 socket 的进程的进程 ID,由内核验证,读自连接本身,而不是载荷。用它而不是 from 来识别发送者:from 可被任何同用户进程伪造;当 Claude Code 无法验证(如在 Windows 或非 socket 入口)时该字段缺失,所以缺失值表示发送者未经验证;对经中继的流量,它标识的是中继而不是消息的原始发送者。