From c21aa230e3d71ca7eaadf3acfc2a8622c129bc6c Mon Sep 17 00:00:00 2001 From: Chris Estreich Date: Thu, 8 May 2025 23:52:18 -0700 Subject: [PATCH] Get rid of `ApiConfiguration` type alias, rename `ApiConfigMeta` to `ProviderSettingsEntry` (#3380) --- e2e/package-lock.json | 2 +- e2e/package.json | 2 +- evals/config/eslint/package.json | 1 - evals/package.json | 2 +- evals/packages/types/src/roo-code.ts | 291 +++++++++++++++--- evals/pnpm-lock.yaml | 73 ++--- package-lock.json | 4 +- package.json | 4 +- src/api/index.ts | 4 +- src/core/config/ProviderSettingsManager.ts | 4 +- src/core/task/Task.ts | 6 +- src/core/task/__tests__/Task.test.ts | 4 +- src/core/webview/ClineProvider.ts | 18 +- .../webview/__tests__/ClineProvider.test.ts | 10 +- src/core/webview/webviewMessageHandler.ts | 7 +- src/schemas/index.ts | 158 +++------- src/shared/ExtensionMessage.ts | 10 +- src/shared/WebviewMessage.ts | 4 +- .../__tests__/checkExistApiConfig.test.ts | 12 +- src/shared/api.ts | 4 +- src/utils/__tests__/enhance-prompt.test.ts | 8 +- src/utils/single-completion-handler.ts | 4 +- .../chat/__tests__/TaskHeader.test.tsx | 4 +- .../components/settings/ApiConfigManager.tsx | 4 +- .../src/components/settings/ApiOptions.tsx | 10 +- .../settings/PromptCachingControl.tsx | 6 +- .../components/settings/ReasoningEffort.tsx | 6 +- .../src/components/settings/SettingsView.tsx | 4 +- .../components/settings/ThinkingBudget.tsx | 6 +- .../settings/__tests__/ApiOptions.test.tsx | 4 +- .../settings/providers/Anthropic.tsx | 10 +- .../components/settings/providers/Bedrock.tsx | 10 +- .../settings/providers/BedrockCustomArn.tsx | 6 +- .../components/settings/providers/Chutes.tsx | 10 +- .../settings/providers/DeepSeek.tsx | 10 +- .../components/settings/providers/Gemini.tsx | 10 +- .../components/settings/providers/Glama.tsx | 10 +- .../components/settings/providers/Groq.tsx | 10 +- .../settings/providers/LMStudio.tsx | 10 +- .../components/settings/providers/LiteLLM.tsx | 11 +- .../components/settings/providers/Mistral.tsx | 10 +- .../components/settings/providers/Ollama.tsx | 10 +- .../components/settings/providers/OpenAI.tsx | 10 +- .../settings/providers/OpenAICompatible.tsx | 10 +- .../settings/providers/OpenRouter.tsx | 10 +- .../settings/providers/Requesty.tsx | 10 +- .../components/settings/providers/Unbound.tsx | 10 +- .../settings/providers/VSCodeLM.tsx | 10 +- .../components/settings/providers/Vertex.tsx | 10 +- .../src/components/settings/providers/XAI.tsx | 10 +- .../components/ui/hooks/useSelectedModel.ts | 6 +- .../src/context/ExtensionStateContext.tsx | 16 +- .../__tests__/ExtensionStateContext.test.tsx | 10 +- webview-ui/src/utils/validate.ts | 6 +- 54 files changed, 501 insertions(+), 410 deletions(-) diff --git a/e2e/package-lock.json b/e2e/package-lock.json index bcee0b2676..e7f75013fd 100644 --- a/e2e/package-lock.json +++ b/e2e/package-lock.json @@ -12,7 +12,7 @@ "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.0", "mocha": "^11.1.0", - "typescript": "^5.4.5" + "typescript": "5.8.3" } }, "node_modules/@bcoe/v8-coverage": { diff --git a/e2e/package.json b/e2e/package.json index a8007b1c4b..1acec6bba5 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -16,6 +16,6 @@ "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.0", "mocha": "^11.1.0", - "typescript": "^5.4.5" + "typescript": "5.8.3" } } diff --git a/evals/config/eslint/package.json b/evals/config/eslint/package.json index 3b84b039de..b706de1d95 100644 --- a/evals/config/eslint/package.json +++ b/evals/config/eslint/package.json @@ -16,7 +16,6 @@ "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-turbo": "^2.4.4", "globals": "^16.0.0", - "typescript": "^5", "typescript-eslint": "^8.26.0" } } diff --git a/evals/package.json b/evals/package.json index 2e7c21d977..92c4ab99cd 100644 --- a/evals/package.json +++ b/evals/package.json @@ -20,7 +20,7 @@ "prettier": "^3.5.3", "tsx": "^4.19.4", "turbo": "^2.5.2", - "typescript": "^5.8.3", + "typescript": "5.8.3", "typescript-eslint": "^8.31.1" } } diff --git a/evals/packages/types/src/roo-code.ts b/evals/packages/types/src/roo-code.ts index 312040cf09..32b54c4c81 100644 --- a/evals/packages/types/src/roo-code.ts +++ b/evals/packages/types/src/roo-code.ts @@ -128,18 +128,6 @@ export const modelInfoSchema = z.object({ export type ModelInfo = z.infer -/** - * ApiConfigMeta - */ - -export const apiConfigMetaSchema = z.object({ - id: z.string(), - name: z.string(), - apiProvider: providerNamesSchema.optional(), -}) - -export type ApiConfigMeta = z.infer - /** * HistoryItem */ @@ -329,27 +317,56 @@ export type Experiments = z.infer // eslint-disable-next-line @typescript-eslint/no-unused-vars type _AssertExperiments = AssertEqual>> +/** + * ProviderSettingsEntry + */ + +export const providerSettingsEntrySchema = z.object({ + id: z.string(), + name: z.string(), + apiProvider: providerNamesSchema.optional(), +}) + +export type ProviderSettingsEntry = z.infer + /** * ProviderSettings */ -export const providerSettingsSchema = z.object({ - apiProvider: providerNamesSchema.optional(), - // Anthropic +const genericProviderSettingsSchema = z.object({ + includeMaxTokens: z.boolean().optional(), + reasoningEffort: reasoningEffortsSchema.optional(), + promptCachingDisabled: z.boolean().optional(), + diffEnabled: z.boolean().optional(), + fuzzyMatchThreshold: z.number().optional(), + modelTemperature: z.number().nullish(), + rateLimitSeconds: z.number().optional(), + // Claude 3.7 Sonnet Thinking + modelMaxTokens: z.number().optional(), + modelMaxThinkingTokens: z.number().optional(), +}) + +const anthropicSchema = z.object({ apiModelId: z.string().optional(), apiKey: z.string().optional(), anthropicBaseUrl: z.string().optional(), anthropicUseAuthToken: z.boolean().optional(), - // Glama +}) + +const glamaSchema = z.object({ glamaModelId: z.string().optional(), glamaApiKey: z.string().optional(), - // OpenRouter +}) + +const openRouterSchema = z.object({ openRouterApiKey: z.string().optional(), openRouterModelId: z.string().optional(), openRouterBaseUrl: z.string().optional(), openRouterSpecificProvider: z.string().optional(), openRouterUseMiddleOutTransform: z.boolean().optional(), - // Amazon Bedrock +}) + +const bedrockSchema = z.object({ awsAccessKey: z.string().optional(), awsSecretKey: z.string().optional(), awsSessionToken: z.string().optional(), @@ -359,15 +376,18 @@ export const providerSettingsSchema = z.object({ awsProfile: z.string().optional(), awsUseProfile: z.boolean().optional(), awsCustomArn: z.string().optional(), - // Google Vertex +}) + +const vertexSchema = z.object({ vertexKeyFile: z.string().optional(), vertexJsonCredentials: z.string().optional(), vertexProjectId: z.string().optional(), vertexRegion: z.string().optional(), - // OpenAI +}) + +const openAiSchema = z.object({ openAiBaseUrl: z.string().optional(), openAiApiKey: z.string().optional(), - openAiHostHeader: z.string().optional(), openAiLegacyFormat: z.boolean().optional(), openAiR1FormatEnabled: z.boolean().optional(), openAiModelId: z.string().optional(), @@ -376,10 +396,16 @@ export const providerSettingsSchema = z.object({ azureApiVersion: z.string().optional(), openAiStreamingEnabled: z.boolean().optional(), enableReasoningEffort: z.boolean().optional(), - // Ollama + openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration. + openAiHeaders: z.record(z.string(), z.string()).optional(), +}) + +const ollamaSchema = z.object({ ollamaModelId: z.string().optional(), ollamaBaseUrl: z.string().optional(), - // VS Code LM +}) + +const vsCodeLmSchema = z.object({ vsCodeLmModelSelector: z .object({ vendor: z.string().optional(), @@ -388,46 +414,210 @@ export const providerSettingsSchema = z.object({ id: z.string().optional(), }) .optional(), - // LM Studio +}) + +const lmStudioSchema = z.object({ lmStudioModelId: z.string().optional(), lmStudioBaseUrl: z.string().optional(), lmStudioDraftModelId: z.string().optional(), lmStudioSpeculativeDecodingEnabled: z.boolean().optional(), - // Gemini +}) + +const geminiSchema = z.object({ geminiApiKey: z.string().optional(), googleGeminiBaseUrl: z.string().optional(), - // OpenAI Native +}) + +const openAiNativeSchema = z.object({ openAiNativeApiKey: z.string().optional(), openAiNativeBaseUrl: z.string().optional(), - // Mistral +}) + +const mistralSchema = z.object({ mistralApiKey: z.string().optional(), mistralCodestralUrl: z.string().optional(), - // DeepSeek +}) + +const deepSeekSchema = z.object({ deepSeekBaseUrl: z.string().optional(), deepSeekApiKey: z.string().optional(), - // Unbound +}) + +const unboundSchema = z.object({ unboundApiKey: z.string().optional(), unboundModelId: z.string().optional(), - // Requesty +}) + +const requestySchema = z.object({ requestyApiKey: z.string().optional(), requestyModelId: z.string().optional(), - // X.AI (Grok) - xaiApiKey: z.string().optional(), - // Claude 3.7 Sonnet Thinking - modelMaxTokens: z.number().optional(), - modelMaxThinkingTokens: z.number().optional(), - // Generic - includeMaxTokens: z.boolean().optional(), - reasoningEffort: reasoningEffortsSchema.optional(), - promptCachingDisabled: z.boolean().optional(), - diffEnabled: z.boolean().optional(), - fuzzyMatchThreshold: z.number().optional(), - modelTemperature: z.number().nullish(), - rateLimitSeconds: z.number().optional(), - // Fake AI +}) + +const humanRelaySchema = z.object({}) + +const fakeAiSchema = z.object({ fakeAi: z.unknown().optional(), }) +const xaiSchema = z.object({ + xaiApiKey: z.string().optional(), +}) + +const groqSchema = z.object({ + groqApiKey: z.string().optional(), +}) + +const chutesSchema = z.object({ + chutesApiKey: z.string().optional(), +}) + +const litellmSchema = z.object({ + litellmBaseUrl: z.string().optional(), + litellmApiKey: z.string().optional(), + litellmModelId: z.string().optional(), +}) + +const defaultSchema = z.object({ + apiProvider: z.undefined(), +}) + +export const providerSettingsSchemaDiscriminated = z + .discriminatedUnion("apiProvider", [ + anthropicSchema.merge( + z.object({ + apiProvider: z.literal("anthropic"), + }), + ), + glamaSchema.merge( + z.object({ + apiProvider: z.literal("glama"), + }), + ), + openRouterSchema.merge( + z.object({ + apiProvider: z.literal("openrouter"), + }), + ), + bedrockSchema.merge( + z.object({ + apiProvider: z.literal("bedrock"), + }), + ), + vertexSchema.merge( + z.object({ + apiProvider: z.literal("vertex"), + }), + ), + openAiSchema.merge( + z.object({ + apiProvider: z.literal("openai"), + }), + ), + ollamaSchema.merge( + z.object({ + apiProvider: z.literal("ollama"), + }), + ), + vsCodeLmSchema.merge( + z.object({ + apiProvider: z.literal("vscode-lm"), + }), + ), + lmStudioSchema.merge( + z.object({ + apiProvider: z.literal("lmstudio"), + }), + ), + geminiSchema.merge( + z.object({ + apiProvider: z.literal("gemini"), + }), + ), + openAiNativeSchema.merge( + z.object({ + apiProvider: z.literal("openai-native"), + }), + ), + mistralSchema.merge( + z.object({ + apiProvider: z.literal("mistral"), + }), + ), + deepSeekSchema.merge( + z.object({ + apiProvider: z.literal("deepseek"), + }), + ), + unboundSchema.merge( + z.object({ + apiProvider: z.literal("unbound"), + }), + ), + requestySchema.merge( + z.object({ + apiProvider: z.literal("requesty"), + }), + ), + humanRelaySchema.merge( + z.object({ + apiProvider: z.literal("human-relay"), + }), + ), + fakeAiSchema.merge( + z.object({ + apiProvider: z.literal("fake-ai"), + }), + ), + xaiSchema.merge( + z.object({ + apiProvider: z.literal("xai"), + }), + ), + groqSchema.merge( + z.object({ + apiProvider: z.literal("groq"), + }), + ), + chutesSchema.merge( + z.object({ + apiProvider: z.literal("chutes"), + }), + ), + litellmSchema.merge( + z.object({ + apiProvider: z.literal("litellm"), + }), + ), + defaultSchema, + ]) + .and(genericProviderSettingsSchema) + +export const providerSettingsSchema = z.object({ + apiProvider: providerNamesSchema.optional(), + ...anthropicSchema.shape, + ...glamaSchema.shape, + ...openRouterSchema.shape, + ...bedrockSchema.shape, + ...vertexSchema.shape, + ...openAiSchema.shape, + ...ollamaSchema.shape, + ...vsCodeLmSchema.shape, + ...lmStudioSchema.shape, + ...geminiSchema.shape, + ...openAiNativeSchema.shape, + ...mistralSchema.shape, + ...deepSeekSchema.shape, + ...unboundSchema.shape, + ...requestySchema.shape, + ...humanRelaySchema.shape, + ...fakeAiSchema.shape, + ...xaiSchema.shape, + ...groqSchema.shape, + ...chutesSchema.shape, + ...litellmSchema.shape, + ...genericProviderSettingsSchema.shape, +}) + export type ProviderSettings = z.infer type ProviderSettingsRecord = Record, undefined> @@ -466,7 +656,6 @@ const providerSettingsRecord: ProviderSettingsRecord = { // OpenAI openAiBaseUrl: undefined, openAiApiKey: undefined, - openAiHostHeader: undefined, openAiLegacyFormat: undefined, openAiR1FormatEnabled: undefined, openAiModelId: undefined, @@ -475,6 +664,8 @@ const providerSettingsRecord: ProviderSettingsRecord = { azureApiVersion: undefined, openAiStreamingEnabled: undefined, enableReasoningEffort: undefined, + openAiHostHeader: undefined, // Keep temporarily for backward compatibility during migration + openAiHeaders: undefined, // Ollama ollamaModelId: undefined, ollamaBaseUrl: undefined, @@ -517,6 +708,14 @@ const providerSettingsRecord: ProviderSettingsRecord = { fakeAi: undefined, // X.AI (Grok) xaiApiKey: undefined, + // Groq + groqApiKey: undefined, + // Chutes AI + chutesApiKey: undefined, + // LiteLLM + litellmBaseUrl: undefined, + litellmApiKey: undefined, + litellmModelId: undefined, } export const PROVIDER_SETTINGS_KEYS = Object.keys(providerSettingsRecord) as Keys[] @@ -527,7 +726,7 @@ export const PROVIDER_SETTINGS_KEYS = Object.keys(providerSettingsRecord) as Key export const globalSettingsSchema = z.object({ currentApiConfigName: z.string().optional(), - listApiConfigMeta: z.array(apiConfigMetaSchema).optional(), + listApiConfigMeta: z.array(providerSettingsEntrySchema).optional(), pinnedApiConfigs: z.record(z.string(), z.boolean()).optional(), lastShownAnnouncementId: z.string().optional(), diff --git a/evals/pnpm-lock.yaml b/evals/pnpm-lock.yaml index 46d2d65dfc..0991bbeb6f 100644 --- a/evals/pnpm-lock.yaml +++ b/evals/pnpm-lock.yaml @@ -30,7 +30,7 @@ importers: specifier: ^2.5.2 version: 2.5.3 typescript: - specifier: ^5.8.3 + specifier: 5.8.3 version: 5.8.3 typescript-eslint: specifier: ^8.31.1 @@ -235,12 +235,9 @@ importers: globals: specifier: ^16.0.0 version: 16.0.0 - typescript: - specifier: ^5 - version: 5.8.2 typescript-eslint: specifier: ^8.26.0 - version: 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) + version: 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) config/typescript: {} @@ -3370,7 +3367,6 @@ packages: libsql@0.4.7: resolution: {integrity: sha512-T9eIRCs6b0J1SHKYIvD8+KCJMcWZ900iZyxdnSCdqxN12Z1ijzT+jY5nrk72Jw4B0HGzms2NgpryArlJqvc3Lw==} - cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] lightningcss-darwin-arm64@1.29.2: @@ -4377,11 +4373,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} @@ -6037,20 +6028,20 @@ snapshots: dependencies: '@types/node': 20.17.24 - '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/type-utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/type-utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.26.1 eslint: 9.22.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -6071,15 +6062,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/parser@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.26.1 '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.26.1 debug: 4.4.0 eslint: 9.22.0(jiti@2.4.2) - typescript: 5.8.2 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -6105,14 +6096,14 @@ snapshots: '@typescript-eslint/types': 8.32.0 '@typescript-eslint/visitor-keys': 8.32.0 - '@typescript-eslint/type-utils@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/type-utils@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.0 eslint: 9.22.0(jiti@2.4.2) - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -6131,7 +6122,7 @@ snapshots: '@typescript-eslint/types@8.32.0': {} - '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2)': + '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/visitor-keys': 8.26.1 @@ -6140,8 +6131,8 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.1 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -6159,14 +6150,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/utils@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.6.1(eslint@9.22.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.26.1 '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.3) eslint: 9.22.0(jiti@2.4.2) - typescript: 5.8.2 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -8577,13 +8568,9 @@ snapshots: toidentifier@1.0.1: {} - ts-api-utils@2.0.1(typescript@5.8.2): + ts-api-utils@2.0.1(typescript@5.8.3): dependencies: - typescript: 5.8.2 - - ts-api-utils@2.1.0(typescript@5.8.2): - dependencies: - typescript: 5.8.2 + typescript: 5.8.3 ts-api-utils@2.1.0(typescript@5.8.3): dependencies: @@ -8670,13 +8657,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2): + typescript-eslint@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.22.0(jiti@2.4.2) - typescript: 5.8.2 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -8690,8 +8677,6 @@ snapshots: transitivePeerDependencies: - supports-color - typescript@5.8.2: {} - typescript@5.8.3: {} unbox-primitive@1.1.0: diff --git a/package-lock.json b/package-lock.json index b00a24fae3..87812de5e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "vscode-material-icons": "^0.1.1", "web-tree-sitter": "^0.22.6", "workerpool": "^9.2.0", - "zod": "^3.23.8" + "zod": "^3.24.2" }, "devDependencies": { "@changesets/cli": "^2.27.10", @@ -103,7 +103,7 @@ "ts-jest": "^29.2.5", "tsup": "^8.4.0", "tsx": "^4.19.3", - "typescript": "^5.4.5", + "typescript": "5.8.3", "vitest": "^3.1.3", "zod-to-ts": "^1.2.0" }, diff --git a/package.json b/package.json index 6552e9f27d..d1f84c5c61 100644 --- a/package.json +++ b/package.json @@ -421,7 +421,7 @@ "vscode-material-icons": "^0.1.1", "web-tree-sitter": "^0.22.6", "workerpool": "^9.2.0", - "zod": "^3.23.8" + "zod": "^3.24.2" }, "devDependencies": { "@changesets/cli": "^2.27.10", @@ -459,7 +459,7 @@ "ts-jest": "^29.2.5", "tsup": "^8.4.0", "tsx": "^4.19.3", - "typescript": "^5.4.5", + "typescript": "5.8.3", "vitest": "^3.1.3", "zod-to-ts": "^1.2.0" }, diff --git a/src/api/index.ts b/src/api/index.ts index c337dff768..10cbe14429 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,7 +1,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import { BetaThinkingConfigParam } from "@anthropic-ai/sdk/resources/beta/messages/index.mjs" -import { ApiConfiguration, ModelInfo, ApiHandlerOptions } from "../shared/api" +import { ProviderSettings, ModelInfo, ApiHandlerOptions } from "../shared/api" import { ANTHROPIC_DEFAULT_MAX_TOKENS } from "./providers/constants" import { GlamaHandler } from "./providers/glama" import { AnthropicHandler } from "./providers/anthropic" @@ -47,7 +47,7 @@ export interface ApiHandler { countTokens(content: Array): Promise } -export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { +export function buildApiHandler(configuration: ProviderSettings): ApiHandler { const { apiProvider, ...options } = configuration switch (apiProvider) { diff --git a/src/core/config/ProviderSettingsManager.ts b/src/core/config/ProviderSettingsManager.ts index 77687a0d36..f05a0233d5 100644 --- a/src/core/config/ProviderSettingsManager.ts +++ b/src/core/config/ProviderSettingsManager.ts @@ -1,7 +1,7 @@ import { ExtensionContext } from "vscode" import { z, ZodError } from "zod" -import { providerSettingsSchema, ApiConfigMeta, providerSettingsSchemaDiscriminated } from "../../schemas" +import { providerSettingsSchema, ProviderSettingsEntry, providerSettingsSchemaDiscriminated } from "../../schemas" import { Mode, modes } from "../../shared/modes" import { telemetryService } from "../../services/telemetry/TelemetryService" @@ -226,7 +226,7 @@ export class ProviderSettingsManager { /** * List all available configs with metadata. */ - public async listConfig(): Promise { + public async listConfig(): Promise { try { return await this.lock(async () => { const providerProfiles = await this.load() diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index f90d692617..05c9785452 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -16,7 +16,7 @@ import { ApiHandler, buildApiHandler } from "../../api" import { ApiStream } from "../../api/transform/stream" // shared -import { ApiConfiguration } from "../../shared/api" +import { ProviderSettings } from "../../shared/api" import { findLastIndex } from "../../shared/array" import { combineApiRequests } from "../../shared/combineApiRequests" import { combineCommandSequences } from "../../shared/combineCommandSequences" @@ -92,7 +92,7 @@ export type ClineEvents = { export type TaskOptions = { provider: ClineProvider - apiConfiguration: ApiConfiguration + apiConfiguration: ProviderSettings customInstructions?: string enableDiff?: boolean enableCheckpoints?: boolean @@ -130,7 +130,7 @@ export class Task extends EventEmitter { customInstructions?: string // API - readonly apiConfiguration: ApiConfiguration + readonly apiConfiguration: ProviderSettings api: ApiHandler private promptCacheKey: string private lastApiRequestTime?: number diff --git a/src/core/task/__tests__/Task.test.ts b/src/core/task/__tests__/Task.test.ts index f70edfdefa..0bffc4a179 100644 --- a/src/core/task/__tests__/Task.test.ts +++ b/src/core/task/__tests__/Task.test.ts @@ -9,7 +9,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import { GlobalState } from "../../../schemas" import { Task } from "../Task" import { ClineProvider } from "../../webview/ClineProvider" -import { ApiConfiguration, ModelInfo } from "../../../shared/api" +import { ProviderSettings, ModelInfo } from "../../../shared/api" import { ApiStreamChunk } from "../../../api/transform/stream" import { ContextProxy } from "../../config/ContextProxy" import { processUserContentMentions } from "../../mentions/processUserContentMentions" @@ -156,7 +156,7 @@ const mockMessages = [ describe("Cline", () => { let mockProvider: jest.Mocked - let mockApiConfig: ApiConfiguration + let mockApiConfig: ProviderSettings let mockOutputChannel: any let mockExtensionContext: vscode.ExtensionContext diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f43f85877d..609565e33d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -9,16 +9,10 @@ import axios from "axios" import pWaitFor from "p-wait-for" import * as vscode from "vscode" -import { GlobalState, ProviderSettings, RooCodeSettings } from "../../schemas" +import type { GlobalState, ProviderName, ProviderSettings, RooCodeSettings } from "../../schemas" import { t } from "../../i18n" import { setPanel } from "../../activate/registerCommands" -import { - ProviderName, - ApiConfiguration, - requestyDefaultModelId, - openRouterDefaultModelId, - glamaDefaultModelId, -} from "../../shared/api" +import { requestyDefaultModelId, openRouterDefaultModelId, glamaDefaultModelId } from "../../shared/api" import { findLast } from "../../shared/array" import { supportPrompt } from "../../shared/support-prompt" import { GlobalFileNames } from "../../shared/globalFileNames" @@ -942,7 +936,7 @@ export class ClineProvider extends EventEmitter implements throw error } - const newConfiguration: ApiConfiguration = { + const newConfiguration: ProviderSettings = { ...apiConfiguration, apiProvider: "openrouter", openRouterApiKey: apiKey, @@ -972,7 +966,7 @@ export class ClineProvider extends EventEmitter implements const { apiConfiguration, currentApiConfigName } = await this.getState() - const newConfiguration: ApiConfiguration = { + const newConfiguration: ProviderSettings = { ...apiConfiguration, apiProvider: "glama", glamaApiKey: apiKey, @@ -987,7 +981,7 @@ export class ClineProvider extends EventEmitter implements async handleRequestyCallback(code: string) { let { apiConfiguration, currentApiConfigName } = await this.getState() - const newConfiguration: ApiConfiguration = { + const newConfiguration: ProviderSettings = { ...apiConfiguration, apiProvider: "requesty", requestyApiKey: code, @@ -999,7 +993,7 @@ export class ClineProvider extends EventEmitter implements // Save configuration - async upsertApiConfiguration(configName: string, apiConfiguration: ApiConfiguration) { + async upsertApiConfiguration(configName: string, apiConfiguration: ProviderSettings) { try { await this.providerSettingsManager.saveConfig(configName, apiConfiguration) const listApiConfig = await this.providerSettingsManager.listConfig() diff --git a/src/core/webview/__tests__/ClineProvider.test.ts b/src/core/webview/__tests__/ClineProvider.test.ts index 67cb181b94..438f256ef0 100644 --- a/src/core/webview/__tests__/ClineProvider.test.ts +++ b/src/core/webview/__tests__/ClineProvider.test.ts @@ -5,7 +5,7 @@ import * as vscode from "vscode" import axios from "axios" import { ClineProvider } from "../ClineProvider" -import { ApiConfigMeta, ClineMessage, ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage" +import { ProviderSettingsEntry, ClineMessage, ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage" import { setSoundEnabled } from "../../../utils/sound" import { setTtsEnabled } from "../../../utils/tts" import { defaultModeSlug } from "../../../shared/modes" @@ -594,7 +594,7 @@ describe("ClineProvider", () => { await provider.resolveWebviewView(mockWebviewView) const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as jest.Mock).mock.calls[0][0] - const profile: ApiConfigMeta = { name: "test-config", id: "test-id", apiProvider: "anthropic" } + const profile: ProviderSettingsEntry = { name: "test-config", id: "test-id", apiProvider: "anthropic" } ;(provider as any).providerSettingsManager = { getModeConfigId: jest.fn().mockResolvedValue("test-id"), @@ -1538,7 +1538,11 @@ describe("ClineProvider", () => { }) it("loads saved API config when switching modes", async () => { - const profile: ApiConfigMeta = { name: "saved-config", id: "saved-config-id", apiProvider: "anthropic" } + const profile: ProviderSettingsEntry = { + name: "saved-config", + id: "saved-config-id", + apiProvider: "anthropic", + } ;(provider as any).providerSettingsManager = { getModeConfigId: jest.fn().mockResolvedValue("saved-config-id"), diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 2f1c888a57..f85f2d2fb3 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -4,7 +4,7 @@ import pWaitFor from "p-wait-for" import * as vscode from "vscode" import { ClineProvider } from "./ClineProvider" -import { Language, ApiConfigMeta, ProviderSettings } from "../../schemas" +import { Language, ProviderSettings } from "../../schemas" import { changeLanguage, t } from "../../i18n" import { RouterName, toRouterName } from "../../shared/api" import { supportPrompt } from "../../shared/support-prompt" @@ -935,10 +935,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We // Try to get enhancement config first, fall back to current config. let configToUse: ProviderSettings = apiConfiguration - if ( - enhancementApiConfigId && - !!listApiConfigMeta.find((c: ApiConfigMeta) => c.id === enhancementApiConfigId) - ) { + if (enhancementApiConfigId && !!listApiConfigMeta.find(({ id }) => id === enhancementApiConfigId)) { const { name: _, ...providerSettings } = await provider.providerSettingsManager.getProfile({ id: enhancementApiConfigId, }) diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 5b7adcfb91..83d0f41f61 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -135,18 +135,6 @@ export const modelInfoSchema = z.object({ export type ModelInfo = z.infer -/** - * ApiConfigMeta - */ - -export const apiConfigMetaSchema = z.object({ - id: z.string(), - name: z.string(), - apiProvider: providerNamesSchema.optional(), -}) - -export type ApiConfigMeta = z.infer - /** * HistoryItem */ @@ -341,11 +329,22 @@ export type Experiments = z.infer type _AssertExperiments = AssertEqual>> +/** + * ProviderSettingsEntry + */ + +export const providerSettingsEntrySchema = z.object({ + id: z.string(), + name: z.string(), + apiProvider: providerNamesSchema.optional(), +}) + +export type ProviderSettingsEntry = z.infer + /** * ProviderSettings */ -// Generic settings that apply to all providers const genericProviderSettingsSchema = z.object({ includeMaxTokens: z.boolean().optional(), reasoningEffort: reasoningEffortsSchema.optional(), @@ -359,7 +358,6 @@ const genericProviderSettingsSchema = z.object({ modelMaxThinkingTokens: z.number().optional(), }) -// Provider-specific schemas const anthropicSchema = z.object({ apiModelId: z.string().optional(), apiKey: z.string().optional(), @@ -410,7 +408,7 @@ const openAiSchema = z.object({ azureApiVersion: z.string().optional(), openAiStreamingEnabled: z.boolean().optional(), enableReasoningEffort: z.boolean().optional(), - openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration + openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration. openAiHeaders: z.record(z.string(), z.string()).optional(), }) @@ -491,119 +489,33 @@ const litellmSchema = z.object({ litellmModelId: z.string().optional(), }) -// Default schema for when apiProvider is not specified const defaultSchema = z.object({ apiProvider: z.undefined(), }) -// Create the discriminated union export const providerSettingsSchemaDiscriminated = z .discriminatedUnion("apiProvider", [ - anthropicSchema.merge( - z.object({ - apiProvider: z.literal("anthropic"), - }), - ), - glamaSchema.merge( - z.object({ - apiProvider: z.literal("glama"), - }), - ), - openRouterSchema.merge( - z.object({ - apiProvider: z.literal("openrouter"), - }), - ), - bedrockSchema.merge( - z.object({ - apiProvider: z.literal("bedrock"), - }), - ), - vertexSchema.merge( - z.object({ - apiProvider: z.literal("vertex"), - }), - ), - openAiSchema.merge( - z.object({ - apiProvider: z.literal("openai"), - }), - ), - ollamaSchema.merge( - z.object({ - apiProvider: z.literal("ollama"), - }), - ), - vsCodeLmSchema.merge( - z.object({ - apiProvider: z.literal("vscode-lm"), - }), - ), - lmStudioSchema.merge( - z.object({ - apiProvider: z.literal("lmstudio"), - }), - ), - geminiSchema.merge( - z.object({ - apiProvider: z.literal("gemini"), - }), - ), - openAiNativeSchema.merge( - z.object({ - apiProvider: z.literal("openai-native"), - }), - ), - mistralSchema.merge( - z.object({ - apiProvider: z.literal("mistral"), - }), - ), - deepSeekSchema.merge( - z.object({ - apiProvider: z.literal("deepseek"), - }), - ), - unboundSchema.merge( - z.object({ - apiProvider: z.literal("unbound"), - }), - ), - requestySchema.merge( - z.object({ - apiProvider: z.literal("requesty"), - }), - ), - humanRelaySchema.merge( - z.object({ - apiProvider: z.literal("human-relay"), - }), - ), - fakeAiSchema.merge( - z.object({ - apiProvider: z.literal("fake-ai"), - }), - ), - xaiSchema.merge( - z.object({ - apiProvider: z.literal("xai"), - }), - ), - groqSchema.merge( - z.object({ - apiProvider: z.literal("groq"), - }), - ), - chutesSchema.merge( - z.object({ - apiProvider: z.literal("chutes"), - }), - ), - litellmSchema.merge( - z.object({ - apiProvider: z.literal("litellm"), - }), - ), + anthropicSchema.merge(z.object({ apiProvider: z.literal("anthropic") })), + glamaSchema.merge(z.object({ apiProvider: z.literal("glama") })), + openRouterSchema.merge(z.object({ apiProvider: z.literal("openrouter") })), + bedrockSchema.merge(z.object({ apiProvider: z.literal("bedrock") })), + vertexSchema.merge(z.object({ apiProvider: z.literal("vertex") })), + openAiSchema.merge(z.object({ apiProvider: z.literal("openai") })), + ollamaSchema.merge(z.object({ apiProvider: z.literal("ollama") })), + vsCodeLmSchema.merge(z.object({ apiProvider: z.literal("vscode-lm") })), + lmStudioSchema.merge(z.object({ apiProvider: z.literal("lmstudio") })), + geminiSchema.merge(z.object({ apiProvider: z.literal("gemini") })), + openAiNativeSchema.merge(z.object({ apiProvider: z.literal("openai-native") })), + mistralSchema.merge(z.object({ apiProvider: z.literal("mistral") })), + deepSeekSchema.merge(z.object({ apiProvider: z.literal("deepseek") })), + unboundSchema.merge(z.object({ apiProvider: z.literal("unbound") })), + requestySchema.merge(z.object({ apiProvider: z.literal("requesty") })), + humanRelaySchema.merge(z.object({ apiProvider: z.literal("human-relay") })), + fakeAiSchema.merge(z.object({ apiProvider: z.literal("fake-ai") })), + xaiSchema.merge(z.object({ apiProvider: z.literal("xai") })), + groqSchema.merge(z.object({ apiProvider: z.literal("groq") })), + chutesSchema.merge(z.object({ apiProvider: z.literal("chutes") })), + litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })), defaultSchema, ]) .and(genericProviderSettingsSchema) @@ -743,7 +655,7 @@ export const PROVIDER_SETTINGS_KEYS = Object.keys(providerSettingsRecord) as Key export const globalSettingsSchema = z.object({ currentApiConfigName: z.string().optional(), - listApiConfigMeta: z.array(apiConfigMetaSchema).optional(), + listApiConfigMeta: z.array(providerSettingsEntrySchema).optional(), pinnedApiConfigs: z.record(z.string(), z.boolean()).optional(), lastShownAnnouncementId: z.string().optional(), diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index d118dd3989..6330556024 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -2,8 +2,8 @@ import { GitCommit } from "../utils/git" import { GlobalSettings, - ApiConfigMeta, - ProviderSettings as ApiConfiguration, + ProviderSettingsEntry, + ProviderSettings, HistoryItem, ModeConfig, TelemetrySetting, @@ -17,7 +17,7 @@ import { McpServer } from "./mcp" import { Mode } from "./modes" import { RouterModels } from "./api" -export type { ApiConfigMeta, ToolProgressStatus } +export type { ProviderSettingsEntry, ToolProgressStatus } export interface LanguageModelChatSelector { vendor?: string @@ -95,7 +95,7 @@ export interface ExtensionMessage { vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[] mcpServers?: McpServer[] commits?: GitCommit[] - listApiConfig?: ApiConfigMeta[] + listApiConfig?: ProviderSettingsEntry[] mode?: Mode customMode?: ModeConfig slug?: string @@ -172,7 +172,7 @@ export type ExtensionState = Pick< version: string clineMessages: ClineMessage[] currentTaskItem?: HistoryItem - apiConfiguration?: ApiConfiguration + apiConfiguration?: ProviderSettings uriScheme?: string shouldShowAnnouncement: boolean diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index fe8dfff40c..c1dc3ffc19 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -1,6 +1,6 @@ import { z } from "zod" -import { ApiConfiguration } from "./api" +import { ProviderSettings } from "./api" import { Mode, PromptComponent, ModeConfig } from "./modes" export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" @@ -134,7 +134,7 @@ export interface WebviewMessage { text?: string disabled?: boolean askResponse?: ClineAskResponse - apiConfiguration?: ApiConfiguration + apiConfiguration?: ProviderSettings images?: string[] bool?: boolean value?: number diff --git a/src/shared/__tests__/checkExistApiConfig.test.ts b/src/shared/__tests__/checkExistApiConfig.test.ts index c99ddddbc4..a8e603db8a 100644 --- a/src/shared/__tests__/checkExistApiConfig.test.ts +++ b/src/shared/__tests__/checkExistApiConfig.test.ts @@ -1,5 +1,5 @@ import { checkExistKey } from "../checkExistApiConfig" -import { ApiConfiguration } from "../api" +import { ProviderSettings } from "../api" describe("checkExistKey", () => { it("should return false for undefined config", () => { @@ -7,19 +7,19 @@ describe("checkExistKey", () => { }) it("should return false for empty config", () => { - const config: ApiConfiguration = {} + const config: ProviderSettings = {} expect(checkExistKey(config)).toBe(false) }) it("should return true when one key is defined", () => { - const config: ApiConfiguration = { + const config: ProviderSettings = { apiKey: "test-key", } expect(checkExistKey(config)).toBe(true) }) it("should return true when multiple keys are defined", () => { - const config: ApiConfiguration = { + const config: ProviderSettings = { apiKey: "test-key", glamaApiKey: "glama-key", openRouterApiKey: "openrouter-key", @@ -28,7 +28,7 @@ describe("checkExistKey", () => { }) it("should return true when only non-key fields are undefined", () => { - const config: ApiConfiguration = { + const config: ProviderSettings = { apiKey: "test-key", apiProvider: undefined, anthropicBaseUrl: undefined, @@ -38,7 +38,7 @@ describe("checkExistKey", () => { }) it("should return false when all key fields are undefined", () => { - const config: ApiConfiguration = { + const config: ProviderSettings = { apiKey: undefined, glamaApiKey: undefined, openRouterApiKey: undefined, diff --git a/src/shared/api.ts b/src/shared/api.ts index 9f64d7913f..17d2b14dd4 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -1,11 +1,9 @@ import { ModelInfo, ProviderName, ProviderSettings } from "../schemas" -export type { ModelInfo, ProviderName } +export type { ModelInfo, ProviderName, ProviderSettings } export type ApiHandlerOptions = Omit -export type ApiConfiguration = ProviderSettings - // Anthropic // https://docs.anthropic.com/en/docs/about-claude/models export type AnthropicModelId = keyof typeof anthropicModels diff --git a/src/utils/__tests__/enhance-prompt.test.ts b/src/utils/__tests__/enhance-prompt.test.ts index adda8860eb..524f99c817 100644 --- a/src/utils/__tests__/enhance-prompt.test.ts +++ b/src/utils/__tests__/enhance-prompt.test.ts @@ -1,5 +1,5 @@ import { singleCompletionHandler } from "../single-completion-handler" -import { ApiConfiguration } from "../../shared/api" +import { ProviderSettings } from "../../shared/api" import { buildApiHandler, SingleCompletionHandler } from "../../api" import { supportPrompt } from "../../shared/support-prompt" @@ -9,7 +9,7 @@ jest.mock("../../api", () => ({ })) describe("enhancePrompt", () => { - const mockApiConfig: ApiConfiguration = { + const mockApiConfig: ProviderSettings = { apiProvider: "openai", openAiApiKey: "test-key", openAiBaseUrl: "https://api.openai.com/v1", @@ -69,7 +69,7 @@ describe("enhancePrompt", () => { }) it("throws error for missing API configuration", async () => { - await expect(singleCompletionHandler({} as ApiConfiguration, "Test prompt")).rejects.toThrow( + await expect(singleCompletionHandler({} as ProviderSettings, "Test prompt")).rejects.toThrow( "No valid API configuration provided", ) }) @@ -94,7 +94,7 @@ describe("enhancePrompt", () => { }) it("uses appropriate model based on provider", async () => { - const openRouterConfig: ApiConfiguration = { + const openRouterConfig: ProviderSettings = { apiProvider: "openrouter", openRouterApiKey: "test-key", openRouterModelId: "test-model", diff --git a/src/utils/single-completion-handler.ts b/src/utils/single-completion-handler.ts index 5e049d4726..7434d07e19 100644 --- a/src/utils/single-completion-handler.ts +++ b/src/utils/single-completion-handler.ts @@ -1,11 +1,11 @@ -import { ApiConfiguration } from "../shared/api" +import { ProviderSettings } from "../shared/api" import { buildApiHandler, SingleCompletionHandler } from "../api" /** * Enhances a prompt using the configured API without creating a full Cline instance or task history. * This is a lightweight alternative that only uses the API's completion functionality. */ -export async function singleCompletionHandler(apiConfiguration: ApiConfiguration, promptText: string): Promise { +export async function singleCompletionHandler(apiConfiguration: ProviderSettings, promptText: string): Promise { if (!promptText) { throw new Error("No prompt text provided") } diff --git a/webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx b/webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx index 625bad1169..f9fb71b066 100644 --- a/webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx @@ -4,7 +4,7 @@ import React from "react" import { render, screen } from "@testing-library/react" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import TaskHeader, { TaskHeaderProps } from "../TaskHeader" @@ -27,7 +27,7 @@ jest.mock("@src/context/ExtensionStateContext", () => ({ apiProvider: "anthropic", apiKey: "test-api-key", // Add relevant fields apiModelId: "claude-3-opus-20240229", // Add relevant fields - } as ApiConfiguration, // Optional: Add type assertion if ApiConfiguration is imported + } as ProviderSettings, // Optional: Add type assertion if ProviderSettings is imported currentTaskItem: null, }), })) diff --git a/webview-ui/src/components/settings/ApiConfigManager.tsx b/webview-ui/src/components/settings/ApiConfigManager.tsx index 841de5d8a2..05b14bc586 100644 --- a/webview-ui/src/components/settings/ApiConfigManager.tsx +++ b/webview-ui/src/components/settings/ApiConfigManager.tsx @@ -2,7 +2,7 @@ import { memo, useEffect, useRef, useState } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" import { ChevronsUpDown, Check, X } from "lucide-react" -import { ApiConfigMeta } from "@roo/shared/ExtensionMessage" +import { ProviderSettingsEntry } from "@roo/shared/ExtensionMessage" import { useAppTranslation } from "@/i18n/TranslationContext" import { cn } from "@/lib/utils" @@ -25,7 +25,7 @@ import { interface ApiConfigManagerProps { currentApiConfigName?: string - listApiConfigMeta?: ApiConfigMeta[] + listApiConfigMeta?: ProviderSettingsEntry[] onSelectConfig: (configName: string) => void onDeleteConfig: (configName: string) => void onRenameConfig: (oldName: string, newName: string) => void diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 7741ced874..f21bb6617b 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -4,7 +4,7 @@ import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { type ProviderName, - type ApiConfiguration, + type ProviderSettings, openRouterDefaultModelId, requestyDefaultModelId, glamaDefaultModelId, @@ -55,8 +55,8 @@ import { BedrockCustomArn } from "./providers/BedrockCustomArn" export interface ApiOptionsProps { uriScheme: string | undefined - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: K, value: ApiConfiguration[K]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void fromWelcomeView?: boolean errorMessage: string | undefined setErrorMessage: React.Dispatch> @@ -125,9 +125,9 @@ const ApiOptions = ({ const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/PromptCachingControl.tsx b/webview-ui/src/components/settings/PromptCachingControl.tsx index e7600915ec..db5687a57d 100644 --- a/webview-ui/src/components/settings/PromptCachingControl.tsx +++ b/webview-ui/src/components/settings/PromptCachingControl.tsx @@ -1,12 +1,12 @@ import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" interface PromptCachingControlProps { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: K, value: ApiConfiguration[K]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void } export const PromptCachingControl = ({ apiConfiguration, setApiConfigurationField }: PromptCachingControlProps) => { diff --git a/webview-ui/src/components/settings/ReasoningEffort.tsx b/webview-ui/src/components/settings/ReasoningEffort.tsx index 8e3c399ae9..53d21a2c49 100644 --- a/webview-ui/src/components/settings/ReasoningEffort.tsx +++ b/webview-ui/src/components/settings/ReasoningEffort.tsx @@ -2,12 +2,12 @@ import { useAppTranslation } from "@/i18n/TranslationContext" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { reasoningEfforts, ReasoningEffort as ReasoningEffortType } from "@roo/schemas" interface ReasoningEffortProps { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: K, value: ApiConfiguration[K]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void } export const ReasoningEffort = ({ apiConfiguration, setApiConfigurationField }: ReasoningEffortProps) => { diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index eeb11ea6eb..735a5b67ba 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -27,7 +27,7 @@ import { import { ExperimentId } from "@roo/shared/experiments" import { TelemetrySetting } from "@roo/shared/TelemetrySetting" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { vscode } from "@/utils/vscode" import { ExtensionStateContextType, useExtensionState } from "@/context/ExtensionStateContext" @@ -195,7 +195,7 @@ const SettingsView = forwardRef(({ onDone, t }, []) const setApiConfigurationField = useCallback( - (field: K, value: ApiConfiguration[K]) => { + (field: K, value: ProviderSettings[K]) => { setCachedState((prevState) => { if (prevState.apiConfiguration?.[field] === value) { return prevState diff --git a/webview-ui/src/components/settings/ThinkingBudget.tsx b/webview-ui/src/components/settings/ThinkingBudget.tsx index 1ee2f310e0..6c4352f22b 100644 --- a/webview-ui/src/components/settings/ThinkingBudget.tsx +++ b/webview-ui/src/components/settings/ThinkingBudget.tsx @@ -3,14 +3,14 @@ import { useAppTranslation } from "@/i18n/TranslationContext" import { Slider } from "@/components/ui" -import { ApiConfiguration, ModelInfo } from "@roo/shared/api" +import { ProviderSettings, ModelInfo } from "@roo/shared/api" const DEFAULT_MAX_OUTPUT_TOKENS = 16_384 const DEFAULT_MAX_THINKING_TOKENS = 8_192 interface ThinkingBudgetProps { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: K, value: ApiConfiguration[K]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void modelInfo?: ModelInfo } diff --git a/webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx b/webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx index 115c623a27..b9b1d1d21e 100644 --- a/webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx @@ -3,7 +3,7 @@ import { render, screen, fireEvent } from "@testing-library/react" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { ExtensionStateContextProvider } from "@/context/ExtensionStateContext" import { openAiModelInfoSaneDefaults } from "@roo/shared/api" @@ -148,7 +148,7 @@ jest.mock("../DiffSettingsControl", () => ({ })) jest.mock("@src/components/ui/hooks/useSelectedModel", () => ({ - useSelectedModel: jest.fn((apiConfiguration: ApiConfiguration) => { + useSelectedModel: jest.fn((apiConfiguration: ProviderSettings) => { if (apiConfiguration.apiModelId?.includes("thinking")) { return { provider: apiConfiguration.apiProvider, diff --git a/webview-ui/src/components/settings/providers/Anthropic.tsx b/webview-ui/src/components/settings/providers/Anthropic.tsx index bf310d1cb7..4d5957b562 100644 --- a/webview-ui/src/components/settings/providers/Anthropic.tsx +++ b/webview-ui/src/components/settings/providers/Anthropic.tsx @@ -2,7 +2,7 @@ import { useCallback, useState } from "react" import { Checkbox } from "vscrui" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -10,8 +10,8 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform, noTransform } from "../transforms" type AnthropicProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: AnthropicProps) => { @@ -20,9 +20,9 @@ export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: Anthro const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Bedrock.tsx b/webview-ui/src/components/settings/providers/Bedrock.tsx index fc69e74dde..2ddc5797ca 100644 --- a/webview-ui/src/components/settings/providers/Bedrock.tsx +++ b/webview-ui/src/components/settings/providers/Bedrock.tsx @@ -2,7 +2,7 @@ import { useCallback } from "react" import { Checkbox } from "vscrui" import { VSCodeTextField, VSCodeRadio, VSCodeRadioGroup } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration, ModelInfo } from "@roo/shared/api" +import { ProviderSettings, ModelInfo } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui" @@ -11,8 +11,8 @@ import { AWS_REGIONS } from "../constants" import { inputEventTransform, noTransform } from "../transforms" type BedrockProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void selectedModelInfo?: ModelInfo } @@ -20,9 +20,9 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx b/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx index f24d9ef81c..1caf95b8c7 100644 --- a/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx +++ b/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx @@ -1,14 +1,14 @@ import { useMemo } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { validateBedrockArn } from "@src/utils/validate" import { useAppTranslation } from "@src/i18n/TranslationContext" type BedrockCustomArnProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const BedrockCustomArn = ({ apiConfiguration, setApiConfigurationField }: BedrockCustomArnProps) => { diff --git a/webview-ui/src/components/settings/providers/Chutes.tsx b/webview-ui/src/components/settings/providers/Chutes.tsx index f87b9650cf..10ca2c202f 100644 --- a/webview-ui/src/components/settings/providers/Chutes.tsx +++ b/webview-ui/src/components/settings/providers/Chutes.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -9,17 +9,17 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type ChutesProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const Chutes = ({ apiConfiguration, setApiConfigurationField }: ChutesProps) => { const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/DeepSeek.tsx b/webview-ui/src/components/settings/providers/DeepSeek.tsx index 8b1e2e91ef..ffb48aec09 100644 --- a/webview-ui/src/components/settings/providers/DeepSeek.tsx +++ b/webview-ui/src/components/settings/providers/DeepSeek.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -9,17 +9,17 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type DeepSeekProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const DeepSeek = ({ apiConfiguration, setApiConfigurationField }: DeepSeekProps) => { const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Gemini.tsx b/webview-ui/src/components/settings/providers/Gemini.tsx index 490ab73a51..0a9af31568 100644 --- a/webview-ui/src/components/settings/providers/Gemini.tsx +++ b/webview-ui/src/components/settings/providers/Gemini.tsx @@ -2,7 +2,7 @@ import { useCallback, useState } from "react" import { Checkbox } from "vscrui" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -10,8 +10,8 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type GeminiProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const Gemini = ({ apiConfiguration, setApiConfigurationField }: GeminiProps) => { @@ -22,9 +22,9 @@ export const Gemini = ({ apiConfiguration, setApiConfigurationField }: GeminiPro ) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Glama.tsx b/webview-ui/src/components/settings/providers/Glama.tsx index 1150e14936..7a7f5dcc49 100644 --- a/webview-ui/src/components/settings/providers/Glama.tsx +++ b/webview-ui/src/components/settings/providers/Glama.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration, RouterModels, glamaDefaultModelId } from "@roo/shared/api" +import { ProviderSettings, RouterModels, glamaDefaultModelId } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { getGlamaAuthUrl } from "@src/oauth/urls" @@ -11,8 +11,8 @@ import { inputEventTransform } from "../transforms" import { ModelPicker } from "../ModelPicker" type GlamaProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void routerModels?: RouterModels uriScheme?: string } @@ -21,9 +21,9 @@ export const Glama = ({ apiConfiguration, setApiConfigurationField, routerModels const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Groq.tsx b/webview-ui/src/components/settings/providers/Groq.tsx index 45f827df14..eaf29a4572 100644 --- a/webview-ui/src/components/settings/providers/Groq.tsx +++ b/webview-ui/src/components/settings/providers/Groq.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -9,17 +9,17 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type GroqProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const Groq = ({ apiConfiguration, setApiConfigurationField }: GroqProps) => { const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/LMStudio.tsx b/webview-ui/src/components/settings/providers/LMStudio.tsx index 0979ec9242..df58f903bb 100644 --- a/webview-ui/src/components/settings/providers/LMStudio.tsx +++ b/webview-ui/src/components/settings/providers/LMStudio.tsx @@ -4,7 +4,7 @@ import { Trans } from "react-i18next" import { Checkbox } from "vscrui" import { VSCodeLink, VSCodeRadio, VSCodeRadioGroup, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { ExtensionMessage } from "@roo/shared/ExtensionMessage" @@ -12,8 +12,8 @@ import { ExtensionMessage } from "@roo/shared/ExtensionMessage" import { inputEventTransform } from "../transforms" type LMStudioProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const LMStudio = ({ apiConfiguration, setApiConfigurationField }: LMStudioProps) => { @@ -22,9 +22,9 @@ export const LMStudio = ({ apiConfiguration, setApiConfigurationField }: LMStudi const [lmStudioModels, setLmStudioModels] = useState([]) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/LiteLLM.tsx b/webview-ui/src/components/settings/providers/LiteLLM.tsx index 5fc466116c..8f98d97e5d 100644 --- a/webview-ui/src/components/settings/providers/LiteLLM.tsx +++ b/webview-ui/src/components/settings/providers/LiteLLM.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration, RouterModels, litellmDefaultModelId } from "@roo/shared/api" +import { ProviderSettings, RouterModels, litellmDefaultModelId } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -9,8 +9,8 @@ import { inputEventTransform } from "../transforms" import { ModelPicker } from "../ModelPicker" type LiteLLMProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void routerModels?: RouterModels } @@ -18,9 +18,9 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) @@ -46,6 +46,7 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode className="w-full"> +
{t("settings:providers.apiKeyStorageNotice")}
diff --git a/webview-ui/src/components/settings/providers/Mistral.tsx b/webview-ui/src/components/settings/providers/Mistral.tsx index c8c27c1d55..1669166043 100644 --- a/webview-ui/src/components/settings/providers/Mistral.tsx +++ b/webview-ui/src/components/settings/providers/Mistral.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration, RouterModels, mistralDefaultModelId } from "@roo/shared/api" +import { ProviderSettings, RouterModels, mistralDefaultModelId } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -9,8 +9,8 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type MistralProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void routerModels?: RouterModels } @@ -18,9 +18,9 @@ export const Mistral = ({ apiConfiguration, setApiConfigurationField }: MistralP const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Ollama.tsx b/webview-ui/src/components/settings/providers/Ollama.tsx index 5646fae18c..bda3c441cc 100644 --- a/webview-ui/src/components/settings/providers/Ollama.tsx +++ b/webview-ui/src/components/settings/providers/Ollama.tsx @@ -2,7 +2,7 @@ import { useState, useCallback } from "react" import { useEvent } from "react-use" import { VSCodeTextField, VSCodeRadioGroup, VSCodeRadio } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { ExtensionMessage } from "@roo/shared/ExtensionMessage" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -10,8 +10,8 @@ import { useAppTranslation } from "@src/i18n/TranslationContext" import { inputEventTransform } from "../transforms" type OllamaProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaProps) => { @@ -20,9 +20,9 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro const [ollamaModels, setOllamaModels] = useState([]) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/OpenAI.tsx b/webview-ui/src/components/settings/providers/OpenAI.tsx index 501dc9df55..771d77ef6a 100644 --- a/webview-ui/src/components/settings/providers/OpenAI.tsx +++ b/webview-ui/src/components/settings/providers/OpenAI.tsx @@ -2,7 +2,7 @@ import { useCallback, useState } from "react" import { Checkbox } from "vscrui" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -10,8 +10,8 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type OpenAIProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const OpenAI = ({ apiConfiguration, setApiConfigurationField }: OpenAIProps) => { @@ -22,9 +22,9 @@ export const OpenAI = ({ apiConfiguration, setApiConfigurationField }: OpenAIPro ) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx index 9d55d57f8c..bb2f1f89eb 100644 --- a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx +++ b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx @@ -4,7 +4,7 @@ import { Checkbox } from "vscrui" import { VSCodeButton, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" import { ModelInfo, ReasoningEffort as ReasoningEffortType } from "@roo/schemas" -import { ApiConfiguration, azureOpenAiDefaultApiVersion, openAiModelInfoSaneDefaults } from "@roo/shared/api" +import { ProviderSettings, azureOpenAiDefaultApiVersion, openAiModelInfoSaneDefaults } from "@roo/shared/api" import { ExtensionMessage } from "@roo/shared/ExtensionMessage" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -16,8 +16,8 @@ import { R1FormatSetting } from "../R1FormatSetting" import { ReasoningEffort } from "../ReasoningEffort" type OpenAICompatibleProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const OpenAICompatible = ({ apiConfiguration, setApiConfigurationField }: OpenAICompatibleProps) => { @@ -68,9 +68,9 @@ export const OpenAICompatible = ({ apiConfiguration, setApiConfigurationField }: }, []) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/OpenRouter.tsx b/webview-ui/src/components/settings/providers/OpenRouter.tsx index 696fcca331..7bb7c30095 100644 --- a/webview-ui/src/components/settings/providers/OpenRouter.tsx +++ b/webview-ui/src/components/settings/providers/OpenRouter.tsx @@ -4,7 +4,7 @@ import { Checkbox } from "vscrui" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" import { ExternalLinkIcon } from "@radix-ui/react-icons" -import { ApiConfiguration, RouterModels, openRouterDefaultModelId } from "@roo/shared/api" +import { ProviderSettings, RouterModels, openRouterDefaultModelId } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { getOpenRouterAuthUrl } from "@src/oauth/urls" @@ -21,8 +21,8 @@ import { ModelPicker } from "../ModelPicker" import { OpenRouterBalanceDisplay } from "./OpenRouterBalanceDisplay" type OpenRouterProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void routerModels?: RouterModels selectedModelId: string uriScheme: string | undefined @@ -42,9 +42,9 @@ export const OpenRouter = ({ const [openRouterBaseUrlSelected, setOpenRouterBaseUrlSelected] = useState(!!apiConfiguration?.openRouterBaseUrl) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Requesty.tsx b/webview-ui/src/components/settings/providers/Requesty.tsx index a8c8fc8099..9c6ba2844e 100644 --- a/webview-ui/src/components/settings/providers/Requesty.tsx +++ b/webview-ui/src/components/settings/providers/Requesty.tsx @@ -1,7 +1,7 @@ import { useCallback, useState } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration, RouterModels, requestyDefaultModelId } from "@roo/shared/api" +import { ProviderSettings, RouterModels, requestyDefaultModelId } from "@roo/shared/api" import { vscode } from "@src/utils/vscode" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -13,8 +13,8 @@ import { ModelPicker } from "../ModelPicker" import { RequestyBalanceDisplay } from "./RequestyBalanceDisplay" type RequestyProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void routerModels?: RouterModels refetchRouterModels: () => void } @@ -30,9 +30,9 @@ export const Requesty = ({ const [didRefetch, setDidRefetch] = useState() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Unbound.tsx b/webview-ui/src/components/settings/providers/Unbound.tsx index 7467d2b7c6..77b24bb7cc 100644 --- a/webview-ui/src/components/settings/providers/Unbound.tsx +++ b/webview-ui/src/components/settings/providers/Unbound.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration, RouterModels, unboundDefaultModelId } from "@roo/shared/api" +import { ProviderSettings, RouterModels, unboundDefaultModelId } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -10,8 +10,8 @@ import { inputEventTransform } from "../transforms" import { ModelPicker } from "../ModelPicker" type UnboundProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void routerModels?: RouterModels } @@ -19,9 +19,9 @@ export const Unbound = ({ apiConfiguration, setApiConfigurationField, routerMode const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/VSCodeLM.tsx b/webview-ui/src/components/settings/providers/VSCodeLM.tsx index ca701ce024..7f9426e5ce 100644 --- a/webview-ui/src/components/settings/providers/VSCodeLM.tsx +++ b/webview-ui/src/components/settings/providers/VSCodeLM.tsx @@ -2,7 +2,7 @@ import { useState, useCallback } from "react" import { useEvent } from "react-use" import { LanguageModelChatSelector } from "vscode" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { ExtensionMessage } from "@roo/shared/ExtensionMessage" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -11,8 +11,8 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { inputEventTransform } from "../transforms" type VSCodeLMProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const VSCodeLM = ({ apiConfiguration, setApiConfigurationField }: VSCodeLMProps) => { @@ -21,9 +21,9 @@ export const VSCodeLM = ({ apiConfiguration, setApiConfigurationField }: VSCodeL const [vsCodeLmModels, setVsCodeLmModels] = useState([]) const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/Vertex.tsx b/webview-ui/src/components/settings/providers/Vertex.tsx index f0723f9d31..b43c793816 100644 --- a/webview-ui/src/components/settings/providers/Vertex.tsx +++ b/webview-ui/src/components/settings/providers/Vertex.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui" @@ -10,17 +10,17 @@ import { inputEventTransform } from "../transforms" import { VERTEX_REGIONS } from "../constants" type VertexProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const Vertex = ({ apiConfiguration, setApiConfigurationField }: VertexProps) => { const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/settings/providers/XAI.tsx b/webview-ui/src/components/settings/providers/XAI.tsx index 39b0e53d34..c42bde1b1e 100644 --- a/webview-ui/src/components/settings/providers/XAI.tsx +++ b/webview-ui/src/components/settings/providers/XAI.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -9,17 +9,17 @@ import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" import { inputEventTransform } from "../transforms" type XAIProps = { - apiConfiguration: ApiConfiguration - setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void } export const XAI = ({ apiConfiguration, setApiConfigurationField }: XAIProps) => { const { t } = useAppTranslation() const handleInputChange = useCallback( - ( + ( field: K, - transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, ) => (event: E | Event) => { setApiConfigurationField(field, transform(event as E)) diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 3b1d792c93..fb1b277981 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -1,6 +1,6 @@ import { type ProviderName, - type ApiConfiguration, + type ProviderSettings, type RouterModels, type ModelInfo, anthropicDefaultModelId, @@ -35,7 +35,7 @@ import { import { useRouterModels } from "./useRouterModels" -export const useSelectedModel = (apiConfiguration?: ApiConfiguration) => { +export const useSelectedModel = (apiConfiguration?: ProviderSettings) => { const { data: routerModels, isLoading, isError } = useRouterModels() const provider = apiConfiguration?.apiProvider || "anthropic" @@ -53,7 +53,7 @@ function getSelectedModel({ routerModels, }: { provider: ProviderName - apiConfiguration: ApiConfiguration + apiConfiguration: ProviderSettings routerModels: RouterModels }): { id: string; info: ModelInfo } { switch (provider) { diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index f3a1f69969..63c895f034 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -1,9 +1,8 @@ import React, { createContext, useCallback, useContext, useEffect, useState } from "react" import { useEvent } from "react-use" -import { ApiConfigMeta, ExtensionMessage, ExtensionState } from "@roo/shared/ExtensionMessage" -import { ApiConfiguration } from "@roo/shared/api" -import { vscode } from "@src/utils/vscode" -import { convertTextMateToHljs } from "@src/utils/textMateToHljs" + +import { ProviderSettingsEntry, ExtensionMessage, ExtensionState } from "@roo/shared/ExtensionMessage" +import { ProviderSettings } from "@roo/shared/api" import { findLastIndex } from "@roo/shared/array" import { McpServer } from "@roo/shared/mcp" import { checkExistKey } from "@roo/shared/checkExistApiConfig" @@ -12,6 +11,9 @@ import { CustomSupportPrompts } from "@roo/shared/support-prompt" import { experimentDefault, ExperimentId } from "@roo/shared/experiments" import { TelemetrySetting } from "@roo/shared/TelemetrySetting" +import { vscode } from "@src/utils/vscode" +import { convertTextMateToHljs } from "@src/utils/textMateToHljs" + export interface ExtensionStateContextType extends ExtensionState { historyPreviewCollapsed?: boolean // Add the new state property didHydrateState: boolean @@ -22,7 +24,7 @@ export interface ExtensionStateContextType extends ExtensionState { currentCheckpoint?: string filePaths: string[] openedTabs: Array<{ label: string; isActive: boolean; path?: string }> - setApiConfiguration: (config: ApiConfiguration) => void + setApiConfiguration: (config: ProviderSettings) => void setCustomInstructions: (value?: string) => void setAlwaysAllowReadOnly: (value: boolean) => void setAlwaysAllowReadOnlyOutsideWorkspace: (value: boolean) => void @@ -65,7 +67,7 @@ export interface ExtensionStateContextType extends ExtensionState { requestDelaySeconds: number setRequestDelaySeconds: (value: number) => void setCurrentApiConfigName: (value: string) => void - setListApiConfigMeta: (value: ApiConfigMeta[]) => void + setListApiConfigMeta: (value: ProviderSettingsEntry[]) => void mode: Mode setMode: (value: Mode) => void setCustomModePrompts: (value: CustomModePrompts) => void @@ -182,7 +184,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode const [currentCheckpoint, setCurrentCheckpoint] = useState() const setListApiConfigMeta = useCallback( - (value: ApiConfigMeta[]) => setState((prevState) => ({ ...prevState, listApiConfigMeta: value })), + (value: ProviderSettingsEntry[]) => setState((prevState) => ({ ...prevState, listApiConfigMeta: value })), [], ) diff --git a/webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx b/webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx index 1ba2d87e9a..02e57b5e35 100644 --- a/webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx +++ b/webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx @@ -1,16 +1,16 @@ -// cd webview-ui && npx jest src/context/__tests__/ExtensionStateContext.test.tsx +// npx jest src/context/__tests__/ExtensionStateContext.test.tsx import { render, screen, act } from "@testing-library/react" import { ExtensionState } from "@roo/shared/ExtensionMessage" import { ExtensionStateContextProvider, useExtensionState, mergeExtensionState } from "../ExtensionStateContext" import { ExperimentId } from "@roo/shared/experiments" -import { ApiConfiguration } from "@roo/shared/api" +import { ProviderSettings } from "@roo/shared/api" -// Test component that consumes the context const TestComponent = () => { const { allowedCommands, setAllowedCommands, soundEnabled, showRooIgnoredFiles, setShowRooIgnoredFiles } = useExtensionState() + return (
{JSON.stringify(allowedCommands)}
@@ -26,9 +26,9 @@ const TestComponent = () => { ) } -// Test component for API configuration const ApiConfigTestComponent = () => { const { apiConfiguration, setApiConfiguration } = useExtensionState() + return (
{JSON.stringify(apiConfiguration)}
@@ -197,7 +197,7 @@ describe("mergeExtensionState", () => { customModes: [], maxOpenTabsContext: 20, maxWorkspaceFiles: 100, - apiConfiguration: { providerId: "openrouter" } as ApiConfiguration, + apiConfiguration: { providerId: "openrouter" } as ProviderSettings, telemetrySetting: "unset", showRooIgnoredFiles: true, renderContext: "sidebar", diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 89abe3dedd..0765fffeda 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -1,8 +1,8 @@ import i18next from "i18next" -import { ApiConfiguration, isRouterName, RouterModels } from "@roo/shared/api" +import { ProviderSettings, isRouterName, RouterModels } from "@roo/shared/api" -export function validateApiConfiguration(apiConfiguration: ApiConfiguration): string | undefined { +export function validateApiConfiguration(apiConfiguration: ProviderSettings): string | undefined { switch (apiConfiguration.apiProvider) { case "openrouter": if (!apiConfiguration.openRouterApiKey) { @@ -118,7 +118,7 @@ export function validateBedrockArn(arn: string, region?: string) { return { isValid: true, arnRegion, errorMessage: undefined } } -export function validateModelId(apiConfiguration: ApiConfiguration, routerModels?: RouterModels): string | undefined { +export function validateModelId(apiConfiguration: ProviderSettings, routerModels?: RouterModels): string | undefined { const provider = apiConfiguration.apiProvider ?? "" if (!isRouterName(provider)) {