Skip to content

fix: resolve google provider default API to google-generative-ai#88512

Merged
steipete merged 1 commit into
openclaw:mainfrom
1052326311:fix/88480-gemini-transport-routing
May 31, 2026
Merged

fix: resolve google provider default API to google-generative-ai#88512
steipete merged 1 commit into
openclaw:mainfrom
1052326311:fix/88480-gemini-transport-routing

Conversation

@1052326311

@1052326311 1052326311 commented May 31, 2026

Copy link
Copy Markdown
Contributor

Fixes #88480

Summary

  • Keeps the generic baseUrl-only fallback for non-Google providers on openai-completions.
  • Lets provider transport hooks claim omitted provider defaults before the generic fallback is applied.
  • Makes the Google provider hook resolve baseUrl-only models.providers.google configs to google-generative-ai, while explicit api: openai-completions stays unchanged.

Verification

  • OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=300000 OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/pr88512-model-vitest-cache2 fnm exec --using=24.15.0 node scripts/run-vitest.mjs run src/agents/embedded-agent-runner/model.test.ts extensions/google/api.test.ts
  • fnm exec --using=24.15.0 node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.src.json --incremental --tsBuildInfoFile /tmp/pr88512-test-src2.tsbuildinfo
  • fnm exec --using=24.15.0 node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile /tmp/pr88512-extensions-test.tsbuildinfo
  • git diff --check

Real behavior proof

Behavior addressed: Google provider configs with models.providers.google.baseUrl and omitted api now resolve to the native Gemini google-generative-ai transport instead of the OpenAI-compatible transport.

Real environment tested: Local OpenClaw checkout at 5a15bd1c79740f7538d31c7cbde2483c4887b0a3, Node 24.15.0, Google Gemini API key read from 1Password item AI API Key - Google Gemini - GEMINI_API_KEY - steipete-m5; key value was not printed.

Exact steps or command run after this patch: Resolved the Google provider transport for provider google, omitted api, and baseUrl https://generativelanguage.googleapis.com, then used the same 1Password Gemini key for a live generateContent request to gemini-2.0-flash.

Evidence after fix: Copied live output from the redacted terminal capture:

head=5a15bd1c79740f7538d31c7cbde2483c4887b0a3
provider=google
configuredApi=omitted
configuredBaseUrl=https://generativelanguage.googleapis.com
resolvedTransport={"api":"google-generative-ai","baseUrl":"https://generativelanguage.googleapis.com/v1beta"}
secretPrefix=AIza
secretSource=1password:AI API Key - Google Gemini - GEMINI_API_KEY - steipete-m5
googleGenerateContent={"status":200,"ok":true,"textLen":3,"containsOk":true}

Observed result after fix: The omitted-api Google config selected the native Gemini transport, and the live Google endpoint accepted the configured key with HTTP 200.

What was not tested: A full packaged gateway chat loop was not run; the focused resolver path, Google provider hook, and live Gemini endpoint were verified directly.

@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed May 30, 2026, 11:49 PM ET / 03:49 UTC.

Summary
The PR changes resolveConfiguredProviderDefaultApi so Google provider configs with a baseUrl and no explicit api default to google-generative-ai, and passes the provider id at its call sites.

PR surface: Source +7. Total +7 across 1 file.

Reproducibility: yes. from source, not from a live run: current main defaults baseUrl-only provider configs to openai-completions, and the linked report shows Google requests being routed through the wrong OpenAI-style transport.

Review metrics: 1 noteworthy metric.

  • Provider default surface: 1 changed default. The PR changes the omitted-api fallback for baseUrl-only Google provider configs, which affects upgrade and routing behavior beyond a local code path.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Move the provider-specific fallback into Google provider policy or a generic provider-owned hook.
  • [P1] Add focused regression coverage for baseUrl-only Google config resolving to google-generative-ai while explicit openai-completions remains unchanged.
  • [P1] Add redacted real behavior proof in the PR body; if re-review does not trigger, ask a maintainer to comment @clawsweeper re-review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: Only test claims are present; the contributor needs redacted terminal/log/live output showing a real Gemini chat now uses google-generative-ai before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P2] Provider routing fallback is compatibility-sensitive; existing models.providers.google rows that intentionally used a Google OpenAI-compatible baseUrl without an explicit api would switch transports unless maintainers require explicit api: openai-completions.
  • [P1] The PR body reports test runs, but no real Gemini/OpenClaw run, redacted logs, terminal output, or linked artifact demonstrates that a chat request now reaches the native Google transport.
  • [P2] The diff does not add focused regression coverage for the baseUrl-only Google default; neighboring tests cover explicit api and discovered-api paths but not the new fallback branch.

