Skip to content

fix(agents): Gemini 3.1 models not recognized with 'google' provider alias#36160

Closed
xinhuagu wants to merge 1 commit intoopenclaw:mainfrom
xinhuagu:fix/gemini-31-forward-compat-google-provider
Closed

fix(agents): Gemini 3.1 models not recognized with 'google' provider alias#36160
xinhuagu wants to merge 1 commit intoopenclaw:mainfrom
xinhuagu:fix/gemini-31-forward-compat-google-provider

Conversation

@xinhuagu
Copy link
Copy Markdown
Contributor

@xinhuagu xinhuagu commented Mar 5, 2026

Fixes #36111
Fixes #36134

Root Cause

resolveGoogleGeminiCli31ForwardCompatModel only accepted google-gemini-cli as the provider ID. Users specifying google/gemini-3.1-flash-lite-preview (using the common google alias) hit the provider guard and got either:

Fix

Accept both google and google-gemini-cli as valid providers. Templates are always searched under google-gemini-cli (where they are registered in the model registry), but the cloned model preserves the caller's original provider ID.

Changes

  • src/agents/model-forward-compat.ts: widen provider check, use templateProvider for registry lookup
  • Added 2 tests for google/gemini-3.1-flash-lite-preview and google/gemini-3.1-pro-preview

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 5, 2026

Greptile Summary

This PR fixes Gemini 3.1 models not being recognized when specified with the google provider alias (e.g., google/gemini-3.1-flash-lite-preview) by widening the provider guard in resolveGoogleGeminiCli31ForwardCompatModel to accept both "google" and "google-gemini-cli". Template registry lookups always use "google-gemini-cli" (where models are registered), while the cloned model preserves the caller's original provider ID via provider: normalized in the patch.

  • src/agents/model-forward-compat.ts: Two-line guard change + templateProvider variable + provider: normalized in the patch — clean and minimal
  • src/agents/pi-embedded-runner/model.forward-compat.test.ts: Two new smoke tests for the google alias, but neither asserts provider: "google", which is the key behavioral guarantee introduced by this fix

Confidence Score: 4/5

  • Safe to merge — the logic change is correct and well-contained; only concern is a minor test coverage gap.
  • The implementation correctly widens the provider guard and routes template lookups through "google-gemini-cli" while preserving the caller's provider. The only gap is that the new tests don't assert provider: "google" on the returned model, meaning the most important behavioral guarantee introduced in this PR goes untested.
  • No files require special attention beyond strengthening the provider assertion in the new tests in src/agents/pi-embedded-runner/model.forward-compat.test.ts.

Last reviewed commit: 26aa88a

