跳转到内容

端到端检查

这些检查使用公开 API、构建出的命令、真实的本地服务器和临时 PostgreSQL 数据库。端到端检查会跟随一项任务,经过这些部分,并检查结果。部分外部服务使用固定的测试回复。Cloudflare 检查使用真实的模型服务。

从项目根目录运行命令。构建必须在测试开始前完成。测试运行时,不要在另一个 shell 中构建。构建会替换测试和子进程读取的 dist 文件。

Terminal window
devenv shell -- pnpm build
devenv shell -- pnpm typecheck
devenv shell -- pnpm test:e2e
devenv shell -- pnpm -r test

默认情况下,测试文件最多在四个独立测试进程中运行,进程数不超过可用 CPU 数。服务和数据库相互隔离。一个文件内的测试按顺序运行。调试时,加上 --maxWorkers=1 可使用单个进程。

所有端到端检查都放在 packages/e2e 中,包名为 @openbot-build/e2e。根目录命令 pnpm test:e2e 会运行该包的类型检查和测试。构建完成后,用以下命令运行一个任务组:

Terminal window
devenv shell -- pnpm --filter @openbot-build/e2e exec vitest run test/read-docs

小改动可在构建后只运行一个文件,或监视该文件的变更:

Terminal window
devenv shell -- pnpm --filter @openbot-build/e2e exec vitest run test/chat/ChatQueries.test.ts
devenv shell -- pnpm --filter @openbot-build/e2e exec vitest --watch test/chat/ChatQueries.test.ts

这些 exec vitest 命令不会在每次运行时检查整个包的类型。先完成构建,再启动测试。再次构建前,先停止监视模式。改动完成后,仍要运行 pnpm typecheck 和 pnpm test:e2e。

packages/e2e/test 中的文件夹按用户任务命名。packages/e2e/scenarios.json 记录每项任务的检查和缺口,并区分普通、边界和极端场景。普通场景检查常见结果。边界场景检查接近规则限制的输入或状态。极端场景检查有界的大量输入、重复任务、丢失或恢复。这些名称不代表已经测试了所有可能的输入或故障。

包的测试命令也会检查测试代码的类型。pnpm test 会在一次 Vitest 运行中运行所有测试文件,但不会构建包或检查测试代码的类型。e2e 以外的包测试检查较小的单元和产品部件。测试会自行创建并删除本地数据库。它们不使用生产数据库。

packages/e2e/test/api-access/ApiE2E.test.ts 读取 HTTP 契约,并向受保护的路由发送真实请求。它检查每条受保护路由的未登录请求。对于每个受保护的写入操作,它检查带有会话 cookie、但缺少 Origin 或使用错误 Origin 的两种情况。这是访问权限检查。它不能证明每条路由都能完成每项有效任务。路由和请求数量来自当前契约。JSON 报告记录每次运行的确切数量。公开路由和钩子路由列在固定清单中,因此意外删除身份验证规则不会让检查范围悄悄缩小。

端到端包按用户任务对检查分组:

任务组 packages/e2e/test 中的文件夹
登录和启动服务器 sign-in、start-server
读取和更改组织设置 organizations、admin-settings
聊天、批准工具调用和恢复任务 chat、approve-tool-calls、chat-recovery
使用和共享 Bot bot-work
连接 App 和使用协议服务 connect-apps、protocol-service
读取和写入文件 files
连接渠道和设置触发器 connect-channels、triggers
运行代码和连接计算机 run-code、connect-computers
使用实时会话和模型服务 live-chat、use-models
运行命令和阅读文档 cli、read-docs

文档检查通过本地 HTTP 端口提供构建出的站点。它们检查手册的三种语言、API 参考、搜索文件、图标、每个构建出的文件、本地链接和解码后的锚点。API 页面只有英语语言链接。检查不会获取外部链接。这些是静态站点检查。它们不运行浏览器,也不测试交互式搜索和菜单。

CLI 检查会启动构建出的命令。计算机检查包含真实终端。协议检查使用独立客户端和本地服务器。单元和组件检查仍放在 core、domain、api、client、openbot、cli、computer、protocol 和 protocol-test 包中。

只有设置 OPENBOT_E2E_LIVE=true,才会运行真实模型检查。默认运行会跳过它。它需要 Cloudflare 账户和具有 Workers AI 访问权限的 API 令牌。账户的免费额度用完后,服务调用会产生费用。请把凭据放在版本控制以外。

测试用 Server.layerFixed 创建会话,再启动构建出的生产入口调用真实模型。会话设置不得留下索引任务或失败记录。测试检查 cookie 和 API 令牌调用、流式回复、保存的历史、重复命令、用量和令牌撤销。这些小任务不能用于判断模型质量。

在本地 shell 或机密存储中设置以下变量。不要把密钥放在命令参数或纳入版本控制的文件中。

变量 值
OPENBOT_E2E_LIVE 设为 true,运行真实服务检查
OPENBOT_E2E_CLOUDFLARE_ENDPOINT 账户的 Workers AI OpenAI 兼容基础 URL
OPENBOT_E2E_CLOUDFLARE_KEY API 令牌
OPENBOT_E2E_CLOUDFLARE_MODEL 可选的模型 ID;默认值为 @cf/meta/llama-3.3-70b-instruct-fp8-fast
OPENBOT_E2E_EVIDENCE 可选的结果 JSON 绝对路径

构建完成后运行:

Terminal window
devenv shell -- pnpm --filter @openbot-build/e2e exec vitest run test/use-models/Cloudflare.test.ts

如果未设置 OPENBOT_E2E_LIVE=true,这个测试会被跳过。跳过真实服务测试不代表服务检查成功。

Terminal window
devenv shell -- python3 papers/experiments/run.py --seeds 30 --output .cache/e2e/papers.json

运行器只使用 Python 标准库。它运行 15 篇论文各自的小型抽象模型和具体示例。JSON 结果记录输入、随机种子、源文件哈希、检查、观察结果和限制。检查失败时,退出码非零。一次检查是运行中的一条断言,不是独立研究,也不是一个单独的用户场景。

如果论文给出了基线,实验会将所述方法与基线比较。实验包含反例:基线在这些输入下会违反预期规则。通过这些小型模型不能证明产品实现了该方法,也不能证明大型服务会得到相同结果。

论文 主要实验
01:持久执行 未知的外部结果、所有权边界和重放
02:权限保持 当前权限、保存的身份和操作准入
03:分层授权 精确规则、模型阈值和人工审核
04:智能体协作 传输中的消息、任务计数和任务结束
05:基于证据的记忆 引用来源的支持、修正和游标移动
06:记忆信息流 来源的读取者和组合记忆的访问权限
07:上下文压缩 跨越切分点的链接和过期写入
08:工具程序重放 输入帧、调用顺序、交付顺序和返回检查
09:机密引用 机密句柄、允许的用途和输出形式
10:工具发现 冲突的证据,以及读取失败时的撤回
11:协议测试 生成轨迹中的可达状态和故障
12:预算调度 未知费用、迟到的回执、价格、上限和份额
13:实时历史 播放回执、轮次和已提交的前缀
14:算力匹配 每个轨迹前缀的资源需求和效果限制
15:运行时组合 插件顺序、守卫、钩子和资源释放

论文定义了方法和研究。其中一些方法超出了当前产品行为。请区分三类结果:产品回归测试、抽象模型实验,以及把产品与论文预期规则进行比较的检查。

构建完成后,运行论文 06 和 12 的产品内部检查:

Terminal window
devenv shell -- node --disable-warning=ExperimentalWarning packages/openbot/test/PaperProductEvidenceMain.ts --strict

这些检查调用内部服务。它们将产品规则与论文比较,并非 packages/e2e 中的端到端用户任务。

命令将证据以 JSON 形式写入标准输出。使用 --strict 时,如果论文的预期规则不满足,命令会以非零退出码结束。检查会先确认测试数据和访问规则已就绪。缺少数据不能让检查通过。

论文 06 的检查把 Ana 和 Bob 的来源组合成一条记忆。早期运行表明,两人都能读取结果,却不能读取对方的来源。现在的检查要求能读取每个来源。两人都不能单独读取结果。能读取两个来源的群组可以读取结果。其他用户和组织仍被阻止访问。这条规则使用来源读取者的交集,也就是只有所有来源共有的读取者才能读取结果。无法证明来源访问权限的旧记忆会保持隐藏,直到重建。

论文 12 的检查把上限设为 1,000 microUSD。一个 microUSD 是一百万分之一美元。早期运行在第一次调用的费用变为未知时释放了它占用的估算金额。第二次调用花掉了释放出的额度。第一次调用的回执迟到,使最终费用达到 2,000 microUSD。现在的检查要求 OpenBot 保留占用并阻止第二次调用。已确认的回执会用实际费用替换占用金额。再次发送同一份回执不得增加费用。对于占用已丢失的旧未知调用,在费用确认前,必须阻止受影响的硬预算下的新调用。预算进入新周期后,也必须保留未知费用的占用。

这些检查必须通过,才能认为修复完成。它们不能证明提供方的最终扣费有硬上限。论文 12 的界限假设每个占用金额都是该调用费用的已验证上限。OpenBot 使用按输入大小和固定输出额度计算的估算。实际费用可能超过估算。参见预算。

现有产品测试还不能证明论文 13 的设备播放回执、论文 14 的基于轨迹的放置规则,或论文 15 的更严格注册检查。不要把适配器或插件测试通过说成这些方法已获验证。

完整测试运行覆盖的是已命名的输入和路径。它不能覆盖所有可能的输入、网络故障或外部服务状态。自动生成的访问检查并不覆盖该端点的全部任务。小型模型运行也不是生产负载测试。

真实的第三方渠道投递、SSO 服务、云计算机服务、对象存储和语音播放,都需要各自的服务账户和测试资源。固定测试服务器检查这些路径的本地契约。它们不能证明真实的第三方部署正常工作。

开发工具请看参与贡献。HTTP 契约请看 API 参考。