Skip to content

fix(provider): skip Gemini schema sanitization for Copilot models#15313

Open
yangheng95 wants to merge 2 commits intoanomalyco:devfrom
yangheng95:fix/copilot-gemini-schema
Open

fix(provider): skip Gemini schema sanitization for Copilot models#15313
yangheng95 wants to merge 2 commits intoanomalyco:devfrom
yangheng95:fix/copilot-gemini-schema

Conversation

@yangheng95
Copy link

@yangheng95 yangheng95 commented Feb 27, 2026

Issue for this PR

Closes #15315

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

sanitizeGemini in ProviderTransform.schema() matches Copilot Gemini models via api.id.includes("gemini"), but these models use an OpenAI-compatible endpoint — the Copilot API handles Gemini schema conversion internally.

Two post-v1.1.49 commits (#11952, #11888) added aggressive schema transforms (defaulting array item types, stripping properties from non-object types) that produce double-transformed schemas the Copilot translation layer can't handle, breaking tool calling.

Fix: add !model.providerID.includes("github-copilot") to the condition so Copilot models receive standard JSON Schema.

How did you verify your code works?

  • All 105 existing transform.test.ts tests pass
  • Added 2 new test cases verifying sanitizeGemini is skipped for github-copilot and github-copilot-enterprise providers
  • Verified Copilot Gemini Flash produces structured tool calls after the fix
  • Copilot Haiku/GPT models unaffected (they never matched includes("gemini"))

Screenshots / recordings

N/A — not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

The `sanitizeGemini` transform in `ProviderTransform.schema()` is
designed for Google's native Gemini API, which rejects certain JSON
Schema constructs (integer enums, empty array items, properties on
non-object types, etc.).

However, GitHub Copilot proxies Gemini models through an
OpenAI-compatible endpoint. The Copilot API handles Gemini-specific
schema requirements internally. Applying `sanitizeGemini` to Copilot
Gemini models (matched via `api.id.includes("gemini")`) produces
schemas that confuse the Copilot API's translation layer, causing
the model to fall back to plain-text tool call descriptions instead
of structured `tool_calls` in the response.

This was not an issue before v1.1.49 because `sanitizeGemini` only
performed mild transforms (enum stringification, required filtering).
Two post-v1.1.49 commits added more aggressive operations:
- 3741516 (default array items type to "string")
- 3adeed8 (strip properties/required from non-object types)

These additional transforms break tool calling for Copilot Gemini
models while Copilot Claude/GPT models are unaffected (they don't
match the `includes("gemini")` condition).

Fix: exclude `github-copilot` provider from `sanitizeGemini`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 27, 2026 02:51
@github-actions github-actions bot added needs:compliance This means the issue will auto-close after 2 hours. needs:issue labels Feb 27, 2026
@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR prevents Copilot-hosted “Gemini” models (e.g. gemini-3-* served via the github-copilot provider) from going through the client-side sanitizeGemini JSON Schema transformation, since Copilot’s API is OpenAI-compatible and already handles Gemini-specific schema quirks internally.

Changes:

  • Update ProviderTransform.schema() to apply sanitizeGemini only for Google/Gemini models when the provider is not github-copilot*.
  • Add clarifying inline comments explaining why Copilot is excluded.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +898 to +904
// Convert integer enums to string enums for Google/Gemini.
// Skip for Copilot models — they use OpenAI-compatible format and the
// Copilot API handles Gemini schema requirements internally.
if (
(model.providerID === "google" || model.api.id.includes("gemini")) &&
!model.providerID.includes("github-copilot")
) {
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

New behavior (skipping sanitizeGemini for github-copilot* providers) isn’t covered by unit tests. Please add a ProviderTransform.schema test case where providerID is "github-copilot" (or "github-copilot-enterprise") and api.id includes "gemini", asserting that Gemini-specific sanitization (e.g., enum-to-string conversion or stripping properties/required) does NOT occur.

Copilot uses AI. Check for mistakes.
Verify that sanitizeGemini is NOT applied when providerID is
"github-copilot" or "github-copilot-enterprise", even when api.id
includes "gemini". Asserts that enum values stay as integers and
properties/required are preserved on non-object types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot removed needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Feb 27, 2026
@github-actions
Copy link
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

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.

fix(provider): Copilot Gemini models fail to produce structured tool calls

2 participants