跳转至

🎯 OmniRoute 搜索与图片能力最终审计(2026-09-24)

历史值说明: 本文中的 207.174.28.120 只记录审计当时事实,不得作为当前端点或恢复值。当前边缘逻辑身份以 edge.yohan.fun 和 P10 权威计划为准。

2026-09-27 当前边界: 本文记录过的 gemini-web-session.service、gemini-egress-mm/dd.service、edge-ssh-socks.sh、独立 Chrome profile、9333 CDP 和 Privoxy/VNC 固定出口均为已退役历史实验,不得恢复。Gemini Web 现在只允许使用 OmniRoute 官方 Provider、官方管理 API 和官方 VNC 登录/harvest;RR 当前无上述自建服务或进程。

📌 结论摘要

本轮只读审计的结论是:搜索路径应显式治理。 统一方向是本地 local_search_registry 主路径加 OmniRoute 显式 Search Provider 辅助,不能依赖 OmniRoute 自动模式作为稳定默认。原因是 /v1/search 不与 21 个聊天模型共用路由,当前自动结果实际命中 ollama-search,返回体大、相关性和结果形态不稳定;通用搜索实测最佳为 serper-search,深度检索再按任务选择 tavily-search、perplexity-search、exa-search 或 firecrawl。

图片侧结论同样需要分开:图片生成已证实,Codex 端取回仍未闭环。 官方 3.8.50 的 gemini-web/nano-banana-web 只走模型/API 方式,不需要再包一层专用 MCP。2026-09-25 用户完成官方 VNC 登录后,官方 harvest 成功了,但 headless 生图仍使用旧会话;根因是官方执行器优先读取 api_key,而 harvest 只更新 provider_specific_data.cookie。通过官方 PATCH /api/providers/{id} 把首选 api_key 同步为新 Cookie 后,response_format=url 真实生成成功,且在同一 Cookie 会话内可下载为 50501 字节 JPEG。无登录态直取同一 URL 仍是 HTTP 403 HTML;b64_json 因官方 3.8.50 在授权 Playwright 上下文之外下载源图,仍返回 HTTP 502。官方 /v1/images/edits 对 gemini-web 返回 HTTP 400,因此当前只能确认“生成成功且可在授权会话取回”,不能声明 101 Codex 图片闭环已经可用。

版本与规则方面,RR 当前是官方 omniroute@3.8.50,与 npm latest、GitHub Release v3.8.50 一致。官方 issue #14760 已精确记录 b64_json 403,并且 PR #14787 给出的修复方向正是“在同一个授权 Playwright 上下文内下载图片”;该 PR 当前仍未合入正式发布。全局和项目规则已固定为只允许官方资源。 源码修改、补丁、私有 Fork、重新编译或改写安装包均被禁止。

🗂️ 目录

🧩 背景与目标

101 Codex 使用第三方通道模型资源,原生 Web Search、MCP/连接器、桌面控制和浏览器控制能力不能按官方 Codex 的完整形态使用。桌面和浏览器链路已由 Cua、Webbridge 与 Playwright 等多层方案补足;本轮只收口剩余两个问题:

  1. Web 搜索与发现应如何在 101 本地和 OmniRoute 之间选择、测试和治理。
  2. OmniRoute 的 Gemini Web 能否承担图片生成和图片编辑,以及应采用模型方式还是 MCP 方式。

这里必须区分“网页产品能力”和“OmniRoute 官方接口能力”。用户可以在 gemini.google.com 页面中上传参考图并编辑,但 OmniRoute 是否暴露对应 HTTP/MCP 入口,只能以已部署官方版本和官方包实现为准。

📊 官方版本与资源边界

RR 只读复核显示服务状态正常,未发现本轮代码改动或服务漂移。当前生产版本、发布来源与包指纹如下:

项目 当前结果 依据
RR 服务 agentmeshos-omniroute.service active/running,PID 467763,NRestarts=0,ActiveEnterTimestamp=2026-09-25 03:41:23 CST systemctl show 与 /proc/<pid>/environ 回读
健康 /healthz=ok curl http://127.0.0.1:39180/healthz
生产版本 3.8.50 RR 全局 npm 包版本
官方 npm 3.8.50 npm view omniroute version engines --json
官方 Release v3.8.50,发布于 2026-08-26T19:30:30Z GitHub Releases API
官方包 SHA-256 738c58af1faae8c57eb643a939d1191f8d7e083d9295ef61687d2bff04878c29 temp/omniroute-audit/omniroute-3.8.50.tgz
Node 要求 >=22.22.2 <23 || >=24.0.0 <27 官方 package.json 与 npm 元数据

