From 4d8e70e4f540cbffe992fdaae9c4fab5fe0906c8 Mon Sep 17 00:00:00 2001 From: David Goldstein Date: Sat, 17 Oct 2026 15:30:02 -0400 Subject: [PATCH 1/5] feat(claude): Ultracode is its own toggle at any reasoning level Claude Code 2.1.284 turned Ultracode into a session toggle that no longer forces xhigh effort. T3 still offered it as a Reasoning choice mapped to xhigh, so Max + Ultracode or High + Ultracode could not be selected. The remote model manifest is read by every installed release, and older releases only understand Ultracode as an effort choice, so the manifest keeps that shape. The Claude catalog now lifts the manifest's "ultracode" effort choice into a boolean `ultracode` option, and chat and text generation send `settings.ultracode` from that toggle alongside whichever effort is selected. The web traits picker shows the option's description and names Ultracode in the trigger label only while it is on. --- apps/server/src/claudeModelOptions.test.ts | 19 ++++++++ apps/server/src/claudeModelOptions.ts | 5 ++- .../Adapters/ClaudeAdapterV2.test.ts | 5 ++- .../src/provider/ClaudeModelCatalog.test.ts | 44 +++++++++++++++++++ .../server/src/provider/ClaudeModelCatalog.ts | 43 +++++++++++++++--- .../textGeneration/ClaudeTextGeneration.ts | 5 ++- apps/web/src/components/chat/TraitsPicker.tsx | 5 +++ .../client-runtime/src/modelTraits.test.ts | 34 ++++++++++++++ packages/client-runtime/src/modelTraits.ts | 5 +++ 9 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 packages/client-runtime/src/modelTraits.test.ts diff --git a/apps/server/src/claudeModelOptions.test.ts b/apps/server/src/claudeModelOptions.test.ts index 4a34d98a796b..1581fc6711b5 100644 --- a/apps/server/src/claudeModelOptions.test.ts +++ b/apps/server/src/claudeModelOptions.test.ts @@ -48,4 +48,23 @@ describe("compileClaudeModelSelection", () => { compileClaudeModelSelection(selection("claude-pool-model-not-in-catalog", [])).effort, ).toBeUndefined(); }); + it("compiles Ultracode independently of the chosen effort", () => { + expect( + compileClaudeModelSelection( + selection("claude-opus-5-5", [ + { id: "effort", value: "max" }, + { id: "ultracode", value: true }, + ]), + ), + ).toMatchObject({ effort: "max", settings: { fastMode: false, ultracode: true } }); + expect( + compileClaudeModelSelection(selection("claude-opus-5-5", [{ id: "effort", value: "max" }])) + .settings, + ).toEqual({ fastMode: false }); + expect( + compileClaudeModelSelection( + selection("claude-sonnet-4-6", [{ id: "ultracode", value: true }]), + ).settings, + ).not.toHaveProperty("ultracode"); + }); }); diff --git a/apps/server/src/claudeModelOptions.ts b/apps/server/src/claudeModelOptions.ts index 06841da9bdb2..6680d098ff31 100644 --- a/apps/server/src/claudeModelOptions.ts +++ b/apps/server/src/claudeModelOptions.ts @@ -9,7 +9,6 @@ import { import { BUNDLED_CLAUDE_MODEL_CATALOG, getClaudeCatalogModelCapabilities, - isClaudeCatalogUltracodeEffort, normalizeClaudeCatalogEffort, resolveClaudeCatalogApiModelId, resolveClaudeCatalogEffort, @@ -41,10 +40,12 @@ export function compileClaudeModelSelection( const thinking = supportsBoolean("thinking") ? getModelSelectionBooleanOptionValue(selection, "thinking") : undefined; + const ultracode = + supportsBoolean("ultracode") && getModelSelectionBooleanOptionValue(selection, "ultracode"); const settings = { ...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}), ...(typeof fastMode === "boolean" ? { fastMode } : {}), - ...(isClaudeCatalogUltracodeEffort(resolvedEffort) ? { ultracode: true } : {}), + ...(ultracode ? { ultracode: true } : {}), }; const apiModelId = resolveClaudeCatalogApiModelId(catalog, selection); const promptEffort = resolvePromptInjectedEffort(capabilities, rawEffort) ?? undefined; diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts index 9dc129c7aa0d..498ee1723abb 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts @@ -3410,7 +3410,8 @@ describe("ClaudeAdapterV2 background wake turns", () => { turn(3, { ...normal, options: [ - { id: "effort", value: "ultracode" }, + { id: "effort", value: "max" }, + { id: "ultracode", value: true }, { id: "fastMode", value: true }, ], }), @@ -3420,7 +3421,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { yield* settle; assert.deepEqual(harness.liveSelectionChanges, [ { model: "claude-opus-5-5" }, - { effortLevel: "xhigh", fastMode: true, ultracode: true }, + { effortLevel: "max", fastMode: true, ultracode: true }, { model: "claude-sonnet-4-6" }, { effortLevel: "high", fastMode: null, ultracode: null }, ]); diff --git a/apps/server/src/provider/ClaudeModelCatalog.test.ts b/apps/server/src/provider/ClaudeModelCatalog.test.ts index 2092429f6d55..4243da17757d 100644 --- a/apps/server/src/provider/ClaudeModelCatalog.test.ts +++ b/apps/server/src/provider/ClaudeModelCatalog.test.ts @@ -4,6 +4,7 @@ import { ProviderDriverKind, ProviderInstanceId } from "@t3tools/contracts"; import { resolveProviderCatalog, type ModelManifestData } from "./ModelManifest.ts"; import { formatClaudeVersionUpgradeMessage, + getClaudeCatalogModelCapabilities, normalizeClaudeCatalogEffort, resolveClaudeCatalogApiModelId, resolveClaudeCatalogContextWindowTokens, @@ -222,4 +223,47 @@ describe("Claude model catalog", () => { ["claude-synthetic-next", "claude-custom-tuned"], ); }); + it("lifts the manifest's Ultracode effort choice into its own toggle", () => { + const effort = { + id: "effort", + label: "Reasoning", + type: "select" as const, + options: [ + { id: "extreme", label: "Extreme", isDefault: true }, + { id: "ultracode", label: "Ultracode" }, + ], + }; + const contextWindow = { + id: "contextWindow", + label: "Context Window", + type: "select" as const, + options: [{ id: "large", label: "Large", isDefault: true }], + }; + const base = manifest(); + const catalog = catalogFromManifest({ + ...base, + providers: { + claudeAgent: { + ...base.providers!.claudeAgent!, + profiles: { + synthetic: { capabilities: { optionDescriptors: [effort, contextWindow] } }, + }, + }, + }, + }); + + assert.deepStrictEqual(getClaudeCatalogModelCapabilities(catalog, "synthetic"), { + optionDescriptors: [ + { ...effort, options: [effort.options[0]!] }, + { + id: "ultracode", + label: "Ultracode", + description: "Multi-agent workflow orchestration at any reasoning level", + type: "boolean", + }, + contextWindow, + ], + }); + assert.strictEqual(resolveClaudeCatalogEffort(catalog, "synthetic", "ultracode"), "extreme"); + }); }); diff --git a/apps/server/src/provider/ClaudeModelCatalog.ts b/apps/server/src/provider/ClaudeModelCatalog.ts index db409077756a..38b66f115eeb 100644 --- a/apps/server/src/provider/ClaudeModelCatalog.ts +++ b/apps/server/src/provider/ClaudeModelCatalog.ts @@ -26,6 +26,42 @@ import { BUNDLED_MODEL_MANIFEST, resolveProviderCatalog } from "./ModelManifest. const CLAUDE = ProviderDriverKind.make("claudeAgent"); const EMPTY_CAPABILITIES: ModelCapabilities = { optionDescriptors: [] }; +const ULTRACODE = "ultracode"; + +/** + * Claude Code 2.1.284 made Ultracode a session toggle that works at any effort + * level. Every installed release reads the remote manifest, and releases before + * this one only understand Ultracode as an effort choice mapped to xhigh, so the + * manifest keeps that shape and the choice is lifted into its own option here. + */ +function withUltracodeToggle(capabilities: T): T { + const descriptors = capabilities?.optionDescriptors; + if (!descriptors || descriptors.some((descriptor) => descriptor.id === ULTRACODE)) { + return capabilities; + } + const effortIndex = descriptors.findIndex( + (descriptor) => descriptor.id === "effort" && descriptor.type === "select", + ); + const effort = descriptors[effortIndex]; + if (effort?.type !== "select") return capabilities; + const choice = effort.options.find((option) => option.id === ULTRACODE); + if (!choice) return capabilities; + + return { + ...capabilities, + optionDescriptors: [ + ...descriptors.slice(0, effortIndex), + { ...effort, options: effort.options.filter((option) => option !== choice) }, + { + id: ULTRACODE, + label: choice.label, + description: "Multi-agent workflow orchestration at any reasoning level", + type: "boolean", + }, + ...descriptors.slice(effortIndex + 1), + ], + }; +} export interface ClaudeCatalogModel { readonly model: ServerProviderModel; @@ -47,8 +83,9 @@ function tryResolveClaudeModelCatalog( const profile = decodeClaudeProfileAdapter(entry.profileAdapter ?? {}); const adapter = decodeClaudeModelAdapter(entry.adapter ?? {}); if (Option.isNone(profile) || Option.isNone(adapter)) return null; + const model = ModelCatalog.catalogServerModel(resolved, entry); models.push({ - model: ModelCatalog.catalogServerModel(resolved, entry), + model: { ...model, capabilities: withUltracodeToggle(model.capabilities) }, runtime: profile.value.claudeCode ?? {}, compatibility: adapter.value.claudeCode ?? {}, }); @@ -237,10 +274,6 @@ export function normalizeClaudeCatalogEffort( return effortMap[effort] ?? undefined; } -export function isClaudeCatalogUltracodeEffort(effort: string | null | undefined): boolean { - return effort === "ultracode"; -} - function resolveClaudeCatalogContextWindow( catalog: ClaudeModelCatalog, modelSelection: ModelSelection | undefined, diff --git a/apps/server/src/textGeneration/ClaudeTextGeneration.ts b/apps/server/src/textGeneration/ClaudeTextGeneration.ts index 8fa9ccb1c809..b5e06d3eb0c4 100644 --- a/apps/server/src/textGeneration/ClaudeTextGeneration.ts +++ b/apps/server/src/textGeneration/ClaudeTextGeneration.ts @@ -22,7 +22,6 @@ import { BUNDLED_CLAUDE_MODEL_CATALOG, type ClaudeModelCatalog, getClaudeCatalogModelCapabilities, - isClaudeCatalogUltracodeEffort, normalizeClaudeCatalogEffort, resolveClaudeCatalogApiModelId, resolveClaudeCatalogEffort, @@ -159,9 +158,9 @@ export const makeClaudeTextGeneration = Effect.fn("makeClaudeTextGeneration")(fu resolvedEffort, resolvedModelSelection.model, ); - const ultracode = isClaudeCatalogUltracodeEffort(resolvedEffort); const thinkingDescriptor = findDescriptor("thinking"); const fastModeDescriptor = findDescriptor("fastMode"); + const ultracodeDescriptor = findDescriptor("ultracode"); // Only a chosen value; otherwise Claude Code's own default applies, as in chat turns. const thinking = thinkingDescriptor?.type === "boolean" @@ -169,6 +168,8 @@ export const makeClaudeTextGeneration = Effect.fn("makeClaudeTextGeneration")(fu : undefined; const fastMode = fastModeDescriptor?.type === "boolean" ? fastModeDescriptor.currentValue : undefined; + const ultracode = + ultracodeDescriptor?.type === "boolean" ? ultracodeDescriptor.currentValue : undefined; const settings = { disableAllHooks: true, ...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}), diff --git a/apps/web/src/components/chat/TraitsPicker.tsx b/apps/web/src/components/chat/TraitsPicker.tsx index 8d46f4399f76..77a772ea21c6 100644 --- a/apps/web/src/components/chat/TraitsPicker.tsx +++ b/apps/web/src/components/chat/TraitsPicker.tsx @@ -482,6 +482,11 @@ export const TraitsMenuContent = memo(function TraitsMenuContentImpl({
{descriptor.label}
+ {descriptor.description ? ( +
+ {descriptor.description} +
+ ) : null} { diff --git a/packages/client-runtime/src/modelTraits.test.ts b/packages/client-runtime/src/modelTraits.test.ts new file mode 100644 index 000000000000..959021d5be3c --- /dev/null +++ b/packages/client-runtime/src/modelTraits.test.ts @@ -0,0 +1,34 @@ +import { ProviderDriverKind, type ProviderOptionDescriptor } from "@t3tools/contracts"; +import { describe, expect, it } from "vite-plus/test"; + +import { buildTraitsTriggerDisplay } from "./modelTraits.ts"; + +const EFFORT: ProviderOptionDescriptor = { + id: "effort", + label: "Reasoning", + type: "select", + options: [ + { id: "high", label: "High" }, + { id: "max", label: "Max" }, + ], + currentValue: "max", +}; + +function display(ultracode: boolean) { + return buildTraitsTriggerDisplay({ + provider: ProviderDriverKind.make("claudeAgent"), + descriptors: [ + EFFORT, + { id: "ultracode", label: "Ultracode", type: "boolean", currentValue: ultracode }, + ], + primarySelectDescriptorId: "effort", + ultrathinkPromptControlled: false, + }); +} + +describe("buildTraitsTriggerDisplay", () => { + it("names Ultracode only while it is on", () => { + expect(display(false)).toEqual({ label: "Max" }); + expect(display(true)).toEqual({ label: "Max · Ultracode" }); + }); +}); diff --git a/packages/client-runtime/src/modelTraits.ts b/packages/client-runtime/src/modelTraits.ts index 198d09e3a13c..b14e6c7a8d8c 100644 --- a/packages/client-runtime/src/modelTraits.ts +++ b/packages/client-runtime/src/modelTraits.ts @@ -121,6 +121,11 @@ export function buildTraitsTriggerDisplay(input: { fastModeFallbackLabel = speedLabel ?? "Normal"; continue; } + // A mode, not a setting: name it only while it is on, like Claude Code's own model pill. + if (descriptor.id === "ultracode" && descriptor.type === "boolean") { + if (descriptor.currentValue === true) labels.push(descriptor.label); + continue; + } if ( input.provider === "codex" && descriptor.id === "serviceTier" && From b248092877ad41adbb52526c5edd6c7136fd36cc Mon Sep 17 00:00:00 2001 From: David Goldstein Date: Sat, 24 Oct 2026 22:30:51 -0400 Subject: [PATCH 2/5] fix(claude): hide the Ultracode toggle on Claude Code before 2.1.284 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before 2.1.284, Claude Code switches to xhigh whenever Ultracode is on, so the toggle would show Max · Ultracode while running at xhigh. Opus 5.5 is offered from 2.1.280, so this range is reachable. --- .../src/provider/ClaudeModelCatalog.test.ts | 13 ++++++++++ .../server/src/provider/ClaudeModelCatalog.ts | 26 ++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/server/src/provider/ClaudeModelCatalog.test.ts b/apps/server/src/provider/ClaudeModelCatalog.test.ts index 4243da17757d..4a1290106443 100644 --- a/apps/server/src/provider/ClaudeModelCatalog.test.ts +++ b/apps/server/src/provider/ClaudeModelCatalog.test.ts @@ -248,6 +248,12 @@ describe("Claude model catalog", () => { profiles: { synthetic: { capabilities: { optionDescriptors: [effort, contextWindow] } }, }, + models: [ + { + ...base.providers!.claudeAgent!.models[0]!, + adapter: { claudeCode: { minVersion: "2.1.280" } }, + }, + ], }, }, }); @@ -265,5 +271,12 @@ describe("Claude model catalog", () => { ], }); assert.strictEqual(resolveClaudeCatalogEffort(catalog, "synthetic", "ultracode"), "extreme"); + + const optionIdsFor = (version: string) => + resolveClaudeModelsForVersion(catalog, version)[0]?.capabilities?.optionDescriptors?.map( + (descriptor) => descriptor.id, + ); + assert.deepStrictEqual(optionIdsFor("2.1.283"), ["effort", "contextWindow"]); + assert.deepStrictEqual(optionIdsFor("2.1.284"), ["effort", "ultracode", "contextWindow"]); }); }); diff --git a/apps/server/src/provider/ClaudeModelCatalog.ts b/apps/server/src/provider/ClaudeModelCatalog.ts index 38b66f115eeb..a23b85cabf53 100644 --- a/apps/server/src/provider/ClaudeModelCatalog.ts +++ b/apps/server/src/provider/ClaudeModelCatalog.ts @@ -27,13 +27,11 @@ import { BUNDLED_MODEL_MANIFEST, resolveProviderCatalog } from "./ModelManifest. const CLAUDE = ProviderDriverKind.make("claudeAgent"); const EMPTY_CAPABILITIES: ModelCapabilities = { optionDescriptors: [] }; const ULTRACODE = "ultracode"; +// Before this, Claude Code switches to xhigh whenever Ultracode is on. +const ULTRACODE_ANY_EFFORT_MIN_VERSION = "2.1.284"; -/** - * Claude Code 2.1.284 made Ultracode a session toggle that works at any effort - * level. Every installed release reads the remote manifest, and releases before - * this one only understand Ultracode as an effort choice mapped to xhigh, so the - * manifest keeps that shape and the choice is lifted into its own option here. - */ +// Older T3 releases read the same remote manifest and only understand Ultracode as an +// effort choice, so the manifest keeps that shape and the choice is lifted out here. function withUltracodeToggle(capabilities: T): T { const descriptors = capabilities?.optionDescriptors; if (!descriptors || descriptors.some((descriptor) => descriptor.id === ULTRACODE)) { @@ -197,9 +195,23 @@ export function resolveClaudeModelsForVersion( catalog: ClaudeModelCatalog, version: string | null | undefined, ): ReadonlyArray { + const ultracodeAtAnyEffort = + !!version && compareSemverVersions(version, ULTRACODE_ANY_EFFORT_MIN_VERSION) >= 0; return catalog.models .filter((entry) => isVersionSupported(entry.compatibility, version)) - .map((entry) => entry.model); + .map(({ model }) => + ultracodeAtAnyEffort || !model.capabilities?.optionDescriptors + ? model + : { + ...model, + capabilities: { + ...model.capabilities, + optionDescriptors: model.capabilities.optionDescriptors.filter( + (descriptor) => descriptor.id !== ULTRACODE, + ), + }, + }, + ); } export function resolveClaudeUpdateRequiredModels( From 636f5d2fda384660f90a9bf83ae7c82d577e1134 Mon Sep 17 00:00:00 2001 From: David Goldstein Date: Sun, 25 Oct 2026 14:18:31 -0400 Subject: [PATCH 3/5] fix(claude): saved Ultracode effort keeps running at xhigh with Ultracode on Threads saved while Ultracode was an effort choice fell back to the model's default effort with Ultracode off. Read effort "ultracode" as xhigh plus the Ultracode toggle wherever descriptors are built, so the server and the picker agree, unless the selection sets Ultracode itself. --- apps/server/src/claudeModelOptions.test.ts | 23 +++++++++++++++++ apps/server/src/claudeModelOptions.ts | 7 ++++-- packages/shared/src/model.test.ts | 28 +++++++++++++++++++++ packages/shared/src/model.ts | 29 ++++++++++++++++++++-- 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/apps/server/src/claudeModelOptions.test.ts b/apps/server/src/claudeModelOptions.test.ts index 1581fc6711b5..db463a4c8b35 100644 --- a/apps/server/src/claudeModelOptions.test.ts +++ b/apps/server/src/claudeModelOptions.test.ts @@ -67,4 +67,27 @@ describe("compileClaudeModelSelection", () => { ).settings, ).not.toHaveProperty("ultracode"); }); + it("keeps a saved Ultracode effort at xhigh with Ultracode on", () => { + expect( + compileClaudeModelSelection( + selection("claude-opus-5-5", [{ id: "effort", value: "ultracode" }]), + ), + ).toMatchObject({ effort: "xhigh", settings: { fastMode: false, ultracode: true } }); + expect( + compileClaudeModelSelection( + selection("claude-opus-5-5", [ + { id: "effort", value: "ultracode" }, + { id: "ultracode", value: false }, + ]), + ), + ).toMatchObject({ effort: "xhigh", settings: { fastMode: false } }); + expect( + compileClaudeModelSelection( + selection("claude-opus-5-5", [ + { id: "effort", value: "ultracode" }, + { id: "ultracode", value: false }, + ]), + ).settings, + ).not.toHaveProperty("ultracode"); + }); }); diff --git a/apps/server/src/claudeModelOptions.ts b/apps/server/src/claudeModelOptions.ts index 6680d098ff31..99492a441504 100644 --- a/apps/server/src/claudeModelOptions.ts +++ b/apps/server/src/claudeModelOptions.ts @@ -40,8 +40,11 @@ export function compileClaudeModelSelection( const thinking = supportsBoolean("thinking") ? getModelSelectionBooleanOptionValue(selection, "thinking") : undefined; - const ultracode = - supportsBoolean("ultracode") && getModelSelectionBooleanOptionValue(selection, "ultracode"); + const ultracodeDescriptor = getProviderOptionDescriptors({ + caps: capabilities, + selections: selection.options, + }).find((descriptor) => descriptor.id === "ultracode"); + const ultracode = ultracodeDescriptor?.type === "boolean" && ultracodeDescriptor.currentValue; const settings = { ...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}), ...(typeof fastMode === "boolean" ? { fastMode } : {}), diff --git a/packages/shared/src/model.test.ts b/packages/shared/src/model.test.ts index fdeac6c8ac91..5a124dbd09aa 100644 --- a/packages/shared/src/model.test.ts +++ b/packages/shared/src/model.test.ts @@ -77,6 +77,34 @@ describe("descriptor helpers", () => { ).toEqual([{ id: "fastMode", value: true }]); }); + it("reads a saved Ultracode effort as xhigh with the Ultracode toggle on", () => { + const effort = { + id: "effort", + label: "Reasoning", + type: "select" as const, + options: [ + { id: "high", label: "High", isDefault: true }, + { id: "xhigh", label: "Extra High" }, + ], + }; + const ultracode = { id: "ultracode", label: "Ultracode", type: "boolean" as const }; + const current = (caps: ModelCapabilities) => + getProviderOptionDescriptors({ + caps, + selections: [{ id: "effort", value: "ultracode" }], + }).map((descriptor) => [descriptor.id, descriptor.currentValue]); + + expect(current({ optionDescriptors: [effort, ultracode] })).toEqual([ + ["effort", "xhigh"], + ["ultracode", true], + ]); + const legacyEffort = { + ...effort, + options: [...effort.options, { id: "ultracode", label: "Ultracode" }], + }; + expect(current({ optionDescriptors: [legacyEffort] })).toEqual([["effort", "ultracode"]]); + }); + it("compares complete model selections independent of option ordering", () => { const left = createModelSelection(ProviderInstanceId.make("codex"), "gpt-5.4", [ { id: "reasoningEffort", value: "high" }, diff --git a/packages/shared/src/model.ts b/packages/shared/src/model.ts index 51cc1430321d..e8ca87329357 100644 --- a/packages/shared/src/model.ts +++ b/packages/shared/src/model.ts @@ -196,12 +196,37 @@ function withDescriptorCurrentValue( }; } +// Saved selections from when Ultracode was a Claude effort choice that ran at xhigh. +function withLegacyUltracodeEffort( + descriptors: ReadonlyArray, + selections: ReadonlyArray | null | undefined, +): ReadonlyArray | null | undefined { + if (getRawSelectionValueById(selections, "effort") !== "ultracode") return selections; + const effort = descriptors.find((descriptor) => descriptor.id === "effort"); + if ( + effort?.type !== "select" || + effort.options.some((option) => option.id === "ultracode") || + !effort.options.some((option) => option.id === "xhigh") + ) { + return selections; + } + const hasToggle = descriptors.some( + (descriptor) => descriptor.id === "ultracode" && descriptor.type === "boolean", + ); + const next = (selections ?? []).map((selection) => + selection.id === "effort" ? { id: "effort", value: "xhigh" } : selection, + ); + return hasToggle && getRawSelectionValueById(selections, "ultracode") === undefined + ? [...next, { id: "ultracode", value: true }] + : next; +} + export function getProviderOptionDescriptors(input: { caps: ModelCapabilities; selections?: ReadonlyArray | null | undefined; }): ReadonlyArray { - const { caps, selections } = input; - const baseDescriptors = (caps.optionDescriptors ?? []).map(cloneDescriptor); + const baseDescriptors = (input.caps.optionDescriptors ?? []).map(cloneDescriptor); + const selections = withLegacyUltracodeEffort(baseDescriptors, input.selections); return baseDescriptors.map((descriptor) => withDescriptorCurrentValue( From d8c48b58df3e9935acda3b00838331beac161f15 Mon Sep 17 00:00:00 2001 From: David Goldstein Date: Sun, 25 Oct 2026 14:27:57 -0400 Subject: [PATCH 4/5] fix(claude): Claude Code before 2.1.284 keeps Ultracode as a reasoning choice Hiding the toggle there took Ultracode away from those users. They get the manifest's original effort choice back, which the server already compiles to xhigh with Ultracode on. --- .../src/provider/ClaudeModelCatalog.test.ts | 4 +++- .../server/src/provider/ClaudeModelCatalog.ts | 22 ++++++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/server/src/provider/ClaudeModelCatalog.test.ts b/apps/server/src/provider/ClaudeModelCatalog.test.ts index 4a1290106443..a89e2d71c8b8 100644 --- a/apps/server/src/provider/ClaudeModelCatalog.test.ts +++ b/apps/server/src/provider/ClaudeModelCatalog.test.ts @@ -276,7 +276,9 @@ describe("Claude model catalog", () => { resolveClaudeModelsForVersion(catalog, version)[0]?.capabilities?.optionDescriptors?.map( (descriptor) => descriptor.id, ); - assert.deepStrictEqual(optionIdsFor("2.1.283"), ["effort", "contextWindow"]); + assert.deepStrictEqual(resolveClaudeModelsForVersion(catalog, "2.1.283")[0]?.capabilities, { + optionDescriptors: [effort, contextWindow], + }); assert.deepStrictEqual(optionIdsFor("2.1.284"), ["effort", "ultracode", "contextWindow"]); }); }); diff --git a/apps/server/src/provider/ClaudeModelCatalog.ts b/apps/server/src/provider/ClaudeModelCatalog.ts index a23b85cabf53..82787da7bbd4 100644 --- a/apps/server/src/provider/ClaudeModelCatalog.ts +++ b/apps/server/src/provider/ClaudeModelCatalog.ts @@ -27,7 +27,8 @@ import { BUNDLED_MODEL_MANIFEST, resolveProviderCatalog } from "./ModelManifest. const CLAUDE = ProviderDriverKind.make("claudeAgent"); const EMPTY_CAPABILITIES: ModelCapabilities = { optionDescriptors: [] }; const ULTRACODE = "ultracode"; -// Before this, Claude Code switches to xhigh whenever Ultracode is on. +// Before this, Claude Code switches to xhigh whenever Ultracode is on, so older versions +// keep the manifest's Ultracode effort choice instead of the toggle. const ULTRACODE_ANY_EFFORT_MIN_VERSION = "2.1.284"; // Older T3 releases read the same remote manifest and only understand Ultracode as an @@ -63,6 +64,7 @@ function withUltracodeToggle(capabilities: T export interface ClaudeCatalogModel { readonly model: ServerProviderModel; + readonly manifestCapabilities?: ServerProviderModel["capabilities"]; readonly runtime: ClaudeCodeProfile; readonly compatibility: ClaudeCodeCompatibility; } @@ -82,8 +84,10 @@ function tryResolveClaudeModelCatalog( const adapter = decodeClaudeModelAdapter(entry.adapter ?? {}); if (Option.isNone(profile) || Option.isNone(adapter)) return null; const model = ModelCatalog.catalogServerModel(resolved, entry); + const capabilities = withUltracodeToggle(model.capabilities); models.push({ - model: { ...model, capabilities: withUltracodeToggle(model.capabilities) }, + model: { ...model, capabilities }, + ...(capabilities === model.capabilities ? {} : { manifestCapabilities: model.capabilities }), runtime: profile.value.claudeCode ?? {}, compatibility: adapter.value.claudeCode ?? {}, }); @@ -199,18 +203,10 @@ export function resolveClaudeModelsForVersion( !!version && compareSemverVersions(version, ULTRACODE_ANY_EFFORT_MIN_VERSION) >= 0; return catalog.models .filter((entry) => isVersionSupported(entry.compatibility, version)) - .map(({ model }) => - ultracodeAtAnyEffort || !model.capabilities?.optionDescriptors + .map(({ model, manifestCapabilities }) => + ultracodeAtAnyEffort || manifestCapabilities === undefined ? model - : { - ...model, - capabilities: { - ...model.capabilities, - optionDescriptors: model.capabilities.optionDescriptors.filter( - (descriptor) => descriptor.id !== ULTRACODE, - ), - }, - }, + : { ...model, capabilities: manifestCapabilities }, ); } From ba9d7b92851cc7280fa9e434518283e8cbadb371 Mon Sep 17 00:00:00 2001 From: David Goldstein Date: Sun, 25 Oct 2026 14:36:19 -0400 Subject: [PATCH 5/5] fix(claude): Ultracode Off and saved Ultracode efforts reach Claude Code Web and mobile kept only the option ids a selection saved, so a saved effort "ultracode" dispatched as xhigh without Ultracode. An Off toggle also sent nothing, leaving Ultracode from the user's settings.json on. Models with the toggle now always send it, like Fast Mode. --- apps/server/src/claudeModelOptions.test.ts | 12 ++---------- apps/server/src/claudeModelOptions.ts | 8 ++++++-- packages/shared/src/model.test.ts | 13 +++++++++++++ packages/shared/src/model.ts | 6 +++++- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/apps/server/src/claudeModelOptions.test.ts b/apps/server/src/claudeModelOptions.test.ts index db463a4c8b35..afa4088aa000 100644 --- a/apps/server/src/claudeModelOptions.test.ts +++ b/apps/server/src/claudeModelOptions.test.ts @@ -60,7 +60,7 @@ describe("compileClaudeModelSelection", () => { expect( compileClaudeModelSelection(selection("claude-opus-5-5", [{ id: "effort", value: "max" }])) .settings, - ).toEqual({ fastMode: false }); + ).toEqual({ fastMode: false, ultracode: false }); expect( compileClaudeModelSelection( selection("claude-sonnet-4-6", [{ id: "ultracode", value: true }]), @@ -80,14 +80,6 @@ describe("compileClaudeModelSelection", () => { { id: "ultracode", value: false }, ]), ), - ).toMatchObject({ effort: "xhigh", settings: { fastMode: false } }); - expect( - compileClaudeModelSelection( - selection("claude-opus-5-5", [ - { id: "effort", value: "ultracode" }, - { id: "ultracode", value: false }, - ]), - ).settings, - ).not.toHaveProperty("ultracode"); + ).toMatchObject({ effort: "xhigh", settings: { fastMode: false, ultracode: false } }); }); }); diff --git a/apps/server/src/claudeModelOptions.ts b/apps/server/src/claudeModelOptions.ts index 99492a441504..fef9ff2b1d5d 100644 --- a/apps/server/src/claudeModelOptions.ts +++ b/apps/server/src/claudeModelOptions.ts @@ -44,11 +44,15 @@ export function compileClaudeModelSelection( caps: capabilities, selections: selection.options, }).find((descriptor) => descriptor.id === "ultracode"); - const ultracode = ultracodeDescriptor?.type === "boolean" && ultracodeDescriptor.currentValue; + // Explicit when supported, so an Off toggle overrides Ultracode set in the user's settings.json. + const ultracode = + ultracodeDescriptor?.type === "boolean" + ? (ultracodeDescriptor.currentValue ?? false) + : undefined; const settings = { ...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}), ...(typeof fastMode === "boolean" ? { fastMode } : {}), - ...(ultracode ? { ultracode: true } : {}), + ...(typeof ultracode === "boolean" ? { ultracode } : {}), }; const apiModelId = resolveClaudeCatalogApiModelId(catalog, selection); const promptEffort = resolvePromptInjectedEffort(capabilities, rawEffort) ?? undefined; diff --git a/packages/shared/src/model.test.ts b/packages/shared/src/model.test.ts index 5a124dbd09aa..fe329f622d2b 100644 --- a/packages/shared/src/model.test.ts +++ b/packages/shared/src/model.test.ts @@ -98,6 +98,19 @@ describe("descriptor helpers", () => { ["effort", "xhigh"], ["ultracode", true], ]); + const saved = [{ id: "effort", value: "ultracode" }]; + expect( + buildExplicitProviderOptionSelectionsFromDescriptors( + getProviderOptionDescriptors({ + caps: { optionDescriptors: [effort, ultracode] }, + selections: saved, + }), + saved, + ), + ).toEqual([ + { id: "effort", value: "xhigh" }, + { id: "ultracode", value: true }, + ]); const legacyEffort = { ...effort, options: [...effort.options, { id: "ultracode", label: "Ultracode" }], diff --git a/packages/shared/src/model.ts b/packages/shared/src/model.ts index e8ca87329357..94897aefebd9 100644 --- a/packages/shared/src/model.ts +++ b/packages/shared/src/model.ts @@ -337,7 +337,11 @@ export function buildExplicitProviderOptionSelectionsFromDescriptors( if (!selections || selections.length === 0) { return undefined; } - const explicitIds = new Set(selections.map((selection) => selection.id)); + const explicitIds = new Set( + (withLegacyUltracodeEffort(descriptors ?? [], selections) ?? []).map( + (selection) => selection.id, + ), + ); const normalized = buildProviderOptionSelectionsFromDescriptors(descriptors)?.filter( (selection) => explicitIds.has(selection.id), );