fix(claude): default Fable and Mythos 5.2 to medium effort

Claude Code 2.1.321's model catalog declares default_effort "medium" for
both models, so Paseo's inherited "high" would start sessions above Claude
Code's own default and cost more.

Gate Mythos 5.2 on 2.1.321 as well: older Claude Code can advertise the
mythos alias without Paseo knowing its capabilities there.

The Fast control now applies beyond Opus, so its description no longer
names a model family.

Co-authored-by: gudcks <84506708+gudcks@users.noreply.github.com>
(cherry picked from commit e4a2e87348)
This commit is contained in:
Mohamed Boudra
2026-11-10 01:53:49 +01:00
parent 23e954099b
commit 56ba3d35b0
4 changed files with 37 additions and 8 deletions
@@ -1364,7 +1364,8 @@ describe("ClaudeAgentSession features", () => {
test.each([
["supported model", "claude-opus-4-8", { type: "disabled" }, undefined],
["Mythos 5.1", "claude-mythos-5-1", { type: "adaptive", display: "summarized" }, "high"],
["Fable 5.2", "claude-fable-5-2", { type: "adaptive", display: "summarized" }, "high"],
["Fable 5.2", "claude-fable-5-2", { type: "adaptive", display: "summarized" }, "medium"],
["Mythos 5.2", "claude-mythos-5-2", { type: "adaptive", display: "summarized" }, "medium"],
["Haiku 5.5", "claude-haiku-5-5", { type: "disabled" }, undefined],
["unsupported model", "claude-fable-5", { type: "adaptive", display: "summarized" }, "high"],
["custom model", "openrouter/anthropic/claude-opus-4-8", undefined, undefined],
@@ -5,7 +5,7 @@ export const CLAUDE_FAST_MODE_FEATURE: Omit<AgentFeatureToggle, "value"> = {
type: "toggle",
id: "fast_mode",
label: "Fast",
description: "Lower latency Opus responses at higher token cost",
description: "Lower latency responses at higher token cost",
tooltip: "Toggle fast mode",
icon: "zap",
};
@@ -63,6 +63,8 @@ export const CLAUDE_MODEL_MANIFEST = [
label: "Mythos 5.2",
requiresDiscovery: true,
description: "Mythos 5.2 · Requires verified access",
minimumClaudeCodeVersion: "2.1.321",
defaultThinkingOptionId: "medium",
contextWindowMaxTokens: 1_000_000,
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
supportsFastMode: true,
@@ -80,6 +82,7 @@ export const CLAUDE_MODEL_MANIFEST = [
label: "Fable 5.2",
description: "Fable 5.2 · Most powerful model",
minimumClaudeCodeVersion: "2.1.321",
defaultThinkingOptionId: "medium",
contextWindowMaxTokens: 1_000_000,
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
supportsFastMode: true,
@@ -248,8 +248,8 @@ describe("getClaudeModels", () => {
["claude-sonnet-5-20260101", true, "high"],
["claude-fable-5", false, "high"],
["claude-fable-5-1", false, "high"],
["claude-fable-5-2", false, "high"],
["claude-mythos-5-2", false, "high"],
["claude-fable-5-2", false, "medium"],
["claude-mythos-5-2", false, "medium"],
["claude-haiku-5-5", true, "medium"],
["claude-haiku-5-5-20261007", true, "medium"],
["claude-haiku-4-5", false, undefined],
@@ -808,14 +808,14 @@ describe("Claude Fable 5.1 catalog", () => {
});
describe("Claude Fable 5.2 catalog", () => {
it("offers one 1M model with high default effort, always-on thinking, and fast mode", () => {
it("offers one 1M model with medium default effort, always-on thinking, and fast mode", () => {
const models = getClaudeModels().filter((model) => model.id.startsWith("claude-fable-5-2"));
expect(models).toHaveLength(1);
expect(models[0]).toMatchObject({
id: "claude-fable-5-2",
label: "Fable 5.2",
contextWindowMaxTokens: 1_000_000,
defaultThinkingOptionId: "high",
defaultThinkingOptionId: "medium",
});
expect(models[0].thinkingOptions?.map((option) => option.id)).toEqual([
"low",
@@ -1026,14 +1026,39 @@ describe("Claude Mythos 5.1 catalog", () => {
});
describe("Claude Mythos 5.2 catalog", () => {
it("offers one 1M model with high default effort, always-on thinking, and fast mode", () => {
it("stays hidden on Claude Code older than 2.1.321 even when advertised", async () => {
const configDir = await createClaudeConfigDir({});
const client = new ClaudeAgentClient({
logger: createTestLogger(),
resolveVersion: async () => "2.1.320",
runtimeSettings: { env: { CLAUDE_CONFIG_DIR: configDir } },
discoverModels: async () => [
{
value: "mythos",
resolvedModel: "claude-mythos-5-2",
displayName: "Mythos",
description: "",
},
],
});
const { models } = await client.fetchCatalog({
scope: "workspace",
cwd: configDir,
force: false,
});
expect(models.some((model) => model.id === "claude-mythos-5-2")).toBe(false);
});
it("offers one 1M model with medium default effort, always-on thinking, and fast mode", () => {
const models = getClaudeModels().filter((model) => model.id.startsWith("claude-mythos-5-2"));
expect(models).toHaveLength(1);
expect(models[0]).toMatchObject({
id: "claude-mythos-5-2",
label: "Mythos 5.2",
contextWindowMaxTokens: 1_000_000,
defaultThinkingOptionId: "high",
defaultThinkingOptionId: "medium",
});
expect(models[0].thinkingOptions?.map((option) => option.id)).toEqual([
"low",