Merge remote-tracking branch 'origin/model-selection' into github-workflow

This commit is contained in:
Andrew Pareles 2025-03-24 19:49:22 -07:00
commit e566db8396
13 changed files with 525 additions and 79 deletions

412
.github/workflows/b2.yml vendored Normal file
View file

@ -0,0 +1,412 @@
name: VS Code Build
on:
push:
branches: [ main, release/*, github-workflow ]
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
build_macos:
description: 'Build macOS'
type: boolean
default: true
build_macos_arm64:
description: 'Build macOS ARM64'
type: boolean
default: true
build_macos_universal:
description: 'Build macOS Universal'
type: boolean
default: true
build_linux:
description: 'Build Linux x64'
type: boolean
default: true
build_linux_arm64:
description: 'Build Linux ARM64'
type: boolean
default: false
build_windows:
description: 'Build Windows'
type: boolean
default: true
quality:
description: 'Quality (insider or stable)'
type: choice
options:
- insider
- stable
default: 'insider'
env:
VSCODE_QUALITY: ${{ github.event.inputs.quality }}
NPM_REGISTRY: 'https://registry.npmjs.org/'
VSCODE_ARCH: 'x64'
VSCODE_CIBUILD: false
jobs:
compile:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Install Dependencies
run: |
npm ci
- name: Compile
run: |
npm run compile
- name: Package Compilation Output
run: |
mkdir -p .build
tar -czf compilation.tar.gz .build out-* test/integration/browser/out test/smoke/out test/automation/out
- name: Upload Compilation Artifact
uses: actions/upload-artifact@v4
with:
name: compilation
path: compilation.tar.gz
compile-cli:
runs-on: ubuntu-latest
needs: compile
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install Dependencies
run: |
npm ci
- name: Build CLI
run: |
cd cli
cargo build --release --bin=code
- name: Upload CLI Artifacts
uses: actions/upload-artifact@v4
with:
name: vscode_cli
path: cli/target/release/code
build-macos:
if: ${{ github.event.inputs.build_macos == 'true' }}
runs-on: macos-latest
needs: [compile, compile-cli]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Download Compilation
uses: actions/download-artifact@v4
with:
name: compilation
- name: Extract Compilation
run: tar -xzf compilation.tar.gz
- name: Install Dependencies
run: npm ci
- name: Build macOS x64
run: |
npm run gulp vscode-darwin-x64-min-ci
- name: Download CLI
uses: actions/download-artifact@v4
with:
name: vscode_cli
path: cli-bin
- name: Integrate CLI
run: |
APP_ROOT="$(pwd)/../VSCode-darwin-x64"
APP_NAME="`ls $APP_ROOT | head -n 1`"
APP_PATH="$APP_ROOT/$APP_NAME"
CLI_APP_NAME=$(node -p "require(\"$APP_PATH/Contents/Resources/app/product.json\").tunnelApplicationName")
mkdir -p "$APP_PATH/Contents/Resources/app/bin"
cp cli-bin/code "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME"
chmod +x "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME"
- name: Package macOS App
run: |
ARCHIVE_PATH="VSCode-darwin-x64.zip"
(cd ../VSCode-darwin-x64 && zip -r -X -y $(pwd)/$ARCHIVE_PATH *)
- name: Upload macOS App
uses: actions/upload-artifact@v4
with:
name: vscode-darwin-x64
path: VSCode-darwin-x64.zip
build-macos-arm64:
if: ${{ github.event.inputs.build_macos_arm64 == 'true' }}
runs-on: macos-latest
needs: [compile, compile-cli]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Download Compilation
uses: actions/download-artifact@v4
with:
name: compilation
- name: Extract Compilation
run: tar -xzf compilation.tar.gz
- name: Install Dependencies
run: npm ci
- name: Build macOS ARM64
run: |
npm run gulp vscode-darwin-arm64-min-ci
- name: Download CLI
uses: actions/download-artifact@v4
with:
name: vscode_cli
path: cli-bin
- name: Integrate CLI
run: |
APP_ROOT="$(pwd)/../VSCode-darwin-arm64"
APP_NAME="`ls $APP_ROOT | head -n 1`"
APP_PATH="$APP_ROOT/$APP_NAME"
CLI_APP_NAME=$(node -p "require(\"$APP_PATH/Contents/Resources/app/product.json\").tunnelApplicationName")
mkdir -p "$APP_PATH/Contents/Resources/app/bin"
cp cli-bin/code "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME"
chmod +x "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME"
- name: Package macOS App
run: |
ARCHIVE_PATH="VSCode-darwin-arm64.zip"
(cd ../VSCode-darwin-arm64 && zip -r -X -y $(pwd)/$ARCHIVE_PATH *)
- name: Upload macOS App
uses: actions/upload-artifact@v4
with:
name: vscode-darwin-arm64
path: VSCode-darwin-arm64.zip
build-macos-universal:
if: ${{ github.event.inputs.build_macos_universal == 'true' && github.event.inputs.build_macos == 'true' && github.event.inputs.build_macos_arm64 == 'true' }}
runs-on: macos-latest
needs: [build-macos, build-macos-arm64]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Download x64 Build
uses: actions/download-artifact@v4
with:
name: vscode-darwin-x64
- name: Download ARM64 Build
uses: actions/download-artifact@v4
with:
name: vscode-darwin-arm64
- name: Extract Builds
run: |
mkdir -p VSCode-darwin-x64
mkdir -p VSCode-darwin-arm64
unzip VSCode-darwin-x64.zip -d VSCode-darwin-x64
unzip VSCode-darwin-arm64.zip -d VSCode-darwin-arm64
- name: Install Dependencies
run: npm ci
- name: Create Universal Build
run: |
node build/darwin/create-universal-app.js $(pwd)
- name: Package Universal App
run: |
ARCHIVE_PATH="VSCode-darwin-universal.zip"
(cd VSCode-darwin-universal && zip -r -X -y $(pwd)/$ARCHIVE_PATH *)
- name: Upload Universal App
uses: actions/upload-artifact@v4
with:
name: vscode-darwin-universal
path: VSCode-darwin-universal.zip
build-linux:
if: ${{ github.event.inputs.build_linux == 'true' }}
runs-on: ubuntu-latest
needs: [compile, compile-cli]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0 libgbm1
npm ci
- name: Download Compilation
uses: actions/download-artifact@v4
with:
name: compilation
- name: Extract Compilation
run: tar -xzf compilation.tar.gz
- name: Build Linux x64
run: |
npm run gulp vscode-linux-x64-min-ci
- name: Download CLI
uses: actions/download-artifact@v4
with:
name: vscode_cli
path: cli-bin
- name: Integrate CLI
run: |
CLI_APP_NAME=$(node -p "require(\"../VSCode-linux-x64/resources/app/product.json\").tunnelApplicationName")
mkdir -p "../VSCode-linux-x64/bin"
cp cli-bin/code "../VSCode-linux-x64/bin/$CLI_APP_NAME"
chmod +x "../VSCode-linux-x64/bin/$CLI_APP_NAME"
- name: Create .tar.gz Archive
run: |
ARCHIVE_PATH="VSCode-linux-x64.tar.gz"
(cd .. && tar -czf $(pwd)/$ARCHIVE_PATH VSCode-linux-x64)
- name: Upload Linux Build
uses: actions/upload-artifact@v4
with:
name: vscode-linux-x64-archive
path: VSCode-linux-x64.tar.gz
- name: Build .deb Package
run: |
npm run gulp vscode-linux-x64-prepare-deb
npm run gulp vscode-linux-x64-build-deb
- name: Upload .deb Package
uses: actions/upload-artifact@v4
with:
name: vscode-linux-x64-deb
path: .build/linux/deb/*/deb/*.deb
- name: Build .rpm Package
run: |
npm run gulp vscode-linux-x64-prepare-rpm
npm run gulp vscode-linux-x64-build-rpm
- name: Upload .rpm Package
uses: actions/upload-artifact@v4
with:
name: vscode-linux-x64-rpm
path: .build/linux/rpm/*/*.rpm
build-windows:
if: ${{ github.event.inputs.build_windows == 'true' }}
runs-on: windows-latest
needs: [compile, compile-cli]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Download Compilation
uses: actions/download-artifact@v4
with:
name: compilation
- name: Extract Compilation
shell: powershell
run: tar -xzf compilation.tar.gz
- name: Install Dependencies
run: npm ci
- name: Build Windows x64
run: |
npm run gulp vscode-win32-x64-min-ci
npm run gulp vscode-win32-x64-inno-updater
- name: Download CLI
uses: actions/download-artifact@v4
with:
name: vscode_cli
path: cli-bin
- name: Integrate CLI
shell: powershell
run: |
$AppProductJson = Get-Content -Raw -Path "../VSCode-win32-x64/resources/app/product.json" | ConvertFrom-Json
$CliAppName = $AppProductJson.tunnelApplicationName
$AppName = $AppProductJson.applicationName
mkdir -Force "../VSCode-win32-x64/bin"
Copy-Item -Path "cli-bin/code" -Destination "../VSCode-win32-x64/bin/$CliAppName.exe"
- name: Package Windows Build
shell: powershell
run: |
$ArchivePath = "VSCode-win32-x64.zip"
Compress-Archive -Path "../VSCode-win32-x64/*" -DestinationPath $ArchivePath
- name: Upload Windows Build
uses: actions/upload-artifact@v4
with:
name: vscode-win32-x64-archive
path: VSCode-win32-x64.zip
- name: Build User Setup
run: |
npm run gulp vscode-win32-x64-user-setup
- name: Upload User Setup
uses: actions/upload-artifact@v4
with:
name: vscode-win32-x64-user-setup
path: .build/win32-x64/user-setup/VSCodeSetup.exe

View file

@ -447,9 +447,23 @@ jobs:
- name: Install dependencies for universal app
run: |
cd build/
# Set npm config to use GitHub token for authentication to avoid rate limits
npm config set //github.com/:_authToken=${{ github.token }}
npm config set //api.github.com/:_authToken=${{ github.token }}
npm config set //npm.pkg.github.com/:_authToken=${{ github.token }}
# Configure npm to use the GitHub token for all requests to github.com domains
npm config set @microsoft:registry https://npm.pkg.github.com
npm config set @vscode:registry https://npm.pkg.github.com
# Increase network timeout to handle slow connections
npm config set fetch-timeout 300000
npm config set fetch-retry-mintimeout 20000
npm config set fetch-retry-maxtimeout 120000
npm install
npm install -g create-dmg
npm run compile
- name: Create Universal App
run: |
# Script to create universal binary
@ -464,9 +478,6 @@ jobs:
with:
node-version-file: '.nvmrc'
- name: Install create-dmg
run: npm install -g create-dmg
- name: Create Universal DMG
run: |
cd .build/darwin-universal/universal

View file

@ -34,7 +34,7 @@
// // const result = await new Promise((res, rej) => {
// // sendLLMMessage({
// // messages,
// // tools: ['text_search'],
// // tools: ['grep_search'],
// // onFinalMessage: ({ result: r, }) => {
// // res(r)
// // },
@ -73,7 +73,7 @@
// // const result = new Promise((res, rej) => {
// // sendLLMMessage({
// // messages,
// // tools: ['text_search'],
// // tools: ['grep_search'],
// // onResult: (r) => {
// // res(r)
// // }

View file

@ -392,7 +392,7 @@ class ChatThreadService extends Disposable implements IChatThreadService {
{
role: 'tool',
name: 'text_search',
name: 'grep_search',
id: 'tool-4',
paramsStr: '{"query": "function main"}',
content: 'Found matches in 3 files',
@ -408,15 +408,15 @@ class ChatThreadService extends Disposable implements IChatThreadService {
hasNextPage: false
}
},
} satisfies ToolMessage<'text_search'>,
} satisfies ToolMessage<'grep_search'>,
// {
// role: 'tool_request',
// name: 'text_search',
// name: 'grep_search',
// params: { queryStr: 'function main', pageNumber: 0 },
// paramsStr: '{"query": "function main"}',
// id: 'request-4',
// } satisfies ToolRequestApproval<'text_search'>,
// } satisfies ToolRequestApproval<'grep_search'>,
// ---

