Skip to content

[Bug] Agent 使用默认 Google 渠道时丢掉 /v1beta,generateContent 打到无版本路径并返回空 404 #1745

Description

@demohyp-debug

环境

  • Proma 版本:0.17.42(macOS)

  • 渠道:设置里新增的 Google 渠道

  • 默认 Base URL:https://generativelanguage.googleapis.com(未改)

  • 模型:gemini-3.7-flash

  • 复现入口:Agent

  • 同一渠道、同一模型走 Chat 时,路径拼接与 Agent 不一致

现象

Agent 使用上述 Google 渠道后失败,错误是:

{"error":{"message":"","code":404,"status":"Not Found"}}

message 为空。这不像 Google 官方的「模型不存在」错误。官方模型 404 一般会写:

models/<id> is not found for API version v1beta, or is not supported for generateContent.

所以这个空 404 更像请求根本没打到 Gemini 的版本化接口。

复现步骤

  1. 设置 → 渠道 → 新增 Google

  2. 保留默认 Base URL:https://generativelanguage.googleapis.com

  3. 填入有效 Gemini API Key,拉取模型列表

  4. 启用任意文本模型,例如 gemini-3.7-flash

  5. 设置 → Agent,把默认渠道/模型切到这条 Google 渠道

  6. 新建 Agent 会话,发送任意一句,例如 ping

实际结果:Agent 立刻失败,返回上面的空 404。

对照实验:

  • 同一渠道、同一 Key、同一模型,开 Chat 发同样一句话。Chat 会自己补 /v1beta,因此更容易成功,或至少返回带 message 的 Google JSON。

  • 不要把渠道 Base URL 改成 https://generativelanguage.googleapis.com/v1beta。那样可能让 Agent 暂时好了,但 Chat / 测连通 / 拉模型会变成 /v1beta/v1beta/...,再 404。

期望行为

Agent 使用默认 Google 渠道时,应请求官方文档里的版本化端点:

  • POST https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent

  • POST https://generativelanguage.googleapis.com/v1beta/models/{model}:streamGenerateContent?alt=sse

官方 REST 定义:

  • https://ai.google.dev/api/rest/v1beta/models/generateContent

  • 端点模板:https://generativelanguage.googleapis.com/v1beta/{model=models/*}:generateContent

官方 curl 示例:

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{"contents":[{"parts":[{"text":"Write a story about a magic backpack."}]}]}'

密钥文档里的 REST 示例同样带 /v1beta

  • https://ai.google.dev/gemini-api/docs/api-key

  • https://generativelanguage.googleapis.com/v1beta/interactions

结论:主机是 generativelanguage.googleapis.com,版本前缀必须是 /v1beta

根因

Proma 里 Google 渠道的默认地址是根域名,不含版本号:

PROVIDER_DEFAULT_URLS = {
  google: "https://generativelanguage.googleapis.com",
}

Chat / 渠道测试 / 拉模型会自己补版本路径:

// Chat GoogleAdapter
`${url}/v1beta/models/${input.modelId}:streamGenerateContent?alt=sse&key=${input.apiKey}`

// 渠道测试 / 拉模型
<span class="hljs-subst">${url}</span>/v1beta/models?key=<span class="hljs-subst">${apiKey}</span>

但 Agent 把渠道 baseUrl 原样交给 Pi / @google/genai,并且没有为 Google 补 /v1beta

// apps/electron/src/main/lib/adapters/pi-model-registry.ts
function normalizePiBaseUrl(baseUrl, provider, api) {
if (!baseUrl) return undefined
if (provider === "proma") { /* ... / }
if (api === "anthropic-messages") { /
... / }
if (provider === "custom" || provider === "openai-responses") { /
... */ }
return baseUrl.trim().replace(//$/, "")
}

随后 Google SDK 看到自定义 baseUrl 后,会把 apiVersion 设成空字符串,不再追加版本号:

// pi-ai google-generative-ai adapter
if (model.baseUrl) {
httpOptions.baseUrl = model.baseUrl
httpOptions.apiVersion = "" // baseUrl already includes version path, don't append
}

于是 Agent 实际打到:

https://generativelanguage.googleapis.com/models/gemini-3.7-flash:generateContent

而不是:

https://generativelanguage.googleapis.com/v1beta/models/gemini-3.7-flash:generateContent

Pi catalog 里内置 Google 模型的 baseUrl  https://generativelanguage.googleapis.com/v1beta,和渠道默认根域名也不一致。

实测对照

对官方主机、不带 Key 直接探测:

URL 结果
POST https://generativelanguage.googleapis.com/models/gemini-3.7-flash:generateContent 404 Not Found,content-type: text/html,空 body
POST https://generativelanguage.googleapis.com/models/gemini-3.7-flash:streamGenerateContent?alt=sse 同样空 404
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3.7-flash:generateContent 进入 Gemini API,返回带 message 的 JSON(无 Key 时是 403 PERMISSION_DENIED)

空 404 的形态,和 Agent 里看到的 {"error":{"message":"","code":404,"status":"Not Found"}} 一致:请求没进 Gemini 版本化接口。

这不是模型名问题。官方模型代码就是 gemini-3.7-flash

  • https://ai.google.dev/gemini-api/docs/models/gemini-3.7-flash

建议修复

不要让用户把渠道地址改成带 /v1beta。那会破坏 Chat / 测连通 / 拉模型已经写死的 ${baseUrl}/v1beta/...

应在 Agent 注册 Google provider 时补版本前缀。最小改法类似:

function normalizePiBaseUrl(baseUrl: string | undefined, provider: ProviderType, api: Api): string | undefined {
  if (!baseUrl) return undefined
  // existing proma / anthropic / openai-responses 分支保持不变
  const normalized = baseUrl.trim().replace(/\/+$/, "")
  if (provider === "google" || api === "google-generative-ai") {
    return /\/v\d+[a-z]*$/i.test(normalized) ? normalized : `${normalized}/v1beta`
  }
  return normalized
}

验收标准:

  1. 默认 Google 渠道地址保持 https://generativelanguage.googleapis.com 不变。

  2. Agent 实际请求变成 /v1beta/models/{model}:generateContent  :streamGenerateContent

  3. Chat、渠道测试、拉模型仍然只追加一次 /v1beta,不会变成 /v1beta/v1beta

  4. 如果用户已经手动填了 .../v1beta,Agent 不再重复追加。

  5. 有效 Key + gemini-3.7-flash 的 Agent 会话可以正常流式输出,不再出现空 404。

补充

  • 这不是 Proma 官方云渠道的问题,是用户自配 Google 直连渠道在 Agent 路径上的协议拼接 bug。

  • README 写明 Google 渠道同时支持 Chat 和 Pi Agent;当前默认配置下 Agent 不可用。

  • 临时绕过:Agent 先改用 Proma 官方渠道里的 Gemini,或只用 Chat 走 Google 直连。用户改渠道 URL 不是正确修复。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions