[Bug] Android 1.0.15 routes remote Codex device execution to Provider API instead of Agent Gateway

这个报错通常发生在自建 LobeHub + Android 客户端(User-Agent `LobeHub-Mobile/android-v1.0.15`)中,当你在 Codex 会话里让已绑定的远程设备执行命令时,Android 没有走 Agent Gateway,而是回退到 Provider A

快速结论:这个报错通常发生在自建 LobeHub + Android 客户端(User-Agent `LobeHub-Mobile/android-v1.0.15`)中,当你在 Codex 会话里让已绑定的远程设备执行命令时,Android 没有走 Agent Gateway,而是回退到 Provider API,弹出 Codex API Key 提示或返回 InvalidProviderAPIKey。优先排查 Android 客户端上 `heterogeneousProvider` 与 `isGatewayMode` 是否为空或为 false。

适用环境:自建 LobeHub 服务端 2.2.14;Android 客户端 User-Agent `LobeHub-Mobile/android-v1.0.15`;macOS 桌面客户端 2.2.14;官方统一 Go Gateway 0.3.2;服务端设置 `ENABLE_AGENT_GATEWAY=1`;Agent Gateway 与 Device Gateway 使用独立公网域名,WSS/health/auth 检查均通过。Issue 未提供 Python、CUDA、显卡、PyTorch 等信息,不要据此推断。

最快修复方案:暂无确认的一步修复方案。Issue 中未给出官方补丁或已验证的一步配置修复;该问题被判定为 Android 客户端路由问题,桌面端对照测试证明服务端路由正确。可优先尝试的方向是确认 Agent 的 `agencyConfig.heterogeneousProvider` 是否已同步到 Android,以及 Android 运行时是否取到 `enableGatewayMode` / `agentGatewayUrl`,但这两点均属 Issue 中的推测性诊断,并非已验证修复。

注意事项:Issue 中所有可用证据都指向 Android 客户端的 dispatch 决策,而非 Gateway 连通性或服务端鉴权;不要在未验证的情况下修改 Gateway 域名、WSS 或鉴权配置。用于排查的日志可能包含 deviceId、账号与请求路径,注意脱敏。上述根因与诊断步骤均为 Issue 讨论中的推断,尚未被作者确认已修复。

问题场景

用户在自建 LobeHub 上从 Android 客户端登录,选择一个在线 macOS Gateway 设备,然后在 Codex 会话中要求它执行一条无害的终端命令并返回标记。预期 Android 与桌面端行为一致:通过所选设备创建远程 Agent operation,经 Agent Gateway 流式返回进度和最终结果。实际 Android 没有创建远程 operation,而是显示自定义 Codex API Key 提示 / InvalidProviderAPIKey。

服务端脱敏证据(一次复现,2026-08-26 09:16 UTC):

POST /trpc/mobile/aiChat.sendMessageInServer 200
POST /webapi/chat/codex 401
User-Agent: LobeHub-Mobile/android-v1.0.15

该次 Android 请求没有创建 Agent Gateway operation,失败的 assistant 消息被记录为 provider `codex`,说明原生客户端回退到了 Provider API 路径。

同一账号、模型、在线设备、服务端和提示词的 macOS 桌面端对照测试成功:

POST /trpc/lambda/aiAgent.execAgent 200
POST Device Gateway /api/device/agent/run 200
Agent Gateway operation: done
heteroIngest / heteroFinish: 200

桌面端正常流式返回工具调用和最终标记,reconnect/resume 也能取回已完成的 operation。Android 端设备列表与 device RPC 均可用,因此问题范围被缩小到 Android 的 Codex dispatch 路由,而不是 Gateway 连通性。

报错原文

[Bug] Android 1.0.15 routes remote Codex device execution to Provider API instead of Agent Gateway
POST /trpc/mobile/aiChat.sendMessageInServer 200
POST /webapi/chat/codex 401
User-Agent: LobeHub-Mobile/android-v1.0.15
InvalidProviderAPIKey

原因分析

Issue 讨论给出的判断是:这是 Android 客户端的路由问题,`selectRuntimeType()` 对 Codex agent 解析成了 `’client’` 而不是 `’gateway’`。服务端路由本身是正确的(桌面端对照测试已证明),问题完全出在 Android 客户端如何评估 dispatch 决策。

调度决策链路:`conversationLifecycle.ts` 中的 `sendMessage` 从 `this.#get().isGatewayModeEnabled(agentId)` 读取 `isGatewayMode`,并从 `agencyConfig` 解析 `heterogeneousProvider`,然后把它们传入 `selectRuntimeType()`。对于非 remote 的异构 provider(如 Codex),该函数会带着 `clientExecutionAvailable: isDesktop` 调用 `resolveExecutionTarget()`,除非目标解析为 `’local’`,否则返回 `’gateway’`。

