github / github/copilot-sdk

Gemini 3.8 Flash is missing from listModels() and silently falls back to Claude Sonnet 5

Open
#2,571 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
10.5k
Forks
1.5k
Avg merge
1d 11h
Merged PRs (30d)
127

Description

## Summary

With `@github/copilot-sdk@1.0.13`, the Copilot-hosted model `gemini-3.8-flash` is absent from `client.listModels()`. However, `client.createSession({ model: "gemini-3.8-flash" })` succeeds, and `session.rpc.model.getCurrent()` reports that Gemini is selected.

When a prompt is sent, the authoritative `assistant.usage` event reports that the request actually used `claude-sonnet-5`.

This results in three conflicting states:

```text
listed: false
selected: gemini-3.8-flash
used: claude-sonnet-5
```

There is no error or warning indicating that the requested model was unavailable or that fallback occurred.

## Environment

- `@github/copilot-sdk`: `1.0.13`
- Bundled Copilot CLI/runtime: `1.0.83`
- Node.js: `v22.17.0`
- npm: `11.6.2`
- OS: Windows NT `10.0.26200.0`
- Authentication: Explicit GitHub token for a Copilot-enabled user
- Provider: GitHub Copilot-hosted models, not BYOK
- Model: `gemini-3.8-flash`

This was reproduced with two separately authenticated GitHub accounts.

## Minimal reproduction

Install the current stable SDK:

```bash
npm install @github/copilot-sdk@1.0.13
```

Save the following as `repro.mjs`:

```js
import { CopilotClient } from "@github/copilot-sdk";

const requestedModel = "gemini-3.8-flash";
const gitHubToken = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;

if (!gitHubToken) {
throw new Error("Set GITHUB_TOKEN or GH_TOKEN.");
}

const client = new CopilotClient({
gitHubToken,
useLoggedInUser: false,
});

let session;

try {
await client.start();

const models = await client.listModels();
console.log(
"listed:",
models.some(({ id }) => id === requestedModel),
);

session = await client.createSession({
model: requestedModel,
});

const current = await session.rpc.model.getCurrent();
console.log("selected:", current.modelId);

let actualModel;

session.on("assistant.usage", ({ data }) => {
actualModel = data.model;
});

const response = await session.sendAndWait(
"Reply with exactly OK.",
120_000,
);

console.log("used:", actualModel);
console.log("response:", response?.data.content);
} finally {
await session?.disconnect();
await client.stop();
}
```

Run it:

```bash
node repro.mjs
```

## Actual result

```text
listed: false
selected: gemini-3.8-flash
used: claude-sonnet-5
response: OK
```

The session-scoped model catalog also omits Gemini when queried with cache bypass:

```js
const result = await session.rpc.model.list({ skipCache: true });
```

## Expected result

One of the following would be consistent behavior:

1. If `gemini-3.8-flash` is available, it should be returned by the model-list APIs and used for the request.
2. If it is unavailable in the SDK/server-mode context, session creation or model switching should fail with a clear error.
3. If automatic fallback is intentional, the SDK should surface it explicitly, and `getCurrent()` should report the effective model rather than the unavailable requested model.

At minimum, `session.rpc.model.getCurrent()` and `assistant.usage.data.model` should not disagree without an accompanying model-change or fallback notification.

## Additional observations

- `client.listModels()` returned 21 models, with no Gemini models.
- `session.rpc.model.list({ skipCache: true })` returned 20 models, also with no Gemini models.
- The same behavior remained after explicitly enabling Gemini 3.8 Flash in the applicable Copilot model policy and waiting for the setting to propagate.
- Standalone Copilot CLI `1.0.83` can use `gemini-3.8-flash` successfully, and its usage data identifies Gemini as the actual model.
- This suggests a difference between standalone CLI startup model resolution and SDK/server-mode model discovery or dispatch.
- The issue is reproducible on a clean temporary Node.js project using the published SDK package.

Contributor guide

Open the contributing guide

Research direction

Start with the provided repro.mjs, then trace client.listModels(), session.rpc.model.list({ skipCache: true }), session.rpc.model.getCurrent(), and the assistant.usage event. Compare SDK/server-mode model discovery and dispatch with the standalone CLI behavior; done means the requested, selected, and actually used models are consistent or fallback is explicitly reported.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.