add better settings

This commit is contained in:
Andrew Pareles 2025-03-14 02:23:58 -07:00
parent 8f3a752562
commit dbdd40bd3d
11 changed files with 101 additions and 52 deletions

View file

@ -1224,13 +1224,16 @@ class EditCodeService extends Disposable implements IEditCodeService {
public async startApplying(opts: StartApplyingOpts): Promise<[URI, Promise<void>] | null> {
let res: [DiffZone, Promise<void>] | undefined = undefined
if (Math.random() > 0) {
console.log('writeover....')
res = await this._initializeWriteoverStream(opts)
} else {
if (opts.type === 'rewrite') res = await this._initializeWriteoverStream(opts)
else if (opts.type === 'searchReplace') res = await this._initializeSearchAndReplaceStream(opts)
if (opts.from === 'QuickEdit') {
res = await this._initializeWriteoverStream(opts) // rewrite
}
else if (opts.from === 'ClickApply') {
if (this._settingsService.state.globalSettings.enableFastApply) {
res = await this._initializeSearchAndReplaceStream(opts) // fast apply
}
else {
res = await this._initializeWriteoverStream(opts) // rewrite
}
}
if (!res) return null

View file

@ -13,11 +13,9 @@ import { createDecorator } from '../../../../platform/instantiation/common/insta
export type StartApplyingOpts = ({
from: 'QuickEdit';
type: 'rewrite';
diffareaid: number; // id of the CtrlK area (contains text selection)
} | {
from: 'ClickApply';
type: 'searchReplace' | 'rewrite';
applyStr: string;
uri: 'current' | URI;
startBehavior: 'accept-conflicts' | 'reject-conflicts';

View file

@ -123,7 +123,6 @@ export const useApplyButtonHTML = ({ codeStr, applyBoxId }: { codeStr: string, a
if (getStreamState() === 'streaming') return
const [newApplyingUri, _] = await editCodeService.startApplying({
from: 'ClickApply',
type: 'searchReplace',
applyStr: codeStr,
uri: 'current',
startBehavior: 'reject-conflicts',

View file

@ -62,7 +62,6 @@ export const QuickEditChat = ({
editCodeService.startApplying({
from: 'QuickEdit',
type: 'rewrite',
diffareaid,
})
}, [isStreamingRef, isDisabled, editCodeService, diffareaid])

View file

@ -363,7 +363,7 @@ export const VoidChatArea: React.FC<VoidChatAreaProps> = ({
{showModelDropdown && (
<div className='max-w-[200px] flex-grow'>
<ReasoningOptionDropdown featureName={featureName} />
<ModelDropdown featureName={featureName} />
<ModelDropdown featureName={featureName} className='text-xs text-void-fg-3' />
</div>
)}

View file

@ -460,7 +460,7 @@ export const VoidCheckBox = ({ label, value, onClick, className }: { label: stri
export const VoidCustomDropdownBox = <T extends any>({
export const VoidCustomDropdownBox = <T extends NonNullable<any>>({
options,
selectedOption,
onChangeOption,
@ -537,7 +537,7 @@ export const VoidCustomDropdownBox = <T extends any>({
// if the selected option is null, set the selection to the 0th option
useEffect(() => {
if (options.length === 0) return
if (selectedOption) return
if (selectedOption !== undefined) return
onChangeOption(options[0])
}, [selectedOption, onChangeOption, options])
@ -566,7 +566,7 @@ export const VoidCustomDropdownBox = <T extends any>({
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [isOpen, refs.floating, refs.reference]);
if (!selectedOption)
if (selectedOption === undefined)
return null
return (

View file

@ -21,7 +21,7 @@ const optionsEqual = (m1: ModelOption[], m2: ModelOption[]) => {
return true
}
const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], featureName: FeatureName }) => {
const ModelSelectBox = ({ options, featureName, className }: { options: ModelOption[], featureName: FeatureName, className: string }) => {
const accessor = useAccessor()
const voidSettingsService = accessor.get('IVoidSettingsService')
@ -40,7 +40,7 @@ const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], feat
getOptionDropdownName={(option) => option.selection.modelName}
getOptionDropdownDetail={(option) => option.selection.providerName}
getOptionsEqual={(a, b) => optionsEqual([a], [b])}
className='text-xs text-void-fg-3'
className={className}
matchInputWidth={false}
/>
}
@ -77,7 +77,7 @@ const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], feat
const MemoizedModelDropdown = ({ featureName }: { featureName: FeatureName }) => {
const MemoizedModelDropdown = ({ featureName, className }: { featureName: FeatureName, className: string }) => {
const settingsState = useSettingsState()
const oldOptionsRef = useRef<ModelOption[]>([])
const [memoizedOptions, setMemoizedOptions] = useState(oldOptionsRef.current)
@ -98,11 +98,11 @@ const MemoizedModelDropdown = ({ featureName }: { featureName: FeatureName }) =>
return <WarningBox text={emptyMessage || 'No models available'} />
}
return <ModelSelectBox featureName={featureName} options={memoizedOptions} />
return <ModelSelectBox featureName={featureName} options={memoizedOptions} className={className} />
}
export const ModelDropdown = ({ featureName }: { featureName: FeatureName }) => {
export const ModelDropdown = ({ featureName, className }: { featureName: FeatureName, className: string }) => {
const settingsState = useSettingsState()
const accessor = useAccessor()
@ -123,5 +123,5 @@ export const ModelDropdown = ({ featureName }: { featureName: FeatureName }) =>
: 'Provider required'
} />
return <MemoizedModelDropdown featureName={featureName} />
return <MemoizedModelDropdown featureName={featureName} className={className} />
}

View file

@ -398,6 +398,30 @@ export const AIInstructionsBox = () => {
/>
}
const FastApplyMethodDropdown = () => {
const accessor = useAccessor()
const voidSettingsService = accessor.get('IVoidSettingsService')
const options = useMemo(() => [true, false], [])
const onChangeOption = useCallback((newVal: boolean) => {
voidSettingsService.setGlobalSetting('enableFastApply', newVal)
}, [voidSettingsService])
return <VoidCustomDropdownBox
className='text-xs text-void-fg-3 bg-void-bg-1 border border-void-border-1 rounded p-0.5 px-1'
options={options}
selectedOption={voidSettingsService.state.globalSettings.enableFastApply}
onChangeOption={onChangeOption}
getOptionDisplayName={(val) => val ? 'Fast Apply' : 'Slow Apply'}
getOptionDropdownName={(val) => val ? 'Fast Apply' : 'Slow Apply'}
getOptionDropdownDetail={(val) => val ? 'Output Search/Replace blocks' : 'Rewrite whole files'}
getOptionsEqual={(a, b) => a === b}
/>
}
export const FeaturesTab = () => {
const voidSettingsState = useSettingsState()
const accessor = useAccessor()
@ -445,42 +469,66 @@ export const FeaturesTab = () => {
<h2 className={`text-3xl mt-12`}>Feature Options</h2>
<ErrorBoundary>
<div className='flex items-start justify-around mt-4 mb-16 gap-x-8'>
{/* FIM */}
<div className='w-full'>
<h4 className={`text-base`}>{displayInfoOfFeatureName('Autocomplete')}</h4>
<div className='text-sm italic text-void-fg-3 my-1'>Experimental. Only works with models that support FIM.</div>
<div className='flex items-center gap-x-2 my-1'>
<VoidSwitch
size='xs'
value={voidSettingsState.globalSettings.enableAutocomplete}
onChange={(newVal) => voidSettingsService.setGlobalSetting('enableAutocomplete', newVal)}
/>
<span className='text-void-fg-3 text-xs pointer-events-none'>{voidSettingsState.globalSettings.enableAutocomplete ? 'Enabled' : 'Disabled'}</span>
<div className='text-sm italic text-void-fg-3 mt-1 mb-4'>Experimental. Only works with models that support FIM.</div>
<div className='my-2'>
{/* Enable Switch */}
<div className='flex items-center gap-x-2 my-2'>
<VoidSwitch
size='xs'
value={voidSettingsState.globalSettings.enableAutocomplete}
onChange={(newVal) => voidSettingsService.setGlobalSetting('enableAutocomplete', newVal)}
/>
<span className='text-void-fg-3 text-xs pointer-events-none'>{voidSettingsState.globalSettings.enableAutocomplete ? 'Enabled' : 'Disabled'}</span>
</div>
{/* Model Dropdown */}
<div className={`my-2 ${!voidSettingsState.globalSettings.enableAutocomplete ? 'hidden' : ''}`}>
<ModelDropdown featureName={'Autocomplete'} className='text-xs text-void-fg-3 bg-void-bg-1 border border-void-border-1 rounded p-0.5 px-1' />
</div>
</div>
<div className={`my-1 ${!voidSettingsState.globalSettings.enableAutocomplete ? 'hidden' : ''}`}>
<ModelDropdown featureName={'Autocomplete'} />
</div>
</div>
{/* Apply */}
<div className='w-full'>
<h4 className={`text-base`}>{displayInfoOfFeatureName('Apply')}</h4>
<div className='text-sm italic text-void-fg-3 my-1'>If you customize this, we recommend using Claude 3.7 or DeepSeek R1.</div>
<div className='flex items-center gap-x-2 my-1'>
<VoidSwitch
size='xs'
value={!voidSettingsState.globalSettings.syncFastApplyToChat}
onChange={(newVal) => voidSettingsService.setGlobalSetting('syncFastApplyToChat', !newVal)}
/>
<span className='text-void-fg-3 text-xs pointer-events-none'>{voidSettingsState.globalSettings.syncFastApplyToChat ? 'Sync with Chat' : 'Use Another Model'}</span>
<div className='text-sm italic text-void-fg-3 mt-1 mb-4'>Settings that control the behavior of the Apply button and the Edit tool.</div>
<div className='my-2'>
{/* Sync to Chat Switch */}
<div className='flex items-center gap-x-2 my-2'>
<VoidSwitch
size='xs'
value={voidSettingsState.globalSettings.syncApplyToChat}
onChange={(newVal) => voidSettingsService.setGlobalSetting('syncApplyToChat', newVal)}
/>
<span className='text-void-fg-3 text-xs pointer-events-none'>{voidSettingsState.globalSettings.syncApplyToChat ? 'Sync with Chat model' : 'Use another model'}</span>
</div>
{/* Model Dropdown */}
<div className={`my-2 ${voidSettingsState.globalSettings.syncApplyToChat ? 'hidden' : ''}`}>
<ModelDropdown featureName={'Apply'} className='text-xs text-void-fg-3 bg-void-bg-1 border border-void-border-1 rounded p-0.5 px-1' />
</div>
</div>
<div className={`my-1 ${voidSettingsState.globalSettings.syncFastApplyToChat ? 'hidden' : ''}`}>
<ModelDropdown featureName={'Apply'} />
<div className='my-2'>
{/* Fast Apply Method Dropdown */}
<div className='flex items-center gap-x-2 my-2'>
<FastApplyMethodDropdown />
</div>
</div>
</div>
</div>
</ErrorBoundary>
</>

View file

@ -330,7 +330,6 @@ export class ToolsService implements IToolsService {
uri,
applyStr: changeDescription,
from: 'ClickApply',
type: 'searchReplace',
startBehavior: 'accept-conflicts',
}) ?? []
await applyDonePromise

View file

@ -273,11 +273,10 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
}
private _onUpdate_syncFastApplyToChat() {
private _onUpdate_syncApplyToChat() {
// if sync is turned on, sync (call this whenever Chat model or !!sync changes)
if (this.state.globalSettings.syncFastApplyToChat) {
this.setModelSelectionOfFeature('Apply', deepClone(this.state.modelSelectionOfFeature['Chat']))
}
this.setModelSelectionOfFeature('Apply', deepClone(this.state.modelSelectionOfFeature['Chat']))
}
setGlobalSetting: SetGlobalSettingFn = async (settingName, newVal) => {
@ -293,7 +292,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
this._onDidChangeState.fire()
// hooks
this._onUpdate_syncFastApplyToChat()
if (this.state.globalSettings.syncApplyToChat) this._onUpdate_syncApplyToChat()
}
@ -312,7 +311,9 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
this._onDidChangeState.fire()
// hooks
if (featureName === 'Chat') { this._onUpdate_syncFastApplyToChat() }
if (featureName === 'Chat') {
if (this.state.globalSettings.syncApplyToChat) this._onUpdate_syncApplyToChat()
}
}

View file

@ -324,7 +324,7 @@ export const displayInfoOfFeatureName = (featureName: FeatureName) => {
else if (featureName === 'Chat')
return 'Chat'
else if (featureName === 'Apply')
return 'Fast Apply'
return 'Apply'
else
throw new Error(`Feature Name ${featureName} not allowed`)
}
@ -385,14 +385,16 @@ export type GlobalSettings = {
autoRefreshModels: boolean;
aiInstructions: string;
enableAutocomplete: boolean;
syncFastApplyToChat: boolean;
syncApplyToChat: boolean;
enableFastApply: boolean;
}
export const defaultGlobalSettings: GlobalSettings = {
autoRefreshModels: true,
aiInstructions: '',
enableAutocomplete: false,
syncFastApplyToChat: true,
syncApplyToChat: true,
enableFastApply: true,
}
export type GlobalSettingName = keyof GlobalSettings