diff --git a/src/vs/workbench/contrib/void/common/voidSettingsService.ts b/src/vs/workbench/contrib/void/common/voidSettingsService.ts index 59089230..e44a294a 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsService.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsService.ts @@ -11,7 +11,7 @@ import { registerSingleton, InstantiationType } from '../../../../platform/insta import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; import { IMetricsService } from './metricsService.js'; -import { defaultSettingsOfProvider, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider, SettingName, providerNames, ModelSelection, modelSelectionsEqual, featureNames, modelInfoOfDefaultModelNames, VoidModelInfo, GlobalSettings, GlobalSettingName, defaultGlobalSettings, displayInfoOfProviderName, defaultProviderSettings } from './voidSettingsTypes.js'; +import { defaultSettingsOfProvider, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider, SettingName, providerNames, ModelSelection, modelSelectionsEqual, featureNames, VoidModelInfo, GlobalSettings, GlobalSettingName, defaultGlobalSettings, displayInfoOfProviderName, defaultProviderSettings, developerInfoOfRecognizedModel, modelInfoOfAutodetectedModelNames } from './voidSettingsTypes.js'; const STORAGE_KEY = 'void.settingsServiceStorage' @@ -289,27 +289,26 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { - setAutodetectedModels(providerName: ProviderName, newDefaultModelNames: string[], logging: object) { + setAutodetectedModels(providerName: ProviderName, autodetectedModelNames: string[], logging: object) { const { models } = this.state.settingsOfProvider[providerName] - const oldModelNames = models.map(m => m.modelName) - const newDefaultModelInfo = modelInfoOfDefaultModelNames(newDefaultModelNames, { isAutodetected: true, existingModels: models }) - const newModelInfo = [ - ...newDefaultModelInfo, // swap out all the default models for the new default models - ...models.filter(m => !m.isDefault), // keep any non-defaul (custom) models + + const newDefaultModels = modelInfoOfAutodetectedModelNames(autodetectedModelNames, { existingModels: models }) + const newModels = [ + ...newDefaultModels, // swap out all the default models for the new default models + ...models.filter(m => !m.isDefault), // keep any non-default (custom) models ] - - this.setSettingOfProvider(providerName, 'models', newModelInfo) + this.setSettingOfProvider(providerName, 'models', newModels) // if the models changed, log it - const new_names = newModelInfo.map(m => m.modelName) + const new_names = newModels.map(m => m.modelName) if (!(oldModelNames.length === new_names.length && oldModelNames.every((_, i) => oldModelNames[i] === new_names[i])) ) { - this._metricsService.capture('Autodetect Models', { providerName, newModels: newModelInfo, ...logging }) + this._metricsService.capture('Autodetect Models', { providerName, newModels: newModels, ...logging }) } } toggleModelHidden(providerName: ProviderName, modelName: string) { @@ -335,7 +334,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { if (existingIdx !== -1) return // if exists, do nothing const newModels = [ ...models, - { modelName, isDefault: false, isHidden: false } + { ...developerInfoOfRecognizedModel(modelName), modelName, isDefault: false, isHidden: false } ] this.setSettingOfProvider(providerName, 'models', newModels) diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index a31eb771..10bee1c0 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -7,45 +7,217 @@ import { VoidSettingsState } from './voidSettingsService.js' -export type VoidModelInfo = { + +// developer info used in sendLLMMessage +type VoidModelDeveloperInfo = { + supportsSystemMessage: 'system' | 'developer' | false, // if null, we will just do a string of system message + supportsTools: boolean, // we will just do a string of tool use if it doesn't support + supportsAutocompleteFIM: boolean, // we will just do a description of FIM if it doens't support <|fim_hole|> + supportsStreaming: boolean, // (o1 does NOT) we will just dump the final result if doesn't support it + maxTokens: number, // required, DEFAULT is Infinity +} + +export type VoidModelInfo = { // <-- STATEFUL modelName: string, isDefault: boolean, // whether or not it's a default for its provider isHidden: boolean, // whether or not the user is hiding it (switched off) isAutodetected?: boolean, // whether the model was autodetected by polling -} +} & VoidModelDeveloperInfo -// creates `modelInfo` from `modelNames` -export const modelInfoOfDefaultModelNames = (defaultModelNames: string[], options?: { isAutodetected: true, existingModels: VoidModelInfo[] }): VoidModelInfo[] => { - const { isAutodetected, existingModels } = options ?? {} - if (!existingModels) { // default settings - return defaultModelNames.map((modelName, i) => ({ - modelName, - isDefault: true, - isAutodetected: isAutodetected, - isHidden: defaultModelNames.length >= 10 // hide all models if there are a ton of them, and make user enable them individually - })) - } else { // settings if there are existing models (keep existing `isHidden` property) - const existingModelsMap: Record = {} - for (const existingModel of existingModels) { - existingModelsMap[existingModel.modelName] = existingModel - } - return defaultModelNames.map((modelName, i) => ({ - modelName, - isDefault: true, - isAutodetected: isAutodetected, - isHidden: !!existingModelsMap[modelName]?.isHidden, - })) +export const recognizedModels = [ + // chat + 'OpenAI 4o', + 'Anthropic Claude', + 'Llama 3.x', + 'Deepseek Chat', // deepseek coder v2 is now merged into chat (V3) https://api-docs.deepseek.com/updates#deepseek-coder--deepseek-chat-upgraded-to-deepseek-v25-model + // 'xAI Grok', + // 'Google Gemini, Gemma', + // 'Microsoft Phi4', + + + // coding (autocomplete) + 'Alibaba Qwen2.5 Coder Instruct', // we recommend this over Qwen2.5 + 'Mistral Codestral', + + // thinking + 'OpenAI o1, o3', + 'Deepseek R1', + + // general + // 'Mixtral 8x7b' + // 'Qwen2.5', + +] as const + + + + +type RecognizedModel = (typeof recognizedModels)[number] | '' + + +// const modelCapabilities: { [recognizedModel in RecognizedModel]: ({ }) => string } = { +// 'OpenAI 4o': { +// template: ({ prefix, suffix, }: { prefix: string; suffix: string; }) => `\ +// ` +// } +// } + +export function getRecognizedModel(modelName: string): RecognizedModel { + const lower = modelName.toLowerCase(); + + if (lower.includes('gpt-4o')) { + return 'OpenAI 4o'; + } + if (lower.includes('claude')) { + return 'Anthropic Claude'; + } + if (lower.includes('llama')) { + return 'Llama 3.x'; + } + if (lower.includes('qwen2.5-coder')) { + return 'Alibaba Qwen2.5 Coder Instruct'; + } + if (lower.includes('mistral')) { + return 'Mistral Codestral'; + } + // Check for "o1" or "o3" + if (/\bo1\b/.test(lower) || /\bo3\b/.test(lower)) { + return 'OpenAI o1, o3'; + } + if (lower.includes('deepseek-r1') || lower.includes('deepseek-reasoner')) { + return 'Deepseek R1'; } + // Fallback: + return ''; } + + +export const developerInfoOfRecognizedModel = (modelName: string) => { + const devInfo: { [recognizedModel in RecognizedModel]: VoidModelDeveloperInfo } = { + 'OpenAI 4o': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'Anthropic Claude': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'Llama 3.x': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'Deepseek Chat': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'Alibaba Qwen2.5 Coder Instruct': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'Mistral Codestral': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'OpenAI o1, o3': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + 'Deepseek R1': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + + '': { + supportsSystemMessage: false, + supportsTools: false, + supportsAutocompleteFIM: false, + supportsStreaming: false, + maxTokens: 4096, + }, + } + + + const modelName_ = getRecognizedModel(modelName) + return devInfo[modelName_] +} + + + + + + +// creates `modelInfo` from `modelNames` +export const modelInfoOfDefaultModelNames = (defaultModelNames: string[]): VoidModelInfo[] => { + return defaultModelNames.map((modelName, i) => ({ + modelName, + isDefault: true, + isAutodetected: false, + isHidden: defaultModelNames.length >= 10, // hide all models if there are a ton of them, and make user enable them individually + ...developerInfoOfRecognizedModel(modelName) + })) +} + +export const modelInfoOfAutodetectedModelNames = (defaultModelNames: string[], options: { existingModels: VoidModelInfo[] }) => { + const { existingModels } = options + + const existingModelsMap: Record = {} + for (const existingModel of existingModels) { + existingModelsMap[existingModel.modelName] = existingModel + } + + return defaultModelNames.map((modelName, i) => ({ + modelName, + isDefault: true, + isAutodetected: true, + isHidden: !!existingModelsMap[modelName]?.isHidden, + ...developerInfoOfRecognizedModel(modelName) + })) +} + + + + + // https://docs.anthropic.com/en/docs/about-claude/models export const defaultAnthropicModels = modelInfoOfDefaultModelNames([ 'claude-3-5-sonnet-20241022', @@ -530,77 +702,3 @@ export const globalSettingNames = Object.keys(defaultGlobalSettings) as GlobalSe - - - -export const recognizedModels = [ - - // chat - 'OpenAI 4o', - 'Anthropic Claude', - 'Llama 3.x', - 'Deepseek Chat', // deepseek coder v2 is now merged into chat (V3) https://api-docs.deepseek.com/updates#deepseek-coder--deepseek-chat-upgraded-to-deepseek-v25-model - // 'xAI Grok', - // 'Google Gemini, Gemma', - // 'Microsoft Phi4', - - - // coding (autocomplete) - 'Alibaba Qwen2.5 Coder Instruct', // we recommend this over Qwen2.5 - 'Mistral Codestral', - - // thinking - 'OpenAI o1, o3', - 'Deepseek R1', - - // general - '' - // 'Mixtral 8x7b' - // 'Qwen2.5', - -] as const - - - - -type RecognizedModel = (typeof recognizedModels)[number] - - -// const modelCapabilities: { [recognizedModel in RecognizedModel]: ({ }) => string } = { -// 'OpenAI 4o': { -// template: ({ prefix, suffix, }: { prefix: string; suffix: string; }) => `\ -// ` -// } -// } - -export function getRecognizedModel(modelName: string): RecognizedModel { - const lower = modelName.toLowerCase(); - - if (lower.includes('gpt-4o')) { - return 'OpenAI 4o'; - } - if (lower.includes('claude')) { - return 'Anthropic Claude'; - } - if (lower.includes('llama')) { - return 'Llama 3.x'; - } - if (lower.includes('qwen2.5-coder')) { - return 'Alibaba Qwen2.5 Coder Instruct'; - } - if (lower.includes('mistral')) { - return 'Mistral Codestral'; - } - // Check for "o1" or "o3" - if (/\bo1\b/.test(lower) || /\bo3\b/.test(lower)) { - return 'OpenAI o1, o3'; - } - if (lower.includes('deepseek-r1') || lower.includes('deepseek-reasoner')) { - return 'Deepseek R1'; - } - - - - // Fallback: - return ''; -} diff --git a/src/vs/workbench/contrib/void/electron-main/templates/templates.ts b/src/vs/workbench/contrib/void/electron-main/templates/templates.ts deleted file mode 100644 index 138f7be3..00000000 --- a/src/vs/workbench/contrib/void/electron-main/templates/templates.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - -modelName -> { - system_message_type: 'system' | 'developer' (openai) | null // if null, we will just do a string of system message - supports_tools: boolean // we will just do a string of tool use if it doesn't support - supports_autocomplete_FIM (suffix) // we will just do a description of FIM if it doens't support <|fim_hole|> - - supports_streaming: boolean // (o1 does NOT) we will just dump the final result if doesn't support it - max_tokens: number // required, DEFAULT is Infinity - -} - -*/