Repository navigation
Agent Workflow v0.19.0
Agent Workflow v0.19.0
本版本是 v0.18.19 之后的次版本,累计 548 个提交。主线只有一条:数据库 provider 统一抽象(RFC-359)完工。SQLite 与 PostgreSQL 不再是两份各自演化的实现,而是同一份实现跑在两个引擎上。合一过程中照出并修掉了一批「换个数据库结果就不一样」的用户可见缺陷;在 10 万任务规模的真实语料上,PostgreSQL 的三个重端点已经比 SQLite 更快。
本版本有数据库迁移:SQLite 新增 0224–0226(端点 0223 → 0226);PostgreSQL 基线在 v0.18.19 发布后又重采了一次,已经在 v0.18.19 上完成 cutover 的 PostgreSQL 部署需要再重做一次 cutover。从本版本起,PostgreSQL 有了不可变的迁移历史和增量升级链,后续版本可以原地升级。详见文末「升级说明」。
主要更新
数据库 provider 统一抽象完工(RFC-359)
起因是用户的两条要求:「以后不允许再出现两种数据库一个好一个不好的分支」,以及「postgresql 要做到最高性能表现」。v0.18.19 时这项工作还在进行中,本版本 12 条验收标准全部达成。
- 一份实现:约 150 对按 provider 分开写的孪生适配器,合到只剩 3 对。这 3 对都属于「只有一个引擎才有的资源形态」(SQLite 是一个文件,PostgreSQL 是一台服务器),并且每一对都有两个引擎各跑一遍的对拍测试。数千行 PostgreSQL 副本已经退役。
- 一条启动序列、一个事务原语:PostgreSQL daemon 与 SQLite 入口按同样的顺序执行同一份启动、恢复与播种逻辑;事务统一走一个中立的异步原语,不再有「同步事务只有 SQLite 能用」的分叉。
- 验收证据:收口提交的 CI 46 / 46 个作业全绿。其中后端测试在真 PostgreSQL 上跑 23,018 条、在 SQLite 上跑 16,740 条,全部 0 失败。在 10 万任务语料上做
scale=full性能对比,九个端点全部落在登记值以内,两个引擎返回的数据逐端点一致(itemIds/schemaVersion/nextCursor)。三个重端点 PostgreSQL 显著更快:任务列表首屏的中位数快 77.6ms,运行中任务列表快 37.7ms。 - 防止分叉重新出现:测试默认用
describeEachProvider在两个引擎上各跑一遍,缺少 PostgreSQL 连接时直接判失败而不是跳过;孪生适配器数量、裸事务、裸方言等债务都有只降不升的账本守卫。今后新增的功能会自动在两种数据库上接受验证。
合一过程中修掉的「换个数据库结果就不一样」
这些缺陷此前各自的测试都是绿的,直到同一份行为被放到两个引擎上对拍才暴露出来。多数只在 PostgreSQL 上出现:
- 定时启动:在 PostgreSQL 上,定时启动代理任务或工作组任务会直接返回 HTTP 500。
- 延后仓库准备(远端暂时拉不动时):SQLite 会留下一行可重试的任务;PostgreSQL 返回 400,而且一行任务都不留。这条落在最主要的启动接口
POST /api/tasks上。 - 重试调用节点:在 PostgreSQL 上重试一个「子任务已完成」的调用节点会失败,并让整个任务卡住。
- 数字员工计划的人工评审闸门:在 PostgreSQL 上永远不会进入
waiting。 - 取消:PostgreSQL 上的限额取消失效;取消没有读取评审变更号,可能与评审写入交错落库。
- 同名并发创建:在 PostgreSQL 上返回 500,现已恢复为稳定的 409 冲突。
- 工作组房间的确认预检:在 PostgreSQL 上是空操作。工作树已经不存在时,SQLite 返回 410,PostgreSQL 却返回 200,随后任务搁浅。
- 工作流同步:在 PostgreSQL 上会遇到三个问题:血缘写入死锁、内置工作流处理有误,以及预览结果和实际执行的动作不一致。
- 两个引擎行为不一致、统一取较完整一侧的几处:被取消任务的工作树不回收;工作流被删除后,手动执行在两个引擎上给出不同答案;同步缺少回滚基线的跨行预检;源终止在没有驱动时不同步收尾;恢复管理面两个引擎各有一处弱于对方。
- 任务列表(这次是 SQLite 出问题):并发的列表查询会合并成一次,但合并键漏掉了「启动来源」筛选。同一时刻按不同来源筛选的两个请求会拿到同一批结果,比如查
api来源时收到的是定时任务。合并键现在对完整的筛选条件做规范序列化,以后新增筛选项也不会再漏。
性能
- 认证请求不再每次都写库:此前 PostgreSQL 在每个端点上都比 SQLite 多出 6 条语句,全部来自每次认证请求的两笔记账写。现在 PAT 的
last_used_at也按会话早已采用的时间窗口合并更新。 - 单行写入的围栏检查内联:PostgreSQL 单行 INSERT 的 p95 从 18.11ms 降到 4.96ms。
- 概览与徽标少走往返:概览页的六条资源计数合并成一条
UNION ALL(22 条语句降到 17 条);评审徽标从三次串行往返合并为一次,反问徽标计数也收成一条语句。 - 新增覆盖索引:分别覆盖概览计数、按仓库查任务和任务列表的分面统计(两个引擎都有)。
其他修复
- 删除代理的引用检查恢复完整:此前正在运行任务的代理、被定时任务引用的代理都可以被删除,这会导致任务当场失去定义,或定时任务到点后在无人值守时失败;拒绝理由也不会点名是哪项引用挡住了删除。现在五道引用检查全部恢复,拒绝时会列出具体引用。
- 代理引用了已停用的插件时,保存被拒的报错重新是
plugin-disabled,不再是笼统的agent-resources-invalid,用户能直接看出要去启用哪个插件。 - 设置页「按条件批量归档」对非管理员可用:
POST /api/tasks/archive此前对所有非管理员都返回 404,即使对方已被授予settings:write。 - git 操作不再被环境变量
GIT_DIR劫持:GIT_DIR的优先级高于git -C,如果 daemon 在设置了GIT_DIR的环境里启动,git 操作会不报错地打到另一个仓库。 - 后端新增常设的「丢 Promise」lint 门禁:门禁上线当天就修掉了 15 处真实丢弃的异步写。这类问题的症状通常是「写入好像没生效」,而且集中出现在崩溃恢复和并发分支上。
升级说明
- SQLite 新增迁移
0224–0226:0224退役node_runs的血缘补齐触发器,改为在插入时显式写入(这个触发器只存在于 SQLite,是两个引擎分叉的来源之一);0225/0226只新增索引。升级前仍建议备份数据库。 - PostgreSQL 基线重采(重要):v0.18.19 发布后,基线又重采了一次,补上此前只存在于 SQLite 迁移、没有进入 PostgreSQL 的 schema 保护,例如大小写不敏感的唯一索引,contract digest 因此变化。已经在 v0.18.19 上完成 RFC-349 cutover 的 PostgreSQL 部署,需要再重做一次 cutover。
- PostgreSQL 从本版本起支持增量升级:迁移历史的根固定为本版本的基线,之后的 schema 变更以追加的升级边(
0001、0002…)原地应用,不再需要重做 cutover。 - SQLite 写入改为异步执行 + 进程内单写者串行(RFC-359 能力影响 C-2,已确认):事务语义不变,只是并发写请求改为在应用层排队,不再在 SQLite 层 busy-wait。
- 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧版本,并恢复升级前的备份。
完整变更记录:v0.18.19...v0.19.0