跳转至

Slack QA

Slack QA

pnpm openclaw qa slack

该命令以一个真实的私有 Slack 频道为目标,包含两个不同的 Bot:一个由测试框架控制的驱动 Bot,以及一个由子 OpenClaw 网关通过内置 Slack 插件启动的 SUT Bot。

Slack QA 适配器加载后,需要异步代理捕获支持,以便可以在 Gateway 线程上不运行 SQLite 的情况下读取写入证据。如果缺少该能力,适配器创建过程会要求你先升级,然后再获取凭据或联系 Slack。这并不能保证当前 QA CLI 能在较旧主机上加载:请使用匹配的当前源码检出,并参阅旧主机导入限制。

Agent E2E 配方

使用被测源码检出中的 .agents/skills/slack-e2e/SKILL.md,获取可复用的原生 fixtures、Gateway 回复以及运行时/配置实验。如果已有能访问 QA broker 的已认证 Convex CLI:

pnpm openclaw qa slack --doctor
pnpm openclaw qa slack \
  --scenario-file qa/scenarios/channels/slack-e2e-lifecycle.yaml

这些可选模式会在内存中发现凭据,并默认使用 Convex、CI 角色和 mock-openai。显式标志或凭据环境设置优先;普通 qa slack 的默认行为保持不变。对于声明了 execution.channel: slack 和 execution.config.agentE2e: true 的完整自定义 YAML 流程,请重复使用 --scenario-file。原生写入只执行一次;正数 retryCount 值会被拒绝。

就绪检查会核验实际租约(lease)的身份、共享工作区、频道访问权限、Gateway 连接以及声明的权限范围。完整生命周期还要求 driver 具备 reactions:read、reactions:write、files:read 和 files:write。下面的 driver 清单包含这些能力。现有安装需要应用所有者添加缺失的权限范围并重新安装应用,然后才能重新运行生命周期。缺少某个权限范围会阻塞该操作和完整生命周期验证,但不会影响基本文本流程。运行器不会为了得到通过的结果而授予权限或轮换凭据。这些 fixture 操作由 Bot OAuth 权限范围授权,而非工作区管理员权限。

driver 使用 Web API 调用;只有 SUT 拥有 Socket Mode。已存储的消息/文件/回应(reaction)回读可证明原生状态,而相关联的 SUT 回复可证明 Gateway 的入站与投递。两者都无法证明客户端渲染、人工斜杠命令、按钮点击、Agent View 或人工输入。如需验证这些主张,请使用手动客户端工作流。

清理会在进程关闭之后、临时捕获状态被移除之前,捕获最终的 Gateway 写入回执;然后在释放租约之前,仅移除自己拥有的 fixtures。私有的 <scenario-id>-slack-e2e.json 回执可区分已接受的写入、已存储的状态和未完成的清理。

直接凭据设置

当使用 --credential-source env 时,所需的环境变量:

  • OPENCLAW_QA_SLACK_CHANNEL_ID
  • OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_APP_TOKEN

可选:

  • OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR 为 Mantis 启用可视化审批检查点。适配器会写入 <scenario>.pending.json 和 <scenario>.resolved.json,然后等待匹配的 .ack.json 文件。
  • OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MS 覆盖检查点确认超时时间。默认值为 120000。

通过 Slack 实时适配器公开的标准 YAML 场景:

  • thread-follow-up
  • thread-isolation

