mirror of
https://github.com/voideditor/void
synced 2026-05-24 01:48:25 +00:00
mistral corrections
This commit is contained in:
parent
5e83d419ce
commit
06513168c1
7 changed files with 3795 additions and 5798 deletions
9282
package-lock.json
generated
9282
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -41,4 +41,3 @@
|
|||
"https://voideditor.dev"
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,7 @@ const notifyYesUpdate = (notifService: INotificationService, res: { message?: st
|
|||
severity: Severity.Info,
|
||||
message: message,
|
||||
sticky: true,
|
||||
// progress: { worked: 0, total: 100 },
|
||||
// progress: { worked: 0, total: 100 },
|
||||
neverShowAgain: {
|
||||
id: 'voidUpdateNotification',
|
||||
isSecondary: false
|
||||
},
|
||||
progress: { worked: 0, total: 100 },
|
||||
actions: {
|
||||
primary: [{
|
||||
id: 'void.updater.update',
|
||||
|
|
|
|||
|
|
@ -59,16 +59,8 @@ export const defaultModelsOfProvider = {
|
|||
mistral: [ // https://docs.mistral.ai/getting-started/models/models_overview/
|
||||
'codestral-latest',
|
||||
'mistral-large-latest',
|
||||
'pixtral-large-latest',
|
||||
'mistral-saba-latest',
|
||||
'ministral-3b-latest',
|
||||
'ministral-8b-latest',
|
||||
'mistral-ocr-latest',
|
||||
'mistral-embed',
|
||||
'mistral-small-latest',
|
||||
'pixtral-12b-2409',
|
||||
'open-mistral-nemo',
|
||||
'open-codestral-mamba'
|
||||
],
|
||||
openAICompatible: [], // fallback
|
||||
} as const satisfies Record<ProviderName, string[]>
|
||||
|
|
@ -88,7 +80,7 @@ type ModelOptions = {
|
|||
cache_write?: number;
|
||||
}
|
||||
supportsSystemMessage: false | 'system-role' | 'developer-role' | 'separated';
|
||||
supportsTools: false | 'anthropic-style' | 'openai-style' | 'mistral-style';
|
||||
supportsTools: false | 'anthropic-style' | 'openai-style';
|
||||
supportsFIM: boolean;
|
||||
|
||||
reasoningCapabilities: false | {
|
||||
|
|
@ -134,115 +126,6 @@ const modelOptionsDefaults: ModelOptions = {
|
|||
reasoningCapabilities: false,
|
||||
}
|
||||
|
||||
const mistralModelOptions = {
|
||||
'codestral-latest': {
|
||||
contextWindow: 128_000,
|
||||
maxOutputTokens: 16_384,
|
||||
cost: { input: 0.000015, output: 0.000090 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'mistral-large-latest': {
|
||||
contextWindow: 131_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.000015, output: 0.000060 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'mistral-small-latest': {
|
||||
contextWindow: 131_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.000002, output: 0.000008 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'pixtral-large-latest': {
|
||||
contextWindow: 128_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.000025, output: 0.000075 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'mistral-saba-latest': {
|
||||
contextWindow: 32_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.000005, output: 0.000025 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: false,
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'ministral-3b-latest': {
|
||||
contextWindow: 131_000,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.000001, output: 0.000003 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'ministral-8b-latest': {
|
||||
contextWindow: 32_000,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.000001, output: 0.000005 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'mistral-ocr-latest': {
|
||||
contextWindow: 64_000,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.000010, output: 0.000020 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: false,
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'pixtral-12b-2409': {
|
||||
contextWindow: 128_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.000020, output: 0.000060 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'mistral-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'open-mistral-nemo': {
|
||||
contextWindow: 32_768,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.0, output: 0.0 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: false,
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'open-codestral-mamba': {
|
||||
contextWindow: 16_384,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.0, output: 0.0 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: false,
|
||||
reasoningCapabilities: false,
|
||||
}
|
||||
|
||||
} as const satisfies { [s: string]: ModelOptions }
|
||||
|
||||
const mistralSettings: ProviderSettings = {
|
||||
...mistralModelOptions,
|
||||
modelOptions: {},
|
||||
modelOptionsFallback: (modelName) => extensiveModelFallback(modelName),
|
||||
}
|
||||
|
||||
const openSourceModelOptions_assumingOAICompat = {
|
||||
'deepseekR1': {
|
||||
supportsFIM: false,
|
||||
|
|
@ -695,6 +578,64 @@ const deepseekSettings: ProviderSettings = {
|
|||
modelOptionsFallback: (modelName) => { return null }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------- MISTRAL ----------------
|
||||
|
||||
const mistralModelOptions = { // https://mistral.ai/products/la-plateforme#pricing https://docs.mistral.ai/getting-started/models/models_overview/#premier-models
|
||||
'mistral-large-latest': {
|
||||
contextWindow: 131_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 2.00, output: 6.00 },
|
||||
supportsFIM: false,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'codestral-latest': {
|
||||
contextWindow: 256_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.30, output: 0.90 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'mistral-saba-latest': {
|
||||
contextWindow: 32_000,
|
||||
maxOutputTokens: 8_192,
|
||||
cost: { input: 0.20, output: 0.60 },
|
||||
supportsFIM: true,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: false,
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'ministral-8b-latest': {
|
||||
contextWindow: 131_000,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.10, output: 0.10 },
|
||||
supportsFIM: false,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'ministral-3b-latest': {
|
||||
contextWindow: 131_000,
|
||||
maxOutputTokens: 4_096,
|
||||
cost: { input: 0.04, output: 0.04 },
|
||||
supportsFIM: false,
|
||||
supportsSystemMessage: 'system-role',
|
||||
supportsTools: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
} as const satisfies { [s: string]: ModelOptions }
|
||||
|
||||
const mistralSettings: ProviderSettings = {
|
||||
modelOptions: mistralModelOptions,
|
||||
modelOptionsFallback: (modelName) => { return null },
|
||||
}
|
||||
|
||||
|
||||
// ---------------- GROQ ----------------
|
||||
const groqModelOptions = { // https://console.groq.com/docs/models, https://groq.com/pricing/
|
||||
'llama-3.3-70b-versatile': {
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
|
|||
providerName === 'gemini' ? 'Get your [API Key here](https://aistudio.google.com/apikey).' :
|
||||
providerName === 'groq' ? 'Get your [API Key here](https://console.groq.com/keys).' :
|
||||
providerName === 'xAI' ? 'Get your [API Key here](https://console.x.ai).' :
|
||||
providerName === 'mistral' ? 'Get your [API Key here](https://mistral.ai/settings/keys).' :
|
||||
providerName === 'mistral' ? 'Get your [API Key here](https://console.mistral.ai/api-keys).' :
|
||||
providerName === 'openAICompatible' ? undefined :
|
||||
'',
|
||||
isPasswordField: true,
|
||||
|
|
@ -280,42 +280,42 @@ export const defaultSettingsOfProvider: SettingsOfProvider = {
|
|||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.xAI),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
groq: { // aggregator
|
||||
mistral: {
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.mistral,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.mistral),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
groq: { // aggregator (serves models from multiple providers)
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.groq,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.groq),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
openRouter: { // aggregator
|
||||
openRouter: { // aggregator (serves models from multiple providers)
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.openRouter,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.openRouter),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
openAICompatible: { // aggregator
|
||||
openAICompatible: { // aggregator (serves models from multiple providers)
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.openAICompatible,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.openAICompatible),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
ollama: { // aggregator
|
||||
ollama: { // aggregator (serves models from multiple providers)
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.ollama,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.ollama),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
vLLM: { // aggregator
|
||||
vLLM: { // aggregator (serves models from multiple providers)
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.vLLM,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.vLLM),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
mistral: { // aggregator
|
||||
...defaultCustomSettings,
|
||||
...defaultProviderSettings.mistral,
|
||||
...modelInfoOfDefaultModelNames(defaultModelsOfProvider.mistral),
|
||||
_didFillInProviderSettings: undefined,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -373,18 +373,15 @@ const prepareMessages_tools_anthropic = ({ messages }: { messages: InternalLLMCh
|
|||
|
||||
|
||||
|
||||
type PrepareMessagesTools = PrepareMessagesToolsAnthropic | PrepareMessagesToolsOpenAI | PrepareMessagesToolsMistral
|
||||
type PrepareMessagesTools = PrepareMessagesToolsAnthropic | PrepareMessagesToolsOpenAI
|
||||
|
||||
const prepareMessages_tools = ({ messages, supportsTools }: { messages: InternalLLMChatMessage[], supportsTools: false | 'anthropic-style' | 'openai-style' | 'mistral-style' }): { messages: PrepareMessagesTools } => {
|
||||
const prepareMessages_tools = ({ messages, supportsTools }: { messages: InternalLLMChatMessage[], supportsTools: false | 'anthropic-style' | 'openai-style' }): { messages: PrepareMessagesTools } => {
|
||||
if (!supportsTools) {
|
||||
return { messages: messages }
|
||||
}
|
||||
else if (supportsTools === 'anthropic-style') {
|
||||
return prepareMessages_tools_anthropic({ messages })
|
||||
}
|
||||
else if (supportsTools === 'mistral-style') {
|
||||
return prepareMessages_tools_mistral({ messages })
|
||||
}
|
||||
else if (supportsTools === 'openai-style') {
|
||||
return prepareMessages_tools_openai({ messages })
|
||||
}
|
||||
|
|
@ -456,12 +453,7 @@ const prepareMessages_noEmptyMessage = ({ messages }: { messages: PrepareMessage
|
|||
return { messages }
|
||||
}
|
||||
|
||||
type PrepareMessagesToolsMistral = PrepareMessagesToolsOpenAI;
|
||||
|
||||
// Implémentation pour Mistral qui réutilise celle d'OpenAI
|
||||
const prepareMessages_tools_mistral = ({ messages }: { messages: InternalLLMChatMessage[] }) => {
|
||||
return prepareMessages_tools_openai({ messages });
|
||||
};
|
||||
|
||||
// --- CHAT ---
|
||||
|
||||
|
|
@ -477,7 +469,7 @@ export const prepareMessages = ({
|
|||
messages: LLMChatMessage[],
|
||||
aiInstructions: string,
|
||||
supportsSystemMessage: false | 'system-role' | 'developer-role' | 'separated',
|
||||
supportsTools: false | 'anthropic-style' | 'openai-style' | 'mistral-style',
|
||||
supportsTools: false | 'anthropic-style' | 'openai-style',
|
||||
supportsAnthropicReasoningSignature: boolean,
|
||||
contextWindow: number,
|
||||
maxOutputTokens: number | null | undefined,
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@
|
|||
import Anthropic from '@anthropic-ai/sdk';
|
||||
import { Ollama } from 'ollama';
|
||||
import OpenAI, { ClientOptions } from 'openai';
|
||||
|
||||
// Mistral FIM
|
||||
import { MistralCore } from "@mistralai/mistralai/core.js";
|
||||
import { fimComplete } from "@mistralai/mistralai/funcs/fimComplete.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';
|
||||
|
|
@ -18,12 +17,6 @@ import { prepareFIMMessage, prepareMessages } from './preprocessLLMMessages.js';
|
|||
import { getSendableReasoningInfo, getModelCapabilities, getProviderCapabilities } from '../../common/modelCapabilities.js';
|
||||
import { InternalToolInfo, ToolName, isAToolName } from '../../common/toolsServiceTypes.js';
|
||||
|
||||
// Déclarer les types manquants pour résoudre les erreurs de linter
|
||||
declare const PrepareMessagesToolsOpenAI: any;
|
||||
declare const prepareMessages_tools_openai: any;
|
||||
declare const prepareMessages_tools_anthropic: any;
|
||||
declare const InternalLLMChatMessage: any;
|
||||
declare const PrepareMessagesTools: any;
|
||||
|
||||
type InternalCommonMessageParams = {
|
||||
aiInstructions: string;
|
||||
|
|
@ -434,43 +427,11 @@ const sendAnthropicChat = ({ messages: messages_, providerName, onText, onFinalM
|
|||
_setAborter(() => stream.controller.abort())
|
||||
}
|
||||
|
||||
//////// MISTRAL ////////
|
||||
const _sendMistralChat = ({ messages: messages_, onText, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, modelSelectionOptions, tools: tools_ }: SendChatParams_Internal) => {
|
||||
const {
|
||||
supportsSystemMessage,
|
||||
supportsTools,
|
||||
contextWindow,
|
||||
maxOutputTokens,
|
||||
} = getModelCapabilities(providerName, modelName_);
|
||||
|
||||
// Preprocess messages for Mistral format
|
||||
prepareMessages({
|
||||
messages: messages_,
|
||||
aiInstructions,
|
||||
supportsSystemMessage,
|
||||
supportsTools,
|
||||
supportsAnthropicReasoningSignature: false,
|
||||
contextWindow,
|
||||
maxOutputTokens
|
||||
});
|
||||
|
||||
// For Mistral, we use the OpenAI compatible implementation
|
||||
_sendOpenAICompatibleChat({
|
||||
messages: messages_,
|
||||
onText,
|
||||
onFinalMessage,
|
||||
onError,
|
||||
settingsOfProvider,
|
||||
modelName: modelName_,
|
||||
_setAborter,
|
||||
providerName,
|
||||
aiInstructions,
|
||||
modelSelectionOptions,
|
||||
tools: tools_
|
||||
});
|
||||
}
|
||||
|
||||
const _sendMistralFIM = ({ messages: messages_, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, modelSelectionOptions }: SendFIMParams_Internal) => {
|
||||
// ------------ MISTRAL ------------
|
||||
// https://docs.mistral.ai/api/#tag/fim
|
||||
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_)
|
||||
|
|
@ -479,25 +440,23 @@ const _sendMistralFIM = ({ messages: messages_, onFinalMessage, onError, setting
|
|||
onError({ message: `Model ${modelName_} (${modelName}) does not support FIM.`, fullError: null })
|
||||
return
|
||||
}
|
||||
|
||||
prepareFIMMessage({ messages: messages_, aiInstructions })
|
||||
const messages = prepareFIMMessage({ messages: messages_, aiInstructions })
|
||||
|
||||
const mistral = new MistralCore({ apiKey: settingsOfProvider.mistral.apiKey })
|
||||
|
||||
fimComplete(
|
||||
mistral, {
|
||||
model: modelName,
|
||||
prompt: messages_.prefix,
|
||||
suffix: messages_.suffix,
|
||||
stream: false,
|
||||
topP: 1,
|
||||
stop: messages_.stopTokens
|
||||
},
|
||||
)
|
||||
fimComplete(mistral,
|
||||
{
|
||||
model: modelName,
|
||||
prompt: messages.prefix,
|
||||
suffix: messages.suffix,
|
||||
stream: false,
|
||||
maxTokens: messages.maxTokens,
|
||||
stop: messages.stopTokens,
|
||||
})
|
||||
.then(async response => {
|
||||
let content = response?.ok ? response.value.choices?.[0]?.message?.content : '';
|
||||
const fullText = typeof content === 'string' ? content :
|
||||
Array.isArray(content) ? content.map(chunk => chunk.type === 'text' ? chunk.text : '').join('') : '';
|
||||
let content = response?.ok ? response.value.choices?.[0]?.message?.content ?? '' : '';
|
||||
const fullText = typeof content === 'string' ? content
|
||||
: content.map(chunk => (chunk.type === 'text' ? chunk.text : '')).join('')
|
||||
|
||||
onFinalMessage({ fullText, fullReasoning: '', anthropicReasoning: null });
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
@ -505,9 +464,6 @@ const _sendMistralFIM = ({ messages: messages_, onFinalMessage, onError, setting
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// // in future, can do tool_use streaming in anthropic, but it's pretty fast even without streaming...
|
||||
// const toolCallOfIndex: { [index: string]: { name: string, args: string } } = {}
|
||||
// stream.on('streamEvent', e => {
|
||||
|
|
@ -622,8 +578,8 @@ export const sendLLMMessageToProviderImplementation = {
|
|||
list: null,
|
||||
},
|
||||
mistral: {
|
||||
sendChat: (params) => _sendMistralChat(params),
|
||||
sendFIM: (params) => _sendMistralFIM(params),
|
||||
sendChat: (params) => _sendOpenAICompatibleChat(params),
|
||||
sendFIM: (params) => sendMistralFIM(params),
|
||||
list: null,
|
||||
},
|
||||
ollama: {
|
||||
|
|
@ -671,7 +627,7 @@ codestral https://ollama.com/library/codestral/blobs/51707752a87c
|
|||
[SUFFIX]{{ .Suffix }}[PREFIX] {{ .Prompt }}
|
||||
|
||||
deepseek-coder-v2 https://ollama.com/library/deepseek-coder-v2/blobs/22091531faf0
|
||||
{{ .Prompt }}
|
||||
<|fim▁begin|>{{ .Prompt }}<|fim▁hole|>{{ .Suffix }}<|fim▁end|>
|
||||
|
||||
starcoder2 https://ollama.com/library/starcoder2/blobs/3b190e68fefe
|
||||
<file_sep>
|
||||
|
|
|
|||
Loading…
Reference in a new issue