Comment on lines +90 to +112
it("builds a forward-compat fallback for google/gemini-3.1-flash-lite-preview", () => {
mockGoogleGeminiCliFlashTemplateModel();
const result = resolveModel("google", "gemini-3.1-flash-lite-preview", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toBeDefined();
expect(result.model).toMatchObject({
id: "gemini-3.1-flash-lite-preview",
name: "gemini-3.1-flash-lite-preview",
reasoning: true,
});
});

it("builds a forward-compat fallback for google/gemini-3.1-pro-preview", () => {
mockGoogleGeminiCliProTemplateModel();
const result = resolveModel("google", "gemini-3.1-pro-preview", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toBeDefined();
expect(result.model).toMatchObject({
id: "gemini-3.1-pro-preview",
name: "gemini-3.1-pro-preview",
reasoning: true,
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing provider assertion in new tests

The two new tests don't assert that the returned model's provider field is "google". The PR description explicitly states that "the cloned model preserves the caller's original provider ID" — this is the key behavioral change introduced here. Without asserting provider: "google", a future accidental removal of provider: normalized from the patch object in model-forward-compat.ts would not be caught by these tests.

The provider field matters at runtime because it drives auth lookup and API key resolution (getApiKeyForModel uses model.provider). If provider were to silently revert to "google-gemini-cli", users who have credentials stored under "google" could face auth failures.

Suggested fix for both tests:

Suggested change
it("builds a forward-compat fallback for google/gemini-3.1-flash-lite-preview", () => {
mockGoogleGeminiCliFlashTemplateModel();
const result = resolveModel("google", "gemini-3.1-flash-lite-preview", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toBeDefined();
expect(result.model).toMatchObject({
id: "gemini-3.1-flash-lite-preview",
name: "gemini-3.1-flash-lite-preview",
reasoning: true,
});
});
it("builds a forward-compat fallback for google/gemini-3.1-pro-preview", () => {
mockGoogleGeminiCliProTemplateModel();
const result = resolveModel("google", "gemini-3.1-pro-preview", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toBeDefined();
expect(result.model).toMatchObject({
id: "gemini-3.1-pro-preview",
name: "gemini-3.1-pro-preview",
reasoning: true,
});
});
it("builds a forward-compat fallback for google/gemini-3.1-flash-lite-preview", () => {
mockGoogleGeminiCliFlashTemplateModel();
const result = resolveModel("google", "gemini-3.1-flash-lite-preview", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toBeDefined();
expect(result.model).toMatchObject({
id: "gemini-3.1-flash-lite-preview",
name: "gemini-3.1-flash-lite-preview",
reasoning: true,
provider: "google",
});
});
it("builds a forward-compat fallback for google/gemini-3.1-pro-preview", () => {
mockGoogleGeminiCliProTemplateModel();
const result = resolveModel("google", "gemini-3.1-pro-preview", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toBeDefined();
expect(result.model).toMatchObject({
id: "gemini-3.1-pro-preview",
name: "gemini-3.1-pro-preview",
reasoning: true,
provider: "google",
});
});
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/model.forward-compat.test.ts
Line: 90-112

Comment:
**Missing `provider` assertion in new tests**

The two new tests don't assert that the returned model's `provider` field is `"google"`. The PR description explicitly states that "the cloned model preserves the caller's original provider ID" — this is the key behavioral change introduced here. Without asserting `provider: "google"`, a future accidental removal of `provider: normalized` from the `patch` object in `model-forward-compat.ts` would not be caught by these tests.

The `provider` field matters at runtime because it drives auth lookup and API key resolution (`getApiKeyForModel` uses `model.provider`). If `provider` were to silently revert to `"google-gemini-cli"`, users who have credentials stored under `"google"` could face auth failures.

Suggested fix for both tests:
```suggestion
  it("builds a forward-compat fallback for google/gemini-3.1-flash-lite-preview", () => {
    mockGoogleGeminiCliFlashTemplateModel();
    const result = resolveModel("google", "gemini-3.1-flash-lite-preview", "/tmp/agent");
    expect(result.error).toBeUndefined();
    expect(result.model).toBeDefined();
    expect(result.model).toMatchObject({
      id: "gemini-3.1-flash-lite-preview",
      name: "gemini-3.1-flash-lite-preview",
      reasoning: true,
      provider: "google",
    });
  });

  it("builds a forward-compat fallback for google/gemini-3.1-pro-preview", () => {
    mockGoogleGeminiCliProTemplateModel();
    const result = resolveModel("google", "gemini-3.1-pro-preview", "/tmp/agent");
    expect(result.error).toBeUndefined();
    expect(result.model).toBeDefined();
    expect(result.model).toMatchObject({
      id: "gemini-3.1-pro-preview",
      name: "gemini-3.1-pro-preview",
      reasoning: true,
      provider: "google",
    });
  });
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26aa88af82

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

templateIds: [...templateIds],
modelRegistry,
patch: { reasoning: true },
patch: { reasoning: true, provider: normalized },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep Gemini CLI schema sanitization active for google alias

Setting the cloned forward-compat model to provider: normalized makes google/gemini-3.1-* models carry provider google even though they still use the google-gemini-cli API template, and that bypasses the Google CLI tool-schema cleanup path because sanitizeToolsForGoogle only runs when provider is google-gemini-cli (src/agents/pi-embedded-runner/google.ts:248, called from src/agents/pi-embedded-runner/run/attempt.ts:797 and src/agents/pi-embedded-runner/compact.ts:390). In runs that use tools with unsupported schema keywords, this causes request failures that did not occur for the google-gemini-cli/... path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f90eae854

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

templateIds: [...templateIds],
modelRegistry,
patch: { reasoning: true },
patch: { reasoning: true, provider: normalized },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve gemini-cli auth provider for cloned 3.1 models

Overriding the cloned model to provider: normalized makes google/gemini-3.1-* forward-compat models report provider: "google" while still inheriting the google-gemini-cli transport fields from the template, and auth lookup is keyed by model.provider (src/agents/model-auth.ts, via getApiKeyForModel). In setups that only have google-gemini-cli OAuth profiles (the normal Cloud Code Assist path), these alias models now fail credential resolution because the runner looks for google credentials instead of google-gemini-cli.

Useful? React with 👍 / 👎.

@xinhuagu xinhuagu force-pushed the fix/gemini-31-forward-compat-google-provider branch from 1f90eae to 73315fc Compare March 5, 2026 14:50
… fallback

resolveGoogleGeminiCli31ForwardCompatModel only matched provider
'google-gemini-cli', silently rejecting the common 'google' alias.
Users specifying 'google/gemini-3.1-flash-lite-preview' or
'google/gemini-3.1-pro-preview' got unknown-model errors or silent
fallback to the default provider.

Accept both 'google' and 'google-gemini-cli' as valid providers,
searching templates under 'google-gemini-cli' (where they are
registered) while preserving the caller's provider ID.

Fixes openclaw#36111
Fixes openclaw#36134
@xinhuagu xinhuagu force-pushed the fix/gemini-31-forward-compat-google-provider branch from 73315fc to bdee4a7 Compare March 5, 2026 14:51
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bdee4a74a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +180 to +185
if (normalized !== "google-gemini-cli" && normalized !== "google") {
return undefined;
}
// Templates are registered under "google-gemini-cli" in the model registry,
// so always search there regardless of which alias the user specified.
const templateProvider = "google-gemini-cli";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep google provider on google forward-compat fallback

Accepting google in this guard now routes google/gemini-3.1-* through a google-gemini-cli template, so resolveModel returns early from forward-compat instead of using the configured models.providers.google fallback path; the resulting model carries Cloud Code Assist transport/auth metadata (model.provider is used by getApiKeyForModel), which breaks environments that only have Google API-key auth (GEMINI_API_KEY or providers.google.apiKey) and no google-gemini-cli credentials. This regression is triggered when a gemini-cli template is available in the registry.

Useful? React with 👍 / 👎.

@xinhuagu
Copy link
Copy Markdown
Contributor Author

xinhuagu commented Mar 5, 2026

Closing — same fix as #36145 and several others. 14 competing PRs for the same change, no point keeping this open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: XS

Projects

None yet

1 participant