[OpenClaw 文档]帮助--环境与调试

.ocdoc h2 { margin-top:2em; padding-bottom:.3em; border-bottom:2px solid #FF5A36; color:#FF5A36; }
.ocdoc h3 { margin-top:1.5em; color:#333; }
.ocdoc pre { background:#1e1e2e; color:#cdd6f4; padding:16px; border-radius:8px; overflow-x:auto; font-size:14px; line-height:1.6; }
.ocdoc code { font-family:'JetBrains Mono','Fira Code',Consolas,monospace; }
.ocdoc pre code { background:none; padding:0; color:inherit; }
.ocdoc :not(pre)>code { background:#f0f0f0; padding:2px 6px; border-radius:3px; font-size:.9em; color:#d63384; }
.ocdoc table { border-collapse:collapse; margin:1em 0; }
.ocdoc th,.ocdoc td { border:1px solid #ddd; padding:8px 12px; }
.ocdoc th { background:#f5f5f5; }
.ocdoc blockquote { border-left:4px solid #FF5A36; padding:.5em 1em; background:#fff7f4; color:#555; margin:1em 0; }
.ocdoc .page-sep { margin:2.5em 0; border:none; border-top:1px dashed #ccc; }
.ocdoc .page-title { color:#444; font-size:1.3em; margin-top:1em; padding:.4em .6em; background:#fafafa; border-left:4px solid #FF5A36; }
.ocdoc .src-link { font-size:.85em; color:#888; margin-top:2em; padding-top:1em; border-top:1px solid #e0e0e0; }
.ocdoc .toc-box { background:#f8f9fa; padding:1em 1.5em; border-radius:6px; margin:1em 0; }

[OpenClaw 文档]帮助--环境与调试

本文档汇总了 OpenClaw 官方文档站 帮助 > 环境与调试 子模块下的全部 6 篇内容,源自 docs.openclaw.ai/zh-CN

📄 环境变量

原文:https://docs.openclaw.ai/zh-CN/help/environment

OpenClaw 会从多个来源读取环境变量。规则是:绝不覆盖已有值

优先级(最高 → 最低)

  1. 进程环境(Gateway 网关进程已从父 shell/守护进程继承的环境)。
  2. 当前工作目录中的 .env(dotenv 默认行为;不会覆盖)。
  3. 全局 .env,位于 ~/.openclaw/.env(也就是 $OPENCLAW_STATE_DIR/.env;不会覆盖)。
  4. ~/.openclaw/openclaw.json 中的配置 env(仅在缺失时应用)。
  5. 可选的登录 shell 导入env.shellEnv.enabledOPENCLAW_LOAD_SHELL_ENV=1),仅对缺失的预期键名应用。

在使用默认状态目录的 Ubuntu 全新安装中,OpenClaw 还会在全局 .env 之后,将 ~/.config/openclaw/gateway.env 作为兼容性回退。如果两个文件都存在且内容不一致,OpenClaw 会保留 ~/.openclaw/.env 并打印警告。

如果配置文件完全缺失,则跳过第 4 步;如果启用了 shell 导入,它仍会运行。

配置 env

设置内联环境变量有两种等效方式(都不会覆盖已有值):

{
  env: {
    OPENROUTER_API_KEY: "sk-or-...",
    vars: {
      GROQ_API_KEY: "gsk-...",
    },
  },
}

Shell 环境导入

env.shellEnv 会运行你的登录 shell,并且只导入缺失的预期键名:

{
  env: {
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
  },
}

等效环境变量:

  • OPENCLAW_LOAD_SHELL_ENV=1
  • OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000

运行时注入的环境变量

OpenClaw 还会将上下文标记注入到派生的子进程中:

  • OPENCLAW_SHELL=exec:为通过 exec 工具运行的命令设置。
  • OPENCLAW_SHELL=acp:为 ACP 运行时后端进程派生设置(例如 acpx)。
  • OPENCLAW_SHELL=acp-client:为派生 ACP 桥接进程的 openclaw acp client 设置。
  • OPENCLAW_SHELL=tui-local:为本地 TUI ! shell 命令设置。

这些是运行时标记(不是必需的用户配置)。它们可用于 shell/profile 逻辑,
以应用特定于上下文的规则。

UI 环境变量

  • OPENCLAW_THEME=light:当你的终端使用浅色背景时,强制使用浅色 TUI 调色板。
  • OPENCLAW_THEME=dark:强制使用深色 TUI 调色板。
  • COLORFGBG:如果你的终端导出了它,OpenClaw 会使用背景色提示自动选择 TUI 调色板。

配置中的环境变量替换

你可以使用 ${VAR_NAME} 语法在配置字符串值中直接引用环境变量:

{
  models: {
    providers: {
      "vercel-gateway": {
        apiKey: "${VERCEL_GATEWAY_API_KEY}",
      },
    },
  },
}

了解详情,请参阅配置:环境变量替换

密钥引用与 ${ENV} 字符串

OpenClaw 支持两种由环境变量驱动的模式:

  • 配置值中的 ${VAR} 字符串替换。
  • SecretRef 对象({ source: "env", provider: "default", id: "VAR" }),用于支持密钥引用的字段。

两者都会在激活时从进程环境中解析。SecretRef 详情记录在密钥管理中。

路径相关环境变量

变量 用途
OPENCLAW_HOME 覆盖用于所有内部路径解析的主目录(~/.openclaw/、智能体目录、会话、凭证)。在以专用服务用户运行 OpenClaw 时很有用。
OPENCLAW_STATE_DIR 覆盖状态目录(默认 ~/.openclaw)。
OPENCLAW_CONFIG_PATH 覆盖配置文件路径(默认 ~/.openclaw/openclaw.json)。
OPENCLAW_INCLUDE_ROOTS 目录路径列表,$include 指令可在这些目录中解析配置目录之外的文件(默认:无 — $include 被限制在配置目录内)。会展开波浪号。

日志记录

变量 用途
OPENCLAW_LOG_LEVEL 覆盖文件和控制台的日志级别(例如 debugtrace)。优先于配置中的 logging.levellogging.consoleLevel。无效值会被忽略并伴随警告。
OPENCLAW_DEBUG_MODEL_TRANSPORT info 级别发出有针对性的模型请求/响应计时诊断,而无需启用全局调试日志。
OPENCLAW_DEBUG_MODEL_PAYLOAD 模型负载诊断:summarytoolsfull-redactedfull-redacted 会被截断和脱敏,但可能包含提示词/消息文本。
OPENCLAW_DEBUG_SSE 流式传输诊断:events 用于 first/done 计时,peek 用于包含前五个已脱敏的 SSE 事件。
OPENCLAW_DEBUG_CODE_MODE 代码模式模型表面诊断,包括隐藏提供商工具以及强制仅允许 exec/wait。

OPENCLAW_HOME

设置后,OPENCLAW_HOME 会在所有内部路径解析中替代系统主目录($HOME / os.homedir())。这可为无界面服务账号启用完整的文件系统隔离。

优先级: OPENCLAW_HOME > $HOME > USERPROFILE > os.homedir()

示例(macOS LaunchDaemon):

<key>EnvironmentVariables</key>
<dict>
  <key>OPENCLAW_HOME</key>
  <string>/Users/user</string>
</dict>

OPENCLAW_HOME 也可以设置为波浪号路径(例如 ~/svc),使用前会通过 $HOME 展开。

nvm 用户:web_fetch TLS 失败

如果 Node.js 是通过 nvm 安装的(而不是系统包管理器),内置的 fetch() 会使用
nvm 捆绑的 CA 存储,其中可能缺少现代根 CA(Let’s Encrypt 的 ISRG Root X1/X2、
DigiCert Global Root G2 等)。这会导致 web_fetch 在大多数 HTTPS 站点上以 "fetch failed" 失败。

在 Linux 上,OpenClaw 会自动检测 nvm,并在实际启动环境中应用修复:

  • openclaw gateway install 会将 NODE_EXTRA_CA_CERTS 写入 systemd 服务环境
  • openclaw CLI 入口点会在 Node 启动前,使用已设置的 NODE_EXTRA_CA_CERTS 重新执行自身

手动修复(适用于旧版本或直接 node ... 启动):

在启动 OpenClaw 前导出该变量:

export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
openclaw gateway run

不要依赖只将此变量写入 ~/.openclaw/.env;Node 会在进程启动时读取
NODE_EXTRA_CA_CERTS

旧版环境变量

OpenClaw 只读取 OPENCLAW_* 环境变量。早期版本中的旧版
CLAWDBOT_*MOLTBOT_* 前缀会被静默
忽略。

如果在启动时 Gateway 网关进程上仍设置了其中任何变量,OpenClaw 会发出一条
Node 弃用警告(OPENCLAW_LEGACY_ENV_VARS),其中列出检测到的
前缀和总数量。请将每个值的旧版前缀替换为 OPENCLAW_ 来重命名(例如 CLAWDBOT_GATEWAY_TOKEN
OPENCLAW_GATEWAY_TOKEN);旧名称不会生效。

相关内容


📄 调试

原文:https://docs.openclaw.ai/zh-CN/help/debugging

用于调试流式输出的辅助工具,尤其适用于提供商将 reasoning 混入普通文本的情况。

运行时调试覆盖

在聊天中使用 /debug 设置仅运行时配置覆盖(内存中,不写入磁盘)。
/debug 默认禁用;通过 commands.debug: true 启用。
当你需要切换较冷门的设置而不编辑 openclaw.json 时,这很方便。

示例:

/debug show
/debug set messages.responsePrefix="[openclaw]"
/debug unset messages.responsePrefix
/debug reset

/debug reset 会清除所有覆盖,并恢复到磁盘上的配置。

会话 trace 输出

当你想在一个会话中查看插件拥有的 trace/debug 行,
但不启用完整 verbose 模式时,使用 /trace

示例:

/trace
/trace on
/trace off

/trace 用于插件诊断,例如 Active Memory 调试摘要。
继续使用 /verbose 查看正常的 verbose 状态/工具输出,并继续使用
/debug 设置仅运行时配置覆盖。

插件生命周期 trace

当插件生命周期命令感觉很慢,并且你需要内置的阶段拆解来分析插件元数据、设备发现、注册表、
运行时镜像、配置变更和刷新工作时,使用 OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1
该 trace 需要显式启用并写入 stderr,因此 JSON 命令输出仍然可解析。

示例:

OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1 openclaw plugins install tokenjuice --force

示例输出:

[plugins:lifecycle] phase="config read" ms=6.83 status=ok command="install"
[plugins:lifecycle] phase="slot selection" ms=94.31 status=ok command="install" pluginId="tokenjuice"
[plugins:lifecycle] phase="registry refresh" ms=51.56 status=ok command="install" reason="source-changed"

在使用 CPU profiler 之前,先用它调查插件生命周期。
如果命令从源码 checkout 运行,优先在 pnpm build 后用
node dist/entry.js ... 测量已构建的运行时;pnpm openclaw ...
也会计入源码运行器开销。

CLI 启动和命令性能分析

当某个命令感觉很慢时,使用仓库中提供的启动基准测试:

pnpm test:startup:bench:smoke
pnpm tsx scripts/bench-cli-startup.ts --preset real --case status --runs 3
pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu

如果要通过正常源码运行器进行一次性性能分析,请设置
OPENCLAW_RUN_NODE_CPU_PROF_DIR

OPENCLAW_RUN_NODE_CPU_PROF_DIR=.artifacts/cli-cpu pnpm openclaw status

源码运行器会添加 Node CPU profile 标志,并为该命令写入一个 .cpuprofile
在向命令代码添加临时插桩之前,先使用这种方式。

对于看起来像同步文件系统或模块加载器工作导致的启动卡顿,
通过源码运行器添加 Node 的同步 I/O trace 标志:

OPENCLAW_TRACE_SYNC_IO=1 pnpm openclaw gateway --force

pnpm gateway:watch 默认会为被监视的 Gateway 网关子进程禁用此标志。
当你明确希望在 watch 模式下看到 Node 同步 I/O trace 输出时,
设置 OPENCLAW_TRACE_SYNC_IO=1

Gateway 网关 watch 模式

为了快速迭代,请在文件 watcher 下运行 gateway:

pnpm gateway:watch

默认情况下,这会启动或重启名为
openclaw-gateway-watch-main 的 tmux 会话(或特定 profile/端口的变体,例如
openclaw-gateway-watch-dev-19001),并从交互式终端自动附加。
非交互式 shell、CI 和智能体 exec 调用会保持分离状态,并打印附加说明。
需要时手动附加:

tmux attach -t openclaw-gateway-watch-main

tmux pane 会运行原始 watcher:

node scripts/watch-node.mjs gateway --force

不需要 tmux 时使用前台模式:

pnpm gateway:watch:raw
# or
OPENCLAW_GATEWAY_WATCH_TMUX=0 pnpm gateway:watch

保留 tmux 管理但禁用自动附加:

OPENCLAW_GATEWAY_WATCH_ATTACH=0 pnpm gateway:watch

调试启动/运行时热点时,对被监视的 Gateway 网关 CPU 时间进行分析:

pnpm gateway:watch --benchmark

watch 包装器会在调用 Gateway 网关前消费 --benchmark,并在
.artifacts/gateway-watch-profiles/ 下为每次 Gateway 网关子进程退出写入一个
V8 .cpuprofile。停止或重启被监视的 gateway 以刷新当前 profile,
然后用 Chrome DevTools 或 Speedscope 打开:

npx speedscope .artifacts/gateway-watch-profiles/*.cpuprofile

当你希望将 profile 写到其他位置时,使用 --benchmark-dir <path>
当你希望被基准测试的子进程跳过默认的 --force 端口清理,并在 Gateway 网关端口已被占用时快速失败,使用 --benchmark-no-force
基准模式默认会抑制同步 I/O trace 噪声。当你明确希望同时获得 CPU
profile 和 Node 同步 I/O stack trace 时,配合 --benchmark 设置
OPENCLAW_TRACE_SYNC_IO=1。在基准模式下,这些 trace 块会写入基准目录下的
gateway-watch-output.log,并从终端 pane 中过滤;正常的 Gateway 网关日志仍然可见。

tmux 包装器会将常见的非秘密运行时选择器带入 pane,例如
OPENCLAW_PROFILEOPENCLAW_CONFIG_PATHOPENCLAW_STATE_DIR
OPENCLAW_GATEWAY_PORTOPENCLAW_SKIP_CHANNELS。将
提供商凭据放在你的正常 profile/config 中,或使用原始前台模式处理一次性临时秘密。
如果被监视的 Gateway 网关在启动期间退出,watcher 会运行一次
openclaw doctor --fix --non-interactive,然后重启 Gateway 网关子进程。
当你希望看到原始启动失败而不执行仅开发用修复流程时,使用
OPENCLAW_GATEWAY_WATCH_AUTO_DOCTOR=0
托管的 tmux pane 也默认使用彩色 Gateway 网关日志以提高可读性;
启动 pnpm gateway:watch 时设置 FORCE_COLOR=0 可禁用 ANSI 输出。

watcher 会在 src/ 下与构建相关的文件、插件源码文件、插件 package.json
openclaw.plugin.json 元数据、tsconfig.jsonpackage.json 以及
tsdown.config.ts 发生变化时重启。插件元数据变化会在不强制执行 tsdown
重建的情况下重启 gateway;源码和配置变化仍会先重建 dist

gateway:watch 后添加任何 gateway CLI 标志,它们都会在每次重启时透传。
重新运行同一个 watch 命令会重新生成具名 tmux pane,并且原始 watcher 仍会保持其
single-watcher 锁,因此重复的 watcher 父进程会被替换,而不是不断堆积。

开发 profile + 开发 gateway(--dev)

使用开发 profile 隔离状态,并启动一个安全、可丢弃的设置用于调试。
这里有两个 --dev 标志:

  • 全局 --dev(profile): 将状态隔离在 ~/.openclaw-dev 下,并
    将 gateway 端口默认设为 19001(派生端口会随之偏移)。
  • gateway --dev:告诉 Gateway 网关在缺失时自动创建默认配置 +
    工作区
    (并跳过 BOOTSTRAP.md)。

推荐流程(开发 profile + 开发 bootstrap):

pnpm gateway:dev
OPENCLAW_PROFILE=dev openclaw tui

如果你还没有全局安装,请通过 pnpm openclaw ... 运行 CLI。

它会执行以下操作:

  1. Profile 隔离(全局 --dev
    - OPENCLAW_PROFILE=dev
    - OPENCLAW_STATE_DIR=~/.openclaw-dev
    - OPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.json
    - OPENCLAW_GATEWAY_PORT=19001(browser/canvas 会相应偏移)

  2. 开发 bootstrapgateway --dev
    - 缺失时写入最小配置(gateway.mode=local,绑定 loopback)。
    - 将 agent.workspace 设置为开发工作区。
    - 设置 agent.skipBootstrap=true(无 BOOTSTRAP.md)。
    - 如果缺失,则初始化工作区文件:
    AGENTS.mdSOUL.mdTOOLS.mdIDENTITY.mdUSER.mdHEARTBEAT.md
    - 默认身份:C3-PO(协议机器人)。
    - 在开发模式下跳过渠道提供商(OPENCLAW_SKIP_CHANNELS=1)。

重置流程(全新开始):

pnpm gateway:dev:reset

--dev 是一个全局 profile 标志,会被某些 runner 吞掉。如果你需要明确写出,请使用环境变量形式:

OPENCLAW_PROFILE=dev openclaw gateway --dev --reset

--reset 会清除配置、凭据、会话和开发工作区(使用
trash,不是 rm),然后重新创建默认开发设置。

如果非开发 gateway 已在运行(launchd 或 systemd),请先停止它:

openclaw gateway stop

原始流日志(OpenClaw)

OpenClaw 可以在任何过滤/格式化之前记录原始 assistant 流
这是查看 reasoning 是作为普通文本 delta 到达
(还是作为单独的 thinking 块到达)的最佳方式。

通过 CLI 启用:

pnpm gateway:watch --raw-stream

可选路径覆盖:

pnpm gateway:watch --raw-stream --raw-stream-path ~/.openclaw/logs/raw-stream.jsonl

等效环境变量:

OPENCLAW_RAW_STREAM=1
OPENCLAW_RAW_STREAM_PATH=~/.openclaw/logs/raw-stream.jsonl

默认文件:

~/.openclaw/logs/raw-stream.jsonl

原始 chunk 日志(pi-mono)

为了在它们被解析为块之前捕获原始 OpenAI 兼容 chunk
pi-mono 暴露了一个单独的 logger:

PI_RAW_STREAM=1

可选路径:

PI_RAW_STREAM_PATH=~/.pi-mono/logs/raw-openai-completions.jsonl

默认文件:

~/.pi-mono/logs/raw-openai-completions.jsonl

注意:这只会由使用 pi-mono 的
openai-completions 提供商的进程发出。

安全注意事项

  • 原始流日志可能包含完整 prompt、工具输出和用户数据。
  • 将日志保留在本地,并在调试后删除。
  • 如果你共享日志,请先清除秘密和 PII。

在 VSCode 中调试

基于 VSCode 的 IDE 需要 source maps 才能启用调试,因为许多生成文件会在构建过程中带有哈希名称。随附的 launch.json 配置面向 Gateway 网关服务,但可以快速调整用于其他目的:

  1. 重建并调试 Gateway 网关 - 创建新构建后调试 Gateway 网关服务
  2. 调试 Gateway 网关 - 调试已有构建中的 Gateway 网关服务

设置

默认的 重建并调试 Gateway 网关 配置开箱即用,它会自动删除 /dist 文件夹,并在启用调试的情况下重建项目:

  1. 从 Activity Bar 打开 Run and Debug 面板,或按 Ctrl+Shift+D
  2. 在 IDE 中,确保配置下拉菜单中选择了 重建并调试 Gateway 网关,然后按下 Start Debugging 按钮

或者,如果你更喜欢手动管理构建和调试流程:

  1. 打开终端并启用 source maps:
    - Linux/macOSexport OUTPUT_SOURCE_MAPS=1
    - Windows (PowerShell)$env:OUTPUT_SOURCE_MAPS="1"
    - Windows (CMD)set OUTPUT_SOURCE_MAPS=1
  2. 在同一终端中重建项目:pnpm clean:dist && pnpm build
  3. 在 IDE 中,在 Run and Debug 配置下拉菜单中选择 调试 Gateway 网关 选项,然后按下 Start Debugging 按钮

现在你可以在 TypeScript 源文件(src/ 目录)中设置断点,调试器会通过 source maps 将断点正确映射到已编译的 JavaScript。你将能够按预期检查变量、单步执行代码并查看调用栈。

说明

  • 如果使用 "重建并调试 Gateway 网关" 选项,每次启动调试器时,它都会完全删除 /dist 文件夹,并在启动 Gateway 网关前运行一次启用 source maps 的完整 pnpm build
  • 如果使用 "调试 Gateway 网关" 选项,调试会话可以随时启动和停止,而不会影响 /dist 文件夹,但你必须使用单独的终端进程来同时启用调试并管理构建周期
  • 修改 launch.json 中的 args 设置,以调试项目的其他部分
  • 如果你需要将已构建的 OpenClaw CLI 用于其他任务(例如当你的调试会话生成新的 auth token 时使用 dashboard --no-open),可以在另一个终端中以 node ./openclaw.mjs 执行它,或创建类似 alias openclaw-build="node $(pwd)/openclaw.mjs" 的 shell alias

相关


📄 测试

原文:https://docs.openclaw.ai/zh-CN/help/testing

OpenClaw 有三套 Vitest 测试套件(单元/集成、e2e、live)和少量 Docker 运行器。本文档是一份“我们如何测试”的指南:

  • 每个套件覆盖什么(以及它刻意_不_覆盖什么)。
  • 常见工作流(本地、推送前、调试)应运行哪些命令。
  • live 测试如何发现凭证并选择模型/提供商。
  • 如何为真实世界的模型/提供商问题添加回归测试。

QA 栈(qa-lab、qa-channel、live 传输通道)单独记录在:

  • QA overview - 架构、命令面、场景编写。
  • Matrix QA - pnpm openclaw qa matrix 的参考。
  • QA channel - 仓库支持场景使用的合成传输插件。

本页涵盖常规测试套件和 Docker/Parallels 运行器的运行方式。下面的 QA 专用运行器部分(QA 专用运行器)列出了具体的 qa 调用,并指回上面的参考资料。

快速开始

大多数时候:

  • 完整门禁(推送前预期运行):pnpm build && pnpm check && pnpm check:test-types && 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 虚拟机支持的 QA 通道:pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline

当你改动测试或想要额外信心时:

  • 覆盖率门禁:pnpm test:coverage
  • E2E 套件:pnpm test:e2e

当调试真实提供商/模型时(需要真实凭证):

  • live 套件(模型 + Gateway 网关工具/图像探测):pnpm test:live
  • 静默定位一个 live 文件:pnpm test:live -- src/agents/models.profiles.live.test.ts
  • 运行时性能报告:派发 OpenClaw Performance,并设置
    live_gpt54=true 来运行一次真实 openai/gpt-5.4 agent 轮次,或设置
    deep_profile=true 来生成 Kova CPU/堆/跟踪工件。每日定时运行会在配置
    CLAWGRIT_REPORTS_TOKEN 时,将 mock-provider、deep-profile 和 GPT 5.4 通道工件发布到
    openclaw/clawgrit-reports。mock-provider 报告还包含源码级 Gateway 网关启动、内存、
    插件压力、重复 fake-model hello-loop 和 CLI 启动数据。
  • Docker live 模型扫测:pnpm test:docker:live-models
  • 每个选中的模型现在会运行一次文本轮次以及一个小型文件读取风格探测。
    元数据声明支持 image 输入的模型还会运行一个微型图像轮次。
    在隔离提供商失败时,可用 OPENCLAW_LIVE_MODEL_FILE_PROBE=0
    OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0 禁用额外探测。
  • CI 覆盖:每日 OpenClaw Scheduled Live And E2E Checks 和手动
    OpenClaw Release Checks 都会以 include_live_suites: true 调用可复用 live/E2E 工作流,
    其中包含按提供商分片的独立 Docker live 模型矩阵作业。
  • 对于聚焦的 CI 重跑,派发 OpenClaw Live And E2E Checks (Reusable)
    并设置 include_live_suites: truelive_models_only: true
  • 将新的高信号提供商密钥添加到 scripts/ci-hydrate-live-auth.sh
    以及 .github/workflows/openclaw-live-and-e2e-checks-reusable.yml 和它的
    定时/发布调用方。
  • 原生 Codex 绑定聊天冒烟测试:pnpm test:docker:live-codex-bind
  • 针对 Codex app-server 路径运行 Docker live 通道,绑定一个带 /codex bind 的合成
    Slack 私信,执行 /codex fast
    /codex permissions,然后验证普通回复和图像附件通过原生插件绑定路由,而不是 ACP。
  • Codex app-server harness 冒烟测试:pnpm test:docker:live-codex-harness
  • 通过插件拥有的 Codex app-server harness 运行 Gateway 网关 agent 轮次,
    验证 /codex status/codex models,并默认执行图像、cron MCP、子 agent 和 Guardian 探测。
    在隔离其他 Codex app-server 失败时,可用
    OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0 禁用子 agent 探测。对于聚焦的子 agent 检查,禁用其他探测:
    OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness
    除非设置 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0,否则会在子 agent 探测后退出。
  • Codex 按需安装冒烟测试:pnpm test:docker:codex-on-demand
  • 在 Docker 中安装打包后的 OpenClaw tarball,运行 OpenAI API key
    新手引导,并验证 Codex 插件以及 @openai/codex 依赖已按需下载到托管 npm 根目录。
  • live 插件工具依赖冒烟测试:pnpm test:docker:live-plugin-tool
  • 打包一个带真实 slugify 依赖的夹具插件,通过
    npm-pack: 安装,验证托管 npm 根目录下的依赖,然后要求一个 live OpenAI 模型调用插件工具并返回隐藏 slug。
  • Crestodian 救援命令冒烟测试:pnpm test:live:crestodian-rescue-channel
  • 针对消息渠道救援命令面的可选双保险检查。
    它会执行 /crestodian status,排队一次持久化模型变更,回复 /crestodian yes,并验证审计/配置写入路径。
  • Crestodian 规划器 Docker 冒烟测试:pnpm test:docker:crestodian-planner
  • 在无配置容器中运行 Crestodian,并在 PATH
    上放置 fake Claude CLI,验证模糊规划器回退会转换为带审计的类型化配置写入。
  • Crestodian 首次运行 Docker 冒烟测试:pnpm test:docker:crestodian-first-run
  • 从空 OpenClaw 状态目录开始,将裸 openclaw 路由到
    Crestodian,应用设置/模型/agent/Discord 插件 + SecretRef 写入,
    校验配置,并验证审计条目。同一 Ring 0 设置路径也由 QA Lab 中的
    pnpm openclaw qa suite --scenario crestodian-ring-zero-setup 覆盖。
  • Moonshot/Kimi 成本冒烟测试:设置 MOONSHOT_API_KEY 后,运行
    openclaw models list --provider moonshot --json,然后针对
    moonshot/kimi-k2.6 运行隔离的
    openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json
    验证 JSON 报告 Moonshot/K2.6,并且助手转录存储了规范化的 usage.cost

当你只需要一个失败用例时,优先通过下面描述的允许列表环境变量来收窄 live 测试。

QA 专用运行器

当你需要 QA-lab 真实度时,这些命令位于主测试套件旁边:

CI 在专用工作流中运行 QA Lab。Agentic 对等性嵌套在
QA-Lab - All Lanes 和发布验证下,而不是独立的 PR 工作流。
广泛验证应使用 Full Release Validation,并设置
rerun_group=qa-parity,或使用 release-checks QA 组。稳定/默认发布检查会把详尽的 live/Docker soak 保留在 run_release_soak=true 后面;full 配置会强制启用 soak。QA-Lab - All Lanes
每晚在 main 上运行,也会从手动派发运行,其中 mock 对等通道、live
Matrix 通道、Convex 托管的 live Telegram 通道,以及 Convex 托管的 live Discord
通道会作为并行作业运行。定时 QA 和发布检查会显式传递 Matrix
--profile fast,而 Matrix CLI 和手动工作流输入的默认值仍为 all;手动派发可将 all 分片为 transport
mediae2ee-smokee2ee-deepe2ee-cli 作业。OpenClaw Release
Checks
会在发布批准前运行对等性以及快速 Matrix 和 Telegram 通道,并为发布传输检查使用 mock-openai/gpt-5.5
使其保持确定性并避开普通提供商插件启动。这些 live 传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA 对等套件覆盖。

完整发布 live 媒体分片使用
ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04,其中已经包含
ffmpegffprobe。Docker live 模型/后端分片使用共享的
ghcr.io/openclaw/openclaw-live-test:<sha> 镜像,该镜像针对所选提交只构建一次,
然后用 OPENCLAW_SKIP_DOCKER_BUILD=1 拉取它,而不是在每个分片内重新构建。

  • pnpm openclaw qa suite
  • 直接在主机上运行由仓库支持的 QA 场景。
  • 默认使用隔离的 Gateway 网关工作进程并行运行多个选定场景。qa-channel 默认并发数为 4(受选定场景数量限制)。使用 --concurrency <count> 调整工作进程数量,或使用 --concurrency 1 进入旧版串行通道。
  • 任一场景失败时以非零状态退出。当你想保留产物但不希望退出码失败时,使用 --allow-failures
  • 支持提供商模式 live-frontiermock-openaiaimockaimock 会启动一个由本地 AIMock 支持的提供商服务器,用于实验性的夹具和协议模拟覆盖,同时不会替代具备场景感知能力的 mock-openai 通道。
  • pnpm test:plugins:kitchen-sink-live
  • 通过 QA Lab 运行实时 OpenAI Kitchen Sink 插件考验。它会安装外部 Kitchen Sink 包,验证插件 SDK 表面清单,探测 /healthz/readyz,记录 Gateway 网关 CPU/RSS 证据,运行一次实时 OpenAI 轮次,并检查对抗性诊断。需要实时 OpenAI 凭证,例如 OPENAI_API_KEY。在已注入环境的 Testbox 会话中,如果存在 openclaw-testbox-env 辅助工具,它会自动加载 Testbox 实时凭证配置。
  • pnpm test:gateway:cpu-scenarios
  • 运行 Gateway 网关启动基准测试以及一个小型模拟 QA Lab 场景包(channel-chat-baselinememory-failure-fallbackgateway-restart-inflight-run),并在 .artifacts/gateway-cpu-scenarios/ 下写入合并后的 CPU 观测摘要。
  • 默认仅标记持续的高 CPU 观测(--cpu-core-warn--hot-wall-warn-ms),因此短暂的启动突增会记录为指标,而不会看起来像持续数分钟的 Gateway 网关占满回归。
  • 使用已构建的 dist 产物;当检出目录还没有新的运行时输出时,请先运行构建。
  • pnpm openclaw qa suite --runner multipass
  • 在一次性 Multipass Linux VM 内运行同一套 QA 套件。
  • 保持与主机上的 qa suite 相同的场景选择行为。
  • 复用与 qa suite 相同的提供商/模型选择标志。
  • 实时运行会转发对 guest 可行的受支持 QA 凭证输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 CODEX_HOME
  • 输出目录必须保留在仓库根目录下,这样 guest 才能通过挂载的工作区写回。
  • .artifacts/qa-e2e/... 下写入常规 QA 报告和摘要,以及 Multipass 日志。
  • pnpm qa:lab:up
  • 启动由 Docker 支持的 QA 站点,用于操作员风格的 QA 工作。
  • pnpm test:docker:npm-onboard-channel-agent
  • 从当前检出构建 npm tarball,在 Docker 中全局安装它,运行非交互式 OpenAI API 密钥新手引导,默认配置 Telegram,验证打包的插件运行时能在没有启动依赖修复的情况下加载,运行 Doctor,并针对模拟的 OpenAI 端点运行一次本地智能体轮次。
  • 使用 OPENCLAW_NPM_ONBOARD_CHANNEL=discord 运行同一条带 Discord 的打包安装通道。
  • pnpm test:docker:session-runtime-context
  • 为嵌入式运行时上下文转录运行确定性的已构建应用 Docker 冒烟测试。它会验证隐藏的 OpenClaw 运行时上下文以非显示自定义消息形式持久化,而不会泄漏到可见用户轮次中,然后植入受影响的损坏会话 JSONL,并验证 openclaw doctor --fix 会将其重写到当前分支并保留备份。
  • pnpm test:docker:npm-telegram-live
  • 在 Docker 中安装一个 OpenClaw 包候选版本,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram,然后复用实时 Telegram QA 通道,并将该已安装包作为被测系统 Gateway 网关。
  • 该包装器只从检出目录挂载 qa-lab 测试框架源代码;已安装包拥有 distopenclaw/plugin-sdk 和内置插件运行时,因此该通道不会把当前检出目录中的插件混入被测包。
  • 默认值为 OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta;设置 OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgzOPENCLAW_CURRENT_PACKAGE_TGZ,以测试已解析的本地 tarball,而不是从注册表安装。
  • 使用与 pnpm openclaw qa telegram 相同的 Telegram 环境变量凭证或 Convex 凭证来源。对于 CI/发布自动化,设置 OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex,以及 OPENCLAW_QA_CONVEX_SITE_URL 和角色密钥。如果 CI 中存在 OPENCLAW_QA_CONVEX_SITE_URL 和一个 Convex 角色密钥,Docker 包装器会自动选择 Convex。
  • Docker 构建/安装工作开始前,包装器会在主机上验证 Telegram 或 Convex 凭证环境变量。仅在有意调试凭证前设置时,才设置 OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1
  • OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer 仅对此通道覆盖共享的 OPENCLAW_QA_CREDENTIAL_ROLE
  • GitHub Actions 将此通道公开为手动维护者工作流 NPM Telegram Beta E2E。它不会在合并时运行。该工作流使用 qa-live-shared 环境和 Convex CI 凭证租约。
  • GitHub Actions 还公开了 Package Acceptance,用于针对一个候选包进行旁路产品证明。它接受可信 ref、已发布的 npm 规格、HTTPS tarball URL 加 SHA-256,或来自另一次运行的 tarball 产物,上传规范化后的 openclaw-current.tgz 作为 package-under-test,然后使用 smoke、package、product、full 或 custom 通道配置运行现有 Docker E2E 调度器。设置 telegram_mode=mock-openailive-frontier,以针对同一个 package-under-test 产物运行 Telegram QA 工作流。
  • 最新 beta 产品证明:
gh workflow run package-acceptance.yml --ref main \
  -f source=npm \
  -f package_spec=openclaw@beta \
  -f suite_profile=product \
  -f telegram_mode=mock-openai
  • 精确 tarball URL 证明需要摘要:
gh workflow run package-acceptance.yml --ref main \
  -f source=url \
  -f package_url=https://registry.npmjs.org/openclaw/-/openclaw-VERSION.tgz \
  -f package_sha256=<sha256> \
  -f suite_profile=package
  • 产物证明会从另一次 Actions 运行下载 tarball 产物:
gh workflow run package-acceptance.yml --ref main \
  -f source=artifact \
  -f artifact_run_id=<run-id> \
  -f artifact_name=<artifact-name> \
  -f suite_profile=smoke
  • pnpm test:docker:plugins
  • 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置频道/插件。
  • 验证设置发现会让未配置的可下载插件保持缺失,第一次已配置的 Doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏依赖修复。
  • 还会安装一个已知的较旧 npm 基线,在运行 openclaw update --tag <candidate> 前启用 Telegram,并验证候选版本的更新后 Doctor 会清理旧版插件依赖残留,而不需要测试框架侧的 postinstall 修复。
  • pnpm test:parallels:npm-update
  • 跨 Parallels guest 运行原生打包安装更新冒烟测试。每个选定平台都会先安装请求的基线包,然后在同一个 guest 中运行已安装的 openclaw update 命令,并验证已安装版本、更新状态、Gateway 网关就绪状态,以及一次本地智能体轮次。
  • 迭代单个 guest 时使用 --platform macos--platform windows--platform linux。使用 --json 获取摘要产物路径和每个通道的状态。
  • OpenAI 通道默认使用 openai/gpt-5.5 进行实时智能体轮次证明。当有意验证另一个 OpenAI 模型时,传入 --model <provider/model> 或设置 OPENCLAW_PARALLELS_OPENAI_MODEL
  • 将较长的本地运行包装在主机超时中,这样 Parallels 传输停滞不会耗尽剩余测试窗口:

    bash
    timeout --foreground 150m pnpm test:parallels:npm-update -- --json
    timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json

  • 该脚本会在 /tmp/openclaw-parallels-npm-update.* 下写入嵌套通道日志。在假设外层包装器挂起之前,先检查 windows-update.logmacos-update.loglinux-update.log

  • 在冷 guest 上,Windows 更新可能会在更新后 Doctor 和包更新工作中花费 10 到 15 分钟;只要嵌套 npm 调试日志仍在推进,这仍然是正常状态。
  • 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟通道并行运行。它们共享 VM 状态,可能在快照还原、包服务或 guest Gateway 网关状态上发生冲突。
  • 更新后证明会运行常规内置插件表面,因为语音、图像生成和媒体理解等能力门面是通过内置运行时 API 加载的,即使智能体轮次本身只检查一个简单文本响应。

  • pnpm openclaw qa aimock

  • 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。
  • pnpm openclaw qa matrix
  • 针对一次性的 Docker 支持 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅支持源代码检出,打包安装不会随附 qa-lab
  • 完整 CLI、配置文件/场景目录、环境变量和产物布局:Matrix QA
  • pnpm openclaw qa telegram
  • 使用来自环境变量的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA 通道。
  • 需要 OPENCLAW_QA_TELEGRAM_GROUP_IDOPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN。群组 id 必须是数字形式的 Telegram chat id。
  • 支持 --credential-source convex 以使用共享池化凭证。默认使用环境变量模式,或设置 OPENCLAW_QA_CREDENTIAL_SOURCE=convex 来选择池化租约。
  • 默认覆盖 canary、mention gating、命令寻址、/status、bot 到 bot 的被提及回复,以及核心原生命令回复。mock-openai 默认还覆盖确定性 reply-chain 和 Telegram final-message streaming 回归。使用 --list-scenarios 查看可选探测,例如 session_status
  • 任一场景失败时以非零状态退出。当你想保留产物但不希望退出码失败时,使用 --allow-failures
  • 需要同一私有群组中的两个不同 bot,且 SUT bot 暴露一个 Telegram 用户名。
  • 为获得稳定的 bot 到 bot 观测,请在 @BotFather 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观测群组 bot 流量。
  • .artifacts/qa-e2e/... 下写入 Telegram QA 报告、摘要和 observed-messages 产物。回复场景包含从 driver 发送请求到观测到 SUT 回复的 RTT。

Mantis Telegram Live 是围绕此通道的 PR 证据包装器。它使用 Convex 租约的 Telegram 凭证运行候选 ref,在 Crabbox 桌面浏览器中渲染已脱敏的观测消息转录,录制 MP4 证据,生成经运动裁剪的 GIF,上传产物包,并在设置 pr_number 时通过 Mantis GitHub App 发布内联 PR 证据。维护者可以通过 Mantis Scenarioscenario_id:
telegram-live
)从 Actions UI 启动它,或直接从拉取请求评论启动:

@Mantis telegram
@Mantis telegram scenario=telegram-status-command
@Mantis telegram scenarios=telegram-status-command,telegram-mentioned-message-reply

Mantis Telegram Desktop Proof 是用于 PR 视觉证明的智能体式原生 Telegram Desktop 前后对比包装器。可在 Actions UI 中使用自由格式 instructions 启动,通过 Mantis Scenarioscenario_id:
telegram-desktop-proof
)启动,或从 PR 评论启动:

@Mantis telegram desktop proof

Mantis 智能体会读取 PR,判断哪些 Telegram 可见行为能证明此
变更,在基线和候选 ref 上运行真实用户 Crabbox Telegram Desktop 证明通道,
反复迭代直到原生 GIF 有用,写入成对的
motionPreview 清单,并在设置了 pr_number 时通过
Mantis GitHub App 发布同样的 2 列 GIF 表格。

  • pnpm openclaw qa mantis telegram-desktop-builder
  • 租用或复用一个 Crabbox Linux 桌面,安装原生 Telegram Desktop,使用租用的 Telegram SUT bot token 配置 OpenClaw,启动 Gateway 网关,并从可见的 VNC 桌面录制截图/MP4 证据。
  • 默认使用 --credential-source convex,因此工作流只需要 Convex broker secret。使用 --credential-source env 时,变量与 pnpm openclaw qa telegram 所用的 OPENCLAW_QA_TELEGRAM_* 相同。
  • Telegram Desktop 仍然需要用户登录/配置文件。bot token 只用于配置 OpenClaw。使用 --telegram-profile-archive-env <name> 指定 base64 .tgz 配置文件归档,或使用 --keep-lease 并通过 VNC 手动登录一次。
  • 在输出目录下写入 mantis-telegram-desktop-builder-report.mdmantis-telegram-desktop-builder-summary.jsontelegram-desktop-builder.pngtelegram-desktop-builder.mp4

实时传输通道共享一个标准契约,避免新传输方式产生偏差;各通道覆盖矩阵位于 QA overview → Live transport coverageqa-channel 是广泛的合成套件,不属于该矩阵。

通过 Convex 共享 Telegram 凭证(v1)

当为实时传输 QA 启用 --credential-source convex(或 OPENCLAW_QA_CREDENTIAL_SOURCE=convex)时,QA lab 会从 Convex 支撑的池中获取独占租约,在通道运行期间为该租约发送 Heartbeat,并在关闭时释放租约。该章节名称早于 Discord、Slack 和 WhatsApp 支持;租约契约在各类凭证之间共享。

参考 Convex 项目脚手架:

  • qa/convex-credential-broker/

必需环境变量:

  • OPENCLAW_QA_CONVEX_SITE_URL(例如 https://your-deployment.convex.site
  • 所选角色对应的一个 secret:
  • OPENCLAW_QA_CONVEX_SECRET_MAINTAINER 用于 maintainer
  • OPENCLAW_QA_CONVEX_SECRET_CI 用于 ci
  • 凭证角色选择:
  • CLI:--credential-role maintainer|ci
  • 环境默认值:OPENCLAW_QA_CREDENTIAL_ROLE(在 CI 中默认为 ci,否则为 maintainer

可选环境变量:

  • OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS(默认 1200000
  • OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS(默认 30000
  • OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS(默认 90000
  • OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS(默认 15000
  • OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX(默认 /qa-credentials/v1
  • OPENCLAW_QA_CREDENTIAL_OWNER_ID(可选 trace id)
  • OPENCLAW_QA_ALLOW_INSECURE_HTTP=1 允许在仅本地开发中使用 loopback http:// Convex URL。

正常运行时,OPENCLAW_QA_CONVEX_SITE_URL 应使用 https://

维护者 admin 命令(池添加/移除/列出)明确需要
OPENCLAW_QA_CONVEX_SECRET_MAINTAINER

面向维护者的 CLI 辅助命令:

pnpm openclaw qa credentials doctor
pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json
pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id <credential-id>

在实时运行前使用 doctor 检查 Convex 站点 URL、broker secrets、
endpoint prefix、HTTP timeout 和 admin/list 可达性,且不会打印
secret 值。在脚本和 CI 工具中使用 --json 获取机器可读输出。

默认端点契约(OPENCLAW_QA_CONVEX_SITE_URL + /qa-credentials/v1):

  • POST /acquire
  • 请求:{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }
  • 成功:{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }
  • 耗尽/可重试:{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }
  • POST /payload-chunk
  • 请求:{ kind, ownerId, actorRole, credentialId, leaseToken, index }
  • 成功:{ status: "ok", index, data }
  • POST /heartbeat
  • 请求:{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }
  • 成功:{ status: "ok" }(或空 2xx
  • POST /release
  • 请求:{ kind, ownerId, actorRole, credentialId, leaseToken }
  • 成功:{ status: "ok" }(或空 2xx
  • POST /admin/add(仅维护者 secret)
  • 请求:{ kind, actorId, payload, note?, status? }
  • 成功:{ status: "ok", credential }
  • POST /admin/remove(仅维护者 secret)
  • 请求:{ credentialId, actorId }
  • 成功:{ status: "ok", changed, credential }
  • 活跃租约保护:{ status: "error", code: "LEASE_ACTIVE", ... }
  • POST /admin/list(仅维护者 secret)
  • 请求:{ kind?, status?, includePayload?, limit? }
  • 成功:{ status: "ok", credentials, count }

Telegram 类型的 payload 形状:

  • { groupId: string, driverToken: string, sutToken: string }
  • groupId 必须是数字形式的 Telegram chat id 字符串。
  • admin/add 会针对 kind: "telegram" 验证此形状,并拒绝格式错误的 payload。

Telegram 真实用户类型的 payload 形状:

  • { groupId: string, sutToken: string, testerUserId: string, testerUsername: string, telegramApiId: string, telegramApiHash: string, tdlibDatabaseEncryptionKey: string, tdlibArchiveBase64: string, tdlibArchiveSha256: string, desktopTdataArchiveBase64: string, desktopTdataArchiveSha256: string }
  • groupIdtesterUserIdtelegramApiId 必须是数字字符串。
  • tdlibArchiveSha256desktopTdataArchiveSha256 必须是 SHA-256 十六进制字符串。
  • kind: "telegram-user" 表示一个 Telegram 临时账号。将租约视为账号级别:TDLib CLI driver 和 Telegram Desktop 视觉见证会从同一个 payload 恢复,并且同一时间只应有一个作业持有租约。

Telegram 真实用户租约恢复:

tmp=$(mktemp -d /tmp/openclaw-telegram-user.XXXXXX)
node --import tsx scripts/e2e/telegram-user-credential.ts lease-restore \
  --user-driver-dir "$tmp/user-driver" \
  --desktop-workdir "$tmp/desktop" \
  --lease-file "$tmp/lease.json"
TELEGRAM_USER_DRIVER_STATE_DIR="$tmp/user-driver" \
  uv run ~/.codex/skills/custom/telegram-e2e-bot-to-bot/scripts/user-driver.py status --json
node --import tsx scripts/e2e/telegram-user-credential.ts release --lease-file "$tmp/lease.json"

需要视觉录制时,将恢复后的 Desktop 配置文件与 Telegram -workdir "$tmp/desktop" 一起使用。在本地 operator 环境中,如果进程环境变量缺失,scripts/e2e/telegram-user-credential.ts 默认会读取 ~/.codex/skills/custom/telegram-e2e-bot-to-bot/convex.local.env

智能体驱动的 Crabbox 会话:

pnpm qa:telegram-user:crabbox -- start \
  --tdlib-url http://artifacts.openclaw.ai/tdlib-v1.8.0-linux-x64.tgz \
  --output-dir .artifacts/qa-e2e/telegram-user-crabbox/pr-review
pnpm qa:telegram-user:crabbox -- send \
  --session .artifacts/qa-e2e/telegram-user-crabbox/pr-review/session.json \
  --text /status
pnpm qa:telegram-user:crabbox -- finish \
  --session .artifacts/qa-e2e/telegram-user-crabbox/pr-review/session.json

start 会租用 telegram-user 凭证,将同一个账号恢复到 Crabbox Linux 桌面上的
TDLib 和 Telegram Desktop,基于当前 checkout 启动本地 mock SUT
Gateway 网关,打开可见的 Telegram 聊天,开始桌面录制,并写入私有的 session.json。会话存活期间,智能体可以持续测试,直到满意为止:

  • send --session <file> --text <message> 通过真实 TDLib 用户发送,并等待 SUT 回复。
  • run --session <file> -- <remote command> 在 Crabbox 上运行任意命令并保存其输出,例如 bash -lc 'source /tmp/openclaw-telegram-user-crabbox/env.sh && python3 /tmp/openclaw-telegram-user-crabbox/user-driver.py transcript --limit 20 --json'
  • screenshot --session <file> 捕获当前可见桌面。
  • status --session <file> 打印租约和 WebVNC 命令。
  • finish --session <file> 停止录制器,捕获截图/视频/运动裁剪 artifacts,释放 Convex 凭证,停止本地 SUT 进程,并停止 Crabbox 租约,除非传入 --keep-box
  • publish --session <file> --pr <number> 默认发布仅包含 GIF 的 PR 评论。仅当有意需要日志或 JSON artifacts 时才传入 --full-artifacts

对于确定性的视觉复现,将 --mock-response-file <path> 传给 start
或单命令 probe 简写。runner 默认使用标准
Crabbox class、24fps 录制、24fps motion GIF previews,以及 1920px GIF
宽度。仅在证明需要不同捕获设置时,才使用 --class--record-fps--preview-fps
--preview-width 覆盖。

单命令 Crabbox 证明:

pnpm qa:telegram-user:crabbox -- --text /status

默认 probe 命令是一次 start/send/finish 循环的简写。将它用于快速 /status 冒烟测试。将会话命令用于 PR review、bug 复现工作,或任何智能体需要先进行数分钟任意实验再判断证明完成的场景。使用 --id <cbx_...> 复用一个已预热的桌面租约,使用 --keep-box 在 finish 后保持 VNC 打开,使用 --desktop-chat-title <name> 选择可见聊天,并在使用预构建的 Linux libtdjson.so 归档而不是在新 box 上构建 TDLib 时使用 --tdlib-url <tgz>。runner 会用 --tdlib-sha256 <hex> 验证 --tdlib-url,默认则使用同级的 <url>.sha256 文件。

Broker 验证的多渠道 payload:

  • Discord:{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string, voiceChannelId?: string }
  • WhatsApp:{ driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string }

Slack 通道也可以从池中租用,但 Slack payload 验证目前位于 Slack QA runner 中,而不是 broker 中。Slack 行使用
{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }

向 QA 添加渠道

新渠道适配器的架构和 scenario helper 名称位于 QA overview → Adding a channel。最低要求:在共享的 qa-lab host seam 上实现 transport runner,在插件清单中声明 qaRunners,挂载为 openclaw qa <runner>,并在 qa/scenarios/ 下编写 scenarios。

测试套件(在哪里运行什么)

可以把套件理解为“真实度递增”(同时不稳定性/成本也递增):

单元 / 集成(默认)

  • 命令:pnpm test
  • 配置:未定向的运行使用 vitest.full-*.config.ts shard set,并且可能将多项目 shards 展开为每项目配置以进行并行调度
  • 文件:src/**/*.test.tspackages/**/*.test.tstest/**/*.test.ts 下的 core/unit inventories;UI 单元测试在专用的 unit-ui shard 中运行
  • 范围:
  • 纯单元测试
  • 进程内集成测试(Gateway 网关 auth、路由、工具、解析、配置)
  • 已知 bug 的确定性回归
  • 预期:
  • 在 CI 中运行
  • 不需要真实 keys
  • 应该快速且稳定
  • Resolver 和 public-surface loader 测试必须使用生成的微型插件 fixtures 证明广泛的 api.js
    runtime-api.js fallback 行为,而不是使用真实内置插件源 API。真实插件 API 加载属于
    插件拥有的契约/集成套件。

原生依赖策略:

  • 默认测试安装会跳过可选的原生 Discord opus 构建。Discord 语音接收使用纯 JS opusscript 解码器,并且 @discordjs/opusallowBuilds 中保持禁用,因此本地测试和 Testbox 线路不会编译原生 addon。
  • 如果你确实需要比较原生 opus 构建,请使用专用的 Discord 语音性能或 live 线路。不要在默认 allowBuilds 中将 @discordjs/opus 设为 true;这会让无关的安装/测试循环编译原生代码。

- 未指定目标的 `pnpm test` 会运行十二个较小的分片配置(`core-unit-fast``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` 项目图,因为多分片 watch 循环并不实用。
- `pnpm test``pnpm test:watch`  `pnpm test:perf:imports` 会先将显式文件/目录目标路由到限定范围线路,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可以避免支付完整根项目启动成本。
- `pnpm test:changed` 默认会将已变更的 git 路径展开为低成本的限定范围线路:直接测试编辑、同级 `*.test.ts` 文件、显式源码映射,以及本地导入图依赖方。配置/设置/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
- `pnpm check:changed` 是窄范围工作的常规智能本地检查关口。它会将 diff 分类为 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling  tooling,然后运行匹配的类型检查、lint 和守卫命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式 `pnpm test <target>`。仅发布元数据的版本升级会运行定向版本/config/根依赖检查,并带有一个守卫,用于拒绝顶层版本字段之外的 package 变更。
- live Docker ACP harness 编辑会运行聚焦检查:live Docker 认证脚本的 shell 语法检查,以及 live Docker 调度器 dry-run。只有当 diff 限定在 `scripts["test:docker:live-*"]` 时才包含 `package.json` 变更;依赖、export、版本和其他 package 表面编辑仍使用更广泛的守卫。
- 来自 agents、commands、plugins、auto-reply helper、`plugin-sdk` 和类似纯工具区域的轻导入单元测试会路由到 `unit-fast` 线路,该线路会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有线路上。
- 选定的 `plugin-sdk`  `commands` helper 源文件也会将 changed-mode 运行映射到这些轻量线路中的显式同级测试,因此 helper 编辑可避免为该目录重新运行完整的重型套件。
- `auto-reply` 为顶层 core helper、顶层 `reply.*` 集成测试和 `src/auto-reply/reply/**` 子树提供专用桶。CI 还会将 reply 子树进一步拆分为 agent-runner、dispatch  commands/state-routing 分片,因此一个导入较重的桶不会占据完整的 Node 尾部。
- 常规 PR/main CI 会有意跳过插件批量扫描和仅发布使用的 `agentic-plugins` 分片。完整发布验证会为发布候选运行独立的 `Plugin Prerelease` 子工作流,以覆盖这些插件较重的套件。

- 当你更改 message-tool 发现输入或 compaction 运行时
  上下文时,请保留两层覆盖。
- 为纯路由和规范化
  边界添加聚焦 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  compaction 行为仍会流经
  真实的 `run.ts` / `compact.ts` 路径;仅 helper 测试
  不能充分替代这些集成路径。

- 基础 Vitest 配置默认使用 `threads`
- 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e  live 配置中使用
  非隔离运行器。
-  UI 线路保留其 `jsdom` 设置和 optimizer,但也运行在
  共享非隔离运行器上。
- 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false`
  默认值。
- `scripts/run-vitest.mjs` 默认会为 Vitest  Node
  进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。
  设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原版 V8
  行为比较。

- `pnpm changed:lanes` 会显示一个 diff 触发哪些架构线路。
- pre-commit hook 仅执行格式化。它会重新暂存已格式化文件,并且
  不运行 lint、类型检查或测试。
- 当你需要智能本地检查关口时,请在交接或 push 前显式运行
  `pnpm check:changed`
- `pnpm test:changed` 默认通过低成本限定范围线路路由。只有当智能体
  判断某个 harness、配置、package 或契约编辑确实需要更广泛的
  Vitest 覆盖时,才使用
  `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
- `pnpm test:max`  `pnpm test:changed:max` 保持相同的路由
  行为,只是 worker 上限更高。
- 本地 worker 自动扩缩容有意保持保守,并且会在主机 load average
  已经很高时退避,因此多个并发
  Vitest 运行默认造成的影响更小。
- 基础 Vitest 配置将 projects/config 文件标记为
  `forceRerunTriggers`,因此测试
  wiring 变化时 changed-mode 重新运行仍保持正确。
- 配置会在受支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`
  如果你想为直接 profiling 使用一个显式缓存位置,请设置
  `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`

- `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及
  导入拆解输出。
- `pnpm test:perf:imports:changed` 会将同一 profiling 视图限定到
  自 `origin/main` 以来变更的文件。
- 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。
  整配置运行使用配置路径作为键;include-pattern CI
  分片会追加分片名称,因此可单独跟踪过滤后的分片。
- 当某个热点测试仍然把大部分时间花在启动导入上时,
  请将重型依赖放在窄范围本地 `*.runtime.ts` 接缝后面,并
  直接 mock 该接缝,而不是仅为通过 `vi.mock(...)`
  传递它们而深度导入运行时 helper。
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会比较该已提交
  diff 的路由后 `test:changed` 与原生根项目路径,并打印 wall time
  以及 macOS 最大 RSS。
- `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到
  `scripts/test-projects.mjs` 和根 Vitest 配置来 benchmark 当前
  dirty tree。
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销
  写入主线程 CPU profile。
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为
  单元套件写入 runner CPU+heap profiles。

稳定性(Gateway 网关)

  • 命令:pnpm test:stability:gateway
  • 配置:vitest.gateway.config.ts,强制为一个 worker
  • 范围:
  • 默认启动启用诊断的真实 loopback Gateway 网关
  • 通过诊断事件路径驱动合成的 Gateway 网关消息、记忆和大载荷 churn
  • 通过 Gateway 网关 WS RPC 查询 diagnostics.stability
  • 覆盖诊断稳定性 bundle 持久化 helper
  • 断言 recorder 保持有界、合成 RSS 样本保持在压力预算内,并且每会话队列深度会回落为零
  • 预期:
  • CI 安全且无需密钥
  • 用于稳定性回归跟进的窄线路,不能替代完整 Gateway 网关套件

E2E(Gateway 网关 smoke)

  • 命令:pnpm test:e2e
  • 配置:vitest.e2e.config.ts
  • 文件:src/**/*.e2e.test.tstest/**/*.e2e.test.ts,以及 extensions/ 下的内置插件 E2E 测试
  • 运行时默认值:
  • 使用 Vitest threadsisolate: false,与仓库其余部分一致。
  • 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。
  • 默认以 silent 模式运行,以减少控制台 I/O 开销。
  • 有用的覆盖项:
  • OPENCLAW_E2E_WORKERS=<n> 用于强制 worker 数量(上限为 16)。
  • OPENCLAW_E2E_VERBOSE=1 用于重新启用详细控制台输出。
  • 范围:
  • 多实例 Gateway 网关端到端行为
  • WebSocket/HTTP 表面、节点配对和更重的网络
  • 预期:
  • 在 CI 中运行(当 pipeline 启用时)
  • 不需要真实密钥
  • 比单元测试有更多移动部件(可能更慢)

E2E:OpenShell 后端 smoke

  • 命令:pnpm test:e2e:openshell
  • 文件:extensions/openshell/src/backend.e2e.test.ts
  • 范围:
  • 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关
  • 从临时本地 Dockerfile 创建一个沙箱
  • 通过真实的 sandbox ssh-config + SSH exec 演练 OpenClaw 的 OpenShell 后端
  • 通过沙箱 fs bridge 验证远程规范文件系统行为
  • 预期:
  • 仅 opt-in;不属于默认 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 binary 或 wrapper script

Live(真实提供商 + 真实模型)

  • 命令:pnpm test:live
  • 配置:vitest.live.config.ts
  • 文件:src/**/*.live.test.tstest/**/*.live.test.ts,以及 extensions/ 下的内置插件 live 测试
  • 默认值:由 pnpm test:live 启用(设置 OPENCLAW_LIVE_TEST=1
  • 范围:
  • “这个提供商/模型在 今天 使用真实凭据时是否真的可用?”
  • 捕获提供商格式变更、工具调用差异、认证问题和速率限制行为
  • 预期:
  • 设计上并非 CI 稳定(真实网络、真实提供商策略、配额、故障)
  • 会产生费用 / 使用速率限制额度
  • 优先运行缩小范围后的子集,而不是“所有内容”
  • Live 运行会读取 ~/.profile,以获取缺失的 API key。
  • 默认情况下,live 运行仍会隔离 HOME,并将配置/认证材料复制到临时测试 home 中,因此单元测试 fixture 无法修改你的真实 ~/.openclaw
  • 只有在你有意让 live 测试使用真实 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_KEYSANTHROPIC_API_KEYSGEMINI_API_KEYS),或通过 OPENCLAW_LIVE_*_KEY 进行每次 live 覆盖;测试会在收到速率限制响应时重试。
  • 进度/heartbeat 输出:
  • Live 套件现在会向 stderr 输出进度行,因此即使 Vitest 控制台捕获处于安静状态,耗时较长的提供商调用也能显示为活跃。
  • vitest.live.config.ts 禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在 live 运行期间立即流式输出。
  • 使用 OPENCLAW_LIVE_HEARTBEAT_MS 调整直接模型 heartbeat。
  • 使用 OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS 调整 Gateway 网关/探测 heartbeat。

我应该运行哪个套件?

使用此决策表:

  • 编辑逻辑/测试:运行 pnpm test(如果你改动较多,也运行 pnpm test:coverage
  • 触及 Gateway 网关网络 / WS 协议 / 配对:添加 pnpm test:e2e
  • 调试“我的机器人宕机了” / 提供商特定故障 / 工具调用:运行缩小范围后的 pnpm test:live

Live(触网)测试

有关 live 模型矩阵、CLI 后端 smoke、ACP smoke、Codex 应用服务器
harness,以及所有媒体提供商 live 测试(Deepgram、BytePlus、ComfyUI、图像、
音乐、视频、媒体 harness),以及 live 运行的凭据处理,请参阅
Testing live suites。有关专用更新和
插件验证清单,请参阅
更新和插件测试

Docker runner(可选的“在 Linux 中可用”检查)

这些 Docker runner 分为两类:

  • Live 模型 runner:test:docker:live-modelstest:docker:live-gateway 只会在仓库 Docker 镜像中运行其匹配的 profile-key live 文件(src/agents/models.profiles.live.test.tssrc/gateway/gateway-models.profiles.live.test.ts),挂载你的本地配置目录和工作区(如果已挂载,也会读取 ~/.profile)。匹配的本地入口点是 test:live:models-profilestest:live:gateway-profiles
  • Docker live runner 默认使用较小的 smoke 上限,以便完整 Docker sweep 仍然实用:
    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 构建一次 live Docker 镜像,通过 scripts/package-openclaw-for-docker.mjs 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 scripts/e2e/Dockerfile 镜像。bare 镜像只是用于安装/更新/插件依赖 lane 的 Node/Git runner;这些 lane 会挂载预构建的 tarball。functional 镜像会把同一个 tarball 安装到 /app,用于构建后应用功能 lane。Docker lane 定义位于 scripts/lib/docker-e2e-scenarios.mjs;planner 逻辑位于 scripts/lib/docker-e2e-plan.mjsscripts/test-docker-all.mjs 执行所选计划。聚合运行使用加权本地调度器:OPENCLAW_DOCKER_ALL_PARALLELISM 控制进程 slot,而资源上限会避免重型 live、npm-install 和多服务 lane 同时全部启动。如果单个 lane 比当前上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到再次有可用容量。默认值为 10 个 slot、OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9OPENCLAW_DOCKER_ALL_NPM_LIMIT=10OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7;仅当 Docker 主机有更多余量时,才调整 OPENCLAW_DOCKER_ALL_WEIGHT_LIMITOPENCLAW_DOCKER_ALL_DOCKER_LIMIT。runner 默认执行 Docker preflight,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印 Status,将成功 lane 的耗时存储在 .artifacts/docker-tests/lane-timings.json,并在后续运行中使用这些耗时优先启动更长的 lane。使用 OPENCLAW_DOCKER_ALL_DRY_RUN=1 可在不构建或运行 Docker 的情况下打印加权 lane 清单,或使用 node scripts/test-docker-all.mjs --plan-json 打印所选 lane、package/image 需求和凭据的 CI 计划。
  • Package Acceptance 是 GitHub 原生的 package 门禁,用于回答“这个可安装的 tarball 作为产品是否可用?”它会从 source=npmsource=refsource=urlsource=artifact 解析一个候选 package,将其上传为 package-under-test,然后针对该确切 tarball 运行可复用的 Docker E2E lane,而不是重新打包所选 ref。Profile 按覆盖范围排序:smokepackageproductfull。有关 package/更新/插件契约、已发布升级 survivor 矩阵、发布默认值和失败分诊,请参阅更新和插件测试
  • 构建和发布检查会在 tsdown 后运行 scripts/check-cli-bootstrap-imports.mjs。该保护会从 dist/entry.jsdist/cli/run-main.js 遍历静态构建图,并在命令分发前的启动阶段导入 Commander、prompt UI、undici 或日志等 package 依赖时失败;它还会让内置 Gateway 网关运行 chunk 保持在预算内,并拒绝对已知冷 Gateway 网关路径的静态导入。打包后的 CLI smoke 还覆盖根帮助、新手引导帮助、Doctor 帮助、Status、配置 schema 和 model-list 命令。
  • Package Acceptance 旧版兼容性上限为 2026.4.25(包括 2026.4.25-beta.*)。在该截止点之前,harness 仅容忍已发布 package 的元数据缺口:省略的私有 QA inventory 条目、缺失的 gateway install --wrapper、tarball 派生 git fixture 中缺失的补丁文件、缺失的持久化 update.channel、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 plugins update 期间的配置元数据迁移。对于 2026.4.25 之后的 package,这些路径都是严格失败。
  • 容器 smoke runner:test:docker:openwebuitest:docker:onboardtest:docker:npm-onboard-channel-agenttest:docker:skill-installtest:docker:update-channel-switchtest:docker:upgrade-survivortest:docker:published-upgrade-survivortest:docker:session-runtime-contexttest:docker:agents-delete-shared-workspacetest:docker:gateway-networktest:docker:browser-cdp-snapshottest:docker:mcp-channelstest:docker:pi-bundle-mcp-toolstest:docker:cron-mcp-cleanuptest:docker:pluginstest:docker:plugin-updatetest:docker:plugin-lifecycle-matrixtest:docker:config-reload 会启动一个或多个真实容器,并验证更高层级的集成路径。

Live 模型 Docker runner 还只会 bind-mount 所需的 CLI auth home(或者在运行未缩小时挂载所有受支持的 auth home),然后在运行前将它们复制到容器 home 中,以便外部 CLI OAuth 可以刷新 token,而不会修改宿主机 auth 存储:

  • 直接模型: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;默认覆盖 Claude、Codex 和 Gemini,并通过 pnpm test:docker:live-acp-bind:droidpnpm test:docker:live-acp-bind:opencode 严格覆盖 Droid/OpenCode)
  • CLI 后端冒烟测试:pnpm test:docker:live-cli-backend(脚本:scripts/test-live-cli-backend-docker.sh
  • Codex 应用服务器测试框架冒烟测试: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
  • 可观测性冒烟测试:pnpm qa:otel:smoke 是私有 QA 源码检出测试通道。它有意不属于包 Docker 发布通道,因为 npm 压缩包会省略 QA Lab。
  • Open WebUI 实时冒烟测试:pnpm test:docker:openwebui(脚本:scripts/e2e/openwebui-docker.sh
  • 新手引导向导(TTY,完整脚手架):pnpm test:docker:onboard(脚本:scripts/e2e/onboard-docker.sh
  • Npm 压缩包新手引导/渠道/智能体冒烟测试:pnpm test:docker:npm-onboard-channel-agent 会在 Docker 中全局安装打包后的 OpenClaw 压缩包,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,运行 Doctor,然后运行一次模拟的 OpenAI 智能体轮次。可用 OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz 复用预构建压缩包,用 OPENCLAW_NPM_ONBOARD_HOST_BUILD=0 跳过主机重建,或用 OPENCLAW_NPM_ONBOARD_CHANNEL=discordOPENCLAW_NPM_ONBOARD_CHANNEL=slack 切换渠道。
  • Skill 安装冒烟测试:pnpm test:docker:skill-install 会在 Docker 中全局安装打包后的 OpenClaw 压缩包,在配置中禁用上传归档安装,从搜索中解析当前实时 ClawHub Skill slug,用 openclaw skills install 安装它,并验证已安装的 Skill 以及 .clawhub 来源/锁定元数据。
  • 更新频道切换冒烟测试:pnpm test:docker:update-channel-switch 会在 Docker 中全局安装打包后的 OpenClaw 压缩包,从包 stable 切换到 git dev,验证持久化的频道和插件更新后可工作,然后切回包 stable 并检查更新状态。
  • 升级存活冒烟测试:pnpm test:docker:upgrade-survivor 会把打包后的 OpenClaw 压缩包安装到一个脏的旧用户夹具上,该夹具包含智能体、渠道配置、插件允许列表、过期插件依赖状态以及现有工作区/会话文件。它会运行包更新和非交互式 Doctor,不需要实时提供商或渠道密钥,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/状态预算。
  • 已发布版本升级存活冒烟测试:pnpm test:docker:published-upgrade-survivor 默认安装 openclaw@latest,播种真实的现有用户文件,用内置命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选压缩包,运行非交互式 Doctor,写入 .artifacts/upgrade-survivor/summary.json,然后启动一个 loopback Gateway 网关,并检查已配置意图、状态保留、启动、/healthz/readyz 和 RPC 状态预算。用 OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC 覆盖一个基线,要求聚合调度器用 OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS 展开精确本地基线,例如 openclaw@2026.5.2 openclaw@2026.4.23 openclaw@2026.4.15,并用 OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS 展开问题形态夹具,例如 reported-issuesreported-issues 集合包含 configured-plugin-installs,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将这些公开为 published_upgrade_survivor_baselinepublished_upgrade_survivor_baselinespublished_upgrade_survivor_scenarios,解析 last-stable-4all-since-2026.4.23 等元基线令牌,并且 Full Release Validation 会把 release-soak 包门禁展开为 last-stable-4 2026.4.23 2026.5.2 2026.4.15reported-issues
  • 会话运行时上下文冒烟测试:pnpm test:docker:session-runtime-context 会验证隐藏运行时上下文转录持久化,以及 Doctor 对受影响的重复提示重写分支的修复。
  • Bun 全局安装冒烟测试:bash scripts/e2e/bun-global-install-smoke.sh 会打包当前树,在隔离 home 中用 bun install -g 安装它,并验证 openclaw infer image providers --json 返回内置图像提供商而不是挂起。可用 OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz 复用预构建压缩包,用 OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0 跳过主机构建,或用 OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local 从已构建的 Docker 镜像复制 dist/
  • 安装器 Docker 冒烟测试:bash scripts/test-install-sh-docker.sh 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm latest 作为稳定基线,然后升级到候选压缩包。可在本地用 OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22 覆盖,或在 GitHub 上用 Install Smoke 工作流的 update_baseline_version 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache 可在本地重复运行之间复用 root/update/direct-npm 缓存。
  • Install Smoke CI 会用 OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1 跳过重复的 direct-npm 全局更新;需要覆盖直接 npm install -g 时,在本地运行脚本且不设置该环境变量。
  • 智能体删除共享工作区 CLI 冒烟测试:pnpm test:docker:agents-delete-shared-workspace(脚本:scripts/e2e/agents-delete-shared-workspace-docker.sh)默认构建根 Dockerfile 镜像,在隔离容器 home 中播种两个智能体和一个工作区,运行 agents delete --json,并验证有效 JSON 以及工作区保留行为。可用 OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1 复用 install-smoke 镜像。
  • Gateway 网关联网(两个容器,WS 凭证 + 健康检查):pnpm test:docker:gateway-network(脚本:scripts/e2e/gateway-network-docker.sh
  • 浏览器 CDP 快照冒烟测试:pnpm test:docker:browser-cdp-snapshot(脚本:scripts/e2e/browser-cdp-snapshot-docker.sh)会构建源码 E2E 镜像和一个 Chromium 层,用原始 CDP 启动 Chromium,运行 browser doctor --deep,并验证 CDP 角色快照覆盖链接 URL、光标提升的可点击项、iframe 引用和 frame 元数据。
  • OpenAI Responses web_search 最小推理回归:pnpm test:docker:openai-web-search-minimal(脚本:scripts/e2e/openai-web-search-minimal-docker.sh)会通过 Gateway 网关运行一个模拟的 OpenAI 服务器,验证 web_searchreasoning.effortminimal 提升到 low,然后强制提供商 schema 拒绝,并检查原始详情出现在 Gateway 网关日志中。
  • MCP 渠道桥接(播种的 Gateway 网关 + stdio 桥接 + 原始 Claude 通知 frame 冒烟测试):pnpm test:docker:mcp-channels(脚本:scripts/e2e/mcp-channels-docker.sh
  • Pi 包 MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile 允许/拒绝冒烟测试):pnpm test:docker:pi-bundle-mcp-tools(脚本:scripts/e2e/pi-bundle-mcp-tools-docker.sh
  • Cron/subagent MCP 清理(真实 Gateway 网关 + 隔离 cron 和一次性 subagent 运行后的 stdio MCP 子进程拆除):pnpm test:docker:cron-mcp-cleanup(脚本:scripts/e2e/cron-mcp-cleanup-docker.sh
  • 插件(本地路径、file:、带提升依赖的 npm registry、git 移动引用、ClawHub kitchen-sink、marketplace 更新以及 Claude-bundle 启用/检查的安装/更新冒烟测试):pnpm test:docker:plugins(脚本:scripts/e2e/plugins-docker.sh
    设置 OPENCLAW_PLUGINS_E2E_CLAWHUB=0 可跳过 ClawHub 块,或用 OPENCLAW_PLUGINS_E2E_CLAWHUB_SPECOPENCLAW_PLUGINS_E2E_CLAWHUB_ID 覆盖默认 kitchen-sink 包/运行时对。如果没有 OPENCLAW_CLAWHUB_URL/CLAWHUB_URL,测试会使用密封的本地 ClawHub 夹具服务器。
  • 插件未变化更新冒烟测试:pnpm test:docker:plugin-update(脚本:scripts/e2e/plugin-update-unchanged-docker.sh
  • 插件生命周期矩阵冒烟测试:pnpm test:docker:plugin-lifecycle-matrix 会在裸容器中安装打包后的 OpenClaw 压缩包,安装一个 npm 插件,切换启用/禁用,通过本地 npm registry 升级和降级它,删除已安装代码,然后验证卸载仍会移除过期状态,同时记录每个生命周期阶段的 RSS/CPU 指标。
  • 配置重载元数据冒烟测试:pnpm test:docker:config-reload(脚本:scripts/e2e/config-reload-source-docker.sh
  • 插件:pnpm test:docker:plugins 覆盖本地路径、file:、带提升依赖的 npm registry、git 移动引用、ClawHub 夹具、marketplace 更新以及 Claude-bundle 启用/检查的安装/更新冒烟测试。pnpm test:docker:plugin-update 覆盖已安装插件的未变化更新行为。pnpm test:docker:plugin-lifecycle-matrix 覆盖带资源跟踪的 npm 插件安装、启用、禁用、升级、降级和缺失代码卸载。

要手动预构建并复用共享功能镜像:

OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-build
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels

设置后,套件专属镜像覆盖项(例如 OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE)仍会优先生效。当 OPENCLAW_SKIP_DOCKER_BUILD=1 指向远程共享镜像时,如果本地尚不存在,脚本会拉取它。QR 和安装器 Docker 测试保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。

live-model Docker 运行器还会将当前 checkout 以只读方式 bind-mount,
并在容器内暂存到临时 workdir 中。这样可以保持运行时
镜像精简,同时仍然针对你的精确本地源代码/配置运行 Vitest。
暂存步骤会跳过大型的仅本地缓存和应用构建输出,例如
.pnpm-store.worktrees__openclaw_vitest__,以及应用本地 .build
Gradle 输出目录,因此 Docker live 运行不会花费数分钟复制
机器特定的产物。
它们还会设置 OPENCLAW_SKIP_CHANNELS=1,因此 Gateway 网关 live 探测不会在容器内启动
真实的 Telegram/Discord 等渠道 worker。
test:docker:live-models 仍然运行 pnpm test:live,所以当你需要缩小或排除该 Docker lane 中的 Gateway 网关
live 覆盖范围时,也要传入
OPENCLAW_LIVE_GATEWAY_*
test:docker:openwebui 是更高层级的兼容性 smoke:它会启动一个
启用了 OpenAI 兼容 HTTP 端点的 OpenClaw 网关容器,
针对该网关启动一个固定版本的 Open WebUI 容器,通过
Open WebUI 登录,验证 /api/models 暴露 openclaw/default,然后通过 Open WebUI 的
/api/chat/completions 代理发送一次
真实聊天请求。
对于发布路径 CI 检查,如果应在 Open WebUI 登录和模型发现后停止,
且不等待 live 模型补全,请设置 OPENWEBUI_SMOKE_MODE=models
首次运行可能明显更慢,因为 Docker 可能需要拉取
Open WebUI 镜像,并且 Open WebUI 可能需要完成自己的冷启动设置。
该 lane 需要可用的 live 模型 key,而 OPENCLAW_PROFILE_FILE
(默认是 ~/.profile)是在 Docker 化运行中提供它的主要方式。
成功运行会打印一个小型 JSON payload,例如 { "ok": true, "model":
"openclaw/default", ... }

test:docker:mcp-channels 是刻意确定性的,不需要
真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带种子的 Gateway 网关
容器,启动第二个会生成 openclaw mcp serve 的容器,然后
验证路由会话发现、transcript 读取、附件元数据、
live 事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 +
权限通知。通知检查会直接检查原始 stdio MCP frame,因此该 smoke 验证的是
bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。
test:docker:pi-bundle-mcp-tools 是确定性的,不需要 live
模型 key。它会构建 repo Docker 镜像,在容器内启动一个真实 stdio MCP probe server,
通过嵌入式 Pi bundle
MCP 运行时物化该 server,执行该工具,然后验证 codingmessaging 保留
bundle-mcp 工具,而 minimaltools.deny: ["bundle-mcp"] 会过滤它们。
test:docker:cron-mcp-cleanup 是确定性的,不需要 live 模型
key。它会启动一个带种子的 Gateway 网关,并带有真实 stdio MCP probe server,运行一次
隔离的 cron turn 和一次 /subagents spawn one-shot child turn,然后验证
MCP child process 在每次运行后退出。

手动 ACP plain-language thread smoke(非 CI):

  • bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...
  • 保留此脚本用于回归/调试工作流。ACP thread routing 验证可能还会再次需要它,因此不要删除。

有用的环境变量:

  • OPENCLAW_CONFIG_DIR=...(默认:~/.openclaw)挂载到 /home/node/.openclaw
  • OPENCLAW_WORKSPACE_DIR=...(默认:~/.openclaw/workspace)挂载到 /home/node/.openclaw/workspace
  • OPENCLAW_PROFILE_FILE=...(默认:~/.profile)挂载到 /home/node/.profile,并在运行测试前 source
  • OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1 仅验证从 OPENCLAW_PROFILE_FILE source 的环境变量,使用临时配置/工作区目录,且不挂载外部 CLI auth
  • OPENCLAW_DOCKER_CLI_TOOLS_DIR=...(默认:~/.cache/openclaw/docker-cli-tools)挂载到 /home/node/.npm-global,用于 Docker 内缓存的 CLI 安装
  • $HOME 下的外部 CLI auth 目录/文件会以只读方式挂载到 /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=allOPENCLAW_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 store(而不是 env)
  • OPENCLAW_OPENWEBUI_MODEL=... 用于选择 Gateway 网关为 Open WebUI smoke 暴露的模型
  • OPENCLAW_OPENWEBUI_PROMPT=... 用于覆盖 Open WebUI smoke 使用的 nonce 检查 prompt
  • OPENWEBUI_IMAGE=... 用于覆盖固定的 Open WebUI 镜像 tag

文档完整性检查

文档编辑后运行文档检查:pnpm check:docs
当你还需要页内 heading 检查时,运行完整 Mintlify anchor 验证:pnpm docs:check-links:anchors

离线回归(CI 安全)

这些是不使用真实提供商的“真实 pipeline”回归:

  • Gateway 网关工具调用(mock OpenAI,真实 Gateway 网关 + Agent loop):src/gateway/gateway.test.ts(用例:"runs a mock OpenAI tool call end-to-end via gateway agent loop")
  • Gateway 网关向导(WS wizard.start/wizard.next,写入配置 + 强制 auth):src/gateway/gateway.test.ts(用例:"runs wizard over ws and writes auth token config")

智能体可靠性评估(Skills)

我们已经有一些 CI 安全测试,其行为类似“智能体可靠性评估”:

  • 通过真实 Gateway 网关 + Agent loop 进行 mock 工具调用(src/gateway/gateway.test.ts)。
  • 验证会话 wiring 和配置效果的端到端向导流程(src/gateway/gateway.test.ts)。

Skills 仍然缺少的内容(见 Skills):

  • 决策: 当 Skills 在 prompt 中列出时,智能体是否选择正确的 Skill(或避开无关的 Skill)?
  • 合规性: 智能体是否在使用前读取 SKILL.md,并遵循必需步骤/参数?
  • 工作流契约: 断言工具顺序、会话历史延续和沙箱边界的多轮场景。

未来评估应首先保持确定性:

  • 使用 mock 提供商的 scenario runner,用于断言工具调用 + 顺序、Skill 文件读取和会话 wiring。
  • 一小组聚焦 Skill 的场景(使用 vs 避免、gating、prompt injection)。
  • 可选 live 评估(opt-in、env-gated)只在 CI 安全套件就位后添加。

契约测试(插件和渠道形态)

契约测试会验证每个注册的插件和渠道都符合其
接口契约。它们会遍历所有发现的插件,并运行一组
形态和行为断言。默认的 pnpm test unit lane 会刻意
跳过这些共享 seam 和 smoke 文件;当你触碰共享渠道或提供商 surface 时,
请显式运行契约命令。

命令

  • 所有契约:pnpm test:contracts
  • 仅渠道契约:pnpm test:contracts:channels
  • 仅提供商契约:pnpm test:contracts:plugins

渠道契约

位于 src/channels/plugins/contracts/*.contract.test.ts

  • plugin - 基本插件形态(id、name、capabilities)
  • setup - 设置向导契约
  • session-binding - 会话绑定行为
  • outbound-payload - 消息 payload 结构
  • inbound - 入站消息处理
  • actions - 渠道 action handlers
  • threading - Thread ID 处理
  • directory - Directory/roster API
  • group-policy - 群组策略执行

提供商状态契约

位于 src/plugins/contracts/*.contract.test.ts

  • status - 渠道状态探测
  • registry - 插件 registry 形态

提供商契约

位于 src/plugins/contracts/*.contract.test.ts

  • auth - Auth 流程契约
  • auth-choice - Auth 选择/选取
  • catalog - 模型 catalog API
  • discovery - 插件发现
  • loader - 插件加载
  • runtime - 提供商运行时
  • shape - 插件形态/接口
  • wizard - 设置向导

何时运行

  • 在更改 plugin-sdk exports 或 subpaths 后
  • 在添加或修改渠道或提供商插件后
  • 在重构插件注册或发现后

契约测试会在 CI 中运行,并且不需要真实 API keys。

添加回归(指南)

当你修复 live 中发现的提供商/模型问题时:

  • 尽可能添加 CI 安全回归(mock/stub 提供商,或捕获精确的 request-shape 转换)
  • 如果它本质上只能 live 运行(rate limits、auth policies),请保持 live 测试范围狭窄,并通过环境变量 opt-in
  • 优先针对能捕获 bug 的最小层级:
  • 提供商请求转换/replay bug → 直接 models 测试
  • Gateway 网关会话/history/tool pipeline bug → Gateway 网关 live smoke 或 CI 安全 Gateway 网关 mock 测试
  • SecretRef 遍历 guardrail:
  • src/secrets/exec-secret-ref-id-parity.test.ts 会从 registry metadata(listSecretTargetRegistryEntries())为每个 SecretRef class 派生一个采样目标,然后断言 traversal-segment exec ids 会被拒绝。
  • 如果你在 src/secrets/target-registry-data.ts 中添加新的 includeInPlan SecretRef 目标 family,请更新该测试中的 classifyTargetClass。该测试会刻意在未分类的目标 ids 上失败,因此新 class 不能被静默跳过。

相关


📄 脚本

原文:https://docs.openclaw.ai/zh-CN/help/scripts

scripts/ 目录包含用于本地工作流和运维任务的辅助脚本。
当任务明确与某个脚本相关时使用这些脚本;否则优先使用 CLI。

约定

  • 除非在文档或发布检查清单中引用,否则脚本都是可选的
  • 存在 CLI 界面时优先使用它们(示例:凭证监控使用 openclaw models status --check)。
  • 假定脚本与宿主机相关;在新机器上运行前先阅读它们。

身份验证监控脚本

身份验证监控在 身份验证 中说明。scripts/ 下的脚本是 systemd/Termux 手机工作流的可选补充。

GitHub 读取助手

当你希望 gh 使用 GitHub App 安装令牌执行仓库范围的读取调用,同时让普通 gh 继续使用你的个人登录执行写入操作时,请使用 scripts/gh-read

必需环境变量:

  • OPENCLAW_GH_READ_APP_ID
  • OPENCLAW_GH_READ_PRIVATE_KEY_FILE

可选环境变量:

  • 当你想跳过基于仓库的安装查找时,使用 OPENCLAW_GH_READ_INSTALLATION_ID
  • 使用 OPENCLAW_GH_READ_PERMISSIONS 作为逗号分隔的覆盖值,指定要请求的读取权限子集

仓库解析顺序:

  • gh ... -R owner/repo
  • GH_REPO
  • git remote origin

示例:

  • scripts/gh-read pr view 123
  • scripts/gh-read run list -R openclaw/openclaw
  • scripts/gh-read api repos/openclaw/openclaw/pulls/123

添加脚本时

  • 保持脚本聚焦且有文档说明。
  • 在相关文档中添加一条简短条目(如果缺失,则创建一个)。

相关内容


📄 Node + tsx 崩溃

原文:https://docs.openclaw.ai/zh-CN/debug/node-issue

Node + tsx “__name is not a function” 崩溃

摘要

通过 Node 搭配 tsx 运行 OpenClaw 时,启动阶段会失败并显示:

[openclaw] Failed to start CLI: TypeError: __name is not a function
    at createSubsystemLogger (.../src/logging/subsystem.ts:203:25)
    at .../src/agents/auth-profiles/constants.ts:25:20

这始于将开发脚本从 Bun 切换到 tsx 之后(提交 2871657e,2026-01-06)。相同运行时路径在 Bun 下可以正常工作。

环境

  • Node:v25.x(在 v25.3.0 上观察到)
  • tsx:4.21.0
  • OS:macOS(复现也很可能出现在其他运行 Node 25 的平台上)

复现(仅 Node)

# in repo root
node --version
pnpm install
node --import tsx src/entry.ts status

仓库中的最小复现

node --import tsx scripts/repro/tsx-name-repro.ts

Node 版本检查

  • Node 25.3.0:失败
  • Node 22.22.0(Homebrew node@22):失败
  • Node 24:此处尚未安装;需要验证

备注 / 假设

  • tsx 使用 esbuild 转换 TS/ESM。esbuild 的 keepNames 会生成 __name 辅助函数,并用 __name(...) 包装函数定义。
  • 崩溃表明运行时 __name 存在但不是函数,这意味着在 Node 25 加载器路径中,该模块的辅助函数缺失或被覆盖。
  • 其他 esbuild 使用者中也报告过类似的 __name 辅助函数问题,原因是辅助函数缺失或被重写。

回归历史

  • 2871657e(2026-01-06):脚本从 Bun 改为 tsx,以便让 Bun 成为可选项。
  • 在此之前(Bun 路径),openclaw statusgateway:watch 可以工作。

解决方法

  • 对开发脚本使用 Bun(当前的临时回退方案)。
  • 使用 tsgo 进行仓库类型检查,然后运行构建输出:

bash
pnpm tsgo
node openclaw.mjs status

  • 历史备注:调试此 Node/tsx 问题时这里曾使用 tsc,但仓库类型检查通道现在使用 tsgo
  • 如果可以,在 TS 加载器中禁用 esbuild keepNames(防止插入 __name 辅助函数);tsx 目前不暴露此选项。
  • 使用 tsx 测试 Node LTS(22/24),以判断该问题是否特定于 Node 25。

参考

后续步骤

  • 在 Node 22/24 上复现,以确认 Node 25 回归。
  • 测试 tsx nightly,或在存在已知回归时固定到较早版本。
  • 如果在 Node LTS 上可复现,带着 __name 堆栈跟踪向上游提交最小复现。

相关内容


📄 诊断标志

原文:https://docs.openclaw.ai/zh-CN/diagnostics/flags

诊断标志允许你启用有针对性的调试日志,而不必在所有地方开启详细日志。标志是选择性启用的,除非某个子系统检查它们,否则不会产生任何影响。

工作原理

  • 标志是字符串(不区分大小写)。
  • 你可以在配置中启用标志,也可以通过环境变量覆盖启用。
  • 支持通配符:
  • telegram.* 匹配 telegram.http
  • * 启用所有标志

通过配置启用

{
  "diagnostics": {
    "flags": ["telegram.http"]
  }
}

多个标志:

{
  "diagnostics": {
    "flags": ["telegram.http", "brave.http", "gateway.*"]
  }
}

更改标志后重启 Gateway 网关。

环境变量覆盖(一次性)

OPENCLAW_DIAGNOSTICS=telegram.http,telegram.payload

禁用所有标志:

OPENCLAW_DIAGNOSTICS=0

时间线构件

timeline 标志会为外部 QA harness 写入结构化的启动和运行时计时事件:

OPENCLAW_DIAGNOSTICS=timeline \
OPENCLAW_DIAGNOSTICS_TIMELINE_PATH=/tmp/openclaw-timeline.jsonl \
openclaw gateway run

你也可以在配置中启用它:

{
  "diagnostics": {
    "flags": ["timeline"]
  }
}

时间线文件路径仍然来自 OPENCLAW_DIAGNOSTICS_TIMELINE_PATH。当 timeline 仅从配置中启用时,最早的配置加载 span 不会被发出,因为 OpenClaw 尚未读取配置;后续启动 span 会使用配置标志。

OPENCLAW_DIAGNOSTICS=1OPENCLAW_DIAGNOSTICS=allOPENCLAW_DIAGNOSTICS=* 也会启用时间线,因为它们会启用所有诊断标志。当你只需要 JSONL 计时构件时,优先使用 timeline

时间线记录使用 openclaw.diagnostics.v1 信封。事件可以包含进程 ID、阶段名称、span 名称、持续时间、插件 ID、依赖项数量、事件循环延迟样本、提供商操作名称、子进程退出状态,以及启动错误名称/消息。将时间线文件视为本地诊断构件;在分享给你的机器外部之前,请先审阅它们。

日志位置

标志会将日志发出到标准诊断日志文件。默认情况下:

/tmp/openclaw/openclaw-YYYY-MM-DD.log

如果你设置了 logging.file,请改用该路径。日志是 JSONL(每行一个 JSON 对象)。脱敏仍会基于 logging.redactSensitive 应用。

提取日志

选择最新的日志文件:

ls -t /tmp/openclaw/openclaw-*.log | head -n 1

筛选 Telegram HTTP 诊断:

rg "telegram http error" /tmp/openclaw/openclaw-*.log

筛选 Brave Search HTTP 诊断:

rg "brave http" /tmp/openclaw/openclaw-*.log

或在复现时跟踪:

tail -f /tmp/openclaw/openclaw-$(date +%F).log | rg "telegram http error"

对于远程 Gateway 网关,你也可以使用 openclaw logs --follow(参见 /cli/logs)。

注意事项

  • 如果 logging.level 设置得高于 warn,这些日志可能会被抑制。默认的 info 没问题。
  • brave.http 会记录 Brave Search 请求 URL/查询参数、响应状态/计时,以及缓存命中/未命中/写入事件。它不会记录 API 密钥或响应正文,但搜索查询可能包含敏感信息。
  • 标志可以安全地保持启用;它们只会影响特定子系统的日志量。
  • 使用 /logging 更改日志目标位置、级别和脱敏设置。

相关

上一篇 [OpenClaw 文档]帮助--社区
下一篇 三层交换机和路由器有什么区别?