Skip to content

fix(llm): 修复 Gemini 在裸 base URL 与当前模型下校验失败 - #1246

Open
DragonNameLeo wants to merge 2 commits into
Open-Less:betafrom
DragonNameLeo:fix/gemini-validation
Open

DragonNameLeo wants to merge 2 commits into
Open-Less:betafrom
DragonNameLeo:fix/gemini-validation

Conversation

@DragonNameLeo

@DragonNameLeo DragonNameLeo commented Oct 21, 2026 •

Copy link
Copy Markdown

摘要

无对应 issue。

Gemini LLM 渠道填写裸 https://generativelanguage.googleapis.com 时,模型列表可以拉取,但校验 / 调用返回 404;默认模型 gemini-2.5-flash 对新用户已不可用;关闭思考时发送的 thinkingBudget: 0 会被 gemini-3.5-flash-lite 等模型以 400 拒绝,且错误信息只是通用的 Request contains an invalid argument.,用户无从判断原因。本 PR 修复前两点,并在第三种情况下明确提示用户打开「思考」开关。

修复 / 新增 / 改进

  • generateContent / streamGenerateContent 对裸 host 默认补 /v1beta,与模型列表、Gemini ASR(asr::gemini::endpoint_url)一致;已带路径的 base URL 不变
  • LLM / Omni 的 Gemini 默认模型改为 gemini-3.5-flash-lite,并用 export_provider_descriptors 重新生成浏览器预览用的 provider 目录
  • 带 thinkingConfig 的请求返回 400 时,去掉 thinkingConfig 再探测一次(unary / SSE 均是):探测成功说明是模型拒绝关闭思考,返回 llmThinkingRequired;探测失败则保留原 HTTP 错误。Gemini 对此返回的是通用错误信息,无法按文案判断,所以用探测区分
  • 设置页(渠道详情的「验证」结果、渠道列表的状态)对 llmThinkingRequired 提示「请打开模型旁的「思考」开关后重新验证」,八种界面语言均已补充(settings.providers.llmThinkingRequired、settings.channels.errThinking)
  • sanitize_validation_error 改为按后缀匹配 parse error: <code>:润色失败的消息形如 LLM provider failed: parse error: <code>,原先的全等匹配会把 llmResponseIncomplete 等错误码在校验时吞成通用失败
  • 新增单测:content_urls_default_bare_host_to_v1beta、rejected_thinking_off_asks_to_turn_thinking_on、other_invalid_arguments_keep_the_http_error、only_a_400_with_thinking_config_is_probed、validation_keeps_llm_codes_from_polish_failures

兼容

  • 不包含:Gemini ASR、其他 provider
  • 对现有用户 / 本地环境 / 构建流程的影响:已保存的模型与带版本路径的 base URL 不受影响;关闭思考且模型拒绝时,校验与润色都会以「需开启思考」失败(此前同样以 400 失败,只是没有原因);只有带 thinkingConfig 的 400 才会多发一次探测请求

测试计划

  • 命令:cargo test --locked -p openless-core --lib -- llm_gemini provider_service provider_rules
  • 结果:73 passed
  • 命令:cargo run --locked -p openless-core --example export_provider_descriptors
  • 结果:重新生成后与提交内容无差异
  • 命令:npx tsx src/lib/ipc/providers.test.ts、npx tsx src/pages/settings/ChannelList.test.ts、npx tsc --noEmit
  • 结果:通过
  • 证据路径:无

🤖 Generated with Claude Code

https://claude.ai/code/session_01Abbfv5hvANpC7Sku5KEXJ3

DragonNameLeo and others added 2 commits October 21, 2026 17:32
…models

- Default a bare https://generativelanguage.googleapis.com to /v1beta for
  generateContent / streamGenerateContent, matching model listing and the
  Gemini ASR path (validation previously 404'd while model listing worked).
- Retry once without thinkingConfig when the model rejects the channel-level
  thinking-off config with a 400, instead of failing the call.
- Switch the LLM / Omni default model from gemini-2.5-flash (no longer
  available to new users) to gemini-3.5-flash-lite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJvDYNu6QoSEhJ4yGSuRqk
… off

gemini-3.5-flash-lite (the Gemini channel default) answers the
thinking-off config (thinkingBudget 0) with the generic
"Request contains an invalid argument.", so the earlier retry that
looked for "thinking" in the error body never fired and validation
kept failing with a bare 400.

- On a 400 for a request that carried thinkingConfig, re-send it once
  without thinkingConfig. If that passes, fail with llmThinkingRequired
  instead of the HTTP error; any other 400 keeps its original error.
- Pass the code through validation (polish failures arrive as
  "LLM provider failed: parse error: <code>") and show it in the
  provider settings and the channel list as "turn Thinking on", in all
  eight UI languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Abbfv5hvANpC7Sku5KEXJ3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant