From c0c7ed2f19f7eb8efbaa37c049e1764ba9cdc601 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Fri, 10 Apr 2026 20:26:35 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/concepts/model-providers.md | 556 +++++++----------- docs/zh-CN/help/testing.md | 637 +++++++++++---------- docs/zh-CN/plugins/sdk-agent-harness.md | 192 +++++++ docs/zh-CN/plugins/sdk-overview.md | 427 +++++++------- docs/zh-CN/plugins/sdk-provider-plugins.md | 314 ++++------ docs/zh-CN/plugins/sdk-runtime.md | 165 +++--- 6 files changed, 1165 insertions(+), 1126 deletions(-) create mode 100644 docs/zh-CN/plugins/sdk-agent-harness.md diff --git a/docs/zh-CN/concepts/model-providers.md b/docs/zh-CN/concepts/model-providers.md index 6681acf64..52a99d782 100644 --- a/docs/zh-CN/concepts/model-providers.md +++ b/docs/zh-CN/concepts/model-providers.md @@ -1,264 +1,148 @@ --- read_when: - - 你需要按提供商分类的模型设置参考 - - 你想查看模型提供商的示例配置或 CLI 新手引导命令 -summary: 提供商概览,包含示例配置和 CLI 流程 + - 你需要一份按提供商分类的模型设置参考。 + - 你想要模型提供商的示例配置或 CLI 新手引导命令。 +summary: 模型提供商概览,包含示例配置和 CLI 流程 title: 模型提供商 x-i18n: - generated_at: "2026-04-08T18:09:20Z" + generated_at: "2026-04-10T20:23:47Z" model: gpt-5.4 provider: openai - source_hash: 53e3141256781002bbe1d7e7b78724a18d061fcf36a203baae04a091b8c9ea1b + source_hash: f3d50795107077c7065773b5e545fae04b97f1d932a650d577b325d93bf25192 source_path: concepts/model-providers.md workflow: 15 --- # 模型提供商 -本页介绍 **LLM/模型提供商**(不是像 WhatsApp/Telegram 这样的聊天渠道)。 -有关模型选择规则,请参阅 [/concepts/models](/zh-CN/concepts/models)。 +本页介绍 **LLM / 模型提供商**(不是像 WhatsApp / Telegram 这样的聊天渠道)。 +有关模型选择规则,请参见 [/concepts/models](/zh-CN/concepts/models)。 ## 快速规则 -- 模型引用使用 `provider/model`(例如:`opencode/claude-opus-4-6`)。 -- 如果你设置了 `agents.defaults.models`,它会成为允许列表。 +- 模型引用使用 `provider/model`(示例:`opencode/claude-opus-4-6`)。 +- 如果你设置了 `agents.defaults.models`,它就会成为允许列表。 - CLI 辅助命令:`openclaw onboard`、`openclaw models list`、`openclaw models set `。 -- 回退运行时规则、冷却探测以及会话覆盖持久化记录在 [/concepts/model-failover](/zh-CN/concepts/model-failover)。 -- `models.providers.*.models[].contextWindow` 是原生模型元数据; - `models.providers.*.models[].contextTokens` 是实际运行时上限。 -- 提供商插件可以通过 `registerProvider({ catalog })` 注入模型目录; - OpenClaw 会在写入 - `models.json` 之前将该输出合并到 `models.providers` 中。 -- 提供商清单可以声明 `providerAuthEnvVars` 和 - `providerAuthAliases`,这样通用的基于环境变量的身份验证探测以及提供商变体 - 就不需要加载插件运行时。剩余的核心环境变量映射现在 - 仅用于非插件/核心提供商,以及少数通用优先级场景, - 例如 Anthropic API 密钥优先的新手引导。 -- 提供商插件还可以通过以下方式拥有提供商运行时行为: - `normalizeModelId`、`normalizeTransport`、`normalizeConfig`、 - `applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、 - `resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`、 - `resolveDynamicModel`、`prepareDynamicModel`、 - `normalizeResolvedModel`、`contributeResolvedModelCompat`、 - `capabilities`、`normalizeToolSchemas`、 - `inspectToolSchemas`、`resolveReasoningOutputMode`、 - `prepareExtraParams`、`createStreamFn`、`wrapStreamFn`、 - `resolveTransportTurnState`、`resolveWebSocketSessionPolicy`、 - `createEmbeddingProvider`、`formatApiKey`、`refreshOAuth`、 - `buildAuthDoctorHint`、 - `matchesContextOverflowError`、`classifyFailoverReason`、 - `isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、 - `augmentModelCatalog`、`isBinaryThinking`、`supportsXHighThinking`、 - `resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、 - `prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot`,以及 - `onModelSelected`。 -- 注意:提供商运行时 `capabilities` 是共享运行器元数据(提供商 - 家族、转录/工具特性、传输/缓存提示)。它与[公共能力模型](/zh-CN/plugins/architecture#public-capability-model) - 不同,后者描述的是插件注册了什么(文本推理、语音等)。 +- 回退运行时规则、冷却探测和会话覆盖持久化记录在 [/concepts/model-failover](/zh-CN/concepts/model-failover)。 +- `models.providers.*.models[].contextWindow` 是原生模型元数据;`models.providers.*.models[].contextTokens` 是实际运行时上限。 +- 提供商插件可以通过 `registerProvider({ catalog })` 注入模型目录;OpenClaw 会在写入 `models.json` 之前将该输出合并到 `models.providers` 中。 +- 提供商清单可以声明 `providerAuthEnvVars` 和 `providerAuthAliases`,这样通用的基于环境变量的凭证探测和提供商变体就不需要加载插件运行时。剩余的核心环境变量映射现在仅用于非插件 / 核心提供商,以及少数通用优先级场景,例如 Anthropic API 密钥优先的新手引导。 +- 提供商插件还可以通过以下能力拥有提供商运行时行为:`normalizeModelId`、`normalizeTransport`、`normalizeConfig`、`applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、`resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`、`resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`、`contributeResolvedModelCompat`、`capabilities`、`normalizeToolSchemas`、`inspectToolSchemas`、`resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`、`wrapStreamFn`、`resolveTransportTurnState`、`resolveWebSocketSessionPolicy`、`createEmbeddingProvider`、`formatApiKey`、`refreshOAuth`、`buildAuthDoctorHint`、`matchesContextOverflowError`、`classifyFailoverReason`、`isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`isBinaryThinking`、`supportsXHighThinking`、`resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot` 和 `onModelSelected`。 +- 注意:提供商运行时 `capabilities` 是共享运行器元数据(提供商家族、转录 / 工具怪癖、传输 / 缓存提示)。它不同于[公共能力模型](/zh-CN/plugins/architecture#public-capability-model),后者描述的是插件注册了什么内容(文本推理、语音等)。 +- 内置的 `codex` 提供商与内置的 Codex 智能体 harness 配对使用。当你需要 Codex 自有登录、模型发现、原生线程恢复和应用服务器执行时,请使用 `codex/gpt-*`。普通的 `openai/gpt-*` 引用仍会使用 OpenAI 提供商和标准的 OpenClaw 提供商传输。 ## 插件自有的提供商行为 -现在,提供商插件可以拥有大多数提供商特定逻辑,而 OpenClaw 保留 -通用推理循环。 +提供商插件现在可以拥有大多数提供商特定逻辑,而 OpenClaw 保持通用推理循环。 -典型拆分如下: +典型分工: -- `auth[].run` / `auth[].runNonInteractive`:提供商拥有 `openclaw onboard`、`openclaw models auth` 和无头设置的 - 新手引导/登录流程 -- `wizard.setup` / `wizard.modelPicker`:提供商拥有身份验证选择标签、 - 旧版别名、新手引导允许列表提示,以及新手引导/模型选择器中的设置项 -- `catalog`:提供商显示在 `models.providers` 中 -- `normalizeModelId`:提供商在 - 查找或规范化之前标准化旧版/预览模型 id -- `normalizeTransport`:提供商在通用模型组装之前标准化传输族的 `api` / `baseUrl`; - OpenClaw 会先检查匹配的提供商, - 然后再检查其他具备 hook 能力的提供商插件,直到其中某个真正修改了 - 传输 -- `normalizeConfig`:提供商在 - 运行时使用前标准化 `models.providers.` 配置;OpenClaw 会先检查匹配的提供商,然后再检查其他 - 具备 hook 能力的提供商插件,直到其中某个真正修改了配置。如果没有 - 提供商 hook 重写配置,内置的 Google 系列辅助工具仍会 - 标准化受支持的 Google 提供商条目。 -- `applyNativeStreamingUsageCompat`:提供商对配置提供商应用由端点驱动的原生流式用量兼容性重写 -- `resolveConfigApiKey`:提供商为配置提供商解析 env 标记身份验证, - 无需强制加载完整运行时身份验证。`amazon-bedrock` 在这里也有一个 - 内置的 AWS env 标记解析器,尽管 Bedrock 运行时身份验证使用的是 - AWS SDK 默认链。 -- `resolveSyntheticAuth`:提供商可以暴露本地/自托管或其他 - 基于配置的身份验证可用性,而不持久化明文密钥 -- `shouldDeferSyntheticProfileAuth`:提供商可以将已存储的合成配置文件 - 占位符标记为优先级低于基于环境变量/配置的身份验证 -- `resolveDynamicModel`:提供商接受本地 - 静态目录中尚不存在的模型 id -- `prepareDynamicModel`:提供商在重试 - 动态解析之前需要刷新元数据 -- `normalizeResolvedModel`:提供商需要重写传输或 base URL -- `contributeResolvedModelCompat`:提供商为其 - 厂商模型提供兼容性标记,即使这些模型是通过另一个兼容传输到达的 -- `capabilities`:提供商发布转录/工具/提供商家族特性 -- `normalizeToolSchemas`:提供商在嵌入式 - 运行器看到工具 schema 之前清理它们 -- `inspectToolSchemas`:提供商在标准化之后显示传输特定的 schema 警告 -- `resolveReasoningOutputMode`:提供商选择原生还是带标签的 - reasoning-output 契约 -- `prepareExtraParams`:提供商为每个模型请求参数设置默认值或执行标准化 -- `createStreamFn`:提供商使用完全 - 自定义传输替换正常流路径 -- `wrapStreamFn`:提供商应用请求头/请求体/模型兼容性包装器 -- `resolveTransportTurnState`:提供商提供逐轮的原生传输 - 请求头或元数据 -- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话 - 请求头或会话冷却策略 -- `createEmbeddingProvider`:当内存嵌入行为 - 更适合放在提供商插件而不是核心嵌入切换板中时,由提供商拥有该行为 -- `formatApiKey`:提供商将已存储的身份验证配置文件格式化为 - 传输期望的运行时 `apiKey` 字符串 -- `refreshOAuth`:当共享的 `pi-ai` - 刷新器不够用时,由提供商拥有 OAuth 刷新逻辑 -- `buildAuthDoctorHint`:当 OAuth 刷新 - 失败时,提供商追加修复指导 -- `matchesContextOverflowError`:提供商识别提供商特有的 - 上下文窗口溢出错误,这是通用启发式方法会漏掉的 -- `classifyFailoverReason`:提供商将提供商特有的原始传输/API - 错误映射为回退原因,例如速率限制或过载 -- `isCacheTtlEligible`:提供商决定哪些上游模型 id 支持提示缓存 TTL -- `buildMissingAuthMessage`:提供商用提供商特有的恢复提示 - 替换通用身份验证存储错误 -- `suppressBuiltInModel`:提供商隐藏过时的上游条目,并且可以在直接解析失败时返回 - 厂商自有错误 -- `augmentModelCatalog`:提供商在 - 发现和配置合并之后追加合成/最终目录条目 -- `isBinaryThinking`:提供商拥有二元开/关 thinking UX +- `auth[].run` / `auth[].runNonInteractive`:提供商拥有用于 `openclaw onboard`、`openclaw models auth` 和无头设置的新手引导 / 登录流程 +- `wizard.setup` / `wizard.modelPicker`:提供商拥有凭证选择标签、旧版别名、新手引导允许列表提示,以及新手引导 / 模型选择器中的设置项 +- `catalog`:提供商会出现在 `models.providers` 中 +- `normalizeModelId`:提供商会在查找或规范化之前标准化旧版 / 预览模型 ID +- `normalizeTransport`:提供商会在通用模型组装之前标准化传输家族 `api` / `baseUrl`;OpenClaw 会先检查匹配的提供商,然后检查其他具备 hook 能力的提供商插件,直到有一个真正更改了传输 +- `normalizeConfig`:提供商会在运行时使用前标准化 `models.providers.` 配置;OpenClaw 会先检查匹配的提供商,然后检查其他具备 hook 能力的提供商插件,直到有一个真正更改了配置。如果没有提供商 hook 重写配置,内置的 Google 系列辅助逻辑仍会标准化受支持的 Google 提供商条目。 +- `applyNativeStreamingUsageCompat`:提供商会为配置提供商应用由端点驱动的原生流式使用量兼容性重写 +- `resolveConfigApiKey`:提供商会为配置提供商解析环境变量标记凭证,而无需强制加载完整运行时凭证。`amazon-bedrock` 在这里也有一个内置的 AWS 环境变量标记解析器,尽管 Bedrock 运行时凭证使用的是 AWS SDK 默认链。 +- `resolveSyntheticAuth`:提供商可以在不持久化明文密钥的情况下暴露本地 / 自托管或其他基于配置的凭证可用性 +- `shouldDeferSyntheticProfileAuth`:提供商可以将存储的合成凭证配置占位符标记为低于环境变量 / 配置支持的凭证优先级 +- `resolveDynamicModel`:提供商可以接受尚未出现在本地静态目录中的模型 ID +- `prepareDynamicModel`:提供商需要在重试动态解析前刷新元数据 +- `normalizeResolvedModel`:提供商需要重写传输或基础 URL +- `contributeResolvedModelCompat`:即使其厂商模型通过另一种兼容传输到达,提供商也可以为其贡献兼容标志 +- `capabilities`:提供商发布转录 / 工具 / 提供商家族怪癖 +- `normalizeToolSchemas`:提供商会在嵌入式运行器看到工具 schema 之前对其进行清理 +- `inspectToolSchemas`:提供商会在标准化之后暴露传输特定的 schema 警告 +- `resolveReasoningOutputMode`:提供商选择原生或带标签的推理输出契约 +- `prepareExtraParams`:提供商为按模型划分的请求参数提供默认值或进行标准化 +- `createStreamFn`:提供商用完全自定义的传输替换正常流式路径 +- `wrapStreamFn`:提供商应用请求头 / 请求体 / 模型兼容包装器 +- `resolveTransportTurnState`:提供商提供每轮的原生传输头或元数据 +- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话头或会话冷却策略 +- `createEmbeddingProvider`:当记忆嵌入行为应归属于提供商插件而不是核心嵌入切换板时,由提供商负责 +- `formatApiKey`:提供商将存储的凭证配置格式化为传输所期望的运行时 `apiKey` 字符串 +- `refreshOAuth`:当共享的 `pi-ai` 刷新器不足时,由提供商负责 OAuth 刷新 +- `buildAuthDoctorHint`:当 OAuth 刷新失败时,提供商追加修复指导 +- `matchesContextOverflowError`:提供商识别通用启发式方法可能漏掉的提供商特定上下文窗口溢出错误 +- `classifyFailoverReason`:提供商将提供商特定的原始传输 / API 错误映射为回退原因,例如速率限制或过载 +- `isCacheTtlEligible`:提供商决定哪些上游模型 ID 支持提示缓存 TTL +- `buildMissingAuthMessage`:提供商用提供商特定的恢复提示替换通用凭证存储错误 +- `suppressBuiltInModel`:提供商隐藏过时的上游条目,并且可以在直接解析失败时返回厂商自有错误 +- `augmentModelCatalog`:提供商在发现和配置合并之后追加合成 / 最终目录条目 +- `isBinaryThinking`:提供商拥有二元开 / 关思考 UX - `supportsXHighThinking`:提供商让选定模型支持 `xhigh` -- `resolveDefaultThinkingLevel`:提供商拥有某个 - 模型家族的默认 `/think` 策略 -- `applyConfigDefaults`:提供商在 - 配置具体化期间,根据身份验证模式、环境变量或模型家族应用提供商特有的全局默认值 -- `isModernModelRef`:提供商拥有 live/smoke 首选模型匹配 -- `prepareRuntimeAuth`:提供商将已配置的凭据转换为短期有效的 - 运行时令牌 -- `resolveUsageAuth`:提供商为 `/usage` - 以及相关状态/报告界面解析用量/配额凭据 -- `fetchUsageSnapshot`:提供商拥有用量端点获取/解析逻辑,而 - 核心仍拥有摘要外壳和格式化 -- `onModelSelected`:提供商运行模型选定后的副作用,例如 - 遥测或提供商自有的会话记账 +- `resolveDefaultThinkingLevel`:提供商拥有某个模型家族的默认 `/think` 策略 +- `applyConfigDefaults`:提供商在配置实体化期间根据凭证模式、环境或模型家族应用提供商特定的全局默认值 +- `isModernModelRef`:提供商拥有 live / smoke 首选模型匹配 +- `prepareRuntimeAuth`:提供商将已配置的凭证转换为短时有效的运行时令牌 +- `resolveUsageAuth`:提供商为 `/usage` 以及相关状态 / 报告界面解析使用量 / 配额凭证 +- `fetchUsageSnapshot`:提供商拥有使用量端点的获取 / 解析逻辑,而核心仍拥有汇总外壳和格式化 +- `onModelSelected`:提供商在选定模型后运行副作用,例如遥测或提供商自有的会话记账 当前内置示例: -- `anthropic`:Claude 4.6 前向兼容回退、身份验证修复提示、用量 - 端点获取、缓存 TTL/提供商家族元数据,以及感知身份验证的全局 - 配置默认值 -- `amazon-bedrock`:提供商自有的上下文溢出匹配和 - Bedrock 特有的节流/未就绪错误回退原因分类,以及 - 共享的 `anthropic-by-model` 重放家族,用于 Anthropic 流量上的 - 仅 Claude 重放策略保护 -- `anthropic-vertex`:Anthropic 消息 - 流量上的仅 Claude 重放策略保护 -- `openrouter`:透传模型 id、请求包装器、提供商能力 - 提示、代理 Gemini 流量上的 Gemini thought-signature 清理、通过 `openrouter-thinking` 流家族 - 注入代理 reasoning、 - 路由元数据转发以及缓存 TTL 策略 -- `github-copilot`:新手引导/设备登录、前向兼容模型回退、 - Claude-thinking 转录提示、运行时令牌交换以及用量端点 - 获取 -- `openai`:GPT-5.4 前向兼容回退、直接 OpenAI 传输 - 标准化、支持 Codex 的缺失身份验证提示、Spark 屏蔽、合成的 - OpenAI/Codex 目录条目、thinking/live-model 策略、用量令牌别名 - 标准化(`input` / `output` 以及 `prompt` / `completion` 家族)、共享的 - `openai-responses-defaults` 流家族,用于原生 OpenAI/Codex - 包装器、提供商家族元数据、为 `gpt-image-1` 注册的内置图像生成提供商, - 以及为 `sora-2` 注册的内置视频生成提供商 -- `google` 和 `google-gemini-cli`:Gemini 3.1 前向兼容回退、 - 原生 Gemini 重放验证、bootstrap 重放清理、带标签的 - reasoning-output 模式、现代模型匹配、为 Gemini 图像预览模型注册的内置图像生成 - 提供商,以及为 Veo 模型注册的内置 - 视频生成提供商;Gemini CLI OAuth 还拥有 - 身份验证配置文件令牌格式化、用量令牌解析和配额端点 - 获取,用于用量界面 -- `moonshot`:共享传输、插件自有的 thinking 负载标准化 -- `kilocode`:共享传输、插件自有的请求头、reasoning 负载 - 标准化、代理 Gemini thought-signature 清理以及缓存 TTL - 策略 -- `zai`:GLM-5 前向兼容回退、`tool_stream` 默认值、缓存 TTL - 策略、二元 thinking/live-model 策略,以及用量身份验证 + 配额获取; - 未知的 `glm-5*` id 会根据内置的 `glm-4.7` 模板合成 -- `xai`:原生 Responses 传输标准化、用于 - Grok fast 变体的 `/fast` 别名重写、默认 `tool_stream`、xAI 特有的工具 schema / - reasoning 负载清理,以及内置的视频生成提供商 - 注册,用于 `grok-imagine-video` -- `mistral`:插件自有的能力元数据 -- `opencode` 和 `opencode-go`:插件自有的能力元数据,以及 - 代理 Gemini thought-signature 清理 -- `alibaba`:用于直接 Wan 模型引用的插件自有视频生成目录, - 例如 `alibaba/wan2.6-t2v` -- `byteplus`:插件自有目录,以及为 Seedance 文生视频/图生视频模型注册的内置 - 视频生成提供商 -- `fal`:为托管的第三方 - 图像生成提供商注册的内置 FLUX 图像模型,以及为托管的第三方视频模型注册的内置 - 视频生成提供商 -- `cloudflare-ai-gateway`、`huggingface`、`kimi`、`nvidia`、`qianfan`、 - `stepfun`、`synthetic`、`venice`、`vercel-ai-gateway` 和 `volcengine`: - 仅有插件自有目录 -- `qwen`:用于文本模型的插件自有目录,以及为其 - 多模态界面注册的共享媒体理解和视频生成提供商;Qwen 视频生成使用标准 DashScope 视频 - 端点以及内置 Wan 模型,例如 `wan2.6-t2v` 和 `wan2.7-r2v` -- `runway`:用于原生 - Runway 基于任务的模型(例如 `gen4.5`)的插件自有视频生成提供商注册 -- `minimax`:插件自有目录、为 Hailuo 视频模型注册的内置视频生成提供商、 - 为 `image-01` 注册的内置图像生成提供商、混合 Anthropic/OpenAI 重放策略 - 选择,以及用量身份验证/快照逻辑 -- `together`:插件自有目录,以及为 Wan 视频模型注册的内置视频生成提供商 -- `xiaomi`:插件自有目录,以及用量身份验证/快照逻辑 +- `anthropic`:Claude 4.6 前向兼容回退、凭证修复提示、使用量端点获取、缓存 TTL / 提供商家族元数据,以及带凭证感知的全局配置默认值 +- `amazon-bedrock`:由提供商自有的上下文溢出匹配,以及针对 Bedrock 特有节流 / 未就绪错误的回退原因分类,外加共享的 `anthropic-by-model` 重放家族,用于 Anthropic 流量上仅限 Claude 的重放策略保护 +- `anthropic-vertex`:针对 Anthropic 消息流量的仅限 Claude 的重放策略保护 +- `openrouter`:透传模型 ID、请求包装器、提供商能力提示、代理 Gemini 流量上的 Gemini thought-signature 清理、通过 `openrouter-thinking` 流家族进行代理推理注入、路由元数据转发,以及缓存 TTL 策略 +- `github-copilot`:新手引导 / 设备登录、前向兼容模型回退、Claude-thinking 转录提示、运行时令牌交换,以及使用量端点获取 +- `openai`:GPT-5.4 前向兼容回退、直接 OpenAI 传输标准化、支持 Codex 感知的缺失凭证提示、Spark 抑制、合成 OpenAI / Codex 目录条目、thinking / live-model 策略、使用量令牌别名标准化(`input` / `output` 和 `prompt` / `completion` 家族)、用于原生 OpenAI / Codex 包装器的共享 `openai-responses-defaults` 流家族、提供商家族元数据、为 `gpt-image-1` 内置的图像生成提供商注册,以及为 `sora-2` 内置的视频生成提供商注册 +- `google` 和 `google-gemini-cli`:Gemini 3.1 前向兼容回退、原生 Gemini 重放校验、bootstrap 重放清理、带标签的推理输出模式、现代模型匹配、为 Gemini image-preview 模型内置的图像生成提供商注册,以及为 Veo 模型内置的视频生成提供商注册;Gemini CLI OAuth 还拥有凭证配置令牌格式化、使用量令牌解析,以及用于使用量界面的配额端点获取 +- `moonshot`:共享传输、由插件自有的 thinking 负载标准化 +- `kilocode`:共享传输、由插件自有的请求头、推理负载标准化、代理 Gemini thought-signature 清理,以及缓存 TTL 策略 +- `zai`:GLM-5 前向兼容回退、`tool_stream` 默认值、缓存 TTL 策略、二元 thinking / live-model 策略,以及使用量凭证 + 配额获取;未知的 `glm-5*` ID 会基于内置的 `glm-4.7` 模板合成 +- `xai`:原生 Responses 传输标准化、针对 Grok 快速变体的 `/fast` 别名重写、默认 `tool_stream`、xAI 特有的工具 schema / 推理负载清理,以及为 `grok-imagine-video` 内置的视频生成提供商注册 +- `mistral`:由插件自有的能力元数据 +- `opencode` 和 `opencode-go`:由插件自有的能力元数据,外加代理 Gemini thought-signature 清理 +- `alibaba`:由插件自有的直接 Wan 模型引用视频生成目录,例如 `alibaba/wan2.6-t2v` +- `byteplus`:由插件自有的目录,外加为 Seedance 文本转视频 / 图像转视频模型内置的视频生成提供商注册 +- `fal`:为托管的第三方图像生成提供商内置的 FLUX 图像模型注册,外加为托管的第三方视频模型内置的视频生成提供商注册 +- `cloudflare-ai-gateway`、`huggingface`、`kimi`、`nvidia`、`qianfan`、`stepfun`、`synthetic`、`venice`、`vercel-ai-gateway` 和 `volcengine`:仅有由插件自有的目录 +- `qwen`:文本模型由插件自有的目录,外加其多模态界面的共享 media-understanding 和视频生成提供商注册;Qwen 视频生成使用标准 DashScope 视频端点以及内置的 Wan 模型,例如 `wan2.6-t2v` 和 `wan2.7-r2v` +- `runway`:为原生 Runway 基于任务的模型(例如 `gen4.5`)由插件自有的视频生成提供商注册 +- `minimax`:由插件自有的目录、为 Hailuo 视频模型内置的视频生成提供商注册、为 `image-01` 内置的图像生成提供商注册、混合的 Anthropic / OpenAI 重放策略选择,以及使用量凭证 / 快照逻辑 +- `together`:由插件自有的目录,外加为 Wan 视频模型内置的视频生成提供商注册 +- `xiaomi`:由插件自有的目录,外加使用量凭证 / 快照逻辑 -内置的 `openai` 插件现在同时拥有这两个提供商 id:`openai` 和 -`openai-codex`。 +内置的 `openai` 插件现在同时拥有这两个提供商 ID:`openai` 和 `openai-codex`。 -以上涵盖了仍然适合 OpenClaw 常规传输的提供商。一个提供商如果 -需要完全自定义的请求执行器,那就是另一个更深层的扩展 -接口。 +以上涵盖了仍适配 OpenClaw 正常传输方式的提供商。需要完全自定义请求执行器的提供商,则属于另一个更深层的扩展接口。 ## API 密钥轮换 -- 支持对选定提供商进行通用提供商轮换。 +- 支持为选定提供商进行通用提供商轮换。 - 通过以下方式配置多个密钥: - - `OPENCLAW_LIVE__KEY`(单个 live 覆盖,最高优先级) + - `OPENCLAW_LIVE__KEY`(单个 live 覆盖,优先级最高) - `_API_KEYS`(逗号或分号分隔列表) - `_API_KEY`(主密钥) - `_API_KEY_*`(编号列表,例如 `_API_KEY_1`) -- 对于 Google 提供商,还会将 `GOOGLE_API_KEY` 作为回退包含在内。 -- 密钥选择顺序会保留优先级并去重。 -- 仅在速率限制响应时才会使用下一个密钥重试请求(例如 - `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many -concurrent requests`、`ThrottlingException`、`concurrency limit reached`、 - `workers_ai ... quota limit exceeded`,或周期性的用量上限消息)。 +- 对于 Google 提供商,还会将 `GOOGLE_API_KEY` 作为回退项包含在内。 +- 密钥选择顺序会保留优先级并对值去重。 +- 只有在速率限制响应时才会使用下一个密钥重试请求(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、“Too many concurrent requests”、`ThrottlingException`、“concurrency limit reached”、`workers_ai ... quota limit exceeded` 或周期性的使用量限制消息)。 - 非速率限制失败会立即失败;不会尝试密钥轮换。 - 当所有候选密钥都失败时,将返回最后一次尝试的最终错误。 ## 内置提供商(pi-ai 目录) -OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** -`models.providers` 配置;只需设置身份验证并选择一个模型。 +OpenClaw 附带 pi-ai 目录。这些提供商**不需要** `models.providers` 配置;只需设置凭证并选择一个模型。 ### OpenAI - 提供商:`openai` -- 身份验证:`OPENAI_API_KEY` +- 凭证:`OPENAI_API_KEY` - 可选轮换:`OPENAI_API_KEYS`、`OPENAI_API_KEY_1`、`OPENAI_API_KEY_2`,以及 `OPENCLAW_LIVE_OPENAI_KEY`(单个覆盖) - 示例模型:`openai/gpt-5.4`、`openai/gpt-5.4-pro` - CLI:`openclaw onboard --auth-choice openai-api-key` - 默认传输为 `auto`(WebSocket 优先,SSE 回退) - 可通过 `agents.defaults.models["openai/"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) -- OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup` 启用(`true`/`false`) -- 可通过 `agents.defaults.models["openai/"].params.serviceTier` 启用 OpenAI 优先级处理 -- `/fast` 和 `params.fastMode` 会将直接 `openai/*` Responses 请求映射到 `api.openai.com` 上的 `service_tier=priority` -- 当你想使用显式层级而不是共享的 `/fast` 开关时,请使用 `params.serviceTier` -- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、 - `User-Agent`)仅适用于发送到 `api.openai.com` 的原生 OpenAI 流量,不适用于 - 通用 OpenAI 兼容代理 -- 原生 OpenAI 路由也会保留 Responses `store`、提示缓存提示,以及 - OpenAI reasoning 兼容负载整形;代理路由则不会 -- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被刻意屏蔽,因为 live OpenAI API 会拒绝它;Spark 被视为仅限 Codex +- OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup`(`true` / `false`)启用 +- 可以通过 `agents.defaults.models["openai/"].params.serviceTier` 启用 OpenAI 优先级处理 +- `/fast` 和 `params.fastMode` 会将直接的 `openai/*` Responses 请求映射到 `api.openai.com` 上的 `service_tier=priority` +- 如果你想使用显式层级而不是共享的 `/fast` 开关,请使用 `params.serviceTier` +- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)仅应用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用的 OpenAI 兼容代理 +- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示以及 OpenAI 推理兼容负载整形;代理路由不会 +- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意抑制,因为 live OpenAI API 会拒绝它;Spark 被视为仅限 Codex ```json5 { @@ -269,13 +153,13 @@ OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** ### Anthropic - 提供商:`anthropic` -- 身份验证:`ANTHROPIC_API_KEY` +- 凭证:`ANTHROPIC_API_KEY` - 可选轮换:`ANTHROPIC_API_KEYS`、`ANTHROPIC_API_KEY_1`、`ANTHROPIC_API_KEY_2`,以及 `OPENCLAW_LIVE_ANTHROPIC_KEY`(单个覆盖) - 示例模型:`anthropic/claude-opus-4-6` - CLI:`openclaw onboard --auth-choice apiKey` -- 直接公共 Anthropic 请求支持共享的 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 身份验证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 与 `standard_only`) -- Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此 OpenClaw 将 Claude CLI 复用和 `claude -p` 用法视为该集成的许可方式,除非 Anthropic 发布新策略。 -- Anthropic setup-token 仍然可作为受支持的 OpenClaw 令牌路径使用,但 OpenClaw 现在会在可用时优先选择 Claude CLI 复用和 `claude -p`。 +- 直接的公共 Anthropic 请求支持共享的 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 与 `standard_only`) +- Anthropic 说明:Anthropic 员工告诉我们,再次允许 OpenClaw 风格的 Claude CLI 用法,因此 OpenClaw 会将 Claude CLI 复用和 `claude -p` 用法视为此集成的受认可方式,除非 Anthropic 发布新策略。 +- Anthropic setup-token 仍可作为受支持的 OpenClaw 令牌路径使用,但 OpenClaw 现在在可用时更倾向于使用 Claude CLI 复用和 `claude -p`。 ```json5 { @@ -286,19 +170,17 @@ OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** ### OpenAI Code(Codex) - 提供商:`openai-codex` -- 身份验证:OAuth(ChatGPT) +- 凭证:OAuth(ChatGPT) - 示例模型:`openai-codex/gpt-5.4` - CLI:`openclaw onboard --auth-choice openai-codex` 或 `openclaw models auth login --provider openai-codex` - 默认传输为 `auto`(WebSocket 优先,SSE 回退) - 可通过 `agents.defaults.models["openai-codex/"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) -- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)上转发 -- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、 - `User-Agent`)仅会附加到发往 - `chatgpt.com/backend-api` 的原生 Codex 流量,不适用于通用 OpenAI 兼容代理 -- 共享与直接 `openai/*` 相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority` -- 当 Codex OAuth 目录暴露它时,`openai-codex/gpt-5.3-codex-spark` 仍然可用;取决于授权资格 -- `openai-codex/gpt-5.4` 保留原生 `contextWindow = 1050000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限 -- 策略说明:OpenAI Codex OAuth 被明确支持用于像 OpenClaw 这样的外部工具/工作流。 +- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)中转发 +- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)仅附加到发往 `chatgpt.com/backend-api` 的原生 Codex 流量,不适用于通用 OpenAI 兼容代理 +- 与直接 `openai/*` 共享相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority` +- 当 Codex OAuth 目录暴露 `openai-codex/gpt-5.3-codex-spark` 时,它仍然可用;取决于授权资格 +- `openai-codex/gpt-5.4` 保持原生 `contextWindow = 1050000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限 +- 策略说明:OpenAI Codex OAuth 明确支持用于像 OpenClaw 这样的外部工具 / 工作流。 ```json5 { @@ -320,13 +202,13 @@ OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** ### 其他订阅式托管选项 -- [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商接口,以及 Alibaba DashScope 与 Coding Plan 端点映射 +- [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商接口,以及 Alibaba DashScope 和 Coding Plan 端点映射 - [MiniMax](/zh-CN/providers/minimax):MiniMax Coding Plan OAuth 或 API 密钥访问 - [GLM Models](/zh-CN/providers/glm):Z.AI Coding Plan 或通用 API 端点 ### OpenCode -- 身份验证:`OPENCODE_API_KEY`(或 `OPENCODE_ZEN_API_KEY`) +- 凭证:`OPENCODE_API_KEY`(或 `OPENCODE_ZEN_API_KEY`) - Zen 运行时提供商:`opencode` - Go 运行时提供商:`opencode-go` - 示例模型:`opencode/claude-opus-4-6`、`opencode-go/kimi-k2.5` @@ -341,20 +223,18 @@ OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** ### Google Gemini(API 密钥) - 提供商:`google` -- 身份验证:`GEMINI_API_KEY` -- 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、`GOOGLE_API_KEY` 回退,以及 `OPENCLAW_LIVE_GEMINI_KEY`(单个覆盖) +- 凭证:`GEMINI_API_KEY` +- 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、`GOOGLE_API_KEY` 回退项,以及 `OPENCLAW_LIVE_GEMINI_KEY`(单个覆盖) - 示例模型:`google/gemini-3.1-pro-preview`、`google/gemini-3-flash-preview` - 兼容性:使用 `google/gemini-3.1-flash-preview` 的旧版 OpenClaw 配置会被标准化为 `google/gemini-3-flash-preview` - CLI:`openclaw onboard --auth-choice gemini-api-key` -- 直接 Gemini 运行还接受 `agents.defaults.models["google/"].params.cachedContent` - (或旧版 `cached_content`),以转发提供商原生的 - `cachedContents/...` 句柄;Gemini 缓存命中会显示为 OpenClaw `cacheRead` +- 直接 Gemini 运行还接受 `agents.defaults.models["google/"].params.cachedContent`(或旧版 `cached_content`),以转发提供商原生的 `cachedContents/...` 句柄;Gemini 缓存命中会显示为 OpenClaw `cacheRead` ### Google Vertex 和 Gemini CLI - 提供商:`google-vertex`、`google-gemini-cli` -- 身份验证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程 -- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告在使用第三方客户端后 Google 账号受到限制。若你选择继续,请查看 Google 条款并使用非关键账号。 +- 凭证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程 +- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告称,在使用第三方客户端后遭遇了 Google 账号限制。请先查看 Google 条款,如果你选择继续,请使用非关键账号。 - Gemini CLI OAuth 作为内置 `google` 插件的一部分提供。 - 先安装 Gemini CLI: - `brew install gemini-cli` @@ -362,67 +242,53 @@ OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** - 启用:`openclaw plugins enable google` - 登录:`openclaw models auth login --provider google-gemini-cli --set-default` - 默认模型:`google-gemini-cli/gemini-3-flash-preview` - - 注意:你**不需要**把 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将 - 令牌存储在 Gateway 网关主机上的身份验证配置文件中。 + - 注意:你**不需要**将 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将令牌存储在 Gateway 网关主机上的凭证配置中。 - 如果登录后请求失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`。 - - Gemini CLI JSON 回复会从 `response` 解析;用量会回退到 - `stats`,其中 `stats.cached` 会被标准化为 OpenClaw `cacheRead`。 + - Gemini CLI JSON 回复会从 `response` 解析;使用量会回退到 `stats`,其中 `stats.cached` 会被标准化为 OpenClaw `cacheRead`。 ### Z.AI(GLM) - 提供商:`zai` -- 身份验证:`ZAI_API_KEY` +- 凭证:`ZAI_API_KEY` - 示例模型:`zai/glm-5.1` - CLI:`openclaw onboard --auth-choice zai-api-key` - - 别名:`z.ai/*` 和 `z-ai/*` 会标准化为 `zai/*` - - `zai-api-key` 会自动检测匹配的 Z.AI 端点;`zai-coding-global`、`zai-coding-cn`、`zai-global` 和 `zai-cn` 会强制指定某个具体接口 + - 别名:`z.ai/*` 和 `z-ai/*` 会被标准化为 `zai/*` + - `zai-api-key` 会自动检测匹配的 Z.AI 端点;`zai-coding-global`、`zai-coding-cn`、`zai-global` 和 `zai-cn` 会强制使用特定接口 ### Vercel AI Gateway - 提供商:`vercel-ai-gateway` -- 身份验证:`AI_GATEWAY_API_KEY` +- 凭证:`AI_GATEWAY_API_KEY` - 示例模型:`vercel-ai-gateway/anthropic/claude-opus-4.6` - CLI:`openclaw onboard --auth-choice ai-gateway-api-key` ### Kilo Gateway - 提供商:`kilocode` -- 身份验证:`KILOCODE_API_KEY` +- 凭证:`KILOCODE_API_KEY` - 示例模型:`kilocode/kilo/auto` - CLI:`openclaw onboard --auth-choice kilocode-api-key` -- base URL:`https://api.kilo.ai/api/gateway/` -- 静态回退目录自带 `kilocode/kilo/auto`;live - `https://api.kilo.ai/api/gateway/models` 发现可以进一步扩展运行时 - 目录。 -- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway 拥有, - 并非在 OpenClaw 中硬编码。 +- 基础 URL:`https://api.kilo.ai/api/gateway/` +- 静态回退目录附带 `kilocode/kilo/auto`;live `https://api.kilo.ai/api/gateway/models` 发现机制可以进一步扩展运行时目录。 +- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway 拥有,不是在 OpenClaw 中硬编码的。 -有关设置详情,请参阅 [/providers/kilocode](/zh-CN/providers/kilocode)。 +有关设置详情,请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。 ### 其他内置提供商插件 - OpenRouter:`openrouter`(`OPENROUTER_API_KEY`) - 示例模型:`openrouter/auto` -- 只有当请求实际发往 - `openrouter.ai` 时,OpenClaw 才会应用 OpenRouter 文档中的应用归因请求头 -- OpenRouter 特有的 Anthropic `cache_control` 标记同样只会应用于 - 已验证的 OpenRouter 路由,而不是任意代理 URL -- OpenRouter 仍使用代理风格的 OpenAI 兼容路径,因此不会转发 - 原生 OpenAI 专属请求整形(`serviceTier`、Responses `store`、 - 提示缓存提示、OpenAI reasoning 兼容负载) -- 由 Gemini 支持的 OpenRouter 引用仅保留代理 Gemini thought-signature 清理; - 原生 Gemini 重放验证和 bootstrap 重写仍然关闭 +- 只有当请求实际发往 `openrouter.ai` 时,OpenClaw 才会应用 OpenRouter 文档中说明的应用归因请求头 +- OpenRouter 特有的 Anthropic `cache_control` 标记同样只会应用于已验证的 OpenRouter 路由,不适用于任意代理 URL +- OpenRouter 仍然走代理风格的 OpenAI 兼容路径,因此不会转发仅限原生 OpenAI 的请求整形(`serviceTier`、Responses `store`、提示缓存提示、OpenAI 推理兼容负载) +- 基于 Gemini 的 OpenRouter 引用只保留代理 Gemini thought-signature 清理;原生 Gemini 重放校验和 bootstrap 重写不会启用 - Kilo Gateway:`kilocode`(`KILOCODE_API_KEY`) - 示例模型:`kilocode/kilo/auto` -- 由 Gemini 支持的 Kilo 引用保留相同的代理 Gemini thought-signature - 清理路径;`kilocode/kilo/auto` 以及其他不支持代理 reasoning 的 - 提示会跳过代理 reasoning 注入 +- 基于 Gemini 的 Kilo 引用保留相同的代理 Gemini thought-signature 清理路径;`kilocode/kilo/auto` 以及其他不支持代理推理的提示会跳过代理推理注入 - MiniMax:`minimax`(API 密钥)和 `minimax-portal`(OAuth) -- 身份验证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` +- 凭证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` - 示例模型:`minimax/MiniMax-M2.7` 或 `minimax-portal/MiniMax-M2.7` -- MiniMax 新手引导/API 密钥设置会写入显式的 M2.7 模型定义,并带有 - `input: ["text", "image"]`;内置提供商目录会将聊天引用 - 保持为纯文本,直到该提供商配置被具体化 +- MiniMax 新手引导 / API 密钥设置会写入显式的 M2.7 模型定义,并带有 `input: ["text", "image"]`;在该提供商配置实体化之前,内置提供商目录会将聊天引用保持为仅文本 - Moonshot:`moonshot`(`MOONSHOT_API_KEY`) - 示例模型:`moonshot/kimi-k2.5` - Kimi Coding:`kimi`(`KIMI_API_KEY` 或 `KIMICODE_API_KEY`) @@ -448,42 +314,35 @@ OpenClaw 自带 pi‑ai 目录。这些提供商**不需要** - BytePlus(国际版):`byteplus`(`BYTEPLUS_API_KEY`) - 示例模型:`byteplus-plan/ark-code-latest` - xAI:`xai`(`XAI_API_KEY`) - - 原生内置 xAI 请求使用 xAI Responses 路径 - - `/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、 - `grok-4` 和 `grok-4-0709` 重写为它们的 `*-fast` 变体 - - `tool_stream` 默认开启;设置 - `agents.defaults.models["xai/"].params.tool_stream` 为 `false` 即可 - 关闭 + - 原生内置的 xAI 请求使用 xAI Responses 路径 + - `/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、`grok-4` 和 `grok-4-0709` 重写为它们的 `*-fast` 变体 + - `tool_stream` 默认开启;设置 `agents.defaults.models["xai/"].params.tool_stream` 为 `false` 可将其关闭 - Mistral:`mistral`(`MISTRAL_API_KEY`) - 示例模型:`mistral/mistral-large-latest` - CLI:`openclaw onboard --auth-choice mistral-api-key` - Groq:`groq`(`GROQ_API_KEY`) - Cerebras:`cerebras`(`CEREBRAS_API_KEY`) - - Cerebras 上的 GLM 模型使用 id `zai-glm-4.7` 和 `zai-glm-4.6`。 - - OpenAI 兼容 base URL:`https://api.cerebras.ai/v1`。 + - Cerebras 上的 GLM 模型使用 ID `zai-glm-4.7` 和 `zai-glm-4.6`。 + - OpenAI 兼容基础 URL:`https://api.cerebras.ai/v1`。 - GitHub Copilot:`github-copilot`(`COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN`) -- Hugging Face Inference 示例模型:`huggingface/deepseek-ai/DeepSeek-R1`;CLI:`openclaw onboard --auth-choice huggingface-api-key`。请参阅 [Hugging Face (Inference)](/zh-CN/providers/huggingface)。 +- Hugging Face Inference 示例模型:`huggingface/deepseek-ai/DeepSeek-R1`;CLI:`openclaw onboard --auth-choice huggingface-api-key`。请参见 [Hugging Face(Inference)](/zh-CN/providers/huggingface)。 -## 通过 `models.providers` 配置的提供商(自定义/base URL) +## 通过 `models.providers` 配置的提供商(自定义 / 基础 URL) -使用 `models.providers`(或 `models.json`)添加**自定义**提供商或 -OpenAI/Anthropic 兼容代理。 +使用 `models.providers`(或 `models.json`)来添加**自定义**提供商或 OpenAI / Anthropic 兼容代理。 -下面许多内置提供商插件已经发布了默认目录。 -只有当你想覆盖默认 base URL、请求头或模型列表时,才使用显式的 -`models.providers.` 条目。 +下面许多内置提供商插件已经发布了默认目录。只有当你想覆盖默认基础 URL、请求头或模型列表时,才使用显式的 `models.providers.` 条目。 ### Moonshot AI(Kimi) -Moonshot 作为内置提供商插件提供。默认情况下使用内置提供商, -只有在你需要覆盖 base URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目: +Moonshot 作为内置提供商插件提供。默认请使用内置提供商,只有在你需要覆盖基础 URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目: - 提供商:`moonshot` -- 身份验证:`MOONSHOT_API_KEY` +- 凭证:`MOONSHOT_API_KEY` - 示例模型:`moonshot/kimi-k2.5` - CLI:`openclaw onboard --auth-choice moonshot-api-key` 或 `openclaw onboard --auth-choice moonshot-api-key-cn` -Kimi K2 模型 id: +Kimi K2 模型 ID: [//]: # "moonshot-kimi-k2-model-refs:start" @@ -518,7 +377,7 @@ Kimi K2 模型 id: Kimi Coding 使用 Moonshot AI 的 Anthropic 兼容端点: - 提供商:`kimi` -- 身份验证:`KIMI_API_KEY` +- 凭证:`KIMI_API_KEY` - 示例模型:`kimi/kimi-code` ```json5 @@ -530,14 +389,14 @@ Kimi Coding 使用 Moonshot AI 的 Anthropic 兼容端点: } ``` -旧版 `kimi/k2p5` 仍然作为兼容模型 id 被接受。 +旧版 `kimi/k2p5` 仍然作为兼容模型 ID 被接受。 ### Volcano Engine(Doubao) -Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型访问。 +Volcano Engine(火山引擎)在中国提供对 Doubao 和其他模型的访问。 -- 提供商:`volcengine`(编码:`volcengine-plan`) -- 身份验证:`VOLCANO_ENGINE_API_KEY` +- 提供商:`volcengine`(编程版:`volcengine-plan`) +- 凭证:`VOLCANO_ENGINE_API_KEY` - 示例模型:`volcengine-plan/ark-code-latest` - CLI:`openclaw onboard --auth-choice volcengine-api-key` @@ -549,13 +408,9 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型访 } ``` -新手引导默认使用编码接口,但通用的 `volcengine/*` -目录会同时注册。 +新手引导默认使用编程接口,但通用的 `volcengine/*` 目录也会同时注册。 -在新手引导/配置模型选择器中,Volcengine 身份验证选项会优先同时显示 -`volcengine/*` 和 `volcengine-plan/*` 条目。如果这些模型尚未加载, -OpenClaw 会回退到未过滤目录,而不是显示一个空的 -提供商作用域选择器。 +在新手引导 / 配置模型选择器中,Volcengine 凭证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商范围筛选的选择器。 可用模型: @@ -565,7 +420,7 @@ OpenClaw 会回退到未过滤目录,而不是显示一个空的 - `volcengine/glm-4-7-251222`(GLM 4.7) - `volcengine/deepseek-v3-2-251201`(DeepSeek V3.2 128K) -编码模型(`volcengine-plan`): +编程模型(`volcengine-plan`): - `volcengine-plan/ark-code-latest` - `volcengine-plan/doubao-seed-code` @@ -577,8 +432,8 @@ OpenClaw 会回退到未过滤目录,而不是显示一个空的 BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。 -- 提供商:`byteplus`(编码:`byteplus-plan`) -- 身份验证:`BYTEPLUS_API_KEY` +- 提供商:`byteplus`(编程版:`byteplus-plan`) +- 凭证:`BYTEPLUS_API_KEY` - 示例模型:`byteplus-plan/ark-code-latest` - CLI:`openclaw onboard --auth-choice byteplus-api-key` @@ -590,13 +445,9 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。 } ``` -新手引导默认使用编码接口,但通用的 `byteplus/*` -目录会同时注册。 +新手引导默认使用编程接口,但通用的 `byteplus/*` 目录也会同时注册。 -在新手引导/配置模型选择器中,BytePlus 身份验证选项会优先同时显示 -`byteplus/*` 和 `byteplus-plan/*` 条目。如果这些模型尚未加载, -OpenClaw 会回退到未过滤目录,而不是显示一个空的 -提供商作用域选择器。 +在新手引导 / 配置模型选择器中,BytePlus(国际版)凭证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商范围筛选的选择器。 可用模型: @@ -604,7 +455,7 @@ OpenClaw 会回退到未过滤目录,而不是显示一个空的 - `byteplus/kimi-k2-5-260127`(Kimi K2.5) - `byteplus/glm-4-7-251222`(GLM 4.7) -编码模型(`byteplus-plan`): +编程模型(`byteplus-plan`): - `byteplus-plan/ark-code-latest` - `byteplus-plan/doubao-seed-code` @@ -617,7 +468,7 @@ OpenClaw 会回退到未过滤目录,而不是显示一个空的 Synthetic 通过 `synthetic` 提供商提供 Anthropic 兼容模型: - 提供商:`synthetic` -- 身份验证:`SYNTHETIC_API_KEY` +- 凭证:`SYNTHETIC_API_KEY` - 示例模型:`synthetic/hf:MiniMaxAI/MiniMax-M2.5` - CLI:`openclaw onboard --auth-choice synthetic-api-key` @@ -644,32 +495,29 @@ Synthetic 通过 `synthetic` 提供商提供 Anthropic 兼容模型: MiniMax 通过 `models.providers` 配置,因为它使用自定义端点: -- MiniMax OAuth(全球):`--auth-choice minimax-global-oauth` -- MiniMax OAuth(中国):`--auth-choice minimax-cn-oauth` -- MiniMax API 密钥(全球):`--auth-choice minimax-global-api` -- MiniMax API 密钥(中国):`--auth-choice minimax-cn-api` -- 身份验证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 - `MINIMAX_API_KEY` +- MiniMax OAuth(Global):`--auth-choice minimax-global-oauth` +- MiniMax OAuth(CN):`--auth-choice minimax-cn-oauth` +- MiniMax API 密钥(Global):`--auth-choice minimax-global-api` +- MiniMax API 密钥(CN):`--auth-choice minimax-cn-api` +- 凭证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` -有关设置详情、模型选项和配置片段,请参阅 [/providers/minimax](/zh-CN/providers/minimax)。 +有关设置详情、模型选项和配置片段,请参见 [/providers/minimax](/zh-CN/providers/minimax)。 -在 MiniMax 的 Anthropic 兼容流式路径上,OpenClaw 默认关闭 thinking, -除非你显式设置它,并且 `/fast on` 会将 -`MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 +在 MiniMax 的 Anthropic 兼容流式路径上,OpenClaw 默认禁用 thinking,除非你明确设置它;并且 `/fast on` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 -插件自有能力拆分: +插件自有能力划分: -- 文本/聊天默认保持在 `minimax/MiniMax-M2.7` -- 图像生成是 `minimax/image-01` 或 `minimax-portal/image-01` -- 图像理解在两个 MiniMax 身份验证路径上都使用插件自有的 `MiniMax-VL-01` -- Web 搜索仍保留在提供商 id `minimax` 上 +- 文本 / 聊天默认保持在 `minimax/MiniMax-M2.7` +- 图像生成使用 `minimax/image-01` 或 `minimax-portal/image-01` +- 图像理解在两条 MiniMax 凭证路径上都使用由插件自有的 `MiniMax-VL-01` +- Web 搜索保持使用提供商 ID `minimax` ### Ollama Ollama 作为内置提供商插件提供,并使用 Ollama 的原生 API: - 提供商:`ollama` -- 身份验证:不需要(本地服务器) +- 凭证:无需(本地服务器) - 示例模型:`ollama/llama3.3` - 安装:[https://ollama.com/download](https://ollama.com/download) @@ -686,27 +534,23 @@ ollama pull llama3.3 } ``` -当你通过 -`OLLAMA_API_KEY` 选择启用时,系统会在本地 `http://127.0.0.1:11434` 检测 Ollama,并且内置提供商插件会将 Ollama 直接添加到 -`openclaw onboard` 和模型选择器中。请参阅 [/providers/ollama](/zh-CN/providers/ollama) -了解新手引导、云端/本地模式以及自定义配置。 +当你通过 `OLLAMA_API_KEY` 选择启用时,系统会在本地 `http://127.0.0.1:11434` 检测 Ollama,并且内置提供商插件会将 Ollama 直接添加到 `openclaw onboard` 和模型选择器中。有关新手引导、云端 / 本地模式和自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。 ### vLLM -vLLM 作为内置提供商插件提供,用于本地/自托管的 OpenAI 兼容 -服务器: +vLLM 作为内置提供商插件提供,用于本地 / 自托管的 OpenAI 兼容服务器: - 提供商:`vllm` -- 身份验证:可选(取决于你的服务器) -- 默认 base URL:`http://127.0.0.1:8000/v1` +- 凭证:可选(取决于你的服务器) +- 默认基础 URL:`http://127.0.0.1:8000/v1` -要在本地选择启用自动发现(如果你的服务器不强制身份验证,任意值都可以): +要在本地选择启用自动发现(如果你的服务器不强制要求凭证,任意值都可以): ```bash export VLLM_API_KEY="vllm-local" ``` -然后设置一个模型(替换为 `/v1/models` 返回的某个 id): +然后设置一个模型(替换为 `/v1/models` 返回的某个 ID): ```json5 { @@ -716,25 +560,23 @@ export VLLM_API_KEY="vllm-local" } ``` -详情请参阅 [/providers/vllm](/zh-CN/providers/vllm)。 +详情请参见 [/providers/vllm](/zh-CN/providers/vllm)。 ### SGLang -SGLang 作为内置提供商插件提供,用于快速的自托管 -OpenAI 兼容服务器: +SGLang 作为内置提供商插件提供,用于快速的自托管 OpenAI 兼容服务器: - 提供商:`sglang` -- 身份验证:可选(取决于你的服务器) -- 默认 base URL:`http://127.0.0.1:30000/v1` +- 凭证:可选(取决于你的服务器) +- 默认基础 URL:`http://127.0.0.1:30000/v1` -要在本地选择启用自动发现(如果你的服务器不 -强制身份验证,任意值都可以): +要在本地选择启用自动发现(如果你的服务器不强制要求凭证,任意值都可以): ```bash export SGLANG_API_KEY="sglang-local" ``` -然后设置一个模型(替换为 `/v1/models` 返回的某个 id): +然后设置一个模型(替换为 `/v1/models` 返回的某个 ID): ```json5 { @@ -744,7 +586,7 @@ export SGLANG_API_KEY="sglang-local" } ``` -详情请参阅 [/providers/sglang](/zh-CN/providers/sglang)。 +详情请参见 [/providers/sglang](/zh-CN/providers/sglang)。 ### 本地代理(LM Studio、vLLM、LiteLLM 等) @@ -755,7 +597,7 @@ export SGLANG_API_KEY="sglang-local" agents: { defaults: { model: { primary: "lmstudio/my-local-model" }, - models: { "lmstudio/my-local-model": { alias: "本地" } }, + models: { "lmstudio/my-local-model": { alias: "Local" } }, }, }, models: { @@ -767,7 +609,7 @@ export SGLANG_API_KEY="sglang-local" models: [ { id: "my-local-model", - name: "本地模型", + name: "Local Model", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, @@ -784,19 +626,17 @@ export SGLANG_API_KEY="sglang-local" 说明: - 对于自定义提供商,`reasoning`、`input`、`cost`、`contextWindow` 和 `maxTokens` 都是可选的。 - 省略时,OpenClaw 默认值为: + 如果省略,OpenClaw 默认使用: - `reasoning: false` - `input: ["text"]` - `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }` - `contextWindow: 200000` - `maxTokens: 8192` -- 建议:设置与你的代理/模型限制相匹配的显式值。 -- 对于非原生端点上的 `api: "openai-completions"`(任何 host 不是 `api.openai.com` 的非空 `baseUrl`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。 -- 代理风格的 OpenAI 兼容路由也会跳过原生 OpenAI 专属请求 - 整形:没有 `service_tier`、没有 Responses `store`、没有提示缓存提示,也没有 - OpenAI reasoning 兼容负载整形。 -- 如果 `baseUrl` 为空/省略,OpenClaw 会保留默认 OpenAI 行为(会解析到 `api.openai.com`)。 -- 出于安全考虑,在非原生 `openai-completions` 端点上,显式的 `compat.supportsDeveloperRole: true` 仍然会被覆盖。 +- 建议:设置与你的代理 / 模型限制匹配的显式值。 +- 对于非原生端点上的 `api: "openai-completions"`(任何 host 不是 `api.openai.com` 的非空 `baseUrl`),OpenClaw 会强制设置 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。 +- 代理风格的 OpenAI 兼容路由也会跳过仅限原生 OpenAI 的请求整形:没有 `service_tier`,没有 Responses `store`,没有提示缓存提示,没有 OpenAI 推理兼容负载整形,也没有隐藏的 OpenClaw 归因请求头。 +- 如果 `baseUrl` 为空 / 被省略,OpenClaw 会保留默认的 OpenAI 行为(即解析到 `api.openai.com`)。 +- 出于安全考虑,即使显式设置了 `compat.supportsDeveloperRole: true`,在非原生 `openai-completions` 端点上仍会被覆盖。 ## CLI 示例 @@ -806,11 +646,11 @@ openclaw models set opencode/claude-opus-4-6 openclaw models list ``` -另请参阅:[/gateway/configuration](/zh-CN/gateway/configuration) 获取完整配置示例。 +另请参见:[/gateway/configuration](/zh-CN/gateway/configuration),获取完整配置示例。 ## 相关内容 -- [Models](/zh-CN/concepts/models) —— 模型配置和别名 -- [Model Failover](/zh-CN/concepts/model-failover) —— 回退链和重试行为 -- [Configuration Reference](/zh-CN/gateway/configuration-reference#agent-defaults) —— 模型配置键 -- [Providers](/zh-CN/providers) —— 各提供商设置指南 +- [Models](/zh-CN/concepts/models) — 模型配置和别名 +- [Model Failover](/zh-CN/concepts/model-failover) — 回退链和重试行为 +- [Configuration Reference](/zh-CN/gateway/configuration-reference#agent-defaults) — 模型配置键 +- [Providers](/zh-CN/providers) — 按提供商分类的设置指南 diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 611ec5f72..bc951e8a5 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -3,41 +3,41 @@ read_when: - 在本地或 CI 中运行测试 - 为模型 / 提供商缺陷添加回归测试 - 调试 Gateway 网关 + 智能体行为 -summary: 测试工具包:单元 / e2e / 实时测试套件、Docker 运行器,以及每项测试覆盖的内容 +summary: 测试工具包:单元 / e2e / 实时测试套件、Docker 运行器,以及每项测试所覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-04-10T13:50:00Z" + generated_at: "2026-04-10T20:23:46Z" model: gpt-5.4 provider: openai - source_hash: 40f29e8db015921a0b6a928517b28440d49b5fb63701e68cb66a1297063012ab + source_hash: e24030b221699c7695ab5c87409a2646b7c5d014780a3482410c3375be8e3bd8 source_path: help/testing.md workflow: 15 --- # 测试 -OpenClaw 有三套 Vitest 测试套件(单元 / 集成、e2e、实时测试)以及一小组 Docker 运行器。 +OpenClaw 有三套 Vitest 测试套件(单元 / 集成、e2e、实时)以及一小组 Docker 运行器。 -这份文档是“我们如何测试”的指南: +本文档是一份“我们如何测试”的指南: -- 每个测试套件覆盖什么内容(以及它**刻意不**覆盖什么) +- 每个测试套件覆盖什么(以及它刻意 _不_ 覆盖什么) - 常见工作流应运行哪些命令(本地、推送前、调试) -- 实时测试如何发现凭证,以及如何选择模型 / 提供商 +- 实时测试如何发现凭证并选择模型 / 提供商 - 如何为真实世界中的模型 / 提供商问题添加回归测试 ## 快速开始 大多数时候: -- 完整门禁(预期应在推送前运行):`pnpm build && pnpm check && pnpm test` -- 在配置充裕的机器上更快地运行本地完整测试套件:`pnpm test:max` -- 直接使用 Vitest 监听循环:`pnpm test:watch` -- 现在直接指定文件也会路由到扩展 / 渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- 当你在迭代单个失败用例时,优先运行有针对性的测试。 +- 完整门禁(推送前的预期要求):`pnpm build && pnpm check && pnpm test` +- 在配置充足的机器上更快地运行本地全量测试:`pnpm test:max` +- 直接进入 Vitest 监听循环:`pnpm test:watch` +- 直接按文件定位现在也会路由扩展 / 渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 当你在迭代处理单个失败用例时,优先先运行定向测试。 - 基于 Docker 的 QA 站点:`pnpm qa:lab:up` - 基于 Linux VM 的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -当你修改了测试或想要更高置信度时: +当你修改了测试,或想获得更多信心时: - 覆盖率门禁:`pnpm test:coverage` - E2E 测试套件:`pnpm test:e2e` @@ -47,35 +47,36 @@ OpenClaw 有三套 Vitest 测试套件(单元 / 集成、e2e、实时测试) - 实时测试套件(模型 + Gateway 网关工具 / 图像探测):`pnpm test:live` - 安静地只运行一个实时测试文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -提示:如果你只需要一个失败用例,优先通过下面描述的 allowlist 环境变量来缩小实时测试范围。 +提示:当你只需要一个失败用例时,优先使用下面描述的 allowlist 环境变量来缩小实时测试范围。 ## QA 专用运行器 -当你需要接近 qa-lab 的真实环境时,这些命令与主测试套件并列使用: +当你需要 QA-lab 级别的真实环境时,这些命令与主测试套件并列使用: - `pnpm openclaw qa suite` - - 直接在主机上运行基于仓库的 QA 场景。 - - 默认会并行运行多个选定场景,并使用隔离的 Gateway 网关 worker,最多 64 个 worker,或以所选场景数量为上限。使用 `--concurrency ` 调整 worker 数量,或用 `--concurrency 1` 使用旧的串行通道。 + - 直接在宿主机上运行基于仓库的 QA 场景。 + - 默认会使用隔离的 Gateway 网关工作进程并行运行多个所选场景,最多 64 个工作进程或所选场景数。使用 `--concurrency ` 调整工作进程数量,或使用 `--concurrency 1` 回到旧的串行通道。 - `pnpm openclaw qa suite --runner multipass` - - 在一次性的 Multipass Linux VM 中运行相同的 QA 测试套件。 - - 保留与主机上 `qa suite` 相同的场景选择行为。 - - 复用与 `qa suite` 相同的提供商 / 模型选择参数。 - - 实时运行会转发适合来宾环境的受支持 QA 凭证输入: + - 在一次性的 Multipass Linux VM 中运行同一套 QA 测试。 + - 保持与宿主机上 `qa suite` 相同的场景选择行为。 + - 复用与 `qa suite` 相同的提供商 / 模型选择标志。 + - 实时运行会转发对来宾环境实际可用的受支持 QA 认证输入: 基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。 - - 输出目录必须位于仓库根目录下,这样来宾才能通过挂载的工作区回写结果。 - - 会将常规 QA 报告 + 摘要以及 Multipass 日志写入 `.artifacts/qa-e2e/...`。 + - 输出目录必须保持在仓库根目录下,以便来宾可通过挂载的工作区回写。 + - 会将常规 QA 报告 + 摘要以及 Multipass 日志写入 + `.artifacts/qa-e2e/...`。 - `pnpm qa:lab:up` - - 启动基于 Docker 的 QA 站点,供偏操作员风格的 QA 工作使用。 + - 启动基于 Docker 的 QA 站点,供运维式 QA 工作使用。 -## 测试套件(每套在哪运行) +## 测试套件(各自在哪里运行) -可以把这些测试套件理解为“真实度逐步提高”(同时波动性 / 成本也逐步提高): +可以把这些套件理解为“真实度逐步提高”(同时不稳定性 / 成本也逐步增加): ### 单元 / 集成(默认) - 命令:`pnpm test` -- 配置:对现有分域 Vitest project 进行十个顺序分片运行(`vitest.full-*.config.ts`) -- 文件:`vitest.unit.config.ts` 覆盖的 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的核心 / 单元测试清单,以及列入白名单的 `ui` Node 测试 +- 配置:通过现有分域 Vitest 项目运行十个顺序分片(`vitest.full-*.config.ts`) +- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的核心 / 单元测试清单,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试 - 范围: - 纯单元测试 - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) @@ -84,42 +85,42 @@ OpenClaw 有三套 Vitest 测试套件(单元 / 集成、e2e、实时测试) - 在 CI 中运行 - 不需要真实密钥 - 应该快速且稳定 -- Projects 说明: - - 未指定目标的 `pnpm test` 现在会运行 11 个更小的分片配置(`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生 root-project 进程。这样可以降低高负载机器上的峰值 RSS,并避免 auto-reply / 扩展相关工作拖慢无关测试套件。 - - `pnpm test --watch` 仍然使用原生根级 `vitest.config.ts` project graph,因为多分片的 watch 循环并不现实。 - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 现在会优先把显式文件 / 目录目标路由到对应的分域通道,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必支付完整 root project 启动成本。 - - 当 diff 只涉及可路由的源文件 / 测试文件时,`pnpm test:changed` 会把变更过的 git 路径展开到相同的分域通道;配置 / setup 编辑仍会回退到更广泛的 root-project 重跑。 - - 部分 `plugin-sdk` 和 `commands` 测试也会通过专用的轻量通道运行,以跳过 `test/setup-openclaw-runtime.ts`;有状态 / 运行时开销较大的文件仍保留在现有通道中。 - - 部分 `plugin-sdk` 和 `commands` 辅助源文件在 changed 模式下也会映射到这些轻量通道中的显式同级测试,因此修改 helper 时无需重跑该目录下的整套重型测试。 - - `auto-reply` 现在有三个专用分桶:顶层核心 helper、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。这使最重的 reply harness 工作不会影响轻量的状态 / chunk / token 测试。 +- 项目说明: + - 无目标的 `pnpm test` 现在会运行 11 个更小的分片配置(`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个庞大的原生根项目进程。这样可以降低高负载机器上的 RSS 峰值,并避免 auto-reply / 扩展相关工作挤占无关套件资源。 + - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片监听循环并不现实。 + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 现在会优先将显式文件 / 目录目标路由到分域通道,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不需要承担整个根项目启动的成本。 + - 当 diff 只涉及可路由的源码 / 测试文件时,`pnpm test:changed` 会将变更过的 git 路径扩展到相同的分域通道;配置 / setup 改动仍会回退到更广泛的根项目重跑。 + - 一些选定的 `plugin-sdk` 和 `commands` 测试也会通过专用轻量通道运行,从而跳过 `test/setup-openclaw-runtime.ts`;有状态 / 运行时较重的文件仍保留在现有通道上。 + - 一些选定的 `plugin-sdk` 和 `commands` 辅助源码文件也会把 changed 模式运行映射到这些轻量通道中的显式同级测试,因此辅助文件改动不必为该目录重跑完整的重型套件。 + - `auto-reply` 现在有三个专用桶:顶层核心辅助函数、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。这样能让最重的 reply harness 工作不再压到廉价的 status / chunk / token 测试上。 - 嵌入式运行器说明: - 当你修改消息工具发现输入或压缩运行时上下文时, - 要同时保留两个层级的覆盖。 - - 为纯路由 / 归一化边界添加聚焦的 helper 回归测试。 - - 还要保持嵌入式运行器集成测试套件健康: + 要同时保持两个层级的覆盖。 + - 为纯路由 / 规范化边界添加聚焦的辅助函数回归测试。 + - 同时也要保持嵌入式运行器集成测试套件健康: `src/agents/pi-embedded-runner/compact.hooks.test.ts`、 `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts`,以及 `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。 - - 这些测试套件验证带作用域的 id 和压缩行为仍然会通过真实的 `run.ts` / `compact.ts` 路径流动;仅有 helper 级测试并不能充分替代这些集成路径。 -- 线程池说明: + - 这些套件会验证分域 id 和压缩行为仍会通过真实的 `run.ts` / `compact.ts` 路径流动;仅有辅助函数测试不足以替代这些集成路径。 +- 进程池说明: - 基础 Vitest 配置现在默认使用 `threads`。 - - 共享 Vitest 配置还固定设置了 `isolate: false`,并在根级 projects、e2e 和实时测试配置中使用非隔离运行器。 - - 根级 UI 通道仍保留其 `jsdom` setup 和 optimizer,但现在也运行在共享的非隔离运行器上。 - - 每个 `pnpm test` 分片都继承共享 Vitest 配置中的相同 `threads` + `isolate: false` 默认值。 - - 共享的 `scripts/run-vitest.mjs` 启动器现在还会默认给 Vitest 子 Node 进程加上 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要对比原始 V8 行为,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 + - 共享 Vitest 配置还固定了 `isolate: false`,并在根项目、e2e 和实时配置中使用非隔离运行器。 + - 根 UI 通道保留了它的 `jsdom` 设置和优化器,但现在也运行在共享的非隔离运行器上。 + - 每个 `pnpm test` 分片都继承共享 Vitest 配置中相同的 `threads` + `isolate: false` 默认值。 + - 共享的 `scripts/run-vitest.mjs` 启动器现在还会默认为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间 V8 编译抖动。如果你需要与原生 V8 行为比较,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 - 本地快速迭代说明: - - 当变更路径可以清晰映射到更小的测试套件时,`pnpm test:changed` 会通过分域通道进行路由。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是使用更高的 worker 上限。 - - 本地 worker 自动扩缩容现在有意更加保守,并且当主机负载平均值已经很高时也会自动回退,因此默认情况下多个并发 Vitest 运行对系统的影响更小。 - - 基础 Vitest 配置会把 projects / config 文件标记为 `forceRerunTriggers`,以确保测试接线变化时 changed 模式的重跑仍然正确。 - - 配置会在受支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望为直接性能分析指定一个明确的缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - 当变更路径能清晰映射到更小的套件时,`pnpm test:changed` 会通过分域通道运行。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是使用更高的工作进程上限。 + - 本地工作进程自动缩放现在刻意更保守,并且在宿主机平均负载已较高时也会回退,因此默认情况下多个并发 Vitest 运行的破坏性更小。 + - 基础 Vitest 配置将这些项目 / 配置文件标记为 `forceRerunTriggers`,从而在测试接线发生变化时保证 changed 模式重跑仍然正确。 + - 配置在受支持宿主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析指定一个明确缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - 性能调试说明: - - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入细分输出。 - - `pnpm test:perf:imports:changed` 会把同样的性能分析视图限制到自 `origin/main` 以来发生变化的文件。 -- `pnpm test:perf:changed:bench -- --ref ` 会把当前提交 diff 的已路由 `test:changed` 与原生 root-project 路径进行比较,并输出耗时以及 macOS 最大 RSS。 -- `pnpm test:perf:changed:bench -- --worktree` 会通过 `scripts/test-projects.mjs` 和根级 Vitest 配置,将当前未提交工作树中的变更文件列表进行路由,并对其进行基准测试。 - - `pnpm test:perf:profile:main` 会为 Vitest / Vite 启动与转换开销写出主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元测试套件写出 runner 的 CPU + 堆 profile。 + - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入明细输出。 + - `pnpm test:perf:imports:changed` 会将同样的性能分析视图限定到相对 `origin/main` 的变更文件。 +- `pnpm test:perf:changed:bench -- --ref ` 会把路由后的 `test:changed` 与该已提交 diff 的原生根项目路径做对比,并输出总耗时以及 macOS 最大 RSS。 +- `pnpm test:perf:changed:bench -- --worktree` 会通过将当前脏工作树中的变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置,对其进行基准测试。 + - `pnpm test:perf:profile:main` 会为 Vitest / Vite 启动和转换开销写出主线程 CPU profile。 + - `pnpm test:perf:profile:runner` 会在关闭文件并行的情况下,为单元测试套件写出运行器 CPU + 堆 profile。 ### E2E(Gateway 网关冒烟测试) @@ -127,153 +128,153 @@ OpenClaw 有三套 Vitest 测试套件(单元 / 集成、e2e、实时测试) - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts` - 运行时默认值: - - 使用 Vitest `threads` 和 `isolate: false`,与仓库其余部分保持一致。 - - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。 + - 使用 Vitest `threads` 和 `isolate: false`,与仓库其余部分一致。 + - 使用自适应工作进程(CI:最多 2 个,本地:默认 1 个)。 - 默认以静默模式运行,以减少控制台 I/O 开销。 -- 常用覆盖选项: - - `OPENCLAW_E2E_WORKERS=`:强制指定 worker 数量(上限 16)。 - - `OPENCLAW_E2E_VERBOSE=1`:重新启用详细控制台输出。 +- 常用覆盖项: + - `OPENCLAW_E2E_WORKERS=` 强制指定工作进程数(上限为 16)。 + - `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。 - 范围: - 多实例 Gateway 网关端到端行为 - - WebSocket / HTTP 接口、节点配对,以及更重型的网络行为 + - WebSocket / HTTP 接口、节点配对和更重的网络行为 - 预期: - 在 CI 中运行(当流水线启用时) - 不需要真实密钥 - - 比单元测试有更多活动部件(可能更慢) + - 比单元测试包含更多可变因素(可能更慢) ### E2E:OpenShell 后端冒烟测试 - 命令:`pnpm test:e2e:openshell` - 文件:`test/openshell-sandbox.e2e.test.ts` - 范围: - - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - - 从临时本地 Dockerfile 创建一个沙箱 + - 通过 Docker 在宿主机上启动一个隔离的 OpenShell Gateway 网关 + - 从一个临时本地 Dockerfile 创建沙箱 - 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端 - - 通过沙箱 fs bridge 验证远端规范文件系统行为 + - 通过沙箱文件系统桥验证远程规范文件系统行为 - 预期: - - 仅按需启用;不属于默认的 `pnpm test:e2e` 运行范围 - - 需要本地 `openshell` CLI 和可用的 Docker 守护进程 - - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,随后销毁测试 Gateway 网关和沙箱 -- 常用覆盖选项: - - `OPENCLAW_E2E_OPENSHELL=1`:在手动运行更广泛的 e2e 测试套件时启用该测试 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指向非默认 CLI 二进制文件或包装脚本 + - 仅限选择加入;不属于默认的 `pnpm test:e2e` 运行范围 + - 需要本地 `openshell` CLI 和可用的 Docker daemon + - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱 +- 常用覆盖项: + - `OPENCLAW_E2E_OPENSHELL=1` 在手动运行更广泛的 e2e 套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 指向非默认的 CLI 二进制文件或包装脚本 ### 实时测试(真实提供商 + 真实模型) - 命令:`pnpm test:live` - 配置:`vitest.live.config.ts` - 文件:`src/**/*.live.test.ts` -- 默认:由 `pnpm test:live` **启用**(会设置 `OPENCLAW_LIVE_TEST=1`) +- 默认:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商 / 模型**今天**在真实凭证下是否真的可用?” + - “这个提供商 / 模型在今天配合真实凭证是否真的能工作?” - 捕获提供商格式变化、工具调用怪癖、认证问题和速率限制行为 - 预期: - - 按设计并不适合作为稳定的 CI 测试(真实网络、真实提供商策略、配额、故障) + - 按设计不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障) - 会花钱 / 消耗速率限制 - - 更推荐运行缩小范围的子集,而不是“全部” -- 实时运行会读取 `~/.profile`,以获取缺失的 API key。 -- 默认情况下,实时运行仍会隔离 `HOME`,并将配置 / 认证材料复制到临时测试 home 中,这样单元测试 fixture 就不会修改你的真实 `~/.openclaw`。 + - 优先运行缩小范围后的子集,而不是“全部跑一遍” +- 实时运行会加载 `~/.profile` 以获取缺失的 API 密钥。 +- 默认情况下,实时运行仍会隔离 `HOME`,并将配置 / 认证材料复制到临时测试 home 中,这样单元测试夹具就不会修改你真实的 `~/.openclaw`。 - 仅当你明确需要让实时测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认使用更安静的模式:会保留 `[live] ...` 进度输出,但隐藏额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志 / Bonjour 杂讯。若想恢复完整启动日志,可设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API key 轮换(按提供商区分):设置 `*_API_KEYS`,使用逗号 / 分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可以通过 `OPENCLAW_LIVE_*_KEY` 做实时测试级覆盖;测试在遇到速率限制响应时会重试。 +- `pnpm test:live` 现在默认使用更安静的模式:保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志 / Bonjour 噪声。如果你想重新看到完整启动日志,可设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API 密钥轮换(按提供商):设置 `*_API_KEYS`,使用逗号 / 分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或者通过 `OPENCLAW_LIVE_*_KEY` 为实时测试单独覆盖;测试会在遇到速率限制响应时重试。 - 进度 / 心跳输出: - - 实时测试套件现在会把进度行输出到 stderr,因此即使 Vitest 控制台捕获处于安静模式,长时间的提供商调用也会显示为仍在活动中。 - - `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商 / Gateway 网关进度行会在实时测试运行期间立即流出。 - - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直连模型的心跳间隔。 - - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关 / 探测心跳间隔。 + - 实时套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获处于安静模式,长时间的提供商调用也能明显显示为活跃状态。 + - `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商 / Gateway 网关进度行会在实时运行期间立即流式输出。 + - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型心跳。 + - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关 / 探测心跳。 -## 我应该运行哪套测试? +## 我应该运行哪个测试套件? -使用这个决策表: +使用下面这个决策表: -- 编辑逻辑 / 测试:运行 `pnpm test`(如果你改动很多,再加上 `pnpm test:coverage`) -- 修改 Gateway 网关网络 / WS 协议 / 配对:加上 `pnpm test:e2e` -- 调试“我的机器人挂了” / 提供商特定故障 / 工具调用:运行缩小范围的 `pnpm test:live` +- 修改逻辑 / 测试:运行 `pnpm test`(如果改动很多,再运行 `pnpm test:coverage`) +- 触及 Gateway 网关网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e` +- 调试“我的机器人挂了” / 提供商特定故障 / 工具调用:运行缩小范围后的 `pnpm test:live` ## 实时测试:Android 节点能力扫描 - 测试:`src/gateway/android-node.capabilities.live.test.ts` - 脚本:`pnpm android:test:integration` -- 目标:调用已连接 Android 节点**当前声明的每一个命令**,并断言命令契约行为。 +- 目标:调用已连接 Android 节点当前公布的**每一条命令**,并断言命令契约行为。 - 范围: - - 基于前置条件 / 手动 setup(该测试套件不会安装 / 运行 / 配对应用)。 - - 对所选 Android 节点逐个命令执行 Gateway 网关 `node.invoke` 验证。 -- 必需的预先 setup: - - Android 应用已连接并已与 Gateway 网关配对。 + - 带前置条件的 / 手动设置(该测试套件不会安装 / 运行 / 配对应用)。 + - 针对所选 Android 节点逐条命令进行 Gateway 网关 `node.invoke` 校验。 +- 必需的预先设置: + - Android 应用已连接并与 Gateway 网关完成配对。 - 应用保持在前台。 - 已为你期望通过的能力授予权限 / 捕获同意。 -- 可选目标覆盖: +- 可选目标覆盖项: - `OPENCLAW_ANDROID_NODE_ID` 或 `OPENCLAW_ANDROID_NODE_NAME`。 - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`。 -- 完整 Android setup 详情:[Android App](/zh-CN/platforms/android) +- 完整 Android 设置详情:[Android App](/zh-CN/platforms/android) ## 实时测试:模型冒烟测试(profile 密钥) -实时测试分为两层,这样我们可以隔离故障: +实时测试分为两层,这样我们就能隔离故障: -- “直连模型”告诉我们,在给定密钥下,提供商 / 模型是否至少能响应。 -- “Gateway 网关冒烟测试”告诉我们,针对该模型,完整的 Gateway 网关 + 智能体流水线是否正常工作(会话、历史记录、工具、沙箱策略等)。 +- “直接模型”告诉我们,提供商 / 模型在给定密钥下是否至少能够响应。 +- “Gateway 网关冒烟测试”告诉我们,完整的 Gateway 网关 + 智能体流水线是否对该模型正常工作(会话、历史记录、工具、沙箱策略等)。 -### 第 1 层:直连模型补全(无 Gateway 网关) +### 第 1 层:直接模型补全(无 Gateway 网关) - 测试:`src/agents/models.profiles.live.test.ts` - 目标: - - 枚举已发现的模型 + - 枚举发现到的模型 - 使用 `getApiKeyForModel` 选择你拥有凭证的模型 - 为每个模型运行一次小型补全(并在需要时运行定向回归测试) - 启用方式: - - `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) -- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)来实际运行此测试套件;否则它会跳过,以便让 `pnpm test:live` 继续聚焦于 Gateway 网关冒烟测试 + - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) +- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)才会真正运行该测试套件;否则它会跳过,以便让 `pnpm test:live` 继续聚焦 Gateway 网关冒烟测试 - 如何选择模型: - `OPENCLAW_LIVE_MODELS=modern` 运行 modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - `OPENCLAW_LIVE_MODELS=all` 是 modern allowlist 的别名 - - 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔 allowlist) - - modern / all 扫描默认使用精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行穷尽式 modern 扫描,或设置为正数以使用更小的上限。 + - 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist) + - modern / all 扫描默认有一个精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行完整的 modern 扫描,或设置为正数以使用更小的上限。 - 如何选择提供商: - - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔 allowlist) + - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的 allowlist) - 密钥来源: - 默认:profile 存储和环境变量回退 - - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 以强制**仅使用 profile 存储** -- 存在原因: - - 用来区分“提供商 API 坏了 / 密钥无效”和“Gateway 网关智能体流水线坏了” - - 容纳小型、隔离的回归测试(例如:OpenAI Responses / Codex Responses 的推理重放 + 工具调用流程) + - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile 存储** +- 为什么需要它: + - 将“提供商 API 出故障 / 密钥无效”和“Gateway 网关智能体流水线出故障”分离开来 + - 容纳小型、隔离的回归测试(例如:OpenAI Responses / Codex Responses 推理重放 + 工具调用流程) -### 第 2 层:Gateway 网关 + dev 智能体冒烟测试(也就是 “@openclaw” 实际执行的内容) +### 第 2 层:Gateway 网关 + 开发智能体冒烟测试(也就是 “@openclaw” 实际做的事) - 测试:`src/gateway/gateway-models.profiles.live.test.ts` - 目标: - 启动一个进程内 Gateway 网关 - - 创建 / 修补一个 `agent:dev:*` 会话(每次运行时覆盖模型) + - 创建 / 修补一个 `agent:dev:*` 会话(每次运行覆盖模型) - 遍历带密钥的模型并断言: - - 有“有意义”的响应(不使用工具) - - 真实工具调用可用(read 探测) + - “有意义的”回复(不使用工具) + - 一次真实工具调用可正常工作(read 探测) - 可选的额外工具探测(exec+read 探测) - - OpenAI 回归路径(仅工具调用 → 后续跟进)继续正常工作 -- 探测细节(这样你可以快速解释失败原因): - - `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 该文件并把 nonce 回显出来。 - - `exec+read` 探测:测试会要求智能体通过 `exec` 将 nonce 写入一个临时文件,然后再 `read` 回来。 + - OpenAI 回归路径(仅工具调用 → 后续跟进)持续可用 +- 探测细节(这样你可以快速解释失败): + - `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 该文件并回显 nonce。 + - `exec+read` 探测:测试要求智能体通过 `exec` 将 nonce 写入一个临时文件,然后再 `read` 回来。 - 图像探测:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 - 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。 - 启用方式: - - `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) + - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) - 如何选择模型: - 默认:modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是 modern allowlist 的别名 - - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号分隔列表)以缩小范围 - - modern / all Gateway 网关扫描默认使用精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行穷尽式 modern 扫描,或设置为正数以使用更小的上限。 -- 如何选择提供商(避免“OpenRouter 全家桶”): - - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔 allowlist) -- 工具 + 图像探测在这个实时测试中始终开启: + - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)来缩小范围 + - modern / all Gateway 网关扫描默认有一个精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行完整的 modern 扫描,或设置为正数以使用更小的上限。 +- 如何选择提供商(避免“OpenRouter 全量”): + - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist) +- 工具 + 图像探测在该实时测试中始终开启: - `read` 探测 + `exec+read` 探测(工具压力测试) - 当模型声明支持图像输入时,会运行图像探测 - - 流程(高层级): - - 测试生成一个带有 “CAT” + 随机代码的小 PNG(`src/gateway/live-image-probe.ts`) + - 流程(高层): + - 测试生成一个带有 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`) - 通过 `agent` `attachments: [{ mimeType: "image/png", content: "" }]` 发送 - Gateway 网关将附件解析为 `images[]`(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - - 嵌入式智能体向模型转发一条多模态用户消息 + - 嵌入式智能体将多模态用户消息转发给模型 - 断言:回复包含 `cat` + 该代码(OCR 容错:允许轻微错误) -提示:如果你想查看你的机器上能测试什么(以及准确的 `provider/model` id),请运行: +提示:如果你想查看你机器上可测试的内容(以及精确的 `provider/model` id),运行: ```bash openclaw models list @@ -283,21 +284,21 @@ openclaw models list --json ## 实时测试:CLI 后端冒烟测试(Claude、Codex、Gemini 或其他本地 CLI) - 测试:`src/gateway/gateway-cli-backend.live.test.ts` -- 目标:在不触碰默认配置的情况下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。 -- 后端特定的冒烟测试默认值位于对应扩展的 `cli-backend.ts` 定义中。 +- 目标:在不触碰你的默认配置的前提下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。 +- 后端专属的冒烟测试默认值与所属扩展的 `cli-backend.ts` 定义一起维护。 - 启用: - - `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) + - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) - `OPENCLAW_LIVE_CLI_BACKEND=1` - 默认值: - 默认提供商 / 模型:`claude-cli/claude-sonnet-4-6` - - 命令 / 参数 / 图像行为来自对应 CLI 后端插件元数据。 + - 命令 / 参数 / 图像行为来自所属 CLI 后端插件元数据。 - 覆盖项(可选): - `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"` - `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"` - `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'` - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图像附件(路径会注入到提示词中)。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 通过 CLI 参数传递图像文件路径,而不是注入到提示词中。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`)用于控制在设置了 `IMAGE_ARG` 时如何传递图像参数。 + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图像附件(路径会注入到提示中)。 + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 通过 CLI 参数传递图像文件路径,而不是通过提示注入。 + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`)控制设置 `IMAGE_ARG` 时图像参数的传递方式。 - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` 发送第二轮消息并验证恢复流程。 - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` 禁用默认的 Claude Sonnet -> Opus 同会话连续性探测(当所选模型支持切换目标时,设置为 `1` 可强制启用)。 @@ -309,13 +310,13 @@ OPENCLAW_LIVE_CLI_BACKEND=1 \ pnpm test:live src/gateway/gateway-cli-backend.live.test.ts ``` -Docker 用法: +Docker 配方: ```bash pnpm test:docker:live-cli-backend ``` -单提供商 Docker 用法: +单提供商 Docker 配方: ```bash pnpm test:docker:live-cli-backend:claude @@ -327,19 +328,19 @@ pnpm test:docker:live-cli-backend:gemini 说明: - Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`。 -- 它会在仓库 Docker 镜像内,以非 root 的 `node` 用户身份运行实时 CLI 后端冒烟测试。 -- 它会从对应扩展解析 CLI 冒烟测试元数据,然后把匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到可缓存的可写前缀 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 中(默认:`~/.cache/openclaw/docker-cli-tools`)。 -- `pnpm test:docker:live-cli-backend:claude-subscription` 需要通过 `~/.claude/.credentials.json` 中的 `claudeAiOauth.subscriptionType`,或来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN`,提供可移植的 Claude Code 订阅 OAuth。它会先证明 Docker 中直接 `claude -p` 可用,然后在不保留 Anthropic API key 环境变量的情况下运行两轮 Gateway 网关 CLI 后端测试。这个订阅通道默认会禁用 Claude MCP / 工具和图像探测,因为 Claude 当前会将第三方应用使用路由到额外使用量计费,而不是普通订阅计划限额。 +- 它会在仓库 Docker 镜像中以非 root 的 `node` 用户身份运行实时 CLI 后端冒烟测试。 +- 它会从所属扩展解析 CLI 冒烟测试元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到一个可写的缓存前缀 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 中(默认:`~/.cache/openclaw/docker-cli-tools`)。 +- `pnpm test:docker:live-cli-backend:claude-subscription` 需要可移植的 Claude Code 订阅 OAuth,可通过带有 `claudeAiOauth.subscriptionType` 的 `~/.claude/.credentials.json`,或来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN` 提供。它会先在 Docker 中验证直接 `claude -p`,然后在不保留 Anthropic API 密钥环境变量的情况下运行两轮 Gateway 网关 CLI 后端测试。这个订阅通道默认会禁用 Claude MCP / 工具和图像探测,因为 Claude 当前会将第三方应用使用量路由到额外使用计费,而不是普通订阅套餐限制。 - 实时 CLI 后端冒烟测试现在会对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图像分类轮次,然后通过 Gateway 网关 CLI 验证 MCP `cron` 工具调用。 -- Claude 的默认冒烟测试还会把会话从 Sonnet 修补到 Opus,并验证恢复后的会话仍记得之前的备注。 +- Claude 的默认冒烟测试还会将会话从 Sonnet 修补为 Opus,并验证恢复后的会话仍记得之前的备注。 ## 实时测试:ACP 绑定冒烟测试(`/acp spawn ... --bind here`) - 测试:`src/gateway/gateway-acp-bind.live.test.ts` -- 目标:使用实时 ACP 智能体验证真实 ACP 会话绑定流程: +- 目标:使用一个实时 ACP 智能体验证真实的 ACP 会话绑定流程: - 发送 `/acp spawn --bind here` - - 原地绑定一个合成的消息渠道会话 - - 在同一个会话上发送一条普通后续消息 + - 就地绑定一个合成的消息渠道会话 + - 在同一会话上发送一条普通后续消息 - 验证后续消息落入已绑定的 ACP 会话转录中 - 启用: - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` @@ -347,7 +348,7 @@ pnpm test:docker:live-cli-backend:gemini - 默认值: - Docker 中的 ACP 智能体:`claude,codex,gemini` - 直接 `pnpm test:live ...` 使用的 ACP 智能体:`claude` - - 合成渠道:Slack 私信风格的会话上下文 + - 合成渠道:Slack 私信风格会话上下文 - ACP 后端:`acpx` - 覆盖项: - `OPENCLAW_LIVE_ACP_BIND_AGENT=claude` @@ -356,8 +357,8 @@ pnpm test:docker:live-cli-backend:gemini - `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini` - `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@'` - 说明: - - 这个通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成 originating-route 字段,因此测试可以附加消息渠道上下文,而无需伪装成外部投递。 - - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会为所选 ACP harness 智能体使用内置 `acpx` 插件的内建智能体注册表。 + - 该通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成来源路由字段,这样测试就能附加消息渠道上下文,而无需假装真的对外投递。 + - 当 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 未设置时,测试会使用内置 `acpx` 插件中针对所选 ACP harness 智能体的内建智能体注册表。 示例: @@ -367,13 +368,13 @@ OPENCLAW_LIVE_ACP_BIND=1 \ pnpm test:live src/gateway/gateway-acp-bind.live.test.ts ``` -Docker 用法: +Docker 配方: ```bash pnpm test:docker:live-acp-bind ``` -单智能体 Docker 用法: +单智能体 Docker 配方: ```bash pnpm test:docker:live-acp-bind:claude @@ -385,48 +386,93 @@ Docker 说明: - Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。 - 默认情况下,它会按顺序对所有受支持的实时 CLI 智能体运行 ACP 绑定冒烟测试:`claude`、`codex`,然后 `gemini`。 -- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可以缩小测试矩阵。 -- 它会读取 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写 npm 前缀,然后在缺失时安装请求的实时 CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。 -- 在 Docker 内,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,这样 acpx 就能让从已读取 profile 中获得的提供商环境变量继续对其子 harness CLI 可用。 +- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可缩小矩阵范围。 +- 它会加载 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写 npm 前缀中,然后在缺失时安装所请求的实时 CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。 +- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,这样 acpx 就能让从 profile 加载到的提供商环境变量继续对其子 harness CLI 可用。 -### 推荐的实时测试用法 +## 实时测试:Codex app-server harness 冒烟测试 -范围明确的窄 allowlist 速度最快,也最不容易波动: +- 目标:通过常规 Gateway 网关 + `agent` 方法验证插件自有的 Codex harness: + - 加载内置 `codex` 插件 + - 选择 `OPENCLAW_AGENT_RUNTIME=codex` + - 向 `codex/gpt-5.4` 发送第一轮 Gateway 网关智能体消息 + - 向同一个 OpenClaw 会话发送第二轮消息,并验证 app-server + 线程能够恢复 +- 测试:`src/gateway/gateway-codex-harness.live.test.ts` +- 启用:`OPENCLAW_LIVE_CODEX_HARNESS=1` +- 默认模型:`codex/gpt-5.4` +- 可选图像探测:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` +- 可选 MCP / 工具探测:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` +- 认证:来自 shell / profile 的 `OPENAI_API_KEY`,以及可选复制的 + `~/.codex/auth.json` 和 `~/.codex/config.toml` -- 单模型,直连(无 Gateway 网关): +本地配方: + +```bash +source ~/.profile +OPENCLAW_LIVE_CODEX_HARNESS=1 \ + OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1 \ + OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1 \ + OPENCLAW_LIVE_CODEX_HARNESS_MODEL=codex/gpt-5.4 \ + pnpm test:live -- src/gateway/gateway-codex-harness.live.test.ts +``` + +Docker 配方: + +```bash +source ~/.profile +pnpm test:docker:live-codex-harness +``` + +Docker 说明: + +- Docker 运行器位于 `scripts/test-live-codex-harness-docker.sh`。 +- 它会加载挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI + 认证文件,将 `@openai/codex` 安装到一个可写的挂载 npm + 前缀中,暂存源代码树,然后仅运行 Codex harness 实时测试。 +- Docker 默认启用图像和 MCP / 工具探测。若你需要更窄的调试运行,可设置 + `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` 或 + `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0`。 + +### 推荐的实时测试配方 + +范围收窄、显式的 allowlist 是最快且最不易出问题的: + +- 单个模型,直接测试(无 Gateway 网关): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` -- 单模型,Gateway 网关冒烟测试: +- 单个模型,Gateway 网关冒烟测试: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - 跨多个提供商的工具调用: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- Google 聚焦(Gemini API key + Antigravity): - - Gemini(API key):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` +- Google 聚焦(Gemini API 密钥 + Antigravity): + - Gemini(API 密钥):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Antigravity(OAuth):`OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` 说明: -- `google/...` 使用 Gemini API(API key)。 -- `google-antigravity/...` 使用 Antigravity OAuth bridge(类似 Cloud Code Assist 风格的智能体端点)。 +- `google/...` 使用 Gemini API(API 密钥)。 +- `google-antigravity/...` 使用 Antigravity OAuth bridge(Cloud Code Assist 风格的智能体端点)。 - `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具行为差异)。 - Gemini API 与 Gemini CLI: - - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API key / profile 认证);这通常就是大多数用户所说的 “Gemini”。 - - CLI:OpenClaw 会 shell out 到本地 `gemini` 二进制;它有自己的认证方式,而且行为可能不同(流式传输 / 工具支持 / 版本偏差)。 + - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API 密钥 / profile 认证);这是大多数用户提到 “Gemini” 时的含义。 + - CLI:OpenClaw 会调用本地 `gemini` 二进制文件;它有自己的认证方式,且行为可能不同(流式传输 / 工具支持 / 版本偏差)。 ## 实时测试:模型矩阵(我们覆盖什么) -没有固定的“CI 模型列表”(实时测试是按需启用的),但以下是**推荐**在有密钥的开发机上定期覆盖的模型。 +没有固定的“CI 模型列表”(实时测试是可选启用的),但如果你在开发机上有可用密钥,下面这些是**推荐**定期覆盖的模型。 -### 现代冒烟测试集合(工具调用 + 图像) +### 现代冒烟测试集(工具调用 + 图像) -这是我们预期应持续可用的“常见模型”运行集合: +这是我们期望持续可用的“常用模型”运行集: - OpenAI(非 Codex):`openai/gpt-5.4`(可选:`openai/gpt-5.4-mini`) - OpenAI Codex:`openai-codex/gpt-5.4` - Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`) -- Google(Gemini API):`google/gemini-3.1-pro-preview` 和 `google/gemini-3-flash-preview`(避免较旧的 Gemini 2.x 模型) +- Google(Gemini API):`google/gemini-3.1-pro-preview` 和 `google/gemini-3-flash-preview`(避免使用较旧的 Gemini 2.x 模型) - Google(Antigravity):`google-antigravity/claude-opus-4-6-thinking` 和 `google-antigravity/gemini-3-flash` - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` @@ -436,7 +482,7 @@ Docker 说明: ### 基线:工具调用(Read + 可选 Exec) -每个提供商家族至少选择一个: +每个提供商家族至少选一个: - OpenAI:`openai/gpt-5.4`(或 `openai/gpt-5.4-mini`) - Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`) @@ -444,44 +490,44 @@ Docker 说明: - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` -可选附加覆盖(有则更好): +可选的额外覆盖(有则更好): -- xAI:`xai/grok-4`(或当前最新可用版本) -- Mistral:`mistral/`…(选择一个你已启用、支持 “tools” 的模型) -- Cerebras:`cerebras/`…(如果你有访问权限) +- xAI:`xai/grok-4`(或当前最新可用模型) +- Mistral:`mistral/`…(选择一个你已启用、支持工具的模型) +- Cerebras:`cerebras/`…(如果你有权限) - LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式) ### 视觉:图像发送(附件 → 多模态消息) 在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude / Gemini / OpenAI 支持视觉的变体等),以执行图像探测。 -### 聚合器 / 替代 Gateway 网关 +### 聚合器 / 其他 Gateway 网关 -如果你启用了相应密钥,我们也支持通过以下方式进行测试: +如果你启用了相应密钥,我们也支持通过以下方式测试: -- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选项) +- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选模型) - OpenCode:`opencode/...` 用于 Zen,`opencode-go/...` 用于 Go(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证) -你也可以将更多提供商纳入实时测试矩阵(如果你有凭证 / 配置): +你还可以在实时测试矩阵中加入更多提供商(如果你有凭证 / 配置): - 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`google-gemini-cli`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot` - 通过 `models.providers`(自定义端点):`minimax`(云 / API),以及任何兼容 OpenAI / Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) -提示:不要试图在文档中硬编码“所有模型”。权威列表应始终是你机器上的 `discoverModels(...)` 返回结果 + 当前可用的密钥。 +提示:不要尝试在文档中硬编码“所有模型”。权威列表是你机器上的 `discoverModels(...)` 返回结果,以及当前可用的密钥。 ## 凭证(绝不要提交) -实时测试发现凭证的方式与 CLI 完全相同。实际含义是: +实时测试发现凭证的方式与 CLI 相同。实际含义如下: -- 如果 CLI 可用,实时测试通常也应能找到相同的密钥。 -- 如果某个实时测试提示“无凭证”,就像调试 `openclaw models list` / 模型选择那样进行调试。 +- 如果 CLI 可用,实时测试通常也应该能找到相同的密钥。 +- 如果某个实时测试提示 “no creds”,请像调试 `openclaw models list` / 模型选择那样调试它。 -- 每个智能体的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义) +- 每个智能体的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是实时测试里 “profile keys” 的含义) - 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`) -- 旧版状态目录:`~/.openclaw/credentials/`(若存在,会复制到已暂存的实时测试 home 中,但它不是主 profile-key 存储) -- 本地实时运行默认会把当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home 中;已暂存的实时测试 home 会跳过 `workspace/` 和 `sandboxes/`,并去除 `agents.*.workspace` / `agentDir` 路径覆盖,这样探测就不会落到你真实主机的工作区上。 +- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制到暂存的实时测试 home 中,但它不是主要的 profile-key 存储) +- 本地实时运行默认会将当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/`,以及受支持的外部 CLI 认证目录复制到临时测试 home 中;暂存的实时测试 home 会跳过 `workspace/` 和 `sandboxes/`,并移除 `agents.*.workspace` / `agentDir` 路径覆盖项,以确保探测不会落到你真实的宿主工作区上。 -如果你想依赖环境变量密钥(例如已导出到你的 `~/.profile` 中),请在执行本地测试前运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以把 `~/.profile` 挂载进容器)。 +如果你想依赖环境变量中的密钥(例如在 `~/.profile` 中导出),请在本地测试前运行 `source ~/.profile`,或使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载进容器)。 ## Deepgram 实时测试(音频转录) @@ -499,9 +545,9 @@ Docker 说明: - 测试:`extensions/comfy/comfy.live.test.ts` - 启用:`OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` - 范围: - - 运行内置 comfy 图像、视频和 `music_generate` 路径 - - 除非配置了 `models.providers.comfy.`,否则会跳过对应能力 - - 在你修改 comfy 工作流提交、轮询、下载或插件注册后尤其有用 + - 覆盖内置 comfy 图像、视频和 `music_generate` 路径 + - 除非配置了 `models.providers.comfy.`,否则会跳过各项能力 + - 在修改 comfy 工作流提交、轮询、下载或插件注册后尤其有用 ## 图像生成实时测试 @@ -511,7 +557,7 @@ Docker 说明: - 范围: - 枚举每个已注册的图像生成提供商插件 - 在探测前从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量 - - 默认优先使用实时 / 环境变量 API key,而不是已存储的认证 profile,这样 `auth-profiles.json` 中过期的测试密钥就不会掩盖真实 shell 凭证 + - 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过时的测试密钥不会掩盖真实 shell 凭证 - 跳过没有可用认证 / profile / 模型的提供商 - 通过共享运行时能力运行标准图像生成变体: - `google:flash-generate` @@ -521,12 +567,12 @@ Docker 说明: - 当前覆盖的内置提供商: - `openai` - `google` -- 可选缩小范围: +- 可选范围收窄: - `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google"` - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅来自环境变量的覆盖 ## 音乐生成实时测试 @@ -534,23 +580,23 @@ Docker 说明: - 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts` - Harness:`pnpm test:live:media music` - 范围: - - 运行共享的内置音乐生成提供商路径 + - 覆盖共享的内置音乐生成提供商路径 - 当前覆盖 Google 和 MiniMax - 在探测前从你的登录 shell(`~/.profile`)加载提供商环境变量 - - 默认优先使用实时 / 环境变量 API key,而不是已存储的认证 profile,这样 `auth-profiles.json` 中过期的测试密钥就不会掩盖真实 shell 凭证 + - 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过时的测试密钥不会掩盖真实 shell 凭证 - 跳过没有可用认证 / profile / 模型的提供商 - - 在可用时同时运行两种已声明的运行时模式: - - 使用仅提示词输入的 `generate` - - 当提供商声明 `capabilities.edit.enabled` 时运行 `edit` + - 在可用时运行两种声明的运行时模式: + - `generate`:仅提示词输入 + - `edit`:当提供商声明 `capabilities.edit.enabled` 时 - 当前共享通道覆盖: - `google`:`generate`、`edit` - `minimax`:`generate` - - `comfy`:独立的 Comfy 实时测试文件,不在这个共享扫描中 -- 可选缩小范围: + - `comfy`:单独的 Comfy 实时测试文件,不在这个共享扫描中 +- 可选范围收窄: - `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"` - `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅来自环境变量的覆盖 ## 视频生成实时测试 @@ -558,162 +604,161 @@ Docker 说明: - 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts` - Harness:`pnpm test:live:media video` - 范围: - - 运行共享的内置视频生成提供商路径 + - 覆盖共享的内置视频生成提供商路径 - 在探测前从你的登录 shell(`~/.profile`)加载提供商环境变量 - - 默认优先使用实时 / 环境变量 API key,而不是已存储的认证 profile,这样 `auth-profiles.json` 中过期的测试密钥就不会掩盖真实 shell 凭证 + - 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过时的测试密钥不会掩盖真实 shell 凭证 - 跳过没有可用认证 / profile / 模型的提供商 - - 在可用时同时运行两种已声明的运行时模式: - - 使用仅提示词输入的 `generate` - - 当提供商声明 `capabilities.imageToVideo.enabled` 且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地图像输入时运行 `imageToVideo` - - 当提供商声明 `capabilities.videoToVideo.enabled` 且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地视频输入时运行 `videoToVideo` - - 当前在共享扫描中已声明但被跳过的 `imageToVideo` 提供商: - - `vydra`,因为内置 `veo3` 仅支持文本,且内置 `kling` 需要远程图像 URL - - 提供商特定的 Vydra 覆盖: + - 在可用时运行两种声明的运行时模式: + - `generate`:仅提示词输入 + - 当提供商声明 `capabilities.imageToVideo.enabled`,且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地图像输入时,运行 `imageToVideo` + - 当提供商声明 `capabilities.videoToVideo.enabled`,且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地视频输入时,运行 `videoToVideo` + - 当前在共享扫描中已声明但跳过的 `imageToVideo` 提供商: + - `vydra`,因为内置 `veo3` 仅支持文本,而内置 `kling` 需要远程图像 URL + - 提供商专属的 Vydra 覆盖: - `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts` - - 该文件会运行 `veo3` 文本转视频,以及一个默认使用远程图像 URL fixture 的 `kling` 通道 + - 该文件会运行 `veo3` 文本转视频,以及一个默认使用远程图像 URL 夹具的 `kling` 通道 - 当前 `videoToVideo` 实时测试覆盖: - - 仅 `runway`,且前提是所选模型为 `runway/gen4_aleph` - - 当前在共享扫描中已声明但被跳过的 `videoToVideo` 提供商: + - 仅 `runway`,且所选模型为 `runway/gen4_aleph` 时 + - 当前在共享扫描中已声明但跳过的 `videoToVideo` 提供商: - `alibaba`、`qwen`、`xai`,因为这些路径当前需要远程 `http(s)` / MP4 参考 URL - - `google`,因为当前共享的 Gemini / Veo 通道使用本地基于 buffer 的输入,而该路径在共享扫描中不被接受 - - `openai`,因为当前共享通道不保证具备组织级视频修补 / remix 访问权限 -- 可选缩小范围: + - `google`,因为当前共享的 Gemini / Veo 通道使用基于本地 buffer 的输入,而该路径在共享扫描中不被接受 + - `openai`,因为当前共享通道无法保证组织专属的视频修补 / remix 访问权限 +- 可选范围收窄: - `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"` - `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅来自环境变量的覆盖 -## 媒体实时测试 harness +## 媒体实时测试 Harness - 命令:`pnpm test:live:media` - 目的: - - 通过一个仓库原生入口运行共享的图像、音乐和视频实时测试套件 + - 通过一个仓库原生入口点运行共享的图像、音乐和视频实时测试套件 - 自动从 `~/.profile` 加载缺失的提供商环境变量 - - 默认自动将每个测试套件缩小到当前具备可用认证的提供商 - - 复用 `scripts/test-live.mjs`,因此心跳和静默模式行为保持一致 + - 默认自动将每个测试套件范围收窄到当前拥有可用认证的提供商 + - 复用 `scripts/test-live.mjs`,因此心跳和安静模式行为保持一致 - 示例: - `pnpm test:live:media` - `pnpm test:live:media image video --providers openai,google,minimax` - `pnpm test:live:media video --video-providers openai,runway --all-providers` - `pnpm test:live:media music --quiet` -## Docker 运行器(可选的“在 Linux 中可用”检查) +## Docker 运行器(可选的“可在 Linux 中工作”检查) 这些 Docker 运行器分为两类: -- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行各自匹配的 profile-key 实时测试文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果挂载了 `~/.profile`,也会读取它)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker 实时运行器默认使用更小的冒烟测试上限,以便完整的 Docker 扫描仍然切实可行: +- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 仅在仓库 Docker 镜像内运行各自对应的 profile-key 实时测试文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),同时挂载你的本地配置目录和工作区(如果已挂载,也会加载 `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker 实时运行器默认使用更小的冒烟测试上限,以便完整的 Docker 扫描仍然可行: `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,而 `test:docker:live-gateway` 默认设置 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`,以及 - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确想要更大范围的穷尽式扫描时,再覆盖这些环境变量。 -- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,然后在两个实时 Docker 通道中复用它。 -- 容器冒烟测试运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层级的集成路径。 + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确想执行更大的完整扫描时,请覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,然后在两个实时 Docker 通道中复用该镜像。 +- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -这些实时模型 Docker 运行器还会只绑定挂载所需的 CLI 认证主目录(如果运行未缩小范围,则挂载所有受支持的目录),然后在运行前把它们复制到容器 home 中,这样外部 CLI OAuth 就能刷新令牌,而不会修改主机上的认证存储: +这些实时模型 Docker 运行器还会仅 bind-mount 所需的 CLI 认证 home(或在未缩小范围时挂载所有受支持的认证 home),然后在运行前将其复制到容器 home 中,以便外部 CLI OAuth 能刷新令牌而不修改宿主认证存储: -- 直连模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) +- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) - ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`) - CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`) -- Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) +- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`) +- Gateway 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) - Open WebUI 实时冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) - 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) - Gateway 网关网络(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) - MCP 渠道桥接(带种子数据的 Gateway 网关 + stdio bridge + 原始 Claude 通知帧冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) -- 插件(安装冒烟测试 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) +- 渠道插件(安装冒烟测试 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) -这些实时模型 Docker 运行器还会以只读方式绑定挂载当前 checkout, -并将其暂存到容器内的临时工作目录中。这样既能让运行时镜像保持精简, -又仍然可以针对你本地精确的源代码 / 配置运行 Vitest。 -暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 +这些实时模型 Docker 运行器还会以只读方式 bind-mount 当前 checkout,并将其暂存到容器内部的临时 workdir 中。这样既能保持运行时镜像精简,又仍然可以针对你精确的本地源码 / 配置运行 Vitest。 +暂存步骤会跳过大型仅本地缓存和应用构建输出,例如 `.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地的 `.build` 或 -Gradle 输出目录,因此 Docker 实时测试运行不会花上几分钟去复制机器相关的产物。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时探测就不会在容器中启动 -真实的 Telegram / Discord / 等渠道 worker。 -`test:docker:live-models` 仍然会运行 `pnpm test:live`,因此当你需要缩小范围或排除该 Docker 通道中的 Gateway 网关实时测试覆盖时,也请一并传入 +Gradle 输出目录,这样 Docker 实时运行就不会花上几分钟去复制 +机器专属产物。 +它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时探测就不会在容器内启动 +真实的 Telegram / Discord / 等渠道工作进程。 +`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要缩小范围或从该 Docker 通道中排除 Gateway 网关实时覆盖时,也请一并传入 `OPENCLAW_LIVE_GATEWAY_*`。 `test:docker:openwebui` 是一个更高层级的兼容性冒烟测试:它会启动一个 -启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, -再针对该 Gateway 网关启动一个固定版本的 Open WebUI 容器,通过 +启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器,启动一个固定版本的 Open WebUI 容器并将其指向该 Gateway 网关,通过 Open WebUI 完成登录,验证 `/api/models` 暴露出 `openclaw/default`,然后通过 -Open WebUI 的 `/api/chat/completions` 代理发送一次真实聊天请求。 -第一次运行可能会明显更慢,因为 Docker 可能需要拉取 -Open WebUI 镜像,而 Open WebUI 也可能需要完成它自己的冷启动 setup。 -这个通道需要一个可用的实时模型密钥,而 `OPENCLAW_PROFILE_FILE` -(默认 `~/.profile`)是在 Docker 化运行中提供它的主要方式。 -成功运行会打印一小段 JSON 载荷,例如 `{ "ok": true, "model": +Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。 +首次运行可能会明显更慢,因为 Docker 可能需要拉取 +Open WebUI 镜像,而 Open WebUI 也可能需要完成自身的冷启动设置。 +该通道需要一个可用的实时模型密钥,而 `OPENCLAW_PROFILE_FILE` +(默认是 `~/.profile`)是在 Docker 化运行中提供它的主要方式。 +成功运行会打印一个小型 JSON 载荷,例如 `{ "ok": true, "model": "openclaw/default", ... }`。 -`test:docker:mcp-channels` 是有意保持确定性的,不需要真实的 -Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Gateway 网关 -容器,启动第二个容器来运行 `openclaw mcp serve`,然后 -通过真实的 stdio MCP bridge 验证已路由会话发现、转录读取、附件元数据、 +`test:docker:mcp-channels` 刻意设计为确定性运行,不需要 +真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Gateway 网关 +容器,再启动第二个容器来运行 `openclaw mcp serve`,然后 +验证路由后的会话发现、转录读取、附件元数据、 实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + -权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是桥接 -实际发出了什么,而不仅仅是某个特定客户端 SDK 恰好暴露了什么。 +权限通知,这些都通过真实的 stdio MCP bridge 完成。通知检查 +会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 bridge 实际发出的内容, +而不仅仅是某个特定客户端 SDK 恰好暴露出来的内容。 -手动 ACP 纯自然语言线程冒烟测试(非 CI): +手动 ACP 平实语言线程冒烟测试(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 保留这个脚本用于回归 / 调试工作流。未来可能还需要它来验证 ACP 线程路由,因此不要删除它。 +- 保留此脚本用于回归 / 调试工作流。之后可能还会再次需要它来验证 ACP 线程路由,所以不要删除它。 -有用的环境变量: +常用环境变量: - `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`),挂载到 `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`),挂载到 `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`),挂载到 `/home/node/.profile`,并在运行测试前读取 -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`),挂载到 `/home/node/.npm-global`,用于缓存 Docker 内部安装的 CLI +- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`),挂载到 `/home/node/.profile` 并在运行测试前加载 +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`),挂载到 `/home/node/.npm-global`,供 Docker 内缓存 CLI 安装使用 - `$HOME` 下的外部 CLI 认证目录 / 文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` - 默认目录:`.minimax` - 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 缩小范围的提供商运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录 / 文件 - - 手动覆盖方式:`OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或逗号分隔列表,例如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` + - 范围已收窄的提供商运行仅挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的必需目录 / 文件 + - 你也可以手动覆盖:`OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或逗号列表,例如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` - `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围 -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内过滤提供商 -- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于复用现有的 `openclaw:local-live` 镜像,以便在无需重建时重复运行 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而不是环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试中使用的 nonce 检查提示词 -- `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签 +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商 +- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于复用现有 `openclaw:local-live` 镜像,以便在无需重建时重新运行 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 确保凭证来自 profile 存储(而不是环境变量) +- `OPENCLAW_OPENWEBUI_MODEL=...` 选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 覆盖 Open WebUI 冒烟测试中使用的 nonce 检查提示词 +- `OPENWEBUI_IMAGE=...` 覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 -编辑文档后运行文档检查:`pnpm check:docs`。 -当你还需要完整的 Mintlify 锚点校验(包括页内标题检查)时,运行:`pnpm docs:check-links:anchors`。 +文档编辑后运行文档检查:`pnpm check:docs`。 +当你还需要页内标题检查时,运行完整的 Mintlify anchor 校验:`pnpm docs:check-links:anchors`。 ## 离线回归测试(CI 安全) -这些是在不依赖真实提供商的情况下,针对“真实流水线”的回归测试: +这些是在不使用真实提供商的情况下,对“真实流水线”进行的回归测试: -- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) -- Gateway 网关向导(WS `wizard.start` / `wizard.next`,会写入配置 + 强制认证):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) +- Gateway 网关工具调用(模拟 OpenAI、真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) +- Gateway 网关向导(WS `wizard.start` / `wizard.next`,并强制写入配置 + 认证):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) ## 智能体可靠性评估(Skills) -我们已经有一些 CI 安全的测试,它们的行为类似“智能体可靠性评估”: +我们已经有一些可在 CI 中安全运行、行为类似“智能体可靠性评估”的测试: -- 通过真实 Gateway 网关 + 智能体循环执行模拟工具调用(`src/gateway/gateway.test.ts`)。 +- 通过真实 Gateway 网关 + 智能体循环进行模拟工具调用(`src/gateway/gateway.test.ts`)。 - 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 -对于 Skills,仍然缺少以下内容(参见 [Skills](/zh-CN/tools/skills)): +对于 Skills(见 [Skills](/zh-CN/tools/skills)),目前仍缺少的是: -- **决策**:当 Skills 列在提示词中时,智能体是否会选择正确的 Skills(或避免无关 Skills)? -- **合规性**:智能体在使用前是否会读取 `SKILL.md` 并遵循必需的步骤 / 参数? -- **工作流契约**:断言工具顺序、会话历史延续以及沙箱边界的多轮场景。 +- **决策能力:** 当 Skills 被列在提示中时,智能体是否会选择正确的 Skills(或避开无关的 Skills)? +- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵循所要求的步骤 / 参数? +- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 -未来的评估应当优先保持确定性: +未来的评估应优先保持确定性: -- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skills 文件读取以及会话接线。 +- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skills 文件读取和会话接线。 - 一小套面向 Skills 的场景(使用 vs 避免、门禁、提示注入)。 -- 仅在 CI 安全套件就位之后,再添加可选的实时评估(按需启用、环境变量门控)。 +- 仅在 CI 安全套件就位之后,才添加可选的实时评估(选择加入、由环境变量控制)。 ## 契约测试(插件和渠道形状) -契约测试用于验证每个已注册的插件和渠道都符合其 -接口契约。它们会遍历所有已发现的插件,并运行一组 -针对形状和行为的断言。默认的 `pnpm test` 单元测试通道会有意 +契约测试会验证每个已注册的插件和渠道都符合其 +接口契约。它们会遍历所有已发现的插件,并运行一组关于形状和行为的断言。默认的 `pnpm test` 单元测试通道会刻意 跳过这些共享接缝和冒烟测试文件;当你修改共享渠道或提供商表面时, -请显式运行契约测试命令。 +请显式运行这些契约命令。 ### 命令 @@ -733,7 +778,7 @@ Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Ga - **actions** - 渠道操作处理器 - **threading** - 线程 ID 处理 - **directory** - 目录 / roster API -- **group-policy** - 群组策略执行 +- **group-policy** - 群组策略强制执行 ### 提供商状态契约测试 @@ -747,7 +792,7 @@ Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Ga 位于 `src/plugins/contracts/*.contract.test.ts`: - **auth** - 认证流程契约 -- **auth-choice** - 认证选择 / 选取 +- **auth-choice** - 认证选项 / 选择 - **catalog** - 模型目录 API - **discovery** - 插件发现 - **loader** - 插件加载 @@ -757,21 +802,21 @@ Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Ga ### 何时运行 -- 修改 `plugin-sdk` 导出或子路径之后 -- 新增或修改渠道插件或提供商插件之后 -- 重构插件注册或发现机制之后 +- 修改 `plugin-sdk` 导出或子路径后 +- 添加或修改渠道插件或提供商插件后 +- 重构插件注册或发现逻辑后 -契约测试会在 CI 中运行,并且不需要真实 API key。 +契约测试会在 CI 中运行,不需要真实 API 密钥。 -## 添加回归测试(指南) +## 添加回归测试(指导) -当你修复了在实时测试中发现的提供商 / 模型问题时: +当你修复了一个在实时测试中发现的提供商 / 模型问题时: -- 如果可能,添加一个 CI 安全的回归测试(模拟 / stub 提供商,或捕获精确的请求形状转换) -- 如果问题本质上只能在实时测试中复现(速率限制、认证策略),就让实时测试保持范围狭窄,并通过环境变量按需启用 -- 优先瞄准能够捕获该缺陷的最小层级: - - 提供商请求转换 / 重放缺陷 → 直连模型测试 - - Gateway 网关会话 / 历史记录 / 工具流水线缺陷 → Gateway 网关实时冒烟测试或 CI 安全的 Gateway 网关模拟测试 -- SecretRef 遍历防护要求: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言遍历片段 exec id 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中新增了一个 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会故意在遇到未分类目标 id 时失败,这样新的类别就无法被静默跳过。 +- 如果可能,添加一个 CI 安全的回归测试(模拟 / 存根提供商,或捕获精确的请求形状转换) +- 如果它天生只能通过实时测试复现(速率限制、认证策略),就让实时测试保持范围收窄,并通过环境变量选择加入 +- 优先定位能捕获该缺陷的最小层级: + - 提供商请求转换 / 重放缺陷 → 直接模型测试 + - Gateway 网关会话 / 历史 / 工具流水线缺陷 → Gateway 网关实时冒烟测试或 CI 安全的 Gateway 网关模拟测试 +- SecretRef 遍历防护约束: + - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言遍历段 exec id 会被拒绝。 + - 如果你在 `src/secrets/target-registry-data.ts` 中新增了一个 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会在遇到未分类的目标 id 时故意失败,这样新类别就无法被悄悄跳过。 diff --git a/docs/zh-CN/plugins/sdk-agent-harness.md b/docs/zh-CN/plugins/sdk-agent-harness.md new file mode 100644 index 000000000..22add9aa9 --- /dev/null +++ b/docs/zh-CN/plugins/sdk-agent-harness.md @@ -0,0 +1,192 @@ +--- +read_when: + - 你正在更改内嵌智能体运行时或 Harness 注册表 + - 你正在从内置或受信任插件注册一个智能体 Harness + - 你需要了解 Codex 插件与模型提供商之间的关系 +sidebarTitle: Agent Harness +summary: 用于替换底层内嵌智能体执行器的插件实验性 SDK 接口层 +title: 智能体 Harness 插件 +x-i18n: + generated_at: "2026-04-10T20:23:47Z" + model: gpt-5.4 + provider: openai + source_hash: ba482dd6a2e4730c2d623b4739e2e6037cec8bb71bf7164b4e9d7ea8e43056d8 + source_path: plugins/sdk-agent-harness.md + workflow: 15 +--- + +# 智能体 Harness 插件 + +**智能体 Harness** 是一个已准备好的 OpenClaw 智能体单次轮转的底层执行器。它不是模型提供商,不是渠道,也不是工具注册表。 + +仅对内置或受信任的原生插件使用此接口层。该契约仍处于实验阶段,因为参数类型有意映射当前的内嵌运行器。 + +## 何时使用 Harness + +当某个模型家族拥有自己的原生会话运行时,而常规 OpenClaw 提供商传输抽象并不适用时,请注册一个智能体 Harness。 + +示例: + +- 拥有线程和上下文压缩能力的原生 coding-agent 服务器 +- 必须流式传输原生计划/推理/工具事件的本地 CLI 或守护进程 +- 除了 OpenClaw 会话转录之外,还需要自己的恢复 id 的模型运行时 + +不要仅为了添加一个新的 LLM API 而注册 Harness。对于普通的 HTTP 或 WebSocket 模型 API,请构建一个 [提供商插件](/zh-CN/plugins/sdk-provider-plugins)。 + +## 核心仍然负责的内容 + +在选择 Harness 之前,OpenClaw 已经解析了: + +- 提供商和模型 +- 运行时凭证状态 +- 思考级别和上下文预算 +- OpenClaw 转录/会话文件 +- 工作区、沙箱和工具策略 +- 渠道回复回调和流式回调 +- 模型回退和实时模型切换策略 + +这种拆分是有意设计的。Harness 负责运行一个已准备好的尝试;它不会选择提供商、替换渠道投递,也不会静默切换模型。 + +## 注册 Harness + +**导入:** `openclaw/plugin-sdk/agent-harness` + +```typescript +import type { AgentHarness } from "openclaw/plugin-sdk/agent-harness"; +import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; + +const myHarness: AgentHarness = { + id: "my-harness", + label: "My native agent harness", + + supports(ctx) { + return ctx.provider === "my-provider" + ? { supported: true, priority: 100 } + : { supported: false }; + }, + + async runAttempt(params) { + // Start or resume your native thread. + // Use params.prompt, params.tools, params.images, params.onPartialReply, + // params.onAgentEvent, and the other prepared attempt fields. + return await runMyNativeTurn(params); + }, +}; + +export default definePluginEntry({ + id: "my-native-agent", + name: "My Native Agent", + description: "Runs selected models through a native agent daemon.", + register(api) { + api.registerAgentHarness(myHarness); + }, +}); +``` + +## 选择策略 + +OpenClaw 会在提供商/模型解析之后选择 Harness: + +1. `OPENCLAW_AGENT_RUNTIME=` 会强制使用具有该 id 的已注册 Harness。 +2. `OPENCLAW_AGENT_RUNTIME=pi` 会强制使用内置的 PI Harness。 +3. `OPENCLAW_AGENT_RUNTIME=auto` 会让已注册的 Harness 查询其是否支持已解析的提供商/模型。 +4. 如果没有匹配的已注册 Harness,OpenClaw 会使用 PI。 + +被强制指定的插件 Harness 如果失败,会作为运行失败呈现。在 `auto` 模式下,如果所选插件 Harness 在某次轮转产生副作用之前失败,OpenClaw 可能会回退到 PI。 + +内置 Codex 插件将 `codex` 注册为其 Harness id。为兼容起见,当你手动设置 `OPENCLAW_AGENT_RUNTIME` 时,`codex-app-server` 和 `app-server` 也会解析到同一个 Harness。 + +## 提供商与 Harness 配对 + +大多数 Harness 也应该注册一个提供商。提供商会让模型引用、凭证状态、模型元数据和 `/model` 选择对 OpenClaw 的其余部分可见。然后 Harness 在 `supports(...)` 中声明该提供商。 + +内置 Codex 插件遵循这一模式: + +- provider id: `codex` +- 用户模型引用:`codex/gpt-5.4`、`codex/gpt-5.2`,或 Codex app server 返回的其他模型 +- harness id: `codex` +- 凭证:合成提供商可用性,因为 Codex Harness 拥有原生 Codex 登录/会话 +- app-server 请求:OpenClaw 向 Codex 发送裸模型 id,并让 Harness 与原生 app-server 协议通信 + +Codex 插件是增量性的。普通 `openai/gpt-*` 引用仍然是 OpenAI 提供商引用,并继续使用常规 OpenClaw 提供商路径。当你希望使用由 Codex 管理的凭证、Codex 模型发现、原生线程以及 Codex app-server 执行时,请选择 `codex/gpt-*`。`/model` 可以在 Codex app server 返回的 Codex 模型之间切换,而无需 OpenAI 提供商凭证。 + +OpenClaw 要求 Codex app-server 版本为 `0.118.0` 或更高。Codex 插件会检查 app-server 初始化握手,并阻止较旧或未带版本信息的服务器,从而确保 OpenClaw 仅在它已测试过的协议接口层上运行。 + +## Harness 选择策略 + +默认情况下,OpenClaw 运行内嵌智能体时,`agents.defaults.embeddedHarness` 设置为 `{ runtime: "auto", fallback: "pi" }`。在 `auto` 模式下,已注册的插件 Harness 可以声明某个提供商/模型对。如果都不匹配,或者自动选中的插件 Harness 在产生输出之前失败,OpenClaw 会回退到 PI。 + +当你需要证明某个插件 Harness 是唯一被执行的运行时时,请设置 `fallback: "none"`: + +```json +{ + "agents": { + "defaults": { + "model": "codex/gpt-5.4", + "embeddedHarness": { + "runtime": "codex", + "fallback": "none" + } + } + } +} +``` + +按智能体覆盖使用相同的结构: + +```json +{ + "agents": { + "defaults": { + "embeddedHarness": { + "runtime": "auto", + "fallback": "pi" + } + }, + "list": [ + { + "id": "codex-only", + "model": "codex/gpt-5.4", + "embeddedHarness": { + "runtime": "codex", + "fallback": "none" + } + } + ] + } +} +``` + +`OPENCLAW_AGENT_RUNTIME` 仍然会覆盖已配置的运行时。使用 `OPENCLAW_AGENT_HARNESS_FALLBACK=none` 可通过环境变量禁用 PI 回退。 + +## 原生会话与转录镜像 + +Harness 可以保留原生 session id、thread id 或守护进程侧恢复 token。请将这种绑定明确关联到 OpenClaw 会话,并继续将用户可见的助手/工具输出镜像到 OpenClaw 转录中。 + +OpenClaw 转录仍然是以下能力的兼容层: + +- 渠道可见的会话历史 +- 转录搜索和索引 +- 在后续轮转中切换回内置 PI Harness +- 通用 `/new`、`/reset` 和会话删除行为 + +如果你的 Harness 存储了 sidecar 绑定,请实现 `reset(...)`,这样 OpenClaw 才能在所属 OpenClaw 会话重置时清除它。 + +## 工具和媒体结果 + +核心会构造 OpenClaw 工具列表并将其传入已准备好的尝试中。当 Harness 执行动态工具调用时,请通过 Harness 结果结构返回工具结果,而不是自行发送渠道媒体。 + +这样可以让文本、图像、视频、音乐、TTS、审批和消息工具输出与基于 PI 的运行共享同一条投递路径。 + +## 当前限制 + +- 公共导入路径是通用的,但某些 attempt/result 类型别名仍然保留 `Pi` 名称以保持兼容性。 +- 第三方 Harness 安装仍处于实验阶段。在你确实需要原生会话运行时之前,请优先使用提供商插件。 +- 支持跨轮转切换 Harness。不要在某次轮转中途切换 Harness,尤其是在原生工具、审批、助手文本或消息发送已经开始之后。 + +## 相关内容 + +- [SDK 概览](/zh-CN/plugins/sdk-overview) +- [运行时辅助工具](/zh-CN/plugins/sdk-runtime) +- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) +- [模型提供商](/zh-CN/concepts/model-providers) diff --git a/docs/zh-CN/plugins/sdk-overview.md b/docs/zh-CN/plugins/sdk-overview.md index 657e6ca92..eee858798 100644 --- a/docs/zh-CN/plugins/sdk-overview.md +++ b/docs/zh-CN/plugins/sdk-overview.md @@ -1,60 +1,67 @@ --- read_when: - 你需要知道应从哪个 SDK 子路径导入 - - 你想查阅 OpenClawPluginApi 上所有注册方法的参考说明 + - 你想查看 OpenClawPluginApi 上所有注册方法的参考信息 - 你正在查找某个特定的 SDK 导出 sidebarTitle: SDK Overview summary: 导入映射、注册 API 参考和 SDK 架构 title: 插件 SDK 概览 x-i18n: - generated_at: "2026-04-09T00:38:10Z" + generated_at: "2026-04-10T20:23:44Z" model: gpt-5.4 provider: openai - source_hash: bf205af060971931df97dca4af5110ce173d2b7c12f56ad7c62d664a402f2381 + source_hash: 4bfeb5896f68e3e4ee8cf434d43a019e0d1fe5af57f5bf7a5172847c476def0c source_path: plugins/sdk-overview.md workflow: 15 --- # 插件 SDK 概览 -插件 SDK 是插件与核心之间的类型化契约。此页面是关于**该导入什么**以及**你可以注册什么**的参考。 +插件 SDK 是插件与核心之间的类型化契约。本页是关于**导入什么**以及**你可以注册什么**的参考文档。 **在找操作指南吗?** - 第一个插件?从 [入门指南](/zh-CN/plugins/building-plugins) 开始 - - 渠道插件?请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) - - 提供商插件?请参阅 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) + - 渠道插件?参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) + - 提供商插件?参见 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) ## 导入约定 -始终从特定子路径导入: +始终从特定的子路径导入: ```typescript import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; ``` -每个子路径都是一个小型、独立的模块。这样可以保持快速启动,并防止循环依赖问题。对于特定于渠道的入口/构建辅助函数,优先使用 `openclaw/plugin-sdk/channel-core`;将 `openclaw/plugin-sdk/core` 保留给更广泛的总入口表面和共享辅助函数,例如 `buildChannelConfigSchema`。 +每个子路径都是一个小型、独立的模块。这能保持快速启动,并防止循环依赖问题。对于特定于渠道的入口点/构建辅助函数,优先使用 `openclaw/plugin-sdk/channel-core`;将 `openclaw/plugin-sdk/core` 保留给更广泛的总括性表面和共享辅助函数,例如 `buildChannelConfigSchema`。 -不要添加或依赖带有提供商名称的便捷接缝,例如 `openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`,或带有渠道品牌的辅助接缝。内置插件应在各自的 `api.ts` 或 `runtime-api.ts` barrel 文件中组合通用 SDK 子路径,而核心则应使用这些插件本地 barrel,或者仅在确实属于跨渠道需求时添加一个狭义的通用 SDK 契约。 +不要添加或依赖以提供商命名的便捷接缝,例如 +`openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、 +`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`,或 +带有渠道品牌的辅助接缝。内置插件应在其自己的 `api.ts` 或 `runtime-api.ts` barrel 文件中组合通用 +SDK 子路径,而核心则应使用这些插件本地的 barrel 文件,或者在需求确实跨渠道时添加一个狭义的通用 SDK +契约。 -生成的导出映射仍然包含一小组内置插件辅助接缝,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些子路径仅为内置插件维护和兼容性而存在;它们有意未包含在下方的常用表格中,也不是新第三方插件推荐的导入路径。 +生成的导出映射仍然包含一小组内置插件辅助接缝,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些 +子路径仅为内置插件维护和兼容性而存在;它们在下方的常用表中被有意省略,也不是新第三方插件推荐的导入路径。 ## 子路径参考 -最常用的子路径,按用途分组。完整的生成列表包含 200 多个子路径,位于 `scripts/lib/plugin-sdk-entrypoints.json`。 +最常用的子路径,按用途分组。完整的 200+ 子路径生成列表位于 `scripts/lib/plugin-sdk-entrypoints.json` 中。 -保留的内置插件辅助子路径仍会出现在该生成列表中。除非某个文档页面明确将其推广为公共接口,否则应将其视为实现细节/兼容性表面。 +保留的内置插件辅助子路径仍会出现在该生成列表中。 +除非某个文档页面明确将其作为公共接口推荐,否则应将它们视为实现细节/兼容性表面。 -### 插件入口 +### 插件入口点 -| 子路径 | 关键导出 | -| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -| `plugin-sdk/plugin-entry` | `definePluginEntry` | -| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` | -| `plugin-sdk/config-schema` | `OpenClawSchema` | -| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | +| 子路径 | 关键导出 | +| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `plugin-sdk/plugin-entry` | `definePluginEntry` | +| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` | +| `plugin-sdk/config-schema` | `OpenClawSchema` | +| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | @@ -63,19 +70,19 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | `plugin-sdk/channel-core` | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` | | `plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema 导出(`OpenClawSchema`) | | `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` | - | `plugin-sdk/setup` | 共享设置向导辅助函数、allowlist 提示、设置状态构建器 | + | `plugin-sdk/setup` | 共享设置向导辅助函数、允许列表提示、设置状态构建器 | | `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` | | `plugin-sdk/setup-adapter-runtime` | `createEnvPatchedAccountSetupAdapter` | | `plugin-sdk/setup-tools` | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | | `plugin-sdk/account-core` | 多账户配置/操作门控辅助函数、默认账户回退辅助函数 | - | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、account-id 规范化辅助函数 | + | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、账户 ID 规范化辅助函数 | | `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助函数 | | `plugin-sdk/account-helpers` | 狭义的账户列表/账户操作辅助函数 | | `plugin-sdk/channel-pairing` | `createChannelPairingController` | | `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline` | | `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` | | `plugin-sdk/channel-config-schema` | 渠道配置 schema 类型 | - | `plugin-sdk/telegram-command-config` | 带有内置契约回退的 Telegram 自定义命令规范化/校验辅助函数 | + | `plugin-sdk/telegram-command-config` | Telegram 自定义命令规范化/验证辅助函数,带内置契约回退 | | `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` | | `plugin-sdk/channel-lifecycle` | `createAccountStatusSink` | | `plugin-sdk/inbound-envelope` | 共享入站路由 + envelope 构建辅助函数 | @@ -84,25 +91,25 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | `plugin-sdk/outbound-media` | 共享出站媒体加载辅助函数 | | `plugin-sdk/outbound-runtime` | 出站身份/发送委托辅助函数 | | `plugin-sdk/thread-bindings-runtime` | 线程绑定生命周期和适配器辅助函数 | - | `plugin-sdk/agent-media-payload` | 旧版智能体媒体载荷构建器 | + | `plugin-sdk/agent-media-payload` | 旧版智能体媒体负载构建器 | | `plugin-sdk/conversation-runtime` | 会话/线程绑定、配对和已配置绑定辅助函数 | | `plugin-sdk/runtime-config-snapshot` | 运行时配置快照辅助函数 | | `plugin-sdk/runtime-group-policy` | 运行时群组策略解析辅助函数 | | `plugin-sdk/channel-status` | 共享渠道状态快照/摘要辅助函数 | - | `plugin-sdk/channel-config-primitives` | 狭义的渠道配置 schema 基元 | + | `plugin-sdk/channel-config-primitives` | 狭义的渠道配置 schema 原语 | | `plugin-sdk/channel-config-writes` | 渠道配置写入授权辅助函数 | | `plugin-sdk/channel-plugin-common` | 共享渠道插件前导导出 | - | `plugin-sdk/allowlist-config-edit` | allowlist 配置编辑/读取辅助函数 | + | `plugin-sdk/allowlist-config-edit` | 允许列表配置编辑/读取辅助函数 | | `plugin-sdk/group-access` | 共享群组访问决策辅助函数 | - | `plugin-sdk/direct-dm` | 共享直接私信认证/防护辅助函数 | - | `plugin-sdk/interactive-runtime` | 交互式回复载荷规范化/归约辅助函数 | - | `plugin-sdk/channel-inbound` | 入站去抖、提及匹配、提及策略辅助函数以及 envelope 辅助函数 | + | `plugin-sdk/direct-dm` | 共享直接私信凭证/保护辅助函数 | + | `plugin-sdk/interactive-runtime` | 交互式回复负载规范化/归约辅助函数 | + | `plugin-sdk/channel-inbound` | 入站去抖动、提及匹配、提及策略辅助函数和 envelope 辅助函数 | | `plugin-sdk/channel-send-result` | 回复结果类型 | | `plugin-sdk/channel-actions` | `createMessageToolButtonsSchema`, `createMessageToolCardSchema` | | `plugin-sdk/channel-targets` | 目标解析/匹配辅助函数 | | `plugin-sdk/channel-contract` | 渠道契约类型 | | `plugin-sdk/channel-feedback` | 反馈/反应接线 | - | `plugin-sdk/channel-secret-runtime` | 狭义的 secret 契约辅助函数,例如 `collectSimpleChannelFieldAssignments`, `getChannelSurface`, `pushAssignment`,以及 secret 目标类型 | + | `plugin-sdk/channel-secret-runtime` | 狭义的 secret 契约辅助函数,例如 `collectSimpleChannelFieldAssignments`, `getChannelSurface`, `pushAssignment` 和 secret 目标类型 | @@ -112,123 +119,124 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | `plugin-sdk/provider-setup` | 精选的本地/自托管提供商设置辅助函数 | | `plugin-sdk/self-hosted-provider-setup` | 聚焦 OpenAI 兼容自托管提供商的设置辅助函数 | | `plugin-sdk/cli-backend` | CLI 后端默认值 + watchdog 常量 | - | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API key 解析辅助函数 | - | `plugin-sdk/provider-auth-api-key` | API key 新手引导/profile 写入辅助函数,例如 `upsertApiKeyProfile` | - | `plugin-sdk/provider-auth-result` | 标准 OAuth auth-result 构建器 | + | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API 密钥解析辅助函数 | + | `plugin-sdk/provider-auth-api-key` | API 密钥新手引导/配置文件写入辅助函数,例如 `upsertApiKeyProfile` | + | `plugin-sdk/provider-auth-result` | 标准 OAuth 认证结果构建器 | | `plugin-sdk/provider-auth-login` | 提供商插件的共享交互式登录辅助函数 | | `plugin-sdk/provider-env-vars` | 提供商认证环境变量查找辅助函数 | | `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` | - | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider-endpoint 辅助函数,以及诸如 `normalizeNativeXaiModelId` 之类的 model-id 规范化辅助函数 | + | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享回放策略构建器、提供商端点辅助函数,以及模型 ID 规范化辅助函数,例如 `normalizeNativeXaiModelId` | | `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` | - | `plugin-sdk/provider-http` | 通用提供商 HTTP/endpoint 能力辅助函数 | + | `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助函数 | | `plugin-sdk/provider-web-fetch-contract` | 狭义的 web-fetch 配置/选择契约辅助函数,例如 `enablePluginInConfig` 和 `WebFetchProviderPlugin` | - | `plugin-sdk/provider-web-fetch` | web-fetch 提供商注册/缓存辅助函数 | - | `plugin-sdk/provider-web-search-config-contract` | 适用于不需要插件启用接线的提供商的狭义 web-search 配置/凭证辅助函数 | - | `plugin-sdk/provider-web-search-contract` | 狭义的 web-search 配置/凭证契约辅助函数,例如 `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`,以及作用域化的凭证设置器/获取器 | - | `plugin-sdk/provider-web-search` | web-search 提供商注册/缓存/运行时辅助函数 | - | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini schema 清理 + 诊断,以及 xAI 兼容辅助函数,例如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` | - | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似函数 | + | `plugin-sdk/provider-web-fetch` | Web-fetch 提供商注册/缓存辅助函数 | + | `plugin-sdk/provider-web-search-config-contract` | 面向无需插件启用接线的提供商的狭义 web-search 配置/凭证辅助函数 | + | `plugin-sdk/provider-web-search-contract` | 狭义的 web-search 配置/凭证契约辅助函数,例如 `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`,以及作用域凭证 setter/getter | + | `plugin-sdk/provider-web-search` | Web-search 提供商注册/缓存/运行时辅助函数 | + | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 xAI 兼容性辅助函数,例如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` | + | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 等 | | `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助函数 | | `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助函数 | | `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助函数 | - + | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助函数、发送者授权辅助函数 | | `plugin-sdk/command-status` | 命令/帮助消息构建器,例如 `buildCommandsMessagePaginated` 和 `buildHelpMessage` | - | `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天 action-auth 辅助函数 | - | `plugin-sdk/approval-client-runtime` | 原生执行审批 profile/filter 辅助函数 | - | `plugin-sdk/approval-delivery-runtime` | 原生审批能力/传递适配器 | + | `plugin-sdk/approval-auth-runtime` | 审批者解析和同聊天操作认证辅助函数 | + | `plugin-sdk/approval-client-runtime` | 原生执行审批配置文件/过滤器辅助函数 | + | `plugin-sdk/approval-delivery-runtime` | 原生审批能力/投递适配器 | | `plugin-sdk/approval-gateway-runtime` | 共享审批 Gateway 网关解析辅助函数 | | `plugin-sdk/approval-handler-adapter-runtime` | 面向高频渠道入口点的轻量级原生审批适配器加载辅助函数 | - | `plugin-sdk/approval-handler-runtime` | 更广泛的审批处理器运行时辅助函数;若更狭义的 adapter/gateway 接缝已足够,优先使用后者 | + | `plugin-sdk/approval-handler-runtime` | 更广泛的审批处理器运行时辅助函数;如果更狭义的适配器/Gateway 网关接缝已足够,优先使用它们 | | `plugin-sdk/approval-native-runtime` | 原生审批目标 + 账户绑定辅助函数 | - | `plugin-sdk/approval-reply-runtime` | exec/plugin 审批回复载荷辅助函数 | + | `plugin-sdk/approval-reply-runtime` | 执行/插件审批回复负载辅助函数 | | `plugin-sdk/command-auth-native` | 原生命令认证 + 原生会话目标辅助函数 | | `plugin-sdk/command-detection` | 共享命令检测辅助函数 | - | `plugin-sdk/command-surface` | 命令体规范化和命令表面辅助函数 | + | `plugin-sdk/command-surface` | 命令正文规范化和命令表面辅助函数 | | `plugin-sdk/allow-from` | `formatAllowFromLowercase` | - | `plugin-sdk/channel-secret-runtime` | 用于渠道/plugin secret 表面的狭义 secret 契约收集辅助函数 | - | `plugin-sdk/secret-ref-runtime` | 狭义的 `coerceSecretRef` 和 SecretRef 类型辅助函数,用于 secret 契约/配置解析 | + | `plugin-sdk/channel-secret-runtime` | 面向渠道/插件 secret 表面的狭义 secret 契约收集辅助函数 | + | `plugin-sdk/secret-ref-runtime` | 狭义的 `coerceSecretRef` 和用于 secret 契约/配置解析的 SecretRef 类型辅助函数 | | `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容和 secret 收集辅助函数 | - | `plugin-sdk/ssrf-policy` | 主机 allowlist 和私有网络 SSRF 策略辅助函数 | - | `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 防护的 fetch,以及 SSRF 策略辅助函数 | - | `plugin-sdk/secret-input` | secret 输入解析辅助函数 | - | `plugin-sdk/webhook-ingress` | webhook 请求/目标辅助函数 | + | `plugin-sdk/ssrf-policy` | 主机允许列表和私有网络 SSRF 策略辅助函数 | + | `plugin-sdk/ssrf-runtime` | 固定调度器、受 SSRF 保护的 fetch 和 SSRF 策略辅助函数 | + | `plugin-sdk/secret-input` | Secret 输入解析辅助函数 | + | `plugin-sdk/webhook-ingress` | Webhook 请求/目标辅助函数 | | `plugin-sdk/webhook-request-guards` | 请求体大小/超时辅助函数 | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/runtime` | 广义的运行时/日志/备份/插件安装辅助函数 | - | `plugin-sdk/runtime-env` | 狭义的运行时环境、logger、timeout、retry 和 backoff 辅助函数 | - | `plugin-sdk/channel-runtime-context` | 通用渠道运行时上下文注册与查找辅助函数 | + | `plugin-sdk/runtime` | 广泛的运行时/日志/备份/插件安装辅助函数 | + | `plugin-sdk/runtime-env` | 狭义的运行时环境、logger、超时、重试和退避辅助函数 | + | `plugin-sdk/channel-runtime-context` | 通用渠道运行时上下文注册和查找辅助函数 | | `plugin-sdk/runtime-store` | `createPluginRuntimeStore` | - | `plugin-sdk/plugin-runtime` | 共享插件命令/hook/http/interactive 辅助函数 | - | `plugin-sdk/hook-runtime` | 共享 webhook/internal hook 管道辅助函数 | - | `plugin-sdk/lazy-runtime` | 惰性运行时导入/绑定辅助函数,例如 `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeSurface` | + | `plugin-sdk/plugin-runtime` | 共享插件命令/hook/http/交互式辅助函数 | + | `plugin-sdk/hook-runtime` | 共享 webhook/内部 hook 管道辅助函数 | + | `plugin-sdk/lazy-runtime` | 惰性运行时导入/绑定辅助函数,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | | `plugin-sdk/process-runtime` | 进程执行辅助函数 | | `plugin-sdk/cli-runtime` | CLI 格式化、等待和版本辅助函数 | | `plugin-sdk/gateway-runtime` | Gateway 网关客户端和渠道状态补丁辅助函数 | | `plugin-sdk/config-runtime` | 配置加载/写入辅助函数 | - | `plugin-sdk/telegram-command-config` | Telegram 命令名称/描述规范化以及重复/冲突检查,即使内置 Telegram 契约表面不可用也可使用 | - | `plugin-sdk/approval-runtime` | exec/plugin 审批辅助函数、审批能力构建器、认证/profile 辅助函数、原生路由/运行时辅助函数 | - | `plugin-sdk/reply-runtime` | 共享入站/回复运行时辅助函数、分块、分发、heartbeat、回复规划器 | + | `plugin-sdk/telegram-command-config` | Telegram 命令名称/描述规范化以及重复/冲突检查,即使内置的 Telegram 契约表面不可用时也可使用 | + | `plugin-sdk/approval-runtime` | 执行/插件审批辅助函数、审批能力构建器、认证/配置文件辅助函数、原生路由/运行时辅助函数 | + | `plugin-sdk/reply-runtime` | 共享入站/回复运行时辅助函数、分块、分发、心跳、回复规划器 | | `plugin-sdk/reply-dispatch-runtime` | 狭义的回复分发/完成辅助函数 | - | `plugin-sdk/reply-history` | 共享短窗口回复历史辅助函数,例如 `buildHistoryContext`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` | + | `plugin-sdk/reply-history` | 共享短时间窗口回复历史辅助函数,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` | | `plugin-sdk/reply-reference` | `createReplyReferencePlanner` | | `plugin-sdk/reply-chunking` | 狭义的文本/Markdown 分块辅助函数 | | `plugin-sdk/session-store-runtime` | 会话存储路径 + updated-at 辅助函数 | | `plugin-sdk/state-paths` | 状态/OAuth 目录路径辅助函数 | - | `plugin-sdk/routing` | 路由/会话键/账户绑定辅助函数,例如 `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId` | - | `plugin-sdk/status-helpers` | 共享渠道/账户状态摘要辅助函数、运行时状态默认值以及问题元数据辅助函数 | + | `plugin-sdk/routing` | 路由/会话键/账户绑定辅助函数,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` | + | `plugin-sdk/status-helpers` | 共享渠道/账户状态摘要辅助函数、运行时状态默认值和问题元数据辅助函数 | | `plugin-sdk/target-resolver-runtime` | 共享目标解析器辅助函数 | | `plugin-sdk/string-normalization-runtime` | slug/字符串规范化辅助函数 | - | `plugin-sdk/request-url` | 从 fetch/request 类输入中提取字符串 URL | - | `plugin-sdk/run-command` | 带超时的命令运行器,返回规范化的 stdout/stderr 结果 | + | `plugin-sdk/request-url` | 从类似 fetch/request 的输入中提取字符串 URL | + | `plugin-sdk/run-command` | 带定时功能的命令运行器,返回规范化的 stdout/stderr 结果 | | `plugin-sdk/param-readers` | 通用工具/CLI 参数读取器 | - | `plugin-sdk/tool-payload` | 从工具结果对象中提取规范化载荷 | + | `plugin-sdk/tool-payload` | 从工具结果对象中提取规范化负载 | | `plugin-sdk/tool-send` | 从工具参数中提取规范的发送目标字段 | | `plugin-sdk/temp-path` | 共享临时下载路径辅助函数 | | `plugin-sdk/logging-core` | 子系统 logger 和脱敏辅助函数 | | `plugin-sdk/markdown-table-runtime` | Markdown 表格模式辅助函数 | - | `plugin-sdk/json-store` | 小型 JSON 状态读取/写入辅助函数 | + | `plugin-sdk/json-store` | 小型 JSON 状态读写辅助函数 | | `plugin-sdk/file-lock` | 可重入文件锁辅助函数 | | `plugin-sdk/persistent-dedupe` | 磁盘支持的去重缓存辅助函数 | - | `plugin-sdk/acp-runtime` | ACP 运行时/会话和 reply-dispatch 辅助函数 | - | `plugin-sdk/agent-config-primitives` | 狭义的智能体运行时配置 schema 基元 | + | `plugin-sdk/acp-runtime` | ACP 运行时/会话和回复分发辅助函数 | + | `plugin-sdk/agent-config-primitives` | 狭义的智能体运行时配置 schema 原语 | | `plugin-sdk/boolean-param` | 宽松布尔参数读取器 | | `plugin-sdk/dangerous-name-runtime` | 危险名称匹配解析辅助函数 | | `plugin-sdk/device-bootstrap` | 设备引导和配对令牌辅助函数 | - | `plugin-sdk/extension-shared` | 共享被动渠道、状态和环境代理辅助基元 | + | `plugin-sdk/extension-shared` | 共享被动渠道、状态和环境代理辅助原语 | | `plugin-sdk/models-provider-runtime` | `/models` 命令/提供商回复辅助函数 | - | `plugin-sdk/skill-commands-runtime` | Skill 命令列表辅助函数 | + | `plugin-sdk/skill-commands-runtime` | Skills 命令列表辅助函数 | | `plugin-sdk/native-command-registry` | 原生命令注册表/构建/序列化辅助函数 | - | `plugin-sdk/provider-zai-endpoint` | Z.AI endpoint 检测辅助函数 | - | `plugin-sdk/infra-runtime` | 系统事件/heartbeat 辅助函数 | + | `plugin-sdk/agent-harness` | 面向低层智能体 harness 的实验性可信插件表面:harness 类型、活动运行转向/中止辅助函数、OpenClaw 工具桥接辅助函数和尝试结果工具 | + | `plugin-sdk/provider-zai-endpoint` | Z.AI 端点检测辅助函数 | + | `plugin-sdk/infra-runtime` | 系统事件/心跳辅助函数 | | `plugin-sdk/collection-runtime` | 小型有界缓存辅助函数 | | `plugin-sdk/diagnostic-runtime` | 诊断标志和事件辅助函数 | | `plugin-sdk/error-runtime` | 错误图、格式化、共享错误分类辅助函数、`isApprovalNotFoundError` | - | `plugin-sdk/fetch-runtime` | 包装后的 fetch、代理和固定查找辅助函数 | + | `plugin-sdk/fetch-runtime` | 包装的 fetch、代理和固定查找辅助函数 | | `plugin-sdk/host-runtime` | 主机名和 SCP 主机规范化辅助函数 | - | `plugin-sdk/retry-runtime` | retry 配置和 retry 运行器辅助函数 | - | `plugin-sdk/agent-runtime` | 智能体目录/身份/workspace 辅助函数 | - | `plugin-sdk/directory-runtime` | 配置支持的目录查询/去重 | + | `plugin-sdk/retry-runtime` | 重试配置和重试运行器辅助函数 | + | `plugin-sdk/agent-runtime` | 智能体目录/身份/工作区辅助函数 | + | `plugin-sdk/directory-runtime` | 基于配置的目录查询/去重 | | `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/media-runtime` | 共享媒体抓取/转换/存储辅助函数,以及媒体载荷构建器 | - | `plugin-sdk/media-generation-runtime` | 共享媒体生成故障切换辅助函数、候选项选择和模型缺失提示 | - | `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图片/音频辅助导出 | - | `plugin-sdk/text-runtime` | 共享文本/Markdown/日志辅助函数,例如去除 assistant 可见文本、Markdown 渲染/分块/表格辅助函数、脱敏辅助函数、directive-tag 辅助函数以及安全文本工具 | + | `plugin-sdk/media-runtime` | 共享媒体获取/转换/存储辅助函数,以及媒体负载构建器 | + | `plugin-sdk/media-generation-runtime` | 共享媒体生成故障切换辅助函数、候选项选择和缺失模型消息 | + | `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像/音频辅助导出 | + | `plugin-sdk/text-runtime` | 共享文本/Markdown/日志辅助函数,例如移除助手可见文本、Markdown 渲染/分块/表格辅助函数、脱敏辅助函数、directive-tag 辅助函数和安全文本工具 | | `plugin-sdk/text-chunking` | 出站文本分块辅助函数 | - | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的 directive、注册表和校验辅助函数 | + | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的 directive、注册表和验证辅助函数 | | `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、directive 和规范化辅助函数 | | `plugin-sdk/realtime-transcription` | 实时转录提供商类型和注册表辅助函数 | | `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助函数 | @@ -238,10 +246,10 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | `plugin-sdk/music-generation-core` | 共享音乐生成类型、故障切换辅助函数、提供商查找和 model-ref 解析 | | `plugin-sdk/video-generation` | 视频生成提供商/请求/结果类型 | | `plugin-sdk/video-generation-core` | 共享视频生成类型、故障切换辅助函数、提供商查找和 model-ref 解析 | - | `plugin-sdk/webhook-targets` | webhook 目标注册表和路由安装辅助函数 | - | `plugin-sdk/webhook-path` | webhook 路径规范化辅助函数 | + | `plugin-sdk/webhook-targets` | Webhook 目标注册表和路由安装辅助函数 | + | `plugin-sdk/webhook-path` | Webhook 路径规范化辅助函数 | | `plugin-sdk/web-media` | 共享远程/本地媒体加载辅助函数 | - | `plugin-sdk/zod` | 面向插件 SDK 使用者重新导出的 `zod` | + | `plugin-sdk/zod` | 为插件 SDK 使用者重新导出的 `zod` | | `plugin-sdk/testing` | `installCommonResolveTargetErrorCases`, `shouldAckReaction` | @@ -249,91 +257,96 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/memory-core` | 内置 memory-core 辅助表面,用于 manager/config/file/CLI 辅助函数 | - | `plugin-sdk/memory-core-engine-runtime` | Memory 索引/搜索运行时外观 | - | `plugin-sdk/memory-core-host-engine-foundation` | Memory host foundation engine 导出 | - | `plugin-sdk/memory-core-host-engine-embeddings` | Memory host embedding engine 导出 | - | `plugin-sdk/memory-core-host-engine-qmd` | Memory host QMD engine 导出 | - | `plugin-sdk/memory-core-host-engine-storage` | Memory host storage engine 导出 | - | `plugin-sdk/memory-core-host-multimodal` | Memory host 多模态辅助函数 | - | `plugin-sdk/memory-core-host-query` | Memory host 查询辅助函数 | - | `plugin-sdk/memory-core-host-secret` | Memory host secret 辅助函数 | - | `plugin-sdk/memory-core-host-events` | Memory host 事件日志辅助函数 | - | `plugin-sdk/memory-core-host-status` | Memory host 状态辅助函数 | - | `plugin-sdk/memory-core-host-runtime-cli` | Memory host CLI 运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-core` | Memory host 核心运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-files` | Memory host 文件/运行时辅助函数 | - | `plugin-sdk/memory-host-core` | 面向供应商中立的 memory host 核心运行时辅助函数别名 | - | `plugin-sdk/memory-host-events` | 面向供应商中立的 memory host 事件日志辅助函数别名 | - | `plugin-sdk/memory-host-files` | 面向供应商中立的 memory host 文件/运行时辅助函数别名 | - | `plugin-sdk/memory-host-markdown` | 供 Memory 邻接插件使用的共享托管 Markdown 辅助函数 | - | `plugin-sdk/memory-host-search` | 用于访问 search-manager 的活动 Memory 运行时外观 | - | `plugin-sdk/memory-host-status` | 面向供应商中立的 memory host 状态辅助函数别名 | + | `plugin-sdk/memory-core-engine-runtime` | Memory 索引/搜索运行时门面 | + | `plugin-sdk/memory-core-host-engine-foundation` | Memory 主机基础引擎导出 | + | `plugin-sdk/memory-core-host-engine-embeddings` | Memory 主机嵌入引擎导出 | + | `plugin-sdk/memory-core-host-engine-qmd` | Memory 主机 QMD 引擎导出 | + | `plugin-sdk/memory-core-host-engine-storage` | Memory 主机存储引擎导出 | + | `plugin-sdk/memory-core-host-multimodal` | Memory 主机多模态辅助函数 | + | `plugin-sdk/memory-core-host-query` | Memory 主机查询辅助函数 | + | `plugin-sdk/memory-core-host-secret` | Memory 主机 secret 辅助函数 | + | `plugin-sdk/memory-core-host-events` | Memory 主机事件日志辅助函数 | + | `plugin-sdk/memory-core-host-status` | Memory 主机状态辅助函数 | + | `plugin-sdk/memory-core-host-runtime-cli` | Memory 主机 CLI 运行时辅助函数 | + | `plugin-sdk/memory-core-host-runtime-core` | Memory 主机核心运行时辅助函数 | + | `plugin-sdk/memory-core-host-runtime-files` | Memory 主机文件/运行时辅助函数 | + | `plugin-sdk/memory-host-core` | 面向供应商中立的 Memory 主机核心运行时辅助函数别名 | + | `plugin-sdk/memory-host-events` | 面向供应商中立的 Memory 主机事件日志辅助函数别名 | + | `plugin-sdk/memory-host-files` | 面向供应商中立的 Memory 主机文件/运行时辅助函数别名 | + | `plugin-sdk/memory-host-markdown` | 面向 Memory 邻接插件的共享托管 Markdown 辅助函数 | + | `plugin-sdk/memory-host-search` | 用于访问搜索管理器的活动 Memory 运行时门面 | + | `plugin-sdk/memory-host-status` | 面向供应商中立的 Memory 主机状态辅助函数别名 | | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助表面 | - | 家族 | 当前子路径 | 预期用途 | + | 系列 | 当前子路径 | 预期用途 | | --- | --- | --- | | Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | 内置 Browser 插件支持辅助函数(`browser-support` 仍是兼容性 barrel) | | Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | 内置 Matrix 辅助/运行时表面 | | Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | 内置 LINE 辅助/运行时表面 | | IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | 内置 IRC 辅助表面 | - | 渠道特定辅助函数 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 内置渠道兼容性/辅助接缝 | - | 认证/插件特定辅助函数 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 内置功能/插件辅助接缝;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`, `deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` | + | 特定于渠道的辅助函数 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 内置渠道兼容性/辅助接缝 | + | 认证/特定于插件的辅助函数 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 内置功能/插件辅助接缝;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` | ## 注册 API -`register(api)` 回调会收到一个带有以下方法的 `OpenClawPluginApi` 对象: +`register(api)` 回调会收到一个 `OpenClawPluginApi` 对象,其中包含这些 +方法: ### 能力注册 -| 方法 | 注册内容 | -| ------------------------------------------------ | ------------------------ | -| `api.registerProvider(...)` | 文本推理(LLM) | -| `api.registerCliBackend(...)` | 本地 CLI 推理后端 | -| `api.registerChannel(...)` | 消息渠道 | -| `api.registerSpeechProvider(...)` | 文本转语音 / STT 合成 | -| `api.registerRealtimeTranscriptionProvider(...)` | 流式实时转录 | -| `api.registerRealtimeVoiceProvider(...)` | 双工实时语音会话 | -| `api.registerMediaUnderstandingProvider(...)` | 图像/音频/视频分析 | -| `api.registerImageGenerationProvider(...)` | 图像生成 | -| `api.registerMusicGenerationProvider(...)` | 音乐生成 | -| `api.registerVideoGenerationProvider(...)` | 视频生成 | -| `api.registerWebFetchProvider(...)` | Web 抓取 / 爬取提供商 | -| `api.registerWebSearchProvider(...)` | Web 搜索 | +| 方法 | 注册内容 | +| ------------------------------------------------ | ------------------------------------- | +| `api.registerProvider(...)` | 文本推理(LLM) | +| `api.registerAgentHarness(...)` | 实验性的低层智能体执行器 | +| `api.registerCliBackend(...)` | 本地 CLI 推理后端 | +| `api.registerChannel(...)` | 消息渠道 | +| `api.registerSpeechProvider(...)` | 文本转语音 / STT 合成 | +| `api.registerRealtimeTranscriptionProvider(...)` | 流式实时转录 | +| `api.registerRealtimeVoiceProvider(...)` | 双工实时语音会话 | +| `api.registerMediaUnderstandingProvider(...)` | 图像/音频/视频分析 | +| `api.registerImageGenerationProvider(...)` | 图像生成 | +| `api.registerMusicGenerationProvider(...)` | 音乐生成 | +| `api.registerVideoGenerationProvider(...)` | 视频生成 | +| `api.registerWebFetchProvider(...)` | Web 获取 / 抓取提供商 | +| `api.registerWebSearchProvider(...)` | Web 搜索 | ### 工具和命令 -| 方法 | 注册内容 | +| 方法 | 注册内容 | | ------------------------------- | --------------------------------------------- | | `api.registerTool(tool, opts?)` | 智能体工具(必需或 `{ optional: true }`) | -| `api.registerCommand(def)` | 自定义命令(绕过 LLM) | +| `api.registerCommand(def)` | 自定义命令(绕过 LLM) | ### 基础设施 -| 方法 | 注册内容 | -| ---------------------------------------------- | -------------------------------- | -| `api.registerHook(events, handler, opts?)` | 事件 hook | -| `api.registerHttpRoute(params)` | Gateway 网关 HTTP endpoint | -| `api.registerGatewayMethod(name, handler)` | Gateway 网关 RPC 方法 | -| `api.registerCli(registrar, opts?)` | CLI 子命令 | -| `api.registerService(service)` | 后台服务 | -| `api.registerInteractiveHandler(registration)` | 交互处理器 | -| `api.registerMemoryPromptSupplement(builder)` | 增量 Memory 邻接提示区段 | -| `api.registerMemoryCorpusSupplement(adapter)` | 增量 Memory 搜索/读取语料库 | +| 方法 | 注册内容 | +| ---------------------------------------------- | --------------------------------------- | +| `api.registerHook(events, handler, opts?)` | 事件 hook | +| `api.registerHttpRoute(params)` | Gateway 网关 HTTP 端点 | +| `api.registerGatewayMethod(name, handler)` | Gateway 网关 RPC 方法 | +| `api.registerCli(registrar, opts?)` | CLI 子命令 | +| `api.registerService(service)` | 后台服务 | +| `api.registerInteractiveHandler(registration)` | 交互式处理器 | +| `api.registerMemoryPromptSupplement(builder)` | 附加的 Memory 邻接提示词部分 | +| `api.registerMemoryCorpusSupplement(adapter)` | 附加的 Memory 搜索/读取语料库 | -保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终保持为 `operator.admin`,即使插件尝试分配更窄的 Gateway 网关方法作用域也是如此。对于插件自有方法,优先使用插件特定前缀。 +保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、 +`update.*`)始终保持为 `operator.admin`,即使插件尝试分配更窄的 +Gateway 网关方法作用域也是如此。对于插件自有的方法,优先使用插件特定的前缀。 ### CLI 注册元数据 `api.registerCli(registrar, opts?)` 接受两类顶层元数据: - `commands`:由注册器拥有的显式命令根 -- `descriptors`:用于根 CLI 帮助、路由和惰性插件 CLI 注册的解析期命令描述符 +- `descriptors`:用于根 CLI 帮助、路由和惰性插件 CLI 注册的解析时命令描述符 -如果你希望插件命令在常规根 CLI 路径中保持惰性加载,请提供 `descriptors`,覆盖该注册器暴露的每个顶层命令根。 +如果你希望插件命令在正常的根 CLI 路径中保持惰性加载, +请提供 `descriptors`,覆盖该注册器暴露的每个顶层命令根。 ```typescript api.registerCli( @@ -345,7 +358,7 @@ api.registerCli( descriptors: [ { name: "matrix", - description: "Manage Matrix accounts, verification, devices, and profile state", + description: "管理 Matrix 账户、验证、设备和配置文件状态", hasSubcommands: true, }, ], @@ -353,72 +366,85 @@ api.registerCli( ); ``` -仅在你不需要惰性根 CLI 注册时,才单独使用 `commands`。这种急切兼容路径仍受支持,但它不会安装由 descriptor 支持的占位符来实现解析期惰性加载。 +仅在你不需要惰性根 CLI 注册时单独使用 `commands`。 +这种急切兼容路径仍受支持,但它不会为解析时惰性加载安装 +由描述符支持的占位符。 ### CLI 后端注册 -`api.registerCliBackend(...)` 允许插件拥有本地 AI CLI 后端(例如 `codex-cli`)的默认配置。 +`api.registerCliBackend(...)` 让插件拥有本地 +AI CLI 后端(例如 `codex-cli`)的默认配置。 - 后端 `id` 会成为模型引用中的提供商前缀,例如 `codex-cli/gpt-5`。 - 后端 `config` 使用与 `agents.defaults.cliBackends.` 相同的结构。 -- 用户配置仍然优先。OpenClaw 会在运行 CLI 之前,将 `agents.defaults.cliBackends.` 合并到插件默认值之上。 -- 当某个后端在合并后需要兼容性重写时,使用 `normalizeConfig`(例如规范化旧 flag 结构)。 +- 用户配置仍然优先。OpenClaw 会在运行 CLI 之前,将 `agents.defaults.cliBackends.` 合并到 + 插件默认值之上。 +- 当某个后端在合并后需要兼容性重写时,请使用 `normalizeConfig` + (例如规范化旧的 flag 结构)。 ### 独占槽位 -| 方法 | 注册内容 | -| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| `api.registerContextEngine(id, factory)` | 上下文引擎(一次仅激活一个)。`assemble()` 回调会收到 `availableTools` 和 `citationsMode`,以便引擎可定制提示补充内容。 | -| `api.registerMemoryCapability(capability)` | 统一 Memory 能力 | -| `api.registerMemoryPromptSection(builder)` | Memory 提示区段构建器 | -| `api.registerMemoryFlushPlan(resolver)` | Memory flush plan 解析器 | -| `api.registerMemoryRuntime(runtime)` | Memory 运行时适配器 | +| 方法 | 注册内容 | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `api.registerContextEngine(id, factory)` | 上下文引擎(一次仅一个处于活动状态)。`assemble()` 回调会收到 `availableTools` 和 `citationsMode`,以便该引擎定制提示词附加内容。 | +| `api.registerMemoryCapability(capability)` | 统一 Memory 能力 | +| `api.registerMemoryPromptSection(builder)` | Memory 提示词部分构建器 | +| `api.registerMemoryFlushPlan(resolver)` | Memory 刷新计划解析器 | +| `api.registerMemoryRuntime(runtime)` | Memory 运行时适配器 | -### Memory embedding 适配器 +### Memory 嵌入适配器 -| 方法 | 注册内容 | -| ---------------------------------------------- | ----------------------------------------- | -| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的 Memory embedding 适配器 | +| 方法 | 注册内容 | +| ---------------------------------------------- | ---------------------------------------------- | +| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的 Memory 嵌入适配器 | - `registerMemoryCapability` 是首选的独占 Memory 插件 API。 -- `registerMemoryCapability` 还可以暴露 `publicArtifacts.listArtifacts(...)`,以便配套插件可以通过 `openclaw/plugin-sdk/memory-host-core` 使用导出的 Memory 工件,而不是深入访问特定 Memory 插件的私有布局。 -- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和 `registerMemoryRuntime` 是兼容旧版的独占 Memory 插件 API。 -- `registerMemoryEmbeddingProvider` 允许活动 Memory 插件注册一个或多个 embedding 适配器 id(例如 `openai`、`gemini` 或自定义插件定义的 id)。 -- 用户配置(例如 `agents.defaults.memorySearch.provider` 和 `agents.defaults.memorySearch.fallback`)会根据这些已注册的适配器 id 进行解析。 +- `registerMemoryCapability` 还可以公开 `publicArtifacts.listArtifacts(...)` + ,以便配套插件通过 + `openclaw/plugin-sdk/memory-host-core` 使用已导出的 Memory 制品,而不是深入特定 + Memory 插件的私有布局。 +- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和 + `registerMemoryRuntime` 是兼容旧版的独占 Memory 插件 API。 +- `registerMemoryEmbeddingProvider` 允许活动的 Memory 插件注册一个 + 或多个嵌入适配器 ID(例如 `openai`、`gemini` 或自定义 + 插件定义的 ID)。 +- 用户配置,例如 `agents.defaults.memorySearch.provider` 和 + `agents.defaults.memorySearch.fallback`,会针对这些已注册的 + 适配器 ID 进行解析。 -### 事件与生命周期 +### 事件和生命周期 -| 方法 | 作用 | -| -------------------------------------------- | ----------------------- | -| `api.on(hookName, handler, opts?)` | 类型化生命周期 hook | -| `api.onConversationBindingResolved(handler)` | 会话绑定回调 | +| 方法 | 作用 | +| -------------------------------------------- | ----------------------------- | +| `api.on(hookName, handler, opts?)` | 类型化生命周期 hook | +| `api.onConversationBindingResolved(handler)` | 会话绑定回调 | ### Hook 决策语义 -- `before_tool_call`:返回 `{ block: true }` 为终止性决定。一旦任一处理器设置它,就会跳过优先级更低的处理器。 -- `before_tool_call`:返回 `{ block: false }` 会被视为未作决定(与省略 `block` 相同),而不是覆盖。 -- `before_install`:返回 `{ block: true }` 为终止性决定。一旦任一处理器设置它,就会跳过优先级更低的处理器。 -- `before_install`:返回 `{ block: false }` 会被视为未作决定(与省略 `block` 相同),而不是覆盖。 -- `reply_dispatch`:返回 `{ handled: true, ... }` 为终止性决定。一旦任一处理器声明已分发,就会跳过优先级更低的处理器以及默认模型分发路径。 -- `message_sending`:返回 `{ cancel: true }` 为终止性决定。一旦任一处理器设置它,就会跳过优先级更低的处理器。 -- `message_sending`:返回 `{ cancel: false }` 会被视为未作决定(与省略 `cancel` 相同),而不是覆盖。 +- `before_tool_call`:返回 `{ block: true }` 为终局决定。一旦任一处理器设置了它,就会跳过更低优先级的处理器。 +- `before_tool_call`:返回 `{ block: false }` 会被视为无决定(与省略 `block` 相同),而不是覆盖。 +- `before_install`:返回 `{ block: true }` 为终局决定。一旦任一处理器设置了它,就会跳过更低优先级的处理器。 +- `before_install`:返回 `{ block: false }` 会被视为无决定(与省略 `block` 相同),而不是覆盖。 +- `reply_dispatch`:返回 `{ handled: true, ... }` 为终局决定。一旦任一处理器声明已分发,就会跳过更低优先级的处理器和默认模型分发路径。 +- `message_sending`:返回 `{ cancel: true }` 为终局决定。一旦任一处理器设置了它,就会跳过更低优先级的处理器。 +- `message_sending`:返回 `{ cancel: false }` 会被视为无决定(与省略 `cancel` 相同),而不是覆盖。 ### API 对象字段 -| 字段 | 类型 | 说明 | -| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------ | -| `api.id` | `string` | 插件 id | -| `api.name` | `string` | 显示名称 | -| `api.version` | `string?` | 插件版本(可选) | -| `api.description` | `string?` | 插件说明(可选) | -| `api.source` | `string` | 插件源路径 | -| `api.rootDir` | `string?` | 插件根目录(可选) | -| `api.config` | `OpenClawConfig` | 当前配置快照(可用时为活动的内存运行时快照) | -| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件专属配置 | -| `api.runtime` | `PluginRuntime` | [运行时辅助函数](/zh-CN/plugins/sdk-runtime) | -| `api.logger` | `PluginLogger` | 作用域 logger(`debug`, `info`, `warn`, `error`) | -| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置前的轻量级预启动/设置窗口 | -| `api.resolvePath(input)` | `(string) => string` | 相对于插件根目录解析路径 | +| 字段 | 类型 | 描述 | +| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------- | +| `api.id` | `string` | 插件 ID | +| `api.name` | `string` | 显示名称 | +| `api.version` | `string?` | 插件版本(可选) | +| `api.description` | `string?` | 插件描述(可选) | +| `api.source` | `string` | 插件源路径 | +| `api.rootDir` | `string?` | 插件根目录(可选) | +| `api.config` | `OpenClawConfig` | 当前配置快照(如果可用,则为活动的内存中运行时快照) | +| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件特定配置 | +| `api.runtime` | `PluginRuntime` | [运行时辅助函数](/zh-CN/plugins/sdk-runtime) | +| `api.logger` | `PluginLogger` | 有作用域的 logger(`debug`、`info`、`warn`、`error`) | +| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置之前的轻量级窗口 | +| `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 | ## 内部模块约定 @@ -429,23 +455,30 @@ my-plugin/ api.ts # 面向外部使用者的公共导出 runtime-api.ts # 仅供内部使用的运行时导出 index.ts # 插件入口点 - setup-entry.ts # 轻量级仅设置入口(可选) + setup-entry.ts # 仅用于轻量级设置的入口点(可选) ``` - 永远不要在生产代码中通过 `openclaw/plugin-sdk/` + 不要在生产代码中通过 `openclaw/plugin-sdk/` 导入你自己的插件。请通过 `./api.ts` 或 - `./runtime-api.ts` 进行内部导入。SDK 路径仅是对外契约。 + `./runtime-api.ts` 进行内部导入。SDK 路径仅是外部契约。 -门面加载的内置插件公共表面(`api.ts`、`runtime-api.ts`、`index.ts`、`setup-entry.ts` 以及类似公共入口文件)现在会在 OpenClaw 已运行时优先使用活动运行时配置快照。如果尚不存在运行时快照,则会回退到磁盘上已解析的配置文件。 +通过门面加载的内置插件公共表面(`api.ts`、`runtime-api.ts`、 +`index.ts`、`setup-entry.ts` 以及类似的公共入口文件)现在会在 OpenClaw 已运行时优先使用 +活动的运行时配置快照。如果运行时快照尚不存在,则会回退到磁盘上已解析的配置文件。 -当某个辅助函数有意是提供商专属且暂时不属于通用 SDK 子路径时,提供商插件也可以暴露一个狭义的插件本地契约 barrel。当前内置示例:Anthropic 提供商将其 Claude 流辅助函数保留在自己的公共 `api.ts` / `contract-api.ts` 接缝中,而不是将 Anthropic beta-header 和 `service_tier` 逻辑提升到通用 `plugin-sdk/*` 契约中。 +当某个辅助函数明确是提供商特定的、且暂时还不属于通用 SDK +子路径时,提供商插件也可以公开一个狭义的插件本地契约 barrel。当前内置示例:Anthropic 提供商将其 Claude +流辅助函数保留在自己的公共 `api.ts` / `contract-api.ts` 接缝中,而不是将 Anthropic beta-header 和 `service_tier` 逻辑提升为通用 +`plugin-sdk/*` 契约。 -其他当前内置示例: +其他当前的内置示例: -- `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、默认模型辅助函数和实时提供商构建器 -- `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及新手引导/配置辅助函数 +- `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、 + 默认模型辅助函数和实时提供商构建器 +- `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及 + 新手引导/配置辅助函数 扩展生产代码也应避免导入 `openclaw/plugin-sdk/`。 @@ -458,7 +491,7 @@ my-plugin/ - [入口点](/zh-CN/plugins/sdk-entrypoints) — `definePluginEntry` 和 `defineChannelPluginEntry` 选项 - [运行时辅助函数](/zh-CN/plugins/sdk-runtime) — 完整的 `api.runtime` 命名空间参考 -- [设置和配置](/zh-CN/plugins/sdk-setup) — 打包、清单、配置 schema +- [设置和配置](/zh-CN/plugins/sdk-setup) — 打包、manifest、配置 schema - [测试](/zh-CN/plugins/sdk-testing) — 测试工具和 lint 规则 - [SDK 迁移](/zh-CN/plugins/sdk-migration) — 从已弃用表面迁移 -- [插件内部机制](/zh-CN/plugins/architecture) — 深入架构和能力模型 +- [插件内部机制](/zh-CN/plugins/architecture) — 深入的架构和能力模型 diff --git a/docs/zh-CN/plugins/sdk-provider-plugins.md b/docs/zh-CN/plugins/sdk-provider-plugins.md index 3f42f57a7..f553cc81a 100644 --- a/docs/zh-CN/plugins/sdk-provider-plugins.md +++ b/docs/zh-CN/plugins/sdk-provider-plugins.md @@ -1,30 +1,32 @@ --- read_when: - 你正在构建一个新的模型提供商插件 - - 你想为 OpenClaw 添加一个兼容 OpenAI 的代理或自定义 LLM - - 你需要了解提供商凭证、目录和运行时 hooks + - 你想将兼容 OpenAI 的代理或自定义 LLM 添加到 OpenClaw 中 + - 你需要理解提供商凭证、目录和运行时钩子 sidebarTitle: Provider Plugins summary: 为 OpenClaw 构建模型提供商插件的分步指南 title: 构建提供商插件 x-i18n: - generated_at: "2026-04-08T18:08:50Z" + generated_at: "2026-04-10T20:23:44Z" model: gpt-5.4 provider: openai - source_hash: 38d9af522dc19e49c81203a83a4096f01c2398b1df771c848a30ad98f251e9e1 + source_hash: b81b80627fd594e2dc889c95359df665ebbbb85c74c231a226219dcb556f193b source_path: plugins/sdk-provider-plugins.md workflow: 15 --- # 构建提供商插件 -本指南将带你构建一个提供商插件,为 OpenClaw 添加一个模型提供商 -(LLM)。完成后,你将拥有一个带有模型目录、API 密钥凭证和动态模型解析的提供商。 +本指南将带你构建一个为 OpenClaw 添加模型提供商(LLM)的提供商插件。完成后,你将拥有一个包含模型目录、API 密钥凭证以及动态模型解析的提供商。 - 如果你之前还没有构建过任何 OpenClaw 插件,请先阅读 - [入门指南](/zh-CN/plugins/building-plugins),了解基础包结构和清单设置。 + 如果你之前没有构建过任何 OpenClaw 插件,请先阅读 [入门指南](/zh-CN/plugins/building-plugins),了解基础包结构和清单设置。 + + 提供商插件会将模型添加到 OpenClaw 的常规推理循环中。如果模型必须通过一个拥有线程、压缩或工具事件的原生智能体守护进程运行,请将该提供商与 [agent harness](/zh-CN/plugins/sdk-agent-harness) 搭配使用,而不是把守护进程协议细节放进核心中。 + + ## 演练 @@ -55,7 +57,7 @@ x-i18n: { "id": "acme-ai", "name": "Acme AI", - "description": "Acme AI model provider", + "description": "Acme AI 模型提供商", "providers": ["acme-ai"], "modelSupport": { "modelPrefixes": ["acme-"] @@ -71,12 +73,12 @@ x-i18n: "provider": "acme-ai", "method": "api-key", "choiceId": "acme-ai-api-key", - "choiceLabel": "Acme AI API key", + "choiceLabel": "Acme AI API 密钥", "groupId": "acme-ai", "groupLabel": "Acme AI", "cliFlag": "--acme-ai-api-key", "cliOption": "--acme-ai-api-key ", - "cliDescription": "Acme AI API key" + "cliDescription": "Acme AI API 密钥" } ], "configSchema": { @@ -87,12 +89,7 @@ x-i18n: ``` - 清单声明了 `providerAuthEnvVars`,这样 OpenClaw 无需加载你的插件运行时, - 就能检测凭证。当某个提供商变体应复用另一个提供商 id 的凭证时,添加 `providerAuthAliases`。 - `modelSupport` 是可选的,它允许 OpenClaw 在运行时 hooks 存在之前, - 通过像 `acme-large` 这样的简写模型 id 自动加载你的提供商插件。如果你要在 - ClawHub 上发布该提供商,那么 `package.json` 中的这些 `openclaw.compat` 和 - `openclaw.build` 字段是必需的。 + 清单声明了 `providerAuthEnvVars`,这样 OpenClaw 无需加载你的插件运行时就能检测凭证。当某个提供商变体应复用另一个提供商 id 的凭证时,请添加 `providerAuthAliases`。`modelSupport` 是可选的,它允许 OpenClaw 在运行时钩子存在之前,先根据类似 `acme-large` 这样的简写模型 id 自动加载你的提供商插件。如果你要在 ClawHub 上发布该提供商,那么 `package.json` 中的这些 `openclaw.compat` 和 `openclaw.build` 字段是必需的。 @@ -168,12 +165,9 @@ x-i18n: }); ``` - 这就是一个可用的提供商。用户现在可以 - `openclaw onboard --acme-ai-api-key ` 并选择 - `acme-ai/acme-large` 作为他们的模型。 + 这样就得到一个可工作的提供商了。用户现在可以运行 `openclaw onboard --acme-ai-api-key ` 并选择 `acme-ai/acme-large` 作为他们的模型。 - 对于仅注册一个文本提供商、使用 API 密钥凭证并带有单个基于目录的运行时的内置提供商, - 优先使用更窄的 `defineSingleProviderPluginEntry(...)` 辅助函数: + 对于只注册一个文本提供商、使用 API 密钥凭证,并且只有一个基于目录的运行时的内置提供商,优先使用更窄的 `defineSingleProviderPluginEntry(...)` 辅助函数: ```typescript import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry"; @@ -208,24 +202,14 @@ x-i18n: }); ``` - 如果你的凭证流程还需要在新手引导期间修补 `models.providers.*`、别名以及 - 智能体默认模型,请使用 `openclaw/plugin-sdk/provider-onboard` 中的预设辅助函数。 - 最窄的辅助函数包括 - `createDefaultModelPresetAppliers(...)`、 - `createDefaultModelsPresetAppliers(...)` 和 - `createModelCatalogPresetAppliers(...)`。 + 如果你的凭证流程还需要在新手引导期间修补 `models.providers.*`、别名以及智能体默认模型,请使用 `openclaw/plugin-sdk/provider-onboard` 中的预设辅助函数。最窄的辅助函数包括 `createDefaultModelPresetAppliers(...)`、`createDefaultModelsPresetAppliers(...)` 和 `createModelCatalogPresetAppliers(...)`。 - 当某个提供商的原生端点在正常的 `openai-completions` 传输协议上支持流式 usage blocks 时, - 优先使用 `openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录辅助函数, - 而不是硬编码 provider-id 检查。`supportsNativeStreamingUsageCompat(...)` 和 - `applyProviderNativeStreamingUsageCompat(...)` 会根据端点能力映射检测支持情况, - 因此即使插件使用了自定义 provider id,原生 Moonshot/DashScope 风格的端点仍可选择启用。 + 当某个提供商的原生端点在常规 `openai-completions` 传输协议上支持分块流式传输使用量块时,优先使用 `openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录辅助函数,而不是硬编码提供商 id 检查。`supportsNativeStreamingUsageCompat(...)` 和 `applyProviderNativeStreamingUsageCompat(...)` 会根据端点能力映射检测支持情况,因此即使插件使用的是自定义提供商 id,原生 Moonshot/DashScope 风格端点仍然可以选择启用。 - 如果你的提供商接受任意模型 ID(例如代理或路由器), - 请添加 `resolveDynamicModel`: + 如果你的提供商接受任意模型 id(例如代理或路由器),请添加 `resolveDynamicModel`: ```typescript api.registerProvider({ @@ -246,17 +230,14 @@ x-i18n: }); ``` - 如果解析需要网络调用,请使用 `prepareDynamicModel` 进行异步预热 — - 完成后会再次运行 `resolveDynamicModel`。 + 如果解析需要网络调用,请使用 `prepareDynamicModel` 进行异步预热 —— 完成后会再次运行 `resolveDynamicModel`。 - - 大多数提供商只需要 `catalog` + `resolveDynamicModel`。随着你的提供商需求增加, - 再逐步添加 hooks。 + + 大多数提供商只需要 `catalog` + `resolveDynamicModel`。随着你的提供商提出更高要求,再逐步添加钩子。 - 共享辅助构建器现在已经覆盖最常见的 replay/tool-compat 系列, - 因此插件通常不需要手动逐个接线每个 hook: + 共享辅助构建器现在已覆盖最常见的重放/工具兼容性系列,因此插件通常不需要手动逐个连接每个钩子: ```typescript import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; @@ -276,15 +257,15 @@ x-i18n: }); ``` - 当前可用的 replay 系列: + 当前可用的重放系列: - | Family | 它会接入什么 | + | 系列 | 它会接入的内容 | | --- | --- | - | `openai-compatible` | 用于兼容 OpenAI 传输协议的共享 OpenAI 风格 replay 策略,包括 tool-call-id 清理、assistant-first 顺序修复,以及传输协议需要时的通用 Gemini 轮次校验 | - | `anthropic-by-model` | 基于 `modelId` 选择的 Claude 感知 replay 策略,因此只有当解析出的模型实际是 Claude id 时,Anthropic-message 传输协议才会获得 Claude 专用的 thinking block 清理 | - | `google-gemini` | 原生 Gemini replay 策略,外加 bootstrap replay 清理和带标签的 reasoning-output 模式 | - | `passthrough-gemini` | 用于通过兼容 OpenAI 的代理传输协议运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini replay 校验或 bootstrap 重写 | - | `hybrid-anthropic-openai` | 适用于在一个插件中混合 Anthropic-message 和兼容 OpenAI 模型表面的提供商的混合策略;可选的仅 Claude thinking block 丢弃会保持限定在 Anthropic 一侧 | + | `openai-compatible` | OpenAI 兼容传输协议的共享 OpenAI 风格重放策略,包括工具调用 id 清理、assistant-first 顺序修复,以及传输协议需要时的通用 Gemini 轮次校验 | + | `anthropic-by-model` | 按 `modelId` 选择的 Claude 感知重放策略,因此 Anthropic 消息传输协议只会在解析出的模型确实是 Claude id 时,才获得 Claude 专用的思维块清理 | + | `google-gemini` | 原生 Gemini 重放策略,加上引导重放清理和带标签的推理输出模式 | + | `passthrough-gemini` | 用于通过 OpenAI 兼容代理传输协议运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini 重放校验或引导重写 | + | `hybrid-anthropic-openai` | 适用于在一个插件中混合 Anthropic 消息和 OpenAI 兼容模型面的提供商的混合策略;可选的仅 Claude 思维块丢弃仍然只作用于 Anthropic 一侧 | 真实的内置示例: @@ -296,15 +277,15 @@ x-i18n: 当前可用的流式系列: - | Family | 它会接入什么 | + | 系列 | 它会接入的内容 | | --- | --- | | `google-thinking` | 共享流路径上的 Gemini thinking 负载规范化 | - | `kilocode-thinking` | 共享代理流路径上的 Kilo reasoning 包装器,其中 `kilo/auto` 和不支持的代理 reasoning id 会跳过注入的 thinking | - | `moonshot-thinking` | 基于配置和 `/think` 级别的 Moonshot 二进制原生 thinking 负载映射 | - | `minimax-fast-mode` | 共享流路径上的 MiniMax 快速模式模型重写 | - | `openai-responses-defaults` | 共享的原生 OpenAI/Codex Responses 包装器:归属标头、`/fast`/`serviceTier`、文本详细程度、原生 Codex web search、reasoning-compat 负载整形,以及 Responses 上下文管理 | - | `openrouter-thinking` | OpenRouter 的代理路由 reasoning 包装器,集中处理不支持模型和 `auto` 跳过 | - | `tool-stream-default-on` | 为像 Z.AI 这类希望默认启用工具流式传输的提供商提供默认开启的 `tool_stream` 包装器,除非显式禁用 | + | `kilocode-thinking` | 共享代理流路径上的 Kilo 推理包装器,其中 `kilo/auto` 和不受支持的代理推理 id 会跳过注入的 thinking | + | `moonshot-thinking` | 根据配置和 `/think` 级别,将 Moonshot 二进制原生 thinking 负载进行映射 | + | `minimax-fast-mode` | 共享流路径上的 MiniMax fast-mode 模型重写 | + | `openai-responses-defaults` | 共享原生 OpenAI/Codex Responses 包装器:归因头、`/fast`/`serviceTier`、文本冗长度、原生 Codex web search、推理兼容负载整形,以及 Responses 上下文管理 | + | `openrouter-thinking` | 用于代理路由的 OpenRouter 推理包装器,集中处理不受支持模型和 `auto` 跳过逻辑 | + | `tool-stream-default-on` | 为像 Z.AI 这样希望默认启用工具流式传输的提供商提供默认开启的 `tool_stream` 包装器,除非显式禁用 | 真实的内置示例: @@ -316,71 +297,40 @@ x-i18n: - `openrouter`:`openrouter-thinking` - `zai`:`tool-stream-default-on` - `openclaw/plugin-sdk/provider-model-shared` 还导出了 replay-family - 枚举,以及这些系列构建所使用的共享辅助函数。常见的公共导出包括: + `openclaw/plugin-sdk/provider-model-shared` 也导出了 replay-family 枚举,以及这些系列所基于的共享辅助函数。常见的公共导出包括: - `ProviderReplayFamily` - `buildProviderReplayFamilyHooks(...)` - - 共享 replay 构建器,例如 `buildOpenAICompatibleReplayPolicy(...)`、 - `buildAnthropicReplayPolicyForModel(...)`、 - `buildGoogleGeminiReplayPolicy(...)` 和 - `buildHybridAnthropicOrOpenAIReplayPolicy(...)` - - Gemini replay 辅助函数,例如 `sanitizeGoogleGeminiReplayHistory(...)` - 和 `resolveTaggedReasoningOutputMode()` - - 端点/模型辅助函数,例如 `resolveProviderEndpoint(...)`、 - `normalizeProviderId(...)`、`normalizeGooglePreviewModelId(...)` 和 - `normalizeNativeXaiModelId(...)` + - 共享重放构建器,例如 `buildOpenAICompatibleReplayPolicy(...)`、`buildAnthropicReplayPolicyForModel(...)`、`buildGoogleGeminiReplayPolicy(...)` 和 `buildHybridAnthropicOrOpenAIReplayPolicy(...)` + - Gemini 重放辅助函数,例如 `sanitizeGoogleGeminiReplayHistory(...)` 和 `resolveTaggedReasoningOutputMode()` + - 端点/模型辅助函数,例如 `resolveProviderEndpoint(...)`、`normalizeProviderId(...)`、`normalizeGooglePreviewModelId(...)` 和 `normalizeNativeXaiModelId(...)` - `openclaw/plugin-sdk/provider-stream` 同时暴露了 family 构建器和这些 family - 复用的公共包装器辅助函数。常见的公共导出包括: + `openclaw/plugin-sdk/provider-stream` 同时公开了系列构建器以及这些系列复用的公共包装辅助函数。常见的公共导出包括: - `ProviderStreamFamily` - `buildProviderStreamFamilyHooks(...)` - `composeProviderStreamWrappers(...)` - - 共享的 OpenAI/Codex 包装器,例如 - `createOpenAIAttributionHeadersWrapper(...)`、 - `createOpenAIFastModeWrapper(...)`、 - `createOpenAIServiceTierWrapper(...)`、 - `createOpenAIResponsesContextManagementWrapper(...)` 和 - `createCodexNativeWebSearchWrapper(...)` - - 共享的代理/提供商包装器,例如 `createOpenRouterWrapper(...)`、 - `createToolStreamWrapper(...)` 和 `createMinimaxFastModeWrapper(...)` + - 共享的 OpenAI/Codex 包装器,例如 `createOpenAIAttributionHeadersWrapper(...)`、`createOpenAIFastModeWrapper(...)`、`createOpenAIServiceTierWrapper(...)`、`createOpenAIResponsesContextManagementWrapper(...)` 和 `createCodexNativeWebSearchWrapper(...)` + - 共享代理/提供商包装器,例如 `createOpenRouterWrapper(...)`、`createToolStreamWrapper(...)` 和 `createMinimaxFastModeWrapper(...)` - 某些流式辅助函数会有意保持为提供商本地。当前的内置 - 示例:`@openclaw/anthropic-provider` 导出了 - `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 - `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`,以及 - 更底层的 Anthropic 包装器构建器,来自其公共 `api.ts` / - `contract-api.ts` 接口。这些辅助函数之所以保持为 Anthropic 专用, - 是因为它们还编码了 Claude OAuth beta 处理和 `context1m` gating。 + 有些流式辅助函数会有意保持为提供商本地实现。当前的内置示例:`@openclaw/anthropic-provider` 从其公共 `api.ts` / `contract-api.ts` 接缝导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`,以及更底层的 Anthropic 包装器构建器。这些辅助函数仍然保持为 Anthropic 专用,因为它们还编码了 Claude OAuth beta 处理和 `context1m` 门控。 - 其他内置提供商在行为无法跨系列清晰共享时,也会将特定传输协议的包装器保留为本地。 - 当前示例:内置的 xAI 插件将原生 xAI Responses 整形保留在自己的 - `wrapStreamFn` 中,包括 `/fast` 别名重写、默认 `tool_stream`、 - 对不支持的 strict-tool 的清理,以及移除 xAI 专用的 reasoning 负载。 + 其他内置提供商也会在行为无法在系列之间清晰共享时,将传输协议专用包装器保留为本地实现。当前示例:内置的 xAI 插件将原生 xAI Responses 整形保留在它自己的 `wrapStreamFn` 中,其中包括 `/fast` 别名重写、默认 `tool_stream`、不受支持的 strict-tool 清理,以及 xAI 专用的 reasoning-payload 移除。 - `openclaw/plugin-sdk/provider-tools` 当前暴露了一个共享的 - 工具 schema 系列以及共享 schema/兼容性辅助函数: + `openclaw/plugin-sdk/provider-tools` 当前公开了一个共享工具模式系列,以及共享模式/兼容性辅助函数: - - `ProviderToolCompatFamily` 记录了当前共享 family 的清单。 - - `buildProviderToolCompatFamilyHooks("gemini")` 为需要 Gemini 安全工具 schema 的提供商接入 Gemini schema 清理 + 诊断。 - - `normalizeGeminiToolSchemas(...)` 和 `inspectGeminiToolSchemas(...)` - 是底层的公共 Gemini schema 辅助函数。 - - `resolveXaiModelCompatPatch()` 返回内置的 xAI compat patch: - `toolSchemaProfile: "xai"`、不支持的 schema 关键字、原生 - `web_search` 支持,以及对 HTML 实体 tool-call 参数的解码。 - - `applyXaiModelCompat(model)` 会在模型到达运行器之前,对已解析模型应用同一个 xAI compat patch。 + - `ProviderToolCompatFamily` 记录了当前共享系列清单。 + - `buildProviderToolCompatFamilyHooks("gemini")` 会为需要 Gemini 安全工具模式的提供商接入 Gemini 模式清理和诊断。 + - `normalizeGeminiToolSchemas(...)` 和 `inspectGeminiToolSchemas(...)` 是底层的公共 Gemini 模式辅助函数。 + - `resolveXaiModelCompatPatch()` 返回内置的 xAI 兼容性补丁:`toolSchemaProfile: "xai"`、不受支持的模式关键字、原生 `web_search` 支持,以及 HTML 实体工具调用参数解码。 + - `applyXaiModelCompat(model)` 会在解析出的模型到达运行器之前,将同样的 xAI 兼容性补丁应用到该模型上。 - 真实的内置示例:xAI 插件使用 `normalizeResolvedModel` 加上 - `contributeResolvedModelCompat`,让这些兼容性元数据保持由提供商拥有, - 而不是在核心中硬编码 xAI 规则。 + 真实的内置示例:xAI 插件使用 `normalizeResolvedModel` 加上 `contributeResolvedModelCompat`,以便让该兼容性元数据由提供商自己维护,而不是在核心中硬编码 xAI 规则。 同样的包根模式也支撑着其他内置提供商: - - `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、 - 默认模型辅助函数,以及 realtime 提供商构建器 - - `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器, - 以及新手引导/配置辅助函数 + - `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、默认模型辅助函数和 realtime 提供商构建器 + - `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及新手引导/配置辅助函数 @@ -397,8 +347,8 @@ x-i18n: }, ``` - - 对于需要自定义请求标头或请求体修改的提供商: + + 对于需要自定义请求头或请求体修改的提供商: ```typescript // wrapStreamFn returns a StreamFn derived from ctx.streamFn @@ -415,8 +365,8 @@ x-i18n: }, ``` - - 对于在通用 HTTP 或 WebSocket 传输协议上需要原生请求/会话标头或元数据的提供商: + + 对于需要在通用 HTTP 或 WebSocket 传输协议上附加原生请求/会话请求头或元数据的提供商: ```typescript resolveTransportTurnState: (ctx) => ({ @@ -436,8 +386,8 @@ x-i18n: }), ``` - - 对于暴露使用量/计费数据的提供商: + + 对于提供用量/计费数据的提供商: ```typescript resolveUsageAuth: async (ctx) => { @@ -451,82 +401,73 @@ x-i18n: - - OpenClaw 会按以下顺序调用 hooks。大多数提供商只会使用 2 到 3 个: + + OpenClaw 会按以下顺序调用这些钩子。大多数提供商只会用到 2-3 个: - | # | Hook | 何时使用 | + | # | 钩子 | 何时使用 | | --- | --- | --- | - | 1 | `catalog` | 模型目录或默认 `baseUrl` | - | 2 | `applyConfigDefaults` | 配置具体化期间由提供商拥有的全局默认值 | - | 3 | `normalizeModelId` | 在查找前清理旧版/预览模型 id 别名 | - | 4 | `normalizeTransport` | 在通用模型组装前清理 provider-family `api` / `baseUrl` | + | 1 | `catalog` | 模型目录或基础 URL 默认值 | + | 2 | `applyConfigDefaults` | 配置实体化期间由提供商拥有的全局默认值 | + | 3 | `normalizeModelId` | 查找前清理旧版/预览版模型 id 别名 | + | 4 | `normalizeTransport` | 通用模型组装前进行提供商系列的 `api` / `baseUrl` 清理 | | 5 | `normalizeConfig` | 规范化 `models.providers.` 配置 | - | 6 | `applyNativeStreamingUsageCompat` | 用于配置提供商的原生流式 usage compat 重写 | - | 7 | `resolveConfigApiKey` | 由提供商拥有的 env-marker 凭证解析 | - | 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的 synthetic auth | - | 9 | `shouldDeferSyntheticProfileAuth` | 将 synthetic 的已存储 profile 占位符降级到 env/config auth 之后 | - | 10 | `resolveDynamicModel` | 接受任意上游模型 ID | - | 11 | `prepareDynamicModel` | 在解析前异步获取元数据 | - | 12 | `normalizeResolvedModel` | 在运行器之前进行传输协议重写 | + | 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生分块流式传输用量兼容性重写 | + | 7 | `resolveConfigApiKey` | 由提供商拥有的环境变量标记凭证解析 | + | 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的合成凭证 | + | 9 | `shouldDeferSyntheticProfileAuth` | 将合成的已存储配置文件占位符优先级降到环境变量/配置凭证之后 | + | 10 | `resolveDynamicModel` | 接受任意上游模型 id | + | 11 | `prepareDynamicModel` | 解析前异步获取元数据 | + | 12 | `normalizeResolvedModel` | 运行器之前的传输协议重写 | 运行时回退说明: - - `normalizeConfig` 会先检查匹配的提供商,然后再检查其他具备 - hook 能力的提供商插件,直到有插件真正修改配置为止。 - 如果没有任何提供商 hook 重写受支持的 Google-family 配置项, - 仍会应用内置的 Google 配置规范化器。 - - `resolveConfigApiKey` 在暴露时会使用提供商 hook。内置的 - `amazon-bedrock` 路径在这里也有一个内建的 AWS env-marker 解析器, - 尽管 Bedrock 运行时凭证本身仍使用 AWS SDK 默认链。 - | 13 | `contributeResolvedModelCompat` | 为运行在另一种兼容传输协议后的厂商模型提供 compat 标志 | + - `normalizeConfig` 会先检查匹配的提供商,然后再检查其他具备钩子能力的提供商插件,直到其中一个真正更改了配置。 + 如果没有任何提供商钩子重写受支持的 Google 系列配置项,内置的 Google 配置规范化器仍会生效。 + - `resolveConfigApiKey` 会在提供商暴露该钩子时使用提供商钩子。内置的 `amazon-bedrock` 路径在这里也有一个内建的 AWS 环境变量标记解析器,即使 Bedrock 运行时凭证本身仍然使用 AWS SDK 默认链。 + | 13 | `contributeResolvedModelCompat` | 为运行在另一种兼容传输协议后的厂商模型提供兼容性标志 | | 14 | `capabilities` | 旧版静态能力包;仅为兼容性保留 | - | 15 | `normalizeToolSchemas` | 注册前由提供商拥有的工具 schema 清理 | - | 16 | `inspectToolSchemas` | 由提供商拥有的工具 schema 诊断 | - | 17 | `resolveReasoningOutputMode` | 带标签与原生 reasoning-output 合约 | + | 15 | `normalizeToolSchemas` | 注册前由提供商拥有的工具模式清理 | + | 16 | `inspectToolSchemas` | 由提供商拥有的工具模式诊断 | + | 17 | `resolveReasoningOutputMode` | 带标签与原生推理输出契约 | | 18 | `prepareExtraParams` | 默认请求参数 | | 19 | `createStreamFn` | 完全自定义的 StreamFn 传输协议 | - | 20 | `wrapStreamFn` | 正常流路径上的自定义标头/请求体包装器 | - | 21 | `resolveTransportTurnState` | 原生逐轮标头/元数据 | - | 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话标头/冷却 | - | 23 | `formatApiKey` | 自定义运行时令牌形态 | + | 20 | `wrapStreamFn` | 常规流路径上的自定义请求头/请求体包装器 | + | 21 | `resolveTransportTurnState` | 原生逐轮请求头/元数据 | + | 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话请求头/冷却时间 | + | 23 | `formatApiKey` | 自定义运行时令牌格式 | | 24 | `refreshOAuth` | 自定义 OAuth 刷新 | - | 25 | `buildAuthDoctorHint` | 凭证修复指引 | + | 25 | `buildAuthDoctorHint` | 凭证修复指导 | | 26 | `matchesContextOverflowError` | 由提供商拥有的上下文溢出检测 | | 27 | `classifyFailoverReason` | 由提供商拥有的限流/过载分类 | - | 28 | `isCacheTtlEligible` | 提示词缓存 TTL gating | + | 28 | `isCacheTtlEligible` | 提示词缓存 TTL 门控 | | 29 | `buildMissingAuthMessage` | 自定义缺失凭证提示 | - | 30 | `suppressBuiltInModel` | 隐藏过时的上游条目 | - | 31 | `augmentModelCatalog` | synthetic 前向兼容条目 | + | 30 | `suppressBuiltInModel` | 隐藏过时的上游行 | + | 31 | `augmentModelCatalog` | 合成的前向兼容行 | | 32 | `isBinaryThinking` | 二进制 thinking 开/关 | - | 33 | `supportsXHighThinking` | `xhigh` reasoning 支持 | + | 33 | `supportsXHighThinking` | `xhigh` 推理支持 | | 34 | `resolveDefaultThinkingLevel` | 默认 `/think` 策略 | - | 35 | `isModernModelRef` | 实时/冒烟模型匹配 | - | 36 | `prepareRuntimeAuth` | 推理前的令牌交换 | - | 37 | `resolveUsageAuth` | 自定义使用量凭证解析 | - | 38 | `fetchUsageSnapshot` | 自定义使用量端点 | - | 39 | `createEmbeddingProvider` | 用于 memory/search 的由提供商拥有的 embedding 适配器 | - | 40 | `buildReplayPolicy` | 自定义 transcript replay/压缩策略 | - | 41 | `sanitizeReplayHistory` | 通用清理之后的提供商专用 replay 重写 | - | 42 | `validateReplayTurns` | 嵌入式运行器之前的严格 replay-turn 校验 | + | 35 | `isModernModelRef` | live/smoke 模型匹配 | + | 36 | `prepareRuntimeAuth` | 推理前进行令牌交换 | + | 37 | `resolveUsageAuth` | 自定义用量凭证解析 | + | 38 | `fetchUsageSnapshot` | 自定义用量端点 | + | 39 | `createEmbeddingProvider` | 用于 memory/search 的由提供商拥有的嵌入适配器 | + | 40 | `buildReplayPolicy` | 自定义转录重放/压缩策略 | + | 41 | `sanitizeReplayHistory` | 通用清理后的提供商专用重放重写 | + | 42 | `validateReplayTurns` | 嵌入式运行器之前的严格重放轮次校验 | | 43 | `onModelSelected` | 选择模型后的回调(例如遥测) | 提示词调优说明: - - `resolveSystemPromptContribution` 允许提供商为某个模型 family 注入 - 具备缓存感知能力的 system prompt 指引。当行为属于某个提供商/模型 - family 并且需要保留稳定/动态缓存拆分时,应优先使用它,而不是 - `before_prompt_build`。 + - `resolveSystemPromptContribution` 允许提供商为某个模型系列注入具备缓存感知能力的 system prompt 指导。对于属于某一个提供商/模型系列且应保留稳定/动态缓存拆分的行为,优先使用它,而不是 `before_prompt_build`。 - 有关详细说明和真实示例,请参阅 - [内部机制:提供商运行时 Hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 + 如需详细说明和真实示例,请参阅 [内部机制:提供商运行时钩子](/zh-CN/plugins/architecture#provider-runtime-hooks)。 - 一个提供商插件除了文本推理外,还可以注册语音、实时转写、实时语音、 - 媒体理解、图像生成、视频生成、web 抓取和 web 搜索: + 提供商插件除了文本推理之外,还可以注册语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取和网页搜索: ```typescript register(api) { @@ -609,7 +550,7 @@ x-i18n: api.registerWebFetchProvider({ id: "acme-ai-fetch", label: "Acme Fetch", - hint: "Fetch pages through Acme's rendering backend.", + hint: "通过 Acme 的渲染后端抓取页面。", envVars: ["ACME_FETCH_API_KEY"], placeholder: "acme-...", signupUrl: "https://acme.example.com/fetch", @@ -620,7 +561,7 @@ x-i18n: acme.apiKey = value; }, createTool: () => ({ - description: "Fetch a page through Acme Fetch.", + description: "通过 Acme Fetch 抓取页面。", parameters: {}, execute: async (args) => ({ content: [] }), }), @@ -634,20 +575,11 @@ x-i18n: } ``` - OpenClaw 会将其归类为 **hybrid-capability** 插件。这是 - 公司插件(每个厂商一个插件)的推荐模式。请参阅 - [内部机制:能力归属](/zh-CN/plugins/architecture#capability-ownership-model)。 + OpenClaw 会将其归类为 **hybrid-capability** 插件。这是公司插件(每个厂商一个插件)的推荐模式。请参阅 [内部机制:能力归属](/zh-CN/plugins/architecture#capability-ownership-model)。 - 对于视频生成,优先使用上面展示的具备模式感知能力的 shape: - `generate`、`imageToVideo` 和 `videoToVideo`。像 - `maxInputImages`、`maxInputVideos` 和 `maxDurationSeconds` - 这样的扁平聚合字段,不足以干净地表达 transform-mode 支持或禁用模式。 + 对于视频生成,优先使用上面展示的具备模式感知的能力结构:`generate`、`imageToVideo` 和 `videoToVideo`。像 `maxInputImages`、`maxInputVideos` 和 `maxDurationSeconds` 这样的扁平聚合字段,不足以清晰表达转换模式支持或已禁用的模式。 - 音乐生成提供商应遵循相同模式: - `generate` 用于仅基于提示词的生成,`edit` 用于基于参考图像的 - 生成。像 `maxInputImages`、 - `supportsLyrics` 和 `supportsFormat` 这样的扁平聚合字段, - 不足以表达 edit 支持;显式的 `generate` / `edit` 块才是预期合约。 + 音乐生成提供商也应遵循同样的模式:`generate` 用于仅基于提示词的生成,`edit` 用于基于参考图像的生成。像 `maxInputImages`、`supportsLyrics` 和 `supportsFormat` 这样的扁平聚合字段,不足以表达编辑支持;显式的 `generate` / `edit` 块才是预期契约。 @@ -688,43 +620,41 @@ x-i18n: ## 发布到 ClawHub -提供商插件的发布方式与任何其他外部代码插件相同: +提供商插件的发布方式与其他外部代码插件相同: ```bash clawhub package publish your-org/your-plugin --dry-run clawhub package publish your-org/your-plugin ``` -这里不要使用旧版的仅限 skill 的发布别名;插件包应使用 -`clawhub package publish`。 +这里不要使用旧版仅适用于 skill 的发布别名;插件包应使用 `clawhub package publish`。 ## 文件结构 ``` /acme-ai/ -├── package.json # openclaw.providers metadata -├── openclaw.plugin.json # Manifest with provider auth metadata +├── package.json # openclaw.providers 元数据 +├── openclaw.plugin.json # 包含提供商凭证元数据的清单 ├── index.ts # definePluginEntry + registerProvider └── src/ - ├── provider.test.ts # Tests - └── usage.ts # Usage endpoint (optional) + ├── provider.test.ts # 测试 + └── usage.ts # 用量端点(可选) ``` ## 目录顺序参考 -`catalog.order` 控制你的目录相对于内置 -提供商何时合并: +`catalog.order` 控制你的目录相对于内置提供商的合并时机: -| Order | 时机 | 使用场景 | +| 顺序 | 时机 | 使用场景 | | --------- | ------------- | ----------------------------------------------- | -| `simple` | 第一轮 | 普通 API 密钥提供商 | -| `profile` | `simple` 之后 | 受 auth profiles 限制的提供商 | -| `paired` | `profile` 之后 | 合成多个相关条目 | -| `late` | 最后一轮 | 覆盖现有提供商(冲突时胜出) | +| `simple` | 第一轮 | 纯 API 密钥提供商 | +| `profile` | 在 simple 之后 | 受凭证配置文件控制的提供商 | +| `paired` | 在 profile 之后 | 合成多个相关条目 | +| `late` | 最后一轮 | 覆盖现有提供商(冲突时胜出) | ## 后续步骤 - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 如果你的插件也提供一个渠道 -- [SDK 运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 辅助函数(TTS、搜索、子智能体) -- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整的子路径导入参考 -- [插件内部机制](/zh-CN/plugins/architecture#provider-runtime-hooks) — hook 细节和内置示例 +- [插件 SDK 运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 辅助函数(TTS、搜索、子智能体) +- [插件 SDK 概览](/zh-CN/plugins/sdk-overview) — 完整的子路径导入参考 +- [插件内部机制](/zh-CN/plugins/architecture#provider-runtime-hooks) — 钩子细节和内置示例 diff --git a/docs/zh-CN/plugins/sdk-runtime.md b/docs/zh-CN/plugins/sdk-runtime.md index 726c4363c..2bee41ce8 100644 --- a/docs/zh-CN/plugins/sdk-runtime.md +++ b/docs/zh-CN/plugins/sdk-runtime.md @@ -1,28 +1,28 @@ --- read_when: - - 当你需要从插件调用核心辅助工具时(TTS、STT、图像生成、Web 搜索、subagent) - - 当你想了解 api.runtime 暴露了什么内容时 - - 当你在插件代码中访问 config、智能体或媒体辅助工具时 + - 你需要从插件中调用核心辅助函数(TTS、STT、图像生成、网页搜索、子智能体) + - 你想了解 `api.runtime` 暴露了什么内容 + - 你正在从插件代码中访问配置、智能体或媒体辅助函数 sidebarTitle: Runtime Helpers -summary: api.runtime —— 在插件中可用的注入式运行时辅助工具 -title: 插件运行时辅助工具 +summary: api.runtime —— 可供插件使用的注入运行时辅助函数 +title: 插件运行时辅助函数 x-i18n: - generated_at: "2026-04-07T06:53:16Z" + generated_at: "2026-04-10T20:23:47Z" model: gpt-5.4 provider: openai - source_hash: acb9e56678e9ed08d0998dfafd7cd1982b592be5bc34d9e2d2c1f70274f8f248 + source_hash: fbf8a6ecd970300f784b8aca20eed40ba12c83107abd27385bfdc3347d2544be source_path: plugins/sdk-runtime.md workflow: 15 --- -# 插件运行时辅助工具 +# 插件运行时辅助函数 -这是对在注册期间注入到每个插件中的 `api.runtime` 对象的参考说明。请使用这些辅助工具,而不是直接导入宿主内部实现。 +在每个插件注册期间注入的 `api.runtime` 对象参考。请使用这些辅助函数,而不要直接导入宿主内部实现。 - **想看操作演示?** 请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) - 或 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) 中的分步指南, - 它们会结合上下文展示这些辅助工具的用法。 + **在找使用演练?** 请参阅 [Channel Plugins](/zh-CN/plugins/sdk-channel-plugins) + 或 [Provider Plugins](/zh-CN/plugins/sdk-provider-plugins) 的分步指南, + 它们会在上下文中展示这些辅助函数的用法。 ```typescript @@ -38,37 +38,41 @@ register(api) { 智能体身份、目录和会话管理。 ```typescript -// Resolve the agent's working directory +// 解析智能体的工作目录 const agentDir = api.runtime.agent.resolveAgentDir(cfg); -// Resolve agent workspace +// 解析智能体工作区 const workspaceDir = api.runtime.agent.resolveAgentWorkspaceDir(cfg); -// Get agent identity +// 获取智能体身份 const identity = api.runtime.agent.resolveAgentIdentity(cfg); -// Get default thinking level +// 获取默认思考级别 const thinking = api.runtime.agent.resolveThinkingDefault(cfg, provider, model); -// Get agent timeout +// 获取智能体超时时间 const timeoutMs = api.runtime.agent.resolveAgentTimeoutMs(cfg); -// Ensure workspace exists +// 确保工作区存在 await api.runtime.agent.ensureAgentWorkspace(cfg); -// Run an embedded Pi agent +// 运行一个嵌入式智能体轮次 const agentDir = api.runtime.agent.resolveAgentDir(cfg); -const result = await api.runtime.agent.runEmbeddedPiAgent({ +const result = await api.runtime.agent.runEmbeddedAgent({ sessionId: "my-plugin:task-1", runId: crypto.randomUUID(), sessionFile: path.join(agentDir, "sessions", "my-plugin-task-1.jsonl"), workspaceDir: api.runtime.agent.resolveAgentWorkspaceDir(cfg), - prompt: "Summarize the latest changes", + prompt: "总结最新的变更", timeoutMs: api.runtime.agent.resolveAgentTimeoutMs(cfg), }); ``` -**会话存储辅助工具** 位于 `api.runtime.agent.session` 下: +`runEmbeddedAgent(...)` 是用于从插件代码启动普通 OpenClaw 智能体轮次的中立辅助函数。它使用与由渠道触发的回复相同的提供商/模型解析方式和智能体 harness 选择逻辑。 + +`runEmbeddedPiAgent(...)` 仍然保留作为兼容性别名。 + +**会话存储辅助函数** 位于 `api.runtime.agent.session` 下: ```typescript const storePath = api.runtime.agent.session.resolveStorePath(cfg); @@ -82,63 +86,62 @@ const filePath = api.runtime.agent.session.resolveSessionFilePath(cfg, sessionId 默认模型和提供商常量: ```typescript -const model = api.runtime.agent.defaults.model; // e.g. "anthropic/claude-sonnet-4-6" -const provider = api.runtime.agent.defaults.provider; // e.g. "anthropic" +const model = api.runtime.agent.defaults.model; // 例如 "anthropic/claude-sonnet-4-6" +const provider = api.runtime.agent.defaults.provider; // 例如 "anthropic" ``` ### `api.runtime.subagent` -启动并管理后台 subagent 运行。 +启动和管理后台子智能体运行。 ```typescript -// Start a subagent run +// 启动一个子智能体运行 const { runId } = await api.runtime.subagent.run({ sessionKey: "agent:main:subagent:search-helper", - message: "Expand this query into focused follow-up searches.", - provider: "openai", // optional override - model: "gpt-4.1-mini", // optional override + message: "将这个查询扩展为聚焦的后续搜索。", + provider: "openai", // 可选覆盖 + model: "gpt-4.1-mini", // 可选覆盖 deliver: false, }); -// Wait for completion +// 等待完成 const result = await api.runtime.subagent.waitForRun({ runId, timeoutMs: 30000 }); -// Read session messages +// 读取会话消息 const { messages } = await api.runtime.subagent.getSessionMessages({ sessionKey: "agent:main:subagent:search-helper", limit: 10, }); -// Delete a session +// 删除一个会话 await api.runtime.subagent.deleteSession({ sessionKey: "agent:main:subagent:search-helper", }); ``` - 模型覆盖(`provider`/`model`)需要操作员在 config 中通过 - `plugins.entries..subagent.allowModelOverride: true` 明确启用。 - 不受信任的插件仍然可以运行 subagent,但其覆盖请求会被拒绝。 + 模型覆盖(`provider`/`model`)要求操作员通过配置中的 + `plugins.entries..subagent.allowModelOverride: true` 显式启用。 + 不受信任的插件仍然可以运行子智能体,但覆盖请求会被拒绝。 ### `api.runtime.taskFlow` -将 Task Flow 运行时绑定到现有的 OpenClaw 会话键或受信任的工具上下文, -然后在每次调用时无需传入 owner,即可创建和管理 Task Flows。 +将 Task Flow 运行时绑定到现有的 OpenClaw 会话键或受信任的工具上下文,然后在每次调用时都无需传递 owner 即可创建和管理 Task Flows。 ```typescript const taskFlow = api.runtime.taskFlow.fromToolContext(ctx); const created = taskFlow.createManaged({ controllerId: "my-plugin/review-batch", - goal: "Review new pull requests", + goal: "审查新的拉取请求", }); const child = taskFlow.runTask({ flowId: created.flowId, runtime: "acp", childSessionKey: "agent:main:subagent:reviewer", - task: "Review PR #123", + task: "审查 PR #123", status: "running", startedAt: Date.now(), }); @@ -151,72 +154,71 @@ const waiting = taskFlow.setWaiting({ }); ``` -当你已经从自己的绑定层获得一个受信任的 OpenClaw 会话键时,请使用 -`bindSession({ sessionKey, requesterOrigin })`。不要从原始用户输入进行绑定。 +当你已经从自己的绑定层获得了受信任的 OpenClaw 会话键时,请使用 `bindSession({ sessionKey, requesterOrigin })`。不要从原始用户输入进行绑定。 ### `api.runtime.tts` 文本转语音合成。 ```typescript -// Standard TTS +// 标准 TTS const clip = await api.runtime.tts.textToSpeech({ text: "Hello from OpenClaw", cfg: api.config, }); -// Telephony-optimized TTS +// 面向电话场景优化的 TTS const telephonyClip = await api.runtime.tts.textToSpeechTelephony({ text: "Hello from OpenClaw", cfg: api.config, }); -// List available voices +// 列出可用语音 const voices = await api.runtime.tts.listVoices({ provider: "elevenlabs", cfg: api.config, }); ``` -使用核心 `messages.tts` 配置和提供商选择。返回 PCM 音频缓冲区和采样率。 +使用核心 `messages.tts` 配置和提供商选择。返回 PCM 音频缓冲区 + 采样率。 ### `api.runtime.mediaUnderstanding` 图像、音频和视频分析。 ```typescript -// Describe an image +// 描述一张图片 const image = await api.runtime.mediaUnderstanding.describeImageFile({ filePath: "/tmp/inbound-photo.jpg", cfg: api.config, agentDir: "/tmp/agent", }); -// Transcribe audio +// 转录音频 const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, - mime: "audio/ogg", // optional, for when MIME cannot be inferred + mime: "audio/ogg", // 可选,用于无法推断 MIME 时 }); -// Describe a video +// 描述一个视频 const video = await api.runtime.mediaUnderstanding.describeVideoFile({ filePath: "/tmp/inbound-video.mp4", cfg: api.config, }); -// Generic file analysis +// 通用文件分析 const result = await api.runtime.mediaUnderstanding.runFile({ filePath: "/tmp/inbound-file.pdf", cfg: api.config, }); ``` -当未生成输出时(例如输入被跳过),返回 `{ text: undefined }`。 +当没有生成输出时(例如输入被跳过),返回 `{ text: undefined }`。 - `api.runtime.stt.transcribeAudioFile(...)` 仍保留为 - `api.runtime.mediaUnderstanding.transcribeAudioFile(...)` 的兼容别名。 + `api.runtime.stt.transcribeAudioFile(...)` 仍然保留作为 + `api.runtime.mediaUnderstanding.transcribeAudioFile(...)` 的兼容性别名。 ### `api.runtime.imageGeneration` @@ -225,7 +227,7 @@ const result = await api.runtime.mediaUnderstanding.runFile({ ```typescript const result = await api.runtime.imageGeneration.generate({ - prompt: "A robot painting a sunset", + prompt: "一个正在绘制日落的机器人", cfg: api.config, }); @@ -234,7 +236,7 @@ const providers = api.runtime.imageGeneration.listProviders({ cfg: api.config }) ### `api.runtime.webSearch` -Web 搜索。 +网页搜索。 ```typescript const providers = api.runtime.webSearch.listProviders({ config: api.config }); @@ -247,7 +249,7 @@ const result = await api.runtime.webSearch.search({ ### `api.runtime.media` -底层媒体实用工具。 +底层媒体工具。 ```typescript const webMedia = await api.runtime.media.loadWebMedia(url); @@ -260,7 +262,7 @@ const resized = await api.runtime.media.resizeToJpeg(buffer, { maxWidth: 800 }); ### `api.runtime.config` -Config 加载和写入。 +配置加载和写入。 ```typescript const cfg = await api.runtime.config.loadConfig(); @@ -269,7 +271,7 @@ await api.runtime.config.writeConfigFile(cfg); ### `api.runtime.system` -系统级实用工具。 +系统级工具。 ```typescript await api.runtime.system.enqueueSystemEvent(event); @@ -302,7 +304,7 @@ const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" }, ### `api.runtime.modelAuth` -模型和提供商凭证解析。 +模型和提供商认证解析。 ```typescript const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg }); @@ -322,7 +324,7 @@ const stateDir = api.runtime.state.resolveStateDir(); ### `api.runtime.tools` -内存工具工厂和 CLI。 +Memory 工具工厂和 CLI。 ```typescript const getTool = api.runtime.tools.createMemoryGetTool(/* ... */); @@ -332,7 +334,7 @@ api.runtime.tools.registerMemoryCli(/* ... */); ### `api.runtime.channel` -渠道专用运行时辅助工具(在加载渠道插件时可用)。 +渠道专用运行时辅助函数(在加载渠道插件时可用)。 `api.runtime.channel.mentions` 是供使用运行时注入的内置渠道插件共享的入站提及策略接口: @@ -361,7 +363,7 @@ const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({ }); ``` -可用的 mention 辅助工具包括: +可用的提及辅助函数: - `buildMentionRegexes` - `matchesMentionPatterns` @@ -369,14 +371,11 @@ const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({ - `implicitMentionKindWhen` - `resolveInboundMentionDecision` -`api.runtime.channel.mentions` 有意不暴露较旧的 -`resolveMentionGating*` 兼容辅助工具。请优先使用标准化的 -`{ facts, policy }` 路径。 +`api.runtime.channel.mentions` 有意不暴露较旧的 `resolveMentionGating*` 兼容性辅助函数。优先使用标准化的 `{ facts, policy }` 路径。 ## 存储运行时引用 -使用 `createPluginRuntimeStore` 存储运行时引用,以便在 `register` -回调之外使用: +使用 `createPluginRuntimeStore` 存储运行时引用,以便在 `register` 回调之外使用: ```typescript import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; @@ -384,7 +383,7 @@ import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store"; const store = createPluginRuntimeStore("my-plugin runtime not initialized"); -// In your entry point +// 在你的入口点中 export default defineChannelPluginEntry({ id: "my-plugin", name: "My Plugin", @@ -393,32 +392,32 @@ export default defineChannelPluginEntry({ setRuntime: store.setRuntime, }); -// In other files +// 在其他文件中 export function getRuntime() { - return store.getRuntime(); // throws if not initialized + return store.getRuntime(); // 如果尚未初始化则抛出异常 } export function tryGetRuntime() { - return store.tryGetRuntime(); // returns null if not initialized + return store.tryGetRuntime(); // 如果尚未初始化则返回 null } ``` ## 其他顶层 `api` 字段 -除 `api.runtime` 之外,API 对象还提供: +除了 `api.runtime` 之外,API 对象还提供: -| Field | Type | Description | +| 字段 | 类型 | 描述 | | ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------- | -| `api.id` | `string` | 插件 id | -| `api.name` | `string` | 插件显示名称 | -| `api.config` | `OpenClawConfig` | 当前 config 快照(可用时为活动的内存中运行时快照) | -| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件专用 config | -| `api.logger` | `PluginLogger` | 作用域日志记录器(`debug`、`info`、`warn`、`error`) | -| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置前的轻量级窗口 | -| `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 | +| `api.id` | `string` | 插件 ID | +| `api.name` | `string` | 插件显示名称 | +| `api.config` | `OpenClawConfig` | 当前配置快照(可用时为活跃的内存中运行时快照) | +| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件专用配置 | +| `api.logger` | `PluginLogger` | 作用域日志记录器(`debug`、`info`、`warn`、`error`) | +| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置之前的轻量预启动/设置窗口 | +| `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 | ## 相关内容 -- [SDK 概览](/zh-CN/plugins/sdk-overview) —— subpath 参考 -- [插件入口点](/zh-CN/plugins/sdk-entrypoints) —— `definePluginEntry` 选项 -- [插件内部架构](/zh-CN/plugins/architecture) —— 能力模型和注册表 +- [SDK 概览](/zh-CN/plugins/sdk-overview) -- 子路径参考 +- [插件入口点](/zh-CN/plugins/sdk-entrypoints) -- `definePluginEntry` 选项 +- [插件内部机制](/zh-CN/plugins/architecture) -- 能力模型和注册表