From 4729e4dac3d9c071931f33e3b2d0fd4d07e3476c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Fri, 27 Dec 2024 14:46:02 +0100 Subject: [PATCH 01/21] Mistral v2 --- package-lock.json | 12 ++++ package.json | 1 + src/package-lock.json | 62 +++++++++++++++++++ .../platform/void/common/voidSettingsTypes.ts | 43 +++++++++++-- .../void/electron-main/llmMessage/mistral.ts | 43 +++++++++++++ .../llmMessage/sendLLMMessage.ts | 4 ++ 6 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 src/package-lock.json create mode 100644 src/vs/platform/void/electron-main/llmMessage/mistral.ts diff --git a/package-lock.json b/package-lock.json index 307f13cf..732ab358 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index ab294d7b..5039e401 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/package-lock.json b/src/package-lock.json new file mode 100644 index 00000000..3b02711d --- /dev/null +++ b/src/package-lock.json @@ -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" + } + } + } +} diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 1b1b2ff7..16d66900 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -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 = { 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, + } } diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts new file mode 100644 index 00000000..3ba71d37 --- /dev/null +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -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 }); + } + } +}; diff --git a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts index 9e106f97..a4ccad91 100644 --- a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts +++ b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts @@ -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; From 4065c5b504a8c5bc4a04aa57721e7f678055aa6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Fri, 27 Dec 2024 16:37:27 +0100 Subject: [PATCH 02/21] Mistral implementation : Working --- package-lock.json | 15 ++- package.json | 5 +- .../void/electron-main/llmMessage/mistral.ts | 94 ++++++++++++++++--- 3 files changed, 95 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 732ab358..91088265 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", + "@mistralai/mistralai": "^1.3.5", "@parcel/watcher": "2.1.0", "@rrweb/record": "^2.0.0-alpha.17", "@rrweb/types": "^2.0.0-alpha.17", @@ -64,10 +65,10 @@ "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.1.0", "yauzl": "^3.0.0", - "yazl": "^2.4.3" + "yazl": "^2.4.3", + "zod": "^3.24.1" }, "devDependencies": { - "@mistralai/mistralai": "^1.3.5", "@playwright/test": "^1.46.1", "@swc/core": "1.3.62", "@types/cookie": "^0.3.3", @@ -1954,7 +1955,6 @@ "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", @@ -23241,6 +23241,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 5039e401..23eee099 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", + "@mistralai/mistralai": "^1.3.5", "@parcel/watcher": "2.1.0", "@rrweb/record": "^2.0.0-alpha.17", "@rrweb/types": "^2.0.0-alpha.17", @@ -128,10 +129,10 @@ "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.1.0", "yauzl": "^3.0.0", - "yazl": "^2.4.3" + "yazl": "^2.4.3", + "zod": "^3.24.1" }, "devDependencies": { - "@mistralai/mistralai": "^1.3.5", "@playwright/test": "^1.46.1", "@swc/core": "1.3.62", "@types/cookie": "^0.3.3", diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts index 3ba71d37..9a32e2b3 100644 --- a/src/vs/platform/void/electron-main/llmMessage/mistral.ts +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -1,43 +1,109 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Glass Devtools, Inc. All rights reserved. + * Mistral implementation by Jérôme Commaret (https://github.com/jcommaret) * Void Editor additions licensed under the AGPL 3.0 License. *--------------------------------------------------------------------------------------------*/ -import MistralClient from '@mistralai/mistralai'; +import { Mistral } from '@mistralai/mistralai'; import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; +interface MistralMessage { + role: 'user' | 'assistant'; + content: string; +} + +interface MistralChunk { + data: { + id: string; + object: string; + created: number; + model: string; + choices: Array<{ + index: number; + delta: { + content?: string; + role?: string; + }; + finishReason: string | null; + }>; + }; +} + // Mistral export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { let fullText = ''; const thisConfig = settingsOfProvider.mistral; - const mistral = new MistralClient({ + if (!thisConfig.apiKey) { + onError({ message: 'Mistral API key not configured.', fullError: new Error('No API key') }); + return; + } + + const mistral = new Mistral({ apiKey: thisConfig.apiKey }); try { + // Check if there are messages to process + if (!messages || messages.length === 0) { + onError({ message: 'No messages to process.', fullError: new Error('No messages provided') }); + return; + } + + // Convert messages for Mistral + const mistralMessages = messages + .filter(msg => msg.role !== 'system') // Ignore system messages + .map(msg => ({ + role: msg.role === 'assistant' ? 'assistant' : 'user', + content: msg.content.trim() + })) as MistralMessage[]; + + // Ensure there is at least one message + if (mistralMessages.length === 0) { + onError({ message: 'No valid messages to send.', fullError: new Error('No valid messages') }); + return; + } + + // Ensure the last message is from the user + if (mistralMessages[mistralMessages.length - 1].role === 'assistant') { + mistralMessages.push({ + role: 'user', + content: 'Continue.' + }); + } + const stream = await mistral.chat.stream({ model: modelName, - messages: messages, + messages: mistralMessages, + temperature: 0.7, + maxTokens: 2048 }); - _setAborter(() => stream.controller.abort()); + _setAborter(() => { }); // Mistral does not provide an abort method for await (const chunk of stream) { - const newText = chunk.choices[0]?.delta?.content || ''; - if (newText) { - fullText += newText; - onText({ newText, fullText }); + if (typeof chunk === 'object' && chunk && 'data' in chunk) { + const { data } = chunk as MistralChunk; + if (data.choices?.[0]?.delta?.content) { + const newText = data.choices[0].delta.content; + 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 }); + if (!fullText) { + onError({ message: 'No response received from Mistral.', fullError: new Error('No response content') }); + return; } + + onFinalMessage({ fullText }); + } catch (error: any) { + const errorMessage = error.message || JSON.stringify(error); + onError({ + message: `Mistral Error: ${errorMessage}`, + fullError: error + }); } }; From 5453acdb1935c71bb8bbdbbb7362a14da8ff5925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Fri, 3 Jan 2025 20:21:46 +0100 Subject: [PATCH 03/21] Mistral : update --- .gitignore | 1 + package-lock.json | 4 ++-- src/vs/platform/void/common/voidSettingsTypes.ts | 6 ------ 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 5daf304c..fcdb9b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ product.overrides.json *.snap.actual .vscode-test .tmp/ +.tool-versions diff --git a/package-lock.json b/package-lock.json index 40c7bcf1..e7570e5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "void-dev", - "version": "1.0.0", + "version": "1.94.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "void-dev", - "version": "1.0.0", + "version": "1.94.0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 5f50e320..35a20c35 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -380,12 +380,6 @@ export const defaultSettingsOfProvider: SettingsOfProvider = { ...voidInitModelOptions.openAICompatible, _enabled: undefined, }, - mistral: { - ...defaultCustomSettings, - ...defaultProviderSettings.mistral, - ...voidInitModelOptions.mistral, - _enabled: undefined, - }, mistral: { ...defaultCustomSettings, ...defaultProviderSettings.mistral, From 9abc3ad3dcfdd9867f2b4df7bb1c3bdc63df20ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Fri, 10 Jan 2025 23:46:58 +0100 Subject: [PATCH 04/21] _aborter set --- .../void/electron-main/llmMessage/mistral.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts index 9a32e2b3..6d59b6a2 100644 --- a/src/vs/platform/void/electron-main/llmMessage/mistral.ts +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -32,6 +32,7 @@ interface MistralChunk { // Mistral export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { let fullText = ''; + let aborted = false; const thisConfig = settingsOfProvider.mistral; @@ -44,6 +45,11 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, apiKey: thisConfig.apiKey }); + // Définir l'aborter avant de commencer le streaming + _setAborter(() => { + aborted = true; + }); + try { // Check if there are messages to process if (!messages || messages.length === 0) { @@ -80,9 +86,12 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, maxTokens: 2048 }); - _setAborter(() => { }); // Mistral does not provide an abort method - for await (const chunk of stream) { + // Vérifier si la requête a été abandonnée + if (aborted) { + return; + } + if (typeof chunk === 'object' && chunk && 'data' in chunk) { const { data } = chunk as MistralChunk; if (data.choices?.[0]?.delta?.content) { @@ -93,6 +102,11 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, } } + // Vérifier une dernière fois si la requête a été abandonnée + if (aborted) { + return; + } + if (!fullText) { onError({ message: 'No response received from Mistral.', fullError: new Error('No response content') }); return; From 2701226ef316665f989cc3e92f5e4b624b9c800c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Fri, 10 Jan 2025 23:57:40 +0100 Subject: [PATCH 05/21] Translate abort comments --- src/vs/platform/void/electron-main/llmMessage/mistral.ts | 6 +++--- void | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 160000 void diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts index 6d59b6a2..ca32fd49 100644 --- a/src/vs/platform/void/electron-main/llmMessage/mistral.ts +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -45,7 +45,7 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, apiKey: thisConfig.apiKey }); - // Définir l'aborter avant de commencer le streaming + // Define the aborter before staring the stream _setAborter(() => { aborted = true; }); @@ -87,7 +87,7 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, }); for await (const chunk of stream) { - // Vérifier si la requête a été abandonnée + // Check if the request has been aborted if (aborted) { return; } @@ -102,7 +102,7 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, } } - // Vérifier une dernière fois si la requête a été abandonnée + // Check one last time if the request has been aborted if (aborted) { return; } diff --git a/void b/void new file mode 160000 index 00000000..5083b8e9 --- /dev/null +++ b/void @@ -0,0 +1 @@ +Subproject commit 5083b8e971e48ae1001e5c8ceee7b010bcea3640 From 278c52bd353a3c690f683c4bbb0bd4d2de0194cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Mon, 13 Jan 2025 22:48:43 +0100 Subject: [PATCH 06/21] Merging everything here --- .gitignore | 1 + package-lock.json | 24 +++- package.json | 4 +- src/package-lock.json | 62 +++++++++ .../platform/void/common/voidSettingsTypes.ts | 42 +++++- .../void/electron-main/llmMessage/mistral.ts | 123 ++++++++++++++++++ .../llmMessage/sendLLMMessage.ts | 4 + void | 1 + 8 files changed, 254 insertions(+), 7 deletions(-) create mode 100644 src/package-lock.json create mode 100644 src/vs/platform/void/electron-main/llmMessage/mistral.ts create mode 160000 void diff --git a/.gitignore b/.gitignore index 5daf304c..fcdb9b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ product.overrides.json *.snap.actual .vscode-test .tmp/ +.tool-versions diff --git a/package-lock.json b/package-lock.json index 91937c1c..510d7228 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", + "@mistralai/mistralai": "^1.3.5", "@parcel/watcher": "2.1.0", "@rrweb/record": "^2.0.0-alpha.17", "@rrweb/types": "^2.0.0-alpha.17", @@ -65,7 +66,8 @@ "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.1.0", "yauzl": "^3.0.0", - "yazl": "^2.4.3" + "yazl": "^2.4.3", + "zod": "^3.24.1" }, "devDependencies": { "@playwright/test": "^1.46.1", @@ -2366,6 +2368,7 @@ "exenv-es6": "^1.1.1" } }, +<<<<<<< HEAD "node_modules/@next/env": { "version": "15.1.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.4.tgz", @@ -2507,6 +2510,16 @@ ], "engines": { "node": ">= 10" +======= + "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" +>>>>>>> fork/feat-mistral-new } }, "node_modules/@nodelib/fs.scandir": { @@ -24104,6 +24117,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 9833d8a9..ebd91306 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", + "@mistralai/mistralai": "^1.3.5", "@parcel/watcher": "2.1.0", "@rrweb/record": "^2.0.0-alpha.17", "@rrweb/types": "^2.0.0-alpha.17", @@ -132,7 +133,8 @@ "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.1.0", "yauzl": "^3.0.0", - "yazl": "^2.4.3" + "yazl": "^2.4.3", + "zod": "^3.24.1" }, "devDependencies": { "@playwright/test": "^1.46.1", diff --git a/src/package-lock.json b/src/package-lock.json new file mode 100644 index 00000000..3b02711d --- /dev/null +++ b/src/package-lock.json @@ -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" + } + } + } +} diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 2b068780..acc81f02 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -94,7 +94,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 @@ -144,6 +155,9 @@ export const defaultProviderSettings = { apiKey: '', }, groq: { + apiKey: '', + }, + mistral: { apiKey: '' } } as const @@ -224,6 +238,11 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn title: 'Groq', } } + else if (providerName === 'mistral') { + return { + title: 'Mistral', + } + } throw new Error(`descOfProviderName: Unknown provider name: "${providerName}"`) } @@ -242,16 +261,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' ? 'Add any OpenAI-Compatible endpoint.' : - undefined, + providerName === 'mistral' ? 'Get your [API Key here](https://console.mistral.ai/api-keys/).' : + providerName === 'openAICompatible' ? undefined : + undefined, } } else if (settingName === 'endpoint') { @@ -293,6 +314,8 @@ const defaultCustomSettings: Record = { endpoint: undefined, } + + export const voidInitModelOptions = { anthropic: { models: defaultAnthropicModels, @@ -315,6 +338,9 @@ export const voidInitModelOptions = { groq: { models: defaultGroqModels, }, + mistral: { + models: defaultMistralModels, + } } @@ -362,6 +388,12 @@ export const defaultSettingsOfProvider: SettingsOfProvider = { ...voidInitModelOptions.openAICompatible, _enabled: undefined, }, + mistral: { + ...defaultCustomSettings, + ...defaultProviderSettings.mistral, + ...voidInitModelOptions.mistral, + _enabled: undefined, + } } diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts new file mode 100644 index 00000000..ca32fd49 --- /dev/null +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -0,0 +1,123 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Glass Devtools, Inc. All rights reserved. + * Mistral implementation by Jérôme Commaret (https://github.com/jcommaret) + * Void Editor additions licensed under the AGPL 3.0 License. + *--------------------------------------------------------------------------------------------*/ + +import { Mistral } from '@mistralai/mistralai'; +import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; + +interface MistralMessage { + role: 'user' | 'assistant'; + content: string; +} + +interface MistralChunk { + data: { + id: string; + object: string; + created: number; + model: string; + choices: Array<{ + index: number; + delta: { + content?: string; + role?: string; + }; + finishReason: string | null; + }>; + }; +} + +// Mistral +export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { + let fullText = ''; + let aborted = false; + + const thisConfig = settingsOfProvider.mistral; + + if (!thisConfig.apiKey) { + onError({ message: 'Mistral API key not configured.', fullError: new Error('No API key') }); + return; + } + + const mistral = new Mistral({ + apiKey: thisConfig.apiKey + }); + + // Define the aborter before staring the stream + _setAborter(() => { + aborted = true; + }); + + try { + // Check if there are messages to process + if (!messages || messages.length === 0) { + onError({ message: 'No messages to process.', fullError: new Error('No messages provided') }); + return; + } + + // Convert messages for Mistral + const mistralMessages = messages + .filter(msg => msg.role !== 'system') // Ignore system messages + .map(msg => ({ + role: msg.role === 'assistant' ? 'assistant' : 'user', + content: msg.content.trim() + })) as MistralMessage[]; + + // Ensure there is at least one message + if (mistralMessages.length === 0) { + onError({ message: 'No valid messages to send.', fullError: new Error('No valid messages') }); + return; + } + + // Ensure the last message is from the user + if (mistralMessages[mistralMessages.length - 1].role === 'assistant') { + mistralMessages.push({ + role: 'user', + content: 'Continue.' + }); + } + + const stream = await mistral.chat.stream({ + model: modelName, + messages: mistralMessages, + temperature: 0.7, + maxTokens: 2048 + }); + + for await (const chunk of stream) { + // Check if the request has been aborted + if (aborted) { + return; + } + + if (typeof chunk === 'object' && chunk && 'data' in chunk) { + const { data } = chunk as MistralChunk; + if (data.choices?.[0]?.delta?.content) { + const newText = data.choices[0].delta.content; + fullText += newText; + onText({ newText, fullText }); + } + } + } + + // Check one last time if the request has been aborted + if (aborted) { + return; + } + + if (!fullText) { + onError({ message: 'No response received from Mistral.', fullError: new Error('No response content') }); + return; + } + + onFinalMessage({ fullText }); + } catch (error: any) { + const errorMessage = error.message || JSON.stringify(error); + onError({ + message: `Mistral Error: ${errorMessage}`, + fullError: error + }); + } +}; diff --git a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts index b3970614..95716e81 100644 --- a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts +++ b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts @@ -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, @@ -97,6 +98,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; diff --git a/void b/void new file mode 160000 index 00000000..5083b8e9 --- /dev/null +++ b/void @@ -0,0 +1 @@ +Subproject commit 5083b8e971e48ae1001e5c8ceee7b010bcea3640 From cd9bb6a07d223b179ebf7cc18f4b6ff91b3fb44f Mon Sep 17 00:00:00 2001 From: Piyu-Pika Date: Tue, 21 Jan 2025 21:46:02 +0530 Subject: [PATCH 07/21] Add new experimental Gemini models to default settings --- src/vs/platform/void/common/voidSettingsTypes.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 2577bfe7..d141ab32 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -91,7 +91,10 @@ export const defaultGeminiModels = modelInfoOfDefaultNames([ 'gemini-1.5-flash', 'gemini-1.5-pro', 'gemini-1.5-flash-8b', - 'gemini-1.0-pro' + 'gemini-1.0-pro', + 'gemini-2.0-flash-exp', + 'gemini-2.0-flash-thinking-exp-1219', + 'learnlm-1.5-pro-experimental' ]) From 67c557b7b9adc77a05126664713fcd9c3c1a36ea Mon Sep 17 00:00:00 2001 From: Andrew Pareles <43356051+andrewpareles@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:02:16 -0800 Subject: [PATCH 08/21] contributing --- CONTRIBUTING.md | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 151badfc..675e4af6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,18 +1,31 @@ # Contributing to Void - -Welcome! 👋 This is the official guide on how to contribute to Void. We want to make it as easy as possible to contribute, so if you have any questions or comments, reach out via email or discord! - - -If you'd like to get started developing Void, feel free to follow the steps below on building Void yourself and doing a PR. -Void's code mostly lives in `src/vs/workbench/contrib/void/` and `src/vs/platform/void/`. +### Welcome! 👋 +This is the official guide on how to contribute to Void. We want to make it as easy as possible to contribute, so if you have any questions or comments, reach out via email or discord! There are a few ways to contribute: -- 👨‍💻 Build new features - see [Roadmap](https://github.com/orgs/voideditor/projects/2/views/3) and [Issues](https://github.com/voideditor/void/issues). +- 💫 Build new features - see [Issues](https://github.com/voideditor/void/issues). - 💡 Make suggestions in our [Discord](https://discord.gg/RSNjgaugJs). +### Codebase Guide + +We highly recommend reading [this](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) article on VSCode's sourcecode organization. + +We are currently putting together our own articles on VSCode and Void's sourcecode organization. The best way to get this information right now is by attending a weekly meeting. + + + +For some miscellaneous useful links on VSCode we've put together, see [`VOID_USEFUL_LINKS.md`](https://github.com/voideditor/void/blob/main/VOID_USEFUL_LINKS.md). + +Most of Void's code lives in the two folders called `void/`. + + + + ## Building Void ### a. Build Prerequisites - Mac @@ -121,20 +134,6 @@ Void's maintainers distribute Void on our website and in releases. If you'd like - Please don't use AI to write your PR 🙂 -## Codebase Guide - -We highly recommend reading [this](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) article on VSCode's sourcecode organization. - -We are currently putting together our own articles on VSCode and Void's sourcecode organization. The best way to get this information right now is by attending a weekly meeting. - - - -For some miscellaneous useful links on VSCode we've put together, see [`VOID_USEFUL_LINKS.md`](https://github.com/voideditor/void/blob/main/VOID_USEFUL_LINKS.md). - - - From 3e045117d6329b3de34fe53f35125872ca1f7940 Mon Sep 17 00:00:00 2001 From: Andrew Pareles <43356051+andrewpareles@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:11:57 -0800 Subject: [PATCH 09/21] contrib --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 675e4af6..7a8d81ac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,8 +4,9 @@ This is the official guide on how to contribute to Void. We want to make it as e There are a few ways to contribute: -- 💫 Build new features - see [Issues](https://github.com/voideditor/void/issues). +- 💫 Complete items on the [Roadmap](https://github.com/orgs/voideditor/projects/2). - 💡 Make suggestions in our [Discord](https://discord.gg/RSNjgaugJs). +- 🪴 Start new Issues - see [Issues](https://github.com/voideditor/void/issues). From eec4f6c95e07a0c3edd0ce743660df86930fa4bb Mon Sep 17 00:00:00 2001 From: Andrew Pareles <43356051+andrewpareles@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:18:04 -0800 Subject: [PATCH 10/21] email --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca38d5b7..f1594fd4 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Void is the open-source Cursor alternative. -This repo contains the full sourcecode for Void. We are currently in [open beta](https://voideditor.com/) for Discord members (see the `announcements` channel), with a waitlist for our official release. If you're new, welcome! +This repo contains the full sourcecode for Void. We are currently in [open beta](https://voideditor.com/email) for Discord members (see the `announcements` channel), with a waitlist for our official release. If you're new, welcome! - 👋 [Discord](https://discord.gg/RSNjgaugJs) From 197067af5ac9de38f1932d942b3a303f991dcd21 Mon Sep 17 00:00:00 2001 From: Andrew Pareles <43356051+andrewpareles@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:19:13 -0800 Subject: [PATCH 11/21] contrib --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7a8d81ac..c7ef8bae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,8 +20,6 @@ We are currently putting together our own articles on VSCode and Void's sourceco We wrote a [guide to working in VSCode]. --> -For some miscellaneous useful links on VSCode we've put together, see [`VOID_USEFUL_LINKS.md`](https://github.com/voideditor/void/blob/main/VOID_USEFUL_LINKS.md). - Most of Void's code lives in the two folders called `void/`. From f69f90b4c8f98972b7544850dec00dd375273599 Mon Sep 17 00:00:00 2001 From: Mathew Pareles <51329589+mathewpareles@users.noreply.github.com> Date: Sat, 25 Jan 2025 16:37:00 -0800 Subject: [PATCH 12/21] Reset Window: Zoom Level default to 0 (#239) Co-authored-by: Chandler Thompson <3262190+chandlertee@users.noreplyrgithub.com> --- src/vs/workbench/electron-sandbox/desktop.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index c14e3e1a..f6bae665 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -190,7 +190,7 @@ import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL } from '../../platform/window/electron-s }, 'window.zoomLevel': { 'type': 'number', - 'default': -1, + 'default': 0, 'minimum': MIN_ZOOM_LEVEL, 'maximum': MAX_ZOOM_LEVEL, 'markdownDescription': localize({ comment: ['{0} will be a setting name rendered as a link'], key: 'zoomLevel' }, "Adjust the default zoom level for all windows. Each increment above `0` (e.g. `1`) or below (e.g. `-1`) represents zooming `20%` larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity. See {0} for configuring if the 'Zoom In' and 'Zoom Out' commands apply the zoom level to all windows or only the active window.", '`#window.zoomPerWindow#`'), From 018fd016c829506a6065e304ef98a939d7fcecc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Commaret?= Date: Sun, 26 Jan 2025 02:05:58 +0100 Subject: [PATCH 13/21] trying to fix error --- CONTRIBUTING.md | 8 +- package-lock.json | 785 +++++++++++++++++- package.json | 2 +- .../platform/void/common/llmMessageTypes.ts | 7 - .../platform/void/common/voidSettingsTypes.ts | 4 +- .../void/electron-main/llmMessage/mistral.ts | 1 - 6 files changed, 785 insertions(+), 22 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7ef8bae..a96aa0e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Void -### Welcome! 👋 -This is the official guide on how to contribute to Void. We want to make it as easy as possible to contribute, so if you have any questions or comments, reach out via email or discord! +### Welcome! 👋 +This is the official guide on how to contribute to Void. We want to make it as easy as possible to contribute, so if you have any questions or comments, reach out via email or discord! There are a few ways to contribute: @@ -12,7 +12,7 @@ There are a few ways to contribute: ### Codebase Guide -We highly recommend reading [this](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) article on VSCode's sourcecode organization. +We highly recommend reading [this](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) article on VSCode's sourcecode organization. We are currently putting together our own articles on VSCode and Void's sourcecode organization. The best way to get this information right now is by attending a weekly meeting. @@ -123,7 +123,7 @@ workspace/ ``` ### Distributing -Void's maintainers distribute Void on our website and in releases. If you'd like to see the scripts to convert `Mac .app -> .dmg`, `Windows folder -> .exe`, and `Linux folder -> appimage` for distribution, feel free to reach out. +Void's maintainers distribute Void on our website and in releases. If you'd like to see the scripts to convert `Mac .app -> .dmg`, `Windows folder -> .exe`, and `Linux folder -> appimage` for distribution, feel free to reach out. ## Pull Request Guidelines diff --git a/package-lock.json b/package-lock.json index e7570e5e..966a06e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", - "@mistralai/mistralai": "^1.3.5", + "@mistralai/mistralai": "^1.4.0", "@parcel/watcher": "2.1.0", "@rrweb/record": "^2.0.0-alpha.17", "@rrweb/types": "^2.0.0-alpha.17", @@ -158,6 +158,7 @@ "mocha": "^10.2.0", "mocha-junit-reporter": "^2.2.1", "mocha-multi-reporters": "^1.5.1", + "next": "^15.1.4", "nodemon": "^3.1.9", "npm-run-all": "^4.1.5", "opn": "^6.0.0", @@ -1058,6 +1059,17 @@ "node": ">= 4.0.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.41.0", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz", @@ -1704,6 +1716,386 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1977,15 +2369,156 @@ } }, "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==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.4.0.tgz", + "integrity": "sha512-xA3DAtIDh4Qgr1EoSuiGVE+2ABNrxpcTeC0kSXYbkDNUGdthalLAH7DgbG0fkKZ7TN8xdWXQq2WiIghp/O96Eg==", "peerDependencies": { - "react": "^18 || ^19", - "react-dom": "^18 || ^19", "zod": ">= 3" } }, + "node_modules/@next/env": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.6.tgz", + "integrity": "sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.6.tgz", + "integrity": "sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.6.tgz", + "integrity": "sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.6.tgz", + "integrity": "sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.6.tgz", + "integrity": "sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.6.tgz", + "integrity": "sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.6.tgz", + "integrity": "sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.6.tgz", + "integrity": "sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.6.tgz", + "integrity": "sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2723,6 +3256,23 @@ "node": ">=10" } }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -5494,6 +6044,18 @@ "esbuild": ">=0.18" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -5919,6 +6481,13 @@ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "dev": true, + "license": "MIT" + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -6123,6 +6692,21 @@ "node": ">=0.10.0" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6141,6 +6725,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -15632,12 +16228,96 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/next": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.6.tgz", + "integrity": "sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/env": "15.1.6", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.1.6", + "@next/swc-darwin-x64": "15.1.6", + "@next/swc-linux-arm64-gnu": "15.1.6", + "@next/swc-linux-arm64-musl": "15.1.6", + "@next/swc-linux-x64-gnu": "15.1.6", + "@next/swc-linux-x64-musl": "15.1.6", + "@next/swc-win32-arm64-msvc": "15.1.6", + "@next/swc-win32-x64-msvc": "15.1.6", + "sharp": "^0.33.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -19456,6 +20136,47 @@ "node": ">=0.10.0" } }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -19616,6 +20337,25 @@ "simple-concat": "^1.0.0" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -20266,6 +21006,15 @@ "node": ">=0.10" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/streamx": { "version": "2.21.1", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", @@ -20504,6 +21253,30 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/stylehacks": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", diff --git a/package.json b/package.json index ebd91306..394a05a8 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", - "@mistralai/mistralai": "^1.3.5", + "@mistralai/mistralai": "^1.4.0", "@parcel/watcher": "2.1.0", "@rrweb/record": "^2.0.0-alpha.17", "@rrweb/types": "^2.0.0-alpha.17", diff --git a/src/vs/platform/void/common/llmMessageTypes.ts b/src/vs/platform/void/common/llmMessageTypes.ts index 77b31c07..fbf7a1b2 100644 --- a/src/vs/platform/void/common/llmMessageTypes.ts +++ b/src/vs/platform/void/common/llmMessageTypes.ts @@ -108,13 +108,6 @@ export type _InternalSendLLMMessageFnType = (params: { - - - - - - - // These are from 'ollama' SDK interface OllamaModelDetails { parent_model: string; diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 659ad446..709bc8e0 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -100,16 +100,14 @@ export const defaultGeminiModels = modelInfoOfDefaultNames([ ]) export const defaultMistralModels = modelInfoOfDefaultNames([ + "codestral-latest", "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) => { diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts index ca32fd49..bf991b22 100644 --- a/src/vs/platform/void/electron-main/llmMessage/mistral.ts +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -59,7 +59,6 @@ export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, // Convert messages for Mistral const mistralMessages = messages - .filter(msg => msg.role !== 'system') // Ignore system messages .map(msg => ({ role: msg.role === 'assistant' ? 'assistant' : 'user', content: msg.content.trim() From 3089bb31b52182ee4af1a5ca94c717a39b3dd025 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 18:39:37 -0800 Subject: [PATCH 14/21] mistral --- .gitignore | 1 - src/package-lock.json | 62 -------- .../void/common/voidSettingsService.ts | 6 +- .../platform/void/common/voidSettingsTypes.ts | 4 +- .../void/electron-main/llmMessage/groq.ts | 8 +- .../void/electron-main/llmMessage/mistral.ts | 138 ++++-------------- void | 1 - 7 files changed, 39 insertions(+), 181 deletions(-) delete mode 100644 src/package-lock.json delete mode 160000 void diff --git a/.gitignore b/.gitignore index fcdb9b6f..5daf304c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,3 @@ product.overrides.json *.snap.actual .vscode-test .tmp/ -.tool-versions diff --git a/src/package-lock.json b/src/package-lock.json deleted file mode 100644 index 3b02711d..00000000 --- a/src/package-lock.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "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" - } - } - } -} diff --git a/src/vs/platform/void/common/voidSettingsService.ts b/src/vs/platform/void/common/voidSettingsService.ts index 7200d8bf..4030a3f3 100644 --- a/src/vs/platform/void/common/voidSettingsService.ts +++ b/src/vs/platform/void/common/voidSettingsService.ts @@ -117,9 +117,9 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { // read and update the actual state immediately this._readState().then(readS => { - // THIS IS A HACK BECAUSE WE ADDED DEEPSEEK - const deepseekAdd = { deepseek: defaultSettingsOfProvider['deepseek'] } - readS = { ...readS, settingsOfProvider: { ...deepseekAdd, ...readS.settingsOfProvider, } } + // THIS IS A HACK BECAUSE WE ADDED DEEPSEEK AND MISTRAL + const additions = { deepseek: defaultSettingsOfProvider['deepseek'], mistral: defaultSettingsOfProvider['mistral'] } + readS = { ...readS, settingsOfProvider: { ...additions, ...readS.settingsOfProvider, } } this.state = readS resolver() diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 709bc8e0..458d6a16 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -363,16 +363,16 @@ export const voidInitModelOptions = { // used when waiting and for a type reference export const defaultSettingsOfProvider: SettingsOfProvider = { anthropic: { - _enabled: undefined, ...defaultCustomSettings, ...defaultProviderSettings.anthropic, ...voidInitModelOptions.anthropic, + _enabled: undefined, }, openAI: { - _enabled: undefined, ...defaultCustomSettings, ...defaultProviderSettings.openAI, ...voidInitModelOptions.openAI, + _enabled: undefined, }, deepseek: { ...defaultCustomSettings, diff --git a/src/vs/platform/void/electron-main/llmMessage/groq.ts b/src/vs/platform/void/electron-main/llmMessage/groq.ts index 1050e25c..70a4250b 100644 --- a/src/vs/platform/void/electron-main/llmMessage/groq.ts +++ b/src/vs/platform/void/electron-main/llmMessage/groq.ts @@ -22,7 +22,7 @@ export const sendGroqMsg: _InternalSendLLMMessageFnType = async ({ messages, onT messages: messages, model: modelName, stream: true, - temperature: 0.7, + // temperature: 0.7, // max_tokens: parseMaxTokensStr(thisConfig.maxTokens), }) .then(async response => { @@ -30,10 +30,8 @@ export const sendGroqMsg: _InternalSendLLMMessageFnType = async ({ messages, onT // when receive text for await (const chunk of response) { const newText = chunk.choices[0]?.delta?.content || ''; - if (newText) { - fullText += newText; - onText({ newText, fullText }); - } + fullText += newText; + onText({ newText, fullText }); } onFinalMessage({ fullText }); diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts index bf991b22..74f9233e 100644 --- a/src/vs/platform/void/electron-main/llmMessage/mistral.ts +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -1,122 +1,46 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Glass Devtools, Inc. All rights reserved. - * Mistral implementation by Jérôme Commaret (https://github.com/jcommaret) - * Void Editor additions licensed under the AGPL 3.0 License. - *--------------------------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------------------- + * Copyright 2025 Glass Devtools, Inc. All rights reserved. + * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. + *--------------------------------------------------------------------------------------*/ import { Mistral } from '@mistralai/mistralai'; import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; -interface MistralMessage { - role: 'user' | 'assistant'; - content: string; -} - -interface MistralChunk { - data: { - id: string; - object: string; - created: number; - model: string; - choices: Array<{ - index: number; - delta: { - content?: string; - role?: string; - }; - finishReason: string | null; - }>; - }; -} - // Mistral export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { let fullText = ''; - let aborted = false; const thisConfig = settingsOfProvider.mistral; - if (!thisConfig.apiKey) { - onError({ message: 'Mistral API key not configured.', fullError: new Error('No API key') }); - return; - } - const mistral = new Mistral({ - apiKey: thisConfig.apiKey - }); + apiKey: thisConfig.apiKey, + }) - // Define the aborter before staring the stream - _setAborter(() => { - aborted = true; - }); - - try { - // Check if there are messages to process - if (!messages || messages.length === 0) { - onError({ message: 'No messages to process.', fullError: new Error('No messages provided') }); - return; - } - - // Convert messages for Mistral - const mistralMessages = messages - .map(msg => ({ - role: msg.role === 'assistant' ? 'assistant' : 'user', - content: msg.content.trim() - })) as MistralMessage[]; - - // Ensure there is at least one message - if (mistralMessages.length === 0) { - onError({ message: 'No valid messages to send.', fullError: new Error('No valid messages') }); - return; - } - - // Ensure the last message is from the user - if (mistralMessages[mistralMessages.length - 1].role === 'assistant') { - mistralMessages.push({ - role: 'user', - content: 'Continue.' - }); - } - - const stream = await mistral.chat.stream({ + await mistral.chat + .stream({ + messages: messages, model: modelName, - messages: mistralMessages, - temperature: 0.7, - maxTokens: 2048 - }); - - for await (const chunk of stream) { - // Check if the request has been aborted - if (aborted) { - return; + stream: true, + // temperature: 0.7, + // maxTokens: 2048, + }) + .then(async response => { + // Mistral has a really nonstandard API - no interrupt and weird stream types + _setAborter(() => { console.log('Mistral does not support interrupts! Further messages will just be ignored.') }); + // when receive text + for await (const chunk of response) { + const c = chunk.data.choices[0].delta.content || '' + const newText = ( + typeof c === 'string' ? c + : c?.map(c => c.type === 'text' ? c.text : c.type).join('\n') + ) + fullText += newText; + onText({ newText, fullText }); } - if (typeof chunk === 'object' && chunk && 'data' in chunk) { - const { data } = chunk as MistralChunk; - if (data.choices?.[0]?.delta?.content) { - const newText = data.choices[0].delta.content; - fullText += newText; - onText({ newText, fullText }); - } - } - } - - // Check one last time if the request has been aborted - if (aborted) { - return; - } - - if (!fullText) { - onError({ message: 'No response received from Mistral.', fullError: new Error('No response content') }); - return; - } - - onFinalMessage({ fullText }); - } catch (error: any) { - const errorMessage = error.message || JSON.stringify(error); - onError({ - message: `Mistral Error: ${errorMessage}`, - fullError: error - }); - } -}; + onFinalMessage({ fullText }); + }) + .catch(error => { + onError({ message: error + '', fullError: error }); + }) +} diff --git a/void b/void deleted file mode 160000 index 5083b8e9..00000000 --- a/void +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5083b8e971e48ae1001e5c8ceee7b010bcea3640 From 7c227e237fbc8d2c52a8a124c0addc48f6b10175 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 19:01:29 -0800 Subject: [PATCH 15/21] key --- src/vs/platform/void/common/voidSettingsTypes.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 458d6a16..bdb892ba 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -267,13 +267,16 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName if (settingName === 'apiKey') { return { title: 'API Key', + + // **Please follow this convention**: + // The word "key..." here is a placeholder for the hash. For example, sk-ant-key means the key will look like sk-ant-abcdefg123... placeholder: providerName === 'anthropic' ? 'sk-ant-key...' : // sk-ant-api03-key providerName === 'openAI' ? 'sk-proj-key...' : - providerName === 'deepseek' ? 'sk-...' : + providerName === 'deepseek' ? 'sk-key...' : providerName === 'openRouter' ? 'sk-or-key...' : // sk-or-v1-key providerName === 'gemini' ? 'key...' : providerName === 'groq' ? 'gsk_key...' : - providerName === 'mistral' ? 'api-key...' : + providerName === 'mistral' ? 'key...' : providerName === 'openAICompatible' ? 'sk-key...' : '', From 0cd6e0fb6745f8c527c04a2a17b81cbc14ebde25 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 19:01:47 -0800 Subject: [PATCH 16/21] ... --- src/vs/platform/void/common/voidSettingsTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index bdb892ba..34ff74ee 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -269,7 +269,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName title: 'API Key', // **Please follow this convention**: - // The word "key..." here is a placeholder for the hash. For example, sk-ant-key means the key will look like sk-ant-abcdefg123... + // The word "key..." here is a placeholder for the hash. For example, sk-ant-key... means the key will look like sk-ant-abcdefg123... placeholder: providerName === 'anthropic' ? 'sk-ant-key...' : // sk-ant-api03-key providerName === 'openAI' ? 'sk-proj-key...' : providerName === 'deepseek' ? 'sk-key...' : From 97ea0f77f96480382f3031be2d0e8262381a58ce Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 19:29:22 -0800 Subject: [PATCH 17/21] remove duplicate model name and add storage fix --- .../void/common/voidSettingsService.ts | 21 ++++++++++++++++--- .../platform/void/common/voidSettingsTypes.ts | 1 - 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/void/common/voidSettingsService.ts b/src/vs/platform/void/common/voidSettingsService.ts index 7200d8bf..fd37290f 100644 --- a/src/vs/platform/void/common/voidSettingsService.ts +++ b/src/vs/platform/void/common/voidSettingsService.ts @@ -117,9 +117,24 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { // read and update the actual state immediately this._readState().then(readS => { - // THIS IS A HACK BECAUSE WE ADDED DEEPSEEK - const deepseekAdd = { deepseek: defaultSettingsOfProvider['deepseek'] } - readS = { ...readS, settingsOfProvider: { ...deepseekAdd, ...readS.settingsOfProvider, } } + readS = { + ...readS, + settingsOfProvider: { + // A HACK BECAUSE WE ADDED DEEPSEEK (did not exist before, comes before readS) + ...{ deepseek: defaultSettingsOfProvider['deepseek'] }, + + ...readS.settingsOfProvider, + + // A HACK BECAUSE WE ADDED NEW GEMINI MODELS (existed before, comes after readS) + gemini: { + ...readS.settingsOfProvider.gemini, + models: [ + ...readS.settingsOfProvider.gemini.models, + ...defaultSettingsOfProvider.gemini.models.filter(m => /* if cant find the model in readS (yes this is O(n^2), very small) */ !readS.settingsOfProvider.gemini.models.find(m2 => m2.modelName === m.modelName)) + ] + } + } + } this.state = readS resolver() diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index dc6ce4a3..33090720 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -96,7 +96,6 @@ export const defaultGeminiModels = modelInfoOfDefaultNames([ 'gemini-1.5-flash', 'gemini-1.5-pro', 'gemini-1.5-flash-8b', - 'gemini-1.0-pro', 'gemini-2.0-flash-exp', 'gemini-2.0-flash-thinking-exp-1219', 'learnlm-1.5-pro-experimental' From a1dfeb0f00f58977bc24ec99cf25e7cce8541fe9 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 19:36:49 -0800 Subject: [PATCH 18/21] .tool-versions --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5daf304c..fcdb9b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ product.overrides.json *.snap.actual .vscode-test .tmp/ +.tool-versions From 4547363ddebdbd39955999b0b572b4b8158c710f Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 19:38:55 -0800 Subject: [PATCH 19/21] mistral fix --- src/vs/platform/void/common/voidSettingsService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/void/common/voidSettingsService.ts b/src/vs/platform/void/common/voidSettingsService.ts index f4063bdf..04ed04a0 100644 --- a/src/vs/platform/void/common/voidSettingsService.ts +++ b/src/vs/platform/void/common/voidSettingsService.ts @@ -121,10 +121,10 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { ...readS, settingsOfProvider: { // A HACK BECAUSE WE ADDED DEEPSEEK (did not exist before, comes before readS) - ...{ deepseek: defaultSettingsOfProvider['deepseek'] }, + ...{ deepseek: defaultSettingsOfProvider.deepseek }, // A HACK BECAUSE WE ADDED MISTRAL (did not exist before, comes before readS) - ...{ deepseek: defaultSettingsOfProvider['deepseek'] }, + ...{ mistral: defaultSettingsOfProvider.mistral }, ...readS.settingsOfProvider, From 4f7fd66c2f0fc137d2b00606050e620d86dfc901 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 25 Jan 2025 19:39:38 -0800 Subject: [PATCH 20/21] explanation --- src/vs/platform/void/common/voidSettingsService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/platform/void/common/voidSettingsService.ts b/src/vs/platform/void/common/voidSettingsService.ts index 04ed04a0..c92810ab 100644 --- a/src/vs/platform/void/common/voidSettingsService.ts +++ b/src/vs/platform/void/common/voidSettingsService.ts @@ -117,6 +117,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { // read and update the actual state immediately this._readState().then(readS => { + // the stored data structure might be outdated, so we need to update it here (can do a more general solution later when we need to) readS = { ...readS, settingsOfProvider: { From a98c77572e45ec351c53b948115dae12abc74421 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Mon, 27 Jan 2025 22:18:12 -0800 Subject: [PATCH 21/21] add gap-4 and remove mt-4 for chat bubbles --- .../contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index ed1611e8..8cb4864f 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -436,7 +436,7 @@ const ChatBubble_ = ({ isEditMode, isLoading, children, role }: { role: ChatMess className={` relative ${isEditMode ? 'px-2 w-full max-w-full' - : role === 'user' ? `px-2 mt-4 self-end w-fit max-w-full` + : role === 'user' ? `px-2 self-end w-fit max-w-full` : role === 'assistant' ? `px-2 self-start w-full max-w-full` : '' } `} @@ -622,6 +622,7 @@ export const SidebarChat = () => { flex flex-col overflow-x-hidden overflow-y-auto + gap-4 `} style={{ maxHeight: sidebarDimensions.height - historyDimensions.height - formDimensions.height - 36 }} // the height of the previousMessages is determined by all other heights >