Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0f18204
feat(claude): Ultracode is a toggle that works with any effort
Bil0000 Oct 29, 2026
9bbf5c7
fix(mcp): old Ultracode effort requests and explicit off still work
Bil0000 Oct 29, 2026
7ac00b9
fix(mcp): reject bad Ultracode values and keep it on old parents
Bil0000 Oct 29, 2026
9a82e08
feat(web): show a Workflow icon for Ultracode in the composer
Bil0000 Oct 29, 2026
e8bb4eb
fix(claude): custom models with an Ultracode effort get the toggle too
Bil0000 Oct 29, 2026
d242369
test: cut takeover tests for #27034 to the Ultracode toggle behaviour
juliusmarminge Oct 30, 2026
ebaa59f
refactor: tighten the legacy Ultracode effort helper
juliusmarminge Oct 30, 2026
db134ef
test(shared): old Ultracode effort dispatches as xhigh with the toggle
juliusmarminge Oct 30, 2026
e8931da
fix(client-runtime): old Ultracode threads keep their effort label
juliusmarminge Oct 30, 2026
8100802
fix(claude): keep the Ultracode toggle to the bundled catalog
juliusmarminge Oct 30, 2026
286fc3a
Merge remote-tracking branch 'origin/main' into pr-27034
juliusmarminge Oct 30, 2026
fb66fca
Revert "fix(claude): keep the Ultracode toggle to the bundled catalog"
juliusmarminge Oct 30, 2026
10640b1
fix(claude): Ultracode off overrides an Ultracode launch setting
Bil0000 Oct 30, 2026
ca16eda
feat(web,mobile): workflow hover cards show the model and effort
Bil0000 Nov 1, 2026
f1d436a
Merge remote-tracking branch 'origin/main' into t3/ultracode-dynamic-…
Bil0000 Nov 1, 2026
87131ce
feat(web): Ultracode sits beside Standard and Fast in the model picker
Bil0000 Nov 1, 2026
01b9c2c
chore(claude): recommend Claude Code 2.1.284 for Ultracode at any effort
Bil0000 Nov 2, 2026
abdb8b6
Merge remote-tracking branch 'origin/main' into t3/ultracode-dynamic-…
Bil0000 Nov 2, 2026
2557f20
Merge remote-tracking branch 'origin/main' into pr-27034
juliusmarminge Nov 3, 2026
193ad89
fix(claude): custom models get the Ultracode toggle everywhere
juliusmarminge Nov 3, 2026
383166a
fix(claude): custom models that defaulted to Ultracode keep it on
juliusmarminge Nov 3, 2026
56c2192
fix(claude): custom models keep Extra High when Ultracode becomes a t…
juliusmarminge Nov 3, 2026
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
24 changes: 24 additions & 0 deletions apps/server/src/claudeModelOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@ describe("compileClaudeModelSelection", () => {
});
});

it("runs Ultracode at the chosen effort and reads the old Ultracode effort as xhigh", () => {
expect(
compileClaudeModelSelection(
selection("claude-opus-5-5", [
{ id: "effort", value: "high" },
{ id: "ultracode", value: true },
]),
),
).toMatchObject({ effort: "high", settings: { ultracode: true } });
expect(
compileClaudeModelSelection(
selection("claude-opus-5-5", [{ id: "effort", value: "ultracode" }]),
),
).toMatchObject({ effort: "xhigh", settings: { ultracode: true } });
const legacyTurnedOff = compileClaudeModelSelection(
selection("claude-opus-5-5", [
{ id: "effort", value: "ultracode" },
{ id: "ultracode", value: false },
]),
);
expect(legacyTurnedOff.effort).toBe("xhigh");
expect(legacyTurnedOff.settings).not.toHaveProperty("ultracode");
});

it("uses the model default SDK effort alongside prompt-injected effort", () => {
expect(
compileClaudeModelSelection(
Expand Down
10 changes: 7 additions & 3 deletions apps/server/src/claudeModelOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
import {
BUNDLED_CLAUDE_MODEL_CATALOG,
getClaudeCatalogModelCapabilities,
isClaudeCatalogUltracodeEffort,
normalizeClaudeCatalogEffort,
resolveClaudeCatalogApiModelId,
resolveClaudeCatalogEffort,
Expand All @@ -29,7 +28,10 @@ export function compileClaudeModelSelection(
catalog: ClaudeModelCatalog = BUNDLED_CLAUDE_MODEL_CATALOG,
): CompiledClaudeModelSelection {
const capabilities = getClaudeCatalogModelCapabilities(catalog, selection.model);
const descriptors = getProviderOptionDescriptors({ caps: capabilities });
const descriptors = getProviderOptionDescriptors({
caps: capabilities,
selections: selection.options,
});
const supportsBoolean = (id: string) =>
descriptors.some((descriptor) => descriptor.type === "boolean" && descriptor.id === id);
const rawEffort = getModelSelectionStringOptionValue(selection, "effort");
Expand All @@ -44,7 +46,9 @@ export function compileClaudeModelSelection(
const settings = {
...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}),
...(typeof fastMode === "boolean" ? { fastMode } : {}),
...(isClaudeCatalogUltracodeEffort(resolvedEffort) ? { ultracode: true } : {}),
...(descriptors.find((descriptor) => descriptor.id === "ultracode")?.currentValue === true
? { ultracode: true }
: {}),
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
Resolved
};
const apiModelId = resolveClaudeCatalogApiModelId(catalog, selection);
const promptEffort = resolvePromptInjectedEffort(capabilities, rawEffort) ?? undefined;
Expand Down
45 changes: 39 additions & 6 deletions apps/server/src/mcp/OrchestratorMcpService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2526,6 +2526,18 @@ describe("OrchestratorMcpService provider resolution", () => {
target: { providerInstanceId: peerId, options: { reasoningEffort: "max" } },
expected: { instanceId: peerId, model: inherited.model, options: override },
},
{
name: "old Ultracode effort level",
target: { model: "ultracode-model", options: { effort: "ultracode" } },
expected: {
instanceId: codexInstanceId,
model: "ultracode-model",
options: [
{ id: "effort", value: "xhigh" },
{ id: "ultracode", value: true },
],
},
},
] as const;
for (const testCase of cases) {
const commands: Array<unknown> = [];
Expand Down Expand Up @@ -2567,12 +2579,33 @@ describe("OrchestratorMcpService provider resolution", () => {
driver,
model: inherited.model,
}),
models: [inherited.model, "other-model"].map((model) => ({
slug: model,
name: model,
isCustom: false,
capabilities: null,
})),
models: [
...[inherited.model, "other-model"].map((model) => ({
slug: model,
name: model,
isCustom: false,
capabilities: null,
})),
{
slug: "ultracode-model",
name: "ultracode-model",
isCustom: false,
capabilities: {
optionDescriptors: [
{
id: "effort",
label: "Reasoning",
type: "select",
options: [
{ id: "high", label: "High" },
{ id: "xhigh", label: "Extra High" },
],
},
{ id: "ultracode", label: "Ultracode", type: "boolean" },
],
},
},
],
},
providerSnapshot({ instanceId: peerId, driver, model: inherited.model }),
]),
Expand Down
12 changes: 7 additions & 5 deletions apps/server/src/mcp/OrchestratorMcpService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import {
ThreadId,
isOrchestrationV2WorkActive,
} from "@t3tools/contracts";
import { getProviderOptionCurrentValue } from "@t3tools/shared/model";
import { getProviderOptionCurrentValue, withLegacyUltracodeEffort } from "@t3tools/shared/model";
import { runRanAfter } from "@t3tools/shared/orchestrationV2ThreadError";
import { formatThreadLink } from "@t3tools/shared/threadLinks";
import {
Expand Down Expand Up @@ -1354,10 +1354,10 @@ const make = Effect.gen(function* () {
);
}

const requestedOptions = input.target?.options;
const descriptors = provider.models.find((candidate) => candidate.slug === model)?.capabilities
?.optionDescriptors;
const requestedOptions = withLegacyUltracodeEffort(descriptors, input.target?.options);
if (requestedOptions !== undefined) {
const descriptors = provider.models.find((candidate) => candidate.slug === model)
?.capabilities?.optionDescriptors;
const invalid = invalidOptionSelections(requestedOptions, descriptors);
if (invalid.length > 0) {
return yield* failure(
Expand All @@ -1369,7 +1369,9 @@ const make = Effect.gen(function* () {

const inheritsOptions =
instanceId === inheritedSelection.instanceId && model === inheritedSelection.model;
let options = inheritsOptions ? inheritedSelection.options : undefined;
let options = inheritsOptions
? withLegacyUltracodeEffort(descriptors, inheritedSelection.options)
: undefined;
if (requestedOptions !== undefined) {
const selections = new Map(
(requestedOptions.length === 0 ? [] : (options ?? [])).map((selection) => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4408,7 +4408,8 @@ describe("ClaudeAdapterV2 background wake turns", () => {
turn(3, {
...normal,
options: [
{ id: "effort", value: "ultracode" },
{ id: "effort", value: "high" },
{ id: "ultracode", value: true },
{ id: "fastMode", value: true },
],
}),
Expand All @@ -4418,7 +4419,7 @@ describe("ClaudeAdapterV2 background wake turns", () => {
yield* settle;
assert.deepEqual(harness.liveSelectionChanges, [
{ model: "claude-opus-5-5" },
{ effortLevel: "xhigh", fastMode: true, ultracode: true },
{ effortLevel: "high", fastMode: true, ultracode: true },
{ model: "claude-sonnet-4-6" },
{ effortLevel: "high", fastMode: null, ultracode: null },
]);
Expand Down
28 changes: 23 additions & 5 deletions apps/server/src/provider/ClaudeModelCatalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,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 ?? {},
});
Expand All @@ -59,6 +60,27 @@ function tryResolveClaudeModelCatalog(
};
}

// The manifest keeps Ultracode as an effort level because released servers read it from main.
function withUltracodeToggle(capabilities: ModelCapabilities | null): ModelCapabilities | null {
const descriptors = capabilities?.optionDescriptors ?? [];
const effortIndex = descriptors.findIndex(
(descriptor) =>
descriptor.id === "effort" &&
descriptor.type === "select" &&
descriptor.options.some((option) => option.id === "ultracode"),
);
const effort = descriptors[effortIndex];
if (effort?.type !== "select") return capabilities;
return {
optionDescriptors: descriptors.toSpliced(
effortIndex,
1,
{ ...effort, options: effort.options.filter((option) => option.id !== "ultracode") },
{ id: "ultracode", label: "Ultracode", type: "boolean" },
),
};
}

/** Resolve the fallback on each read so its new-model badges can expire. */
export function resolveClaudeModelCatalog(
catalog: ModelCatalog.ProviderCatalog | undefined,
Expand Down Expand Up @@ -235,10 +257,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,
Expand Down
3 changes: 1 addition & 2 deletions apps/server/src/textGeneration/ClaudeTextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
BUNDLED_CLAUDE_MODEL_CATALOG,
type ClaudeModelCatalog,
getClaudeCatalogModelCapabilities,
isClaudeCatalogUltracodeEffort,
normalizeClaudeCatalogEffort,
resolveClaudeCatalogApiModelId,
resolveClaudeCatalogEffort,
Expand Down Expand Up @@ -159,7 +158,7 @@ export const makeClaudeTextGeneration = Effect.fn("makeClaudeTextGeneration")(fu
resolvedEffort,
resolvedModelSelection.model,
);
const ultracode = isClaudeCatalogUltracodeEffort(resolvedEffort);
const ultracode = findDescriptor("ultracode")?.currentValue === true;
const thinkingDescriptor = findDescriptor("thinking");
const fastModeDescriptor = findDescriptor("fastMode");
// Only a chosen value; otherwise Claude Code's own default applies, as in chat turns.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/chat/EffortGlyph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const BASELINE_INSET = 2;

type SelectDescriptor = Extract<ProviderOptionDescriptor, { type: "select" }>;

// Ultracode changes the workflow, not only intensity, so it keeps its name like Ultrathink.
// Older servers offer Ultracode as a level. It changes the workflow, so it keeps its name.
// Max is named too, so the full scale stops short of it.
const NAMED_LEVELS = new Set(["ultracode", "max"]);
const OFF_LEVELS = new Set(["off", "none"]);
Expand Down
6 changes: 5 additions & 1 deletion apps/web/src/components/chat/TraitsPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
normalizeModelSlug,
} from "@t3tools/shared/model";
import { memo, type ReactNode, useRef } from "react";
import { GaugeIcon, ZapIcon } from "lucide-react";
import { GaugeIcon, WorkflowIcon, ZapIcon } from "lucide-react";
import {
Menu,
MenuGroup,
Expand Down Expand Up @@ -586,6 +586,7 @@ export const TraitsPicker = memo(function TraitsPicker({
const {
label: triggerLabel,
speedLabel,
ultracode,
otherLabels,
} = buildTraitsTriggerDisplay({
provider,
Expand Down Expand Up @@ -688,6 +689,9 @@ export const TraitsPicker = memo(function TraitsPicker({
{speedLabel === "Fast" || speedLabel === "Ultrafast" ? (
<FastBolt ultra={speedLabel === "Ultrafast"} />
) : null}
{ultracode ? (
<WorkflowIcon aria-hidden="true" data-composer-control-icon className="size-3" />
) : null}
{otherLabels.length > 0 ? (
<span
aria-hidden="true"
Expand Down
20 changes: 16 additions & 4 deletions packages/client-runtime/src/modelTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,28 @@ export function buildTraitsTriggerDisplay(input: {
label: string;
/** "Fast" or "Ultrafast" when a speed option is on. */
speedLabel: string | null;
/** Labels other than reasoning and speed, such as context window or thinking. */
ultracode: boolean;
/** Labels other than reasoning, speed, and Ultracode, such as context window or thinking. */
otherLabels: ReadonlyArray<string>;
} {
let fastModeFallbackLabel: string | null = null;
let speedLabel: string | null = null;
let reasoningLabelIndex = -1;
let ultracodeLabelIndex = -1;
const labels: Array<string> = [];
for (const descriptor of input.descriptors) {
if (descriptor.id === "fastMode" && descriptor.type === "boolean") {
speedLabel = descriptor.currentValue === true ? "Fast" : null;
fastModeFallbackLabel = speedLabel ?? "Normal";
continue;
}
if (descriptor.id === "ultracode" && descriptor.type === "boolean") {
if (descriptor.currentValue === true) {
ultracodeLabelIndex = labels.length;
labels.push(descriptor.label);
}
continue;
}
if (
input.provider === "codex" &&
descriptor.id === "serviceTier" &&
Expand Down Expand Up @@ -173,9 +182,12 @@ export function buildTraitsTriggerDisplay(input: {
}
}

const otherLabels = labels.filter((_, index) => index !== reasoningLabelIndex);
const ultracode = ultracodeLabelIndex >= 0;
const otherLabels = labels.filter(
(_, index) => index !== reasoningLabelIndex && index !== ultracodeLabelIndex,
);
if (labels.length === 0 && fastModeFallbackLabel !== null) {
return { label: fastModeFallbackLabel, speedLabel, otherLabels };
return { label: fastModeFallbackLabel, speedLabel, ultracode, otherLabels };
}
if (speedLabel) {
if (reasoningLabelIndex >= 0) {
Expand All @@ -184,5 +196,5 @@ export function buildTraitsTriggerDisplay(input: {
labels.push(speedLabel);
}
}
return { label: labels.join(" · "), speedLabel, otherLabels };
return { label: labels.join(" · "), speedLabel, ultracode, otherLabels };
}
35 changes: 35 additions & 0 deletions packages/client-runtime/src/state/threadExecution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
type OrchestrationV2RunStatus,
} from "@t3tools/contracts";
import * as DateTime from "effect/DateTime";
import { createModelCapabilities, createModelSelection } from "@t3tools/shared/model";
import { usageLimitBlockedRun } from "@t3tools/shared/orchestrationV2ThreadError";
import { describe, expect, it } from "vite-plus/test";

Expand All @@ -25,6 +26,7 @@ import {
deriveRunlessWorkStartedAt,
deriveThreadActivityRun,
deriveThreadRuntime,
formatModelSelectionEffort,
threadRuntimeHasInterruptibleRun,
} from "./threadExecution.ts";

Expand Down Expand Up @@ -393,3 +395,36 @@ describe("provider-reported model selection", () => {
).toBeNull();
});
});

describe("formatModelSelectionEffort", () => {
it("labels an old Ultracode effort by the effort it runs at", () => {
const models = [
{
slug: "claude-opus-5-5",
name: "Claude Opus 5.5",
isCustom: false,
capabilities: createModelCapabilities({
optionDescriptors: [
{
id: "effort",
label: "Reasoning",
type: "select",
options: [
{ id: "high", label: "High", isDefault: true },
{ id: "xhigh", label: "Extra High" },
],
},
{ id: "ultracode", label: "Ultracode", type: "boolean" },
],
}),
},
];
const selection = createModelSelection(
ProviderInstanceId.make("claudeAgent"),
"claude-opus-5-5",
[{ id: "effort", value: "ultracode" }],
);

expect(formatModelSelectionEffort(selection, models)).toBe("Extra High");
});
});
Loading
Loading