Slack YAML 模块场景(qa/scenarios/channels/slack-*.yaml):

  • slack-canary
  • slack-mention-gating
  • slack-mpim-app-mention-dedupe - 打开一个真实的 C 前缀群组 DM,在消息/app-mention 双投递后验证恰好只有一条 SUT 回复,确认原生线程跟进可以取回该 Bot 回复,然后关闭该 MPIM。
  • slack-allowlist-block
  • slack-channel-disabled-warning - 一个可选的真实 Slack 探测,确认配置为禁用的频道会发出结构化警告而不进行回复。
  • slack-top-level-reply-shape
  • slack-restart-resume
  • slack-progress-commentary-true、slack-progress-commentary-false、slack-progress-commentary-omitted 以及 slack-progress-commentary-verbose-dedupe / slack-progress-commentary-verbose-full - 这些可选的真实 Slack 探测用于独立的评论/工具进度控制、省略该键时的旧版默认行为,以及持久化 verbose 进度的单次投递行为。on 探测需要一个安全的 Exec 摘要,且不含命令文本或输出;full 探测要求在单独的工具输出消息中包含精确的 stdout 标记。两者使用同一条命令,并要求一个与最终答案分离的 commentary 身份。完整详细模式允许使用运行时的命令元数据和一个独立的开始摘要,但要求具有唯一的已完成输出身份。Slack 在投递时可能会去除命令摘要头部,因此标识已完成输出的是精确的输出行,而不是工具标签。失败时会保留有边界的展示事实,不包含原始 Slack 消息或平台身份,包括标记格式以及缺少命令标记的 sleep 摘要。
  • slack-reaction-glyph-native - 一个可选的实时消息工具 reaction 场景。指示 agent 传递精确的 ✅ 字形,并确认 Slack 在目标消息上为 SUT Bot 存储了 white_check_mark。
  • slack-chart-presentation-native - 一个可选的可移植图表场景,验证原生 data_visualization 块和精确的无障碍文本。
  • slack-table-presentation-native - 一个可选的可移植表格场景,验证原生 data_table 块、精确的行以及无障碍文本。
  • slack-table-invalid-blocks-fallback - 一个可选的直接传输场景,它通过生产环境的 Slack 发送路径发送一个结构上可读但超限的原始表格,包含 101 行数据及其表头,证明 Slack 本身会返回 invalid_blocks,并验证存储的禁用格式回退内容完整且不包含原生数据块。场景详情只保留安全的错误码、计数和布尔证据。
  • slack-approval-exec-native - 一个可选的原生 Slack exec 审批场景。通过网关请求 exec 审批,验证 Slack 消息带有原生审批按钮,处理该审批,并验证处理后的 Slack 更新。
  • slack-approval-plugin-native - 一个可选的原生 Slack 插件审批场景。同时启用 exec 和插件审批转发,使插件事件不会被 exec 审批路由抑制,然后验证相同的待处理/已解决原生 Slack UI 路径。
  • slack-codex-approval-exec-native - 一个可选的 Codex Guardian 命令审批场景。在 Guardian 模式下启用 Codex 插件,将通过 Slack 发起的 Gateway agent 回合路由到 Codex 应用服务器测试框架(app-server harness)中,等待针对 codex 的原生 Slack 插件审批提示,处理该审批,并验证 Codex 回合最终产生预期的命令输出和 assistant 标记。
  • slack-codex-approval-plugin-native - 一个可选的 Codex Guardian 文件审批场景。使用工作区外部的 apply_patch 指令,使 Codex 发出应用服务器文件变更审批路由,然后验证相同的原生 Slack 待处理/已解决审批路径、最终的 assistant 标记,并在清理前验证精确的文件内容。