Maintainer options:

  1. Move the default to provider policy (recommended)
    Before merge, keep core fallback generic, have the Google provider resolve the undefined-api/baseUrl case, add focused regression coverage, and attach redacted real behavior proof.
  2. Accept native Google as the bare default
    Maintainers can decide that models.providers.google without explicit api always means native Gemini, but should document that OpenAI-compatible Google endpoints must set api: openai-completions.

Next step before merge

  • [P1] Needs contributor proof and maintainer review of the provider-boundary and compatibility choice; it is not safe for automated repair while proof is missing.

Security
Cleared: The diff only changes provider transport selection logic and does not introduce dependency, workflow, secret-storage, or supply-chain changes.

Review findings

  • [P2] Move the Google default into provider policy — src/agents/embedded-agent-runner/model.ts:351-352
Review details

Best possible solution:

Move the provider-specific default into the Google provider runtime/policy hook or a generic provider-owned hook contract, add focused regression coverage for baseUrl-only Google config, and require redacted real behavior proof before merge.

Do we have a high-confidence way to reproduce the issue?

Yes from source, not from a live run: current main defaults baseUrl-only provider configs to openai-completions, and the linked report shows Google requests being routed through the wrong OpenAI-style transport.

Is this the best way to solve the issue?

No: the intended behavior is right, but the current patch puts a Google-specific fallback in core instead of the Google provider boundary or a generic provider hook.

Full review comments:

  • [P2] Move the Google default into provider policy — src/agents/embedded-agent-runner/model.ts:351-352
    This core fallback now hard-codes provider === "google", but Google transport/default behavior is owned by the Google provider hooks (normalizeTransport/normalizeConfig). Please resolve the undefined-api/baseUrl case through the provider policy or a generic provider hook so core stays provider-agnostic and future provider aliases do not drift.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against e1a98171417c.

Label changes

Label changes:

  • add P1: The linked bug breaks Google Gemini chat routing for real model use, but the PR still needs a safe provider-boundary fix and proof before merge.
  • add merge-risk: 🚨 compatibility: Changing the omitted-api default for existing Google provider configs can alter upgrade behavior for users relying on the prior OpenAI-compatible fallback.
  • add merge-risk: 🚨 auth-provider: The diff changes provider transport routing for Google models, which directly affects which credential and endpoint family receives the request.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Only test claims are present; the contributor needs redacted terminal/log/live output showing a real Gemini chat now uses google-generative-ai before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P1: The linked bug breaks Google Gemini chat routing for real model use, but the PR still needs a safe provider-boundary fix and proof before merge.
  • merge-risk: 🚨 compatibility: Changing the omitted-api default for existing Google provider configs can alter upgrade behavior for users relying on the prior OpenAI-compatible fallback.
  • merge-risk: 🚨 auth-provider: The diff changes provider transport routing for Google models, which directly affects which credential and endpoint family receives the request.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Only test claims are present; the contributor needs redacted terminal/log/live output showing a real Gemini chat now uses google-generative-ai before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +7. Total +7 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 11 4 +7
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 11 4 +7

What I checked:

  • Current fallback: Current main returns an explicit configured api when present, otherwise any baseUrl-only provider config defaults to openai-completions without provider context. (src/agents/embedded-agent-runner/model.ts:340, e1a98171417c)
  • PR fallback change: The PR head adds a provider parameter, returns google-generative-ai when the provider is exactly google, and passes the provider at the three call sites. (src/agents/embedded-agent-runner/model.ts:340, b14ff960d60c)
  • Google provider boundary: The bundled Google provider already owns transport normalization and only creates the Google stream function for model.api === "google-generative-ai", so the default can be resolved in provider policy instead of core fallback logic. (extensions/google/provider-registration.ts:47, e1a98171417c)
  • Explicit OpenAI-compatible path: Existing tests preserve explicit api: "openai-completions" for Google provider rows using the Google /openai endpoint; this PR changes only the omitted-api default. (src/config/model-alias-defaults.test.ts:284, e1a98171417c)
  • Review policy: Root policy treats provider routing, config/default, and fallback behavior as compatibility-sensitive and asks review to inspect the whole provider/model routing surface. (AGENTS.md:26, e1a98171417c)
  • Proof gap: The PR changes only model.ts and the supplied GitHub context has test-run claims but no real Gemini/OpenClaw terminal output, logs, screenshot, recording, or linked artifact showing the fixed runtime path. (b14ff960d60c)

