diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 54a5c422..fe8e8b5d 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -52,7 +52,12 @@ export const defaultModelsOfProvider = { // 'qwen-2.5-coder-32b', // preview mode (experimental) ], mistral: [ // https://docs.mistral.ai/getting-started/models/models_overview/ - 'codestral-latest' + 'codestral-latest', + 'open-codestral-mamba', + 'mistral-small-latest', + 'mistral-large-latest', + 'ministral-3b-latest', + 'ministral-8b-latest', ], openAICompatible: [], // fallback } as const satisfies Record @@ -117,6 +122,41 @@ const modelOptionsDefaults: ModelOptions = { supportsReasoning: false, } +const mistralModelOptions = { + 'codestral-latest': { + contextWindow: 32_000, + maxOutputTokens: 4_096, + cost: { input: 0.00, output: 0.00 }, + supportsFIM: true, + supportsSystemMessage: 'system-role', + supportsTools: 'openai-style', + supportsReasoning: false, + }, + 'open-codestral-mamba': { + contextWindow: 32_000, + maxOutputTokens: 4_096, + cost: { input: 0.00, output: 0.00 }, + supportsFIM: true, + supportsSystemMessage: 'system-role', + supportsTools: 'openai-style', + supportsReasoning: false, + }, + 'mistral-large-latest': { + contextWindow: 32_000, + maxOutputTokens: 4_096, + cost: { input: 0.00, output: 0.00 }, + supportsFIM: false, + supportsSystemMessage: 'system-role', + supportsTools: 'openai-style', + supportsReasoning: false, + } +} as const satisfies { [s: string]: ModelOptions } + +const mistralSettings: ProviderSettings = { + ...mistralModelOptions, + modelOptions: {}, + modelOptionsFallback: (modelName) => extensiveModelFallback(modelName), +} const openSourceModelOptions_assumingOAICompat = { 'deepseekR1': { @@ -195,11 +235,9 @@ const openSourceModelOptions_assumingOAICompat = { supportsTools: false, supportsReasoning: false, }, + ...mistralModelOptions, } as const satisfies { [s: string]: Partial } - - - const extensiveModelFallback: ProviderSettings['modelOptionsFallback'] = (modelName) => { const toFallback = (opts: Omit): ModelOptions & { modelName: string } => { return { @@ -217,17 +255,12 @@ const extensiveModelFallback: ProviderSettings['modelOptionsFallback'] = (modelN if (modelName.includes('deepseek')) return toFallback({ ...openSourceModelOptions_assumingOAICompat.deepseekCoderV2, contextWindow: 32_000, maxOutputTokens: 4_096, }) if (modelName.includes('llama3')) return toFallback({ ...openSourceModelOptions_assumingOAICompat.llama3, contextWindow: 32_000, maxOutputTokens: 4_096, }) if (modelName.includes('qwen') && modelName.includes('2.5') && modelName.includes('coder')) return toFallback({ ...openSourceModelOptions_assumingOAICompat['qwen2.5coder'], contextWindow: 32_000, maxOutputTokens: 4_096, }) - if (modelName.includes('mistral-large-latest')) return toFallback({ ...openSourceModelOptions_assumingOAICompat['mistral-large-latest'], contextWindow: 32_000, maxOutputTokens: 4_096, }) - if (modelName.includes('codestral-latest')) return toFallback(mistralModelOptions['codestral-latest']) + if (modelName.includes('mistral')) return toFallback({ ...openSourceModelOptions_assumingOAICompat['mistral-large-latest'] }) + if (modelName.includes('codestral')) return toFallback({ ...openSourceModelOptions_assumingOAICompat['codestral-latest'] }) if (/\bo1\b/.test(modelName) || /\bo3\b/.test(modelName)) return toFallback(openAIModelOptions['o1']) return toFallback(modelOptionsDefaults) } - - - - - // ---------------- ANTHROPIC ---------------- const anthropicModelOptions = { 'claude-3-7-sonnet-20250219': { // https://docs.anthropic.com/en/docs/about-claude/models/all-models#model-comparison-table @@ -628,14 +661,6 @@ const openRouterSettings: ProviderSettings = { } -const mistralSettings: ProviderSettings = { - ...openSourceModelOptions_assumingOAICompat.mistral, - modelOptions: {}, - modelOptionsFallback: (modelName) => extensiveModelFallback(modelName), -} - - - // ---------------- model settings of everything above ---------------- const modelSettingsOfProvider: { [providerName in ProviderName]: ProviderSettings } = { @@ -653,7 +678,7 @@ const modelSettingsOfProvider: { [providerName in ProviderName]: ProviderSetting vLLM: vLLMSettings, ollama: ollamaSettings, openAICompatible: openaiCompatible, - + mistral: mistralSettings, // googleVertex: {}, // microsoftAzure: {}, } as const diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index 8041bbef..0f3e50e6 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -298,6 +298,12 @@ export const defaultSettingsOfProvider: SettingsOfProvider = { ...modelInfoOfDefaultModelNames(defaultModelsOfProvider.openAICompatible), _didFillInProviderSettings: undefined, }, + mistral: { // aggregator + ...defaultCustomSettings, + ...defaultProviderSettings.mistral, + ...modelInfoOfDefaultModelNames(defaultModelsOfProvider.mistral), + _didFillInProviderSettings: undefined, + }, ollama: { // aggregator ...defaultCustomSettings, ...defaultProviderSettings.ollama, diff --git a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts index 602373ac..24afe0c5 100644 --- a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts +++ b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts @@ -6,13 +6,8 @@ import Anthropic from '@anthropic-ai/sdk'; import { Ollama } from 'ollama'; import OpenAI, { ClientOptions } from 'openai'; - -/* Mistral standalone Fim endpoint */ -import { MistralCore } from "@mistralai/mistralai/core.js"; -import { fimComplete } from "@mistralai/mistralai/funcs/fimComplete.js"; -/* End Mistral standalone Fim endpoint */ - import { Model as OpenAIModel } from 'openai/resources/models.js'; + import { extractReasoningOnFinalMessage, extractReasoningOnTextWrapper } from '../../common/helpers/extractCodeFromResult.js'; import { LLMChatMessage, LLMFIMMessage, ModelListParams, OllamaModelResponse, OnError, OnFinalMessage, OnText } from '../../common/sendLLMMessageTypes.js'; import { defaultProviderSettings, displayInfoOfProviderName, ModelSelectionOptions, ProviderName, SettingsOfProvider } from '../../common/voidSettingsTypes.js'; @@ -126,7 +121,7 @@ const newOpenAICompatibleSDK = ({ settingsOfProvider, providerName, includeInPay } -const _sendOpenAICompatibleFIM = ({ messages: messages_, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, }: SendFIMParams_Internal) => { +const _sendOpenAICompatibleFIM = ({ messages: messages_, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, modelSelectionOptions, }: SendFIMParams_Internal) => { const { modelName, supportsFIM } = getModelCapabilities(providerName, modelName_) if (!supportsFIM) { if (modelName === modelName_) @@ -203,7 +198,7 @@ const _sendMistralFIM = ({ messages: messages_, onFinalMessage, onError, setting }) } -const _sendOpenAICompatibleChat = ({ messages: messages_, onText, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, tools: tools_ }: SendChatParams_Internal) => { +const _sendOpenAICompatibleChat = ({ messages: messages_, onText, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, modelSelectionOptions, tools: tools_ }: SendChatParams_Internal) => { const { modelName, supportsReasoning, @@ -516,6 +511,47 @@ const sendOllamaFIM = ({ messages: messages_, onFinalMessage, onError, settingsO }) } +//////// MISTRAL //////// +const sendMistralChat = ({ messages: messages_, onText, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, modelSelectionOptions }: SendChatParams_Internal) => { + _sendOpenAICompatibleChat({ + messages: messages_, + onText, + onFinalMessage, + onError, + settingsOfProvider, + modelName: modelName_, + _setAborter, + providerName, + aiInstructions, + modelSelectionOptions + }); +} + +const sendMistralFIM = ({ messages: messages_, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, modelSelectionOptions }: SendFIMParams_Internal) => { + const { modelName, supportsFIM } = getModelCapabilities(providerName, modelName_) + if (!supportsFIM) { + if (modelName === modelName_) + onError({ message: `Model ${modelName} does not support FIM.`, fullError: null }) + else + onError({ message: `Model ${modelName_} (${modelName}) does not support FIM.`, fullError: null }) + return + } + + prepareFIMMessage({ messages: messages_, aiInstructions }) + + _sendOpenAICompatibleFIM({ + messages: messages_, + onFinalMessage, + onError, + settingsOfProvider, + modelName: modelName_, + _setAborter, + providerName, + aiInstructions, + modelSelectionOptions, + onText: () => { } + }); +} type CallFnOfProvider = { @@ -547,11 +583,6 @@ export const sendLLMMessageToProviderImplementation = { sendFIM: null, list: null, }, - // mistral: { - // sendChat: , // TODO - // sendFIM: , // TODO // https://docs.mistral.ai/api/#tag/fim - // list: null, - // }, ollama: { sendChat: (params) => _sendOpenAICompatibleChat(params), sendFIM: sendOllamaFIM, @@ -583,31 +614,8 @@ export const sendLLMMessageToProviderImplementation = { list: null, }, mistral: { - sendChat: (params) => _sendOpenAICompatibleChat(params), - sendFIM: (params) => _sendMistralFIM(params), - list: null + sendChat: (params) => sendMistralChat(params), + sendFIM: (params) => sendMistralFIM(params), + list: null, }, -} satisfies CallFnOfProvider - - - - -/* -FIM info (this may be useful in the future with vLLM, but in most cases the only way to use FIM is if the provider explicitly supports it): - -qwen2.5-coder https://ollama.com/library/qwen2.5-coder/blobs/e94a8ecb9327 -<|fim_prefix|>{{ .Prompt }}<|fim_suffix|>{{ .Suffix }}<|fim_middle|> - -codestral https://ollama.com/library/codestral/blobs/51707752a87c -{{ .Prompt }} - -starcoder2 https://ollama.com/library/starcoder2/blobs/3b190e68fefe - - -{{ .Prompt }}{{ .Suffix }} -<|end_of_text|> - -codegemma https://ollama.com/library/codegemma:2b/blobs/48d9a8140749 -<|fim_prefix|>{{ .Prompt }}<|fim_suffix|>{{ .Suffix }}<|fim_middle|> - -*/ +} satisfies CallFnOfProvider \ No newline at end of file