From db771c4f33cbbf8ac4bd9cc392fa194b410960f6 Mon Sep 17 00:00:00 2001 From: Animesh Gosain <126562373+animeshlego5@users.noreply.github.com> Date: Sat, 17 May 2025 16:24:13 +0530 Subject: [PATCH 01/25] Fix system role for o-series models --- src/vs/workbench/contrib/void/common/modelCapabilities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 49b38b84..6f69f3cb 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -381,7 +381,7 @@ const extensiveModelOptionsFallback: VoidStaticProviderInfo['modelOptionsFallbac recognizedModelName, modelName, ...opts, - supportsSystemMessage: opts.supportsSystemMessage ? 'system-role' : false, + supportsSystemMessage: opts.supportsSystemMessage ?? false, cost: { input: 0, output: 0 }, downloadable: false, ...fallbackKnownValues From 1d15d29a19889bf6762e2091088d05d68d29c00a Mon Sep 17 00:00:00 2001 From: vrtnis <123119434+vrtnis@users.noreply.github.com> Date: Sun, 18 May 2025 20:46:45 +0000 Subject: [PATCH 02/25] Updated Settings.tsx with new sidebar tabs --- .../react/src/void-settings-tsx/Settings.tsx | 110 +++++++++++++++--- 1 file changed, 95 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 2200dee7..14af51ed 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -19,6 +19,16 @@ import { ToolApprovalType, toolApprovalTypes } from '../../../../common/toolsSer import Severity from '../../../../../../../base/common/severity.js' import { getModelCapabilities, ModelOverrides } from '../../../../common/modelCapabilities.js'; import { TransferEditorType, TransferFilesInfo } from '../../../extensionTransferTypes.js'; +// ───────────────────────────────────────────── +// Sidebar navigation helpers +// ───────────────────────────────────────────── +type SectionKey = + | 'models' + | 'localProviders' + | 'providers' + | 'featureOptions' + | 'general' + | 'all'; const ButtonLeftTextRightOption = ({ text, leftButton }: { text: string, leftButton?: React.ReactNode }) => { @@ -906,6 +916,19 @@ export const OneClickSwitchButton = ({ fromEditor = 'VS Code', className = '' }: export const Settings = () => { const isDark = useIsDark() + // ─── sidebar nav ────────────────────────── + const [selectedSection, setSelectedSection] = + useState('models'); + + const navItems: { key: SectionKey; label: string }[] = [ + { key: 'models', label: 'Models' }, + { key: 'localProviders', label: 'Local Providers' }, + { key: 'providers', label: 'Providers' }, + { key: 'featureOptions', label: 'Feature Options' }, + { key: 'general', label: 'General' }, + { key: 'all', label: 'All Settings' }, + ]; + const show = (key: SectionKey) => selectedSection === 'all' || selectedSection === key; const accessor = useAccessor() const commandService = accessor.get('ICommandService') const environmentService = accessor.get('IEnvironmentService') @@ -979,10 +1002,44 @@ export const Settings = () => { } - return
-
+ return ( +
+
+ {/* ────────────── SIDEBAR ────────────── */} -
+ + + {/* ───────────── MAIN PANE ───────────── */} +
+ + + +

{`Void's Settings`}

@@ -997,13 +1054,19 @@ export const Settings = () => { {/* Models section (formerly FeaturesTab) */} +{show('models') && ( +<>

Models

+ + )} - +{show('localProviders') && ( + + <>

Local Providers

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

@@ -1012,18 +1075,26 @@ export const Settings = () => {
- - - + + +
+)} +{show('providers') && ( + + <>

Providers

{`Void can access models from Anthropic, OpenAI, OpenRouter, and more.`}

- + - - + +
+)} +{show('featureOptions') && ( + + <>

Feature Options

@@ -1108,7 +1179,6 @@ export const Settings = () => { - {/* Tools Section */}

Tools

@@ -1161,8 +1231,14 @@ export const Settings = () => {
+ + +)} +{show('general') && ( + <> + {/* General section (formerly GeneralTab) */}
@@ -1248,9 +1324,13 @@ Alternatively, place a \`.voidrules\` file in the root of your workspace. -
-
-
-} + +)} +
+ +
+ +); +} From 05e27a0885a933afd99a88a070f2d7d757a23c6f Mon Sep 17 00:00:00 2001 From: Animesh Gosain <126562373+animeshlego5@users.noreply.github.com> Date: Mon, 19 May 2025 13:34:01 +0530 Subject: [PATCH 03/25] Refactor role mapping logic --- .../contrib/void/common/modelCapabilities.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 6f69f3cb..bc46fe99 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -374,19 +374,29 @@ const extensiveModelOptionsFallback: VoidStaticProviderInfo['modelOptionsFallbac const lower = modelName.toLowerCase() const toFallback = },>(obj: T, recognizedModelName: string & keyof T) - : VoidStaticModelInfo & { modelName: string, recognizedModelName: string } => { + : VoidStaticModelInfo & { modelName: string, recognizedModelName: string, roleMode: 'system' | 'developer' | false } => { + + const opts = obj[recognizedModelName]; + + const roleMode = + recognizedModelName === 'system' || recognizedModelName === 'gemini' + ? 'system' + : recognizedModelName === 'developer' + ? 'developer' + : false; - const opts = obj[recognizedModelName] return { recognizedModelName, modelName, ...opts, - supportsSystemMessage: opts.supportsSystemMessage ?? false, + supportsSystemMessage: roleMode !== false, + roleMode, cost: { input: 0, output: 0 }, downloadable: false, ...fallbackKnownValues - } + }; } + if (lower.includes('gemini') && (lower.includes('2.5') || lower.includes('2-5'))) return toFallback(geminiModelOptions, 'gemini-2.5-pro-exp-03-25') if (lower.includes('claude-3-5') || lower.includes('claude-3.5')) return toFallback(anthropicModelOptions, 'claude-3-5-sonnet-20241022') From 7642b3281a2ec274c0282689d0b6ac681e38cc1a Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Mon, 19 May 2025 01:34:29 -0700 Subject: [PATCH 04/25] role --- .../contrib/void/common/modelCapabilities.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index bc46fe99..1e56a0d5 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -374,23 +374,18 @@ const extensiveModelOptionsFallback: VoidStaticProviderInfo['modelOptionsFallbac const lower = modelName.toLowerCase() const toFallback = },>(obj: T, recognizedModelName: string & keyof T) - : VoidStaticModelInfo & { modelName: string, recognizedModelName: string, roleMode: 'system' | 'developer' | false } => { + : VoidStaticModelInfo & { modelName: string, recognizedModelName: string } => { - const opts = obj[recognizedModelName]; - - const roleMode = - recognizedModelName === 'system' || recognizedModelName === 'gemini' - ? 'system' - : recognizedModelName === 'developer' - ? 'developer' - : false; + const opts = obj[recognizedModelName] + const supportsSystemMessage = opts.supportsSystemMessage === 'separated' + ? 'system-role' + : opts.supportsSystemMessage return { recognizedModelName, modelName, ...opts, - supportsSystemMessage: roleMode !== false, - roleMode, + supportsSystemMessage: supportsSystemMessage, cost: { input: 0, output: 0 }, downloadable: false, ...fallbackKnownValues From 5995591296d7464afa2c041fe5ae873f16ac346a Mon Sep 17 00:00:00 2001 From: vrtnis <123119434+vrtnis@users.noreply.github.com> Date: Tue, 20 May 2025 01:36:16 +0000 Subject: [PATCH 05/25] feat(void): add Bedrock provider in onboarding + type updates --- .../src/void-onboarding/VoidOnboarding.tsx | 2 +- .../contrib/void/common/modelCapabilities.ts | 20 +++++++++++++ .../contrib/void/common/voidSettingsTypes.ts | 20 +++++++++++-- .../llmMessage/sendLLMMessage.impl.ts | 29 +++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-onboarding/VoidOnboarding.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-onboarding/VoidOnboarding.tsx index d16ebefd..9ac3645c 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-onboarding/VoidOnboarding.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-onboarding/VoidOnboarding.tsx @@ -100,7 +100,7 @@ const tabNames = ['Free', 'Paid', 'Local'] as const; type TabName = typeof tabNames[number] | 'Cloud/Other'; // Data for cloud providers tab -const cloudProviders: ProviderName[] = ['googleVertex', 'liteLLM', 'microsoftAzure', 'openAICompatible']; +const cloudProviders: ProviderName[] = ['googleVertex', 'liteLLM', 'microsoftAzure', 'awsBedrock', 'openAICompatible']; // Data structures for provider tabs const providerNamesOfTab: Record = { diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 49b38b84..a1785022 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -60,6 +60,12 @@ export const defaultProviderSettings = { apiKey: '', azureApiVersion: '2024-05-01-preview', }, + awsBedrock: { + apiKey: '', + region: 'us-east-1', // add region setting + endpoint: '', // optionally allow overriding default + }, + } as const @@ -136,6 +142,7 @@ export const defaultModelsOfProvider = { openAICompatible: [], // fallback googleVertex: [], microsoftAzure: [], + awsBedrock: [], liteLLM: [], @@ -1028,6 +1035,18 @@ const microsoftAzureSettings: VoidStaticProviderInfo = { }, } +// ---------------- AWS BEDROCK ---------------- +const awsBedrockModelOptions = { +} as const satisfies Record + +const awsBedrockSettings: VoidStaticProviderInfo = { + modelOptions: awsBedrockModelOptions, + modelOptionsFallback: (modelName) => { return null }, + providerReasoningIOSettings: { + input: { includeInPayload: openAICompatIncludeInPayloadReasoning }, + }, +} + // ---------------- VLLM, OLLAMA, OPENAICOMPAT (self-hosted / local) ---------------- const ollamaModelOptions = { @@ -1333,6 +1352,7 @@ const modelSettingsOfProvider: { [providerName in ProviderName]: VoidStaticProvi googleVertex: googleVertexSettings, microsoftAzure: microsoftAzureSettings, + awsBedrock: awsBedrockSettings, } as const diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index a911dfe6..55c4f81e 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -103,6 +103,9 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn else if (providerName === 'microsoftAzure') { return { title: 'Microsoft Azure OpenAI', } } + else if (providerName === 'awsBedrock') { + return { title: 'AWS Bedrock', } + } throw new Error(`descOfProviderName: Unknown provider name: "${providerName}"`) } @@ -120,6 +123,7 @@ export const subTextMdOfProviderName = (providerName: ProviderName): string => { if (providerName === 'openAICompatible') return `Use any provider that's OpenAI-compatible (use this for llama.cpp and more).` if (providerName === 'googleVertex') return 'You must authenticate before using Vertex with Void. Read more about endpoints [here](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/call-vertex-using-openai-library), and regions [here](https://cloud.google.com/vertex-ai/docs/general/locations#available-regions).' if (providerName === 'microsoftAzure') return 'Read more about endpoints [here](https://learn.microsoft.com/en-us/rest/api/aifoundry/model-inference/get-chat-completions/get-chat-completions?view=rest-aifoundry-model-inference-2024-05-01-preview&tabs=HTTP), and get your API key [here](https://learn.microsoft.com/en-us/azure/search/search-security-api-keys?tabs=rest-use%2Cportal-find%2Cportal-query#find-existing-keys).' + if (providerName === 'awsBedrock') return 'Connect via a LiteLLM proxy or the AWS [Bedrock-Access-Gateway](https://github.com/aws-samples/bedrock-access-gateway). LiteLLM Bedrock setup docs are [here](https://docs.litellm.ai/docs/providers/bedrock).' if (providerName === 'ollama') return 'Read more about custom [Endpoints here](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-expose-ollama-on-my-network).' if (providerName === 'vLLM') return 'Read more about custom [Endpoints here](https://docs.vllm.ai/en/latest/getting_started/quickstart.html#openai-compatible-server).' if (providerName === 'lmStudio') return 'Read more about custom [Endpoints here](https://lmstudio.ai/docs/app/api/endpoints/openai).' @@ -165,14 +169,16 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName providerName === 'googleVertex' ? 'baseURL' : providerName === 'microsoftAzure' ? 'baseURL' : providerName === 'liteLLM' ? 'baseURL' : - '(never)', + providerName === 'awsBedrock' ? 'Endpoint' : + '(never)', placeholder: providerName === 'ollama' ? defaultProviderSettings.ollama.endpoint : providerName === 'vLLM' ? defaultProviderSettings.vLLM.endpoint : providerName === 'openAICompatible' ? 'https://my-website.com/v1' : providerName === 'lmStudio' ? defaultProviderSettings.lmStudio.endpoint : providerName === 'liteLLM' ? 'http://localhost:4000' - : '(never)', + : providerName === 'awsBedrock' ? 'http://localhost:4000/v1' + : '(never)', } @@ -185,7 +191,9 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName return { title: 'Region', placeholder: providerName === 'googleVertex' ? defaultProviderSettings.googleVertex.region - : '' + : providerName === 'awsBedrock' + ? defaultProviderSettings.awsBedrock.region + : '' } } else if (settingName === 'azureApiVersion') { @@ -340,6 +348,12 @@ export const defaultSettingsOfProvider: SettingsOfProvider = { ...modelInfoOfDefaultModelNames(defaultModelsOfProvider.microsoftAzure), _didFillInProviderSettings: undefined, }, + awsBedrock: { // aggregator (serves models from multiple providers) + ...defaultCustomSettings, + ...defaultProviderSettings.awsBedrock, + ...modelInfoOfDefaultModelNames(defaultModelsOfProvider.awsBedrock), + _didFillInProviderSettings: undefined, + }, } diff --git a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts index 1190b283..89fb5a87 100644 --- a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts +++ b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts @@ -121,6 +121,29 @@ const newOpenAICompatibleSDK = async ({ settingsOfProvider, providerName, includ const options = { endpoint, apiKey: thisConfig.apiKey, apiVersion }; return new AzureOpenAI({ ...options, ...commonPayloadOpts }); } + else if (providerName === 'awsBedrock') { + /** + * We treat Bedrock as *OpenAI-compatible only through a proxy*: + * • LiteLLM default → http://localhost:4000/v1 + * • Bedrock-Access-Gateway → https://.execute-api..amazonaws.com/openai/ + * + * The native Bedrock runtime endpoint + * https://bedrock-runtime..amazonaws.com + * is **NOT** OpenAI-compatible, so we do *not* fall back to it here. + */ + const { endpoint, apiKey } = settingsOfProvider.awsBedrock + + // ① use the user-supplied proxy if present + // ② otherwise default to local LiteLLM + let baseURL = endpoint || 'http://localhost:4000/v1' + + // Normalize: make sure we end with “/v1” + if (!baseURL.endsWith('/v1')) + baseURL = baseURL.replace(/\/+$/, '') + '/v1' + + return new OpenAI({ baseURL, apiKey, ...commonPayloadOpts }) + } + else if (providerName === 'deepseek') { const thisConfig = settingsOfProvider[providerName] @@ -907,6 +930,12 @@ export const sendLLMMessageToProviderImplementation = { sendFIM: null, list: null, }, + awsBedrock: { + sendChat: (params) => _sendOpenAICompatibleChat(params), + sendFIM: null, + list: null, + }, + } satisfies CallFnOfProvider From cbc7cf0841608d5da2520ed1d9314a98dd3e6e2a Mon Sep 17 00:00:00 2001 From: anschmieg <6830368+anschmieg@users.noreply.github.com> Date: Wed, 21 May 2025 17:58:34 +0200 Subject: [PATCH 06/25] Fix keymap for Void: Quick Edit to resolve conflict The current keymap causes a conflict between 'Void: Quick Edit' and 'Clear Console'/'Clear Terminal'. Using this _when_ expression, we can resolve the conflict without affecting functionality. * Add the when expression `editorFocus && !terminalFocus` to the keybinding for 'Void: Quick Edit' `void.ctrlKAction`. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/voideditor/void?shareId=XXXX-XXXX-XXXX-XXXX). --- src/vs/workbench/contrib/void/browser/quickEditActions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/void/browser/quickEditActions.ts b/src/vs/workbench/contrib/void/browser/quickEditActions.ts index a420d8bb..4159a7fd 100644 --- a/src/vs/workbench/contrib/void/browser/quickEditActions.ts +++ b/src/vs/workbench/contrib/void/browser/quickEditActions.ts @@ -42,6 +42,7 @@ registerAction2(class extends Action2 { keybinding: { primary: KeyMod.CtrlCmd | KeyCode.KeyK, weight: KeybindingWeight.VoidExtension, + when: 'editorFocus && !terminalFocus', } }); } From ebae55cd4b32cb049b2d57e8011dae610725ff7e Mon Sep 17 00:00:00 2001 From: Andrew Pareles <43356051+andrewpareles@users.noreply.github.com> Date: Wed, 21 May 2025 18:25:23 -0700 Subject: [PATCH 07/25] Revert "Fix keymap for Void: Quick Edit to resolve conflict" --- src/vs/workbench/contrib/void/browser/quickEditActions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/browser/quickEditActions.ts b/src/vs/workbench/contrib/void/browser/quickEditActions.ts index 4159a7fd..a420d8bb 100644 --- a/src/vs/workbench/contrib/void/browser/quickEditActions.ts +++ b/src/vs/workbench/contrib/void/browser/quickEditActions.ts @@ -42,7 +42,6 @@ registerAction2(class extends Action2 { keybinding: { primary: KeyMod.CtrlCmd | KeyCode.KeyK, weight: KeybindingWeight.VoidExtension, - when: 'editorFocus && !terminalFocus', } }); } From 588953be96448dac7c05a88179279eace8f32ed5 Mon Sep 17 00:00:00 2001 From: vrtnis <123119434+vrtnis@users.noreply.github.com> Date: Thu, 22 May 2025 02:01:51 +0000 Subject: [PATCH 08/25] feat: add Devstral model mapping + fix quick-edit keybinding type --- .../contrib/void/browser/quickEditActions.ts | 4 +- .../contrib/void/common/modelCapabilities.ts | 39 ++++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/quickEditActions.ts b/src/vs/workbench/contrib/void/browser/quickEditActions.ts index 4159a7fd..63deba31 100644 --- a/src/vs/workbench/contrib/void/browser/quickEditActions.ts +++ b/src/vs/workbench/contrib/void/browser/quickEditActions.ts @@ -13,7 +13,7 @@ import { roundRangeToLines } from './sidebarActions.js'; import { VOID_CTRL_K_ACTION_ID } from './actionIDs.js'; import { localize2 } from '../../../../nls.js'; import { IMetricsService } from '../common/metricsService.js'; - +import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js'; export type QuickEditPropsType = { diffareaid: number, @@ -42,7 +42,7 @@ registerAction2(class extends Action2 { keybinding: { primary: KeyMod.CtrlCmd | KeyCode.KeyK, weight: KeybindingWeight.VoidExtension, - when: 'editorFocus && !terminalFocus', + when: ContextKeyExpr.deserialize('editorFocus && !terminalFocus'), } }); } diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 1e56a0d5..0b44d5aa 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -111,6 +111,7 @@ export const defaultModelsOfProvider = { 'anthropic/claude-3.5-sonnet', 'deepseek/deepseek-r1', 'deepseek/deepseek-r1-zero:free', + 'mistralai/devstral-small:free' // 'openrouter/quasar-alpha', // 'google/gemini-2.5-pro-preview-03-25', // 'mistralai/codestral-2501', @@ -128,6 +129,7 @@ export const defaultModelsOfProvider = { ], mistral: [ // https://docs.mistral.ai/getting-started/models/models_overview/ 'codestral-latest', + 'devstral-small-latest', 'mistral-large-latest', 'mistral-medium-latest', 'ministral-3b-latest', @@ -263,6 +265,12 @@ const openSourceModelOptions_assumingOAICompat = { reasoningCapabilities: false, contextWindow: 32_000, reservedOutputTokenSpace: 4_096, }, + 'devstral': { + supportsFIM: false, + supportsSystemMessage: 'system-role', + reasoningCapabilities: false, + contextWindow: 131_000, reservedOutputTokenSpace: 8_192, + }, 'openhands-lm-32b': { // https://www.all-hands.dev/blog/introducing-openhands-lm-32b----a-strong-open-coding-agent-model supportsFIM: false, supportsSystemMessage: 'system-role', @@ -418,6 +426,7 @@ const extensiveModelOptionsFallback: VoidStaticProviderInfo['modelOptionsFallbac if (lower.includes('qwq')) { return toFallback(openSourceModelOptions_assumingOAICompat, 'qwq') } if (lower.includes('phi4')) return toFallback(openSourceModelOptions_assumingOAICompat, 'phi4') if (lower.includes('codestral')) return toFallback(openSourceModelOptions_assumingOAICompat, 'codestral') + if (lower.includes('devstral')) return toFallback(openSourceModelOptions_assumingOAICompat, 'devstral') if (lower.includes('gemma')) return toFallback(openSourceModelOptions_assumingOAICompat, 'gemma') @@ -924,6 +933,17 @@ const mistralModelOptions = { // https://mistral.ai/products/la-plateforme#prici supportsSystemMessage: 'system-role', reasoningCapabilities: false, }, + + 'devstral-small-latest': { //https://openrouter.ai/mistralai/devstral-small:free + contextWindow: 131_000, + reservedOutputTokenSpace: 8_192, + cost: { input: 0, output: 0 }, + supportsFIM: false, + downloadable: { sizeGb: 14 }, //https://ollama.com/library/devstral + supportsSystemMessage: 'system-role', + reasoningCapabilities: false, + }, + 'ministral-8b-latest': { // ollama 'mistral' contextWindow: 131_000, reservedOutputTokenSpace: 4_096, @@ -1099,10 +1119,19 @@ const ollamaModelOptions = { supportsSystemMessage: 'system-role', reasoningCapabilities: { supportsReasoning: true, canIOReasoning: false, canTurnOffReasoning: false, openSourceThinkTags: ['', ''] }, }, + 'devstral:latest': { + contextWindow: 131_000, + reservedOutputTokenSpace: 8_192, + cost: { input: 0, output: 0 }, + downloadable: { sizeGb: 14 }, + supportsFIM: false, + supportsSystemMessage: 'system-role', + reasoningCapabilities: false, + }, } as const satisfies Record -export const ollamaRecommendedModels = ['qwen2.5-coder:1.5b', 'llama3.1', 'qwq', 'deepseek-r1'] as const satisfies (keyof typeof ollamaModelOptions)[] +export const ollamaRecommendedModels = ['qwen2.5-coder:1.5b', 'llama3.1', 'qwq', 'deepseek-r1', 'devstral:latest'] as const satisfies (keyof typeof ollamaModelOptions)[] const vLLMSettings: VoidStaticProviderInfo = { @@ -1257,6 +1286,14 @@ const openRouterModelOptions_assumingOpenAICompat = { downloadable: false, reasoningCapabilities: false, }, + 'mistralai/devstral-small:free': { + ...openSourceModelOptions_assumingOAICompat.devstral, + contextWindow: 130_000, + reservedOutputTokenSpace: null, + cost: { input: 0, output: 0 }, + downloadable: false, + reasoningCapabilities: false, + }, 'qwen/qwen-2.5-coder-32b-instruct': { ...openSourceModelOptions_assumingOAICompat['qwen2.5coder'], contextWindow: 33_000, From 5a5732601e7318a103e6f4429c792364c67bd4e3 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 22 May 2025 11:22:36 -0700 Subject: [PATCH 09/25] claude 4 --- .../contrib/void/common/modelCapabilities.ts | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 49b38b84..8ecfe917 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -78,6 +78,8 @@ export const defaultModelsOfProvider = { // 'gpt-4o-mini', ], anthropic: [ // https://docs.anthropic.com/en/docs/about-claude/models + 'claude-opus-4-0', + 'claude-sonnet-4-0', 'claude-3-7-sonnet-latest', 'claude-3-5-sonnet-latest', 'claude-3-5-haiku-latest', @@ -106,6 +108,8 @@ export const defaultModelsOfProvider = { openRouter: [ // https://openrouter.ai/models // 'anthropic/claude-3.7-sonnet:thinking', + 'anthropic/claude-opus-4', + 'anthropic/claude-sonnet-4', 'qwen/qwen3-235b-a22b', 'anthropic/claude-3.7-sonnet', 'anthropic/claude-3.5-sonnet', @@ -465,6 +469,40 @@ const anthropicModelOptions = { reasoningSlider: { type: 'budget_slider', min: 1024, max: 8192, default: 1024 }, // they recommend batching if max > 32_000. we cap at 8192 because above is typically not necessary (often even buggy) }, + }, + 'claude-opus-4-20250514': { + contextWindow: 200_000, + reservedOutputTokenSpace: 8_192, + cost: { input: 15.00, cache_read: 1.50, cache_write: 18.75, output: 30.00 }, + downloadable: false, + supportsFIM: false, + specialToolFormat: 'anthropic-style', + supportsSystemMessage: 'separated', + reasoningCapabilities: { + supportsReasoning: true, + canTurnOffReasoning: true, + canIOReasoning: true, + reasoningReservedOutputTokenSpace: 8192, // can bump it to 128_000 with beta mode output-128k-2025-02-19 + reasoningSlider: { type: 'budget_slider', min: 1024, max: 8192, default: 1024 }, // they recommend batching if max > 32_000. we cap at 8192 because above is typically not necessary (often even buggy) + }, + + }, + 'claude-sonnet-4-20250514': { + contextWindow: 200_000, + reservedOutputTokenSpace: 8_192, + cost: { input: 3.00, cache_read: 0.30, cache_write: 3.75, output: 6.00 }, + downloadable: false, + supportsFIM: false, + specialToolFormat: 'anthropic-style', + supportsSystemMessage: 'separated', + reasoningCapabilities: { + supportsReasoning: true, + canTurnOffReasoning: true, + canIOReasoning: true, + reasoningReservedOutputTokenSpace: 8192, // can bump it to 128_000 with beta mode output-128k-2025-02-19 + reasoningSlider: { type: 'budget_slider', min: 1024, max: 8192, default: 1024 }, // they recommend batching if max > 32_000. we cap at 8192 because above is typically not necessary (often even buggy) + }, + }, 'claude-3-5-sonnet-20241022': { contextWindow: 200_000, @@ -524,6 +562,10 @@ const anthropicSettings: VoidStaticProviderInfo = { modelOptionsFallback: (modelName) => { const lower = modelName.toLowerCase() let fallbackName: keyof typeof anthropicModelOptions | null = null + if (lower.includes('claude-4-opus') || lower.includes('claude-opus-4')) fallbackName = 'claude-opus-4-20250514' + if (lower.includes('claude-4-sonnet') || lower.includes('claude-sonnet-4')) fallbackName = 'claude-sonnet-4-20250514' + + if (lower.includes('claude-3-7-sonnet')) fallbackName = 'claude-3-7-sonnet-20250219' if (lower.includes('claude-3-5-sonnet')) fallbackName = 'claude-3-5-sonnet-20241022' if (lower.includes('claude-3-5-haiku')) fallbackName = 'claude-3-5-haiku-20241022' @@ -1211,6 +1253,24 @@ const openRouterModelOptions_assumingOpenAICompat = { cost: { input: 0.8, output: 2.4 }, downloadable: false, }, + 'anthropic/claude-opus-4': { + contextWindow: 200_000, + reservedOutputTokenSpace: null, + cost: { input: 15.00, output: 75.00 }, + downloadable: false, + supportsFIM: false, + supportsSystemMessage: 'system-role', + reasoningCapabilities: false, + }, + 'anthropic/claude-sonnet-4': { + contextWindow: 200_000, + reservedOutputTokenSpace: null, + cost: { input: 15.00, output: 75.00 }, + downloadable: false, + supportsFIM: false, + supportsSystemMessage: 'system-role', + reasoningCapabilities: false, + }, 'anthropic/claude-3.7-sonnet:thinking': { contextWindow: 200_000, reservedOutputTokenSpace: null, From 5a34feb328a211a6e7b20f1da4e1f5bcadafae1c Mon Sep 17 00:00:00 2001 From: William Viana Date: Fri, 23 May 2025 12:16:01 -0500 Subject: [PATCH 10/25] chore: add grok mini and fast models to dropdown options --- src/vs/workbench/contrib/void/common/modelCapabilities.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 0b44d5aa..01b29a4f 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -86,6 +86,9 @@ export const defaultModelsOfProvider = { xAI: [ // https://docs.x.ai/docs/models?cluster=us-east-1 'grok-2', 'grok-3', + 'grok-3-mini', + 'grok-3-fast', + 'grok-3-mini-fast' ], gemini: [ // https://ai.google.dev/gemini-api/docs/models/gemini 'gemini-2.5-pro-exp-03-25', From 31cde552a0faa7eaf9e3dd884dad38d7eedb42ee Mon Sep 17 00:00:00 2001 From: Animesh Gosain <126562373+animeshlego5@users.noreply.github.com> Date: Mon, 19 May 2025 12:35:11 +0530 Subject: [PATCH 11/25] Local Changes --- src/vs/platform/terminal/node/terminalProcess.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index 2ecdba35..ed74ee2f 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -170,7 +170,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess cols, rows, useConpty, - useConptyDll, + ...(useConptyDll ? { useConptyDll } : {}) as IPtyForkOptions, // This option will force conpty to not redraw the whole viewport on launch conptyInheritCursor: useConpty && !!shellLaunchConfig.initialText }; @@ -392,7 +392,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess return; } // Don't throttle when using conpty.dll as it seems to have been fixed in later versions - if (this._ptyOptions.useConptyDll) { + if ((this._ptyOptions as any).useConptyDll) { return; } // Use a loop to ensure multiple calls in a single interval space out From c185807e6084de014be63020debed476007d3930 Mon Sep 17 00:00:00 2001 From: Animesh Gosain <126562373+animeshlego5@users.noreply.github.com> Date: Sat, 24 May 2025 17:44:32 +0530 Subject: [PATCH 12/25] feat: Add toggle to disable AI system message Refactor role mapping logic role Fix keymap for Void: Quick Edit to resolve conflict The current keymap causes a conflict between 'Void: Quick Edit' and 'Clear Console'/'Clear Terminal'. Using this _when_ expression, we can resolve the conflict without affecting functionality. * Add the when expression `editorFocus && !terminalFocus` to the keybinding for 'Void: Quick Edit' `void.ctrlKAction`. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/voideditor/void?shareId=XXXX-XXXX-XXXX-XXXX). feat: add Devstral model mapping + fix quick-edit keybinding type claude 4 feat: Add to .gitignore remove whitespace changed gitignore changed gitignore again changed gitignore again --- .../platform/terminal/node/terminalProcess.ts | 4 ++-- .../browser/convertToLLMMessageService.ts | 22 ++++++++++--------- .../react/src/void-settings-tsx/Settings.tsx | 20 +++++++++++++++++ .../void/common/voidSettingsService.ts | 5 ++++- .../contrib/void/common/voidSettingsTypes.ts | 2 ++ 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index ed74ee2f..2ecdba35 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -170,7 +170,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess cols, rows, useConpty, - ...(useConptyDll ? { useConptyDll } : {}) as IPtyForkOptions, + useConptyDll, // This option will force conpty to not redraw the whole viewport on launch conptyInheritCursor: useConpty && !!shellLaunchConfig.initialText }; @@ -392,7 +392,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess return; } // Don't throttle when using conpty.dll as it seems to have been fixed in later versions - if ((this._ptyOptions as any).useConptyDll) { + if (this._ptyOptions.useConptyDll) { return; } // Use a loop to ensure multiple calls in a single interval space out diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index 01fd58aa..795d9b58 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -250,8 +250,8 @@ const prepareOpenAIOrAnthropicMessages = ({ reservedOutputTokenSpace, }: { messages: SimpleLLMMessage[], - systemMessage: string, - aiInstructions: string, + systemMessage: string | undefined, + aiInstructions: string | undefined, supportsSystemMessage: false | 'system-role' | 'developer-role' | 'separated', specialToolFormat: 'openai-style' | 'anthropic-style' | undefined, supportsAnthropicReasoning: boolean, @@ -491,8 +491,8 @@ const prepareGeminiMessages = (messages: AnthropicLLMChatMessage[]) => { const prepareMessages = (params: { messages: SimpleLLMMessage[], - systemMessage: string, - aiInstructions: string, + systemMessage: string | undefined, + aiInstructions: string | undefined, supportsSystemMessage: false | 'system-role' | 'developer-role' | 'separated', specialToolFormat: 'openai-style' | 'anthropic-style' | 'gemini-style' | undefined, supportsAnthropicReasoning: boolean, @@ -520,7 +520,7 @@ const prepareMessages = (params: { export interface IConvertToLLMMessageService { readonly _serviceBrand: undefined; prepareLLMSimpleMessages: (opts: { simpleMessages: SimpleLLMMessage[], systemMessage: string, modelSelection: ModelSelection | null, featureName: FeatureName }) => { messages: LLMChatMessage[], separateSystemMessage: string | undefined } - prepareLLMChatMessages: (opts: { chatMessages: ChatMessage[], chatMode: ChatMode, modelSelection: ModelSelection | null }) => Promise<{ messages: LLMChatMessage[], separateSystemMessage: string | undefined }> + prepareLLMChatMessages: (opts: { chatMessages: ChatMessage[], chatMode: ChatMode, modelSelection: ModelSelection | null, explicitlyDisableSystemMessage?: boolean, explicitlyProvideAiInstructions?: string, }) => Promise<{ messages: LLMChatMessage[], separateSystemMessage: string | undefined }> prepareFIMMessage(opts: { messages: LLMFIMMessage, }): { prefix: string, suffix: string, stopTokens: string[] } } @@ -662,7 +662,7 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess }) return { messages, separateSystemMessage }; } - prepareLLMChatMessages: IConvertToLLMMessageService['prepareLLMChatMessages'] = async ({ chatMessages, chatMode, modelSelection }) => { + prepareLLMChatMessages: IConvertToLLMMessageService['prepareLLMChatMessages'] = async ({ chatMessages, chatMode, modelSelection, explicitlyDisableSystemMessage, explicitlyProvideAiInstructions, }) => { if (modelSelection === null) return { messages: [], separateSystemMessage: undefined } const { overridesOfModel } = this.voidSettingsService.state @@ -673,20 +673,22 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess contextWindow, supportsSystemMessage, } = getModelCapabilities(providerName, modelName, overridesOfModel) - const systemMessage = await this._generateChatMessagesSystemMessage(chatMode, specialToolFormat) + + const systemMessageFromGenerator = await this._generateChatMessagesSystemMessage(chatMode, specialToolFormat) const modelSelectionOptions = this.voidSettingsService.state.optionsOfModelSelection['Chat'][modelSelection.providerName]?.[modelSelection.modelName] // Get combined AI instructions - const aiInstructions = this._getCombinedAIInstructions(); - + const aiInstructions = explicitlyProvideAiInstructions || this._getCombinedAIInstructions(); + const globalDisableSystemMessageSetting = this.voidSettingsService.state.globalSettings.disableSystemMessage; + const finalSystemMessageForPrepareMessages = (explicitlyDisableSystemMessage || globalDisableSystemMessageSetting) ? undefined : systemMessageFromGenerator; const isReasoningEnabled = getIsReasoningEnabledState('Chat', providerName, modelName, modelSelectionOptions, overridesOfModel) const reservedOutputTokenSpace = getReservedOutputTokenSpace(providerName, modelName, { isReasoningEnabled, overridesOfModel }) const llmMessages = this._chatMessagesToSimpleMessages(chatMessages) const { messages, separateSystemMessage } = prepareMessages({ messages: llmMessages, - systemMessage, + systemMessage: finalSystemMessageForPrepareMessages, aiInstructions, supportsSystemMessage, specialToolFormat, diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index a133ff49..0d23f5bb 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -5,6 +5,7 @@ import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; // Added useRef import just in case it was missed, though likely already present import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidStatefulModelInfo, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, nonlocalProviderNames, localProviderNames, GlobalSettingName, featureNames, displayInfoOfFeatureName, isProviderNameDisabled, FeatureName, hasDownloadButtonsOnModelsProviderNames, subTextMdOfProviderName } from '../../../../common/voidSettingsTypes.js' +import { IVoidSettingsService, DISABLE_SYSTEM_MESSAGE_SETTING_ID } from '../../../../common/voidSettingsService.js'; import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' import { VoidButtonBgDarken, VoidCustomDropdownBox, VoidInputBox2, VoidSimpleInputBox, VoidSwitch } from '../util/inputs.js' import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' @@ -1242,6 +1243,25 @@ Alternatively, place a \`.voidrules\` file in the root of your workspace. + {/* --- Disable System Message Toggle --- */} +
+ +
+ { + voidSettingsService.setGlobalSetting('disableSystemMessage', newValue); + }} + /> + + {settingsState.globalSettings.disableSystemMessage ? 'Minimal system messages sent' : 'Full system messages sent'} + +
+
+
When enabled, Void will send a minimal system message to the model to reduce token usage and improve model performance for certain tasks. +
+
diff --git a/src/vs/workbench/contrib/void/common/voidSettingsService.ts b/src/vs/workbench/contrib/void/common/voidSettingsService.ts index 73c9eceb..5c3ae2d6 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsService.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsService.ts @@ -13,7 +13,8 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../platfo import { IMetricsService } from './metricsService.js'; import { defaultProviderSettings, getModelCapabilities, ModelOverrides } from './modelCapabilities.js'; import { VOID_SETTINGS_STORAGE_KEY } from './storageKeys.js'; -import { defaultSettingsOfProvider, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider, SettingName, providerNames, ModelSelection, modelSelectionsEqual, featureNames, VoidStatefulModelInfo, GlobalSettings, GlobalSettingName, defaultGlobalSettings, ModelSelectionOptions, OptionsOfModelSelection, ChatMode, OverridesOfModel, defaultOverridesOfModel } from './voidSettingsTypes.js'; +import { defaultSettingsOfProvider, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider, SettingName, providerNames, ModelSelection, modelSelectionsEqual, featureNames, VoidStatefulModelInfo, GlobalSettings, GlobalSettingName, defaultGlobalSettings, ModelSelectionOptions, OptionsOfModelSelection, ChatMode, OverridesOfModel, defaultOverridesOfModel, } from './voidSettingsTypes.js'; +export const DISABLE_SYSTEM_MESSAGE_SETTING_ID = 'void.disableSystemMessage'; // name is the name in the dropdown @@ -272,6 +273,8 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { // autoapprove is now an obj not a boolean (1.2.5) if (typeof readS.globalSettings.autoApprove === 'boolean') readS.globalSettings.autoApprove = {} + + if (readS.globalSettings.disableSystemMessage === undefined) readS.globalSettings.disableSystemMessage = false; } catch (e) { readS = defaultState() diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index a911dfe6..f63abec5 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -434,6 +434,7 @@ export type GlobalSettings = { showInlineSuggestions: boolean; includeToolLintErrors: boolean; isOnboardingComplete: boolean; + disableSystemMessage: boolean; } export const defaultGlobalSettings: GlobalSettings = { @@ -447,6 +448,7 @@ export const defaultGlobalSettings: GlobalSettings = { showInlineSuggestions: true, includeToolLintErrors: true, isOnboardingComplete: false, + disableSystemMessage: false, } export type GlobalSettingName = keyof GlobalSettings From cfb15e1117a9c0366fda52dfe58e92dc239a3cd9 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 29 May 2025 22:41:21 -0700 Subject: [PATCH 13/25] remove unused variable --- .../void/browser/react/src/void-settings-tsx/Settings.tsx | 1 - src/vs/workbench/contrib/void/common/voidSettingsService.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 0d23f5bb..67b37256 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -5,7 +5,6 @@ import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; // Added useRef import just in case it was missed, though likely already present import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidStatefulModelInfo, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, nonlocalProviderNames, localProviderNames, GlobalSettingName, featureNames, displayInfoOfFeatureName, isProviderNameDisabled, FeatureName, hasDownloadButtonsOnModelsProviderNames, subTextMdOfProviderName } from '../../../../common/voidSettingsTypes.js' -import { IVoidSettingsService, DISABLE_SYSTEM_MESSAGE_SETTING_ID } from '../../../../common/voidSettingsService.js'; import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' import { VoidButtonBgDarken, VoidCustomDropdownBox, VoidInputBox2, VoidSimpleInputBox, VoidSwitch } from '../util/inputs.js' import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' diff --git a/src/vs/workbench/contrib/void/common/voidSettingsService.ts b/src/vs/workbench/contrib/void/common/voidSettingsService.ts index 5c3ae2d6..b46e3f36 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsService.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsService.ts @@ -14,7 +14,6 @@ import { IMetricsService } from './metricsService.js'; import { defaultProviderSettings, getModelCapabilities, ModelOverrides } from './modelCapabilities.js'; import { VOID_SETTINGS_STORAGE_KEY } from './storageKeys.js'; import { defaultSettingsOfProvider, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider, SettingName, providerNames, ModelSelection, modelSelectionsEqual, featureNames, VoidStatefulModelInfo, GlobalSettings, GlobalSettingName, defaultGlobalSettings, ModelSelectionOptions, OptionsOfModelSelection, ChatMode, OverridesOfModel, defaultOverridesOfModel, } from './voidSettingsTypes.js'; -export const DISABLE_SYSTEM_MESSAGE_SETTING_ID = 'void.disableSystemMessage'; // name is the name in the dropdown From ac6b5601ef5edae6e8a8b1b6f1043bfdde34c6bf Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 29 May 2025 22:45:11 -0700 Subject: [PATCH 14/25] remove optional variables that arent even used --- .../contrib/void/browser/convertToLLMMessageService.ts | 8 ++++---- .../void/browser/react/src/void-settings-tsx/Settings.tsx | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index 795d9b58..ca3c8c48 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -520,7 +520,7 @@ const prepareMessages = (params: { export interface IConvertToLLMMessageService { readonly _serviceBrand: undefined; prepareLLMSimpleMessages: (opts: { simpleMessages: SimpleLLMMessage[], systemMessage: string, modelSelection: ModelSelection | null, featureName: FeatureName }) => { messages: LLMChatMessage[], separateSystemMessage: string | undefined } - prepareLLMChatMessages: (opts: { chatMessages: ChatMessage[], chatMode: ChatMode, modelSelection: ModelSelection | null, explicitlyDisableSystemMessage?: boolean, explicitlyProvideAiInstructions?: string, }) => Promise<{ messages: LLMChatMessage[], separateSystemMessage: string | undefined }> + prepareLLMChatMessages: (opts: { chatMessages: ChatMessage[], chatMode: ChatMode, modelSelection: ModelSelection | null }) => Promise<{ messages: LLMChatMessage[], separateSystemMessage: string | undefined }> prepareFIMMessage(opts: { messages: LLMFIMMessage, }): { prefix: string, suffix: string, stopTokens: string[] } } @@ -662,7 +662,7 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess }) return { messages, separateSystemMessage }; } - prepareLLMChatMessages: IConvertToLLMMessageService['prepareLLMChatMessages'] = async ({ chatMessages, chatMode, modelSelection, explicitlyDisableSystemMessage, explicitlyProvideAiInstructions, }) => { + prepareLLMChatMessages: IConvertToLLMMessageService['prepareLLMChatMessages'] = async ({ chatMessages, chatMode, modelSelection, }) => { if (modelSelection === null) return { messages: [], separateSystemMessage: undefined } const { overridesOfModel } = this.voidSettingsService.state @@ -679,9 +679,9 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess const modelSelectionOptions = this.voidSettingsService.state.optionsOfModelSelection['Chat'][modelSelection.providerName]?.[modelSelection.modelName] // Get combined AI instructions - const aiInstructions = explicitlyProvideAiInstructions || this._getCombinedAIInstructions(); + const aiInstructions = this._getCombinedAIInstructions(); const globalDisableSystemMessageSetting = this.voidSettingsService.state.globalSettings.disableSystemMessage; - const finalSystemMessageForPrepareMessages = (explicitlyDisableSystemMessage || globalDisableSystemMessageSetting) ? undefined : systemMessageFromGenerator; + const finalSystemMessageForPrepareMessages = globalDisableSystemMessageSetting ? undefined : systemMessageFromGenerator; const isReasoningEnabled = getIsReasoningEnabledState('Chat', providerName, modelName, modelSelectionOptions, overridesOfModel) const reservedOutputTokenSpace = getReservedOutputTokenSpace(providerName, modelName, { isReasoningEnabled, overridesOfModel }) const llmMessages = this._chatMessagesToSimpleMessages(chatMessages) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 67b37256..3cc67ded 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -1258,7 +1258,8 @@ Alternatively, place a \`.voidrules\` file in the root of your workspace. -
When enabled, Void will send a minimal system message to the model to reduce token usage and improve model performance for certain tasks. +
+ {`When enabled, Void will not include anything in the system message except for content you specified in voidrules and AI Instructions.`}
From 29f004a826c3e4b05560b7931614adc7ba6d910e Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 29 May 2025 23:56:55 -0700 Subject: [PATCH 15/25] sys --- .../void/browser/convertToLLMMessageService.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index ca3c8c48..8ebd5e76 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -250,8 +250,8 @@ const prepareOpenAIOrAnthropicMessages = ({ reservedOutputTokenSpace, }: { messages: SimpleLLMMessage[], - systemMessage: string | undefined, - aiInstructions: string | undefined, + systemMessage: string, + aiInstructions: string, supportsSystemMessage: false | 'system-role' | 'developer-role' | 'separated', specialToolFormat: 'openai-style' | 'anthropic-style' | undefined, supportsAnthropicReasoning: boolean, @@ -491,8 +491,8 @@ const prepareGeminiMessages = (messages: AnthropicLLMChatMessage[]) => { const prepareMessages = (params: { messages: SimpleLLMMessage[], - systemMessage: string | undefined, - aiInstructions: string | undefined, + systemMessage: string, + aiInstructions: string, supportsSystemMessage: false | 'system-role' | 'developer-role' | 'separated', specialToolFormat: 'openai-style' | 'anthropic-style' | 'gemini-style' | undefined, supportsAnthropicReasoning: boolean, @@ -674,21 +674,21 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess supportsSystemMessage, } = getModelCapabilities(providerName, modelName, overridesOfModel) - const systemMessageFromGenerator = await this._generateChatMessagesSystemMessage(chatMode, specialToolFormat) + const { disableSystemMessage } = this.voidSettingsService.state.globalSettings; + const fullSystemMessage = await this._generateChatMessagesSystemMessage(chatMode, specialToolFormat) + const systemMessage = disableSystemMessage ? '' : fullSystemMessage; const modelSelectionOptions = this.voidSettingsService.state.optionsOfModelSelection['Chat'][modelSelection.providerName]?.[modelSelection.modelName] // Get combined AI instructions const aiInstructions = this._getCombinedAIInstructions(); - const globalDisableSystemMessageSetting = this.voidSettingsService.state.globalSettings.disableSystemMessage; - const finalSystemMessageForPrepareMessages = globalDisableSystemMessageSetting ? undefined : systemMessageFromGenerator; const isReasoningEnabled = getIsReasoningEnabledState('Chat', providerName, modelName, modelSelectionOptions, overridesOfModel) const reservedOutputTokenSpace = getReservedOutputTokenSpace(providerName, modelName, { isReasoningEnabled, overridesOfModel }) const llmMessages = this._chatMessagesToSimpleMessages(chatMessages) const { messages, separateSystemMessage } = prepareMessages({ messages: llmMessages, - systemMessage: finalSystemMessageForPrepareMessages, + systemMessage, aiInstructions, supportsSystemMessage, specialToolFormat, From 0a6be740e12abf2a8d4bbf017a3648e1e74675d3 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 29 May 2025 23:58:21 -0700 Subject: [PATCH 16/25] simplify --- .../contrib/void/browser/convertToLLMMessageService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index 471e0c24..94545c0d 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -667,7 +667,7 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess }) return { messages, separateSystemMessage }; } - prepareLLMChatMessages: IConvertToLLMMessageService['prepareLLMChatMessages'] = async ({ chatMessages, chatMode, modelSelection, }) => { + prepareLLMChatMessages: IConvertToLLMMessageService['prepareLLMChatMessages'] = async ({ chatMessages, chatMode, modelSelection }) => { if (modelSelection === null) return { messages: [], separateSystemMessage: undefined } const { overridesOfModel } = this.voidSettingsService.state From 83c4a056420389c159a653dd241fa9da444e82fb Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 00:15:39 -0700 Subject: [PATCH 17/25] toggle --- .../react/src/void-settings-tsx/Settings.tsx | 154 +++++++++--------- 1 file changed, 79 insertions(+), 75 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index d0f2529d..52e00dc2 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -919,66 +919,72 @@ const MCPServerComponent = ({ name, server }: { name: string, server: MCPServer const removeUniquePrefix = (name: string) => name.split('_').slice(1).join('_') return ( -
-
- {/* Status indicator */} -
+
+ {/* Left side - status and name */} +
+ {/* Status indicator */} +
- `}>
- - {/* Server name */} -
{name}
- - {/* Power toggle switch */} -
- mcpService.toggleServerIsOn(name, !isOn)} - /> + {/* Server name */} +
{name}
+ + {/* Right side - power toggle switch */} + mcpService.toggleServerIsOn(name, !isOn)} + />
{/* Tools section */} -
-
- {isOn && (server.tools ?? []).length > 0 ? ( - (server.tools ?? []).map((tool: { name: string; description?: string }) => ( - +
+ {(server.tools ?? []).length > 0 ? ( + (server.tools ?? []).map((tool: { name: string; description?: string }) => ( + - {removeUniquePrefix(tool.name)} - - )) - ) : ( - No tools available - )} + data-tooltip-id='void-tooltip' + data-tooltip-content={tool.description || ''} + data-tooltip-class-name='void-max-w-[300px]' + > + {removeUniquePrefix(tool.name)} + + )) + ) : ( + No tools available + )} +
-
+ )} {/* Command badge */} {isOn && server.command && ( -
-
Command:
-
+
+
Command:
+
{server.command}
)} {/* Error message if present */} - {server.error && ()} + {server.error && ( +
+ +
+ )}
); }; @@ -989,27 +995,25 @@ const MCPServersList = () => { let content: React.ReactNode if (mcpServiceState.error) { - content =
+ content =
{mcpServiceState.error}
} else { const entries = Object.entries(mcpServiceState.mcpServerOfName) if (entries.length === 0) { - content =
+ content =
No servers found
} else { content = entries.map(([name, server]) => ( -
- -
+ )) } } - return content + return
{content}
}; export const Settings = () => { @@ -1359,44 +1363,44 @@ Alternatively, place a \`.voidrules\` file in the root of your workspace. {/* --- Disable System Message Toggle --- */} -
- -
- { - voidSettingsService.setGlobalSetting('disableSystemMessage', newValue); - }} - /> - - {settingsState.globalSettings.disableSystemMessage ? 'Minimal system messages sent' : 'Full system messages sent'} - -
+
+ +
+ { + voidSettingsService.setGlobalSetting('disableSystemMessage', newValue); + }} + /> + + {settingsState.globalSettings.disableSystemMessage ? 'Disable system message' : 'Disable system message'} + +
-
- {`When enabled, Void will not include anything in the system message except for content you specified in voidrules and AI Instructions.`} -
-
+
+ {`When disabled, Void will not include anything in the system message except for content you specified above.`} +
+
-
+

MCP

-
- { await mcpService.revealMCPConfigFile() }}> +
+ { await mcpService.revealMCPConfigFile() }}> Add MCP Server
-
- - - + + + +
From 27c40d84288dd3d08de213e26b0208cf74e4d938 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 00:28:22 -0700 Subject: [PATCH 18/25] key --- src/vs/workbench/contrib/void/common/voidSettingsTypes.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index 55c4f81e..778887a8 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -155,7 +155,8 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName providerName === 'mistral' ? 'api-key...' : providerName === 'googleVertex' ? 'AIzaSy...' : providerName === 'microsoftAzure' ? 'key-...' : - '', + providerName === 'awsBedrock' ? 'key-...' : + '', isPasswordField: true, } From 382ecaae1b1be42ea51f75009a1d5d60561ae0e8 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 00:34:42 -0700 Subject: [PATCH 19/25] auto format --- .../react/src/void-settings-tsx/Settings.tsx | 642 +++++++++--------- 1 file changed, 321 insertions(+), 321 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 1efb8d63..6ae26df6 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -23,12 +23,12 @@ import { TransferEditorType, TransferFilesInfo } from '../../../extensionTransfe // Sidebar navigation helpers // ───────────────────────────────────────────── type SectionKey = - | 'models' - | 'localProviders' - | 'providers' - | 'featureOptions' - | 'general' - | 'all'; + | 'models' + | 'localProviders' + | 'providers' + | 'featureOptions' + | 'general' + | 'all'; const ButtonLeftTextRightOption = ({ text, leftButton }: { text: string, leftButton?: React.ReactNode }) => { @@ -910,19 +910,19 @@ export const OneClickSwitchButton = ({ fromEditor = 'VS Code', className = '' }: export const Settings = () => { const isDark = useIsDark() - // ─── sidebar nav ────────────────────────── - const [selectedSection, setSelectedSection] = - useState('models'); + // ─── sidebar nav ────────────────────────── + const [selectedSection, setSelectedSection] = + useState('models'); - const navItems: { key: SectionKey; label: string }[] = [ - { key: 'models', label: 'Models' }, - { key: 'localProviders', label: 'Local Providers' }, - { key: 'providers', label: 'Providers' }, - { key: 'featureOptions', label: 'Feature Options' }, - { key: 'general', label: 'General' }, - { key: 'all', label: 'All Settings' }, - ]; - const show = (key: SectionKey) => selectedSection === 'all' || selectedSection === key; + const navItems: { key: SectionKey; label: string }[] = [ + { key: 'models', label: 'Models' }, + { key: 'localProviders', label: 'Local Providers' }, + { key: 'providers', label: 'Providers' }, + { key: 'featureOptions', label: 'Feature Options' }, + { key: 'general', label: 'General' }, + { key: 'all', label: 'All Settings' }, + ]; + const show = (key: SectionKey) => selectedSection === 'all' || selectedSection === key; const accessor = useAccessor() const commandService = accessor.get('ICommandService') const environmentService = accessor.get('IEnvironmentService') @@ -997,334 +997,334 @@ export const Settings = () => { return ( -
-
- {/* ────────────── SIDEBAR ────────────── */} +
+
+ {/* ────────────── SIDEBAR ────────────── */} - - - {/* ───────────── MAIN PANE ───────────── */} -
- - - -
- -

{`Void's Settings`}

- -
- - {/* Models section (formerly FeaturesTab) */} - - - - -
- - {/* Models section (formerly FeaturesTab) */} - -{show('models') && ( -<> -

Models

- -
- - - - )} - -{show('localProviders') && ( - - <> - -

Local Providers

-

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

- -
- -
- - - - -
-)} -{show('providers') && ( - - <> -

Providers

-

{`Void can access models from Anthropic, OpenAI, OpenRouter, and more.`}

- - - -
-)} - - -{show('featureOptions') && ( - - <> -

Feature Options

- -
- - {/* FIM */} -
-

{displayInfoOfFeatureName('Autocomplete')}

-
- - Experimental.{' '} - - - Only works with FIM models.* - -
- -
- {/* Enable Switch */} - -
- voidSettingsService.setGlobalSetting('enableAutocomplete', newVal)} - /> - {settingsState.globalSettings.enableAutocomplete ? 'Enabled' : 'Disabled'} -
-
- - {/* Model Dropdown */} - -
- -
-
- -
- -
-
- - {/* Apply */} - - -
-

{displayInfoOfFeatureName('Apply')}

-
Settings that control the behavior of the Apply button.
- -
- {/* Sync to Chat Switch */} -
- voidSettingsService.setGlobalSetting('syncApplyToChat', newVal)} - /> - {settingsState.globalSettings.syncApplyToChat ? 'Same as Chat model' : 'Different model'} -
- - {/* Model Dropdown */} -
- -
-
- - -
- {/* Fast Apply Method Dropdown */} -
- -
-
- -
-
- - - - - {/* Tools Section */} -
-

Tools

-
{`Tools are functions that LLMs can call. Some tools require user approval.`}
- -
- {/* Auto Accept Switch */} - - {[...toolApprovalTypes].map((approvalType) => { - return
- -
- })} - -
- - {/* Tool Lint Errors Switch */} - - -
- voidSettingsService.setGlobalSetting('includeToolLintErrors', newVal)} - /> - {settingsState.globalSettings.includeToolLintErrors ? 'Fix lint errors' : `Fix lint errors`} -
-
-
+ > + {label} + + ))}
+ + + {/* ───────────── MAIN PANE ───────────── */} +
-
-

Editor

-
{`Settings that control the visibility of Void suggestions in the code editor.`}
+
-
- {/* Auto Accept Switch */} +

{`Void's Settings`}

+ +
+ + {/* Models section (formerly FeaturesTab) */} + + + + +
+ + {/* Models section (formerly FeaturesTab) */} + + {show('models') && ( + <> +

Models

+ +
+ + + + )} + + {show('localProviders') && ( -
- voidSettingsService.setGlobalSetting('showInlineSuggestions', newVal)} - /> - {settingsState.globalSettings.showInlineSuggestions ? 'Show suggestions on select' : 'Show suggestions on select'} -
+ <> + +

Local Providers

+

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

+ +
+ +
+ + + +
-
-
-
- - -)} + )} + {show('providers') && ( + + <> +

Providers

+

{`Void can access models from Anthropic, OpenAI, OpenRouter, and more.`}

+ + + +
+ )} -{show('general') && ( - <> + {show('featureOptions') && ( + + <> +

Feature Options

- {/* General section (formerly GeneralTab) */} -
- -

One-Click Switch

-

{`Transfer your editor settings into Void.`}

+
+ + {/* FIM */} +
+

{displayInfoOfFeatureName('Autocomplete')}

+
+ + Experimental.{' '} + + + Only works with FIM models.* + +
-
- - - -
- -
+
+ {/* Enable Switch */} + +
+ voidSettingsService.setGlobalSetting('enableAutocomplete', newVal)} + /> + {settingsState.globalSettings.enableAutocomplete ? 'Enabled' : 'Disabled'} +
+
- {/* Import/Export section, as its own block right after One-Click Switch */} -
-

Import/Export

-

{`Transfer Void's settings and chats in and out of Void.`}

-
- {/* Settings Subcategory */} -
- - { fileInputSettingsRef.current?.click() }}> - Import Settings - - onDownload('Settings')}> - Export Settings - - { voidSettingsService.resetState(); }}> - Reset Settings - -
- {/* Chats Subcategory */} -
- - { fileInputChatsRef.current?.click() }}> - Import Chats - - onDownload('Chats')}> - Export Chats - - { chatThreadsService.resetState(); }}> - Reset Chats - -
-
-
+ {/* Model Dropdown */} + +
+ +
+
+ +
+ +
+
+ + {/* Apply */} + + +
+

{displayInfoOfFeatureName('Apply')}

+
Settings that control the behavior of the Apply button.
+ +
+ {/* Sync to Chat Switch */} +
+ voidSettingsService.setGlobalSetting('syncApplyToChat', newVal)} + /> + {settingsState.globalSettings.syncApplyToChat ? 'Same as Chat model' : 'Different model'} +
+ + {/* Model Dropdown */} +
+ +
+
+ + +
+ {/* Fast Apply Method Dropdown */} +
+ +
+
+ +
+
-
-

Built-in Settings

-

{`IDE settings, keyboard settings, and theme customization.`}

+ {/* Tools Section */} +
+

Tools

+
{`Tools are functions that LLMs can call. Some tools require user approval.`}
- -
- { commandService.executeCommand('workbench.action.openSettings') }}> - General Settings - - { commandService.executeCommand('workbench.action.openGlobalKeybindings') }}> - Keyboard Settings - - { commandService.executeCommand('workbench.action.selectTheme') }}> - Theme Settings - - { nativeHostService.showItemInFolder(environmentService.logsHome.fsPath) }}> - Open Logs - -
-
-
+
+ {/* Auto Accept Switch */} + + {[...toolApprovalTypes].map((approvalType) => { + return
+ +
+ })} + +
+ + {/* Tool Lint Errors Switch */} + + +
+ voidSettingsService.setGlobalSetting('includeToolLintErrors', newVal)} + /> + {settingsState.globalSettings.includeToolLintErrors ? 'Fix lint errors' : `Fix lint errors`} +
+
+
+
-
-

