From 9d1ab8728aa028e69de5c095fac7de12d7d927f2 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 00:58:24 -0700 Subject: [PATCH 01/40] styles --- .../src/void-onboarding/VoidOnboarding.tsx | 188 +++++++++--------- 1 file changed, 91 insertions(+), 97 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 aa440078..2c30381a 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 @@ -5,13 +5,13 @@ import { useEffect, useState } from 'react'; import { useAccessor, useIsDark, useSettingsState } from '../util/services.js'; -import { Check, ExternalLink, X } from 'lucide-react'; +import { Brain, Check, DollarSign, ExternalLink, Lock, X } from 'lucide-react'; import { displayInfoOfProviderName, ProviderName, providerNames, refreshableProviderNames } from '../../../../common/voidSettingsTypes.js'; import { getModelCapabilities, ollamaRecommendedModels } from '../../../../common/modelCapabilities.js'; import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'; import { AddModelInputBox, AnimatedCheckmarkButton, ollamaSetupInstructions, OneClickSwitchButton, SettingsForProvider } from '../void-settings-tsx/Settings.js'; -const OVERRIDE_VALUE = true +const OVERRIDE_VALUE = false export const VoidOnboarding = () => { @@ -24,7 +24,6 @@ export const VoidOnboarding = () => {
+ - - } - content={<>} + +
+ + + } />, 2: + <> {/* Title */} -
Choose a Provider
+ +
Choose a Provider
{/* Preference Selector */} -
+
} - - - + } bottom={ @@ -701,7 +691,9 @@ const VoidOnboardingContent = () => { // {prevAndNextButtons} // , 3:
Settings and Themes
@@ -716,20 +708,22 @@ const VoidOnboardingContent = () => { bottom={prevAndNextButtons} />, 4: Jump in - } - content={ -
{ - // TODO make a fadeout effect - voidSettingsService.setGlobalSetting('isOnboardingComplete', true) - }} + key={4} - > - Enter the Void -
+ content={ + <> +
Jump in
+
{ + // TODO make a fadeout effect + voidSettingsService.setGlobalSetting('isOnboardingComplete', true) + }} + + > + Enter the Void +
+ } bottom={ Date: Tue, 15 Apr 2025 02:01:23 -0700 Subject: [PATCH 02/40] colors --- .../src/void-onboarding/VoidOnboarding.tsx | 160 +++++++----------- .../react/src/void-settings-tsx/Settings.tsx | 6 +- .../contrib/void/common/voidSettingsTypes.ts | 13 +- 3 files changed, 76 insertions(+), 103 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 2c30381a..d4d20926 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 @@ -101,15 +101,14 @@ const FadeIn = ({ children, className, delayMs = 0, ...props }: { children: Reac // content // prev/next - const NextButton = ({ onClick, ...props }: { onClick: () => void } & React.ButtonHTMLAttributes) => { return ( +
+ - + - -
+ + } @@ -552,62 +550,32 @@ const VoidOnboardingContent = () => {
Choose a Provider
{/* Preference Selector */} +
- - - - + }`} + data-tooltip-id='void-tooltip' + data-tooltip-content={`${option.label} providers`} + data-tooltip-place='bottom' + > + {option.label} + + ))}
+ {/* Provider Buttons */}
{
} 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 dd8914fb..9e7419dd 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 @@ -121,7 +121,7 @@ export const AnimatedCheckmarkButton = ({ text, className }: { text?: string, cl return
@@ -146,7 +146,7 @@ const AddButton = ({ disabled, text = 'Add', ...props }: { disabled?: boolean, t return @@ -175,7 +175,7 @@ export const AddModelInputBox = ({ providerName: permanentProviderName, classNam const numModels = settingsState.settingsOfProvider[providerName].models.length if (showCheckmark) { - return + return } if (!isOpen) { diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index f126cdcf..eb647795 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -70,7 +70,8 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn } else if (providerName === 'deepseek') { return { - title: 'DeepSeek.com API', + // title: 'DeepSeek.com API', + title: 'DeepSeek', } } else if (providerName === 'openRouter') { @@ -95,21 +96,25 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn } else if (providerName === 'gemini') { return { - title: 'Gemini API', + // title: 'Gemini API', + title: 'Gemini', } } else if (providerName === 'groq') { return { - title: 'Groq.com API', + // title: 'Groq.com API', + title: 'Groq', } } else if (providerName === 'xAI') { return { - title: 'Grok (xAI)', + // title: 'Grok (xAI)', + title: 'xAI', } } else if (providerName === 'mistral') { return { + // title: 'Mistral API', title: 'Mistral API', } } From 5f8fddb01e899d7c12b0dc5fe287c58c05bb2639 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 02:54:51 -0700 Subject: [PATCH 03/40] fix flash --- .../src/void-onboarding/VoidOnboarding.tsx | 104 ++++++++++++------ 1 file changed, 73 insertions(+), 31 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 d4d20926..a396866e 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 @@ -475,7 +475,6 @@ const VoidOnboardingContent = () => { // } // />, 0:
Welcome to Void
@@ -491,11 +490,10 @@ const VoidOnboardingContent = () => { } />, 1: } - content={ + content={ {/*
AI Preferences
*/}
What are you looking for in an AI model?
@@ -540,9 +538,6 @@ const VoidOnboardingContent = () => {
} />, 2: {/* Title */} @@ -551,7 +546,9 @@ const VoidOnboardingContent = () => { {/* Preference Selector */} -
+
{[ { id: 'smart', label: 'Intelligent' }, { id: 'private', label: 'Private' }, @@ -576,28 +573,75 @@ const VoidOnboardingContent = () => { - {/* Provider Buttons */} -
- - {(wantToUseOption === 'all' ? providerNames : providerNamesOfWantToUseOption[wantToUseOption]).map((providerName) => { - const isSelected = selectedProviderName === providerName - - return ( - - ) - })} - + {/* Provider Buttons - Pre-render all sets and use CSS to hide/show */} +
+ {/* Smart providers - only visible when wantToUseOption is 'smart' */} +
+ {providerNamesOfWantToUseOption.smart.map((providerName) => { + const isSelected = selectedProviderName === providerName + return ( + + ) + })} +
+ + {/* Private providers - only visible when wantToUseOption is 'private' */} +
+ {providerNamesOfWantToUseOption.private.map((providerName) => { + const isSelected = selectedProviderName === providerName + return ( + + ) + })} +
+ + {/* Cheap providers - only visible when wantToUseOption is 'cheap' */} +
+ {providerNamesOfWantToUseOption.cheap.map((providerName) => { + const isSelected = selectedProviderName === providerName + return ( + + ) + })} +
+ + {/* All providers - only visible when wantToUseOption is 'all' */} +
+ {providerNames.map((providerName) => { + const isSelected = selectedProviderName === providerName + return ( + + ) + })} +
{/* Description */} @@ -659,7 +703,6 @@ const VoidOnboardingContent = () => { // {prevAndNextButtons} //
, 3: @@ -676,7 +719,6 @@ const VoidOnboardingContent = () => { bottom={prevAndNextButtons} />, 4: From 0ddab03f8b0bba4034d491e5cbcd0b759a7a60ea Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 03:23:29 -0700 Subject: [PATCH 04/40] styles --- .../src/void-onboarding/VoidOnboarding.tsx | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 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 a396866e..fe78f6b5 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 @@ -37,11 +37,12 @@ export const VoidOnboarding = () => { const FADE_DURATION_MS = 2000 - -const FadeIn = ({ children, className, delayMs = 0, ...props }: { children: React.ReactNode, delayMs?: number, className?: string } & React.HTMLAttributes) => { +const FadeIn = ({ children, className, delayMs = 0, durationMs, ...props }: { children: React.ReactNode, delayMs?: number, durationMs?: number, className?: string } & React.HTMLAttributes) => { const [opacity, setOpacity] = useState(0) + const effectiveDurationMs = durationMs ?? FADE_DURATION_MS + useEffect(() => { const timeout = setTimeout(() => { @@ -53,7 +54,7 @@ const FadeIn = ({ children, className, delayMs = 0, ...props }: { children: Reac return ( -
+
{children}
) @@ -461,19 +462,7 @@ const VoidOnboardingContent = () => { }, [setPageIndex, voidSettingsState.globalSettings.isOnboardingComplete]) - // TODO add a description next to the skip button saying (you can always restart the onboarding in Settings) const contentOfIdx: { [pageIndex: number]: React.ReactNode } = { - // 0: - // } - // content={ - //
- // } - // bottom={ - //
- // } - // />, 0: @@ -493,7 +482,7 @@ const VoidOnboardingContent = () => { hasMaxWidth={false} top={<>} - content={ + content={
{/*
AI Preferences
*/}
What are you looking for in an AI model?
@@ -535,7 +524,7 @@ const VoidOnboardingContent = () => {
-
} +
} />, 2: { ) })}
- + {/* Private providers - only visible when wantToUseOption is 'private' */}
{providerNamesOfWantToUseOption.private.map((providerName) => { @@ -608,7 +597,7 @@ const VoidOnboardingContent = () => { ) })}
- + {/* Cheap providers - only visible when wantToUseOption is 'cheap' */}
{providerNamesOfWantToUseOption.cheap.map((providerName) => { @@ -625,7 +614,7 @@ const VoidOnboardingContent = () => { ) })}
- + {/* All providers - only visible when wantToUseOption is 'all' */}
{providerNames.map((providerName) => { @@ -684,7 +673,10 @@ const VoidOnboardingContent = () => { } bottom={ - prevAndNextButtons + + {prevAndNextButtons} + + } />, From f335ce7204d07da23db9a3b6701381bb787c50fb Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Tue, 15 Apr 2025 14:59:30 -0700 Subject: [PATCH 05/40] fix gemini --- create-appimage.sh | 112 ------------------ scripts/appimage/readme.md | 13 ++ .../llmMessage/sendLLMMessage.impl.ts | 8 +- 3 files changed, 19 insertions(+), 114 deletions(-) delete mode 100644 create-appimage.sh diff --git a/create-appimage.sh b/create-appimage.sh deleted file mode 100644 index c79a351c..00000000 --- a/create-appimage.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash -set -e # Exit on error -set -x # Print commands as they are executed - -# Configuration -APP_NAME="void" -APP_VERSION="1.0.0" -ARCH="x86_64" - -export ARCH - -# Check if void binary exists in current directory -if [ ! -f "./void" ]; then - echo "Error: void binary not found in current directory" - exit 1 -fi - -# Check if icon exists -if [ ! -f "./void.png" ]; then - echo "Error: void.png icon not found in current directory" - exit 1 -fi - -# Create temporary directory -TEMP_DIR="$(mktemp -d)" -echo "Created temporary directory: $TEMP_DIR" -APP_DIR="$TEMP_DIR/$APP_NAME.AppDir" - -# Create basic AppDir structure -mkdir -pv "$APP_DIR/usr/bin" -mkdir -pv "$APP_DIR/usr/lib" -mkdir -pv "$APP_DIR/usr/share/applications" -mkdir -pv "$APP_DIR/usr/share/icons/hicolor/256x256/apps" - -# Exclude create-appimage.sh and appimagetool-x86_64.AppImage from being copied -echo "Copying files excluding create-appimage.sh and appimagetool-x86_64.AppImage..." -for file in ./*; do - if [[ "$file" != "./create-appimage.sh" && "$file" != "./appimagetool-x86_64.AppImage" ]]; then - cp -rv "$file" "$APP_DIR/usr/bin/" - fi -done - -# Copy the icon to required locations -cp -v ./void.png "$APP_DIR/void.png" -cp -v ./void.png "$APP_DIR/usr/share/icons/hicolor/256x256/apps/void.png" - -# Copy dependencies with error checking -echo "Copying dependencies..." -for lib in $(ldd ./void | grep "=> /" | awk '{print $3}'); do - if [ -f "$lib" ]; then - cp -v "$lib" "$APP_DIR/usr/lib/" || echo "Failed to copy $lib" - else - echo "Warning: Library $lib not found" - fi -done - -# Create desktop file with error checking -echo "Creating desktop file..." -if ! cat > "$APP_DIR/$APP_NAME.desktop" < "$APP_DIR/AppRun" < Date: Tue, 15 Apr 2025 15:00:44 -0700 Subject: [PATCH 06/40] eslint --- .../void/electron-main/llmMessage/sendLLMMessage.impl.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 d613c62a..1645cdac 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 @@ -3,12 +3,14 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ +// disable foreign import complaints +/* eslint-disable */ import Anthropic from '@anthropic-ai/sdk'; import { Ollama } from 'ollama'; import OpenAI, { ClientOptions } from 'openai'; import { MistralCore } from '@mistralai/mistralai/core.js'; import { fimComplete } from '@mistralai/mistralai/funcs/fimComplete.js'; - +/* eslint-enable */ import { AnthropicLLMChatMessage, LLMChatMessage, LLMFIMMessage, ModelListParams, OllamaModelResponse, OnError, OnFinalMessage, OnText, RawToolCallObj, RawToolParamsObj } from '../../common/sendLLMMessageTypes.js'; import { ChatMode, displayInfoOfProviderName, ModelSelectionOptions, ProviderName, SettingsOfProvider } from '../../common/voidSettingsTypes.js'; From f59b24496ea7cb388009bfc5bd9508d830272f2d Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Tue, 15 Apr 2025 15:01:24 -0700 Subject: [PATCH 07/40] 1.2.2 fix gemini --- product.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product.json b/product.json index aee6d2c9..5f4f84bd 100644 --- a/product.json +++ b/product.json @@ -1,7 +1,7 @@ { "nameShort": "Void", "nameLong": "Void", - "voidVersion": "1.2.1", + "voidVersion": "1.2.2", "applicationName": "void", "dataFolderName": ".void-editor", "win32MutexName": "voideditor", From 119db73f69f5dd159fa434e17f1a74396e14992f Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 15:12:03 -0700 Subject: [PATCH 08/40] colors --- .../src/void-onboarding/VoidOnboarding.tsx | 113 +++++------------- 1 file changed, 30 insertions(+), 83 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 fe78f6b5..91ec82b3 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 @@ -400,7 +400,6 @@ const VoidOnboardingContent = () => { private: ['ollama', 'vLLM', 'openAICompatible'], cheap: ['gemini', 'deepseek', 'openRouter', 'ollama', 'vLLM'], all: providerNames, - // TODO allow user to redo onboarding } @@ -426,7 +425,7 @@ const VoidOnboardingContent = () => { // cannot be md const basicDescOfWantToUseOption: { [wantToUseOption in WantToUseOption]: string } = { smart: "Models with the best performance on benchmarks.", - private: "Host on your computer or network for full privacy.", + private: "Host on your computer or local network for full data privacy.", cheap: "Free and affordable options.", all: "", } @@ -439,21 +438,11 @@ const VoidOnboardingContent = () => { all: "", } - // set the selected provider name appropriately + // set the selected provider name to be the zeroth option when the user changes the page useEffect(() => { - if (wantToUseOption && providerNamesOfWantToUseOption[wantToUseOption].length > 0) { - setSelectedProviderName(providerNamesOfWantToUseOption[wantToUseOption][0]); - } else { - setSelectedProviderName(null); - } + setSelectedProviderName(providerNamesOfWantToUseOption[wantToUseOption][0]); }, [wantToUseOption]); - // set wantToUseOption to smart when page changes - useEffect(() => { - setWantToUseOption(wantToUseOption); - }, [pageIndex]); - - // reset the page to page 0 if the user redos onboarding useEffect(() => { if (!voidSettingsState.globalSettings.isOnboardingComplete) { @@ -562,75 +551,33 @@ const VoidOnboardingContent = () => { - {/* Provider Buttons - Pre-render all sets and use CSS to hide/show */} -
- {/* Smart providers - only visible when wantToUseOption is 'smart' */} -
- {providerNamesOfWantToUseOption.smart.map((providerName) => { - const isSelected = selectedProviderName === providerName - return ( - - ) - })} -
- - {/* Private providers - only visible when wantToUseOption is 'private' */} -
- {providerNamesOfWantToUseOption.private.map((providerName) => { - const isSelected = selectedProviderName === providerName - return ( - - ) - })} -
- - {/* Cheap providers - only visible when wantToUseOption is 'cheap' */} -
- {providerNamesOfWantToUseOption.cheap.map((providerName) => { - const isSelected = selectedProviderName === providerName - return ( - - ) - })} -
- - {/* All providers - only visible when wantToUseOption is 'all' */} -
- {providerNames.map((providerName) => { - const isSelected = selectedProviderName === providerName - return ( - - ) - })} -
+ {/* Provider Buttons */} +
+ {/* Provider options - mapped for each wantToUseOption type */} + {(['smart', 'private', 'cheap', 'all'] as WantToUseOption[]).map((option) => ( +
+ {(option === 'all' ? providerNames : providerNamesOfWantToUseOption[option]).map((providerName) => { + const isSelected = selectedProviderName === providerName + return ( + + ) + })} +
+ ))}
{/* Description */} From feea5e13f337697017f5e325c8921bc8c6452f02 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Tue, 15 Apr 2025 15:56:15 -0700 Subject: [PATCH 09/40] update service fix --- .../contrib/void/browser/voidUpdateActions.ts | 2 +- .../electron-main/voidUpdateMainService.ts | 84 ++++++++++++++----- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/voidUpdateActions.ts b/src/vs/workbench/contrib/void/browser/voidUpdateActions.ts index 378171d1..31666fb6 100644 --- a/src/vs/workbench/contrib/void/browser/voidUpdateActions.ts +++ b/src/vs/workbench/contrib/void/browser/voidUpdateActions.ts @@ -99,7 +99,7 @@ const notifyUpdate = (res: VoidCheckUpdateRespose & { message: string }, notifSe secondary: [{ id: 'void.updater.close', enabled: true, - label: `Keep Void outdated`, + label: `Keep current version`, tooltip: '', class: undefined, run: () => { diff --git a/src/vs/workbench/contrib/void/electron-main/voidUpdateMainService.ts b/src/vs/workbench/contrib/void/electron-main/voidUpdateMainService.ts index df46911c..c8ef9e64 100644 --- a/src/vs/workbench/contrib/void/electron-main/voidUpdateMainService.ts +++ b/src/vs/workbench/contrib/void/electron-main/voidUpdateMainService.ts @@ -23,6 +23,7 @@ export class VoidMainUpdateService extends Disposable implements IVoidUpdateServ super() } + async check(explicit: boolean): Promise { const isDevMode = !this._envMainService.isBuilt // found in abstractUpdateService.ts @@ -37,17 +38,17 @@ export class VoidMainUpdateService extends Disposable implements IVoidUpdateServ if (this._updateService.state.type === StateType.Uninitialized) { // The update service hasn't been initialized yet - return { message: explicit ? 'Not yet checking for updates...' : null, action: explicit ? 'reinstall' : undefined } as const + return { message: explicit ? 'Checking for updates soon...' : null, action: explicit ? 'reinstall' : undefined } as const } if (this._updateService.state.type === StateType.Idle) { // No updates currently available - return { message: explicit ? 'No update found!' : null, action: explicit ? 'reinstall' : undefined } as const + return { message: explicit ? 'No updates found!' : null, action: explicit ? 'reinstall' : undefined } as const } if (this._updateService.state.type === StateType.CheckingForUpdates) { // Currently checking for updates - return { message: explicit ? 'No updates found!' : null } as const + return { message: explicit ? 'Checking for updates...' : null } as const } if (this._updateService.state.type === StateType.AvailableForDownload) { @@ -62,7 +63,7 @@ export class VoidMainUpdateService extends Disposable implements IVoidUpdateServ if (this._updateService.state.type === StateType.Downloaded) { // Update has been downloaded but not yet ready - return { message: explicit ? 'Got download, need to apply...' : null, action: 'apply' } as const + return { message: explicit ? 'An update is ready to be applied!' : null, action: 'apply' } as const } if (this._updateService.state.type === StateType.Updating) { @@ -76,28 +77,69 @@ export class VoidMainUpdateService extends Disposable implements IVoidUpdateServ } if (this._updateService.state.type === StateType.Disabled) { - try { - const res = await fetch(`https://updates.voideditor.dev/api/v0/${this._productService.commit}`) - const resJSON = await res.json() + return await this._manualCheckGHTagIfDisabled(explicit) + } + return null + } - if (!resJSON) return null // null means error - const { hasUpdate, downloadMessage } = resJSON ?? {} - if (hasUpdate === undefined) - return null - const after = (downloadMessage || '') + '' - if (hasUpdate) - return { message: after, action: 'reinstall' } as const - return { message: 'Void is up-to-date!' } as const + + + + private async _manualCheckGHTagIfDisabled(explicit: boolean): Promise { + try { + const response = await fetch('https://api.github.com/repos/voideditor/binaries/releases/latest'); + + const data = await response.json(); + const version = data.tag_name; + + const myVersion = `${this._productService.voidVersion}.${this._productService.release}` + const latestVersion = version + + const isUpToDate = myVersion === latestVersion // only makes sense if response.ok + + let message: string | null + let action: 'reinstall' | undefined + + // explicit + if (explicit) { + if (response.ok) { + if (!isUpToDate) { + message = 'A new version of Void is available! Please reinstall (auto-updates are disabled on this OS) - it only takes a second!' + action = 'reinstall' + } + else { + message = 'Void is up-to-date!' + } + } + else { + message = `An error occurred when fetching the latest GitHub release tag. Please try again in ~5 minutes, or reinstall.` + action = 'reinstall' + } } - catch (e) { - return null + // not explicit + else { + if (response.ok && !isUpToDate) { + message = 'A new version of Void is available! Please reinstall (auto-updates are disabled on this OS) - it only takes a second!' + action = 'reinstall' + } + else { + message = null + } + } + return { message, action } as const + } + catch (e) { + if (explicit) { + return { + message: `An error occurred when fetching the latest GitHub release tag: ${e}. Please try again in ~5 minutes.`, + action: 'reinstall', + } + } + else { + return { message: null } as const } } - - return null - } } - From 29d1a919be37d66e1218d30536dc9eb0395e4cc2 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 16:16:04 -0700 Subject: [PATCH 10/40] small styles --- .../void/browser/react/src/sidebar-tsx/SidebarChat.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 d58b7559..ab7bca52 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 @@ -1364,12 +1364,12 @@ const EditToolLintErrors = ({ lintErrors }: { lintErrors: LintErrorItem[] }) => style={{ background: 'none' }} > Lint errors
{lintErrors.map((error, i) => ( From aa4398c7345f43bba7dfcfe14ac17ea3de73bd74 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 16:36:46 -0700 Subject: [PATCH 11/40] small changes --- src/vs/workbench/contrib/void/common/voidSettingsTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index eb647795..3977f31b 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -115,7 +115,7 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn else if (providerName === 'mistral') { return { // title: 'Mistral API', - title: 'Mistral API', + title: 'Mistral', } } From d3fd5be294e6e052367d329f391b1a2b87a0c50e Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 16:38:54 -0700 Subject: [PATCH 12/40] small --- .../void/browser/react/src/void-settings-tsx/Settings.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9e7419dd..1662d4cd 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 @@ -707,7 +707,7 @@ export const FeaturesTab = () => { value={voidSettingsState.globalSettings.includeToolLintErrors} onChange={(newVal) => voidSettingsService.setGlobalSetting('includeToolLintErrors', newVal)} /> - {voidSettingsState.globalSettings.includeToolLintErrors ? 'Fix lint errors' : `Don't fix lint errors`} + {voidSettingsState.globalSettings.includeToolLintErrors ? 'Fix lint errors' : `Fix lint errors`}
From 9b8f3ec2e27f8af74a20506a41a3506824c6de1a Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 16:52:21 -0700 Subject: [PATCH 13/40] desc --- .../browser/react/src/void-settings-tsx/Settings.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 1662d4cd..ab92f45f 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 @@ -549,7 +549,14 @@ export const ollamaSetupInstructions =
-
+
+ * +
From 6058b7ff7865e472ac0ce25d0cad1a13b2cd51e5 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Tue, 15 Apr 2025 17:04:04 -0700 Subject: [PATCH 14/40] misc fixes and gemini prompt improvement --- .../browser/convertToLLMMessageService.ts | 6 +- .../contrib/void/browser/editCodeService.ts | 26 +++- .../VoidCommandBar.tsx | 2 +- .../src/void-onboarding/VoidOnboarding.tsx | 142 ++++++++++++++---- .../react/src/void-settings-tsx/Settings.tsx | 4 +- .../contrib/void/common/prompt/prompts.ts | 12 +- 6 files changed, 140 insertions(+), 52 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index 3d64033e..5518d810 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -7,7 +7,7 @@ import { IWorkspaceContextService } from '../../../../platform/workspace/common/ import { IEditorService } from '../../../services/editor/common/editorService.js'; import { ChatMessage } from '../common/chatThreadServiceTypes.js'; import { getIsReasoningEnabledState, getMaxOutputTokens, getModelCapabilities } from '../common/modelCapabilities.js'; -import { toolCallXMLStr, chat_systemMessage, ToolName } from '../common/prompt/prompts.js'; +import { reParsedToolXMLString, chat_systemMessage, ToolName } from '../common/prompt/prompts.js'; import { AnthropicLLMChatMessage, AnthropicReasoning, LLMChatMessage, LLMFIMMessage, OpenAILLMChatMessage, RawToolParamsObj } from '../common/sendLLMMessageTypes.js'; import { IVoidSettingsService } from '../common/voidSettingsService.js'; import { ChatMode, FeatureName, ModelSelection } from '../common/voidSettingsTypes.js'; @@ -199,7 +199,7 @@ const prepareMessages_XML_tools = (messages: SimpleLLMMessage[], supportsAnthrop // alternatively, could just hold onto the original output, but this way requires less piping raw strings everywhere let content: LLMChatMessage['content'] = c.content if (next?.role === 'tool') { - content = `${content}\n\n${toolCallXMLStr(next.name, next.rawParams)}` + content = `${content}\n\n${reParsedToolXMLString(next.name, next.rawParams)}` } // anthropic reasoning @@ -442,7 +442,7 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess `...Directories string cut off, use tools to read more...` : `...Directories string cut off, ask user for more if necessary...` }) - const includeXMLToolDefinitions = specialToolFormat === undefined + const includeXMLToolDefinitions = !specialToolFormat const runningTerminalIds = this.terminalToolService.listTerminalIds() const systemMessage = chat_systemMessage({ workspaceFolders, openedURIs, directoryStr, activeURI, runningTerminalIds, chatMode, includeXMLToolDefinitions }) diff --git a/src/vs/workbench/contrib/void/browser/editCodeService.ts b/src/vs/workbench/contrib/void/browser/editCodeService.ts index 653cf3af..78fafa7c 100644 --- a/src/vs/workbench/contrib/void/browser/editCodeService.ts +++ b/src/vs/workbench/contrib/void/browser/editCodeService.ts @@ -1562,20 +1562,22 @@ class EditCodeService extends Disposable implements IEditCodeService { } - const errContentOfInvalidStr = (str: string & ReturnType, blockOrig: string, blockNum: number, blocks: ExtractedSearchReplaceBlock[]) => { + const errContentOfInvalidStr = (str: 'Not found' | 'Not unique' | 'Has overlap', blockOrig: string) => { const descStr = str === `Not found` ? `The most recent ORIGINAL code could not be found in the file, so you were interrupted. The text in ORIGINAL must EXACTLY match lines of code. The problematic ORIGINAL code was:\n${JSON.stringify(blockOrig)}` : str === `Not unique` ? `The most recent ORIGINAL code shows up multiple times in the file, so you were interrupted. You might want to expand the ORIGINAL excerpt so it's unique. The problematic ORIGINAL code was:\n${JSON.stringify(blockOrig)}` - : `` + : str === 'Has overlap' ? + `The most recent ORIGINAL code has overlap with another ORIGINAL code block that you outputted. Do NOT output any overlapping edits. The problematic ORIGINAL code was:\n${JSON.stringify(blockOrig)}` + : `` // string of <<<<< ORIGINAL >>>>> REPLACE blocks so far so LLM can understand what it currently has // const blocksSoFarStr = blocks.slice(0, blockNum).map(block => `${ORIGINAL}\n${block.orig}\n${DIVIDER}\n${block.final}\n${FINAL}`).join('\n') // const soFarStr = blocksSoFarStr ? `These are the Search/Replace blocks that have been applied so far:${tripleTick[0]}\n${blocksSoFarStr}\n${tripleTick[1]}` : '' // const continueMsg = soFarStr ? `${soFarStr}Please continue outputting SEARCH/REPLACE blocks starting where this leaves off.` : '' // const errMsg = `${descStr}${continueMsg ? `\n${continueMsg}` : ''}` - const soFarStr = 'All of your previous outputs have been ignored. Please re-output ALL SEARCH/REPLACE blocks starting from the first one, and avoid the error.' + const soFarStr = 'All of your previous outputs have been ignored. Please re-output ALL SEARCH/REPLACE blocks starting from the first one, and avoid the error this time.' const errMsg = `${descStr}\n${soFarStr}` return errMsg @@ -1610,7 +1612,7 @@ class EditCodeService extends Disposable implements IEditCodeService { const addedTrackingZoneOfBlockNum: TrackingZone[] = [] diffZone._streamState.line = 1 - const N_RETRIES = 2 + const N_RETRIES = 4 // allowed to throw errors - this is called inside a promise that handles everything const runSearchReplace = async () => { @@ -1684,17 +1686,25 @@ class EditCodeService extends Disposable implements IEditCodeService { // if this is the first time we're seeing this block, add it as a diffarea so we can start streaming in it if (!(blockNum in addedTrackingZoneOfBlockNum)) { - const originalBounds = findTextInCode(block.orig, originalFileCode, true) // if error - if (typeof originalBounds === 'string') { + // Check for overlap with existing modified ranges + const hasOverlap = addedTrackingZoneOfBlockNum.some(trackingZone => { + const [existingStart, existingEnd] = trackingZone.metadata.originalBounds; + const hasNoOverlap = endLine < existingStart || startLine > existingEnd + return !hasNoOverlap + }); + + if (typeof originalBounds === 'string' || hasOverlap) { + const errorMessage = typeof originalBounds === 'string' ? originalBounds : 'Has overlap' as const + console.log('--------------Error finding text in code:') console.log('originalFileCode', { originalFileCode }) console.log('fullText', { fullText }) - console.log('error:', originalBounds) + console.log('error:', errorMessage) console.log('block.orig:', block.orig) console.log('---------') - const content = errContentOfInvalidStr(originalBounds, block.orig, blockNum, blocks) + const content = errContentOfInvalidStr(errorMessage, block.orig) messages.push( { role: 'assistant', content: fullText }, // latest output { role: 'user', content: content } // user explanation of what's wrong diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-editor-widgets-tsx/VoidCommandBar.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-editor-widgets-tsx/VoidCommandBar.tsx index dcf97f8e..40b34d14 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-editor-widgets-tsx/VoidCommandBar.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-editor-widgets-tsx/VoidCommandBar.tsx @@ -111,7 +111,7 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => { const { model } = await voidModelService.getModelSafe(nextURI) if (model) { // switch to the URI - editorService.openCodeEditor({ resource: nextURI, options: { revealIfVisible: true } }, editor) + editorService.openCodeEditor({ resource: model.uri, options: { revealIfVisible: true } }, editor) } } 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 91ec82b3..3a885c6c 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 @@ -392,8 +392,32 @@ const VoidOnboardingContent = () => { // page 1 state const [wantToUseOption, setWantToUseOption] = useState('smart') - // page 2 state - const [selectedProviderName, setSelectedProviderName] = useState(null) + // Replace the single selectedProviderName with four separate states + // page 2 state - each tab gets its own state + const [selectedIntelligentProvider, setSelectedIntelligentProvider] = useState('anthropic'); + const [selectedPrivateProvider, setSelectedPrivateProvider] = useState('ollama'); + const [selectedAffordableProvider, setSelectedAffordableProvider] = useState('gemini'); + const [selectedAllProvider, setSelectedAllProvider] = useState('anthropic'); + + // Helper function to get the current selected provider based on active tab + const getSelectedProvider = (): ProviderName => { + switch (wantToUseOption) { + case 'smart': return selectedIntelligentProvider; + case 'private': return selectedPrivateProvider; + case 'cheap': return selectedAffordableProvider; + case 'all': return selectedAllProvider; + } + } + + // Helper function to set the selected provider for the current tab + const setSelectedProvider = (provider: ProviderName) => { + switch (wantToUseOption) { + case 'smart': setSelectedIntelligentProvider(provider); break; + case 'private': setSelectedPrivateProvider(provider); break; + case 'cheap': setSelectedAffordableProvider(provider); break; + case 'all': setSelectedAllProvider(provider); break; + } + } const providerNamesOfWantToUseOption: { [wantToUseOption in WantToUseOption]: ProviderName[] } = { smart: ['anthropic', 'openAI', 'gemini', 'openRouter'], @@ -403,6 +427,7 @@ const VoidOnboardingContent = () => { } + const selectedProviderName = getSelectedProvider(); const didFillInProviderSettings = selectedProviderName && voidSettingsState.settingsOfProvider[selectedProviderName]._didFillInProviderSettings const isApiKeyLongEnoughIfApiKeyExists = selectedProviderName && voidSettingsState.settingsOfProvider[selectedProviderName].apiKey ? voidSettingsState.settingsOfProvider[selectedProviderName].apiKey.length > 15 : true const isAtLeastOneModel = selectedProviderName && voidSettingsState.settingsOfProvider[selectedProviderName].models.length >= 1 @@ -438,10 +463,21 @@ const VoidOnboardingContent = () => { all: "", } - // set the selected provider name to be the zeroth option when the user changes the page + // Modified: initialize separate provider states on initial render instead of watching wantToUseOption changes useEffect(() => { - setSelectedProviderName(providerNamesOfWantToUseOption[wantToUseOption][0]); - }, [wantToUseOption]); + if (selectedIntelligentProvider === undefined) { + setSelectedIntelligentProvider(providerNamesOfWantToUseOption['smart'][0]); + } + if (selectedPrivateProvider === undefined) { + setSelectedPrivateProvider(providerNamesOfWantToUseOption['private'][0]); + } + if (selectedAffordableProvider === undefined) { + setSelectedAffordableProvider(providerNamesOfWantToUseOption['cheap'][0]); + } + if (selectedAllProvider === undefined) { + setSelectedAllProvider(providerNamesOfWantToUseOption['all'][0]); + } + }, []); // reset the page to page 0 if the user redos onboarding useEffect(() => { @@ -551,33 +587,75 @@ const VoidOnboardingContent = () => { - {/* Provider Buttons */} -
- {/* Provider options - mapped for each wantToUseOption type */} - {(['smart', 'private', 'cheap', 'all'] as WantToUseOption[]).map((option) => ( -
- {(option === 'all' ? providerNames : providerNamesOfWantToUseOption[option]).map((providerName) => { - const isSelected = selectedProviderName === providerName - return ( - - ) - })} -
- ))} + {/* Provider Buttons - Modified to use separate components for each tab */} +
+ {/* Intelligent tab */} +
+ {providerNamesOfWantToUseOption['smart'].map((providerName) => { + const isSelected = selectedIntelligentProvider === providerName; + return ( + + ); + })} +
+ + {/* Private tab */} +
+ {providerNamesOfWantToUseOption['private'].map((providerName) => { + const isSelected = selectedPrivateProvider === providerName; + return ( + + ); + })} +
+ + {/* Affordable tab */} +
+ {providerNamesOfWantToUseOption['cheap'].map((providerName) => { + const isSelected = selectedAffordableProvider === providerName; + return ( + + ); + })} +
+ + {/* All tab */} +
+ {providerNames.map((providerName) => { + const isSelected = selectedAllProvider === providerName; + return ( + + ); + })} +
{/* Description */} 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 ab92f45f..c87a6c98 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 @@ -624,7 +624,7 @@ export const FeaturesTab = () => {

{displayInfoOfFeatureName('Autocomplete')}

- Experimental. Only works with FIM models. + Experimental.{' '} { data-tooltip-content='We recommend using qwen2.5-coder:1.5b with Ollama.' data-tooltip-class-name='void-max-w-[20px]' > - * + Only works with FIM models.*
diff --git a/src/vs/workbench/contrib/void/common/prompt/prompts.ts b/src/vs/workbench/contrib/void/common/prompt/prompts.ts index 0c33c7f7..19dcf545 100644 --- a/src/vs/workbench/contrib/void/common/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/common/prompt/prompts.ts @@ -205,7 +205,7 @@ export const availableTools = (chatMode: ChatMode) => { return tools } -const availableXMLToolsStr = (tools: InternalToolInfo[]) => { +const toolCallDefinitionsXMLString = (tools: InternalToolInfo[]) => { return `${tools.map((t, i) => { const params = Object.keys(t.params).map(paramName => `<${paramName}>${t.params[paramName].description}`).join('\n') return `\ @@ -217,7 +217,7 @@ Format: }).join('\n\n')}` } -export const toolCallXMLStr = (toolName: ToolName, toolParams: RawToolParamsObj) => { +export const reParsedToolXMLString = (toolName: ToolName, toolParams: RawToolParamsObj) => { const params = Object.keys(toolParams).map(paramName => `<${paramName}>${toolParams[paramName as ToolParamName]}`).join('\n') return `\ <${toolName}>${!params ? '' : `\n${params}`} @@ -234,12 +234,12 @@ const systemToolsXMLPrompt = (chatMode: ChatMode) => { const toolXMLDefinitions = (`\ Available tools: -${availableXMLToolsStr(tools)}`) +${toolCallDefinitionsXMLString(tools)}`) const toolCallXMLGuidelines = (`\ Tool calling details: -- Once you write a tool call, you must STOP and WAIT for the result. -- To call a tool, write its name and parameters in one of the XML formats specified above at the BOTTOM of your response. +- To call a tool, write its name and parameters in one of the XML formats specified above. +- After you write the tool call, you must STOP and WAIT for the result. - All parameters are REQUIRED unless noted otherwise. - You are only allowed to output ONE tool call, and it must be at the END of your response. - Your tool call will be executed immediately, and the results will appear in the following user message.`) @@ -341,9 +341,9 @@ ${details.map((d, i) => `${i + 1}. ${d}`).join('\n\n')}`) const ansStrs: string[] = [] ansStrs.push(header) ansStrs.push(sysInfo) - ansStrs.push(fsInfo) if (toolDefinitions) ansStrs.push(toolDefinitions) ansStrs.push(importantDetails) + ansStrs.push(fsInfo) const fullSystemMsgStr = ansStrs .join('\n\n\n') From bf9852858e0f24aeae3107c25d62b181bed97b42 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Tue, 15 Apr 2025 17:30:21 -0700 Subject: [PATCH 15/40] remove auto-selection of current file --- .../contrib/void/browser/chatThreadService.ts | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/chatThreadService.ts b/src/vs/workbench/contrib/void/browser/chatThreadService.ts index cb2816ee..8afa92dd 100644 --- a/src/vs/workbench/contrib/void/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/void/browser/chatThreadService.ts @@ -25,8 +25,6 @@ import { Position } from '../../../../editor/common/core/position.js'; import { IMetricsService } from '../common/metricsService.js'; import { shorten } from '../../../../base/common/labels.js'; import { IVoidModelService } from '../common/voidModelService.js'; -import { IEditorService } from '../../../services/editor/common/editorService.js'; -import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; import { findLast, findLastIdx } from '../../../../base/common/arraysFind.js'; import { IEditCodeService } from './editCodeServiceInterface.js'; import { VoidFileSnapshot } from '../common/editCodeServiceTypes.js'; @@ -246,8 +244,6 @@ class ChatThreadService extends Disposable implements IChatThreadService { @IVoidSettingsService private readonly _settingsService: IVoidSettingsService, @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, @IMetricsService private readonly _metricsService: IMetricsService, - @IEditorService private readonly _editorService: IEditorService, - @ICodeEditorService private readonly _codeEditorService: ICodeEditorService, @IEditCodeService private readonly _editCodeService: IEditCodeService, @INotificationService private readonly _notificationService: INotificationService, @IConvertToLLMMessageService private readonly _convertToLLMMessagesService: IConvertToLLMMessageService, @@ -266,9 +262,6 @@ class ChatThreadService extends Disposable implements IChatThreadService { // always be in a thread this.openNewThread() - // when the user changes files, automatically add the new file as a stagingSelection - this._register(this._editorService.onDidActiveEditorChange(() => this._addCurrentFileAsStagingSelectionDuringFileChange())); - // keep track of user-modified files // const disposablesOfModelId: { [modelId: string]: IDisposable[] } = {} @@ -288,40 +281,6 @@ class ChatThreadService extends Disposable implements IChatThreadService { } - // add the current file to the thread being edited - private _addCurrentFileAsStagingSelectionDuringFileChange() { - const newModel = this._codeEditorService.getActiveCodeEditor()?.getModel() ?? null - if (!newModel) { return } - - const isCurrentlyFocusing = this.isCurrentlyFocusingMessage() - if (isCurrentlyFocusing) return - - // only add if the user hasn't sent a message yet - if (this.getCurrentThread().messages.length !== 0) return - - const newStagingSelection: StagingSelectionItem = { - type: 'File', - uri: newModel.uri, - language: newModel.getLanguageId(), - state: { wasAddedAsCurrentFile: true } - } - - const oldStagingSelections = this.getCurrentThreadState().stagingSelections || []; - - // remove all old selectons that are marked as `wasAddedAsCurrentFile` - const newStagingSelections: StagingSelectionItem[] = oldStagingSelections.filter(s => s.state && !s.state.wasAddedAsCurrentFile) - - const fileIsAlreadyHere = oldStagingSelections.some(s => s.type === 'File' && s.uri.fsPath === newStagingSelection.uri.fsPath) - - if (!fileIsAlreadyHere) { - newStagingSelections.push(newStagingSelection) - } - - this.setCurrentThreadState({ stagingSelections: newStagingSelections }); - - } - - // !!! this is important for properly restoring URIs from storage // should probably re-use code from void/src/vs/base/common/marshalling.ts instead. but this is simple enough private _convertThreadDataFromStorage(threadsStr: string): ChatThreads { @@ -1386,21 +1345,6 @@ We only need to do it for files that were edited since `from`, ie files between // switch to the thread this.switchToThread(threadId) - // add the current file as a staging selection - const model = this._codeEditorService.getActiveCodeEditor()?.getModel() - if (model) { - this._setThreadState(this.state.currentThreadId, { - stagingSelections: [{ - type: 'File', - uri: model.uri, - language: model.getLanguageId(), - state: { - wasAddedAsCurrentFile: true - } - }] - }) - } - return; } } // otherwise, start a new thread From 9bd97d0cd5a88e10704cf31e7abee18ebf5f87f1 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Tue, 15 Apr 2025 17:30:35 -0700 Subject: [PATCH 16/40] Claude reasoning small fix --- .../contrib/void/browser/convertToLLMMessageService.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index 5518d810..053d25bd 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -143,13 +143,19 @@ const prepareMessages_anthropic_tools = (messages: SimpleLLMMessage[], supportsA // add anthropic reasoning if (currMsg.role === 'assistant') { if (currMsg.anthropicReasoning && supportsAnthropicReasoning) { - const content = currMsg.content newMessages[i] = { role: 'assistant', content: content ? [...currMsg.anthropicReasoning, { type: 'text' as const, text: content }] : currMsg.anthropicReasoning } } + else { + newMessages[i] = { + role: 'assistant', + content: currMsg.content, + // strip away anthropicReasoning + } + } continue } From b62943fffd653862fb78ae01cece57077f6c41c0 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Tue, 15 Apr 2025 18:35:21 -0700 Subject: [PATCH 17/40] tooltip for ollama --- .../react/src/void-settings-tsx/Settings.tsx | 10 +++--- .../react/src/void-tooltip/VoidTooltip.tsx | 31 ++++++++++++++++++- 2 files changed, 34 insertions(+), 7 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 c87a6c98..9dbb164e 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 @@ -550,12 +550,10 @@ export const ollamaSetupInstructions =
- * + className='pl-6 flex items-center w-fit' + data-tooltip-id='void-tooltip-ollama-settings' + > +
diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-tooltip/VoidTooltip.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-tooltip/VoidTooltip.tsx index cc376fde..0bd7d9e0 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-tooltip/VoidTooltip.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-tooltip/VoidTooltip.tsx @@ -3,6 +3,7 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ +import '../styles.css' import { Tooltip } from 'react-tooltip'; import 'react-tooltip/dist/react-tooltip.css'; import { useIsDark } from '../util/services.js'; @@ -44,7 +45,7 @@ export const VoidTooltip = () => { <>