四个核心实现与官方 tarball 的 SHA-256 一致,RR 生产包没有落入私有补丁:

文件 SHA-256
package.json 46394660a338155902350761999849bfa539e6fdc5aef74d7b69765a6ba788a2
open-sse/executors/gemini-web.ts c76289416ea121a4a3e58c473c695535d6807a8cccaadcbf7399abe41bb468aa
open-sse/handlers/imageGeneration/providers/geminiWeb.ts af59e51a12eb60c0ed3cad1a040fd65e6a338579a5865e866b9116a910827985
open-sse/config/searchRegistry.ts ad028f4179722234710db472eb7f2fda69c6142de5619401ad6bc3541063899e

因此本轮结论可作为官方 3.8.50 行为基线;一旦官方升级或此包指纹变化,搜索、图片和权限验收必须重新执行。

结论

Search Provider 不是聊天模型。 OmniRoute 官方注册表注释写明:搜索提供者没有 “models”,Provider 本身就是搜索执行器。101 Codex 可以同时看到本地 local_search_registry 和远程 omniroute MCP,但 Codex 当前没有本地强制优先级;若不增加提示规则或客户端策略,模型仍可能自行选择。稳产建议是把本地 SearXNG 当作通用搜索主路径,把 OmniRoute 当作显式补充通道,而不是依赖 Omni 自动模式。

自动路由真实行为

官方 searchRegistry.ts 的自动选择逻辑是筛选已配置、非 fallbackOnly 且支持目标类型的 Provider,然后选择最低 costPerQuery。官方 executeWebSearch.ts 会优先寻找有凭据的常规 Provider,再选择 fallback-only Provider,并只预选一个备用 Provider。它不是按剩余额度、健康状态、错误分类、冷却窗口和结果质量做完整动态路由。

101 自动查询 OpenAI Codex official documentation 实际命中 ollama-search。该结果虽然返回 3 条,但单个正文可达到约 49 万字符,自动结果文件超过 1 MB,相关性和可消费性不稳定,因此不能作为日常默认。

文档查询实测

下表中的输出是同一文档类查询 OpenAI Codex official documentation 的只读对照;“结果数”来自官方 /v1/search 响应,“成本”来自官方响应用量字段。

Provider 结果数 耗时 ms 成本 USD 判定
auto / ollama-search 3 1353 0 可用但不稳定,不作为默认
context7 3 647 0 仅文档语料,自动模式排除
duckduckgo-free 0 183 0 免费兜底,本次无结果
exa-search 3 977 0.007 适合语义检索
firecrawl 3 888 0.002 适合搜索后抓取
google-pse-search 0 0 0 未配置有效凭据
jina-search 0 0 0 上游 HTTP 402
linkup-search 0 0 0 未配置有效凭据
perplexity-search 3 783 0.005 适合带综合答案的深度检索
searchapi-search 3 3342 0.004 可用但延迟明显更高
searxng-search 0 0 0 仍指向官方默认 localhost:8888,未指向 101 的 8090
serper-search 3 668 0.001 当前通用 Web 搜索最优选择
tavily-search 3 1151 0.008 适合深度检索
youcom-search 3 702 0.005 可用,作为补充

上述结果保存在 temp/omniroute-e2e-20260924/search/。失败文件也保留 HTTP 错误原文,例如 Google PSE 和 Linkup 的“未配置凭据”、Jina 的 HTTP 402、SearXNG 的错误本地地址。

最终搜索策略

场景 推荐通道 原因
101 日常 Web 搜索 local_search_registry / 101 SearXNG 127.0.0.1:8090 自有链路、结果结构稳定、无外部 Provider 波动
OmniRoute 通用搜索 显式 serper-search 本次延迟约 668 ms、成本 0.001 USD、相关性最好
OmniRoute 深度检索 tavily-search 或 perplexity-search 覆盖内容更完整,但成本更高
文档/库检索 context7 官方定位为文档语料,明确排除自动通用搜索
语义检索 exa-search 适合按语义召回,不替代普通 SERP
抓取/内容抽取 firecrawl 官方把搜索与抓取能力放在同一 Provider 链路上