AI Instructions

-

- +

Editor

+
{`Settings that control the visibility of Void suggestions in the code editor.`}
+ +
+ {/* Auto Accept Switch */} + +
+ voidSettingsService.setGlobalSetting('showInlineSuggestions', newVal)} + /> + {settingsState.globalSettings.showInlineSuggestions ? 'Show suggestions on select' : 'Show suggestions on select'} +
+
+
+

+
+ +
+ )} + + + {show('general') && ( + <> + + {/* General section (formerly GeneralTab) */} +
+ +

One-Click Switch

+

{`Transfer your editor settings into Void.`}

+ +
+ + + +
+
+
+ + {/* Import/Export section, as its own block right after One-Click Switch */} +
+

Import/Export

+

{`Transfer Void's settings and chats in and out of Void.`}

+
+ {/* Settings Subcategory */} +
+ + { fileInputSettingsRef.current?.click() }}> + Import Settings + + onDownload('Settings')}> + Export Settings + + { voidSettingsService.resetState(); }}> + Reset Settings + +
+ {/* Chats Subcategory */} +
+ + { fileInputChatsRef.current?.click() }}> + Import Chats + + onDownload('Chats')}> + Export Chats + + { chatThreadsService.resetState(); }}> + Reset Chats + +
+
+
+ + + +
+ +