Likely related people:

  • steipete: Current-main blame and log history show Peter Steinberger on the existing provider default helper and recent model-provider refactors in this checkout; older provenance is limited by the available grafted history. (role: recent area contributor; confidence: medium; commits: 22e4289d3f05, 4c33aaa86c16, 00d8d7ead059; files: src/agents/embedded-agent-runner/model.ts, extensions/google/provider-registration.ts, extensions/google/provider-policy.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels May 31, 2026
@byungskers

Copy link
Copy Markdown

This seems to target the right misrouting symptom, but I am a little nervous about hard-coding provider === "google" inside the generic fallback helper. Would it be cleaner to resolve this through Google provider policy / transport normalization instead, so the core fallback stays provider-agnostic and future provider-specific defaults do not accumulate here? Even if you keep the current shape, a focused regression for the baseUrl-only Google case would help lock the intended contract down.

@steipete steipete self-assigned this May 31, 2026
…nclaw#88480)

When a configured Google provider/model row had no explicit
but had a baseUrl set, the fallback defaulted to openai-completions,
causing Gemini requests to route through the OpenAI Responses
transport instead of the native @google/genai transport.

Made resolveConfiguredProviderDefaultApi provider-aware: for the
google provider, the default API is now google-generative-ai.

Root cause: the generic fallback assumed any provider with a baseUrl
should use openai-completions, which is incorrect for Google's native
Gemini API.
@steipete steipete force-pushed the fix/88480-gemini-transport-routing branch from b14ff96 to 5a15bd1 Compare May 31, 2026 21:42
@openclaw-barnacle openclaw-barnacle Bot added extensions: google size: S proof: supplied External PR includes structured after-fix real behavior proof. and removed size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 31, 2026
@steipete steipete merged commit b73e135 into openclaw:main May 31, 2026
199 of 207 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 1, 2026
…nclaw#88480) (openclaw#88512)

When a configured Google provider/model row had no explicit
but had a baseUrl set, the fallback defaulted to openai-completions,
causing Gemini requests to route through the OpenAI Responses
transport instead of the native @google/genai transport.

Made resolveConfiguredProviderDefaultApi provider-aware: for the
google provider, the default API is now google-generative-ai.

Root cause: the generic fallback assumed any provider with a baseUrl
should use openai-completions, which is incorrect for Google's native
Gemini API.

Co-authored-by: xin <1052326311+xin@users.noreply.github.com>
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
…nclaw#88480) (openclaw#88512)

When a configured Google provider/model row had no explicit
but had a baseUrl set, the fallback defaulted to openai-completions,
causing Gemini requests to route through the OpenAI Responses
transport instead of the native @google/genai transport.

Made resolveConfiguredProviderDefaultApi provider-aware: for the
google provider, the default API is now google-generative-ai.

Root cause: the generic fallback assumed any provider with a baseUrl
should use openai-completions, which is incorrect for Google's native
Gemini API.

Co-authored-by: xin <1052326311+xin@users.noreply.github.com>
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…nclaw#88480) (openclaw#88512)

When a configured Google provider/model row had no explicit
but had a baseUrl set, the fallback defaulted to openai-completions,
causing Gemini requests to route through the OpenAI Responses
transport instead of the native @google/genai transport.

Made resolveConfiguredProviderDefaultApi provider-aware: for the
google provider, the default API is now google-generative-ai.

Root cause: the generic fallback assumed any provider with a baseUrl
should use openai-completions, which is incorrect for Google's native
Gemini API.

Co-authored-by: xin <1052326311+xin@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling extensions: google merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Google Gemini chat model routes to openai-responses transport (401), native @google/genai transport never selected

3 participants