101 当前“让模型自行选择本地和 Omni”可以保留,但必须在规则或提示中明确:泛化查询优先本地;使用 Omni 时必须显式指定 Provider;不要依赖自动模式。OmniRoute 自身无法控制 Codex 选择哪一个 MCP,因此如果后续要求确定性优先级,落点应在 Codex 客户端策略,而不是再套一层网关或修改 Omni 源码。

🖼️ 图片生成与编辑

结论

官方 headless 生图已打通,Codex 端消费仍未闭环。 2026-09-25 用户完成官方 VNC 登录后,官方 harvest 返回 harvested: true 且连接验证通过。随后发现的真实根因是凭据优先级:官方执行器先读 api_key,harvest 却只更新 provider_specific_data.cookie,因此生图仍在使用旧会话。通过官方 PATCH /api/providers/{id} 同步首选 api_key 后,官方连接测试返回 valid: true,response_format=url 生图返回 HTTP 200。该图片在同一 Cookie 会话内可下载为 50501 字节 JPEG,但无登录态直取仍是 403 HTML;b64_json 因官方 3.8.50 在授权上下文之外下载源图而继续返回 502。图片编辑在官方 /v1/images/edits 上仍不支持 gemini-web。不需要再做一个专用 MCP 包装层:MCP 若只是包装同一个 HTTP 端点,不会解决 Cookie、下载 403 或编辑能力缺失。

url 与 b64_json

返回格式 通俗解释 当前结论
url 网关返回一个图片链接,Codex 或浏览器再访问链接显示图片 Gemini Web 生成本身 HTTP 200;无登录态直取 HTTP 403 HTML,但同一 Gemini Cookie 会话内可取得 200 image/jpeg,共 50501 字节
b64_json 图片内容直接编码在 JSON 响应里,调用方不用再下载链接 对普通 API Provider 有价值;Gemini Web 当前仍由 OmniRoute 在授权上下文之外抓取源图,返回 HTTP 502,错误为远程图片下载 403

因此用户即使看到“生成成功”或拿到链接,也不能直接等同于 Codex 可以在对话中显示或保存图片。当前判断标准是生成与取回两段都通过;只通过生成只说明上游产出了文件引用。

图片能力矩阵

能力 官方 3.8.50 结果 依据
Gemini Web Cookie 恢复 官方 VNC harvest 返回 harvested: true,validation.valid: true;写入 providerSpecificData.cookie 2026-09-25 官方 /api/vnc-session/{connectionId}/{sessionId}/harvest 返回
凭据优先级根因 旧 api_key 为 1746 字符、15 个 Cookie;新 harvest Cookie 为 2397 字符、23 个 Cookie,两者 SHA-256 不同;执行器优先使用旧 api_key RR provider_connections 解密后的无泄漏摘要;旧 SHA-256 3cb66e...,新 SHA-256 bd6427...
官方配置同步 官方 PATCH /api/providers/{id} 返回 HTTP 200,api_key 与最新 provider_specific_data.cookie 一致;连接测试 HTTP 200、valid: true RR /root/.omniroute/backups/gemini-web-connection-before-api-key-sync-2026-09-24T20-22-00-033Z.json
Gemini Web 生图 官方入口返回 HTTP 200、1 个 lh3.googleusercontent.com URL;实测生成耗时约 36.8 秒 RR /tmp/omniroute-gemini-image-e2e-20260925.mjs 与本轮 OpenAI 兼容入口响应
Gemini Web 图片消费 无登录态 URL 直取 HTTP 403 HTML;同一 Cookie Playwright 上下文请求返回 HTTP 200、image/jpeg、50501 字节,并保存为有效 JPEG RR /root/.omniroute/image-tests/gemini-web-e2e-1790281427880.jpeg
Gemini Web 生图 + b64_json HTTP 502,官方错误为 Remote image fetch error 403;图片已经生成,但官方下载阶段没有携带会话 Cookie 2026-09-25 官方入口复测结果
Gemini Web /v1/images/edits HTTP 400:Image edit is not supported for built-in provider "gemini-web" 官方 3.8.50 构建产物
Gemini Web 聊天传图编辑 不成立;执行器只过滤并输入字符串消息,图片 part 不会可靠传入网页 open-sse/executors/gemini-web.ts 的 buildGeminiPrompt
Gemini Web 聊天路径 文本和带图编辑均曾返回 HTTP 504,原因是本机 request queue 15 秒执行上限 RR /root/.omniroute/image-tests/e2e-gemini-web-chat-text-after-cleanup-20260924.json

官方编辑错误还明确给出可替代方向:adobe-firefly、chatgpt-web、codex 或自定义 OpenAI-compatible 图片 Provider。若这些官方 Provider 未配置或稳定性不足,方案只能是等待上游支持、恢复 Gemini Web 会话后仅做生成,或选择其他官方支持的编辑 Provider;禁止通过补丁给 3.8.50 添加私有 /v1/images/edits 分支。

凭据优先级根因与官方配置修复(2026-09-25)

harvest 成功不等于执行器使用了新会话。 官方 resolveGeminiWebCookie() 的读取顺序是 api_key、credentials.cookie、providerSpecificData.cookie、最后才拼 __Secure-1PSID 与 __Secure-1PSIDTS。官方 VNC harvest 只更新 providerSpecificData.cookie 和两个 __Secure-1PSID* 字段,不更新已有 api_key;现有连接又保留着 2026-09-24 的旧 Cookie,因此 headless 请求继续读取旧会话。

这个问题没有通过改代码解决。验证和修复顺序如下:

  1. 先对数据库中旧 api_key 与 harvest 新 Cookie 做解密后的长度、字段名和 SHA-256 比对,确认两者确实不同,且旧 api_key 是执行器首选来源。
  2. 用官方管理 API PATCH /api/providers/fefdf6be-2231-403f-a51e-08ba519d8c5a 只提交新的 apiKey,不改 Omni 包、不重启服务。
  3. 回读数据库确认 api_key == providerSpecificData.cookie,再执行官方连接测试。
  4. 重新调用官方 /v1/images/generations,确认 response_format=url 已从旧会话的“Are you signed in”错误转为 HTTP 200 并生成图片。

修复前整行连接已保存到 RR /root/.omniroute/backups/gemini-web-connection-before-api-key-sync-2026-09-24T20-22-00-033Z.json,权限 0600。回滚时可在 Omni 停写窗口内从该文件恢复并重新执行官方连接测试;不得直接覆盖整个数据库。

官方 VNC 浏览器登录路径(2026-09-25)

根因是 headless 不复用常驻 Chrome profile。 官方 3.8.50 的 gemini-web 执行器不连接 RR 常驻 Chrome 的 127.0.0.1:9333 CDP,也不复用 /root/.gemini-login-profile。官方 VNC 提供了合规的登录与 harvest 路径;本次登录成功后,用新 Cookie 的新 headless 上下文已能在 Gemini 页面看到账号和历史会话,不再显示登录或地区错误。

官方包同时提供了 /api/vnc-session 浏览器登录流程:Omni 启动隔离 Chromium 容器,操作者在 VNC 页面完成 Google 登录,再由官方 CDP harvest 只回收该 Provider 声明的 Cookie 和存储字段,写回指定 provider_connections 行。gemini-web 在官方 provider 清单中标记为支持该流程;这不是新增 MCP,也不是修改 Omni 源码。

实施项 当前结果 证据或路径
官方 VNC 镜像 已按官方 v3.8.50 包内 README 从官方 Dockerfile 构建 omniroute-vnc-chromium:local,镜像 ID sha256:01de7051ebb2b86667584e4726303f6eaab0665b97706c10075ef09ea5b10b0a,大小约 1.18 GB RR /root/omniroute-vnc-build/chromium/;Dockerfile SHA-256 c80d744776d7dee1215a5249e37be16c471263165144842351e3212fdccf01e1
容器自检 VNC 与 CDP 端口均可用,容器内浏览器为 Chrome/153.0.8010.52 RR 临时容器探针,完成后已删除
宿主集成 新增 systemd drop-in,只恢复 Docker socket 可见性,继续隔离 /etc/agentmeshos、/etc/nomad.d、/etc/ssh 和 Runtime 目录 RR /etc/systemd/system/agentmeshos-omniroute.service.d/vnc-browser-login.conf;SHA-256 cff905d85819cf5b7043a56c93cb2ede08477473f0e6b4443c54a0d24b7dfa79
服务验证 Omni 重启后 active、NRestarts=0、/healthz=ok,/api/vnc-session 返回 HTTP 200,且 gemini-web 出现在 VNC Provider 清单中 2026-09-25 RR 只读回读
VNC 地区限制根因 旧 VNC 容器的 CHROME_CLI 没有 --proxy-server,浏览器直接使用 RR 公网 96.44.133.235;宿主 OmniRoute 的 HTTP(S)_PROXY 只覆盖 headless 执行器,容器不继承 docker inspect 旧容器环境与 systemctl show 宿主环境对照
MM 出口固定 新增包外 systemd drop-in,使用官方变量把 VNC Chromium 固定到宿主 Privoxy;Privoxy 原有 .google.com、.googleusercontent.com、.gstatic.com 规则继续经 gemini-egress-mm.service 的 127.0.0.1:11080 SOCKS5 转发到 MM 207.174.28.120 RR /etc/systemd/system/agentmeshos-omniroute.service.d/vnc-gemini-egress.conf;SHA-256 ab1996c94d81d699e07d737cb3d414a985e6310320bfc7974b14198206e523c5
Docker 访问边界 Privoxy 监听 172.17.0.1:8118,UFW 仅允许 Docker 默认网桥 172.17.0.0/16 访问该目标端口;其他公网入口未放行 RR /etc/privoxy/config 与 ufw status;配置 SHA-256 e224107b5f91b348ba5b6a9072079d0b8b493a9c0f7e11f64f385c8128c19d3d
新容器实参 新会话容器 CHROME_CLI 和 Chromium 进程均包含 --proxy-server=http://172.17.0.1:8118;容器经该代理访问 Google 与 Gemini 均 HTTP 200 RR docker inspect efad7b456242、docker exec ps、容器内 curl 探针
VNC 地区检查 会话 f783cf81-3a95-4e0d-bab8-0adcad1e17dc 打开 https://gemini.google.com/app;CDP 页面文本 HAS_REGION_UNAVAILABLE=false,页面仍显示 Sign in RR CDP 127.0.0.1:32779/json 与 Runtime.evaluate
第二次 502 根因 首个 VNC 容器从 1790276943 启动,到 1790278760 被 Docker 以 exit 137 销毁,存活 1817 秒;官方默认 OMNIROUTE_VNC_MAX_MS=1800000,因此 /touch 只能保 idle,不能延长 max RR docker events 与官方 manifest.ts 默认值
会话时长修复 官方 env 固定为 OMNIROUTE_VNC_IDLE_MS=86400000、OMNIROUTE_VNC_MAX_MS=86400000;新会话不再在 30 分钟被官方计时器销毁 RR /etc/systemd/system/agentmeshos-omniroute.service.d/vnc-gemini-egress.conf;SHA-256 ecfeaffb554d480dc95c7531f3715e164ce60353458efecc25bf11958446d43f
当前新会话 c6182281-a0b5-4640-b13f-65bb6417c28d,VNC 127.0.0.1:32780,CDP 127.0.0.1:32781;容器仍带 MM 代理参数 RR 官方 API、docker inspect 与 docker port
Home 可访问入口 https://omni.yohan.fun:8443/ 经 MM Nginx 回源到 100.64.0.1:39275,再转发到当前 VNC 127.0.0.1:32780;socat 使用 Restart=always 并在反向验证中自动换 PID 后恢复 HTTP 200 101 curl -I、RR socat 监听与主动终止回归
VNC 登录与 harvest 用户完成登录后,CDP 页面 HAS_SIGN_IN=false、HAS_REGION_UNAVAILABLE=false;官方 harvest 返回 harvested: true、3 个更新字段、validation.valid: true 2026-09-25 官方 VNC/CDP 与 harvest 响应
新 Cookie 的 headless 会话 注入 provider_specific_data.cookie 后,Gemini 页面显示账号名和最近会话,不再显示 Sign in;该会话能生成图片并在同一上下文取回 JPEG RR /tmp/gemini-web-fresh-cookie-probe-20260925.mjs 与官方图片入口复测