Built-in Settings

+

{`IDE settings, keyboard settings, and theme customization.`}

+ + +
+ { commandService.executeCommand('workbench.action.openSettings') }}> + General Settings + + { commandService.executeCommand('workbench.action.openGlobalKeybindings') }}> + Keyboard Settings + + { commandService.executeCommand('workbench.action.selectTheme') }}> + Theme Settings + + { nativeHostService.showItemInFolder(environmentService.logsHome.fsPath) }}> + Open Logs + +
+
+
+ + +
+

AI Instructions

+

+ -

- - - -
- -)} + + + + +
+ + )} -
-
-
-
-); +
+
+
+
+ ); } From 57d94d2d449f1b58c27e5efb57707ce74f37b772 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 00:54:59 -0700 Subject: [PATCH 20/25] fix spacing issues and make scroll whole settings page --- .../react/src/void-settings-tsx/Settings.tsx | 122 +++++++++--------- 1 file changed, 59 insertions(+), 63 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 6ae26df6..eeae0c09 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -22,7 +22,7 @@ import { TransferEditorType, TransferFilesInfo } from '../../../extensionTransfe // ───────────────────────────────────────────── // Sidebar navigation helpers // ───────────────────────────────────────────── -type SectionKey = +type Tab = | 'models' | 'localProviders' | 'providers' @@ -912,17 +912,17 @@ export const Settings = () => { const isDark = useIsDark() // ─── sidebar nav ────────────────────────── const [selectedSection, setSelectedSection] = - useState('models'); + useState('models'); - const navItems: { key: SectionKey; label: string }[] = [ - { key: 'models', label: 'Models' }, - { key: 'localProviders', label: 'Local Providers' }, - { key: 'providers', label: 'Providers' }, - { key: 'featureOptions', label: 'Feature Options' }, - { key: 'general', label: 'General' }, - { key: 'all', label: 'All Settings' }, + const navItems: { tab: Tab; label: string }[] = [ + { tab: 'models', label: 'Models' }, + { tab: 'localProviders', label: 'Local Providers' }, + { tab: 'providers', label: 'Other Providers' }, + { tab: 'featureOptions', label: 'Feature Options' }, + { tab: 'general', label: 'General' }, + { tab: 'all', label: 'All Settings' }, ]; - const show = (key: SectionKey) => selectedSection === 'all' || selectedSection === key; + const shouldShowTab = (tab: Tab) => selectedSection === 'all' || selectedSection === tab; const accessor = useAccessor() const commandService = accessor.get('ICommandService') const environmentService = accessor.get('IEnvironmentService') @@ -997,27 +997,27 @@ export const Settings = () => { return ( -
-
+
+
{/* ────────────── SIDEBAR ────────────── */} -
+ {/* MCP section */} +
+ +

