54 lines
5.6 KiB
Markdown
54 lines
5.6 KiB
Markdown
# Codex App Web Search 接入发现
|
||
|
||
## 已确认
|
||
|
||
- 用户观察正确:Codex App/app-server 本身会做原生自动上下文压缩。
|
||
- 旧的“检测上下文超限 → `/compact` → 重放”属于 detached Claude/旧 Codex CLI 的客户端兜底,不等于 Codex App 没有自动压缩。
|
||
- `lib/codex-app-runtime.js` 已识别 `webSearch` item,并映射为 `web_search` / `WebSearch` 展示事件。
|
||
- 当前 Codex 配置把 `enableSearch` 与 `supportsSearch` 硬编码为 `false`,保存开启请求时也会忽略;该限制来自旧 `codex exec` 路径,需要收敛到 Codex App 原生能力。
|
||
- OpenAI 官方页面在当前网络环境不可访问:developers 域返回 Forbidden,platform 域被 Cloudflare 拦截。
|
||
- 按用户提示补用 `proxyd.picpi.top/{原始 URL}` 后,官方搜索页与 app-server 文档页仍返回上游 `Forbidden`;代理链路可达,但无法绕过官方站点的访问限制。
|
||
- TODO CSV 计划审查已通过;审查员建议在确认 schema 后记录字段名、关闭语义与证据来源。
|
||
|
||
## 待确认
|
||
|
||
- hapi 是否使用相同字段;主线程全文检索暂未命中,等待只读研究子代理复核。
|
||
|
||
## Codex 0.147.0 协议证据
|
||
|
||
- 本机 `codex app-server generate-json-schema --experimental` 生成的 v2 schema 中,`Config.web_search` 引用 `WebSearchMode`。
|
||
- `WebSearchMode` 的枚举值为 `disabled`、`cached`、`indexed`、`live`。
|
||
- `ThreadStartParams.config` 和 `ThreadResumeParams.config` 都允许线程级 config;`TurnStartParams` 没有 Web Search 专用字段。
|
||
- cc-web 的 `codexAppThreadParams()` 已把 `codexAppThreadConfig()` 同时用于 `thread/start` 与 `thread/resume`,因此正确接入点是 `codexAppThreadConfig()` 写入 `web_search`。
|
||
- 生成的 resolved `Config` 同时存在两层:顶层 `web_search: WebSearchMode`,以及 `tools.web_search: WebSearchToolConfig`。前者选择 `disabled/cached/indexed/live` 模式,后者承载 `context_size/allowed_domains/location` 等工具配置;不能把二者混成同一字段。
|
||
- CLI 解析实测:`web_search="live"`、`tools.web_search=true`、`tools.web_search=false` 都能加载;`tools.web_search="live"` 或 `"disabled"` 不合法。
|
||
- app-server `config/read` 实测:顶层配置会解析为 `web_search: "live"`;`tools.web_search=true/false` 都归一到 `tools.web_search: null`,仅凭读取结果无法证明布尔输入的最终启停语义。
|
||
- `codex --help` 明确 `--search` 是“Enable live web search”,但该开关只属于 Codex CLI 根命令,`codex app-server --search` 会被拒绝;app-server 应使用线程 config。
|
||
- 官方 OpenAI 文档通过 `proxyd-accelerator` 成功获取:`web-search.md` 明确 live 用 `web_search = "live"`、关闭用 `web_search = "disabled"`;`config-reference.md` 明确 `tools.web_search` 只是可选的上下文大小、域名和位置配置。
|
||
- 最终协议决策:cc-web 开关只传顶层 `web_search: enableSearch ? 'live' : 'disabled'`;当前产品没有域名/位置细节 UI,因此不传 `tools.web_search`。
|
||
- app-server 的 `webSearch` thread item 已由 `lib/codex-app-runtime.js` 映射为前端 `web_search` 工具事件,展示链路已有基础。
|
||
|
||
## 实现与回归落点
|
||
|
||
- 服务端配置需把 `load/save/masked/handleSave` 的 `enableSearch` 改为真实布尔值,并将 `supportsSearch` 对 Codex App 暴露为 `true`;旧 Codex CLI 路径仍不读取该开关。
|
||
- `codexAppThreadConfig()` 应无条件写入 `web_search: enableSearch ? 'live' : 'disabled'`,让 `thread/start` 与 `thread/resume` 都明确覆盖用户全局搜索默认值。
|
||
- 设置面板已有 `.settings-toggle-row` / `.settings-switch` 组件,可新增“Web Search”开关,无需新增 CSS。
|
||
- mock app-server 当前可在 `thread/start` / `thread/resume` 捕获 `params.config.web_search`;回归应分别覆盖开启后的 `live` 与保存关闭后的 `disabled`。
|
||
- 现有配置回归仍断言“unsupported/ignore”,必须改为 `supportsSearch === true`、`enableSearch === true`,并在后续关闭保存中断言 `enableSearch === false`。
|
||
- Web Search 事件映射已有实现,但目前回归未直接断言 `webSearch` item → `web_search` 工具事件,需要补 mock 事件或静态契约断言。
|
||
|
||
## 最终实现结果
|
||
|
||
- `server.js` 的 Codex 配置现在真实保存/读取 `enableSearch`,对 Codex App 暴露 `supportsSearch: true`,保存提示不再声称“Codex exec 暂未接入”。
|
||
- `codexAppThreadConfig()` 每次组装线程参数时写入 `web_search: 'live' | 'disabled'`;同一配置同时覆盖 `thread/start` 和 `thread/resume`。
|
||
- `public/app.js` 设置面板新增可读写的 Web Search switch,说明文案限定为当前 Codex App 会话。
|
||
- mock app-server 暴露首次线程搜索模式与当前线程搜索模式,回归分别证明开启态 `live`、关闭后的 resume `disabled`,并证明未使用 `tools.web_search` 代替模式开关。
|
||
- `scripts/regression.js` 新增 `webSearch` item 的 `WebSearch/web_search` tool_start/tool_end/persistence 断言。
|
||
- 两次回归均通过:`timeout 60s node scripts/regression.js`、`timeout 60s npm run regression`。
|
||
|
||
## 旧 Codex 模式盘点结论
|
||
|
||
- 普通 UI 已默认 Codex App,Codex App 的 `/compact`、`/goal`、协作模式、MCP、附件、标题、自动容量重试已有实现。
|
||
- 仍需后续单独处理的遗留:后端可新建 `agent='codex'`,旧 `codex exec` 运行链路完整存在,rollout 导入与 regression 仍覆盖旧 CLI。它们属于迁移/封口任务,不在本轮 Web Search 范围内。
|
||
- 未知 app-server request 的“不支持”兜底应保留;运行中已知 slash 的策略需要产品决定,不应与本轮 Web Search 混改。
|