登录动作必须由用户在官方 VNC 页面完成,不能把账号密码或 2FA 交给 Agent 保存。当前可以确认“登录成功、harvest 成功、官方生图成功、授权会话内可取回 JPEG”;不能确认“Codex 可直接显示或保存图片”以及“官方 API 图片编辑可用”。只有官方修复进入正式版本并通过 b64_json 与编辑 E2E 后,才能把 101 Codex 图片闭环声明为完成。

当前未决项

VNC 登录和官方 headless 生图已经完成,剩余阻塞已经从“会话问题”收敛为“官方取回实现问题”。官方 issue #14760 与当前 3.8.50 实验完全一致,官方 PR #14787 的修复是在同一个授权 Playwright 上下文内下载图片,但尚未进入正式发布。要按“Codex 图片可用”声明,必须继续满足两个真实验收:b64_json 或等价可消费响应能在 101 Codex 中直接使用;带图编辑能从官方入口提交并取回结果。当前不采用源码补丁、私有 MCP 或第二层网关;等待官方发布期间,最多只能采用“先生成 URL,再由持有官方 Cookie 的会话取回”的两步临时操作。

🧩 规则与治理

规则已经落到全局和项目边界,目的是防止升级后被本地补丁覆盖,也防止后续为了短期功能继续走私有构建。

边界 当前规则 文件
全局 搜索场景和图片验收门槛已经固定;只允许官方 npm/Release、官方镜像、官方 CLI/API 和控制台配置 /root/.codex/AGENTS.md
全局细则 搜索按本地主路径和显式 Provider 回退;禁止把“生成成功”写成“端到端可用”;禁止源码修改、补丁、私有 Fork/分支/镜像、重新编译、替换包文件、改写构建产物 /root/.codex/docs/core-operating-rules.md
项目架构 官方 OmniRoute 是唯一模型/Provider/路由权威 docs/architecture/03_总体架构设计.md
项目规范 宿主层 systemd/代理可保留,但不得改包内容 docs/architecture/05_技术选型说明.md、docs/architecture/06_工程规范.md
部署 外部适配要有用途、路径、回滚点和升级后 Smoke docs/architecture/07_部署规范.md
协作 故障只能通过官方控制台、API、升级、包外配置或数据恢复处理 docs/architecture/08_AI协作规范.md

Codex 规则落点

搜索与图片路由已于 2026-09-24 写入 Codex 常驻规则和核心细则。修改前先备份,再按原文件权限写回;回滚时可直接比对以下指纹恢复,不得改装为项目内脚本或第二层网关。

文件 修改前 SHA-256 修改后 SHA-256 备份
/root/.codex/AGENTS.md 38fc749c32240979c93680be00e264b0e3e83b9e2510be598222cbc0fb5bbeb1 f912545eb80933834f731f28165a9370e632c0700ae6b8fcb1d183e184084e71 /root/.codex/backups/omniroute-search-image-rules-20260924T2025/AGENTS.md
/root/.codex/docs/core-operating-rules.md cacdbe7907703b1edf31971dc2eaf21118206b388d548690207b9ef42a2a761d 52564db3caa9ec0a68161ee62452073dc216ce9fbefc20f3c2fd9c72047f0501 /root/.codex/backups/omniroute-search-image-rules-20260924T2025/core-operating-rules.md

2026-09-24 的初始审计没有修改 OmniRoute 源码、没有重新编译、没有替换已安装包、没有重启服务。2026-09-25 为启用官方 VNC 流程,新增了包外 systemd drop-in 并重启 Omni;随后又新增 VNC 出口代理配置并再次重启 Omni。官方 npm 包、源码和构建产物均未修改。temp/ 下历史补丁脚本只作为审计材料,不得在后续生产流程中执行。

🧪 验证与复核

本轮使用的只读验证命令与结果如下:

验证项 结果
101 MCP 可见性 local_search_registry、omniroute 均 enabled;Omni MCP 当前只暴露 Web Search 与 Web Fetch,没有图片生成或编辑工具,因此图片仍应走模型/API
RR 版本 官方 3.8.50
RR 健康 ok
RR 重启次数 NRestarts=0
官方 VNC 服务能力 /api/vnc-session 返回 HTTP 200;33 个 VNC Provider 中包含 gemini-web
官方 VNC 浏览器 VNC/CDP 正常,浏览器为 Chrome/153.0.8010.52;当前 Gemini 页面无登录提示和地区限制,账号历史可见
VNC 出口代理 容器实际使用 http://172.17.0.1:8118,Privoxy 上游为 MM SOCKS5 127.0.0.1:11080,MM 出口 207.174.28.120
VNC 页面状态 CDP 文本匹配 HAS_SIGN_IN=false、HAS_REGION_UNAVAILABLE=false;不是地区提示伪装
VNC 会话寿命 新会话使用官方 OMNIROUTE_VNC_IDLE_MS=86400000、OMNIROUTE_VNC_MAX_MS=86400000;03:42 至 04:05 连续探测约 23 分 55 秒,容器、端口和公网 HTTP 200 均无变化
访问桥故障恢复 主动终止 socat 旧 PID 471298 后,systemd 自动拉起新 PID 471442,公网入口仍为 HTTP 200
OmniRoute 重启后 active/running、NRestarts=0、/healthz=ok;新进程环境包含官方 OMNIROUTE_VNC_CHROMIUM_ARGS 和会话时长参数
官方 tarball 指纹 与审计目录中的 3.8.50 包一致
Gemini Web 会话 官方 VNC 登录和 harvest 已完成;旧 api_key 与新 Cookie 不一致的问题已由官方管理 API 修正,连接测试 valid: true
Gemini Web 生成 HTTP 200,返回 1 个 Google 图片 URL,耗时约 36.8 秒
Gemini Web 图片取回 无 Cookie 请求 HTTP 403 HTML;同 Cookie Playwright 上下文 HTTP 200、JPEG、50501 字节,可解码
Gemini Web b64_json 消费 HTTP 502,官方下载器仍返回远程图片 403;对应官方 issue #14760,修复 PR #14787 尚未发布
Gemini Web 编辑 官方 /v1/images/edits 返回 HTTP 400,当前版本不支持
搜索结果证据 temp/omniroute-e2e-20260924/search/
图片结果证据 RR /root/.omniroute/image-tests/gemini-web-e2e-1790281427880.jpeg;本轮无泄漏摘要与官方接口复测脚本位于项目 temp/gemini-web-*20260925.mjs、temp/omniroute-gemini-*20260925.mjs

101 上手工验证搜索时,应优先让 Codex 调用 local_search_registry;需要验证 Omni 时,测试请求必须显式带 provider,例如选择 serper-search。不要用自动模式的一次成功作为长期稳定性证明。

🔁 回滚方案

2026-09-24 的初始审计没有生产服务、包内容、配置或数据库变更,因此当时不需要服务回滚。2026-09-25 的 VNC 集成新增了包外 systemd drop-in;回滚时删除 /etc/systemd/system/agentmeshos-omniroute.service.d/vnc-browser-login.conf,执行 systemctl daemon-reload 并重启 Omni,或在需要完整恢复时使用备份目录 /root/omniroute-systemd-backup-20260925T014634+0800/。项目文档可通过对应 Git 提交反向回滚;全局 /root/.codex 规则不属于项目仓库,修改时应保留变更前后副本,回滚时逐条恢复,不得用未经验证的历史配置覆盖。

VNC 出口代理的独立回滚点如下。该修复只改宿主层,回滚不涉及 OmniRoute 包或数据库:

对象 修复前 修复后 / 当前 回滚动作
Privoxy 主配置 SHA-256 845df06d418ce746fb9351ecc66012828ef3a420136847d2cc896c6b6827d1e8 SHA-256 e224107b5f91b348ba5b6a9072079d0b8b493a9c0f7e11f64f385c8128c19d3d 从 /root/omniroute-vnc-egress-backup-20260925T030255+0800/privoxy.config.before 恢复,重启 privoxy.service
VNC Chromium 参数 无 OMNIROUTE_VNC_CHROMIUM_ARGS,容器直连 RR RR /etc/systemd/system/agentmeshos-omniroute.service.d/vnc-gemini-egress.conf,SHA-256 ab1996c94d81d699e07d737cb3d414a985e6310320bfc7974b14198206e523c5 删除该 drop-in,执行 systemctl daemon-reload && systemctl restart agentmeshos-omniroute.service
Docker 到宿主代理放行 无 UFW 允许 172.17.0.0/16 -> 172.17.0.1:8118/tcp 执行 ufw delete allow from 172.17.0.0/16 to 172.17.0.1 port 8118 proto tcp
历史自建出口服务(已退役) 当时已有 gemini-egress-mm.service enabled/running,DD 为备份 不得恢复;当前 Gemini Web 只使用官方 Provider/VNC,不依赖常驻 Chrome 或宿主出口服务
VNC 会话时长 官方默认 idle 10 分钟、max 30 分钟 idle/max 均固定为 24 小时 从 /root/omniroute-vnc-session-lifetime-backup-20260925T034058+0800/vnc-gemini-egress.conf.before 恢复 drop-in,重启 OmniRoute
Gemini Web 首选凭据 旧 api_key,1746 字符、15 个 Cookie 与当前 providerSpecificData.cookie 一致,2397 字符、23 个 Cookie 仅在需要恢复旧连接状态时,从 /root/.omniroute/backups/gemini-web-connection-before-api-key-sync-2026-09-24T20-22-00-033Z.json 恢复;恢复后必须重新执行官方连接测试