MCP

+

+ +

+
+ { await mcpService.revealMCPConfigFile() }}> + Add MCP Server + +
+ + + + +
+
+ {/* General section */}
{/* One-Click Switch section */} @@ -1397,7 +1420,6 @@ export const Settings = () => { {/* Built-in Settings section */}
-

Built-in Settings

{`IDE settings, keyboard settings, and theme customization.`}

@@ -1432,8 +1454,29 @@ Alternatively, place a \`.voidrules\` file in the root of your workspace. + {/* --- Disable System Message Toggle --- */} +
+ +
+ { + voidSettingsService.setGlobalSetting('disableSystemMessage', newValue); + }} + /> + + {'Disable system message'} + +
+
+
+ {`When disabled, Void will not include anything in the system message except for content you specified above.`} +
+
+
From 020fb60d7472a6648b86037c0b28776d197fdf77 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 01:08:11 -0700 Subject: [PATCH 22/25] mcp tool rename --- src/vs/workbench/contrib/void/browser/chatThreadService.ts | 2 +- .../void/browser/react/src/sidebar-tsx/SidebarChat.tsx | 2 +- src/vs/workbench/contrib/void/common/toolsServiceTypes.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/chatThreadService.ts b/src/vs/workbench/contrib/void/browser/chatThreadService.ts index eb1a6883..30f38f10 100644 --- a/src/vs/workbench/contrib/void/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/void/browser/chatThreadService.ts @@ -641,7 +641,7 @@ class ChatThreadService extends Disposable implements IChatThreadService { // 2. if tool requires approval, break from the loop, awaiting approval - const approvalType = isBuiltInTool ? approvalTypeOfBuiltinToolName[toolName] : 'mcp-tools' + const approvalType = isBuiltInTool ? approvalTypeOfBuiltinToolName[toolName] : 'MCP tools' if (approvalType) { const autoApprove = this._settingsService.state.globalSettings.autoApprove[approvalType] // add a tool_request because we use it for UI if a tool is loading (this should be improved in the future) 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 26b12cc8..4bd6424a 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 @@ -1616,7 +1616,7 @@ const ToolRequestAcceptRejectButtons = ({ toolName }: { toolName: ToolName }) => ) - const approvalType = isABuiltinToolName(toolName) ? approvalTypeOfBuiltinToolName[toolName] : 'mcp-tools' + const approvalType = isABuiltinToolName(toolName) ? approvalTypeOfBuiltinToolName[toolName] : 'MCP tools' const approvalToggle = approvalType ?
: null diff --git a/src/vs/workbench/contrib/void/common/toolsServiceTypes.ts b/src/vs/workbench/contrib/void/common/toolsServiceTypes.ts index d930f5de..d5da3e17 100644 --- a/src/vs/workbench/contrib/void/common/toolsServiceTypes.ts +++ b/src/vs/workbench/contrib/void/common/toolsServiceTypes.ts @@ -18,7 +18,7 @@ export type ShallowDirectoryItem = { } -export const approvalTypeOfBuiltinToolName: Partial<{ [T in BuiltinToolName]?: 'edits' | 'terminal' | 'mcp-tools' }> = { +export const approvalTypeOfBuiltinToolName: Partial<{ [T in BuiltinToolName]?: 'edits' | 'terminal' | 'MCP tools' }> = { 'create_file_or_folder': 'edits', 'delete_file_or_folder': 'edits', 'rewrite_file': 'edits', @@ -35,7 +35,7 @@ export type ToolApprovalType = NonNullable<(typeof approvalTypeOfBuiltinToolName export const toolApprovalTypes = new Set([ ...Object.values(approvalTypeOfBuiltinToolName), - 'mcp-tools', + 'MCP tools', ]) From 822430535ea62e69888db90aec3bf2c98564bce6 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 01:12:34 -0700 Subject: [PATCH 23/25] MCP --- .../react/src/void-settings-tsx/Settings.tsx | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index b4249f3b..60294f06 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -1037,8 +1037,8 @@ export const Settings = () => { { tab: 'localProviders', label: 'Local Providers' }, { tab: 'providers', label: 'Other Providers' }, { tab: 'featureOptions', label: 'Feature Options' }, - { tab: 'mcp', label: 'MCP' }, { tab: 'general', label: 'General' }, + { tab: 'mcp', label: 'MCP' }, { tab: 'all', label: 'All Settings' }, ]; const shouldShowTab = (tab: Tab) => selectedSection === 'all' || selectedSection === tab; @@ -1345,27 +1345,6 @@ export const Settings = () => {
- {/* MCP section */} -
- -

MCP

-

- -

-
- { await mcpService.revealMCPConfigFile() }}> - Add MCP Server - -
- - - - -
-
- {/* General section */}
{/* One-Click Switch section */} @@ -1477,6 +1456,33 @@ Alternatively, place a \`.voidrules\` file in the root of your workspace.
+ + + {/* MCP section */} +
+ +

MCP

+

+ +

+
+ { await mcpService.revealMCPConfigFile() }}> + Add MCP Server + +
+ + + + +
+
+ + + + +
From a24d097264277c546b19dd7e6642ec2ab76ddde5 Mon Sep 17 00:00:00 2001 From: Joaquin Coromina Date: Fri, 30 May 2025 17:43:06 -0400 Subject: [PATCH 24/25] add remove prefix function for tool call, updated the tool call error to return tool call error response string rather than content object --- .../workbench/contrib/void/electron-main/mcpChannel.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts b/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts index 7e1be86b..39d5f79d 100644 --- a/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts +++ b/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts @@ -245,6 +245,10 @@ export class MCPChannel implements IServerChannel { } } + private _removeUniquePrefix(name: string) { + return name.split('_').slice(1).join('_') + } + private async _closeAllMCPServers() { for (const serverName in this.infoOfClientId) { await this._closeClient(serverName) @@ -310,7 +314,7 @@ export class MCPChannel implements IServerChannel { // Call the tool with the provided parameters const response = await client.callTool({ - name: toolName, + name: this._removeUniquePrefix(toolName), arguments: params }) const { content } = response as CallToolResult @@ -320,8 +324,7 @@ export class MCPChannel implements IServerChannel { // handle text response if (response.isError) { - throw new Error(`Tool call error: ${response.content}`) - // handle error + throw new Error(`Tool call error: ${returnValue.text}`) } // handle success From 9c642763f006c5a37561559c2820e6e89d506d75 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 30 May 2025 20:39:57 -0700 Subject: [PATCH 25/25] update voidrules --- .voidrules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.voidrules b/.voidrules index 59586971..6c655134 100644 --- a/.voidrules +++ b/.voidrules @@ -10,3 +10,5 @@ In typescript, do NOT cast to types if not neccessary. NEVER lazily cast to 'any Do not add or remove semicolons to any of my files. Just go with convention and make the least number of changes. Never modify files outside src/vs/workbench/contrib/void without consulting with the user first. + +All types that map from a value A to B should be called bOfA. For example, if you create a hashmap that goes from toolId to toolName, it should be called toolNameOfToolId, etc.