codex@macbookpro
·
2026-04-01
T-S068.md
1# Task T-S068:ChatGPT proxy send 冷启动降级保护
2
3## 状态
4
5- 当前状态:`已完成`
6- 规模预估:`S`
7- 依赖任务:无
8- 建议执行者:`Codex`
9
10## 直接给对话的提示词
11
12读 `/Users/george/code/baa-conductor/tasks/T-S068.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
19## 当前基线
20
21- 仓库:`/Users/george/code/baa-conductor`
22- 分支基线:`main`
23
24## 分支与 worktree(强制)
25
26- 分支名:`feat/chatgpt-cold-start-protection`
27- worktree 路径:`/Users/george/code/baa-conductor-chatgpt-cold-start-protection`
28
29开工步骤:
30
311. `cd /Users/george/code/baa-conductor`
322. `git worktree add ../baa-conductor-chatgpt-cold-start-protection -b feat/chatgpt-cold-start-protection main`
333. `cd ../baa-conductor-chatgpt-cold-start-protection`
34
35## 风险描述
36
37ChatGPT proxy send 依赖最近捕获的真实发送模板(请求头、cookie、conversation 上下文)。当插件刚重载或浏览器刚启动时,如果还没有观察到任何 ChatGPT 真实发送请求,proxy delivery 会静默失败或退回同页 DOM fallback。
38
39对于续命场景,这意味着 conductor 重启 + 插件重载后,第一批续命 job 可能全部走 DOM fallback 或直接失败。
40
41## 目标
42
43为 ChatGPT proxy send 增加冷启动保护,确保插件重载后能尽快恢复到 proxy delivery 能力。
44
45## 范围
46
47- 分析 ChatGPT proxy send 模板的最小依赖集(哪些字段必须从真实请求捕获,哪些可以预置)
48- 实现以下至少一种冷启动缓解策略:
49 - 策略 A:插件在 WS 连接建立后主动触发一次轻量请求(如查询 conversation list),预热模板缓存
50 - 策略 B:将最近捕获的模板持久化到 `localStorage` 或 conductor 侧,重载后恢复
51 - 策略 C:在 dispatcher 侧检测到模板缺失时延迟 retry 而不是立即失败,等待插件预热
52- 在 dispatcher 日志中明确标记"冷启动期间的 delivery 失败"和"模板预热完成"事件
53
54## 路径约束
55
56- 不修改 ChatGPT 网站的请求协议行为
57- 不增加对 ChatGPT API 的额外调用(避免触发风控)
58- 预热请求如果有,必须是只读性质(GET/list),不能发送消息
59
60## 需要特别注意
61
62- ChatGPT 的请求模板包含 CSRF token、auth header、conversation context,部分字段有时效性
63- 如果选择持久化模板,需要考虑 token 过期后的自动失效机制
64- DOM fallback 不是完全不可用,只是稳定性和速度不如 proxy delivery
65- `BUG-029`(ChatGPT SSE abort)和插件重载刷新(`T-BUG-031`)的修复经验可参考
66
67## 验收标准
68
69- 插件重载后 30 秒内恢复 ChatGPT proxy delivery 能力
70- 冷启动期间的续命 job 不会直接标记 failed,而是进入 retry 等待预热
71- 日志中可区分冷启动 fallback 和正常 proxy failure
72- 不影响已经预热完成后的正常 delivery 路径
73
74## 执行记录
75
76> 以下内容由执行任务的 AI 填写,创建任务时留空。
77
78### 开始执行
79
80- 执行者:`Codex`
81- 开始时间:`2026-04-01 17:23:21 CST`
82- 状态变更:`待开始` → `进行中`
83
84### 完成摘要
85
86- 完成时间:`2026-04-01 17:59:25 CST`
87- 状态变更:`进行中` → `已完成`
88- 修改了哪些文件:
89 - `plugins/baa-firefox/controller.js`
90 - `plugins/baa-firefox/controller.test.cjs`
91 - `apps/conductor-daemon/src/renewal/dispatcher.ts`
92 - `apps/conductor-daemon/src/index.test.js`
93 - `tasks/T-S068.md`
94 - `tasks/TASK_OVERVIEW.md`
95 - `plans/STATUS_SUMMARY.md`
96- 核心实现思路:
97 - 先收敛 ChatGPT proxy send 的最小依赖集:真正必须从真实请求继承的是最近一次可用的 `reqBody/model` 模板;登录态请求头、cookie、CSRF 仍继续复用现有持久化 credential snapshot;`message_id`、`parent_message_id`、`websocket_request_id` 则在每次 proxy delivery 时动态重建
98 - 在 Firefox controller 侧把最近 12 条 ChatGPT send template 持久化到 `browser.storage.local`,并在恢复时做 TTL 和 credential fingerprint 校验;controller 重载后可直接恢复最近模板,不需要额外触发只读预热请求
99 - 在 renewal dispatcher 侧把 `delivery.template_missing` / `delivery.template_invalid` 识别为 ChatGPT 冷启动失败,改成 5s 起步短延迟 retry,并新增 `chatgpt_cold_start_delivery` / `chatgpt_template_warmup` 日志事件,区分“冷启动等待预热”和“模板预热完成”
100- 跑了哪些测试:
101 - `pnpm install`
102 - `node --check plugins/baa-firefox/controller.js`
103 - `node --test plugins/baa-firefox/controller.test.cjs`
104 - `pnpm -C apps/conductor-daemon build`
105 - `node --test --test-name-pattern "renewal dispatcher uses short retries for ChatGPT cold-start template misses and logs warmup recovery|renewal dispatcher classifies downstream proxy_delivery statuses for retry and terminal failure|renewal dispatcher sends due pending jobs through browser.proxy_delivery and marks them done" apps/conductor-daemon/src/index.test.js`
106 - `pnpm -C apps/conductor-daemon test`
107
108### 执行过程中遇到的问题
109
110- 新 worktree 初始没有 `node_modules`,先执行了 `pnpm install` 后才可跑 `tsc` 和完整 `node --test`
111- `node --test` 的筛选参数首轮传法不对,改为直接使用 `node --test --test-name-pattern ... src/index.test.js` 后完成了定向验证
112
113### 剩余风险
114
115- ChatGPT 模板持久化只覆盖最近 12 个 conversation,且 TTL 跟随现有 credential TTL;如果 controller 冷启动前本地没有任何可恢复模板,首批 job 仍会先进入短延迟 retry,等待下一次真实 ChatGPT 发送完成预热
116- 持久化模板只解决“最近模板丢失”,不改变 ChatGPT 上游协议结构;若 ChatGPT 后续调整 `/backend-api/conversation` body 结构,仍需继续跟进模板构造逻辑