|
1 | 1 | import { z } from "zod" |
2 | 2 |
|
3 | | -import { reasoningEffortsSchema, verbosityLevelsSchema, modelInfoSchema } from "./model.js" |
| 3 | +import { modelInfoSchema, reasoningEffortWithMinimalSchema, verbosityLevelsSchema } from "./model.js" |
4 | 4 | import { codebaseIndexProviderSchema } from "./codebase-index.js" |
5 | | - |
6 | | -// Bedrock Claude Sonnet 4 model ID that supports 1M context |
7 | | -export const BEDROCK_CLAUDE_SONNET_4_MODEL_ID = "anthropic.claude-sonnet-4-20250514-v1:0" |
8 | | - |
9 | | -// Extended schema that includes "minimal" for GPT-5 models |
10 | | -export const extendedReasoningEffortsSchema = z.union([reasoningEffortsSchema, z.literal("minimal")]) |
11 | | - |
12 | | -export type ReasoningEffortWithMinimal = z.infer<typeof extendedReasoningEffortsSchema> |
| 5 | +import { |
| 6 | + anthropicModels, |
| 7 | + bedrockModels, |
| 8 | + cerebrasModels, |
| 9 | + chutesModels, |
| 10 | + claudeCodeModels, |
| 11 | + deepSeekModels, |
| 12 | + doubaoModels, |
| 13 | + featherlessModels, |
| 14 | + fireworksModels, |
| 15 | + geminiModels, |
| 16 | + groqModels, |
| 17 | + ioIntelligenceModels, |
| 18 | + mistralModels, |
| 19 | + moonshotModels, |
| 20 | + openAiNativeModels, |
| 21 | + rooModels, |
| 22 | + sambaNovaModels, |
| 23 | + vertexModels, |
| 24 | + vscodeLlmModels, |
| 25 | + xaiModels, |
| 26 | + internationalZAiModels, |
| 27 | +} from "./providers/index.js" |
13 | 28 |
|
14 | 29 | /** |
15 | 30 | * ProviderName |
@@ -87,7 +102,7 @@ const baseProviderSettingsSchema = z.object({ |
87 | 102 |
|
88 | 103 | // Model reasoning. |
89 | 104 | enableReasoningEffort: z.boolean().optional(), |
90 | | - reasoningEffort: extendedReasoningEffortsSchema.optional(), |
| 105 | + reasoningEffort: reasoningEffortWithMinimalSchema.optional(), |
91 | 106 | modelMaxTokens: z.number().optional(), |
92 | 107 | modelMaxThinkingTokens: z.number().optional(), |
93 | 108 |
|
@@ -407,21 +422,126 @@ export const getModelId = (settings: ProviderSettings): string | undefined => { |
407 | 422 | return modelIdKey ? (settings[modelIdKey] as string) : undefined |
408 | 423 | } |
409 | 424 |
|
410 | | -// Providers that use Anthropic-style API protocol |
| 425 | +// Providers that use Anthropic-style API protocol. |
411 | 426 | export const ANTHROPIC_STYLE_PROVIDERS: ProviderName[] = ["anthropic", "claude-code", "bedrock"] |
412 | 427 |
|
413 | | -// Helper function to determine API protocol for a provider and model |
414 | 428 | export const getApiProtocol = (provider: ProviderName | undefined, modelId?: string): "anthropic" | "openai" => { |
415 | | - // First check if the provider is an Anthropic-style provider |
416 | 429 | if (provider && ANTHROPIC_STYLE_PROVIDERS.includes(provider)) { |
417 | 430 | return "anthropic" |
418 | 431 | } |
419 | 432 |
|
420 | | - // For vertex provider, check if the model ID contains "claude" (case-insensitive) |
421 | 433 | if (provider && provider === "vertex" && modelId && modelId.toLowerCase().includes("claude")) { |
422 | 434 | return "anthropic" |
423 | 435 | } |
424 | 436 |
|
425 | | - // Default to OpenAI protocol |
426 | 437 | return "openai" |
427 | 438 | } |
| 439 | + |
| 440 | +export const MODELS_BY_PROVIDER: Record< |
| 441 | + Exclude<ProviderName, "fake-ai" | "human-relay" | "gemini-cli" | "lmstudio" | "openai" | "ollama">, |
| 442 | + { id: ProviderName; label: string; models: string[] } |
| 443 | +> = { |
| 444 | + anthropic: { |
| 445 | + id: "anthropic", |
| 446 | + label: "Anthropic", |
| 447 | + models: Object.keys(anthropicModels), |
| 448 | + }, |
| 449 | + bedrock: { |
| 450 | + id: "bedrock", |
| 451 | + label: "Amazon Bedrock", |
| 452 | + models: Object.keys(bedrockModels), |
| 453 | + }, |
| 454 | + cerebras: { |
| 455 | + id: "cerebras", |
| 456 | + label: "Cerebras", |
| 457 | + models: Object.keys(cerebrasModels), |
| 458 | + }, |
| 459 | + chutes: { |
| 460 | + id: "chutes", |
| 461 | + label: "Chutes AI", |
| 462 | + models: Object.keys(chutesModels), |
| 463 | + }, |
| 464 | + "claude-code": { id: "claude-code", label: "Claude Code", models: Object.keys(claudeCodeModels) }, |
| 465 | + deepseek: { |
| 466 | + id: "deepseek", |
| 467 | + label: "DeepSeek", |
| 468 | + models: Object.keys(deepSeekModels), |
| 469 | + }, |
| 470 | + doubao: { id: "doubao", label: "Doubao", models: Object.keys(doubaoModels) }, |
| 471 | + featherless: { |
| 472 | + id: "featherless", |
| 473 | + label: "Featherless", |
| 474 | + models: Object.keys(featherlessModels), |
| 475 | + }, |
| 476 | + fireworks: { |
| 477 | + id: "fireworks", |
| 478 | + label: "Fireworks", |
| 479 | + models: Object.keys(fireworksModels), |
| 480 | + }, |
| 481 | + gemini: { |
| 482 | + id: "gemini", |
| 483 | + label: "Google Gemini", |
| 484 | + models: Object.keys(geminiModels), |
| 485 | + }, |
| 486 | + groq: { id: "groq", label: "Groq", models: Object.keys(groqModels) }, |
| 487 | + "io-intelligence": { |
| 488 | + id: "io-intelligence", |
| 489 | + label: "IO Intelligence", |
| 490 | + models: Object.keys(ioIntelligenceModels), |
| 491 | + }, |
| 492 | + mistral: { |
| 493 | + id: "mistral", |
| 494 | + label: "Mistral", |
| 495 | + models: Object.keys(mistralModels), |
| 496 | + }, |
| 497 | + moonshot: { |
| 498 | + id: "moonshot", |
| 499 | + label: "Moonshot", |
| 500 | + models: Object.keys(moonshotModels), |
| 501 | + }, |
| 502 | + "openai-native": { |
| 503 | + id: "openai-native", |
| 504 | + label: "OpenAI", |
| 505 | + models: Object.keys(openAiNativeModels), |
| 506 | + }, |
| 507 | + roo: { id: "roo", label: "Roo", models: Object.keys(rooModels) }, |
| 508 | + sambanova: { |
| 509 | + id: "sambanova", |
| 510 | + label: "SambaNova", |
| 511 | + models: Object.keys(sambaNovaModels), |
| 512 | + }, |
| 513 | + vertex: { |
| 514 | + id: "vertex", |
| 515 | + label: "GCP Vertex AI", |
| 516 | + models: Object.keys(vertexModels), |
| 517 | + }, |
| 518 | + "vscode-lm": { |
| 519 | + id: "vscode-lm", |
| 520 | + label: "VS Code LM API", |
| 521 | + models: Object.keys(vscodeLlmModels), |
| 522 | + }, |
| 523 | + xai: { id: "xai", label: "xAI (Grok)", models: Object.keys(xaiModels) }, |
| 524 | + zai: { id: "zai", label: "Zai", models: Object.keys(internationalZAiModels) }, |
| 525 | + |
| 526 | + // Dynamic providers; models pulled from the respective APIs. |
| 527 | + glama: { id: "glama", label: "Glama", models: [] }, |
| 528 | + huggingface: { id: "huggingface", label: "Hugging Face", models: [] }, |
| 529 | + litellm: { id: "litellm", label: "LiteLLM", models: [] }, |
| 530 | + openrouter: { id: "openrouter", label: "OpenRouter", models: [] }, |
| 531 | + requesty: { id: "requesty", label: "Requesty", models: [] }, |
| 532 | + unbound: { id: "unbound", label: "Unbound", models: [] }, |
| 533 | +} |
| 534 | + |
| 535 | +export const dynamicProviders = [ |
| 536 | + "glama", |
| 537 | + "huggingface", |
| 538 | + "litellm", |
| 539 | + "openrouter", |
| 540 | + "requesty", |
| 541 | + "unbound", |
| 542 | +] as const satisfies readonly ProviderName[] |
| 543 | + |
| 544 | +export type DynamicProvider = (typeof dynamicProviders)[number] |
| 545 | + |
| 546 | +export const isDynamicProvider = (key: string): key is DynamicProvider => |
| 547 | + dynamicProviders.includes(key as DynamicProvider) |
0 commit comments