View file

@ -1628,7 +1628,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
this._notifyError(e)
onDone()
this._undoHistory(uri)
throw e.fullError // throw error h
throw e.fullError || new Error(e.message) // throw error h
}
// refresh now in case onText takes a while to get 1st message

View file

@ -267,7 +267,7 @@ export const useApplyButtonHTML = ({ codeStr, applyBoxId, uri }: { codeStr: stri
</>
}
const statusIndicatorHTML = <div className='flex flex-row items-center size-4'>
const statusIndicatorHTML = <div className='flex flex-row items-center min-h-4 max-h-4 min-w-4 max-w-4'>
<div
className={` size-1.5 rounded-full border
${currStreamState === 'idle-no-changes' ? 'bg-void-bg-3 border-void-border-1' :

View file

@ -740,7 +740,7 @@ const ToolHeaderWrapper = ({
</span>}
{numResults !== undefined && (
<span className="text-void-fg-4 text-xs ml-auto mr-1">
{`(${numResults}${hasNextPage ? '+' : ''} result${numResults !== 1 ? 's' : ''})`}
{`${numResults}${hasNextPage ? '+' : ''} result${numResults !== 1 ? 's' : ''}`}
</span>
)}
{isError && <AlertTriangle className='text-void-warning opacity-90 flex-shrink-0' size={14} />}
@ -750,8 +750,8 @@ const ToolHeaderWrapper = ({
</div>
{/* children */}
{<div
className={`overflow-hidden transition-all duration-200 ease-in-out ${isExpanded ? 'opacity-100' : 'max-h-0 opacity-0'}
text-void-fg-4 rounded-sm
className={`overflow-hidden transition-all duration-200 ease-in-out ${isExpanded ? 'opacity-100 py-1' : 'max-h-0 opacity-0'}
text-void-fg-4 rounded-sm overflow-x-auto
`}
// bg-black bg-opacity-10 border border-void-border-4 border-opacity-50
>
@ -1018,6 +1018,9 @@ const SmallProseWrapper = ({ children }: { children: React.ReactNode }) => {
leading-snug
text-[13px]
[&>:first-child]:!mt-0
[&>:last-child]:!mb-0
prose-h1:text-[14px]
prose-h1:my-4
@ -1154,7 +1157,7 @@ const ReasoningWrapper = ({ isDoneReasoning, isStreaming, children }: { isDoneRe
if (!isWriting) setIsOpen(false) // if just finished reasoning, close
}, [isWriting])
return <ToolHeaderWrapper title='Reasoning' desc1={isWriting ? <IconLoading /> : ''} isOpen={isOpen} onClick={() => setIsOpen(v => !v)}>
<ToolChildrenWrapper className='bg-void-bg-3'>
<ToolChildrenWrapper>
<div className='!select-text cursor-auto'>
{children}
</div>
@ -1178,7 +1181,7 @@ const titleOfToolName = {
'read_file': { done: 'Read file', proposed: 'Read file', running: loadingTitleWrapper('Reading file') },
'list_dir': { done: 'Inspected folder', proposed: 'Inspect folder', running: loadingTitleWrapper('Inspecting folder') },
'pathname_search': { done: 'Searched by file name', proposed: 'Search by file name', running: loadingTitleWrapper('Searching by file name') },
'text_search': { done: 'Searched', proposed: 'Search text', running: loadingTitleWrapper('Searching') },
'grep_search': { done: 'Searched', proposed: 'Search', running: loadingTitleWrapper('Searching') },
'create_uri': {
done: (isFolder: boolean) => `Created ${folderFileStr(isFolder)}`,
proposed: (isFolder: boolean | null) => isFolder === null ? 'Create URI' : `Create ${folderFileStr(isFolder)}`,
@ -1210,8 +1213,8 @@ const toolNameToDesc = (toolName: ToolName, _toolParams: ToolCallParams[ToolName
} else if (toolName === 'pathname_search') {
const toolParams = _toolParams as ToolCallParams['pathname_search']
return `"${toolParams.queryStr}"`;
} else if (toolName === 'text_search') {
const toolParams = _toolParams as ToolCallParams['text_search']
} else if (toolName === 'grep_search') {
const toolParams = _toolParams as ToolCallParams['grep_search']
return `"${toolParams.queryStr}"`;
} else if (toolName === 'create_uri') {
const toolParams = _toolParams as ToolCallParams['create_uri']
@ -1310,7 +1313,7 @@ const ToolRequestAcceptRejectButtons = () => {
}
export const ToolChildrenWrapper = ({ children, className }: { children: React.ReactNode, className?: string }) => {
return <div className={`${className ? className : ''} overflow-x-auto cursor-default select-none`}>
return <div className={`${className ? className : ''} cursor-default select-none`}>
<div className='px-2 min-w-full'>
{children}
</div>
@ -1490,7 +1493,7 @@ const toolNameToComponent: { [T in ToolName]: ToolComponent<T> } = {
return <ToolHeaderWrapper {...componentParams} />
}
},
'text_search': {
'grep_search': {
requestWrapper: null,
resultWrapper: ({ toolMessage }) => {
const accessor = useAccessor()
@ -1763,17 +1766,19 @@ const toolNameToComponent: { [T in ToolName]: ToolComponent<T> } = {
resolveReason.type === 'toofull' ? `\n(truncated)`
: null
componentParams.children = <ToolChildrenWrapper className='bg-void-bg-3 font-mono whitespace-pre text-nowrap overflow-auto text-sm'>
<ListableToolItem
showDot={false}
name={`$ ${command}`}
className='w-full overflow-auto py-1'
onClick={() => terminalToolsService.openTerminal(terminalId)}
/>
componentParams.children = <ToolChildrenWrapper className='font-mono whitespace-pre text-nowrap overflow-auto text-sm'>
<div className='!select-text cursor-auto'>
{resolveReason.type === 'bgtask' ? 'Result so far:\n' : null}
{result}
{resultStr}
<div>
<span>{`Ran command: `}</span>
<span className="text-void-fg-1">{command}</span>
</div>
<div>
<span>{resolveReason.type === 'bgtask' ? 'Result so far:\n' : null}</span>
<span>{`Result: `}</span>
<span className="text-void-fg-1">{result}</span>
<span className="text-void-fg-1">{resultStr}</span>
</div>
</div>
</ToolChildrenWrapper>

View file

@ -152,6 +152,37 @@ export const VoidInputBox2 = forwardRef<HTMLTextAreaElement, InputBox2Props>(fun
})
export const VoidSimpleInputBox = ({ value, onChangeValue, placeholder, className, disabled, passwordBlur, ...inputProps }: {
value: string;
onChangeValue: (value: string) => void;
placeholder: string;
className?: string;
disabled?: boolean;
passwordBlur?: boolean;
} & React.InputHTMLAttributes<HTMLInputElement>) => {
return (
<input
value={value}
onChange={(e) => onChangeValue(e.target.value)}
placeholder={placeholder}
disabled={disabled}
className={`w-full resize-none text-void-fg-1 placeholder:text-void-fg-3 px-2 py-1 rounded-sm
${disabled ? 'opacity-50 cursor-not-allowed' : ''}
${className}`}
style={{
...passwordBlur && { WebkitTextSecurity: 'disc' },
background: asCssVariable(inputBackground),
color: asCssVariable(inputForeground)
}}
{...inputProps}
type={undefined} // VS Code is doing some annoyingness that breaks paste if this is defined
/>
);
};
export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, placeholder, isPasswordField, multiline }: {
onChangeText: (value: string) => void;
styles?: Partial<IInputBoxStyles>,
@ -319,7 +350,7 @@ export const VoidSlider = ({
size === 'xs' ? 'h-1' :
size === 'sm' ? 'h-1.5' :
size === 'sm+' ? 'h-2' : 'h-2.5'
} bg-gray-200 dark:bg-gray-700 rounded-full cursor-pointer`}
} bg-void-bg-2 rounded-full cursor-pointer`}
onClick={handleTrackClick}
>
{/* Filled part of track */}
@ -328,12 +359,12 @@ export const VoidSlider = ({
size === 'xs' ? 'h-1' :
size === 'sm' ? 'h-1.5' :
size === 'sm+' ? 'h-2' : 'h-2.5'
} bg-gray-900 dark:bg-white rounded-full`}
} bg-void-fg-1 rounded-full`}
style={{ width: `${percentage}%` }}
/>
</div>
{/* Thumb with sizes matching VoidSwitch */}
{/* Thumb */}
<div
className={`absolute top-1/2 transform -translate-x-1/2 -translate-y-1/2
${size === 'xxs' ? 'h-2 w-2' :
@ -341,7 +372,8 @@ export const VoidSlider = ({
size === 'sm' ? 'h-3 w-3' :
size === 'sm+' ? 'h-3.5 w-3.5' : 'h-4 w-4'
}
bg-white dark:bg-gray-900 rounded-full shadow-md ${disabled ? 'cursor-not-allowed' : 'cursor-grab active:cursor-grabbing'}`}
bg-void-fg-1 rounded-full shadow-md ${disabled ? 'cursor-not-allowed' : 'cursor-grab active:cursor-grabbing'}
border border-void-fg-1`}
style={{ left: `${percentage}%`, zIndex: 2 }} // Ensure thumb is above the invisible clickable area
onMouseDown={(e) => {
if (disabled) return;
@ -393,7 +425,7 @@ export const VoidSwitch = ({
className={`
cursor-pointer
relative inline-flex items-center rounded-full transition-colors duration-200 ease-in-out
${value ? 'bg-gray-900 dark:bg-white' : 'bg-gray-200 dark:bg-gray-700'}
${value ? 'bg-zinc-900 dark:bg-white' : 'bg-white dark:bg-zinc-600'}
${disabled ? 'opacity-25' : ''}
${size === 'xxs' ? 'h-3 w-5' : ''}
${size === 'xs' ? 'h-4 w-7' : ''}
@ -404,7 +436,7 @@ export const VoidSwitch = ({
>
<span
className={`
inline-block transform rounded-full bg-white dark:bg-gray-900 shadow transition-transform duration-200 ease-in-out
inline-block transform rounded-full bg-white dark:bg-zinc-900 shadow transition-transform duration-200 ease-in-out
${size === 'xxs' ? 'h-2 w-2' : ''}
${size === 'xs' ? 'h-2.5 w-2.5' : ''}
${size === 'sm' ? 'h-3 w-3' : ''}
@ -924,7 +956,7 @@ export const BlockCode = ({ initValue, language, maxHeight, showScrollbars }: Bl
export const VoidButton = ({ children, disabled, onClick }: { children: React.ReactNode; disabled?: boolean; onClick: () => void }) => {
return <button disabled={disabled}
className='px-3 py-1 bg-black/10 dark:bg-gray-200/10 rounded-sm overflow-hidden whitespace-nowrap'
className='px-3 py-1 bg-black/10 dark:bg-white/10 rounded-sm overflow-hidden whitespace-nowrap'
onClick={onClick}
>{children}</button>
}

View file

@ -97,7 +97,7 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
if (diffid === undefined) return
const diff = editCodeService.diffOfId[diffid]
if (!diff) return
editor.revealLineNearTop(diff.startLine, ScrollType.Immediate)
editor.revealLineNearTop(diff.startLine - 1, ScrollType.Immediate)
commandBarService.setDiffIdx(uri, idx)
}
const getNextUriIdx = (step: 1 | -1) => {

View file

@ -7,7 +7,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'
import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, globalSettingNames, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, defaultProviderSettings, nonlocalProviderNames, localProviderNames, GlobalSettingName, featureNames, displayInfoOfFeatureName, isProviderNameDisabled, FeatureName } from '../../../../common/voidSettingsTypes.js'
import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js'
import { VoidButton, VoidCheckBox, VoidCustomDropdownBox, VoidInputBox, VoidInputBox2, VoidSwitch } from '../util/inputs.js'
import { VoidButton, VoidCheckBox, VoidCustomDropdownBox, VoidInputBox, VoidInputBox2, VoidSimpleInputBox, VoidSwitch } from '../util/inputs.js'
import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js'
import { X, RefreshCw, Loader2, Check, MoveRight } from 'lucide-react'
import { useScrollbarStyles } from '../util/useScrollbarStyles.js'
@ -255,45 +255,29 @@ export const ModelDump = () => {
const ProviderSetting = ({ providerName, settingName }: { providerName: ProviderName, settingName: SettingName }) => {
// const { title: providerTitle, } = displayInfoOfProviderName(providerName)
const { title: settingTitle, placeholder, isPasswordField, subTextMd } = displayInfoOfSettingName(providerName, settingName)
const accessor = useAccessor()
const voidSettingsService = accessor.get('IVoidSettingsService')
const settingsState = useSettingsState()
let weChangedTextRef = false
const settingValue = settingsState.settingsOfProvider[providerName][settingName] as string // this should always be a string in this component
console.log(`providerName:${providerName} settingName: ${settingName}, settingValue: ${settingValue}`)
if (typeof settingValue !== 'string') {
console.log('Error: Provider setting had a non-string value.')
return
}
return <ErrorBoundary>
<div className='my-1'>
<VoidInputBox
// placeholder={`${providerTitle} ${settingTitle} (${placeholder})`}
placeholder={`${settingTitle} (${placeholder})`}
onChangeText={useCallback((newVal) => {
if (weChangedTextRef) return
<VoidSimpleInputBox
value={settingValue}
onChangeValue={useCallback((newVal) => {
voidSettingsService.setSettingOfProvider(providerName, settingName, newVal)
}, [voidSettingsService, providerName, settingName])}
// we are responsible for setting the initial value. always sync the instance whenever there's a change to state.
onCreateInstance={useCallback((instance: InputBox) => {
const syncInstance = () => {
const settingsAtProvider = voidSettingsService.state.settingsOfProvider[providerName];
const stateVal = settingsAtProvider[settingName as SettingName]
// console.log('SYNCING TO', providerName, settingName, stateVal)
weChangedTextRef = true
instance.value = stateVal as string
weChangedTextRef = false
}
syncInstance()
const disposable = voidSettingsService.onDidChangeState(syncInstance)
return [disposable]
}, [voidSettingsService, providerName, settingName])}
multiline={false}
isPasswordField={isPasswordField}
// placeholder={`${providerTitle} ${settingTitle} (${placeholder})`}
placeholder={`${settingTitle} (${placeholder})`}
passwordBlur={isPasswordField}
/>
{subTextMd === undefined ? null : <div className='py-1 px-3 opacity-50 text-sm'>
<ChatMarkdownRender string={subTextMd} chatMessageLocation={undefined} />

View file

@ -227,7 +227,7 @@ export class ToolsService implements IToolsService {
return { queryStr, pageNumber }
},
text_search: async (params: string) => {
grep_search: async (params: string) => {
const o = validateJSON(params)
const { query: queryUnknown, pageNumber: pageNumberUnknown } = o
@ -314,7 +314,7 @@ export class ToolsService implements IToolsService {
return { result: { uris, hasNextPage } }
},
text_search: async ({ queryStr, pageNumber }) => {
grep_search: async ({ queryStr, pageNumber }) => {
const query = queryBuilder.text({
pattern: queryStr,
isRegExp: true,
@ -388,7 +388,7 @@ export class ToolsService implements IToolsService {
pathname_search: (params, result) => {
return result.uris.map(uri => uri.fsPath).join('\n') + nextPageStr(result.hasNextPage)
},
text_search: (params, result) => {
grep_search: (params, result) => {
return result.uris.map(uri => uri.fsPath).join('\n') + nextPageStr(result.hasNextPage)
},
// ---

View file

@ -69,16 +69,16 @@ export const voidTools = {
pathname_search: {
name: 'pathname_search',
description: `Returns all pathnames that match a given grep query. You should use this when looking for a file with a specific name or path. This does NOT search file content. ${paginationHelper.desc}`,
description: `Returns all pathnames that match a given \`find\`-style query (searches ONLY file names). You should use this when looking for a file with a specific name or path. ${paginationHelper.desc}`,
params: {
query: { type: 'string', description: undefined },
...paginationHelper.param,
},
},
text_search: {
name: 'text_search',
description: `Returns pathnames of files with an exact match of the query. The query can be any regex. This does NOT search pathname. As a follow-up, you may want to use read_file to view the full file contents of the results. ${paginationHelper.desc}`,
grep_search: {
name: 'grep_search',
description: `Returns all pathnames that match a given \`grep\`-style query (searches ONLY file contents). The query can be any regex. This is often followed by the \`read_file\` tool to view the full file contents of results. ${paginationHelper.desc}`,
params: {
query: { type: 'string', description: undefined },
...paginationHelper.param,
@ -146,7 +146,7 @@ Here's an example of a good description:\n${editToolDescription}.`
export const chat_systemMessage = (workspaces: string[], runningTerminalIds: string[], mode: ChatMode) => `\
You are an expert coding ${mode === 'agent' ? 'agent' : 'assistant'} that runs in the Void code editor. Your job is \
${mode === 'agent' ? `to help the user develop, run, deploy, and make changes to their codebase. You should ALWAYS bring user's task to completion to the fullest extent possible, calling tools to make all necessary changes. Do not be lazy.`
${mode === 'agent' ? `to help the user develop, run, deploy, and make changes to their codebase. You should ALWAYS bring user's task to completion to the fullest extent possible, calling tools to make all necessary changes.`
: mode === 'gather' ? `to search and understand the user's codebase. You MUST use tools to read files and help the user understand the codebase, even if you were initially given files.`
: mode === 'normal' ? `to assist the user with their coding tasks.`
: ''}
@ -163,7 +163,9 @@ ${/* tool use */ mode === 'agent' || mode === 'gather' ? `\
You will be given tools you can call.
${mode === 'agent' ? `\
- Only use tools if they help you accomplish the user's goal. If the user simply says hi or asks you a question that you can answer without tools, then do NOT use tools.
- ALWAYS use tools to take actions. For example, if you would like to edit a file, you MUST use a tool.`
- ALWAYS use tools to take actions. For example, if you would like to edit a file, you MUST use a tool.
- You will OFTEN need to gather context before making a change. Do not immediately make a change unless you have ALL relevant context.
- ALWAYS have maximal certainty in a change BEFORE you make it. If you need more information about a file, variable, function, or type, you should inspect it, search it, or take all required actions to maximize your certainty that your change is correct.`
: mode === 'gather' ? `\
- Your primary use of tools should be to gather information to help the user understand the codebase and answer their query.
- You should extensively read files, types, etc and gather relevant context.`

View file

@ -44,7 +44,7 @@ export type ToolCallParams = {
'read_file': { uri: URI, pageNumber: number },
'list_dir': { rootURI: URI, pageNumber: number },
'pathname_search': { queryStr: string, pageNumber: number },
'text_search': { queryStr: string, pageNumber: number },
'grep_search': { queryStr: string, pageNumber: number },
// ---
'edit': { uri: URI, changeDescription: string },
'create_uri': { uri: URI, isFolder: boolean },
@ -57,7 +57,7 @@ export type ToolResultType = {
'read_file': { fileContents: string, hasNextPage: boolean },
'list_dir': { children: ToolDirectoryItem[] | null, hasNextPage: boolean, hasPrevPage: boolean, itemsRemaining: number },
'pathname_search': { uris: URI[], hasNextPage: boolean },
'text_search': { uris: URI[], hasNextPage: boolean },
'grep_search': { uris: URI[], hasNextPage: boolean },
// ---
'edit': Promise<void>,
'create_uri': {},