mirror of
https://github.com/voideditor/void
synced 2026-05-23 09:28:23 +00:00
improvements
This commit is contained in:
parent
5c047b78f3
commit
4a43b628d4
6 changed files with 77 additions and 53 deletions
|
|
@ -5,7 +5,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 } from '../../../../common/voidSettingsTypes.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 { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js'
|
||||
|
|
@ -368,15 +368,15 @@ export const AutoRefreshToggle = () => {
|
|||
// right now this is just `enabled_autoRefreshModels`
|
||||
const enabled = voidSettingsState.globalSettings[settingName]
|
||||
|
||||
return <SubtleButton
|
||||
onClick={() => {
|
||||
voidSettingsService.setGlobalSetting(settingName, !enabled)
|
||||
metricsService.capture('Click', { action: 'Autorefresh Toggle', settingName, enabled: !enabled })
|
||||
}}
|
||||
text={`Automatically detect local providers and models (${refreshableProviderNames.map(providerName => displayInfoOfProviderName(providerName).title).join(', ')}).`}
|
||||
icon={enabled ? <Check className='stroke-green-500 size-3' /> : <X className='stroke-red-500 size-3' />}
|
||||
disabled={false}
|
||||
/>
|
||||
return <SubtleButton
|
||||
onClick={() => {
|
||||
voidSettingsService.setGlobalSetting(settingName, !enabled)
|
||||
metricsService.capture('Click', { action: 'Autorefresh Toggle', settingName, enabled: !enabled })
|
||||
}}
|
||||
text={`Automatically detect local providers and models (${refreshableProviderNames.map(providerName => displayInfoOfProviderName(providerName).title).join(', ')}).`}
|
||||
icon={enabled ? <Check className='stroke-green-500 size-3' /> : <X className='stroke-red-500 size-3' />}
|
||||
disabled={false}
|
||||
/>
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ export const FeaturesTab = () => {
|
|||
<ErrorBoundary>
|
||||
<AutoRefreshToggle />
|
||||
<RefreshableModels />
|
||||
<div className='py-2'/>
|
||||
<div className='py-2' />
|
||||
<ModelDump />
|
||||
<AddModelMenuFull />
|
||||
</ErrorBoundary>
|
||||
|
|
@ -437,12 +437,13 @@ export const FeaturesTab = () => {
|
|||
<h2 className={`text-3xl mb-2 mt-12`}>Feature Options</h2>
|
||||
<ErrorBoundary>
|
||||
{featureNames.map(featureName =>
|
||||
<div key={featureName}
|
||||
className='mb-2'
|
||||
>
|
||||
<h4 className={`text-void-fg-3`}>{displayInfoOfFeatureName(featureName)}</h4>
|
||||
<ModelDropdown featureName={featureName} />
|
||||
</div>
|
||||
(['Ctrl+L', 'Ctrl+K'] as FeatureName[]).includes(featureName) ? null :
|
||||
<div key={featureName}
|
||||
className='mb-2'
|
||||
>
|
||||
<h4 className={`text-void-fg-3`}>{displayInfoOfFeatureName(featureName)}</h4>
|
||||
<ModelDropdown featureName={featureName} />
|
||||
</div>
|
||||
)}
|
||||
</ErrorBoundary>
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export const voidTools = {
|
|||
query: { type: 'string', description: undefined },
|
||||
...paginationHelper.param,
|
||||
},
|
||||
required: ['query']
|
||||
required: ['query'],
|
||||
},
|
||||
|
||||
search: {
|
||||
|
|
@ -305,6 +305,8 @@ export class ToolsService implements IToolsService {
|
|||
return { queryStr, uris, hasNextPage }
|
||||
},
|
||||
search: async (s: string) => {
|
||||
|
||||
|
||||
console.log('search')
|
||||
|
||||
const o = validateJSON(s)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,30 @@ export interface IVoidSettingsService {
|
|||
|
||||
|
||||
|
||||
const _updatedValidatedState = (state: Omit<VoidSettingsState, '_modelOptions'>) => {
|
||||
|
||||
const _updatedModelsAfterDefaultModelsChange = (defaultModelNames: string[], options: { existingModels: VoidModelInfo[] }) => {
|
||||
const { existingModels } = options
|
||||
|
||||
const existingModelsMap: Record<string, VoidModelInfo> = {}
|
||||
for (const existingModel of existingModels) {
|
||||
existingModelsMap[existingModel.modelName] = existingModel
|
||||
}
|
||||
|
||||
const newDefaultModels = defaultModelNames.map((modelName, i) => ({
|
||||
modelName,
|
||||
isDefault: true,
|
||||
isAutodetected: true,
|
||||
isHidden: !!existingModelsMap[modelName]?.isHidden,
|
||||
}))
|
||||
|
||||
return [
|
||||
...newDefaultModels, // swap out all the default models for the new default models
|
||||
...existingModels.filter(m => !m.isDefault), // keep any non-default (custom) models
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
const _validatedState = (state: Omit<VoidSettingsState, '_modelOptions'>) => {
|
||||
|
||||
let newSettingsOfProvider = state.settingsOfProvider
|
||||
|
||||
|
|
@ -201,7 +224,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
|||
modelSelectionOfFeature: newModelSelectionOfFeature,
|
||||
}
|
||||
|
||||
this.state = _updatedValidatedState(readS)
|
||||
this.state = _validatedState(readS)
|
||||
|
||||
resolver()
|
||||
this._onDidChangeState.fire()
|
||||
|
|
@ -248,7 +271,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
|||
globalSettings: newGlobalSettings,
|
||||
}
|
||||
|
||||
this.state = _updatedValidatedState(newState)
|
||||
this.state = _validatedState(newState)
|
||||
|
||||
await this._storeState()
|
||||
this._onDidChangeState.fire()
|
||||
|
|
@ -290,27 +313,6 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
|||
}
|
||||
|
||||
|
||||
private _updatedModelsAfterAutodetection = (defaultModelNames: string[], options: { existingModels: VoidModelInfo[] }) => {
|
||||
const { existingModels } = options
|
||||
|
||||
const existingModelsMap: Record<string, VoidModelInfo> = {}
|
||||
for (const existingModel of existingModels) {
|
||||
existingModelsMap[existingModel.modelName] = existingModel
|
||||
}
|
||||
|
||||
const newDefaultModels = defaultModelNames.map((modelName, i) => ({
|
||||
modelName,
|
||||
isDefault: true,
|
||||
isAutodetected: true,
|
||||
isHidden: !!existingModelsMap[modelName]?.isHidden,
|
||||
}))
|
||||
|
||||
return [
|
||||
...newDefaultModels, // swap out all the default models for the new default models
|
||||
...existingModels.filter(m => !m.isDefault), // keep any non-default (custom) models
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
setAutodetectedModels(providerName: ProviderName, autodetectedModelNames: string[], logging: object) {
|
||||
|
|
@ -318,7 +320,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
|||
const { models } = this.state.settingsOfProvider[providerName]
|
||||
const oldModelNames = models.map(m => m.modelName)
|
||||
|
||||
const newModels = this._updatedModelsAfterAutodetection(autodetectedModelNames, { existingModels: models })
|
||||
const newModels = _updatedModelsAfterDefaultModelsChange(autodetectedModelNames, { existingModels: models })
|
||||
this.setSettingOfProvider(providerName, 'models', newModels)
|
||||
|
||||
// if the models changed, log it
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export const defaultModelsOfProvider = {
|
|||
'anthropic/claude-3.5-sonnet',
|
||||
'deepseek/deepseek-r1',
|
||||
'mistralai/codestral-2501',
|
||||
'qwen/qwen2.5-vl-72b-instruct:free',
|
||||
'qwen/qwen-2.5-coder-32b-instruct',
|
||||
],
|
||||
groq: [ // https://console.groq.com/docs/models
|
||||
'llama-3.3-70b-versatile',
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ const extensiveModelFallback: ProviderSettings['modelOptionsFallback'] = (modelN
|
|||
if (modelName.includes('deepseek-r1') || modelName.includes('deepseek-reasoner')) return toFallback({ ...openSourceModelDefaultOptionsAssumingOAICompat.deepseekR1, contextWindow: 32_000, maxOutputTokens: 4_096, })
|
||||
if (modelName.includes('deepseek')) return toFallback({ ...openSourceModelDefaultOptionsAssumingOAICompat.deepseekCoderV2, contextWindow: 32_000, maxOutputTokens: 4_096, })
|
||||
if (modelName.includes('llama3')) return toFallback({ ...openSourceModelDefaultOptionsAssumingOAICompat.llama3, contextWindow: 32_000, maxOutputTokens: 4_096, })
|
||||
if (modelName.includes('qwen2.5-coder')) return toFallback({ ...openSourceModelDefaultOptionsAssumingOAICompat['qwen2.5coder'], contextWindow: 32_000, maxOutputTokens: 4_096, })
|
||||
if (modelName.includes('qwen') && modelName.includes('2.5') && modelName.includes('coder')) return toFallback({ ...openSourceModelDefaultOptionsAssumingOAICompat['qwen2.5coder'], contextWindow: 32_000, maxOutputTokens: 4_096, })
|
||||
if (modelName.includes('codestral')) return toFallback({ ...openSourceModelDefaultOptionsAssumingOAICompat.codestral, contextWindow: 32_000, maxOutputTokens: 4_096, })
|
||||
if (/\bo1\b/.test(modelName) || /\bo3\b/.test(modelName)) return toFallback(openAIModelOptions['o1'])
|
||||
return toFallback(modelOptionDefaults)
|
||||
|
|
@ -482,6 +482,15 @@ const openRouterModelOptions = {
|
|||
supportsTools: 'openai-style',
|
||||
supportsReasoningOutput: false,
|
||||
},
|
||||
'qwen/qwen-2.5-coder-32b-instruct': {
|
||||
...openSourceModelDefaultOptionsAssumingOAICompat['qwen2.5coder'],
|
||||
contextWindow: 33_000,
|
||||
maxOutputTokens: null,
|
||||
supportsTools: false, // openrouter qwen doesn't seem to support tools...?
|
||||
cost: { input: 0.07, output: 0.16 },
|
||||
}
|
||||
|
||||
|
||||
} as const satisfies { [s: string]: ModelOptions }
|
||||
|
||||
const openRouterSettings: ProviderSettings = {
|
||||
|
|
@ -520,7 +529,7 @@ const modelSettingsOfProvider: ModelSettingsOfProvider = {
|
|||
|
||||
|
||||
|
||||
export const modelOptionsOfProvider = (providerName: ProviderName, modelName: string): ModelOptions & { modelName: string } => {
|
||||
export const getModelCapabilities = (providerName: ProviderName, modelName: string): ModelOptions & { modelName: string } => {
|
||||
const { modelOptions, modelOptionsFallback } = modelSettingsOfProvider[providerName]
|
||||
if (modelName in modelOptions) return { modelName, ...modelOptions[modelName] }
|
||||
const result = modelOptionsFallback(modelName)
|
||||
|
|
@ -629,7 +638,15 @@ const newOpenAICompatibleSDK = ({ settingsOfProvider, providerName, includeInPay
|
|||
|
||||
|
||||
const _sendOpenAICompatibleFIM = ({ messages: messages_, onFinalMessage, onError, settingsOfProvider, modelName: modelName_, _setAborter, providerName, aiInstructions, }: SendFIMParams_Internal) => {
|
||||
const { modelName } = modelOptionsOfProvider(providerName, modelName_)
|
||||
const { modelName, supportsFIM } = getModelCapabilities(providerName, modelName_)
|
||||
if (!supportsFIM) {
|
||||
if (modelName === modelName_)
|
||||
onFinalMessage({ fullText: `Model ${modelName} does not support FIM.` })
|
||||
else
|
||||
onFinalMessage({ fullText: `Model ${modelName_} (${modelName}) does not support FIM.` })
|
||||
return
|
||||
}
|
||||
|
||||
const messages = prepareFIMMessage({ messages: messages_, aiInstructions, })
|
||||
|
||||
const openai = newOpenAICompatibleSDK({ providerName, settingsOfProvider })
|
||||
|
|
@ -661,7 +678,7 @@ const _sendOpenAICompatibleChat = ({ messages: messages_, onText, onFinalMessage
|
|||
supportsSystemMessage,
|
||||
supportsTools,
|
||||
maxOutputTokens,
|
||||
} = modelOptionsOfProvider(providerName, modelName_)
|
||||
} = getModelCapabilities(providerName, modelName_)
|
||||
|
||||
const { messages } = prepareMessages({ messages: messages_, aiInstructions, supportsSystemMessage, supportsTools, })
|
||||
const tools = (supportsTools && ((tools_?.length ?? 0) !== 0)) ? tools_?.map(tool => toOpenAICompatibleTool(tool)) : undefined
|
||||
|
|
@ -777,7 +794,7 @@ const sendAnthropicChat = ({ messages: messages_, onText, providerName, onFinalM
|
|||
supportsSystemMessage,
|
||||
supportsTools,
|
||||
maxOutputTokens,
|
||||
} = modelOptionsOfProvider(providerName, modelName_)
|
||||
} = getModelCapabilities(providerName, modelName_)
|
||||
|
||||
const { messages, separateSystemMessageStr } = prepareMessages({ messages: messages_, aiInstructions, supportsSystemMessage, supportsTools, })
|
||||
|
||||
|
|
|
|||
|
|
@ -335,14 +335,16 @@ export const prepareFIMMessage = ({
|
|||
}) => {
|
||||
|
||||
let prefix = `\
|
||||
## You are a helpful coding assistant that performs autocomplete.
|
||||
${!aiInstructions ? '' : `\
|
||||
## Instructions:
|
||||
${aiInstructions.split('\n').map(line => `##${line}`).join('\n')}`}
|
||||
// Instructions:
|
||||
// Do not output an explanation. Try to avoid outputting comments. Only output the middle code.
|
||||
${aiInstructions.split('\n').map(line => `//${line}`).join('\n')}`}
|
||||
|
||||
${messages.prefix}`
|
||||
|
||||
const suffix = messages.suffix
|
||||
const stopTokens = messages.stopTokens
|
||||
return { prefix, suffix, stopTokens, maxTokens: 300 } as const
|
||||
const ret = { prefix, suffix, stopTokens, maxTokens: 300 } as const
|
||||
console.log('ret', ret)
|
||||
return ret
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue