| ... | ... | @@ -48,50 +48,42 @@ const CLAUDE_PRESENTATION = { |
| 48 | 48 | displayName: "Claude", |
| 49 | 49 | showInteractionModeToggle: true, |
| 50 | 50 | } as const; |
| 51 | const MINIMUM_CLAUDE_FABLE_5_VERSION = "2.1.169"; |
| 51 | 52 | const MINIMUM_CLAUDE_OPUS_4_8_VERSION = "2.1.154"; |
| 52 | 53 | const MINIMUM_CLAUDE_OPUS_4_7_VERSION = "2.1.111"; |
| 53 | 54 | |
| 54 | | const CLAUDE_EFFORT_OPTIONS = { |
| 55 | | opus48: [ |
| 56 | | { value: "low", label: "Low" }, |
| 57 | | { value: "medium", label: "Medium" }, |
| 58 | | { value: "high", label: "High", isDefault: true }, |
| 59 | | { value: "xhigh", label: "Extra High" }, |
| 60 | | { value: "max", label: "Max" }, |
| 61 | | { value: "ultracode", label: "Ultracode" }, |
| 62 | | { value: "ultrathink", label: "Ultrathink" }, |
| 63 | | ], |
| 64 | | opus47: [ |
| 65 | | { value: "low", label: "Low" }, |
| 66 | | { value: "medium", label: "Medium" }, |
| 67 | | { value: "high", label: "High" }, |
| 68 | | { value: "xhigh", label: "Extra High", isDefault: true }, |
| 69 | | { value: "max", label: "Max" }, |
| 70 | | { value: "ultrathink", label: "Ultrathink" }, |
| 71 | | ], |
| 72 | | opus46: [ |
| 73 | | { value: "low", label: "Low" }, |
| 74 | | { value: "medium", label: "Medium" }, |
| 75 | | { value: "high", label: "High", isDefault: true }, |
| 76 | | { value: "max", label: "Max" }, |
| 77 | | { value: "ultrathink", label: "Ultrathink" }, |
| 78 | | ], |
| 79 | | sonnet46: [ |
| 80 | | { value: "low", label: "Low" }, |
| 81 | | { value: "medium", label: "Medium" }, |
| 82 | | { value: "high", label: "High", isDefault: true }, |
| 83 | | { value: "max", label: "Max" }, |
| 84 | | { value: "ultrathink", label: "Ultrathink" }, |
| 85 | | ], |
| 86 | | opus45: [ |
| 87 | | { value: "low", label: "Low" }, |
| 88 | | { value: "medium", label: "Medium" }, |
| 89 | | { value: "high", label: "High", isDefault: true }, |
| 90 | | { value: "max", label: "Max" }, |
| 91 | | ], |
| 92 | | } as const; |
| 93 | | |
| 94 | 55 | const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 56 | { |
| 57 | slug: "claude-fable-5", |
| 58 | name: "Claude Fable 5", |
| 59 | isCustom: false, |
| 60 | capabilities: createModelCapabilities({ |
| 61 | optionDescriptors: [ |
| 62 | buildSelectOptionDescriptor({ |
| 63 | id: "effort", |
| 64 | label: "Reasoning", |
| 65 | options: [ |
| 66 | { value: "low", label: "Low" }, |
| 67 | { value: "medium", label: "Medium" }, |
| 68 | { value: "high", label: "High", isDefault: true }, |
| 69 | { value: "xhigh", label: "Extra High" }, |
| 70 | { value: "max", label: "Max" }, |
| 71 | { value: "ultracode", label: "Ultracode" }, |
| 72 | { value: "ultrathink", label: "Ultrathink" }, |
| 73 | ], |
| 74 | promptInjectedValues: ["ultrathink"], |
| 75 | }), |
| 76 | buildSelectOptionDescriptor({ |
| 77 | id: "contextWindow", |
| 78 | label: "Context Window", |
| 79 | options: [ |
| 80 | { value: "200k", label: "200k", isDefault: true }, |
| 81 | { value: "1m", label: "1M" }, |
| 82 | ], |
| 83 | }), |
| 84 | ], |
| 85 | }), |
| 86 | }, |
| 95 | 87 | { |
| 96 | 88 | slug: "claude-opus-4-8", |
| 97 | 89 | name: "Claude Opus 4.8", |
| ... | ... | @@ -101,9 +93,21 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 101 | 93 | buildSelectOptionDescriptor({ |
| 102 | 94 | id: "effort", |
| 103 | 95 | label: "Reasoning", |
| 104 | | options: CLAUDE_EFFORT_OPTIONS.opus48, |
| 96 | options: [ |
| 97 | { value: "low", label: "Low" }, |
| 98 | { value: "medium", label: "Medium" }, |
| 99 | { value: "high", label: "High", isDefault: true }, |
| 100 | { value: "xhigh", label: "Extra High" }, |
| 101 | { value: "max", label: "Max" }, |
| 102 | { value: "ultracode", label: "Ultracode" }, |
| 103 | { value: "ultrathink", label: "Ultrathink" }, |
| 104 | ], |
| 105 | 105 | promptInjectedValues: ["ultrathink"], |
| 106 | 106 | }), |
| 107 | buildBooleanOptionDescriptor({ |
| 108 | id: "fastMode", |
| 109 | label: "Fast Mode", |
| 110 | }), |
| 107 | 111 | buildSelectOptionDescriptor({ |
| 108 | 112 | id: "contextWindow", |
| 109 | 113 | label: "Context Window", |
| ... | ... | @@ -124,9 +128,20 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 124 | 128 | buildSelectOptionDescriptor({ |
| 125 | 129 | id: "effort", |
| 126 | 130 | label: "Reasoning", |
| 127 | | options: CLAUDE_EFFORT_OPTIONS.opus47, |
| 131 | options: [ |
| 132 | { value: "low", label: "Low" }, |
| 133 | { value: "medium", label: "Medium" }, |
| 134 | { value: "high", label: "High" }, |
| 135 | { value: "xhigh", label: "Extra High", isDefault: true }, |
| 136 | { value: "max", label: "Max" }, |
| 137 | { value: "ultrathink", label: "Ultrathink" }, |
| 138 | ], |
| 128 | 139 | promptInjectedValues: ["ultrathink"], |
| 129 | 140 | }), |
| 141 | buildBooleanOptionDescriptor({ |
| 142 | id: "fastMode", |
| 143 | label: "Fast Mode", |
| 144 | }), |
| 130 | 145 | buildSelectOptionDescriptor({ |
| 131 | 146 | id: "contextWindow", |
| 132 | 147 | label: "Context Window", |
| ... | ... | @@ -147,7 +162,13 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 147 | 162 | buildSelectOptionDescriptor({ |
| 148 | 163 | id: "effort", |
| 149 | 164 | label: "Reasoning", |
| 150 | | options: CLAUDE_EFFORT_OPTIONS.opus46, |
| 165 | options: [ |
| 166 | { value: "low", label: "Low" }, |
| 167 | { value: "medium", label: "Medium" }, |
| 168 | { value: "high", label: "High", isDefault: true }, |
| 169 | { value: "max", label: "Max" }, |
| 170 | { value: "ultrathink", label: "Ultrathink" }, |
| 171 | ], |
| 151 | 172 | promptInjectedValues: ["ultrathink"], |
| 152 | 173 | }), |
| 153 | 174 | buildBooleanOptionDescriptor({ |
| ... | ... | @@ -174,7 +195,12 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 174 | 195 | buildSelectOptionDescriptor({ |
| 175 | 196 | id: "effort", |
| 176 | 197 | label: "Reasoning", |
| 177 | | options: CLAUDE_EFFORT_OPTIONS.opus45, |
| 198 | options: [ |
| 199 | { value: "low", label: "Low" }, |
| 200 | { value: "medium", label: "Medium" }, |
| 201 | { value: "high", label: "High", isDefault: true }, |
| 202 | { value: "max", label: "Max" }, |
| 203 | ], |
| 178 | 204 | }), |
| 179 | 205 | buildBooleanOptionDescriptor({ |
| 180 | 206 | id: "fastMode", |
| ... | ... | @@ -192,7 +218,13 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 192 | 218 | buildSelectOptionDescriptor({ |
| 193 | 219 | id: "effort", |
| 194 | 220 | label: "Reasoning", |
| 195 | | options: CLAUDE_EFFORT_OPTIONS.sonnet46, |
| 221 | options: [ |
| 222 | { value: "low", label: "Low" }, |
| 223 | { value: "medium", label: "Medium" }, |
| 224 | { value: "high", label: "High", isDefault: true }, |
| 225 | { value: "max", label: "Max" }, |
| 226 | { value: "ultrathink", label: "Ultrathink" }, |
| 227 | ], |
| 196 | 228 | promptInjectedValues: ["ultrathink"], |
| 197 | 229 | }), |
| 198 | 230 | buildSelectOptionDescriptor({ |
| ... | ... | @@ -221,6 +253,10 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ |
| 221 | 253 | }, |
| 222 | 254 | ]; |
| 223 | 255 | |
| 256 | function supportsClaudeFable5(version: string | null | undefined): boolean { |
| 257 | return version ? compareSemverVersions(version, MINIMUM_CLAUDE_FABLE_5_VERSION) >= 0 : false; |
| 258 | } |
| 259 | |
| 224 | 260 | function supportsClaudeOpus48(version: string | null | undefined): boolean { |
| 225 | 261 | return version ? compareSemverVersions(version, MINIMUM_CLAUDE_OPUS_4_8_VERSION) >= 0 : false; |
| 226 | 262 | } |
| ... | ... | @@ -233,6 +269,9 @@ function getBuiltInClaudeModelsForVersion( |
| 233 | 269 | version: string | null | undefined, |
| 234 | 270 | ): ReadonlyArray<ServerProviderModel> { |
| 235 | 271 | return BUILT_IN_MODELS.filter((model) => { |
| 272 | if (model.slug === "claude-fable-5") { |
| 273 | return supportsClaudeFable5(version); |
| 274 | } |
| 236 | 275 | if (model.slug === "claude-opus-4-8") { |
| 237 | 276 | return supportsClaudeOpus48(version); |
| 238 | 277 | } |
| ... | ... | @@ -243,6 +282,11 @@ function getBuiltInClaudeModelsForVersion( |
| 243 | 282 | }); |
| 244 | 283 | } |
| 245 | 284 | |
| 285 | function formatClaudeFable5UpgradeMessage(version: string | null): string { |
| 286 | const versionLabel = version ? `v${version}` : "the installed version"; |
| 287 | return `Claude Code ${versionLabel} is too old for Claude Fable 5. Upgrade to v${MINIMUM_CLAUDE_FABLE_5_VERSION} or newer to access it.`; |
| 288 | } |
| 289 | |
| 246 | 290 | function formatClaudeOpus48UpgradeMessage(version: string | null): string { |
| 247 | 291 | const versionLabel = version ? `v${version}` : "the installed version"; |
| 248 | 292 | return `Claude Code ${versionLabel} is too old for Claude Opus 4.8. Upgrade to v${MINIMUM_CLAUDE_OPUS_4_8_VERSION} or newer to access it.`; |
| ... | ... | @@ -294,7 +338,7 @@ export function normalizeClaudeCliEffort( |
| 294 | 338 | if (effort === "ultracode") { |
| 295 | 339 | return "xhigh"; |
| 296 | 340 | } |
| 297 | | if (effort === "xhigh" && model !== "claude-opus-4-8") { |
| 341 | if (effort === "xhigh" && model !== "claude-fable-5" && model !== "claude-opus-4-8") { |
| 298 | 342 | return "max"; |
| 299 | 343 | } |
| 300 | 344 | if (effort === "max" && model === "claude-sonnet-4-6") { |
| ... | ... | @@ -688,11 +732,13 @@ export const checkClaudeProviderStatus = Effect.fn("checkClaudeProviderStatus")( |
| 688 | 732 | claudeSettings.customModels, |
| 689 | 733 | DEFAULT_CLAUDE_MODEL_CAPABILITIES, |
| 690 | 734 | ); |
| 691 | | const versionUpgradeMessage = supportsClaudeOpus48(parsedVersion) |
| 735 | const versionUpgradeMessage = supportsClaudeFable5(parsedVersion) |
| 692 | 736 | ? undefined |
| 693 | | : supportsClaudeOpus47(parsedVersion) |
| 694 | | ? formatClaudeOpus48UpgradeMessage(parsedVersion) |
| 695 | | : formatClaudeOpus47UpgradeMessage(parsedVersion); |
| 737 | : supportsClaudeOpus48(parsedVersion) |
| 738 | ? formatClaudeFable5UpgradeMessage(parsedVersion) |
| 739 | : supportsClaudeOpus47(parsedVersion) |
| 740 | ? formatClaudeOpus48UpgradeMessage(parsedVersion) |
| 741 | : formatClaudeOpus47UpgradeMessage(parsedVersion); |
| 696 | 742 | |
| 697 | 743 | const capabilities = resolveCapabilities |
| 698 | 744 | ? yield* resolveCapabilities(claudeSettings).pipe(Effect.orElseSucceed(() => undefined)) |