完整备份目录为 /root/omniroute-vnc-egress-backup-20260925T030255+0800/,其中保留修复前两文件和 before.sha256。回滚后必须重新启动一个新的官方 VNC 会话,并重新确认容器不再带 --proxy-server;不能只凭配置文件删除就宣告回滚成功。

若未来升级 OmniRoute,回滚必须先恢复已验证数据快照,再恢复上一官方包版本,并在切换后验证健康、搜索显式 Provider、签名鉴权、模型调用和图片生成;不得通过恢复私有源码或重新编译回滚。

⚠️ 风险与未决项

  • Gemini Web 会话已闭环:VNC 登录、官方 harvest、首选凭据同步和官方连接测试均通过;后续再次 harvest 时必须重新同步 api_key,否则旧的 api_key 仍会优先于新 Cookie。
  • Gemini Web 生成与消费分离:url 生成和授权会话取回已经通过,但无登录态 URL 仍是 403,b64_json 仍因官方下载器缺少 Cookie 返回 502;在官方修复发布前,不能把结果声明为 101 Codex 可直接消费。
  • Gemini Web 图片编辑未闭环:/v1/images/edits 不支持该内置 Provider,聊天入口的带图编辑也未通过;网页能力不能替代官方网关能力。
  • 上游修复未发布:官方 issue #14760 与已复现问题完全一致,PR #14787 采用“授权上下文内下载”的修复思路,但当前 npm latest 和 GitHub Release 仍是 3.8.50;不能从 PR 私自移植。
  • 搜索优先级现已落到 Codex 规则:日常搜索先本地,本地失败后回退 Omni 并显式指定 Provider;该约束仍依赖 Codex 运行时实际加载全局规则。
  • 自动搜索不应作为稳定依赖:当前自动模式等价于最低成本已配置 Provider,本次为 ollama-search,不是完整健康/额度路由。
  • Docker 默认网桥内的容器都可访问 172.17.0.1:8118;当前通过源网段、目标地址和单端口三重限制降低暴露面,如果后续引入不可信多租户容器,必须进一步拆出专用网桥或代理 ACL。
  • VNC 临时访问入口和 /touch 保活绑定当前会话 ID;会话过期后需要按官方 API 重新建会话并更新端口映射,但 MM 出口参数、Privoxy 监听和 UFW 规则会在 OmniRoute 重启后继续生效。
  • 版本行为绑定:本文结论只对官方 3.8.50 及所列包指纹成立;官方升级后必须重新验证。

✅ 未决项 / 需要用户决策

当前的不再是登录或地区问题,也不需要用户继续操作 VNC。需要决策的是“是否接受等待官方发布”:

选项 结果 影响
等待官方修复版本 保持 3.8.50,不做源码改动;官方发布包含 #14787 的版本后,按官方升级流程验证 b64_json 和图片编辑 最稳妥,符合只使用官方资源规则;期间只能使用授权会话两步取图
现在做 Codex 侧两步取图 先调用 Omni 的 url 生成,再用持有 Gemini Cookie 的 RR 会话下载并落到本地,由 Codex 显示文件 可以立即取得图片,但这是客户端后处理,不是 Omni 官方 b64_json 能力;用户需明确接受这一条临时路径

不采用的方案是修改 Omni 源码、把 PR #14787 直接打到生产包、重新编译,或在前面再套一层网关。这些操作会产生升级覆盖和双重路由问题,违反现有多节点统一边界。