Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions packages/types/src/__tests__/vscode-llm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ describe("vscodeLlmModels", () => {
expect(vscodeLlmModels["gemini-2.5-pro"].maxInputTokens).toBe(108594)
})
it.each([
["claude-opus-5", "Claude Opus 5", 935793, "advertised, unverified"],
["claude-sonnet-5", "Claude Sonnet 5", 925449, "measured"],
["gpt-5.6-luna", "GPT-5.6 Luna", 199753, "measured"],
["gpt-5.6-sol", "GPT-5.6 Sol", 271785, "measured"],
["gpt-5.6-terra", "GPT-5.6 Terra", 271785, "measured"],
["gemini-3.6-flash", "Gemini 3.6 Flash", 935793, "advertised, unverified"],
] as const)("preserves PR #13 row %s (%s), limit %i (%s)", (...[family, name, limit]) => {
["claude-opus-5", "Claude Opus 5", 935793, 197897],
["claude-sonnet-5", "Claude Sonnet 5", 925449, 925449],
["gpt-5.6-luna", "GPT-5.6 Luna", 199753, 199753],
["gpt-5.6-sol", "GPT-5.6 Sol", 271785, 271785],
["gpt-5.6-terra", "GPT-5.6 Terra", 271785, 271785],
["gemini-3.6-flash", "Gemini 3.6 Flash", 935793, 197897],
] as const)("preserves PR #13 row %s (%s) with PR #14 ceilings", (family, name, contextWindow, maxInputTokens) => {
expect(vscodeLlmModels[family]).toEqual({
contextWindow: limit,
contextWindow,
supportsImages: true,
supportsPromptCache: false,
inputPrice: 0,
Expand All @@ -33,7 +33,7 @@ describe("vscodeLlmModels", () => {
version: family,
name,
supportsToolCalling: true,
maxInputTokens: limit,
maxInputTokens,
})
})

Expand Down
15 changes: 7 additions & 8 deletions packages/types/src/providers/vscode-llm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ export type VscodeLlmModelId = keyof typeof vscodeLlmModels

export const vscodeLlmDefaultModelId: VscodeLlmModelId = "claude-sonnet-4.5"

// Curated VS Code LM (GitHub Copilot) model catalog.
// The API exposes only `maxInputTokens`; the UI and condense gate read that. `contextWindow` is
// the advertised window, kept for rows where it diverges from the ceiling (e.g. claude-opus-4.8).
// https://github.com/simurg79/Roo-Code/pull/13: sonnet-5 and gpt-5.6 limits were measured
// by single-message binary search on VS Code 1.126.0 (2026-07-14). Opus-5 and gemini-3.6-flash
// retain advertised, unverified limits from the Copilot model-picker cache (2026-07-26).
// The UI and condense gate use maxInputTokens; contextWindow preserves the advertised window.
// https://github.com/simurg79/Roo-Code/pull/13: sonnet-5 and gpt-5.6 were binary-searched.
// https://github.com/simurg79/Roo-Code/pull/14: opus-5 and gemini-3.6-flash retain advertised
// 935793 windows but conservatively reuse the 197897 ceiling measured on other models to avoid
// request overflow; neither model's actual input ceiling has been measured.
export const vscodeLlmModels = {
"claude-opus-5": {
contextWindow: 935793,
Expand All @@ -31,7 +30,7 @@ export const vscodeLlmModels = {
version: "claude-opus-5",
name: "Claude Opus 5",
supportsToolCalling: true,
maxInputTokens: 935793,
maxInputTokens: 197897,
},
"claude-opus-4.8": {
contextWindow: 679560,
Expand Down Expand Up @@ -247,7 +246,7 @@ export const vscodeLlmModels = {
version: "gemini-3.6-flash",
name: "Gemini 3.6 Flash",
supportsToolCalling: true,
maxInputTokens: 935793,
maxInputTokens: 197897,
},
"gemini-3.1-pro-preview": {
contextWindow: 197897,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1422,24 +1422,25 @@ describe("useSelectedModel", () => {
expect(result.current.info?.supportsImages).toBe(false)
})

it("pins a divergent family's contextWindow to maxInputTokens, not its advertised window", () => {
// claude-opus-4.8 is the row where contextWindow and maxInputTokens differ; a field swap to
// the advertised window would be caught here.
const family = "claude-opus-4.8"
const apiConfiguration: ProviderSettings = {
apiProvider: providerIdentifiers.vscodeLm,
vsCodeLmModelSelector: { vendor: "copilot", family },
}
it.each(["claude-opus-4.8", "claude-opus-5", "gemini-3.6-flash"] as const)(
"pins %s to the 197897 input ceiling, not its advertised window",
(family) => {
const apiConfiguration: ProviderSettings = {
apiProvider: providerIdentifiers.vscodeLm,
vsCodeLmModelSelector: { vendor: "copilot", family },
}

const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })

expect(result.current.provider).toBe(providerIdentifiers.vscodeLm)
expect(result.current.id).toBe(`copilot/${family}`)
expect(result.current.info?.contextWindow).toBe(vscodeLlmModels[family].maxInputTokens) // 197897
expect(result.current.info?.contextWindow).not.toBe(vscodeLlmModels[family].contextWindow) // NOT 679560
expect(result.current.info?.supportsImages).toBe(false)
})
expect(result.current.provider).toBe(providerIdentifiers.vscodeLm)
expect(result.current.id).toBe(`copilot/${family}`)
expect(result.current.info?.contextWindow).toBe(197897)
expect(result.current.info?.contextWindow).toBe(vscodeLlmModels[family].maxInputTokens)
expect(result.current.info?.contextWindow).not.toBe(vscodeLlmModels[family].contextWindow)
expect(result.current.info?.supportsImages).toBe(false)
},
)

it("falls back to the default model's window for an unlisted family (NOT 128000)", () => {
const apiConfiguration: ProviderSettings = {
Expand Down
Loading