diff --git a/package.json b/package.json index 943a62f..6717b67 100644 --- a/package.json +++ b/package.json @@ -46,25 +46,20 @@ "configuration": { "title": "Predicte Commit", "properties": { - "predicteCommit.modelPriority": { + "predicteCommit.provider": { + "type": "string", + "default": "mistral", + "description": "AI provider to use (e.g. 'mistral', 'local'). Matches the registered provider ID.", + "order": 1 + }, + "predicteCommit.models": { "type": "array", "items": { "type": "string" }, - "default": [ - "devstral-latest", - "devstral-small-latest" - ], - "description": "Order of Mistral models to attempt" - }, - "predicteCommit.provider": { - "type": "string", - "default": "mistral", - "enum": [ - "mistral", - "local" - ], - "description": "AI provider to use. 'local' uses an Ollama-compatible endpoint." + "default": [], + "description": "List of models to use for the active provider. If empty, the provider's defaults are used.", + "order": 2 }, "predicteCommit.ignoredFiles": { "type": "array", @@ -76,27 +71,32 @@ "*.svg", "dist/**" ], - "description": "Glob patterns (repo-relative) to exclude from staged diff context" + "description": "Glob patterns (repo-relative) to exclude from staged diff context", + "order": 3 }, "predicteCommit.useLocal": { "type": "boolean", "default": false, - "description": "Use local Ollama-compatible endpoint instead of Mistral cloud" + "description": "Use local Ollama-compatible endpoint instead of Mistral cloud", + "order": 10 }, "predicteCommit.localBaseUrl": { "type": "string", "default": "http://localhost:11434/v1", - "description": "Base URL for local provider (POST to /chat/completions)" + "description": "Base URL for local provider (POST to /chat/completions)", + "order": 11 }, "predicteCommit.localModel": { "type": "string", "default": "mistral", - "description": "Model name for local provider" + "description": "Model name for local provider", + "order": 12 }, "predicteCommit.debugLogging": { "type": "boolean", "default": false, - "description": "Log prompt payload and ignore-filter diagnostics to the Predicte Commit output channel" + "description": "Log prompt payload and ignore-filter diagnostics to the Predicte Commit output channel", + "order": 99 } } } diff --git a/src/core/config.ts b/src/core/config.ts index 87b4b32..d66e854 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; export type PredicteCommitConfig = { provider: string; - modelPriority: string[]; + models: string[]; ignoredFiles: string[]; useLocal: boolean; localBaseUrl: string; @@ -16,7 +16,7 @@ export function getConfig(): PredicteCommitConfig { const useLocal = cfg.get('useLocal', false); return { provider, - modelPriority: cfg.get('modelPriority', ['devstral-latest', 'devstral-small-latest']), + models: cfg.get('models', []), ignoredFiles: cfg.get('ignoredFiles', ['*-lock.json', '*.svg', 'dist/**']), useLocal, localBaseUrl: cfg.get('localBaseUrl', 'http://localhost:11434/v1'), diff --git a/src/providers/local/index.ts b/src/providers/local/index.ts index 582514a..0c26f5b 100644 --- a/src/providers/local/index.ts +++ b/src/providers/local/index.ts @@ -24,6 +24,7 @@ registerProvider({ id: 'local', label: 'Local (Ollama)', create: async (_context, config) => { - return new LocalProvider(config.localBaseUrl, config.localModel); + const model = config.models.length > 0 ? config.models[0] : config.localModel; + return new LocalProvider(config.localBaseUrl, model); }, }); diff --git a/src/providers/mistral/index.ts b/src/providers/mistral/index.ts index 2ce78bd..418ca41 100644 --- a/src/providers/mistral/index.ts +++ b/src/providers/mistral/index.ts @@ -4,17 +4,18 @@ import type { GenerateRequest, GenerateResult, ProviderClient } from '../../ai/t import { registerProvider } from '../../ai/registry'; export const MISTRAL_API_KEY = 'predicteCommit.mistralApiKey'; +const DEFAULT_MODELS = ['devstral-latest', 'devstral-small-latest']; export class MistralProvider implements ProviderClient { readonly id = 'mistral'; - constructor(private readonly apiKey: string, private readonly modelPriority: string[]) {} + constructor(private readonly apiKey: string, private readonly models: string[]) {} async generate(req: GenerateRequest): Promise { const url = 'https://api.mistral.ai/v1/chat/completions'; let lastErr: ProviderError | undefined; - for (const model of this.modelPriority) { + for (const model of this.models) { try { const text = await postChatCompletion(url, this.apiKey, { model, @@ -54,6 +55,7 @@ registerProvider({ configKey: MISTRAL_API_KEY, create: async (context, config) => { const key = (await context.secrets.get(MISTRAL_API_KEY)) ?? ''; - return new MistralProvider(key, config.modelPriority); + const models = config.models.length > 0 ? config.models : DEFAULT_MODELS; + return new MistralProvider(key, models); }, }); diff --git a/src/test/ai.test.ts b/src/test/ai.test.ts index 1383173..ae903a1 100644 --- a/src/test/ai.test.ts +++ b/src/test/ai.test.ts @@ -23,7 +23,7 @@ suite('AI Selector Test Suite', () => { const configMock: PredicteCommitConfig = { provider: 'test-provider', useLocal: false, - modelPriority: [], + models: [], ignoredFiles: [], localBaseUrl: '', localModel: '', @@ -41,7 +41,7 @@ suite('AI Selector Test Suite', () => { const configMock: PredicteCommitConfig = { provider: 'unknown-provider', useLocal: false, - modelPriority: [], + models: [], ignoredFiles: [], localBaseUrl: '', localModel: '', @@ -57,7 +57,7 @@ suite('AI Selector Test Suite', () => { const configMock: PredicteCommitConfig = { provider: 'mistral', useLocal: false, - modelPriority: [], + models: [], ignoredFiles: [], localBaseUrl: '', localModel: '', diff --git a/src/test/config.test.ts b/src/test/config.test.ts index 858e84c..7880b24 100644 --- a/src/test/config.test.ts +++ b/src/test/config.test.ts @@ -7,7 +7,7 @@ suite('Config Test Suite', () => { const cfgLocal: PredicteCommitConfig = { provider: 'mistral', useLocal: true, - modelPriority: [], + models: [], ignoredFiles: [], localBaseUrl: '', localModel: '',