baa-conductor

git clone 

baa-conductor / tasks
codex@macbookpro  ·  2026-04-01

T-S069.md

  1# Task T-S069:proxy_delivery 成功语义增强 — 补齐下游回复确认
  2
  3## 状态
  4
  5- 当前状态:`已完成`
  6- 规模预估:`L`
  7- 依赖任务:`T-S060`
  8- 建议执行者:`Codex`
  9
 10## 直接给对话的提示词
 11
 12`/Users/george/code/baa-conductor/tasks/T-S069.md` 任务文档,完成开发任务。
 13
 14如需补背景,再读:
 15
 16- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/renewal/dispatcher.ts`
 17- `/Users/george/code/baa-conductor/plugins/baa-firefox/delivery-adapters.js`
 18- `/Users/george/code/baa-conductor/plans/AUTOMATION_ARBITRATION_REQUIREMENTS.md`
 19
 20## 当前基线
 21
 22- 仓库:`/Users/george/code/baa-conductor`
 23- 分支基线:`main`
 24
 25## 分支与 worktree(强制)
 26
 27- 分支名:`feat/delivery-ack-confirmation`
 28- worktree 路径:`/Users/george/code/baa-conductor-delivery-ack-confirmation`
 29
 30开工步骤:
 31
 321. `cd /Users/george/code/baa-conductor`
 332. `git worktree add ../baa-conductor-delivery-ack-confirmation -b feat/delivery-ack-confirmation main`
 343. `cd ../baa-conductor-delivery-ack-confirmation`
 35
 36## 风险描述
 37
 38当前 `proxy_delivery` 的成功语义是"请求已派发到目标页面上下文",不是"下游 AI 已完整回复"。这意味着:
 39
 40- dispatcher 标记 renewal job 为 `done` 时,实际上只确认了请求发出去了
 41- 如果下游 AI 拒绝了请求(如 rate limit 429、网络超时、session 过期),conductor 不知道
 42- renewal 的 cooldownUntil 已经设置,但实际续命可能没有成功
 43- 对于 baa 指令执行,回送结果可能在 proxy 层面"成功"但实际 AI 没有响应
 44
 45## 目标
 46
 47为 proxy_delivery 补齐下游回复确认机制,使 conductor 能区分"请求已发出"和"下游已响应"。
 48
 49## 范围
 50
 51- 定义增强后的 delivery 成功语义层级:
 52  - Level 0:请求已派发(当前行为)
 53  - Level 1:下游返回了 HTTP 200(proxy 层面确认)
 54  - Level 2:下游开始了 SSE 流(AI 开始回复)
 55  - Level 3:下游 SSE 流正常结束(AI 完整回复,即触发了新的 final-message)
 56- 首版至少实现 Level 1(HTTP 状态码回传)
 57- 在 dispatcher 中根据回传的状态码决定 job 的最终状态(200 → done,429/5xx → retry)
 58- 在插件侧补齐 proxy_delivery 的 HTTP 状态码回传到 conductor
 59
 60## 路径约束
 61
 62- 不要求首版实现 Level 2/3,但数据模型要为后续扩展预留空间
 63- 不改变现有 proxy_delivery 的请求派发逻辑,只在结果回传上增强
 64- 状态码回传必须是异步的,不能阻塞 proxy_delivery 的请求派发
 65
 66## 需要特别注意
 67
 68- ChatGPT 的 proxy delivery 返回的是 SSE 流,需要等到流开始或流结束才能判断成功
 69- 等流结束可能需要 30s+ — 首版不建议等,只判断 HTTP 状态码即可
 70- Gemini 的 proxy delivery 结构不同(form data + 非标准 SSE),需要独立处理
 71- Level 3 实际上就是等下一条 final-message 回来 — 这可以复用现有 final-message 链路,不需要在 proxy 里等
 72- 如果首版只做 Level 1,job 的 done 语义从"已派发"升级为"下游已接受",这是一个有意义的增强
 73
 74## 验收标准
 75
 76- proxy_delivery 结果回传中包含下游 HTTP 状态码
 77- dispatcher 能根据状态码区分成功(200)和失败(429/5xx)
 78- 429/5xx 的 job 进入 retry 而不是 done
 79- 不影响现有 proxy_delivery 的请求派发速度
 80- 日志中记录下游状态码
 81
 82## 执行记录
 83
 84> 以下内容由执行任务的 AI 填写,创建任务时留空。
 85
 86### 开始执行
 87
 88- 执行者:`Codex`
 89- 开始时间:`2026-04-01 16:56:18 CST`
 90- 状态变更:`待开始` → `进行中`
 91
 92### 完成摘要
 93
 94- 完成时间:`2026-04-01 17:21:11 CST`
 95- 状态变更:`进行中` → `已完成`
 96- 修改了哪些文件:
 97  - `plugins/baa-firefox/controller.js`
 98  - `apps/conductor-daemon/src/browser-types.ts`
 99  - `apps/conductor-daemon/src/firefox-ws.ts`
100  - `apps/conductor-daemon/src/local-api.ts`
101  - `apps/conductor-daemon/src/renewal/dispatcher.ts`
102  - `apps/conductor-daemon/src/index.test.js`
103  - `docs/api/control-interfaces.md`
104  - `docs/api/firefox-local-ws.md`
105  - `tasks/T-S069.md`
106  - `tasks/TASK_OVERVIEW.md`
107  - `plans/STATUS_SUMMARY.md`
108- 核心实现思路:
109  - 在 Firefox 插件侧给 `proxy_delivery` 增加异步下游确认跟踪,不阻塞请求派发;等拿到 HTTP 响应头后,把 `delivery_ack.level/status_code` 回填到结构化 `action_result.results[*]`
110  - 在 daemon 侧扩展 `action_result` 数据模型与读面序列化,为后续 Level 2/3 预留 `delivery_ack.level` 扩展位
111  - renewal dispatcher 改为基于 `delivery_ack` 判定结果:`200 -> done`,`429/5xx -> retry`,其他非 `200` 下游状态记为失败,并在日志里显式写出下游状态码
112- 跑了哪些测试:
113  - `pnpm install`
114  - `node --check plugins/baa-firefox/controller.js`
115  - `pnpm -C apps/conductor-daemon build`
116  - `pnpm -C apps/conductor-daemon test`
117
118### 执行过程中遇到的问题
119
120- 新 worktree 初始没有 `node_modules`,先执行了 `pnpm install` 后才可跑 `tsc``node --test`
121
122### 剩余风险
123
124- 本轮只实现到 Level 1(HTTP 状态码确认);Level 2/3 的“流已开始 / 完整回复已结束”仍需后续复用 SSE / final-message 链路继续补齐
125- renewal dispatcher 已消费 `delivery_ack`,但其他仍只看 proxy 派发层语义的调用方若要升级到“下游已接受”或“完整回复完成”,还需要后续分别接入