关键回退分支:`heterogeneousProvider` 的解析为 `agencyConfig?.heterogeneousProvider ?? (isDesktop && !isGatewayMode && isHeterogeneousAgentModelId(…))`。在 Android 上 `isDesktop` 为 `false`,所以这个基于旧 model-id 的回退永远不会触发。如果 `agencyConfig.heterogeneousProvider` 也是 `undefined`(例如 agent 配置未正确同步到 Android 客户端),那么 `heterogeneousProvider` 就是 `undefined`,`selectRuntimeType` 会直接越过所有 hetero 检查。

此时如果 `isGatewayMode` 同样为假值——取决于 `isGatewayModeEnabled()` 能否从 `global_serverConfigStore` 读到 `serverConfig.enableGatewayMode`——函数就会返回 `’client’`。`’client’` runtime 会走 `aiChat.sendMessageInServer` → `/webapi/chat/codex`,而这条路径需要 Codex API Key,于是正好对上 `InvalidProviderAPIKey`。

`global_serverConfigStore` 是在 `createServerConfigStore` 里挂到 `window` 上的。如果 React Native 环境没有填充该 store(或没有从服务端配置中暴露 `enableGatewayMode` / `agentGatewayUrl`),`isGatewayModeEnabled()` 就会返回 `false`,从而阻断 Gateway 这条兜底路径。

需要注意的是,移动端 router 其实已经包含 `aiAgentRouter`(PR #14103 加入的 gateway 执行端点),也就是说服务端已经就绪,只是客户端从未走到该路径。

可能原因(Issue 讨论中列出的一项或两项):一是 `agencyConfig.heterogeneousProvider` 在 Android 上为 `undefined`,导致异构检测被整体跳过;二是 `isGatewayModeEnabled()` 在 Android 上返回 `false`,导致 Gateway 兜底从未激活。

环境排查

  • 确认服务端 LobeHub 版本为 2.2.14,且已设置 `ENABLE_AGENT_GATEWAY=1`。
  • 确认 Android 客户端 User-Agent 为 `LobeHub-Mobile/android-v1.0.15`(用于区分是否命中同一问题范围)。
  • 确认官方统一 Go Gateway 版本为 0.3.2,Agent Gateway 与 Device Gateway 使用独立公网域名,且 WSS/health/auth 检查通过。
  • 检查 agent 的数据库记录:`agencyConfig` 是否设置了 `heterogeneousProvider`,以及是否同时带有 `executionTarget: ‘device’` 和有效的 `boundDeviceId`;如果没有,桌面端可能只是把设备选择存在本地,而没有写入共享配置。
  • 检查 Android 端 `config.getServerConfig` 拉取的配置是否包含 `enableGatewayMode` 与 `agentGatewayUrl`,这两项必须分别为 `true` 和非空,Gateway 路径才可能作为兜底激活。
  • Issue 未提供 Python、CUDA、PyTorch、显卡等依赖信息,无需纳入排查范围。

解决步骤

  1. 先复现并抓取 Android 端日志,确认失败请求形态是否为 `POST /trpc/mobile/aiChat.sendMessageInServer 200` 后紧跟 `POST /webapi/chat/codex 401`,且 User-Agent 为 `LobeHub-Mobile/android-v1.0.15`。
  2. 对照同一账号、模型、在线设备、服务端和提示词,用 macOS 桌面客户端执行一次,确认是否得到 `POST /trpc/lambda/aiAgent.execAgent 200` 与 `POST Device Gateway /api/device/agent/run 200`。若桌面成功,即可把问题范围收敛到 Android 客户端。
  3. 检查 agent 的 DB 记录中 `agencyConfig` 是否设置了 `heterogeneousProvider`、`executionTarget: ‘device’` 和有效的 `boundDeviceId`。如果缺失,则在配置同步或持久化环节补齐(此步骤基于 Issue 的诊断建议,属可优先尝试方向)。
  4. 在 Android 端 `selectRuntimeType` 被调用的位置(约 conversationLifecycle.ts 第 409–420 行)记录 `heterogeneousProvider` 和 `isGatewayMode` 的实际取值,判断是哪一个输入为假。
  5. 若确认是 `isGatewayMode` 为假,检查 Android 应用通过 `config.getServerConfig` 获取的配置是否填充了 `enableGatewayMode` 和 `agentGatewayUrl`;这两项需为 `true` / 非空,Gateway 兜底才能生效。
  6. 不要把改动直接落到 Gateway 域名、WSS 或鉴权配置上:Issue 已确认设备列表、device RPC 与桌面端 Gateway 路径均正常,问题不在这里。

验证方法

在 Android 端重复相同操作(选择在线 macOS Gateway 设备,在 Codex 会话中执行无害命令并返回标记),确认不再出现 Codex API Key 提示或 InvalidProviderAPIKey;服务端日志中应出现 Agent Gateway operation 创建记录,并伴随 `heteroIngest` / `heteroFinish` 200,工具调用与最终标记能正常流式返回,reconnect/resume 也能取回已完成的 operation。若日志仍停留在 `/webapi/chat/codex 401`,说明 Android 仍走 Provider API 路径,问题未解决。

参考来源

lobehub/lobe-chat #18713

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 23675

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注