Codex 审批场景需要一个 openai/* 或 codex/* --model、正常的实时模型凭据,以及 Codex 插件接受的 Codex 认证或 API 密钥认证。 场景详情包括 Codex app-server 方法、所选 Codex 模型键、最终 Codex 回合状态,以及经过脱敏的 Slack 审批元数据旁边的操作标记验证。

输出产物:

  • qa-suite-report.md
  • qa-suite-summary.json
  • qa-evidence.json - 实时传输检查的证据条目。
  • approval-checkpoints/ - 仅当 Mantis 设置 OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR 时;包含检查点 JSON、 确认 JSON,以及待处理/已解决截图。

设置 Slack 工作区

该 lane 需要在同一个工作区中有两个不同的 Slack 应用,以及一个两个 bot 都是成员的频道:

  • channelId - 两个 bot 都已被邀请加入的频道的 Cxxxxxxxxxx id。 请使用专用频道;该 lane 每次运行都会发帖。
  • driverBotToken - Driver 应用的 bot token(xoxb-...)。
  • sutBotToken - SUT 应用的 bot token(xoxb-...),它必须与 driver 是不同的 Slack 应用,以便其 bot user id 不同。
  • sutAppToken - SUT 应用的应用级 token(xapp-...),具有 connections:write,由 Socket Mode 使用,以便 SUT 应用可以接收事件。

优先使用专用于 QA 的 Slack 工作区,而不是复用生产工作区。

下面的 SUT manifest 有意将捆绑的 Slack 插件的生产安装 (extensions/slack/src/setup-shared.ts:12)缩小到实时 Slack QA 套件覆盖的 权限和事件。对于用户看到的生产频道设置,请参阅 Slack 频道快速设置;QA Driver/SUT 对是有意分开的,因为该 lane 需要在同一个工作区中有两个不同的 bot user id。

1. 创建 Driver 应用

前往 api.slack.com/apps → 创建新应用 → 从 manifest 创建 → 选择 QA 工作区,粘贴以下 manifest, 然后 安装到工作区:

{
  "display_information": {
    "name": "OpenClaw QA Driver",
    "description": "Test driver bot for OpenClaw QA Slack live lane"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw QA Driver",
      "always_online": true
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "channels:history",
        "chat:write",
        "files:read",
        "files:write",
        "groups:history",
        "reactions:read",
        "reactions:write",
        "users:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": false
  }
}

复制 Bot User OAuth Token(xoxb-...)——它将成为 driverBotToken。driver 可以读写 fixture 消息、reaction 和文件; 它既不需要事件订阅,也不需要 Socket Mode。

2. 创建 SUT 应用

在同一工作区中重复 创建新应用 → 从 manifest 创建。此 QA 应用 有意使用捆绑的 Slack 插件生产 manifest (extensions/slack/src/setup-shared.ts:12)的更窄版本: reaction 作用域和事件被省略,因为实时 Slack QA 套件尚未覆盖 reaction 处理。

{
  "display_information": {
    "name": "OpenClaw QA SUT",
    "description": "OpenClaw QA SUT connector for OpenClaw"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw QA SUT",
      "always_online": true
    },
    "app_home": {
      "home_tab_enabled": true,
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "app_mentions:read",
        "assistant:write",
        "channels:history",
        "channels:read",
        "chat:write",
        "commands",
        "emoji:read",
        "files:read",
        "files:write",
        "groups:history",
        "groups:read",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "pins:read",
        "pins:write",
        "usergroups:read",
        "users:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_home_opened",
        "app_mention",
        "channel_rename",
        "member_joined_channel",
        "member_left_channel",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "pin_added",
        "pin_removed"
      ]
    }
  }
}

Slack 创建应用后,在其设置页面上执行两项操作:

  • 安装到工作区 → 复制 Bot User OAuth Token → 它将成为 sutBotToken。
  • 基本信息 → 应用级 Token → 生成 Token 和 Scopes → 添加 作用域 connections:write → 保存 → 复制 xapp-... 值 → 它 将成为 sutAppToken。

通过分别对每个 token 调用 auth.test,验证两个 bot 具有不同的 user id。运行时通过 user id 区分 driver 和 SUT;将同一个应用 复用于两者会立即导致 mention-gating 失败。

3. 创建频道

在 QA 工作区中创建一个频道(例如 #openclaw-qa),并在频道内 邀请两个 bot:

/invite @OpenClaw QA Driver
/invite @OpenClaw QA SUT

从 频道信息 → 关于 → 频道 ID 复制 Cxxxxxxxxxx id——它 将成为 channelId。公共频道可以工作;如果使用私有频道, 两个应用已经具有 groups:history,因此 harness 的历史读取仍会 成功。

4. 注册凭据

有两种选择。对于单机器调试,使用环境变量(设置四个 OPENCLAW_QA_SLACK_* 变量并传递 --credential-source env),或者向 共享 Convex 池播种,以便 CI 和其他维护者可以借用它们。

对于 Convex 池,将四个字段写入一个 JSON 文件:

{
  "channelId": "Cxxxxxxxxxx",
  "driverBotToken": "xoxb-...",
  "sutBotToken": "xoxb-...",
  "sutAppToken": "xapp-..."
}

在你的 shell 中导出 OPENCLAW_QA_CONVEX_SITE_URL 和 OPENCLAW_QA_CONVEX_SECRET_MAINTAINER 后,注册并验证:

pnpm openclaw qa credentials add \
  --kind slack \
  --payload-file slack-creds.json \
  --note "QA Slack pool seed"

pnpm openclaw qa credentials list --kind slack --status all --json

预期 count: 1、status: "active",且没有 lease 字段。

5. 端到端验证

在本地运行该 lane,以确认两个 bot 可以通过 broker 相互通信:

pnpm openclaw qa slack \
  --credential-source convex \
  --credential-role maintainer \
  --output-dir .artifacts/qa-e2e/slack-local

绿色运行会在远小于 30 秒内完成,并且 qa-suite-report.md 显示 slack-canary 和 slack-mention-gating 的状态均为 pass。如果该 lane 挂起约 90 秒,并以 Convex credential pool exhausted for kind "slack" 退出,要么池为空,要么每一行都已被租约占用 - qa credentials list --kind slack --status all --json 会告诉你具体是哪种情况。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw