Mistral v2

This commit is contained in:
Jérôme Commaret 2024-12-27 14:46:02 +01:00
parent d85a316536
commit 4729e4dac3
6 changed files with 159 additions and 6 deletions

12
package-lock.json generated
View file

@ -67,6 +67,7 @@
"yazl": "^2.4.3"
},
"devDependencies": {
"@mistralai/mistralai": "^1.3.5",
"@playwright/test": "^1.46.1",
"@swc/core": "1.3.62",
"@types/cookie": "^0.3.3",
@ -1949,6 +1950,17 @@
"exenv-es6": "^1.1.1"
}
},
"node_modules/@mistralai/mistralai": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.5.tgz",
"integrity": "sha512-yC91oJ5ScEPqbXmv3mJTwTFgu/ZtsYoOPOhaVXSsy6x4zXTqTI57yEC1flC9uiA8GpG/yhpn2BBUXF95+U9Blw==",
"dev": true,
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19",
"zod": ">= 3"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",

View file

@ -131,6 +131,7 @@
"yazl": "^2.4.3"
},
"devDependencies": {
"@mistralai/mistralai": "^1.3.5",
"@playwright/test": "^1.46.1",
"@swc/core": "1.3.62",
"@types/cookie": "^0.3.3",

62
src/package-lock.json generated Normal file
View file

@ -0,0 +1,62 @@
{
"name": "src",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@mistralai/mistralai": "^1.3.5",
"zod": "^3.23.8"
}
},
"node_modules/@mistralai/mistralai": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.5.tgz",
"integrity": "sha512-yC91oJ5ScEPqbXmv3mJTwTFgu/ZtsYoOPOhaVXSsy6x4zXTqTI57yEC1flC9uiA8GpG/yhpn2BBUXF95+U9Blw==",
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19",
"zod": ">= 3"
}
},
"node_modules/react": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.25.0"
},
"peerDependencies": {
"react": "^19.0.0"
}
},
"node_modules/scheduler": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz",
"integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==",
"license": "MIT",
"peer": true
},
"node_modules/zod": {
"version": "3.23.8",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}

View file

@ -1,4 +1,3 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Glass Devtools, Inc. All rights reserved.
* Void Editor additions licensed under the AGPL 3.0 License.
@ -67,7 +66,18 @@ export const defaultGeminiModels = modelInfoOfDefaultNames([
'gemini-1.0-pro'
])
export const defaultMistralModels = modelInfoOfDefaultNames([
"open-codestral-mamba",
"open-mistral-nemo",
"pixtral-12b-2409",
"mistral-large-latest",
"pixtral-large-latest",
"ministral-3b-latest",
"ministral-8b-latest",
"mistral-small-latest",
"codestral-latest",
"mistral-embed"
])
// export const parseMaxTokensStr = (maxTokensStr: string) => {
// // parse the string but only if the full string is a valid number, eg parseInt('100abc') should return NaN
@ -117,6 +127,9 @@ export const defaultProviderSettings = {
apiKey: '',
},
groq: {
apiKey: '',
},
mistral: {
apiKey: ''
}
} as const
@ -196,6 +209,11 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn
title: 'Groq',
}
}
else if (providerName === 'mistral') {
return {
title: 'Mistral',
}
}
throw new Error(`descOfProviderName: Unknown provider name: "${providerName}"`)
}
@ -214,16 +232,18 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
providerName === 'openRouter' ? 'sk-or-key...' : // sk-or-v1-key
providerName === 'gemini' ? 'key...' :
providerName === 'groq' ? 'gsk_key...' :
providerName === 'openAICompatible' ? 'sk-key...' :
'(never)',
providerName === 'mistral' ? 'api-key...' :
providerName === 'openAICompatible' ? 'sk-key...' :
'(never)',
subTextMd: providerName === 'anthropic' ? 'Get your [API Key here](https://console.anthropic.com/settings/keys).' :
providerName === 'openAI' ? 'Get your [API Key here](https://platform.openai.com/api-keys).' :
providerName === 'openRouter' ? 'Get your [API Key here](https://openrouter.ai/settings/keys).' :
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 === 'openAICompatible' ? undefined :
undefined,
providerName === 'mistral' ? 'Get your [API Key here](https://console.mistral.ai/api-keys/).' :
providerName === 'openAICompatible' ? undefined :
undefined,
}
}
else if (settingName === 'endpoint') {
@ -265,6 +285,8 @@ const defaultCustomSettings: Record<CustomSettingName, undefined> = {
endpoint: undefined,
}
export const voidInitModelOptions = {
anthropic: {
models: defaultAnthropicModels,
@ -287,6 +309,9 @@ export const voidInitModelOptions = {
groq: {
models: defaultGroqModels,
},
mistral: {
models: defaultMistralModels,
}
}
@ -334,6 +359,12 @@ export const defaultSettingsOfProvider: SettingsOfProvider = {
...voidInitModelOptions.openAICompatible,
enabled: undefined,
},
mistral: {
...defaultCustomSettings,
...defaultProviderSettings.mistral,
...voidInitModelOptions.mistral,
enabled: undefined,
}
}

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Glass Devtools, Inc. All rights reserved.
* Void Editor additions licensed under the AGPL 3.0 License.
*--------------------------------------------------------------------------------------------*/
import MistralClient from '@mistralai/mistralai';
import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js';
// Mistral
export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => {
let fullText = '';
const thisConfig = settingsOfProvider.mistral;
const mistral = new MistralClient({
apiKey: thisConfig.apiKey
});
try {
const stream = await mistral.chat.stream({
model: modelName,
messages: messages,
});
_setAborter(() => stream.controller.abort());
for await (const chunk of stream) {
const newText = chunk.choices[0]?.delta?.content || '';
if (newText) {
fullText += newText;
onText({ newText, fullText });
}
}
onFinalMessage({ fullText });
} catch (error) {
if (error.status === 401) {
onError({ message: 'Invalid API key.', fullError: error });
} else {
onError({ message: error + '', fullError: error });
}
}
};

View file

@ -11,6 +11,7 @@ import { sendOllamaMsg } from './ollama.js';
import { sendOpenAIMsg } from './openai.js';
import { sendGeminiMsg } from './gemini.js';
import { sendGroqMsg } from './groq.js';
import { sendMistralMsg } from './mistral.js';
export const sendLLMMessage = ({
messages,
@ -96,6 +97,9 @@ export const sendLLMMessage = ({
case 'groq':
sendGroqMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName });
break;
case 'mistral':
sendMistralMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName });
break;
default:
onError({ message: `Error: Void provider was "${providerName}", which is not recognized.`, fullError: null })
break;