diff --git a/apps/server/src/provider/Layers/GeminiCliProvider.test.ts b/apps/server/src/provider/Layers/GeminiCliProvider.test.ts new file mode 100644 index 000000000000..d9ecde6a9d7c --- /dev/null +++ b/apps/server/src/provider/Layers/GeminiCliProvider.test.ts @@ -0,0 +1,32 @@ +import assert from "node:assert/strict"; + +import * as Schema from "effect/Schema"; +import { describe, it } from "vitest"; + +import { GenericProviderSettings } from "@t3tools/contracts"; +import { makePendingGeminiCliProvider } from "./GeminiCliProvider.ts"; + +const decodeSettings = Schema.decodeSync(GenericProviderSettings); + +/** + * The Gemini "Thinking Budget" selector was inert — its value was never read + * by the adapter and never reached the Gemini CLI. It was removed (rather than + * shipping a control that does nothing). This guard keeps it gone: an upstream + * sync that re-adds the descriptor without real wiring will fail here. + */ +describe("GeminiCliProvider capabilities", () => { + it("does not expose the removed (inert) thinkingBudget selector", () => { + const draft = makePendingGeminiCliProvider(decodeSettings({ enabled: true })); + + const builtIn = draft.models.find((model) => !model.isCustom); + if (!builtIn) { + assert.fail("expected a built-in gemini model"); + } + + const descriptors = builtIn.capabilities?.optionDescriptors ?? []; + assert.ok( + !descriptors.some((descriptor) => descriptor.id === "thinkingBudget"), + "thinkingBudget was inert; keep it removed until wired to the Gemini CLI", + ); + }); +}); diff --git a/apps/server/src/provider/Layers/GeminiCliProvider.ts b/apps/server/src/provider/Layers/GeminiCliProvider.ts index 38b1409d996d..79b19ea85bc4 100644 --- a/apps/server/src/provider/Layers/GeminiCliProvider.ts +++ b/apps/server/src/provider/Layers/GeminiCliProvider.ts @@ -26,7 +26,6 @@ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import { createModelCapabilities } from "@t3tools/shared/model"; import { - buildSelectOptionDescriptor, buildServerProvider, DEFAULT_TIMEOUT_MS, detailFromResult, @@ -44,23 +43,17 @@ const GEMINI_PRESENTATION = { } as const; /** - * Capabilities for known Gemini models. Includes a `thinkingBudget` selector - * (fork-only feature) — kept in this layer because the probe / adapter both - * need it. + * Capabilities for known Gemini models. + * + * A `thinkingBudget` selector used to live here, but it was inert: the chosen + * value was never read by the adapter and never reached the Gemini CLI (which + * exposes no per-invocation thinking flag), so it rendered a control that did + * nothing. It has been removed rather than ship a misleading trait. Reinstate + * it only together with real wiring (e.g. a per-turn settings.json + * `thinkingConfig` override) verified against an actual Gemini CLI. */ -const THINKING_BUDGET_DESCRIPTOR = buildSelectOptionDescriptor({ - id: "thinkingBudget", - label: "Thinking Budget", - options: [ - { value: "auto", label: "Auto", isDefault: true }, - { value: "low", label: "Low" }, - { value: "medium", label: "Medium" }, - { value: "high", label: "High" }, - ], -}); - const DEFAULT_GEMINI_MODEL_CAPABILITIES: ModelCapabilities = createModelCapabilities({ - optionDescriptors: [THINKING_BUDGET_DESCRIPTOR], + optionDescriptors: [], }); const BUILT_IN_MODELS: ReadonlyArray = [