Skip to content

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

Closed as not planned

Description

@yangheng95

Description

Copilot Gemini Flash models (e.g. gemini-3-flash-preview) cannot make structured tool calls. The model outputs plain-text descriptions like [tool_call: mirror-url ...] instead of structured tool_calls in the response.

Root cause

sanitizeGemini in ProviderTransform.schema() matches Copilot Gemini models via api.id.includes("gemini"). This transform is designed for Google's native Gemini API, but Copilot models use an OpenAI-compatible endpoint — the Copilot API handles Gemini schema conversion internally.

Two post-v1.1.49 commits added aggressive schema transforms that produce double-transformed schemas the Copilot translation layer can't handle:

This breaks tool calling for Copilot Gemini models. Copilot Claude/GPT models are unaffected (they don't match includes("gemini")).

Steps to reproduce

  1. Authenticate with GitHub Copilot
  2. Select a Gemini model (e.g. gemini-3-flash-preview)
  3. Send a message that should trigger a tool call
  4. Observe that the model outputs a plain-text tool call description instead of a structured tool_calls response

Expected behavior

The model should produce structured tool_calls in the response, the same as Copilot Haiku or GPT models.

Environment

  • OpenCode version: any post-v1.1.49
  • Provider: github-copilot
  • Model: gemini-3-flash-preview

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Feb 27, 2026
  2. ll01 commented on Mar 5, 2026

    @ll01

    I'm facing a similar issue

    Image
  3. thatdaveguy1 commented on Mar 29, 2026

    @thatdaveguy1

    I checked preserved local session history in ~/.local/share/opencode/opencode.db and found a concrete Copilot Gemini Flash example that matches this issue.

    Representative stored example:

    • session: ses_2c99226d4ffeg3prz743ArLhvE
    • title: Fix cutoff UI & replace drilldown modal with dark Google Map
    • assistant message: msg_d3679e4d1001sB1zVNAbQmgVDM

    The assistant text part contains pseudo-tool / planner text like:

    • <TodoWrite ... />
    • @explorer

    but the stored message parts are only:

    • step-start
    • text
    • step-finish with reason = "stop"

    There is no structured tool part for that message. So in this case Gemini/Copilot appears to emit tool intent as plain text instead of structured tool calls.

    This looks distinct from #14972:

    • #14972: real tool part exists, but the loop stops anyway
    • this issue: no real tool part exists because Copilot Gemini emitted pseudo-tool text instead

    I observed this in preserved local sessions on OpenCode 1.3.3/1.3.4. So this does not seem limited to custom providers; it also affects normal github-copilot / gemini-3-flash-preview usage.

  4. sparticle9 commented on Apr 1, 2026

    @sparticle9

    i was testing about this as well on both gemini-3.1-pro and gemini-3-flash, and after some digging with gemini pro itself, it asserted:

    The root cause is a known limitation of the Copilot session.send API pipeline: It completely ignores system instructions that
    enforce schema.

    When Vercel AI SDK calls generateObject in mode: 'json', it injects a system prompt asking the model to strictly follow your
    provided JSON schema (which in our script was {"recipe": {"name": "...", "ingredients": [...]}}).

    But look at what Gemini actually returns:

      {
        "title": "Toast",
        "ingredients": [
          "1 slice of bread"
        ],
        "instructions": [
          "Place the bread in a toaster and heat until golden brown."
        ]
      }

    It outputs valid JSON, but it invents its own schema (title, ingredients as an array of strings, instructions) completely
    ignoring the schema the AI SDK requested. Because the fields don't match the Zod schema exactly, the SDK throws a
    AI_NoObjectGeneratedError: response did not match schema.

    As confirmed by my Exa search across the github/copilot-sdk issues, the GitHub Copilot API currently lacks a response_format:
    { type: "json_schema" } field on the backend (Issue #41 / #857). Until GitHub adds native structured_outputs: true support to
    their proxy, any model routed through Copilot (including gemini-3.1-pro-preview) will be "deaf" to strict schema enforcement.

  5. hrez commented on Apr 4, 2026

    @hrez

    I am not sure it's at all related. And it could be github copilot gemini model degradation too. But basically lately GitHub Copilot gemini-3-flash-preview tasks often stop mid-way without any error or a reason. No questions asked, no explanation, just stops working on the task after some of it done but before finishing it up.
    Copilot's gemini-3-flash-preview was working fine in opencode for a long time until recently.
    As you can imagine it's hard to reproduce. But switching to copilot's sonnet works fine. So, it's gemini flash specific.
    I can't say which opencode version was working fine. I thought it may be recent and reverted to 1.2.25 but that also has this issue.

  6. thatdaveguy1 commented on Apr 4, 2026

    @thatdaveguy1

    I am not sure it's at all related. And it could be github copilot gemini model degradation too. But basically lately GitHub Copilot gemini-3-flash-preview tasks often stop mid-way without any error or a reason. No questions asked, no explanation, just stops working on the task after some of it done but before finishing it up. Copilot's gemini-3-flash-preview was working fine in opencode for a long time until recently. As you can imagine it's hard to reproduce. But switching to copilot's sonnet works fine. So, it's gemini flash specific. I can't say which opencode version was working fine. I thought it may be recent and reverted to 1.2.25 but that also has this issue.

    I am pretty confident it's something Opencode, because if I use Gemini 3 Flash in VSCode this doesn't happen

  7. assigned and unassigned on Apr 26, 2026
  8. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  9. alex-pathcourse commented on May 11, 2026

    @alex-pathcourse

    You're seeing plain-text tool call outputs instead of structured tool_calls when using Copilot Gemini models like gemini-3-flash-preview. PathCourse Health handles OpenAI-compatible structured outputs natively so you don't have to build or maintain custom parsing and response transforms.

    Working example: https://github.com/pathcourse-health/pch-integration-examples#framework-adapters

  10. MusabaN commented on Jul 7, 2026

    @MusabaN

    This is also happening with gemini flash 3.5

  11. github-actions commented on Sep 6, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

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