Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vscode from 'vscode';

export type PredicteCommitConfig = {
provider: string;
modelPriority: string[];
models: string[];
ignoredFiles: string[];
useLocal: boolean;
localBaseUrl: string;
Expand All @@ -16,7 +16,7 @@ export function getConfig(): PredicteCommitConfig {
const useLocal = cfg.get<boolean>('useLocal', false);
return {
provider,
modelPriority: cfg.get<string[]>('modelPriority', ['devstral-latest', 'devstral-small-latest']),
models: cfg.get<string[]>('models', []),
ignoredFiles: cfg.get<string[]>('ignoredFiles', ['*-lock.json', '*.svg', 'dist/**']),
useLocal,
localBaseUrl: cfg.get<string>('localBaseUrl', 'http://localhost:11434/v1'),
Expand Down
3 changes: 2 additions & 1 deletion src/providers/local/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
},
});
8 changes: 5 additions & 3 deletions src/providers/mistral/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<GenerateResult> {
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,
Expand Down Expand Up @@ -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);
},
});
6 changes: 3 additions & 3 deletions src/test/ai.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ suite('AI Selector Test Suite', () => {
const configMock: PredicteCommitConfig = {
provider: 'test-provider',
useLocal: false,
modelPriority: [],
models: [],
ignoredFiles: [],
localBaseUrl: '',
localModel: '',
Expand All @@ -41,7 +41,7 @@ suite('AI Selector Test Suite', () => {
const configMock: PredicteCommitConfig = {
provider: 'unknown-provider',
useLocal: false,
modelPriority: [],
models: [],
ignoredFiles: [],
localBaseUrl: '',
localModel: '',
Expand All @@ -57,7 +57,7 @@ suite('AI Selector Test Suite', () => {
const configMock: PredicteCommitConfig = {
provider: 'mistral',
useLocal: false,
modelPriority: [],
models: [],
ignoredFiles: [],
localBaseUrl: '',
localModel: '',
Expand Down
2 changes: 1 addition & 1 deletion src/test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ suite('Config Test Suite', () => {
const cfgLocal: PredicteCommitConfig = {
provider: 'mistral',
useLocal: true,
modelPriority: [],
models: [],
ignoredFiles: [],
localBaseUrl: '',
localModel: '',
Expand Down