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" < 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 { @@ -390,36 +349,6 @@ class ChatThreadService extends Disposable implements IChatThreadService { - editUserMessageAndStreamResponse: IChatThreadService['editUserMessageAndStreamResponse'] = async ({ userMessage, messageIdx, threadId }) => { - - const thread = this.state.allThreads[threadId] - if (!thread) return // should never happen - - if (thread.messages?.[messageIdx]?.role !== 'user') { - throw new Error(`Error: editing a message with role !=='user'`) - } - - // get prev and curr selections before clearing the message - const currSelns = thread.messages[messageIdx].state.stagingSelections || [] // staging selections for the edited message - - // clear messages up to the index - const slicedMessages = thread.messages.slice(0, messageIdx) - this._setState({ - allThreads: { - ...this.state.allThreads, - [thread.id]: { - ...thread, - messages: slicedMessages - } - } - }, true) - - // re-add the message and stream it - this.addUserMessageAndStreamResponse({ userMessage, _chatSelections: currSelns, threadId }) - - } - - private _currentModelSelectionProps = () => { // these settings should not change throughout the loop (eg anthropic breaks if you change its thinking mode and it's using tools) const featureName: FeatureName = 'Chat' @@ -924,7 +853,7 @@ class ChatThreadService extends Disposable implements IChatThreadService { const [_, toIdx] = c if (toIdx === fromIdx) return - // console.log(`going from ${fromIdx} to ${toIdx}`) + console.log(`going from ${fromIdx} to ${toIdx}`) // update the user's checkpoint this._addUserModificationsToCurrCheckpoint({ threadId }) @@ -936,15 +865,14 @@ A,B,C are all files. x means a checkpoint where the file changed. A B C D E F G H I -x x x x x x x x x -| | | | | | | | | -x | | | | | | | x ----x-|-|-|-x-|-x-|----- <-- to - x | | | | | x - | | x x | - | | | | --------x-|---x-x------- <-- from - x + x x x x x x <-- you can't always go up to find the "before" version; sometimes you need to go down + | | | | | | x +--x-|-|-|-x---x-|----- <-- to + | | | | x x + | | x x | + | | | | +----x-|---x-x------- <-- from + x We need to revert anything that happened between to+1 and from. **We do this by finding the last x from 0...`to` for each file and applying those contents.** @@ -952,9 +880,19 @@ We only need to do it for files that were edited since `to`, ie files between to */ if (toIdx < fromIdx) { const { lastIdxOfURI } = this._getCheckpointsBetween({ threadId, loIdx: toIdx + 1, hiIdx: fromIdx }) + + const idxes = function* () { + for (let k = toIdx; k >= 0; k -= 1) { // first go up + yield k + } + for (let k = toIdx + 1; k < thread.messages.length; k += 1) { // then go down + yield k + } + } + for (const fsPath in lastIdxOfURI) { - // apply lowest down content for each uri (or original if not found) - for (let k = toIdx; k >= 0; k -= 1) { + // find the first instance of this file starting at toIdx (go up to latest file; if there is none, go down) + for (const k of idxes()) { const message = thread.messages[k] if (message.role !== 'checkpoint') continue const res = this._getCheckpointInfo(message, fsPath, { includeUserModifiedChanges: jumpToUserModified }) @@ -970,16 +908,16 @@ We only need to do it for files that were edited since `to`, ie files between to /* if redoing -A B C D E F G H I -x x x x x x x x x -| | | | | | | | | -x | | | | | | | x ----x-|-|-|-x-|-x-|----- <-- from - x | | | | | x - | | x x | - | | | | --------x-|---x-x------- <-- to - x +A B C D E F G H I J + x x x x x x x + | | | | | | x x x +--x-|-|-|-x---x-|-|--- <-- from + | | | | x x + | | x x | + | | | | +----x-|---x-x-----|--- <-- to + x x + We need to apply latest change for anything that happened between from+1 and to. We only need to do it for files that were edited since `from`, ie files between from+1...to. @@ -995,7 +933,6 @@ We only need to do it for files that were edited since `from`, ie files between if (!res) continue const { voidFileSnapshot } = res if (!voidFileSnapshot) continue - this._editCodeService.restoreVoidFileSnapshot(URI.file(fsPath), voidFileSnapshot) break } @@ -1044,11 +981,15 @@ We only need to do it for files that were edited since `from`, ie files between }) } - async addUserMessageAndStreamResponse({ userMessage, _chatSelections, threadId }: { userMessage: string, _chatSelections?: StagingSelectionItem[], threadId: string }) { + dismissStreamError(threadId: string): void { + this._setStreamState(threadId, { error: undefined }, 'merge') + } + + + private async _addUserMessageAndStreamResponse({ userMessage, _chatSelections, threadId }: { userMessage: string, _chatSelections?: StagingSelectionItem[], threadId: string }) { const thread = this.state.allThreads[threadId] if (!thread) return // should never happen - const llmCancelToken = this.streamState[threadId]?.streamingToken // currently streaming LLM on this thread if (llmCancelToken === undefined && this.streamState[threadId]?.isRunning === 'LLM') { // if about to call the other LLM, just wait for it by stopping right now @@ -1057,14 +998,11 @@ We only need to do it for files that were edited since `from`, ie files between // stop it (this simply resolves the promise to free up space) if (llmCancelToken !== undefined) this._llmMessageService.abort(llmCancelToken) - - // add dummy before this message to keep checkpoint before user message idea consistent if (thread.messages.length === 0) { this._addUserCheckpoint({ threadId }) } - const { chatMode } = this._settingsService.state.globalSettings // add user's message to chat history @@ -1084,11 +1022,61 @@ We only need to do it for files that were edited since `from`, ie files between ) } - dismissStreamError(threadId: string): void { - this._setStreamState(threadId, { error: undefined }, 'merge') + + async addUserMessageAndStreamResponse({ userMessage, _chatSelections, threadId }: { userMessage: string, _chatSelections?: StagingSelectionItem[], threadId: string }) { + const thread = this.state.allThreads[threadId]; + if (!thread) return + + // if there's a current checkpoint, delete all messages after it + if (thread.state.currCheckpointIdx !== null) { + const checkpointIdx = thread.state.currCheckpointIdx; + const newMessages = thread.messages.slice(0, checkpointIdx + 1); + + // Update the thread with truncated messages + const newThreads = { + ...this.state.allThreads, + [threadId]: { + ...thread, + lastModified: new Date().toISOString(), + messages: newMessages, + } + }; + this._storeAllThreads(newThreads); + this._setState({ allThreads: newThreads }, true); + } + + // Now call the original method to add the user message and stream the response + await this._addUserMessageAndStreamResponse({ userMessage, _chatSelections, threadId }); + } + editUserMessageAndStreamResponse: IChatThreadService['editUserMessageAndStreamResponse'] = async ({ userMessage, messageIdx, threadId }) => { + const thread = this.state.allThreads[threadId] + if (!thread) return // should never happen + + if (thread.messages?.[messageIdx]?.role !== 'user') { + throw new Error(`Error: editing a message with role !=='user'`) + } + + // get prev and curr selections before clearing the message + const currSelns = thread.messages[messageIdx].state.stagingSelections || [] // staging selections for the edited message + + // clear messages up to the index + const slicedMessages = thread.messages.slice(0, messageIdx) + this._setState({ + allThreads: { + ...this.state.allThreads, + [thread.id]: { + ...thread, + messages: slicedMessages + } + } + }, true) + + // re-add the message and stream it + this._addUserMessageAndStreamResponse({ userMessage, _chatSelections: currSelns, threadId }) + } // ---------- the rest ---------- @@ -1386,21 +1374,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 diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index 3d64033e..053d25bd 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'; @@ -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 } @@ -199,7 +205,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 +448,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..72d90ce7 100644 --- a/src/vs/workbench/contrib/void/browser/editCodeService.ts +++ b/src/vs/workbench/contrib/void/browser/editCodeService.ts @@ -258,6 +258,22 @@ class EditCodeService extends Disposable implements IEditCodeService { this._realignAllDiffAreasLines(uri, change.text, change.range) } this._refreshStylesAndDiffsInURI(uri) + + // if diffarea has no diffs after a user edit, delete it + const diffAreasToDelete: DiffZone[] = [] + for (const diffareaid of this.diffAreasOfURI[uri.fsPath] ?? []) { + const diffArea = this.diffAreaOfId[diffareaid] ?? null + const shouldDelete = diffArea?.type === 'DiffZone' && Object.keys(diffArea._diffOfId).length === 0 + if (shouldDelete) { + diffAreasToDelete.push(diffArea) + } + } + if (diffAreasToDelete.length !== 0) { + const { onFinishEdit } = this._addToHistory(uri) + diffAreasToDelete.forEach(da => this._deleteDiffZone(da)) + onFinishEdit() + } + } @@ -1562,20 +1578,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 +1628,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 +1702,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/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index d58b7559..97ffa768 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) => ( @@ -1949,10 +1949,14 @@ const Checkpoint = ({ message, threadId, messageIdx, isCheckpointGhost, threadIs style={{ position: 'relative', display: 'inline-block' }} // allow absolute icon onClick={() => { if (threadIsRunning) return - chatThreadService.jumpToCheckpointBeforeMessageIdx({ threadId, messageIdx, jumpToUserModified: true }) + chatThreadService.jumpToCheckpointBeforeMessageIdx({ + threadId, + messageIdx, + jumpToUserModified: messageIdx === (chatThreadService.state.allThreads[threadId]?.messages.length ?? 0) - 1 + }) }} > - Checkpoint + Checkpoint
} diff --git a/src/vs/workbench/contrib/void/browser/react/src/styles.css b/src/vs/workbench/contrib/void/browser/react/src/styles.css index e7a3da15..13257709 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/styles.css +++ b/src/vs/workbench/contrib/void/browser/react/src/styles.css @@ -11,7 +11,7 @@ --void-bg-1: var(--vscode-input-background); --void-bg-1-alt: var(--vscode-badge-background); --void-bg-2: var(--vscode-sideBar-background); - --void-bg-2-alt: color-mix(in srgb, var(--vscode-sideBar-background) 30%, var(--vscode-editor-background) 70%); + --void-bg-2-alt: color-mix(in srgb, var(--vscode-editor-background) 30%, var(--vscode-sideBar-background) 70%); --void-bg-3: var(--vscode-editor-background); --void-fg-0: color-mix(in srgb, var(--vscode-tab-activeForeground) 90%, black 10%); diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index b7e31757..c0f00c53 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -664,57 +664,60 @@ export const VoidCustomDropdownBox = >({ {isOpen && (
- {options.map((option) => { - const thisOptionIsSelected = getOptionsEqual(option, selectedOption); - const optionName = getOptionDropdownName(option); - const optionDetail = getOptionDropdownDetail?.(option) || ''; + onWheel={(e) => e.stopPropagation()} + >
- return ( -
{ + const thisOptionIsSelected = getOptionsEqual(option, selectedOption); + const optionName = getOptionDropdownName(option); + const optionDetail = getOptionDropdownDetail?.(option) || ''; + + return ( +
{ - onChangeOption(option); - setIsOpen(false); - }} - > -
- {thisOptionIsSelected && ( - - - - )} + onClick={() => { + onChangeOption(option); + setIsOpen(false); + }} + > +
+ {thisOptionIsSelected && ( + + + + )} +
+ + {optionName} + {optionDetail} +
- - {optionName} - {optionDetail} - -
- ); - })} + ); + })} +
+
)}
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 aa440078..47b3ce1c 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 = () => {
} - -
- + } bottom={ - prevAndNextButtons + + {prevAndNextButtons} + + } />, @@ -701,7 +720,8 @@ const VoidOnboardingContent = () => { // {prevAndNextButtons} // , 3:
Settings and Themes
@@ -716,20 +736,21 @@ const VoidOnboardingContent = () => { bottom={prevAndNextButtons} />, 4: Jump in - } - content={ -
{ - // TODO make a fadeout effect - voidSettingsService.setGlobalSetting('isOnboardingComplete', true) - }} - > - Enter the Void -
+ content={ + <> +
Jump in
+
{ + // TODO make a fadeout effect + voidSettingsService.setGlobalSetting('isOnboardingComplete', true) + }} + + > + Enter the Void +
+ } bottom={ } -// const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], featureName: FeatureName }) => { -// const accessor = useAccessor() - -// const voidSettingsService = accessor.get('IVoidSettingsService') - -// let weChangedText = false - -// return { -// if (weChangedText) return -// voidSettingsService.setModelSelectionOfFeature(featureName, newVal) -// }, [voidSettingsService, featureName])} -// // we are responsible for setting the initial state here. always sync instance when state changes. -// onCreateInstance={useCallback((instance: SelectBox) => { -// const syncInstance = () => { -// const modelsListRef = voidSettingsService.state._modelOptions // as a ref -// const settingsAtProvider = voidSettingsService.state.modelSelectionOfFeature[featureName] -// const selectionIdx = settingsAtProvider === null ? -1 : modelsListRef.findIndex(v => modelSelectionsEqual(v.value, settingsAtProvider)) -// weChangedText = true -// instance.select(selectionIdx === -1 ? 0 : selectionIdx) -// weChangedText = false -// } -// syncInstance() -// const disposable = voidSettingsService.onDidChangeState(syncInstance) -// return [disposable] -// }, [voidSettingsService, featureName])} -// /> -// } - const MemoizedModelDropdown = ({ featureName, className }: { featureName: FeatureName, className: string }) => { 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..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 @@ -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) { @@ -549,7 +549,12 @@ export const ollamaSetupInstructions =
-
+
+ +
@@ -617,7 +622,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.*
@@ -707,7 +712,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`} 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 = () => { <>