From 4ed3ffe8e01266fb244d92f7bebdc6c8e833acb9 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Wed, 28 Oct 2026 21:14:46 +0000 Subject: [PATCH 1/2] refactor(types): move provider-settings into providers Merge packages/types/src/provider-settings/*.ts into packages/types/src/providers/, appending each source file's code to the end of the same-named destination file and combining their imports. Files without a same-named counterpart (common, fake-ai, gemini-cli, litellm, openai-native, vscode-lm) move over unchanged. The providerDefinitionList registry from provider-settings/index.ts is appended to providers/index.ts, and all import sites now point at the new location. --- .../src/__tests__/provider-settings.test.ts | 2 +- packages/types/src/provider-settings.ts | 6 +- .../types/src/provider-settings/anthropic.ts | 22 ---- .../types/src/provider-settings/baseten.ts | 19 ---- .../types/src/provider-settings/bedrock.ts | 36 ------ .../types/src/provider-settings/deepseek.ts | 20 ---- .../types/src/provider-settings/fireworks.ts | 19 ---- .../types/src/provider-settings/friendli.ts | 19 ---- .../types/src/provider-settings/gemini.ts | 20 ---- packages/types/src/provider-settings/index.ts | 90 --------------- .../src/provider-settings/io-intelligence.ts | 17 --- .../types/src/provider-settings/kenari.ts | 17 --- .../types/src/provider-settings/kimi-code.ts | 23 ---- .../types/src/provider-settings/lm-studio.ts | 19 ---- packages/types/src/provider-settings/mimo.ts | 27 ----- .../types/src/provider-settings/minimax.ts | 22 ---- .../types/src/provider-settings/mistral.ts | 20 ---- .../types/src/provider-settings/moonshot.ts | 22 ---- .../types/src/provider-settings/nanogpt.ts | 24 ---- .../types/src/provider-settings/ollama.ts | 19 ---- .../src/provider-settings/openai-codex.ts | 21 ---- .../types/src/provider-settings/openai.ts | 104 ------------------ .../src/provider-settings/opencode-go.ts | 17 --- .../types/src/provider-settings/openrouter.ts | 19 ---- packages/types/src/provider-settings/poe.ts | 20 ---- .../types/src/provider-settings/qwen-code.ts | 19 ---- .../types/src/provider-settings/requesty.ts | 18 --- .../types/src/provider-settings/sambanova.ts | 19 ---- .../types/src/provider-settings/unbound.ts | 17 --- .../provider-settings/vercel-ai-gateway.ts | 17 --- .../types/src/provider-settings/vertex.ts | 23 ---- packages/types/src/provider-settings/xai.ts | 19 ---- packages/types/src/provider-settings/zai.ts | 23 ---- .../src/provider-settings/zoo-gateway.ts | 18 --- packages/types/src/providers/anthropic.ts | 24 +++- packages/types/src/providers/baseten.ts | 21 +++- packages/types/src/providers/bedrock.ts | 38 ++++++- .../common.ts | 2 +- packages/types/src/providers/deepseek.ts | 22 +++- .../fake-ai.ts | 0 packages/types/src/providers/fireworks.ts | 21 +++- packages/types/src/providers/friendli.ts | 21 +++- .../gemini-cli.ts | 0 packages/types/src/providers/gemini.ts | 22 +++- packages/types/src/providers/index.ts | 86 +++++++++++++++ .../types/src/providers/io-intelligence.ts | 19 +++- packages/types/src/providers/kenari.ts | 19 +++- packages/types/src/providers/kimi-code.ts | 25 ++++- packages/types/src/providers/lite-llm.ts | 2 +- .../litellm.ts | 0 packages/types/src/providers/lm-studio.ts | 19 +++- packages/types/src/providers/mimo.ts | 29 ++++- packages/types/src/providers/minimax.ts | 24 +++- packages/types/src/providers/mistral.ts | 22 +++- packages/types/src/providers/moonshot.ts | 24 +++- packages/types/src/providers/nanogpt.ts | 27 ++++- packages/types/src/providers/ollama.ts | 19 +++- packages/types/src/providers/openai-codex.ts | 22 +++- .../openai-native.ts | 2 +- packages/types/src/providers/openai.ts | 103 ++++++++++++++++- packages/types/src/providers/opencode-go.ts | 19 +++- packages/types/src/providers/openrouter.ts | 21 +++- packages/types/src/providers/poe.ts | 21 ++++ packages/types/src/providers/qwen-code.ts | 21 +++- packages/types/src/providers/requesty.ts | 20 +++- packages/types/src/providers/sambanova.ts | 21 +++- packages/types/src/providers/unbound.ts | 19 +++- .../types/src/providers/vercel-ai-gateway.ts | 19 +++- packages/types/src/providers/vertex.ts | 25 ++++- packages/types/src/providers/vscode-llm.ts | 2 +- .../vscode-lm.ts | 0 packages/types/src/providers/xai.ts | 21 +++- packages/types/src/providers/zai.ts | 26 ++++- packages/types/src/providers/zoo-gateway.ts | 20 +++- 74 files changed, 836 insertions(+), 849 deletions(-) delete mode 100644 packages/types/src/provider-settings/anthropic.ts delete mode 100644 packages/types/src/provider-settings/baseten.ts delete mode 100644 packages/types/src/provider-settings/bedrock.ts delete mode 100644 packages/types/src/provider-settings/deepseek.ts delete mode 100644 packages/types/src/provider-settings/fireworks.ts delete mode 100644 packages/types/src/provider-settings/friendli.ts delete mode 100644 packages/types/src/provider-settings/gemini.ts delete mode 100644 packages/types/src/provider-settings/index.ts delete mode 100644 packages/types/src/provider-settings/io-intelligence.ts delete mode 100644 packages/types/src/provider-settings/kenari.ts delete mode 100644 packages/types/src/provider-settings/kimi-code.ts delete mode 100644 packages/types/src/provider-settings/lm-studio.ts delete mode 100644 packages/types/src/provider-settings/mimo.ts delete mode 100644 packages/types/src/provider-settings/minimax.ts delete mode 100644 packages/types/src/provider-settings/mistral.ts delete mode 100644 packages/types/src/provider-settings/moonshot.ts delete mode 100644 packages/types/src/provider-settings/nanogpt.ts delete mode 100644 packages/types/src/provider-settings/ollama.ts delete mode 100644 packages/types/src/provider-settings/openai-codex.ts delete mode 100644 packages/types/src/provider-settings/openai.ts delete mode 100644 packages/types/src/provider-settings/opencode-go.ts delete mode 100644 packages/types/src/provider-settings/openrouter.ts delete mode 100644 packages/types/src/provider-settings/poe.ts delete mode 100644 packages/types/src/provider-settings/qwen-code.ts delete mode 100644 packages/types/src/provider-settings/requesty.ts delete mode 100644 packages/types/src/provider-settings/sambanova.ts delete mode 100644 packages/types/src/provider-settings/unbound.ts delete mode 100644 packages/types/src/provider-settings/vercel-ai-gateway.ts delete mode 100644 packages/types/src/provider-settings/vertex.ts delete mode 100644 packages/types/src/provider-settings/xai.ts delete mode 100644 packages/types/src/provider-settings/zai.ts delete mode 100644 packages/types/src/provider-settings/zoo-gateway.ts rename packages/types/src/{provider-settings => providers}/common.ts (98%) rename packages/types/src/{provider-settings => providers}/fake-ai.ts (100%) rename packages/types/src/{provider-settings => providers}/gemini-cli.ts (100%) rename packages/types/src/{provider-settings => providers}/litellm.ts (100%) rename packages/types/src/{provider-settings => providers}/openai-native.ts (100%) rename packages/types/src/{provider-settings => providers}/vscode-lm.ts (100%) diff --git a/packages/types/src/__tests__/provider-settings.test.ts b/packages/types/src/__tests__/provider-settings.test.ts index c5a79002a4..7d9a64bb91 100644 --- a/packages/types/src/__tests__/provider-settings.test.ts +++ b/packages/types/src/__tests__/provider-settings.test.ts @@ -8,7 +8,7 @@ import { providerSettingsSchemaDiscriminated, } from "../provider-settings.js" import { OpenAiCodexServiceTier, OpenAiServiceTier } from "../model.js" -import { providerDefinitionList } from "../provider-settings/index.js" +import { providerDefinitionList } from "../providers/index.js" describe("provider settings discriminated union", () => { it("composes exactly one provider-specific definition for every provider", () => { diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 36009290cb..7ee1f09007 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -1,7 +1,7 @@ import { z } from "zod" -import { providerDefinitionList, type ProviderDefinition } from "./provider-settings/index.js" -import { API_PROVIDER_FIELD, SETTINGS_SHAPE_FIELD } from "./provider-settings/common.js" +import { providerDefinitionList, type ProviderDefinition } from "./providers/index.js" +import { API_PROVIDER_FIELD, SETTINGS_SHAPE_FIELD } from "./providers/common.js" export { DEFAULT_OPEN_AI_STRICT_TOOL_SCHEMAS, OPEN_AI_CODEX_SERVICE_TIER_KEY, @@ -14,7 +14,7 @@ export { type NanoGptRoutingPreference, zaiApiLineSchema, type ZaiApiLine, -} from "./provider-settings/index.js" +} from "./providers/index.js" import { codebaseIndexProviderSchema } from "./codebase-index.js" import type { UnionToIntersection } from "./type-fu.js" diff --git a/packages/types/src/provider-settings/anthropic.ts b/packages/types/src/provider-settings/anthropic.ts deleted file mode 100644 index 80ff6f15fb..0000000000 --- a/packages/types/src/provider-settings/anthropic.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const anthropicProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.anthropic, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - apiKey: z.string().optional(), - anthropicBaseUrl: z.string().optional(), - anthropicUseAuthToken: z.boolean().optional(), - anthropicBeta1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. - }, -}) diff --git a/packages/types/src/provider-settings/baseten.ts b/packages/types/src/provider-settings/baseten.ts deleted file mode 100644 index ac9649af30..0000000000 --- a/packages/types/src/provider-settings/baseten.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const basetenProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.baseten, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - basetenApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/bedrock.ts b/packages/types/src/provider-settings/bedrock.ts deleted file mode 100644 index 475e07f66d..0000000000 --- a/packages/types/src/provider-settings/bedrock.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const bedrockProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.bedrock, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - awsAccessKey: z.string().optional(), - awsSecretKey: z.string().optional(), - awsSessionToken: z.string().optional(), - awsRegion: z.string().optional(), - awsUseCrossRegionInference: z.boolean().optional(), - awsUseGlobalInference: z.boolean().optional(), // Enable Global Inference profile routing when supported - awsUsePromptCache: z.boolean().optional(), - awsProfile: z.string().optional(), - awsUseProfile: z.boolean().optional(), - awsApiKey: z.string().optional(), - awsUseApiKey: z.boolean().optional(), - awsCustomArn: z.string().optional(), - awsCustomArnBaseModelId: z.string().optional(), // Registry model a custom ARN points to; drives capabilities and pricing - awsModelContextWindow: z.number().optional(), - awsBedrockEndpointEnabled: z.boolean().optional(), - awsBedrockEndpoint: z.string().optional(), - awsBedrock1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. - awsBedrockServiceTier: z.enum(["STANDARD", "FLEX", "PRIORITY"]).optional(), // AWS Bedrock service tier selection - }, -}) diff --git a/packages/types/src/provider-settings/deepseek.ts b/packages/types/src/provider-settings/deepseek.ts deleted file mode 100644 index 746f87e421..0000000000 --- a/packages/types/src/provider-settings/deepseek.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const deepSeekProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.deepseek, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - deepSeekBaseUrl: z.string().optional(), - deepSeekApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/fireworks.ts b/packages/types/src/provider-settings/fireworks.ts deleted file mode 100644 index 8d5e1ef3fa..0000000000 --- a/packages/types/src/provider-settings/fireworks.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const fireworksProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.fireworks, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - fireworksApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/friendli.ts b/packages/types/src/provider-settings/friendli.ts deleted file mode 100644 index c64aa3595b..0000000000 --- a/packages/types/src/provider-settings/friendli.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const friendliProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.friendli, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - friendliApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/gemini.ts b/packages/types/src/provider-settings/gemini.ts deleted file mode 100644 index fd287e34ac..0000000000 --- a/packages/types/src/provider-settings/gemini.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const geminiProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.gemini, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - geminiApiKey: z.string().optional(), - googleGeminiBaseUrl: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/index.ts b/packages/types/src/provider-settings/index.ts deleted file mode 100644 index 77d7ec001a..0000000000 --- a/packages/types/src/provider-settings/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { anthropicProviderDefinition } from "./anthropic.js" -import { openRouterProviderDefinition } from "./openrouter.js" -import { bedrockProviderDefinition } from "./bedrock.js" -import { vertexProviderDefinition } from "./vertex.js" -import { openAiProviderDefinition } from "./openai.js" -import { ollamaProviderDefinition } from "./ollama.js" -import { githubCopilotProviderDefinition, vsCodeLmProviderDefinition } from "./vscode-lm.js" -import { lmStudioProviderDefinition } from "./lm-studio.js" -import { geminiProviderDefinition } from "./gemini.js" -import { geminiCliProviderDefinition } from "./gemini-cli.js" -import { openAiCodexProviderDefinition } from "./openai-codex.js" -import { openAiNativeProviderDefinition } from "./openai-native.js" -import { mistralProviderDefinition } from "./mistral.js" -import { deepSeekProviderDefinition } from "./deepseek.js" -import { poeProviderDefinition } from "./poe.js" -import { moonshotProviderDefinition } from "./moonshot.js" -import { kimiCodeProviderDefinition } from "./kimi-code.js" -import { minimaxProviderDefinition } from "./minimax.js" -import { mimoProviderDefinition } from "./mimo.js" -import { requestyProviderDefinition } from "./requesty.js" -import { unboundProviderDefinition } from "./unbound.js" -import { fakeAiProviderDefinition } from "./fake-ai.js" -import { xaiProviderDefinition } from "./xai.js" -import { litellmProviderDefinition } from "./litellm.js" -import { sambaNovaProviderDefinition } from "./sambanova.js" -import { zaiProviderDefinition } from "./zai.js" -import { fireworksProviderDefinition } from "./fireworks.js" -import { friendliProviderDefinition } from "./friendli.js" -import { qwenCodeProviderDefinition } from "./qwen-code.js" -import { vercelAiGatewayProviderDefinition } from "./vercel-ai-gateway.js" -import { opencodeGoProviderDefinition } from "./opencode-go.js" -import { kenariProviderDefinition } from "./kenari.js" -import { ioIntelligenceProviderDefinition } from "./io-intelligence.js" -import { nanoGptProviderDefinition } from "./nanogpt.js" -import { zooGatewayProviderDefinition } from "./zoo-gateway.js" -import { basetenProviderDefinition } from "./baseten.js" - -import type { ProviderDefinition } from "./common.js" - -export { OPEN_AI_CODEX_SERVICE_TIER_KEY } from "./openai-codex.js" -export { parseOpenAiExtraBody, DEFAULT_OPEN_AI_STRICT_TOOL_SCHEMAS } from "./openai.js" -export { kimiCodeAuthMethodSchema, type KimiCodeAuthMethod } from "./kimi-code.js" -export { zaiApiLineSchema, type ZaiApiLine } from "./zai.js" -export { - nanoGptDefaultRoutingPreference, - nanoGptRoutingPreferences, - nanoGptRoutingPreferenceSchema, - type NanoGptRoutingPreference, -} from "./nanogpt.js" -export type { ProviderDefinition } from "./common.js" - -export const providerDefinitionList = [ - anthropicProviderDefinition, - openRouterProviderDefinition, - bedrockProviderDefinition, - vertexProviderDefinition, - openAiProviderDefinition, - ollamaProviderDefinition, - vsCodeLmProviderDefinition, - githubCopilotProviderDefinition, - lmStudioProviderDefinition, - geminiProviderDefinition, - geminiCliProviderDefinition, - openAiCodexProviderDefinition, - openAiNativeProviderDefinition, - mistralProviderDefinition, - deepSeekProviderDefinition, - poeProviderDefinition, - moonshotProviderDefinition, - kimiCodeProviderDefinition, - minimaxProviderDefinition, - mimoProviderDefinition, - requestyProviderDefinition, - unboundProviderDefinition, - fakeAiProviderDefinition, - xaiProviderDefinition, - litellmProviderDefinition, - sambaNovaProviderDefinition, - zaiProviderDefinition, - fireworksProviderDefinition, - friendliProviderDefinition, - qwenCodeProviderDefinition, - vercelAiGatewayProviderDefinition, - opencodeGoProviderDefinition, - kenariProviderDefinition, - nanoGptProviderDefinition, - ioIntelligenceProviderDefinition, - zooGatewayProviderDefinition, - basetenProviderDefinition, -] as const satisfies readonly ProviderDefinition[] diff --git a/packages/types/src/provider-settings/io-intelligence.ts b/packages/types/src/provider-settings/io-intelligence.ts deleted file mode 100644 index 7198e8c1c1..0000000000 --- a/packages/types/src/provider-settings/io-intelligence.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -const IO_INTELLIGENCE_MODEL_ID_FIELD = "ioIntelligenceModelId" - -export const ioIntelligenceProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.ioIntelligence, - modelIdKey: IO_INTELLIGENCE_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(IO_INTELLIGENCE_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - ioIntelligenceApiKey: z.string().optional(), - [IO_INTELLIGENCE_MODEL_ID_FIELD]: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/kenari.ts b/packages/types/src/provider-settings/kenari.ts deleted file mode 100644 index da1a082059..0000000000 --- a/packages/types/src/provider-settings/kenari.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -const KENARI_MODEL_ID_FIELD = "kenariModelId" - -export const kenariProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.kenari, - modelIdKey: KENARI_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(KENARI_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - kenariApiKey: z.string().optional(), - [KENARI_MODEL_ID_FIELD]: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/kimi-code.ts b/packages/types/src/provider-settings/kimi-code.ts deleted file mode 100644 index 44e6fd8d7b..0000000000 --- a/packages/types/src/provider-settings/kimi-code.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const kimiCodeAuthMethodSchema = z.enum(["oauth", "api-key"]) -export type KimiCodeAuthMethod = z.infer - -export const kimiCodeProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.kimiCode, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - kimiCodeAuthMethod: kimiCodeAuthMethodSchema.optional(), - kimiCodeApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/lm-studio.ts b/packages/types/src/provider-settings/lm-studio.ts deleted file mode 100644 index dea9659d9b..0000000000 --- a/packages/types/src/provider-settings/lm-studio.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const LM_STUDIO_MODEL_ID_FIELD = "lmStudioModelId" - -export const lmStudioProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.lmstudio, - modelIdKey: LM_STUDIO_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(LM_STUDIO_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - [LM_STUDIO_MODEL_ID_FIELD]: z.string().optional(), - lmStudioBaseUrl: z.string().optional(), - lmStudioDraftModelId: z.string().optional(), - lmStudioSpeculativeDecodingEnabled: z.boolean().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/mimo.ts b/packages/types/src/provider-settings/mimo.ts deleted file mode 100644 index 690ede3839..0000000000 --- a/packages/types/src/provider-settings/mimo.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const mimoProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.mimo, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - mimoBaseUrl: z - .union([ - z.literal("https://api.xiaomimimo.com/v1"), - z.literal("https://token-plan-cn.xiaomimimo.com/v1"), - z.literal("https://token-plan-sgp.xiaomimimo.com/v1"), - z.literal("https://token-plan-ams.xiaomimimo.com/v1"), - ]) - .optional(), - mimoApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/minimax.ts b/packages/types/src/provider-settings/minimax.ts deleted file mode 100644 index 86e8b1ce98..0000000000 --- a/packages/types/src/provider-settings/minimax.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const minimaxProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.minimax, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - minimaxBaseUrl: z - .union([z.literal("https://api.minimax.io/v1"), z.literal("https://api.minimaxi.com/v1")]) - .optional(), - minimaxApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/mistral.ts b/packages/types/src/provider-settings/mistral.ts deleted file mode 100644 index d2353563b6..0000000000 --- a/packages/types/src/provider-settings/mistral.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const mistralProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.mistral, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - mistralApiKey: z.string().optional(), - mistralCodestralUrl: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/moonshot.ts b/packages/types/src/provider-settings/moonshot.ts deleted file mode 100644 index 6d5a99e6cd..0000000000 --- a/packages/types/src/provider-settings/moonshot.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const moonshotProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.moonshot, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - moonshotBaseUrl: z - .union([z.literal("https://api.moonshot.ai/v1"), z.literal("https://api.moonshot.cn/v1")]) - .optional(), - moonshotApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/nanogpt.ts b/packages/types/src/provider-settings/nanogpt.ts deleted file mode 100644 index e1db6a237f..0000000000 --- a/packages/types/src/provider-settings/nanogpt.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -const NANOGPT_MODEL_ID_FIELD = "nanoGptModelId" - -export const nanoGptRoutingPreferences = ["auto", "fast", "cheap", "latency", "throughput", "tools", "caching"] as const - -export const nanoGptRoutingPreferenceSchema = z.enum(nanoGptRoutingPreferences) -export type NanoGptRoutingPreference = z.infer -export const nanoGptDefaultRoutingPreference: NanoGptRoutingPreference = "auto" - -export const nanoGptProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.nanogpt, - modelIdKey: NANOGPT_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(NANOGPT_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - nanoGptApiKey: z.string().optional(), - [NANOGPT_MODEL_ID_FIELD]: z.string().optional(), - nanoGptRoutingPreference: nanoGptRoutingPreferenceSchema.optional(), - }, -}) diff --git a/packages/types/src/provider-settings/ollama.ts b/packages/types/src/provider-settings/ollama.ts deleted file mode 100644 index 323484ad8d..0000000000 --- a/packages/types/src/provider-settings/ollama.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const OLLAMA_MODEL_ID_FIELD = "ollamaModelId" - -export const ollamaProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.ollama, - modelIdKey: OLLAMA_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(OLLAMA_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - [OLLAMA_MODEL_ID_FIELD]: z.string().optional(), - ollamaBaseUrl: z.string().optional(), - ollamaApiKey: z.string().optional(), - ollamaNumCtx: z.number().int().min(128).optional(), - }, -}) diff --git a/packages/types/src/provider-settings/openai-codex.ts b/packages/types/src/provider-settings/openai-codex.ts deleted file mode 100644 index 93117224ae..0000000000 --- a/packages/types/src/provider-settings/openai-codex.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { providerIdentifiers } from "../provider-identifiers.js" -import { openAiCodexServiceTierSchema } from "../model.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const OPEN_AI_CODEX_SERVICE_TIER_KEY = "openAiCodexServiceTier" - -export const openAiCodexProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.openaiCodex, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - // Codex "Fast" mode maps to the Responses API priority service tier. - [OPEN_AI_CODEX_SERVICE_TIER_KEY]: openAiCodexServiceTierSchema.optional(), - }, -}) diff --git a/packages/types/src/provider-settings/openai.ts b/packages/types/src/provider-settings/openai.ts deleted file mode 100644 index 19ef88cee4..0000000000 --- a/packages/types/src/provider-settings/openai.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { modelInfoSchema } from "../model.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const OPEN_AI_MODEL_ID_FIELD = "openAiModelId" - -/** - * Default for the OpenAI `openAiStrictToolSchemas` setting. - * When true (default), non-MCP tools are sent with strict: true and their - * schemas are normalized for OpenAI strict mode. Some OpenAI-compatible - * proxies reject strict: true; set this to false for those endpoints. - */ -export const DEFAULT_OPEN_AI_STRICT_TOOL_SCHEMAS = true - -const OPENAI_EXTRA_BODY_RESERVED_KEYS = [ - // Prototype-pollution defenses; remaining keys are request-owned, including tool-call protocol controls. - "__proto__", - "constructor", - "prototype", - "max_completion_tokens", - "max_tokens", - "messages", - "model", - "parallel_tool_calls", - "reasoning", - "reasoning_effort", - "response_format", - "stream", - "stream_options", - "temperature", - "tool_choice", - "tools", -] as const - -type OpenAiExtraBodyParseResult = - | { success: true; data: Record } - | { - success: false - reason: "invalidJson" | "objectRequired" | "reservedKeys" - data: Record - reservedKeys?: string[] - } - -export function parseOpenAiExtraBody(value: string | undefined): OpenAiExtraBodyParseResult { - if (!value?.trim()) { - return { success: true, data: {} } - } - - let parsed: unknown - try { - parsed = JSON.parse(value) - } catch { - return { success: false, reason: "invalidJson", data: {} } - } - - if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) { - return { success: false, reason: "objectRequired", data: {} } - } - - const entries = Object.entries(parsed) - const reservedKeys = entries - .map(([key]) => key) - .filter((key) => (OPENAI_EXTRA_BODY_RESERVED_KEYS as readonly string[]).includes(key)) - const data = Object.fromEntries(entries.filter(([key]) => !reservedKeys.includes(key))) - - if (reservedKeys.length > 0) { - return { success: false, reason: "reservedKeys", reservedKeys, data } - } - - return { success: true, data } -} - -const openAiExtraBodySchema = z - .string() - .superRefine((value, ctx) => { - const result = parseOpenAiExtraBody(value) - if (!result.success) { - ctx.addIssue({ code: "custom", message: result.reason }) - } - }) - .optional() - -export const openAiProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.openai, - modelIdKey: OPEN_AI_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(OPEN_AI_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - openAiBaseUrl: z.string().optional(), - openAiApiKey: z.string().optional(), - openAiR1FormatEnabled: z.boolean().optional(), - openAiStrictToolSchemas: z.boolean().optional(), - [OPEN_AI_MODEL_ID_FIELD]: z.string().optional(), - openAiCustomModelInfo: modelInfoSchema.nullish(), - openAiUseAzure: z.boolean().optional(), - azureApiVersion: z.string().optional(), - openAiStreamingEnabled: z.boolean().optional(), - openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration. - openAiHeaders: z.record(z.string(), z.string()).optional(), - openAiExtraBody: openAiExtraBodySchema, - }, -}) diff --git a/packages/types/src/provider-settings/opencode-go.ts b/packages/types/src/provider-settings/opencode-go.ts deleted file mode 100644 index f1e51890a0..0000000000 --- a/packages/types/src/provider-settings/opencode-go.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const OPENCODE_GO_MODEL_ID_FIELD = "opencodeGoModelId" - -export const opencodeGoProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.opencodeGo, - modelIdKey: OPENCODE_GO_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(OPENCODE_GO_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - opencodeGoApiKey: z.string().optional(), - [OPENCODE_GO_MODEL_ID_FIELD]: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/openrouter.ts b/packages/types/src/provider-settings/openrouter.ts deleted file mode 100644 index 8ed4480f88..0000000000 --- a/packages/types/src/provider-settings/openrouter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const OPEN_ROUTER_MODEL_ID_FIELD = "openRouterModelId" - -export const openRouterProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.openrouter, - modelIdKey: OPEN_ROUTER_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(OPEN_ROUTER_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - openRouterApiKey: z.string().optional(), - [OPEN_ROUTER_MODEL_ID_FIELD]: z.string().optional(), - openRouterBaseUrl: z.string().optional(), - openRouterSpecificProvider: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/poe.ts b/packages/types/src/provider-settings/poe.ts deleted file mode 100644 index d5c1055490..0000000000 --- a/packages/types/src/provider-settings/poe.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const poeProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.poe, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - poeApiKey: z.string().optional(), - poeBaseUrl: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/qwen-code.ts b/packages/types/src/provider-settings/qwen-code.ts deleted file mode 100644 index c1c2f8be81..0000000000 --- a/packages/types/src/provider-settings/qwen-code.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const qwenCodeProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.qwenCode, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - qwenCodeOauthPath: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/requesty.ts b/packages/types/src/provider-settings/requesty.ts deleted file mode 100644 index ec37d6bb68..0000000000 --- a/packages/types/src/provider-settings/requesty.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const REQUESTY_MODEL_ID_FIELD = "requestyModelId" - -export const requestyProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.requesty, - modelIdKey: REQUESTY_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(REQUESTY_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - requestyBaseUrl: z.string().optional(), - requestyApiKey: z.string().optional(), - [REQUESTY_MODEL_ID_FIELD]: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/sambanova.ts b/packages/types/src/provider-settings/sambanova.ts deleted file mode 100644 index 1067e01391..0000000000 --- a/packages/types/src/provider-settings/sambanova.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const sambaNovaProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.sambanova, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - sambaNovaApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/unbound.ts b/packages/types/src/provider-settings/unbound.ts deleted file mode 100644 index cadecf5912..0000000000 --- a/packages/types/src/provider-settings/unbound.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const UNBOUND_MODEL_ID_FIELD = "unboundModelId" - -export const unboundProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.unbound, - modelIdKey: UNBOUND_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(UNBOUND_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - unboundApiKey: z.string().optional(), - [UNBOUND_MODEL_ID_FIELD]: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/vercel-ai-gateway.ts b/packages/types/src/provider-settings/vercel-ai-gateway.ts deleted file mode 100644 index c9d838d7bc..0000000000 --- a/packages/types/src/provider-settings/vercel-ai-gateway.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const VERCEL_AI_GATEWAY_MODEL_ID_FIELD = "vercelAiGatewayModelId" - -export const vercelAiGatewayProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.vercelAiGateway, - modelIdKey: VERCEL_AI_GATEWAY_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(VERCEL_AI_GATEWAY_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - vercelAiGatewayApiKey: z.string().optional(), - [VERCEL_AI_GATEWAY_MODEL_ID_FIELD]: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/vertex.ts b/packages/types/src/provider-settings/vertex.ts deleted file mode 100644 index 2bfa3b114e..0000000000 --- a/packages/types/src/provider-settings/vertex.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const vertexProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.vertex, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - vertexKeyFile: z.string().optional(), - vertexJsonCredentials: z.string().optional(), - vertexProjectId: z.string().optional(), - vertexRegion: z.string().optional(), - vertex1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. - }, -}) diff --git a/packages/types/src/provider-settings/xai.ts b/packages/types/src/provider-settings/xai.ts deleted file mode 100644 index d5c2fbb874..0000000000 --- a/packages/types/src/provider-settings/xai.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const xaiProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.xai, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - xaiApiKey: z.string().optional(), - }, -}) diff --git a/packages/types/src/provider-settings/zai.ts b/packages/types/src/provider-settings/zai.ts deleted file mode 100644 index 0f4c4a0333..0000000000 --- a/packages/types/src/provider-settings/zai.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { - API_MODEL_ID_FIELD, - apiModelIdProviderModelShape, - createModelIdAccessor, - createProviderDefinition, -} from "./common.js" - -export const zaiApiLineSchema = z.enum(["international_coding", "china_coding", "international_api", "china_api"]) -export type ZaiApiLine = z.infer - -export const zaiProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.zai, - modelIdKey: API_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), - schema: { - ...apiModelIdProviderModelShape, - zaiApiKey: z.string().optional(), - zaiApiLine: zaiApiLineSchema.optional(), - }, -}) diff --git a/packages/types/src/provider-settings/zoo-gateway.ts b/packages/types/src/provider-settings/zoo-gateway.ts deleted file mode 100644 index d2082bff33..0000000000 --- a/packages/types/src/provider-settings/zoo-gateway.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { z } from "zod" - -import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" - -export const ZOO_GATEWAY_MODEL_ID_FIELD = "zooGatewayModelId" - -export const zooGatewayProviderDefinition = createProviderDefinition({ - apiProvider: providerIdentifiers.zooGateway, - modelIdKey: ZOO_GATEWAY_MODEL_ID_FIELD, - getModelId: createModelIdAccessor(ZOO_GATEWAY_MODEL_ID_FIELD), - schema: { - ...baseProviderSettingsShape, - zooSessionToken: z.string().optional(), - [ZOO_GATEWAY_MODEL_ID_FIELD]: z.string().optional(), - zooGatewayBaseUrl: z.string().optional(), - }, -}) diff --git a/packages/types/src/providers/anthropic.ts b/packages/types/src/providers/anthropic.ts index 567f6268be..160f637a4a 100644 --- a/packages/types/src/providers/anthropic.ts +++ b/packages/types/src/providers/anthropic.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://docs.anthropic.com/en/docs/about-claude/models // https://platform.claude.com/docs/en/about-claude/pricing @@ -348,3 +357,16 @@ export const anthropicModels = { } as const satisfies Record export const ANTHROPIC_DEFAULT_MAX_TOKENS = 8192 + +export const anthropicProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.anthropic, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + apiKey: z.string().optional(), + anthropicBaseUrl: z.string().optional(), + anthropicUseAuthToken: z.boolean().optional(), + anthropicBeta1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. + }, +}) diff --git a/packages/types/src/providers/baseten.ts b/packages/types/src/providers/baseten.ts index 2c1701ab0a..43ed965d1c 100644 --- a/packages/types/src/providers/baseten.ts +++ b/packages/types/src/providers/baseten.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // Baseten // https://baseten.co/products/model-apis/ @@ -158,3 +167,13 @@ export const basetenModels = { export type BasetenModelId = keyof typeof basetenModels export const basetenDefaultModelId = "zai-org/GLM-4.6" satisfies BasetenModelId + +export const basetenProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.baseten, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + basetenApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/bedrock.ts b/packages/types/src/providers/bedrock.ts index 1e89f3e6ba..c6041f0b21 100644 --- a/packages/types/src/providers/bedrock.ts +++ b/packages/types/src/providers/bedrock.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html @@ -816,3 +825,30 @@ export const resolveBedrockCustomArnBaseModelId = ( return baseModelId && isBedrockModelId(baseModelId) ? baseModelId : namedModelId } + +export const bedrockProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.bedrock, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + awsAccessKey: z.string().optional(), + awsSecretKey: z.string().optional(), + awsSessionToken: z.string().optional(), + awsRegion: z.string().optional(), + awsUseCrossRegionInference: z.boolean().optional(), + awsUseGlobalInference: z.boolean().optional(), // Enable Global Inference profile routing when supported + awsUsePromptCache: z.boolean().optional(), + awsProfile: z.string().optional(), + awsUseProfile: z.boolean().optional(), + awsApiKey: z.string().optional(), + awsUseApiKey: z.boolean().optional(), + awsCustomArn: z.string().optional(), + awsCustomArnBaseModelId: z.string().optional(), // Registry model a custom ARN points to; drives capabilities and pricing + awsModelContextWindow: z.number().optional(), + awsBedrockEndpointEnabled: z.boolean().optional(), + awsBedrockEndpoint: z.string().optional(), + awsBedrock1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. + awsBedrockServiceTier: z.enum(["STANDARD", "FLEX", "PRIORITY"]).optional(), // AWS Bedrock service tier selection + }, +}) diff --git a/packages/types/src/provider-settings/common.ts b/packages/types/src/providers/common.ts similarity index 98% rename from packages/types/src/provider-settings/common.ts rename to packages/types/src/providers/common.ts index ca78c3a25d..1ea2daf6f4 100644 --- a/packages/types/src/provider-settings/common.ts +++ b/packages/types/src/providers/common.ts @@ -1,7 +1,7 @@ import { z } from "zod" import { reasoningEffortSettingSchema, verbosityLevelsSchema } from "../model.js" -import type { ProviderIdentifier } from "../provider-identifiers.js" +import { type ProviderIdentifier } from "../provider-identifiers.js" export const API_PROVIDER_FIELD = "apiProvider" export const SETTINGS_SHAPE_FIELD = "settingsShape" diff --git a/packages/types/src/providers/deepseek.ts b/packages/types/src/providers/deepseek.ts index 5cd2e0f21d..72b11e0d4e 100644 --- a/packages/types/src/providers/deepseek.ts +++ b/packages/types/src/providers/deepseek.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://platform.deepseek.com/docs/api // preserveReasoning enables interleaved thinking mode for tool calls: @@ -75,3 +84,14 @@ export const deepSeekModels = { // https://api-docs.deepseek.com/quick_start/parameter_settings export const DEEP_SEEK_DEFAULT_TEMPERATURE = 0.0 + +export const deepSeekProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.deepseek, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + deepSeekBaseUrl: z.string().optional(), + deepSeekApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/provider-settings/fake-ai.ts b/packages/types/src/providers/fake-ai.ts similarity index 100% rename from packages/types/src/provider-settings/fake-ai.ts rename to packages/types/src/providers/fake-ai.ts diff --git a/packages/types/src/providers/fireworks.ts b/packages/types/src/providers/fireworks.ts index 5417618ac6..9c4a7c6834 100644 --- a/packages/types/src/providers/fireworks.ts +++ b/packages/types/src/providers/fireworks.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" export type FireworksModelId = | "accounts/fireworks/models/kimi-k2-instruct" @@ -320,3 +329,13 @@ export const fireworksModels = { "Z.ai GLM-5.1 is the latest coding-focused model in the GLM family, with exceptional performance on complex programming tasks and enhanced reasoning and code generation quality.", }, } as const satisfies Record + +export const fireworksProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.fireworks, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + fireworksApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/friendli.ts b/packages/types/src/providers/friendli.ts index 76ce6d0c6e..85d3eb114a 100644 --- a/packages/types/src/providers/friendli.ts +++ b/packages/types/src/providers/friendli.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" export type FriendliModelId = "zai-org/GLM-5.2" | "zai-org/GLM-5.1" | "deepseek-ai/DeepSeek-V3.2" | "MiniMaxAI/MiniMax-M2.5" @@ -62,3 +71,13 @@ export const friendliModels = { "MiniMax M2.5 is a high-performance language model with a 204.8K context window, optimized for long-context understanding and generation tasks, served via Friendli Model APIs.", }, } as const satisfies Record + +export const friendliProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.friendli, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + friendliApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/provider-settings/gemini-cli.ts b/packages/types/src/providers/gemini-cli.ts similarity index 100% rename from packages/types/src/provider-settings/gemini-cli.ts rename to packages/types/src/providers/gemini-cli.ts diff --git a/packages/types/src/providers/gemini.ts b/packages/types/src/providers/gemini.ts index 9a0f275917..4c1a99c929 100644 --- a/packages/types/src/providers/gemini.ts +++ b/packages/types/src/providers/gemini.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://ai.google.dev/gemini-api/docs/models/gemini export type GeminiModelId = keyof typeof geminiModels @@ -374,3 +383,14 @@ export const geminiModels = { maxThinkingTokens: 24_576, }, } as const satisfies Record + +export const geminiProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.gemini, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + geminiApiKey: z.string().optional(), + googleGeminiBaseUrl: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index 29c445399d..df50085fde 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -2,10 +2,13 @@ export * from "./anthropic.js" export * from "./baseten.js" export * from "./bedrock.js" export * from "./deepseek.js" +export * from "./fake-ai.js" export * from "./fireworks.js" export * from "./friendli.js" export * from "./gemini.js" +export * from "./gemini-cli.js" export * from "./lite-llm.js" +export * from "./litellm.js" export * from "./lm-studio.js" export * from "./mistral.js" export * from "./moonshot.js" @@ -13,6 +16,7 @@ export * from "./ollama.js" export * from "./openai.js" export * from "./openai-codex.js" export * from "./openai-codex-rate-limits.js" +export * from "./openai-native.js" export * from "./openrouter.js" export * from "./poe.js" export * from "./qwen-code.js" @@ -20,6 +24,7 @@ export * from "./requesty.js" export * from "./sambanova.js" export * from "./unbound.js" export * from "./vertex.js" +export * from "./vscode-lm.js" export * from "./vscode-llm.js" export * from "./xai.js" export * from "./vercel-ai-gateway.js" @@ -33,6 +38,8 @@ export * from "./minimax.js" export * from "./mimo.js" export * from "./zoo-gateway.js" +export type { ProviderDefinition } from "./common.js" + import { anthropicDefaultModelId } from "./anthropic.js" import { basetenDefaultModelId } from "./baseten.js" import { bedrockDefaultModelId } from "./bedrock.js" @@ -65,6 +72,45 @@ import { minimaxDefaultModelId } from "./minimax.js" import { mimoDefaultModelId } from "./mimo.js" import { zooGatewayDefaultModelId } from "./zoo-gateway.js" +import { anthropicProviderDefinition } from "./anthropic.js" +import { basetenProviderDefinition } from "./baseten.js" +import { bedrockProviderDefinition } from "./bedrock.js" +import { deepSeekProviderDefinition } from "./deepseek.js" +import { fakeAiProviderDefinition } from "./fake-ai.js" +import { fireworksProviderDefinition } from "./fireworks.js" +import { friendliProviderDefinition } from "./friendli.js" +import { geminiProviderDefinition } from "./gemini.js" +import { geminiCliProviderDefinition } from "./gemini-cli.js" +import { ioIntelligenceProviderDefinition } from "./io-intelligence.js" +import { kenariProviderDefinition } from "./kenari.js" +import { kimiCodeProviderDefinition } from "./kimi-code.js" +import { litellmProviderDefinition } from "./litellm.js" +import { lmStudioProviderDefinition } from "./lm-studio.js" +import { mimoProviderDefinition } from "./mimo.js" +import { minimaxProviderDefinition } from "./minimax.js" +import { mistralProviderDefinition } from "./mistral.js" +import { moonshotProviderDefinition } from "./moonshot.js" +import { nanoGptProviderDefinition } from "./nanogpt.js" +import { ollamaProviderDefinition } from "./ollama.js" +import { openAiProviderDefinition } from "./openai.js" +import { openAiCodexProviderDefinition } from "./openai-codex.js" +import { openAiNativeProviderDefinition } from "./openai-native.js" +import { opencodeGoProviderDefinition } from "./opencode-go.js" +import { openRouterProviderDefinition } from "./openrouter.js" +import { poeProviderDefinition } from "./poe.js" +import { qwenCodeProviderDefinition } from "./qwen-code.js" +import { requestyProviderDefinition } from "./requesty.js" +import { sambaNovaProviderDefinition } from "./sambanova.js" +import { unboundProviderDefinition } from "./unbound.js" +import { vercelAiGatewayProviderDefinition } from "./vercel-ai-gateway.js" +import { vertexProviderDefinition } from "./vertex.js" +import { githubCopilotProviderDefinition, vsCodeLmProviderDefinition } from "./vscode-lm.js" +import { xaiProviderDefinition } from "./xai.js" +import { zaiProviderDefinition } from "./zai.js" +import { zooGatewayProviderDefinition } from "./zoo-gateway.js" + +import type { ProviderDefinition } from "./common.js" + // Import the ProviderName type from provider-settings to avoid duplication import type { ProviderName } from "../provider-settings.js" import { providerIdentifiers } from "../provider-identifiers.js" @@ -153,3 +199,43 @@ export function getProviderDefaultModelId( return anthropicDefaultModelId } } + +export const providerDefinitionList = [ + anthropicProviderDefinition, + openRouterProviderDefinition, + bedrockProviderDefinition, + vertexProviderDefinition, + openAiProviderDefinition, + ollamaProviderDefinition, + vsCodeLmProviderDefinition, + githubCopilotProviderDefinition, + lmStudioProviderDefinition, + geminiProviderDefinition, + geminiCliProviderDefinition, + openAiCodexProviderDefinition, + openAiNativeProviderDefinition, + mistralProviderDefinition, + deepSeekProviderDefinition, + poeProviderDefinition, + moonshotProviderDefinition, + kimiCodeProviderDefinition, + minimaxProviderDefinition, + mimoProviderDefinition, + requestyProviderDefinition, + unboundProviderDefinition, + fakeAiProviderDefinition, + xaiProviderDefinition, + litellmProviderDefinition, + sambaNovaProviderDefinition, + zaiProviderDefinition, + fireworksProviderDefinition, + friendliProviderDefinition, + qwenCodeProviderDefinition, + vercelAiGatewayProviderDefinition, + opencodeGoProviderDefinition, + kenariProviderDefinition, + nanoGptProviderDefinition, + ioIntelligenceProviderDefinition, + zooGatewayProviderDefinition, + basetenProviderDefinition, +] as const satisfies readonly ProviderDefinition[] diff --git a/packages/types/src/providers/io-intelligence.ts b/packages/types/src/providers/io-intelligence.ts index 5e18806163..bfdc46b39c 100644 --- a/packages/types/src/providers/io-intelligence.ts +++ b/packages/types/src/providers/io-intelligence.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" export const IO_INTELLIGENCE_BASE_URL = "https://api.intelligence.io.solutions/api/v1" @@ -11,3 +15,16 @@ export const ioIntelligenceDefaultModelInfo: ModelInfo = { supportsPromptCache: false, description: "IO Intelligence model. The full model catalog is resolved dynamically from the /models endpoint.", } + +const IO_INTELLIGENCE_MODEL_ID_FIELD = "ioIntelligenceModelId" + +export const ioIntelligenceProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.ioIntelligence, + modelIdKey: IO_INTELLIGENCE_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(IO_INTELLIGENCE_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + ioIntelligenceApiKey: z.string().optional(), + [IO_INTELLIGENCE_MODEL_ID_FIELD]: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/kenari.ts b/packages/types/src/providers/kenari.ts index 3b14b5f746..3142471dc3 100644 --- a/packages/types/src/providers/kenari.ts +++ b/packages/types/src/providers/kenari.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // Kenari: Indonesian OpenAI-compatible AI gateway billed in Rupiah (IDR). // https://kenari.id/docs · base URL: https://kenari.id/v1 @@ -24,3 +28,16 @@ export const kenariDefaultModelInfo: ModelInfo = { } export const KENARI_DEFAULT_TEMPERATURE = 0 + +const KENARI_MODEL_ID_FIELD = "kenariModelId" + +export const kenariProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.kenari, + modelIdKey: KENARI_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(KENARI_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + kenariApiKey: z.string().optional(), + [KENARI_MODEL_ID_FIELD]: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/kimi-code.ts b/packages/types/src/providers/kimi-code.ts index 0837e25832..899b520ef0 100644 --- a/packages/types/src/providers/kimi-code.ts +++ b/packages/types/src/providers/kimi-code.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" export const KIMI_CODE_BASE_URL = "https://api.kimi.com/coding/v1" export const kimiCodeDefaultModelId = "kimi-for-coding" @@ -28,3 +37,17 @@ export const kimiCodeModels = { } as const satisfies Record export type KimiCodeModelId = keyof typeof kimiCodeModels + +export const kimiCodeAuthMethodSchema = z.enum(["oauth", "api-key"]) +export type KimiCodeAuthMethod = z.infer + +export const kimiCodeProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.kimiCode, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + kimiCodeAuthMethod: kimiCodeAuthMethodSchema.optional(), + kimiCodeApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/lite-llm.ts b/packages/types/src/providers/lite-llm.ts index 5c28369651..5303772586 100644 --- a/packages/types/src/providers/lite-llm.ts +++ b/packages/types/src/providers/lite-llm.ts @@ -1,4 +1,4 @@ -import type { ModelInfo } from "../model.js" +import { type ModelInfo } from "../model.js" // https://docs.litellm.ai/ export const litellmDefaultModelId = "claude-3-7-sonnet-20250219" diff --git a/packages/types/src/provider-settings/litellm.ts b/packages/types/src/providers/litellm.ts similarity index 100% rename from packages/types/src/provider-settings/litellm.ts rename to packages/types/src/providers/litellm.ts diff --git a/packages/types/src/providers/lm-studio.ts b/packages/types/src/providers/lm-studio.ts index 5360178840..1c0f384ad3 100644 --- a/packages/types/src/providers/lm-studio.ts +++ b/packages/types/src/providers/lm-studio.ts @@ -1,6 +1,8 @@ import { z } from "zod" -import type { ModelInfo } from "../model.js" +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" export const lmStudioModelsMessageTypes = ["requestLmStudioModels", "lmStudioModels"] as const @@ -26,3 +28,18 @@ export const lMStudioDefaultModelInfo: ModelInfo = { cacheReadsPrice: 0, description: "LM Studio hosted models", } + +export const LM_STUDIO_MODEL_ID_FIELD = "lmStudioModelId" + +export const lmStudioProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.lmstudio, + modelIdKey: LM_STUDIO_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(LM_STUDIO_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + [LM_STUDIO_MODEL_ID_FIELD]: z.string().optional(), + lmStudioBaseUrl: z.string().optional(), + lmStudioDraftModelId: z.string().optional(), + lmStudioSpeculativeDecodingEnabled: z.boolean().optional(), + }, +}) diff --git a/packages/types/src/providers/mimo.ts b/packages/types/src/providers/mimo.ts index debd0cbefc..6233a32e90 100644 --- a/packages/types/src/providers/mimo.ts +++ b/packages/types/src/providers/mimo.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://developer.puter.com/ai/xiaomi/mimo-v2.5-pro/ // https://developer.puter.com/ai/xiaomi/mimo-v2.5/ @@ -60,3 +69,21 @@ export const mimoModels = { export const mimoDefaultModelInfo: ModelInfo = mimoModels[mimoDefaultModelId] export const MIMO_DEFAULT_TEMPERATURE = 1.0 + +export const mimoProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.mimo, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + mimoBaseUrl: z + .union([ + z.literal("https://api.xiaomimimo.com/v1"), + z.literal("https://token-plan-cn.xiaomimimo.com/v1"), + z.literal("https://token-plan-sgp.xiaomimimo.com/v1"), + z.literal("https://token-plan-ams.xiaomimimo.com/v1"), + ]) + .optional(), + mimoApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/minimax.ts b/packages/types/src/providers/minimax.ts index 7fe22e4041..30be640b10 100644 --- a/packages/types/src/providers/minimax.ts +++ b/packages/types/src/providers/minimax.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // Minimax // https://platform.minimax.io/docs/guides/models-intro @@ -149,3 +158,16 @@ export const minimaxDefaultModelInfo: ModelInfo = minimaxModels[minimaxDefaultMo export const MINIMAX_DEFAULT_MAX_TOKENS = 16_384 export const MINIMAX_DEFAULT_TEMPERATURE = 1.0 + +export const minimaxProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.minimax, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + minimaxBaseUrl: z + .union([z.literal("https://api.minimax.io/v1"), z.literal("https://api.minimaxi.com/v1")]) + .optional(), + minimaxApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/mistral.ts b/packages/types/src/providers/mistral.ts index 0b030c80d4..0d6f7411bf 100644 --- a/packages/types/src/providers/mistral.ts +++ b/packages/types/src/providers/mistral.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://docs.mistral.ai/getting-started/models/models_overview/ export type MistralModelId = keyof typeof mistralModels @@ -81,3 +90,14 @@ export const mistralModels = { } as const satisfies Record export const MISTRAL_DEFAULT_TEMPERATURE = 1 + +export const mistralProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.mistral, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + mistralApiKey: z.string().optional(), + mistralCodestralUrl: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/moonshot.ts b/packages/types/src/providers/moonshot.ts index 8e041d160a..bc0b2b5af0 100644 --- a/packages/types/src/providers/moonshot.ts +++ b/packages/types/src/providers/moonshot.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://platform.moonshot.ai/ export type MoonshotModelId = keyof typeof moonshotModels @@ -120,3 +129,16 @@ export const moonshotModels = { } as const satisfies Record export const MOONSHOT_DEFAULT_TEMPERATURE = 0.6 + +export const moonshotProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.moonshot, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + moonshotBaseUrl: z + .union([z.literal("https://api.moonshot.ai/v1"), z.literal("https://api.moonshot.cn/v1")]) + .optional(), + moonshotApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/nanogpt.ts b/packages/types/src/providers/nanogpt.ts index 1b0459ab24..a456e1b5f1 100644 --- a/packages/types/src/providers/nanogpt.ts +++ b/packages/types/src/providers/nanogpt.ts @@ -1,5 +1,8 @@ -import type { ModelInfo } from "../model.js" -import type { NanoGptRoutingPreference } from "../provider-settings/nanogpt.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" export const NANOGPT_BASE_URL = "https://nano-gpt.com/api/v1" @@ -55,3 +58,23 @@ export function applyNanoGptRoutingPreference(modelId: string, preference: NanoG ? canonicalId : `${canonicalId}:${ROUTING_SUFFIX_BY_PREFERENCE[preference]}` } + +const NANOGPT_MODEL_ID_FIELD = "nanoGptModelId" + +export const nanoGptRoutingPreferences = ["auto", "fast", "cheap", "latency", "throughput", "tools", "caching"] as const + +export const nanoGptRoutingPreferenceSchema = z.enum(nanoGptRoutingPreferences) +export type NanoGptRoutingPreference = z.infer +export const nanoGptDefaultRoutingPreference: NanoGptRoutingPreference = "auto" + +export const nanoGptProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.nanogpt, + modelIdKey: NANOGPT_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(NANOGPT_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + nanoGptApiKey: z.string().optional(), + [NANOGPT_MODEL_ID_FIELD]: z.string().optional(), + nanoGptRoutingPreference: nanoGptRoutingPreferenceSchema.optional(), + }, +}) diff --git a/packages/types/src/providers/ollama.ts b/packages/types/src/providers/ollama.ts index e97a480b88..cdb3ab996b 100644 --- a/packages/types/src/providers/ollama.ts +++ b/packages/types/src/providers/ollama.ts @@ -1,6 +1,8 @@ import { z } from "zod" -import type { ModelInfo } from "../model.js" +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // Ollama // https://ollama.com/models @@ -24,3 +26,18 @@ export const ollamaDefaultModelInfo: ModelInfo = { cacheReadsPrice: 0, description: "Ollama hosted models", } + +export const OLLAMA_MODEL_ID_FIELD = "ollamaModelId" + +export const ollamaProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.ollama, + modelIdKey: OLLAMA_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(OLLAMA_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + [OLLAMA_MODEL_ID_FIELD]: z.string().optional(), + ollamaBaseUrl: z.string().optional(), + ollamaApiKey: z.string().optional(), + ollamaNumCtx: z.number().int().min(128).optional(), + }, +}) diff --git a/packages/types/src/providers/openai-codex.ts b/packages/types/src/providers/openai-codex.ts index 95ba2dfae1..02a2a7d0d5 100644 --- a/packages/types/src/providers/openai-codex.ts +++ b/packages/types/src/providers/openai-codex.ts @@ -1,4 +1,11 @@ -import type { ModelInfo } from "../model.js" +import { openAiCodexServiceTierSchema, type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" /** * OpenAI Codex Provider @@ -350,3 +357,16 @@ export const openAiCodexModels = { description: "GPT-5.2: Latest GPT model via ChatGPT subscription", }, } as const satisfies Record + +export const OPEN_AI_CODEX_SERVICE_TIER_KEY = "openAiCodexServiceTier" + +export const openAiCodexProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.openaiCodex, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + // Codex "Fast" mode maps to the Responses API priority service tier. + [OPEN_AI_CODEX_SERVICE_TIER_KEY]: openAiCodexServiceTierSchema.optional(), + }, +}) diff --git a/packages/types/src/provider-settings/openai-native.ts b/packages/types/src/providers/openai-native.ts similarity index 100% rename from packages/types/src/provider-settings/openai-native.ts rename to packages/types/src/providers/openai-native.ts index 683fd4dfee..857a51dabe 100644 --- a/packages/types/src/provider-settings/openai-native.ts +++ b/packages/types/src/providers/openai-native.ts @@ -1,7 +1,7 @@ import { z } from "zod" -import { providerIdentifiers } from "../provider-identifiers.js" import { serviceTierSchema } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" import { API_MODEL_ID_FIELD, apiModelIdProviderModelShape, diff --git a/packages/types/src/providers/openai.ts b/packages/types/src/providers/openai.ts index 41d00c7a04..05e278df20 100644 --- a/packages/types/src/providers/openai.ts +++ b/packages/types/src/providers/openai.ts @@ -1,6 +1,8 @@ import { z } from "zod" -import type { ModelInfo } from "../model.js" +import { modelInfoSchema, type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // https://openai.com/api/pricing/ export const openAiModelsMessageTypes = ["requestOpenAiModels", "openAiModels"] as const @@ -978,3 +980,102 @@ export function isAzureOpenAiBaseUrl(baseUrl?: string, useAzure?: boolean): bool return false } } + +export const OPEN_AI_MODEL_ID_FIELD = "openAiModelId" + +/** + * Default for the OpenAI `openAiStrictToolSchemas` setting. + * When true (default), non-MCP tools are sent with strict: true and their + * schemas are normalized for OpenAI strict mode. Some OpenAI-compatible + * proxies reject strict: true; set this to false for those endpoints. + */ +export const DEFAULT_OPEN_AI_STRICT_TOOL_SCHEMAS = true + +const OPENAI_EXTRA_BODY_RESERVED_KEYS = [ + // Prototype-pollution defenses; remaining keys are request-owned, including tool-call protocol controls. + "__proto__", + "constructor", + "prototype", + "max_completion_tokens", + "max_tokens", + "messages", + "model", + "parallel_tool_calls", + "reasoning", + "reasoning_effort", + "response_format", + "stream", + "stream_options", + "temperature", + "tool_choice", + "tools", +] as const + +type OpenAiExtraBodyParseResult = + | { success: true; data: Record } + | { + success: false + reason: "invalidJson" | "objectRequired" | "reservedKeys" + data: Record + reservedKeys?: string[] + } + +export function parseOpenAiExtraBody(value: string | undefined): OpenAiExtraBodyParseResult { + if (!value?.trim()) { + return { success: true, data: {} } + } + + let parsed: unknown + try { + parsed = JSON.parse(value) + } catch { + return { success: false, reason: "invalidJson", data: {} } + } + + if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) { + return { success: false, reason: "objectRequired", data: {} } + } + + const entries = Object.entries(parsed) + const reservedKeys = entries + .map(([key]) => key) + .filter((key) => (OPENAI_EXTRA_BODY_RESERVED_KEYS as readonly string[]).includes(key)) + const data = Object.fromEntries(entries.filter(([key]) => !reservedKeys.includes(key))) + + if (reservedKeys.length > 0) { + return { success: false, reason: "reservedKeys", reservedKeys, data } + } + + return { success: true, data } +} + +const openAiExtraBodySchema = z + .string() + .superRefine((value, ctx) => { + const result = parseOpenAiExtraBody(value) + if (!result.success) { + ctx.addIssue({ code: "custom", message: result.reason }) + } + }) + .optional() + +export const openAiProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.openai, + modelIdKey: OPEN_AI_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(OPEN_AI_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + openAiBaseUrl: z.string().optional(), + openAiApiKey: z.string().optional(), + openAiR1FormatEnabled: z.boolean().optional(), + openAiStrictToolSchemas: z.boolean().optional(), + [OPEN_AI_MODEL_ID_FIELD]: z.string().optional(), + openAiCustomModelInfo: modelInfoSchema.nullish(), + openAiUseAzure: z.boolean().optional(), + azureApiVersion: z.string().optional(), + openAiStreamingEnabled: z.boolean().optional(), + openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration. + openAiHeaders: z.record(z.string(), z.string()).optional(), + openAiExtraBody: openAiExtraBodySchema, + }, +}) diff --git a/packages/types/src/providers/opencode-go.ts b/packages/types/src/providers/opencode-go.ts index 827cac1c58..faadd1739d 100644 --- a/packages/types/src/providers/opencode-go.ts +++ b/packages/types/src/providers/opencode-go.ts @@ -1,4 +1,8 @@ -import type { ModelInfo, ReasoningEffortExtended } from "../model.js" +import { z } from "zod" + +import { type ModelInfo, type ReasoningEffortExtended } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // Opencode "Go" plan — OpenAI-compatible gateway. // https://opencode.ai/docs/go/ · base URL: https://opencode.ai/zen/go/v1 @@ -822,3 +826,16 @@ export function opencodeGoResponsesSupportsTemperature( export function getOpencodeGoModelInfo(modelId: string): ModelInfo | undefined { return opencodeGoModels[modelId] } + +export const OPENCODE_GO_MODEL_ID_FIELD = "opencodeGoModelId" + +export const opencodeGoProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.opencodeGo, + modelIdKey: OPENCODE_GO_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(OPENCODE_GO_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + opencodeGoApiKey: z.string().optional(), + [OPENCODE_GO_MODEL_ID_FIELD]: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/openrouter.ts b/packages/types/src/providers/openrouter.ts index abfdafb8ca..8480ee6d63 100644 --- a/packages/types/src/providers/openrouter.ts +++ b/packages/types/src/providers/openrouter.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // https://openrouter.ai/models?order=newest&supported_parameters=tools export const openRouterDefaultModelId = "anthropic/claude-sonnet-4.5" @@ -100,3 +104,18 @@ export const OPEN_ROUTER_REASONING_BUDGET_MODELS = new Set([ "anthropic/claude-3.7-sonnet:thinking", "google/gemini-2.5-flash-preview-05-20:thinking", ]) + +export const OPEN_ROUTER_MODEL_ID_FIELD = "openRouterModelId" + +export const openRouterProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.openrouter, + modelIdKey: OPEN_ROUTER_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(OPEN_ROUTER_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + openRouterApiKey: z.string().optional(), + [OPEN_ROUTER_MODEL_ID_FIELD]: z.string().optional(), + openRouterBaseUrl: z.string().optional(), + openRouterSpecificProvider: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/poe.ts b/packages/types/src/providers/poe.ts index c9b6211ddd..f7f2587be4 100644 --- a/packages/types/src/providers/poe.ts +++ b/packages/types/src/providers/poe.ts @@ -1,2 +1,23 @@ +import { z } from "zod" + +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" + export { poeDefaultModelId, POE_DEFAULT_BASE_URL, getPoeDefaultModelInfo } from "ai-sdk-provider-poe/code" export type { PoeDefaultModelInfo } from "ai-sdk-provider-poe/code" + +export const poeProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.poe, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + poeApiKey: z.string().optional(), + poeBaseUrl: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/qwen-code.ts b/packages/types/src/providers/qwen-code.ts index 0f51e4eacb..b632d6e7c5 100644 --- a/packages/types/src/providers/qwen-code.ts +++ b/packages/types/src/providers/qwen-code.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" export type QwenCodeModelId = "qwen3-coder-plus" | "qwen3-coder-flash" @@ -28,3 +37,13 @@ export const qwenCodeModels = { description: "Qwen3 Coder Flash - Fast coding model with 1M context window optimized for speed", }, } as const satisfies Record + +export const qwenCodeProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.qwenCode, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + qwenCodeOauthPath: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/requesty.ts b/packages/types/src/providers/requesty.ts index d312adb397..676553797f 100644 --- a/packages/types/src/providers/requesty.ts +++ b/packages/types/src/providers/requesty.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // Requesty // https://requesty.ai/router-2 @@ -16,3 +20,17 @@ export const requestyDefaultModelInfo: ModelInfo = { description: "The best coding model, optimized by Requesty, and automatically routed to the fastest provider. Claude 4 Sonnet is an advanced large language model with improved reasoning, coding, and problem-solving capabilities.", } + +export const REQUESTY_MODEL_ID_FIELD = "requestyModelId" + +export const requestyProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.requesty, + modelIdKey: REQUESTY_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(REQUESTY_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + requestyBaseUrl: z.string().optional(), + requestyApiKey: z.string().optional(), + [REQUESTY_MODEL_ID_FIELD]: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/sambanova.ts b/packages/types/src/providers/sambanova.ts index 624a7eb8c7..758b696f39 100644 --- a/packages/types/src/providers/sambanova.ts +++ b/packages/types/src/providers/sambanova.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://docs.sambanova.ai/cloud/docs/get-started/supported-models export type SambaNovaModelId = @@ -88,3 +97,13 @@ export const sambaNovaModels = { description: "OpenAI gpt oss 120b model with 128k context window.", }, } as const satisfies Record + +export const sambaNovaProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.sambanova, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + sambaNovaApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/unbound.ts b/packages/types/src/providers/unbound.ts index f45c986dd0..432753f2fb 100644 --- a/packages/types/src/providers/unbound.ts +++ b/packages/types/src/providers/unbound.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // Unbound // https://gateway.getunbound.ai @@ -14,3 +18,16 @@ export const unboundDefaultModelInfo: ModelInfo = { cacheWritesPrice: 3.75, cacheReadsPrice: 0.3, } + +export const UNBOUND_MODEL_ID_FIELD = "unboundModelId" + +export const unboundProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.unbound, + modelIdKey: UNBOUND_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(UNBOUND_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + unboundApiKey: z.string().optional(), + [UNBOUND_MODEL_ID_FIELD]: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/vercel-ai-gateway.ts b/packages/types/src/providers/vercel-ai-gateway.ts index eddf792b7d..0f28869277 100644 --- a/packages/types/src/providers/vercel-ai-gateway.ts +++ b/packages/types/src/providers/vercel-ai-gateway.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // https://ai-gateway.vercel.sh/v1/ export const vercelAiGatewayDefaultModelId = "anthropic/claude-sonnet-4" @@ -122,3 +126,16 @@ export const vercelAiGatewayDefaultModelInfo: ModelInfo = { } export const VERCEL_AI_GATEWAY_DEFAULT_TEMPERATURE = 0.7 + +export const VERCEL_AI_GATEWAY_MODEL_ID_FIELD = "vercelAiGatewayModelId" + +export const vercelAiGatewayProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.vercelAiGateway, + modelIdKey: VERCEL_AI_GATEWAY_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(VERCEL_AI_GATEWAY_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + vercelAiGatewayApiKey: z.string().optional(), + [VERCEL_AI_GATEWAY_MODEL_ID_FIELD]: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/vertex.ts b/packages/types/src/providers/vertex.ts index e58aa3e331..df10df5a75 100644 --- a/packages/types/src/providers/vertex.ts +++ b/packages/types/src/providers/vertex.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude export type VertexModelId = keyof typeof vertexModels @@ -812,3 +821,17 @@ export const VERTEX_REGIONS = [ { value: "me-central1", label: "me-central1" }, { value: "africa-south1", label: "africa-south1" }, ] + +export const vertexProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.vertex, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + vertexKeyFile: z.string().optional(), + vertexJsonCredentials: z.string().optional(), + vertexProjectId: z.string().optional(), + vertexRegion: z.string().optional(), + vertex1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. + }, +}) diff --git a/packages/types/src/providers/vscode-llm.ts b/packages/types/src/providers/vscode-llm.ts index b6ba122d53..8625c7d0fb 100644 --- a/packages/types/src/providers/vscode-llm.ts +++ b/packages/types/src/providers/vscode-llm.ts @@ -1,6 +1,6 @@ import { z } from "zod" -import type { ModelInfo } from "../model.js" +import { type ModelInfo } from "../model.js" import { openAiModelInfoSaneDefaults } from "./openai.js" export const vsCodeLmModelsMessageTypes = [ diff --git a/packages/types/src/provider-settings/vscode-lm.ts b/packages/types/src/providers/vscode-lm.ts similarity index 100% rename from packages/types/src/provider-settings/vscode-lm.ts rename to packages/types/src/providers/vscode-lm.ts diff --git a/packages/types/src/providers/xai.ts b/packages/types/src/providers/xai.ts index 50adeaeb96..7c19ac8ffe 100644 --- a/packages/types/src/providers/xai.ts +++ b/packages/types/src/providers/xai.ts @@ -1,4 +1,13 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // https://docs.x.ai/docs/api-reference export type XAIModelId = keyof typeof xaiModels @@ -159,3 +168,13 @@ export const xaiModels = { excludedTools: ["apply_diff"], }, } as const satisfies Record + +export const xaiProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.xai, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + xaiApiKey: z.string().optional(), + }, +}) diff --git a/packages/types/src/providers/zai.ts b/packages/types/src/providers/zai.ts index 56c43c3212..d3b88bb027 100644 --- a/packages/types/src/providers/zai.ts +++ b/packages/types/src/providers/zai.ts @@ -1,5 +1,13 @@ -import type { ModelInfo } from "../model.js" -import { ZaiApiLine } from "../provider-settings.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { + API_MODEL_ID_FIELD, + apiModelIdProviderModelShape, + createModelIdAccessor, + createProviderDefinition, +} from "./common.js" // Z AI // https://docs.z.ai/guides/llm/glm-4-32b-0414-128k @@ -561,3 +569,17 @@ export function getZAiModels(apiLine: ZaiApiLine = "international_coding"): Reco ? { ...regionalModels, ...mainlandZAiCodingPlanOnlyModels } : regionalModels } + +export const zaiApiLineSchema = z.enum(["international_coding", "china_coding", "international_api", "china_api"]) +export type ZaiApiLine = z.infer + +export const zaiProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.zai, + modelIdKey: API_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + schema: { + ...apiModelIdProviderModelShape, + zaiApiKey: z.string().optional(), + zaiApiLine: zaiApiLineSchema.optional(), + }, +}) diff --git a/packages/types/src/providers/zoo-gateway.ts b/packages/types/src/providers/zoo-gateway.ts index 8596026441..46402b6649 100644 --- a/packages/types/src/providers/zoo-gateway.ts +++ b/packages/types/src/providers/zoo-gateway.ts @@ -1,4 +1,8 @@ -import type { ModelInfo } from "../model.js" +import { z } from "zod" + +import { type ModelInfo } from "../model.js" +import { providerIdentifiers } from "../provider-identifiers.js" +import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" // Zoo Gateway uses the same model ID format as Vercel AI Gateway (provider/model-name) export const zooGatewayDefaultModelId = "anthropic/claude-sonnet-4" @@ -22,3 +26,17 @@ export const zooGatewayDefaultModelInfo: ModelInfo = { } export const ZOO_GATEWAY_DEFAULT_TEMPERATURE = 0.7 + +export const ZOO_GATEWAY_MODEL_ID_FIELD = "zooGatewayModelId" + +export const zooGatewayProviderDefinition = createProviderDefinition({ + apiProvider: providerIdentifiers.zooGateway, + modelIdKey: ZOO_GATEWAY_MODEL_ID_FIELD, + getModelId: createModelIdAccessor(ZOO_GATEWAY_MODEL_ID_FIELD), + schema: { + ...baseProviderSettingsShape, + zooSessionToken: z.string().optional(), + [ZOO_GATEWAY_MODEL_ID_FIELD]: z.string().optional(), + zooGatewayBaseUrl: z.string().optional(), + }, +}) From 3b0d2811129ff20cba6fabf9f6855755ae922417 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 29 Oct 2026 11:49:27 +0000 Subject: [PATCH 2/2] refactor(types): move provider default model data into provider definitions Each provider definition now declares its own `getDefaultModelId`, mirroring `getModelId`, so per-provider default-model data lives next to the rest of that provider's configuration instead of in a central switch. - Add `getDefaultModelId` to `ProviderDefinition`/`createProviderDefinition` and a shared `NO_DEFAULT_MODEL_ID` constant. - Move every provider's default into its definition; Z.ai keeps its region-dependent logic by reading `zaiApiLine` from settings. - Remove the `getProviderDefaultModelId` switch from `providers/index.ts`. - Re-add `getProviderDefaultModelId(provider, settings)` in `provider-settings.ts`, resolving the definition and falling back to the Anthropic default. - Update webview callers to pass `apiConfiguration` and drop the duplicated Z.ai region logic in `providerModelConfig.ts`. - Extend tests to cover the new accessor and the Z.ai API-line defaults. --- .../src/__tests__/io-intelligence.test.ts | 2 +- packages/types/src/__tests__/nanogpt.test.ts | 2 +- .../__tests__/provider-default-model.test.ts | 56 ++++++-- .../src/__tests__/provider-settings.test.ts | 10 ++ packages/types/src/provider-settings.ts | 9 ++ packages/types/src/providers/anthropic.ts | 1 + packages/types/src/providers/baseten.ts | 1 + packages/types/src/providers/bedrock.ts | 1 + packages/types/src/providers/common.ts | 11 ++ packages/types/src/providers/deepseek.ts | 1 + packages/types/src/providers/fake-ai.ts | 3 + packages/types/src/providers/fireworks.ts | 1 + packages/types/src/providers/friendli.ts | 1 + packages/types/src/providers/gemini-cli.ts | 3 + packages/types/src/providers/gemini.ts | 1 + packages/types/src/providers/index.ts | 121 ------------------ .../types/src/providers/io-intelligence.ts | 1 + packages/types/src/providers/kenari.ts | 1 + packages/types/src/providers/kimi-code.ts | 1 + packages/types/src/providers/litellm.ts | 2 + packages/types/src/providers/lm-studio.ts | 9 +- packages/types/src/providers/mimo.ts | 1 + packages/types/src/providers/minimax.ts | 1 + packages/types/src/providers/mistral.ts | 1 + packages/types/src/providers/moonshot.ts | 1 + packages/types/src/providers/nanogpt.ts | 1 + packages/types/src/providers/ollama.ts | 9 +- packages/types/src/providers/openai-codex.ts | 1 + packages/types/src/providers/openai-native.ts | 2 + packages/types/src/providers/openai.ts | 9 +- packages/types/src/providers/opencode-go.ts | 1 + packages/types/src/providers/openrouter.ts | 1 + packages/types/src/providers/poe.ts | 3 + packages/types/src/providers/qwen-code.ts | 1 + packages/types/src/providers/requesty.ts | 1 + packages/types/src/providers/sambanova.ts | 1 + packages/types/src/providers/unbound.ts | 1 + .../types/src/providers/vercel-ai-gateway.ts | 1 + packages/types/src/providers/vertex.ts | 1 + packages/types/src/providers/vscode-lm.ts | 3 + packages/types/src/providers/xai.ts | 1 + packages/types/src/providers/zai.ts | 24 ++++ packages/types/src/providers/zoo-gateway.ts | 1 + .../settings/utils/providerModelConfig.ts | 10 +- .../components/ui/hooks/useSelectedModel.ts | 18 ++- 45 files changed, 181 insertions(+), 151 deletions(-) diff --git a/packages/types/src/__tests__/io-intelligence.test.ts b/packages/types/src/__tests__/io-intelligence.test.ts index ca0e4a4390..d448ef0ade 100644 --- a/packages/types/src/__tests__/io-intelligence.test.ts +++ b/packages/types/src/__tests__/io-intelligence.test.ts @@ -12,7 +12,7 @@ describe("IO Intelligence shared contract", () => { it("registers the stable dynamic-provider identity and default model", () => { expect(providerIdentifiers.ioIntelligence).toBe("io-intelligence") expect(dynamicProviders).toContain(providerIdentifiers.ioIntelligence) - expect(getProviderDefaultModelId(providerIdentifiers.ioIntelligence)).toBe(ioIntelligenceDefaultModelId) + expect(getProviderDefaultModelId(providerIdentifiers.ioIntelligence, {})).toBe(ioIntelligenceDefaultModelId) }) it("classifies the API key as secret and resolves the configured model", () => { diff --git a/packages/types/src/__tests__/nanogpt.test.ts b/packages/types/src/__tests__/nanogpt.test.ts index 717d05ec59..f400526658 100644 --- a/packages/types/src/__tests__/nanogpt.test.ts +++ b/packages/types/src/__tests__/nanogpt.test.ts @@ -14,7 +14,7 @@ describe("NanoGPT shared contract", () => { it("registers the stable dynamic-provider identity and default model", () => { expect(providerIdentifiers.nanogpt).toBe("nanogpt") expect(dynamicProviders).toContain(providerIdentifiers.nanogpt) - expect(getProviderDefaultModelId(providerIdentifiers.nanogpt)).toBe(nanoGptDefaultModelId) + expect(getProviderDefaultModelId(providerIdentifiers.nanogpt, {})).toBe(nanoGptDefaultModelId) }) it("classifies the API key as secret and resolves missing routing to auto", () => { diff --git a/packages/types/src/__tests__/provider-default-model.test.ts b/packages/types/src/__tests__/provider-default-model.test.ts index 7578391bac..36099cc1d5 100644 --- a/packages/types/src/__tests__/provider-default-model.test.ts +++ b/packages/types/src/__tests__/provider-default-model.test.ts @@ -15,7 +15,7 @@ vi.mock("../provider-identifiers.js", async (importOriginal) => { import { providerIdentifiers } from "../provider-identifiers.js" import { anthropicDefaultModelId, - getProviderDefaultModelId, + getZAiDefaultModelId, internationalZAiDefaultModelId, kimiCodeDefaultModelId, mainlandZAiDefaultModelId, @@ -24,49 +24,79 @@ import { vscodeLlmDefaultModelId, zooGatewayDefaultModelId, } from "../providers/index.js" +import { getProviderDefaultModelId } from "../provider-settings.js" + +const zaiApiLineCases = [ + ["china_coding", "china"], + ["china_api", "china"], + ["international_coding", "international"], + ["international_api", "international"], +] as const describe("getProviderDefaultModelId", () => { it("selects a static default through the canonical provider identifier", () => { - expect(getProviderDefaultModelId(providerIdentifiers.openrouter as ProviderName)).toBe(openRouterDefaultModelId) + expect(getProviderDefaultModelId(providerIdentifiers.openrouter as ProviderName, {})).toBe( + openRouterDefaultModelId, + ) }) it("triangulates static selection with another provider category", () => { - expect(getProviderDefaultModelId(providerIdentifiers.vscodeLm)).toBe(vscodeLlmDefaultModelId) + expect(getProviderDefaultModelId(providerIdentifiers.vscodeLm, {})).toBe(vscodeLlmDefaultModelId) }) it("gives GitHub Copilot the same default as the VS Code LM provider", () => { - expect(getProviderDefaultModelId(providerIdentifiers.githubCopilot)).toBe(vscodeLlmDefaultModelId) + expect(getProviderDefaultModelId(providerIdentifiers.githubCopilot, {})).toBe(vscodeLlmDefaultModelId) }) it("uses the canonical OpenAI Native default model", () => { - expect(getProviderDefaultModelId(providerIdentifiers.openaiNative)).toBe(openAiNativeDefaultModelId) + expect(getProviderDefaultModelId(providerIdentifiers.openaiNative, {})).toBe(openAiNativeDefaultModelId) }) it.each([ [providerIdentifiers.kimiCode, kimiCodeDefaultModelId], [providerIdentifiers.zooGateway, zooGatewayDefaultModelId], ])("preserves the %s default added on main", (provider, expectedModelId) => { - expect(getProviderDefaultModelId(provider)).toBe(expectedModelId) + expect(getProviderDefaultModelId(provider, {})).toBe(expectedModelId) + }) + + it.each(zaiApiLineCases)("resolves the %s Z.ai default through the provider definition", (zaiApiLine, region) => { + const expected = region === "china" ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId + + expect(getProviderDefaultModelId(providerIdentifiers.zai, { zaiApiLine })).toBe(expected) }) - it("preserves region-dependent defaults", () => { - // These defaults currently share the same model ID, so the assertions document - // both branches but cannot detect swapped ternary arms until the IDs diverge. - expect(getProviderDefaultModelId(providerIdentifiers.zai, { isChina: true })).toBe(mainlandZAiDefaultModelId) - expect(getProviderDefaultModelId(providerIdentifiers.zai)).toBe(internationalZAiDefaultModelId) + it("falls back to the international Z.ai default when the API line is unset", () => { + expect(getProviderDefaultModelId(providerIdentifiers.zai, {})).toBe(internationalZAiDefaultModelId) + }) + + describe("Z.ai region mapping", () => { + // Both regional catalogs currently share a default model ID, so inject + // distinct values to prove the mainland/international arms are not swapped. + const distinctDefaults = { china: "test-china-model", international: "test-international-model" } + + it.each(zaiApiLineCases)("maps %s to the %s default", (zaiApiLine, region) => { + expect(getZAiDefaultModelId(zaiApiLine, distinctDefaults)).toBe(distinctDefaults[region]) + }) + + it.each([undefined, null, "bogus"])( + "falls back to the international default for the invalid API line %s", + (zaiApiLine) => { + expect(getZAiDefaultModelId(zaiApiLine, distinctDefaults)).toBe(distinctDefaults.international) + }, + ) }) it.each([providerIdentifiers.openai, providerIdentifiers.ollama, providerIdentifiers.lmstudio])( "returns an empty default for custom or locally selected models from %s", (provider) => { - expect(getProviderDefaultModelId(provider)).toBe("") + expect(getProviderDefaultModelId(provider, {})).toBe("") }, ) it.each([providerIdentifiers.anthropic, providerIdentifiers.geminiCli, providerIdentifiers.fakeAi])( "preserves the Anthropic fallback for %s", (provider) => { - expect(getProviderDefaultModelId(provider)).toBe(anthropicDefaultModelId) + expect(getProviderDefaultModelId(provider, {})).toBe(anthropicDefaultModelId) }, ) }) diff --git a/packages/types/src/__tests__/provider-settings.test.ts b/packages/types/src/__tests__/provider-settings.test.ts index 7d9a64bb91..f318b40e7f 100644 --- a/packages/types/src/__tests__/provider-settings.test.ts +++ b/packages/types/src/__tests__/provider-settings.test.ts @@ -18,6 +18,16 @@ describe("provider settings discriminated union", () => { expect(new Set(registeredProviders).size).toBe(providerNames.length) }) + it.each(providerDefinitionList.map((definition) => definition.apiProvider))( + "exposes a default model accessor for %s", + (apiProvider) => { + const definition = providerDefinitionList.find((candidate) => candidate.apiProvider === apiProvider) + + expect(typeof definition?.getDefaultModelId).toBe("function") + expect(typeof definition?.getDefaultModelId({})).toBe("string") + }, + ) + it.each(providerNames)("accepts the %s provider branch", (apiProvider) => { expect(providerSettingsSchemaDiscriminated.safeParse({ apiProvider }).success).toBe(true) }) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 7ee1f09007..ebb48b041b 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -25,6 +25,7 @@ import { type RetiredProviderIdentifier, } from "./provider-identifiers.js" import { + anthropicDefaultModelId, anthropicModels, basetenModels, bedrockModels, @@ -359,6 +360,14 @@ export function getModelId(settings: ProviderSettings): string | undefined { return undefined } +/** + * Get the provider's default model ID, ignoring any configured model selection. + * Used as a fallback while provider models are still loading. + */ +export function getProviderDefaultModelId(provider: ProviderName, settings: ProviderSettings): string { + return providerDefinitions[provider]?.getDefaultModelId(settings) ?? anthropicDefaultModelId +} + /** * ANTHROPIC_STYLE_PROVIDERS */ diff --git a/packages/types/src/providers/anthropic.ts b/packages/types/src/providers/anthropic.ts index 160f637a4a..ba3c2f820e 100644 --- a/packages/types/src/providers/anthropic.ts +++ b/packages/types/src/providers/anthropic.ts @@ -362,6 +362,7 @@ export const anthropicProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.anthropic, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => anthropicDefaultModelId, schema: { ...apiModelIdProviderModelShape, apiKey: z.string().optional(), diff --git a/packages/types/src/providers/baseten.ts b/packages/types/src/providers/baseten.ts index 43ed965d1c..58070defe8 100644 --- a/packages/types/src/providers/baseten.ts +++ b/packages/types/src/providers/baseten.ts @@ -172,6 +172,7 @@ export const basetenProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.baseten, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => basetenDefaultModelId, schema: { ...apiModelIdProviderModelShape, basetenApiKey: z.string().optional(), diff --git a/packages/types/src/providers/bedrock.ts b/packages/types/src/providers/bedrock.ts index c6041f0b21..ca599cb29a 100644 --- a/packages/types/src/providers/bedrock.ts +++ b/packages/types/src/providers/bedrock.ts @@ -830,6 +830,7 @@ export const bedrockProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.bedrock, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => bedrockDefaultModelId, schema: { ...apiModelIdProviderModelShape, awsAccessKey: z.string().optional(), diff --git a/packages/types/src/providers/common.ts b/packages/types/src/providers/common.ts index 1ea2daf6f4..2f580ab380 100644 --- a/packages/types/src/providers/common.ts +++ b/packages/types/src/providers/common.ts @@ -7,6 +7,12 @@ export const API_PROVIDER_FIELD = "apiProvider" export const SETTINGS_SHAPE_FIELD = "settingsShape" export const API_MODEL_ID_FIELD = "apiModelId" +/** + * Providers whose model is chosen by the user (custom endpoints or locally + * discovered models) have no meaningful default. + */ +export const NO_DEFAULT_MODEL_ID = "" + // Treat a persisted `null` as an unset value. Previously persisted or imported // profiles may store `null` for these fields; converting `null` to `undefined` // before validation keeps the inferred type as `NonNull | undefined` (so @@ -43,6 +49,7 @@ export const apiModelIdProviderModelShape = { type ModelId = string | undefined type UntypedProviderSettings = Record type ProviderModelIdAccessor = (settings: UntypedProviderSettings) => ModelId +type ProviderDefaultModelIdAccessor = (settings: UntypedProviderSettings) => string type ProviderSettingsFromSchema = z.infer> type TypedProviderModelIdAccessor = (settings: ProviderSettingsFromSchema) => ModelId @@ -51,6 +58,8 @@ type ProviderDefinitionInput

getModelId: TypedProviderModelIdAccessor + // Provider-specific default model data lives with the provider definition, mirroring `getModelId`. + getDefaultModelId: ProviderDefaultModelIdAccessor } export type ProviderDefinition = { @@ -59,6 +68,7 @@ export type ProviderDefinition = { modelIdKey?: string schema: z.ZodObject getModelId: ProviderModelIdAccessor + getDefaultModelId: ProviderDefaultModelIdAccessor } export const createModelIdAccessor = @@ -87,5 +97,6 @@ export const createProviderDefinition =

deepSeekDefaultModelId, schema: { ...apiModelIdProviderModelShape, deepSeekBaseUrl: z.string().optional(), diff --git a/packages/types/src/providers/fake-ai.ts b/packages/types/src/providers/fake-ai.ts index f6be6c72ed..0827e58d3b 100644 --- a/packages/types/src/providers/fake-ai.ts +++ b/packages/types/src/providers/fake-ai.ts @@ -1,6 +1,7 @@ import { z } from "zod" import { providerIdentifiers } from "../provider-identifiers.js" +import { anthropicDefaultModelId } from "./anthropic.js" import { API_MODEL_ID_FIELD, apiModelIdProviderModelShape, @@ -12,6 +13,8 @@ export const fakeAiProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.fakeAi, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + // Fake AI has no catalog of its own; it keeps the Anthropic fallback default. + getDefaultModelId: () => anthropicDefaultModelId, schema: { ...apiModelIdProviderModelShape, fakeAi: z.unknown().optional(), diff --git a/packages/types/src/providers/fireworks.ts b/packages/types/src/providers/fireworks.ts index 9c4a7c6834..819ee20fd0 100644 --- a/packages/types/src/providers/fireworks.ts +++ b/packages/types/src/providers/fireworks.ts @@ -334,6 +334,7 @@ export const fireworksProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.fireworks, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => fireworksDefaultModelId, schema: { ...apiModelIdProviderModelShape, fireworksApiKey: z.string().optional(), diff --git a/packages/types/src/providers/friendli.ts b/packages/types/src/providers/friendli.ts index 85d3eb114a..3b98f61bd3 100644 --- a/packages/types/src/providers/friendli.ts +++ b/packages/types/src/providers/friendli.ts @@ -76,6 +76,7 @@ export const friendliProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.friendli, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => friendliDefaultModelId, schema: { ...apiModelIdProviderModelShape, friendliApiKey: z.string().optional(), diff --git a/packages/types/src/providers/gemini-cli.ts b/packages/types/src/providers/gemini-cli.ts index 29cd66d0ec..2fb7deecc9 100644 --- a/packages/types/src/providers/gemini-cli.ts +++ b/packages/types/src/providers/gemini-cli.ts @@ -1,6 +1,7 @@ import { z } from "zod" import { providerIdentifiers } from "../provider-identifiers.js" +import { anthropicDefaultModelId } from "./anthropic.js" import { API_MODEL_ID_FIELD, apiModelIdProviderModelShape, @@ -12,6 +13,8 @@ export const geminiCliProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.geminiCli, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + // Gemini CLI has no catalog of its own; it keeps the Anthropic fallback default. + getDefaultModelId: () => anthropicDefaultModelId, schema: { ...apiModelIdProviderModelShape, geminiCliOAuthPath: z.string().optional(), diff --git a/packages/types/src/providers/gemini.ts b/packages/types/src/providers/gemini.ts index 4c1a99c929..3048d7d697 100644 --- a/packages/types/src/providers/gemini.ts +++ b/packages/types/src/providers/gemini.ts @@ -388,6 +388,7 @@ export const geminiProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.gemini, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => geminiDefaultModelId, schema: { ...apiModelIdProviderModelShape, geminiApiKey: z.string().optional(), diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index df50085fde..63c1585fdf 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -40,38 +40,6 @@ export * from "./zoo-gateway.js" export type { ProviderDefinition } from "./common.js" -import { anthropicDefaultModelId } from "./anthropic.js" -import { basetenDefaultModelId } from "./baseten.js" -import { bedrockDefaultModelId } from "./bedrock.js" -import { deepSeekDefaultModelId } from "./deepseek.js" -import { fireworksDefaultModelId } from "./fireworks.js" -import { friendliDefaultModelId } from "./friendli.js" -import { geminiDefaultModelId } from "./gemini.js" -import { litellmDefaultModelId } from "./lite-llm.js" -import { mistralDefaultModelId } from "./mistral.js" -import { moonshotDefaultModelId } from "./moonshot.js" -import { openAiNativeDefaultModelId } from "./openai.js" -import { openAiCodexDefaultModelId } from "./openai-codex.js" -import { openRouterDefaultModelId } from "./openrouter.js" -import { poeDefaultModelId } from "./poe.js" -import { qwenCodeDefaultModelId } from "./qwen-code.js" -import { requestyDefaultModelId } from "./requesty.js" -import { sambaNovaDefaultModelId } from "./sambanova.js" -import { unboundDefaultModelId } from "./unbound.js" -import { vertexDefaultModelId } from "./vertex.js" -import { vscodeLlmDefaultModelId } from "./vscode-llm.js" -import { xaiDefaultModelId } from "./xai.js" -import { vercelAiGatewayDefaultModelId } from "./vercel-ai-gateway.js" -import { opencodeGoDefaultModelId } from "./opencode-go.js" -import { kenariDefaultModelId } from "./kenari.js" -import { ioIntelligenceDefaultModelId } from "./io-intelligence.js" -import { nanoGptDefaultModelId } from "./nanogpt.js" -import { kimiCodeDefaultModelId } from "./kimi-code.js" -import { internationalZAiDefaultModelId, mainlandZAiDefaultModelId } from "./zai.js" -import { minimaxDefaultModelId } from "./minimax.js" -import { mimoDefaultModelId } from "./mimo.js" -import { zooGatewayDefaultModelId } from "./zoo-gateway.js" - import { anthropicProviderDefinition } from "./anthropic.js" import { basetenProviderDefinition } from "./baseten.js" import { bedrockProviderDefinition } from "./bedrock.js" @@ -111,95 +79,6 @@ import { zooGatewayProviderDefinition } from "./zoo-gateway.js" import type { ProviderDefinition } from "./common.js" -// Import the ProviderName type from provider-settings to avoid duplication -import type { ProviderName } from "../provider-settings.js" -import { providerIdentifiers } from "../provider-identifiers.js" - -const NO_DEFAULT_MODEL_ID = "" - -/** - * Get the default model ID for a given provider. - * This function returns only the provider's default model ID, without considering user configuration. - * Used as a fallback when provider models are still loading. - */ -export function getProviderDefaultModelId( - provider: ProviderName, - options: { isChina?: boolean } = { isChina: false }, -): string { - switch (provider) { - case providerIdentifiers.openrouter: - return openRouterDefaultModelId - case providerIdentifiers.requesty: - return requestyDefaultModelId - case providerIdentifiers.litellm: - return litellmDefaultModelId - case providerIdentifiers.xai: - return xaiDefaultModelId - case providerIdentifiers.baseten: - return basetenDefaultModelId - case providerIdentifiers.bedrock: - return bedrockDefaultModelId - case providerIdentifiers.vertex: - return vertexDefaultModelId - case providerIdentifiers.gemini: - return geminiDefaultModelId - case providerIdentifiers.deepseek: - return deepSeekDefaultModelId - case providerIdentifiers.moonshot: - return moonshotDefaultModelId - case providerIdentifiers.minimax: - return minimaxDefaultModelId - case providerIdentifiers.mimo: - return mimoDefaultModelId - case providerIdentifiers.zai: - return options?.isChina ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId - case providerIdentifiers.openaiNative: - return openAiNativeDefaultModelId - case providerIdentifiers.openaiCodex: - return openAiCodexDefaultModelId - case providerIdentifiers.mistral: - return mistralDefaultModelId - case providerIdentifiers.openai: - case providerIdentifiers.ollama: - case providerIdentifiers.lmstudio: - return NO_DEFAULT_MODEL_ID - case providerIdentifiers.vscodeLm: - case providerIdentifiers.githubCopilot: - return vscodeLlmDefaultModelId - case providerIdentifiers.sambanova: - return sambaNovaDefaultModelId - case providerIdentifiers.fireworks: - return fireworksDefaultModelId - case providerIdentifiers.friendli: - return friendliDefaultModelId - case providerIdentifiers.qwenCode: - return qwenCodeDefaultModelId - case providerIdentifiers.poe: - return poeDefaultModelId - case providerIdentifiers.unbound: - return unboundDefaultModelId - case providerIdentifiers.vercelAiGateway: - return vercelAiGatewayDefaultModelId - case providerIdentifiers.opencodeGo: - return opencodeGoDefaultModelId - case providerIdentifiers.kenari: - return kenariDefaultModelId - case providerIdentifiers.ioIntelligence: - return ioIntelligenceDefaultModelId - case providerIdentifiers.nanogpt: - return nanoGptDefaultModelId - case providerIdentifiers.kimiCode: - return kimiCodeDefaultModelId - case providerIdentifiers.zooGateway: - return zooGatewayDefaultModelId - case providerIdentifiers.anthropic: - case providerIdentifiers.geminiCli: - case providerIdentifiers.fakeAi: - default: - return anthropicDefaultModelId - } -} - export const providerDefinitionList = [ anthropicProviderDefinition, openRouterProviderDefinition, diff --git a/packages/types/src/providers/io-intelligence.ts b/packages/types/src/providers/io-intelligence.ts index bfdc46b39c..74fe2e7b46 100644 --- a/packages/types/src/providers/io-intelligence.ts +++ b/packages/types/src/providers/io-intelligence.ts @@ -22,6 +22,7 @@ export const ioIntelligenceProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.ioIntelligence, modelIdKey: IO_INTELLIGENCE_MODEL_ID_FIELD, getModelId: createModelIdAccessor(IO_INTELLIGENCE_MODEL_ID_FIELD), + getDefaultModelId: () => ioIntelligenceDefaultModelId, schema: { ...baseProviderSettingsShape, ioIntelligenceApiKey: z.string().optional(), diff --git a/packages/types/src/providers/kenari.ts b/packages/types/src/providers/kenari.ts index 3142471dc3..d781913d85 100644 --- a/packages/types/src/providers/kenari.ts +++ b/packages/types/src/providers/kenari.ts @@ -35,6 +35,7 @@ export const kenariProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.kenari, modelIdKey: KENARI_MODEL_ID_FIELD, getModelId: createModelIdAccessor(KENARI_MODEL_ID_FIELD), + getDefaultModelId: () => kenariDefaultModelId, schema: { ...baseProviderSettingsShape, kenariApiKey: z.string().optional(), diff --git a/packages/types/src/providers/kimi-code.ts b/packages/types/src/providers/kimi-code.ts index 899b520ef0..254fa2928d 100644 --- a/packages/types/src/providers/kimi-code.ts +++ b/packages/types/src/providers/kimi-code.ts @@ -45,6 +45,7 @@ export const kimiCodeProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.kimiCode, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => kimiCodeDefaultModelId, schema: { ...apiModelIdProviderModelShape, kimiCodeAuthMethod: kimiCodeAuthMethodSchema.optional(), diff --git a/packages/types/src/providers/litellm.ts b/packages/types/src/providers/litellm.ts index 018cbdecdd..adbb751e1b 100644 --- a/packages/types/src/providers/litellm.ts +++ b/packages/types/src/providers/litellm.ts @@ -2,6 +2,7 @@ import { z } from "zod" import { providerIdentifiers } from "../provider-identifiers.js" import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" +import { litellmDefaultModelId } from "./lite-llm.js" export const LITELLM_MODEL_ID_FIELD = "litellmModelId" @@ -9,6 +10,7 @@ export const litellmProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.litellm, modelIdKey: LITELLM_MODEL_ID_FIELD, getModelId: createModelIdAccessor(LITELLM_MODEL_ID_FIELD), + getDefaultModelId: () => litellmDefaultModelId, schema: { ...baseProviderSettingsShape, litellmBaseUrl: z.string().optional(), diff --git a/packages/types/src/providers/lm-studio.ts b/packages/types/src/providers/lm-studio.ts index 1c0f384ad3..7dea8afacc 100644 --- a/packages/types/src/providers/lm-studio.ts +++ b/packages/types/src/providers/lm-studio.ts @@ -2,7 +2,12 @@ import { z } from "zod" import { type ModelInfo } from "../model.js" import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" +import { + baseProviderSettingsShape, + createModelIdAccessor, + createProviderDefinition, + NO_DEFAULT_MODEL_ID, +} from "./common.js" export const lmStudioModelsMessageTypes = ["requestLmStudioModels", "lmStudioModels"] as const @@ -35,6 +40,8 @@ export const lmStudioProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.lmstudio, modelIdKey: LM_STUDIO_MODEL_ID_FIELD, getModelId: createModelIdAccessor(LM_STUDIO_MODEL_ID_FIELD), + // LM Studio models are discovered from the local server, so there is no default. + getDefaultModelId: () => NO_DEFAULT_MODEL_ID, schema: { ...baseProviderSettingsShape, [LM_STUDIO_MODEL_ID_FIELD]: z.string().optional(), diff --git a/packages/types/src/providers/mimo.ts b/packages/types/src/providers/mimo.ts index 6233a32e90..9279c8b1cf 100644 --- a/packages/types/src/providers/mimo.ts +++ b/packages/types/src/providers/mimo.ts @@ -74,6 +74,7 @@ export const mimoProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.mimo, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => mimoDefaultModelId, schema: { ...apiModelIdProviderModelShape, mimoBaseUrl: z diff --git a/packages/types/src/providers/minimax.ts b/packages/types/src/providers/minimax.ts index 30be640b10..4dcf49ed10 100644 --- a/packages/types/src/providers/minimax.ts +++ b/packages/types/src/providers/minimax.ts @@ -163,6 +163,7 @@ export const minimaxProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.minimax, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => minimaxDefaultModelId, schema: { ...apiModelIdProviderModelShape, minimaxBaseUrl: z diff --git a/packages/types/src/providers/mistral.ts b/packages/types/src/providers/mistral.ts index 0d6f7411bf..36e281aeb1 100644 --- a/packages/types/src/providers/mistral.ts +++ b/packages/types/src/providers/mistral.ts @@ -95,6 +95,7 @@ export const mistralProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.mistral, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => mistralDefaultModelId, schema: { ...apiModelIdProviderModelShape, mistralApiKey: z.string().optional(), diff --git a/packages/types/src/providers/moonshot.ts b/packages/types/src/providers/moonshot.ts index bc0b2b5af0..27e2b3e7a8 100644 --- a/packages/types/src/providers/moonshot.ts +++ b/packages/types/src/providers/moonshot.ts @@ -134,6 +134,7 @@ export const moonshotProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.moonshot, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => moonshotDefaultModelId, schema: { ...apiModelIdProviderModelShape, moonshotBaseUrl: z diff --git a/packages/types/src/providers/nanogpt.ts b/packages/types/src/providers/nanogpt.ts index a456e1b5f1..97c185b913 100644 --- a/packages/types/src/providers/nanogpt.ts +++ b/packages/types/src/providers/nanogpt.ts @@ -71,6 +71,7 @@ export const nanoGptProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.nanogpt, modelIdKey: NANOGPT_MODEL_ID_FIELD, getModelId: createModelIdAccessor(NANOGPT_MODEL_ID_FIELD), + getDefaultModelId: () => nanoGptDefaultModelId, schema: { ...baseProviderSettingsShape, nanoGptApiKey: z.string().optional(), diff --git a/packages/types/src/providers/ollama.ts b/packages/types/src/providers/ollama.ts index cdb3ab996b..88e1d0dee1 100644 --- a/packages/types/src/providers/ollama.ts +++ b/packages/types/src/providers/ollama.ts @@ -2,7 +2,12 @@ import { z } from "zod" import { type ModelInfo } from "../model.js" import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" +import { + baseProviderSettingsShape, + createModelIdAccessor, + createProviderDefinition, + NO_DEFAULT_MODEL_ID, +} from "./common.js" // Ollama // https://ollama.com/models @@ -33,6 +38,8 @@ export const ollamaProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.ollama, modelIdKey: OLLAMA_MODEL_ID_FIELD, getModelId: createModelIdAccessor(OLLAMA_MODEL_ID_FIELD), + // Ollama models are discovered from the local server, so there is no default. + getDefaultModelId: () => NO_DEFAULT_MODEL_ID, schema: { ...baseProviderSettingsShape, [OLLAMA_MODEL_ID_FIELD]: z.string().optional(), diff --git a/packages/types/src/providers/openai-codex.ts b/packages/types/src/providers/openai-codex.ts index 02a2a7d0d5..58344cbfbc 100644 --- a/packages/types/src/providers/openai-codex.ts +++ b/packages/types/src/providers/openai-codex.ts @@ -364,6 +364,7 @@ export const openAiCodexProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.openaiCodex, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => openAiCodexDefaultModelId, schema: { ...apiModelIdProviderModelShape, // Codex "Fast" mode maps to the Responses API priority service tier. diff --git a/packages/types/src/providers/openai-native.ts b/packages/types/src/providers/openai-native.ts index 857a51dabe..cffd30225e 100644 --- a/packages/types/src/providers/openai-native.ts +++ b/packages/types/src/providers/openai-native.ts @@ -8,11 +8,13 @@ import { createModelIdAccessor, createProviderDefinition, } from "./common.js" +import { openAiNativeDefaultModelId } from "./openai.js" export const openAiNativeProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.openaiNative, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => openAiNativeDefaultModelId, schema: { ...apiModelIdProviderModelShape, openAiNativeApiKey: z.string().optional(), diff --git a/packages/types/src/providers/openai.ts b/packages/types/src/providers/openai.ts index 05e278df20..cb50a7d40a 100644 --- a/packages/types/src/providers/openai.ts +++ b/packages/types/src/providers/openai.ts @@ -2,7 +2,12 @@ import { z } from "zod" import { modelInfoSchema, type ModelInfo } from "../model.js" import { providerIdentifiers } from "../provider-identifiers.js" -import { baseProviderSettingsShape, createModelIdAccessor, createProviderDefinition } from "./common.js" +import { + baseProviderSettingsShape, + createModelIdAccessor, + createProviderDefinition, + NO_DEFAULT_MODEL_ID, +} from "./common.js" // https://openai.com/api/pricing/ export const openAiModelsMessageTypes = ["requestOpenAiModels", "openAiModels"] as const @@ -1063,6 +1068,8 @@ export const openAiProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.openai, modelIdKey: OPEN_AI_MODEL_ID_FIELD, getModelId: createModelIdAccessor(OPEN_AI_MODEL_ID_FIELD), + // OpenAI-compatible endpoints are fully user-configured, so there is no default. + getDefaultModelId: () => NO_DEFAULT_MODEL_ID, schema: { ...baseProviderSettingsShape, openAiBaseUrl: z.string().optional(), diff --git a/packages/types/src/providers/opencode-go.ts b/packages/types/src/providers/opencode-go.ts index faadd1739d..ce037c92d2 100644 --- a/packages/types/src/providers/opencode-go.ts +++ b/packages/types/src/providers/opencode-go.ts @@ -833,6 +833,7 @@ export const opencodeGoProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.opencodeGo, modelIdKey: OPENCODE_GO_MODEL_ID_FIELD, getModelId: createModelIdAccessor(OPENCODE_GO_MODEL_ID_FIELD), + getDefaultModelId: () => opencodeGoDefaultModelId, schema: { ...baseProviderSettingsShape, opencodeGoApiKey: z.string().optional(), diff --git a/packages/types/src/providers/openrouter.ts b/packages/types/src/providers/openrouter.ts index 8480ee6d63..936556aa8c 100644 --- a/packages/types/src/providers/openrouter.ts +++ b/packages/types/src/providers/openrouter.ts @@ -111,6 +111,7 @@ export const openRouterProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.openrouter, modelIdKey: OPEN_ROUTER_MODEL_ID_FIELD, getModelId: createModelIdAccessor(OPEN_ROUTER_MODEL_ID_FIELD), + getDefaultModelId: () => openRouterDefaultModelId, schema: { ...baseProviderSettingsShape, openRouterApiKey: z.string().optional(), diff --git a/packages/types/src/providers/poe.ts b/packages/types/src/providers/poe.ts index f7f2587be4..821d85c6a2 100644 --- a/packages/types/src/providers/poe.ts +++ b/packages/types/src/providers/poe.ts @@ -8,6 +8,8 @@ import { createProviderDefinition, } from "./common.js" +import { poeDefaultModelId } from "ai-sdk-provider-poe/code" + export { poeDefaultModelId, POE_DEFAULT_BASE_URL, getPoeDefaultModelInfo } from "ai-sdk-provider-poe/code" export type { PoeDefaultModelInfo } from "ai-sdk-provider-poe/code" @@ -15,6 +17,7 @@ export const poeProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.poe, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => poeDefaultModelId, schema: { ...apiModelIdProviderModelShape, poeApiKey: z.string().optional(), diff --git a/packages/types/src/providers/qwen-code.ts b/packages/types/src/providers/qwen-code.ts index b632d6e7c5..baa4114f90 100644 --- a/packages/types/src/providers/qwen-code.ts +++ b/packages/types/src/providers/qwen-code.ts @@ -42,6 +42,7 @@ export const qwenCodeProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.qwenCode, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => qwenCodeDefaultModelId, schema: { ...apiModelIdProviderModelShape, qwenCodeOauthPath: z.string().optional(), diff --git a/packages/types/src/providers/requesty.ts b/packages/types/src/providers/requesty.ts index 676553797f..65b3aa0232 100644 --- a/packages/types/src/providers/requesty.ts +++ b/packages/types/src/providers/requesty.ts @@ -27,6 +27,7 @@ export const requestyProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.requesty, modelIdKey: REQUESTY_MODEL_ID_FIELD, getModelId: createModelIdAccessor(REQUESTY_MODEL_ID_FIELD), + getDefaultModelId: () => requestyDefaultModelId, schema: { ...baseProviderSettingsShape, requestyBaseUrl: z.string().optional(), diff --git a/packages/types/src/providers/sambanova.ts b/packages/types/src/providers/sambanova.ts index 758b696f39..cb9e22c09e 100644 --- a/packages/types/src/providers/sambanova.ts +++ b/packages/types/src/providers/sambanova.ts @@ -102,6 +102,7 @@ export const sambaNovaProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.sambanova, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => sambaNovaDefaultModelId, schema: { ...apiModelIdProviderModelShape, sambaNovaApiKey: z.string().optional(), diff --git a/packages/types/src/providers/unbound.ts b/packages/types/src/providers/unbound.ts index 432753f2fb..3158e23c08 100644 --- a/packages/types/src/providers/unbound.ts +++ b/packages/types/src/providers/unbound.ts @@ -25,6 +25,7 @@ export const unboundProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.unbound, modelIdKey: UNBOUND_MODEL_ID_FIELD, getModelId: createModelIdAccessor(UNBOUND_MODEL_ID_FIELD), + getDefaultModelId: () => unboundDefaultModelId, schema: { ...baseProviderSettingsShape, unboundApiKey: z.string().optional(), diff --git a/packages/types/src/providers/vercel-ai-gateway.ts b/packages/types/src/providers/vercel-ai-gateway.ts index 0f28869277..08bd43ca9a 100644 --- a/packages/types/src/providers/vercel-ai-gateway.ts +++ b/packages/types/src/providers/vercel-ai-gateway.ts @@ -133,6 +133,7 @@ export const vercelAiGatewayProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.vercelAiGateway, modelIdKey: VERCEL_AI_GATEWAY_MODEL_ID_FIELD, getModelId: createModelIdAccessor(VERCEL_AI_GATEWAY_MODEL_ID_FIELD), + getDefaultModelId: () => vercelAiGatewayDefaultModelId, schema: { ...baseProviderSettingsShape, vercelAiGatewayApiKey: z.string().optional(), diff --git a/packages/types/src/providers/vertex.ts b/packages/types/src/providers/vertex.ts index df10df5a75..6b1fa5e3ac 100644 --- a/packages/types/src/providers/vertex.ts +++ b/packages/types/src/providers/vertex.ts @@ -826,6 +826,7 @@ export const vertexProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.vertex, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => vertexDefaultModelId, schema: { ...apiModelIdProviderModelShape, vertexKeyFile: z.string().optional(), diff --git a/packages/types/src/providers/vscode-lm.ts b/packages/types/src/providers/vscode-lm.ts index f666e6c8b3..6d0624fbb5 100644 --- a/packages/types/src/providers/vscode-lm.ts +++ b/packages/types/src/providers/vscode-lm.ts @@ -2,6 +2,7 @@ import { z } from "zod" import { providerIdentifiers } from "../provider-identifiers.js" import { baseProviderSettingsShape, createProviderDefinition } from "./common.js" +import { vscodeLlmDefaultModelId } from "./vscode-llm.js" const schema = { ...baseProviderSettingsShape, @@ -18,11 +19,13 @@ const schema = { export const vsCodeLmProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.vscodeLm, getModelId: (settings) => settings.vsCodeLmModelSelector?.id, + getDefaultModelId: () => vscodeLlmDefaultModelId, schema, }) export const githubCopilotProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.githubCopilot, getModelId: (settings) => settings.vsCodeLmModelSelector?.id, + getDefaultModelId: () => vscodeLlmDefaultModelId, schema, }) diff --git a/packages/types/src/providers/xai.ts b/packages/types/src/providers/xai.ts index 7c19ac8ffe..1fa6f5529a 100644 --- a/packages/types/src/providers/xai.ts +++ b/packages/types/src/providers/xai.ts @@ -173,6 +173,7 @@ export const xaiProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.xai, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + getDefaultModelId: () => xaiDefaultModelId, schema: { ...apiModelIdProviderModelShape, xaiApiKey: z.string().optional(), diff --git a/packages/types/src/providers/zai.ts b/packages/types/src/providers/zai.ts index d3b88bb027..a94f57e429 100644 --- a/packages/types/src/providers/zai.ts +++ b/packages/types/src/providers/zai.ts @@ -573,10 +573,34 @@ export function getZAiModels(apiLine: ZaiApiLine = "international_coding"): Reco export const zaiApiLineSchema = z.enum(["international_coding", "china_coding", "international_api", "china_api"]) export type ZaiApiLine = z.infer +export type ZaiDefaultModelIds = { + readonly china: string + readonly international: string +} + +const zaiDefaultModelIds: ZaiDefaultModelIds = { + china: mainlandZAiDefaultModelId, + international: internationalZAiDefaultModelId, +} + +/** + * Resolve the default model for a Z.ai API line. Both regional catalogs currently + * share a default model ID, so the regional defaults are injectable to let tests + * prove the mainland/international mapping is not inverted. + */ +export function getZAiDefaultModelId(zaiApiLine: unknown, defaults: ZaiDefaultModelIds = zaiDefaultModelIds): string { + const parsedApiLine = zaiApiLineSchema.safeParse(zaiApiLine) + const apiLine = parsedApiLine.success ? parsedApiLine.data : "international_coding" + return zaiApiLineConfigs[apiLine].isChina ? defaults.china : defaults.international +} + export const zaiProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.zai, modelIdKey: API_MODEL_ID_FIELD, getModelId: createModelIdAccessor(API_MODEL_ID_FIELD), + // Z.ai serves separate model catalogs for mainland China and international + // endpoints, so the default depends on the configured API line. + getDefaultModelId: (settings) => getZAiDefaultModelId(settings.zaiApiLine), schema: { ...apiModelIdProviderModelShape, zaiApiKey: z.string().optional(), diff --git a/packages/types/src/providers/zoo-gateway.ts b/packages/types/src/providers/zoo-gateway.ts index 46402b6649..28d99547e0 100644 --- a/packages/types/src/providers/zoo-gateway.ts +++ b/packages/types/src/providers/zoo-gateway.ts @@ -33,6 +33,7 @@ export const zooGatewayProviderDefinition = createProviderDefinition({ apiProvider: providerIdentifiers.zooGateway, modelIdKey: ZOO_GATEWAY_MODEL_ID_FIELD, getModelId: createModelIdAccessor(ZOO_GATEWAY_MODEL_ID_FIELD), + getDefaultModelId: () => zooGatewayDefaultModelId, schema: { ...baseProviderSettingsShape, zooSessionToken: z.string().optional(), diff --git a/webview-ui/src/components/settings/utils/providerModelConfig.ts b/webview-ui/src/components/settings/utils/providerModelConfig.ts index 43d0ee614e..1bda52cf6f 100644 --- a/webview-ui/src/components/settings/utils/providerModelConfig.ts +++ b/webview-ui/src/components/settings/utils/providerModelConfig.ts @@ -16,7 +16,6 @@ import { xaiDefaultModelId, sambaNovaDefaultModelId, internationalZAiDefaultModelId, - mainlandZAiDefaultModelId, fireworksDefaultModelId, friendliDefaultModelId, minimaxDefaultModelId, @@ -32,8 +31,8 @@ import { ioIntelligenceDefaultModelId, nanoGptDefaultModelId, zooGatewayDefaultModelId, - zaiApiLineConfigs, getZAiModels, + getProviderDefaultModelId, } from "@roo-code/types" import { MODELS_BY_PROVIDER } from "../constants" @@ -99,10 +98,9 @@ export const getProviderServiceConfig = (provider: ProviderName): ProviderServic } export const getDefaultModelIdForProvider = (provider: ProviderName, apiConfiguration?: ProviderSettings): string => { - // Handle Z.ai's China/International entrypoint distinction - if (provider === providerIdentifiers.zai && apiConfiguration) { - const apiLine = apiConfiguration.zaiApiLine ?? "international_coding" - return zaiApiLineConfigs[apiLine].isChina ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId + // Z.ai's default depends on the configured China/International API line. + if (provider === providerIdentifiers.zai) { + return getProviderDefaultModelId(provider, apiConfiguration ?? {}) } return PROVIDER_DEFAULT_MODEL_IDS[provider] ?? "" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 32d2392a63..9222e9ca9f 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -21,7 +21,6 @@ import { openAiCodexModels, sambaNovaModels, getZAiModels, - zaiApiLineConfigs, fireworksModels, friendliModels, basetenModels, @@ -162,10 +161,18 @@ export const useSelectedModel = (apiConfiguration?: ProviderSettings) => { }) : activeProvider === providerIdentifiers.kimiCode && apiConfiguration ? { - id: apiConfiguration.apiModelId || getProviderDefaultModelId(providerIdentifiers.kimiCode), + id: + apiConfiguration.apiModelId || + getProviderDefaultModelId(providerIdentifiers.kimiCode, apiConfiguration), info: kimiCodeDefaultModelInfo, } - : { id: getProviderDefaultModelId(activeProvider ?? providerIdentifiers.openrouter), info: undefined } + : { + id: getProviderDefaultModelId( + activeProvider ?? providerIdentifiers.openrouter, + apiConfiguration ?? {}, + ), + info: undefined, + } return { provider, @@ -206,7 +213,7 @@ function getSelectedModel({ // the `undefined` case are used to show the invalid selection to prevent // users from seeing the default model if their selection is invalid // this gives a better UX than showing the default model - const defaultModelId = getProviderDefaultModelId(provider) + const defaultModelId = getProviderDefaultModelId(provider, apiConfiguration) switch (provider) { case providerIdentifiers.openrouter: { const id = getValidatedModelId( @@ -393,9 +400,8 @@ function getSelectedModel({ } case providerIdentifiers.zai: { const apiLine = apiConfiguration.zaiApiLine ?? "international_coding" - const isChina = zaiApiLineConfigs[apiLine].isChina const models = getZAiModels(apiLine) - const defaultModelId = getProviderDefaultModelId(provider, { isChina }) + const defaultModelId = getProviderDefaultModelId(provider, apiConfiguration) const configuredId = apiConfiguration.apiModelId if (configuredId) { return { id: configuredId, info: models[configuredId] ?? openAiModelInfoSaneDefaults }