From 3fd435750366e6691c3827e3c7314e9c4abc9fe7 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 8 Nov 2024 02:23:11 -0800 Subject: [PATCH] progress migrating to native vscode --- package-lock.json | 26 + package.json | 2 + .../contrib/void/browser/registerMetrics.ts | 37 + .../contrib/void/browser/registerSettings.ts | 275 ++++++ .../contrib/void/browser/registerSidebar.ts | 306 +++++++ .../void/browser/registerThreadsHistory.ts | 137 +++ .../contrib/void/browser/registerViewPane.ts | 66 -- .../contrib/void/browser/sidebar/Sidebar.tsx | 52 +- .../void/browser/sidebar/contextForConfig.tsx | 522 +++++------ .../void/browser/sidebar/contextForProps.tsx | 36 - .../browser/sidebar/contextForThreads.tsx | 182 ++-- .../contrib/void/browser/sidebar/index.tsx | 7 - .../contrib/void/browser/util/mount.tsx | 61 ++ .../contrib/void/browser/util/shared_types.ts | 56 +- .../contrib/void/browser/void.contribution.ts | 10 +- .../contrib/void/browser/voidViewPane.ts | 56 -- void-imports/index.ts | 9 +- void-imports/package-lock.json | 817 ++++++++++++++++++ void-imports/package.json | 19 + .../util => void-imports}/sendLLMMessage.ts | 22 +- void-imports/tsconfig.json | 12 + 21 files changed, 2124 insertions(+), 586 deletions(-) create mode 100644 src/vs/workbench/contrib/void/browser/registerMetrics.ts create mode 100644 src/vs/workbench/contrib/void/browser/registerSettings.ts create mode 100644 src/vs/workbench/contrib/void/browser/registerSidebar.ts create mode 100644 src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts delete mode 100644 src/vs/workbench/contrib/void/browser/registerViewPane.ts delete mode 100644 src/vs/workbench/contrib/void/browser/sidebar/contextForProps.tsx delete mode 100644 src/vs/workbench/contrib/void/browser/sidebar/index.tsx create mode 100644 src/vs/workbench/contrib/void/browser/util/mount.tsx delete mode 100644 src/vs/workbench/contrib/void/browser/voidViewPane.ts create mode 100644 void-imports/package-lock.json create mode 100644 void-imports/package.json rename {src/vs/workbench/contrib/void/browser/util => void-imports}/sendLLMMessage.ts (96%) create mode 100644 void-imports/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 2b9a985b..82a0032e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { + "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@parcel/watcher": "2.1.0", @@ -43,6 +44,7 @@ "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", "node-pty": "1.1.0-beta21", + "ollama": "^0.5.9", "open": "^8.4.2", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", @@ -1554,6 +1556,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@google/generative-ai": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.21.0.tgz", + "integrity": "sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@gulp-sourcemaps/identity-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", @@ -15276,6 +15287,15 @@ "node": ">=0.10.0" } }, + "node_modules/ollama": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.9.tgz", + "integrity": "sha512-F/KZuDRC+ZsVCuMvcOYuQ6zj42/idzCkkuknGyyGVmNStMZ/sU3jQpvhnl4SyC0+zBzLiKNZJnJeuPFuieWZvQ==", + "license": "MIT", + "dependencies": { + "whatwg-fetch": "^3.6.20" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -21885,6 +21905,12 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", diff --git a/package.json b/package.json index c8759228..7b7b6aee 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "update-build-ts-version": "npm install typescript@next && tsc -p ./build/tsconfig.build.json" }, "dependencies": { + "@google/generative-ai": "^0.21.0", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@parcel/watcher": "2.1.0", @@ -105,6 +106,7 @@ "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", "node-pty": "1.1.0-beta21", + "ollama": "^0.5.9", "open": "^8.4.2", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", diff --git a/src/vs/workbench/contrib/void/browser/registerMetrics.ts b/src/vs/workbench/contrib/void/browser/registerMetrics.ts new file mode 100644 index 00000000..4c256d30 --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/registerMetrics.ts @@ -0,0 +1,37 @@ +import { Disposable } from '../../../../base/common/lifecycle.js'; +import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions'; +import { createDecorator } from '../../../../platform/instantiation/common/instantiation'; +import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry'; + +interface IMetricsService { + readonly _serviceBrand: undefined; +} + +const IMetricsService = createDecorator('inlineDiffService'); +class MetricsService extends Disposable implements IMetricsService { + _serviceBrand: undefined; + + constructor( + @ITelemetryService private readonly _telemetryService: ITelemetryService + ) { + super() + } + + init() { + + posthog.init('phc_UanIdujHiLp55BkUTjB1AuBXcasVkdqRwgnwRlWESH2', + { + api_host: 'https://us.i.posthog.com', + person_profiles: 'identified_only' // we only track events from identified users. We identify them in Sidebar + } + ) + + const deviceId = this._telemetryService.devDeviceId + console.debug('deviceId', deviceId) + + posthog.identify(deviceId) + } + +} + +registerSingleton(IMetricsService, MetricsService, InstantiationType.Eager); diff --git a/src/vs/workbench/contrib/void/browser/registerSettings.ts b/src/vs/workbench/contrib/void/browser/registerSettings.ts new file mode 100644 index 00000000..0297c035 --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/registerSettings.ts @@ -0,0 +1,275 @@ +import { Emitter, Event } from '../../../../base/common/event.js'; +import { Disposable } from '../../../../base/common/lifecycle.js'; +import { IEncryptionService } from '../../../../platform/encryption/common/encryptionService.js'; +import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js'; +import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; +import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; + +const configEnum = (description: string, defaultVal: EnumArr[number], enumArr: EnumArr) => { + return { + description, + defaultVal, + enumArr, + } +} + +const configString = (description: string, defaultVal: string) => { + return { + description, + defaultVal, + enumArr: undefined, + } +} + +// fields you can customize (don't forget 'default' - it isn't included here!) +export const nonDefaultConfigFields = [ + 'anthropic', + 'openAI', + 'gemini', + 'greptile', + 'ollama', + 'openRouter', + 'openAICompatible', + 'azure', +] as const + + + +const voidConfigInfo: Record< + typeof nonDefaultConfigFields[number] | 'default', { + [prop: string]: { + description: string, + enumArr?: readonly string[] | undefined, + defaultVal: string, + }, + } +> = { + default: { + whichApi: configEnum( + "API Provider.", + 'anthropic', + nonDefaultConfigFields, + ), + + maxTokens: configEnum( + "Max number of tokens to output.", + '1024', + [ + "default", // this will be parseInt'd into NaN and ignored by the API. Anything that's not a number has this behavior. + "1024", + "2048", + "4096", + "8192" + ] as const, + ), + + }, + anthropic: { + apikey: configString('Anthropic API key.', ''), + model: configEnum( + "Anthropic model to use.", + 'claude-3-5-sonnet-20240620', + [ + "claude-3-5-sonnet-20240620", + "claude-3-opus-20240229", + "claude-3-sonnet-20240229", + "claude-3-haiku-20240307" + ] as const, + ), + }, + openAI: { + apikey: configString('OpenAI API key.', ''), + model: configEnum( + 'OpenAI model to use.', + 'gpt-4o', + [ + "o1-preview", + "o1-mini", + "gpt-4o", + "gpt-4o-2024-05-13", + "gpt-4o-2024-08-06", + "gpt-4o-mini", + "gpt-4o-mini-2024-07-18", + "gpt-4-turbo", + "gpt-4-turbo-2024-04-09", + "gpt-4-turbo-preview", + "gpt-4-0125-preview", + "gpt-4-1106-preview", + "gpt-4", + "gpt-4-0613", + "gpt-3.5-turbo-0125", + "gpt-3.5-turbo", + "gpt-3.5-turbo-1106" + ] as const + ), + }, + greptile: { + apikey: configString('Greptile API key.', ''), + githubPAT: configString('Github PAT that Greptile uses to access your repository', ''), + remote: configEnum( + 'Repo location', + 'github', + [ + 'github', + 'gitlab' + ] as const + ), + repository: configString('Repository identifier in "owner/repository" format.', ''), + branch: configString('Name of the branch to use.', 'main'), + }, + ollama: { + endpoint: configString( + 'The endpoint of your Ollama instance. Start Ollama by running `OLLAMA_ORIGINS="vscode-webview://*" ollama serve`.', + 'http://127.0.0.1:11434' + ), + // TODO we should allow user to select model inside Void, but for now we'll just let them handle the Ollama setup on their own + // model: configEnum( + // 'Ollama model to use.', + // 'llama3.1', + // ["codegemma", "codegemma:2b", "codegemma:7b", "codellama", "codellama:7b", "codellama:13b", "codellama:34b", "codellama:70b", "codellama:code", "codellama:python", "command-r", "command-r:35b", "command-r-plus", "command-r-plus:104b", "deepseek-coder-v2", "deepseek-coder-v2:16b", "deepseek-coder-v2:236b", "falcon2", "falcon2:11b", "firefunction-v2", "firefunction-v2:70b", "gemma", "gemma:2b", "gemma:7b", "gemma2", "gemma2:2b", "gemma2:9b", "gemma2:27b", "llama2", "llama2:7b", "llama2:13b", "llama2:70b", "llama3", "llama3:8b", "llama3:70b", "llama3-chatqa", "llama3-chatqa:8b", "llama3-chatqa:70b", "llama3-gradient", "llama3-gradient:8b", "llama3-gradient:70b", "llama3.1", "llama3.1:8b", "llama3.1:70b", "llama3.1:405b", "llava", "llava:7b", "llava:13b", "llava:34b", "llava-llama3", "llava-llama3:8b", "llava-phi3", "llava-phi3:3.8b", "mistral", "mistral:7b", "mistral-large", "mistral-large:123b", "mistral-nemo", "mistral-nemo:12b", "mixtral", "mixtral:8x7b", "mixtral:8x22b", "moondream", "moondream:1.8b", "openhermes", "openhermes:v2.5", "phi3", "phi3:3.8b", "phi3:14b", "phi3.5", "phi3.5:3.8b", "qwen", "qwen:7b", "qwen:14b", "qwen:32b", "qwen:72b", "qwen:110b", "qwen2", "qwen2:0.5b", "qwen2:1.5b", "qwen2:7b", "qwen2:72b", "smollm", "smollm:135m", "smollm:360m", "smollm:1.7b"] as const + // ), + }, + openRouter: { + model: configString( + 'OpenRouter model to use.', + 'openai/gpt-4o' + ), + apikey: configString('OpenRouter API key.', ''), + }, + openAICompatible: { + endpoint: configString('The baseUrl (exluding /chat/completions).', 'http://127.0.0.1:11434/v1'), + model: configString('The name of the model to use.', 'gpt-4o'), + apikey: configString('Your API key.', ''), + }, + azure: { + // "void.azure.apiKey": { + // "type": "string", + // "description": "Azure API key." + // }, + // "void.azure.deploymentId": { + // "type": "string", + // "description": "Azure API deployment ID." + // }, + // "void.azure.resourceName": { + // "type": "string", + // "description": "Name of the Azure OpenAI resource. Either this or `baseURL` can be used. \nThe resource name is used in the assembled URL: `https://{resourceName}.openai.azure.com/openai/deployments/{modelId}{path}`" + // }, + // "void.azure.providerSettings": { + // "type": "object", + // "properties": { + // "baseURL": { + // "type": "string", + // "default": "https://${resourceName}.openai.azure.com/openai/deployments", + // "description": "Azure API base URL." + // }, + // "headers": { + // "type": "object", + // "description": "Custom headers to include in the requests." + // } + // } + // }, + }, + gemini: { + apikey: configString('Google API key.', ''), + model: configEnum( + 'Gemini model to use.', + 'gemini-1.5-flash', + [ + "gemini-1.5-flash", + "gemini-1.5-pro", + "gemini-1.5-flash-8b", + "gemini-1.0-pro" + ] as const + ), + }, +} + + +// this is the type that comes with metadata like desc, default val, etc +type VoidConfigInfo = typeof voidConfigInfo +export type VoidConfigField = keyof typeof voidConfigInfo // typeof configFields[number] + +// this is the type that specifies the user's actual config +export type PartialVoidConfig = { + [K in keyof typeof voidConfigInfo]?: { + [P in keyof typeof voidConfigInfo[K]]?: typeof voidConfigInfo[K][P]['defaultVal'] + } +} + +export type VoidConfig = { + [K in keyof typeof voidConfigInfo]: { + [P in keyof typeof voidConfigInfo[K]]: typeof voidConfigInfo[K][P]['defaultVal'] + } +} + + +const VOID_CONFIG_KEY = 'void.partialVoidConfig' + +export interface IVoidSettingsService { + readonly _serviceBrand: undefined; +} + +export const IVoidSettingsService = createDecorator('voidSettingsService'); +class VoidSettingsService extends Disposable implements IVoidSettingsService { + _serviceBrand: undefined; + + private readonly _onDidChange = new Emitter(); + readonly onDidChange: Event = this._onDidChange.event; + + + async getPartialVoidConfig(): Promise { + const encryptedPartialConfig = this._storageService.get(VOID_CONFIG_KEY, StorageScope.APPLICATION) + + if (!encryptedPartialConfig) + return {} + + const partialVoidConfigStr = await this._encryptionService.decrypt(encryptedPartialConfig) + return JSON.parse(partialVoidConfigStr) + } + + + async getVoidConfig(): Promise { + const partialVoidConfig = await this.getPartialVoidConfig() + const config = {} as PartialVoidConfig + for (let field of [...nonDefaultConfigFields, 'default'] as const) { + config[field] = {} + for (let prop in voidConfigInfo[field]) { + config[field][prop] = partialVoidConfig[field]?.[prop]?.trim() || voidConfigInfo[field][prop].defaultVal + } + } + return config as VoidConfig + } + + + private async storePartialVoidConfig(partialVoidConfig: PartialVoidConfig) { + const encryptedPartialConfigStr = await this._encryptionService.encrypt(JSON.stringify(partialVoidConfig)) + this._storageService.store(VOID_CONFIG_KEY, encryptedPartialConfigStr, StorageScope.APPLICATION, StorageTarget.USER) + } + + + // Set field on PartialVoidConfig + async setField(field: K, param: keyof VoidConfigInfo[K], newVal: string) { + const partialVoidConfig = await this.getPartialVoidConfig() + + const newPartialConfig: PartialVoidConfig = { + ...partialVoidConfig, + [field]: { + ...partialVoidConfig[field], + [param]: newVal + } + } + await this.storePartialVoidConfig(newPartialConfig) + this._onDidChange.fire() + } + + + constructor( + @IStorageService private readonly _storageService: IStorageService, + @IEncryptionService private readonly _encryptionService: IEncryptionService, + ) { + super() + } + +} + +registerSingleton(IVoidSettingsService, VoidSettingsService, InstantiationType.Eager); diff --git a/src/vs/workbench/contrib/void/browser/registerSidebar.ts b/src/vs/workbench/contrib/void/browser/registerSidebar.ts new file mode 100644 index 00000000..27a5d1b0 --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/registerSidebar.ts @@ -0,0 +1,306 @@ +import { Registry } from '../../../../platform/registry/common/platform.js'; +import { + Extensions as ViewContainerExtensions, IViewContainersRegistry, + ViewContainerLocation, IViewsRegistry, Extensions as ViewExtensions, + IViewDescriptorService, +} from '../../../common/views.js'; + +import * as nls from '../../../../nls.js'; +import * as dom from '../../../../base/browser/dom.js'; + +import { Codicon } from '../../../../base/common/codicons.js'; +import { localize } from '../../../../nls.js'; +import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js'; +import { ViewPaneContainer } from '../../../browser/parts/views/viewPaneContainer.js'; + +import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js'; +import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js'; + + +import { IViewPaneOptions, ViewPane } from '../../../browser/parts/views/viewPane.js'; +import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js'; +import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js'; + +import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js'; +import { ContextKeyExpr, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js'; +import { createDecorator, IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; +import { Disposable } from '../../../../base/common/lifecycle.js'; +import { Emitter, Event } from '../../../../base/common/event.js'; +import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; +import { IViewsService } from '../../../services/views/common/viewsService.js'; +import { IThreadHistoryService } from './registerThreadsHistory.js'; +import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; +import { IThemeService } from '../../../../platform/theme/common/themeService.js'; +import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js'; +import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js'; +import { IOpenerService } from '../../../../platform/opener/common/opener.js'; +import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; +import { IHoverService } from '../../../../platform/hover/browser/hover.js'; +import { IVoidSettingsService } from './registerSettings.js'; + + +// compare against search.contribution.ts and https://app.greptile.com/chat/w1nsmt3lauwzculipycpn?repo=github%3Amain%3Amicrosoft%2Fvscode +// and debug.contribution.ts, scm.contribution.ts (source control) + +type VoidSidebarState = { + isHistoryOpen: boolean + currentTab: 'chat' | 'settings' +} + + +// ---------- Define viewpane ---------- + +class VoidSidebarViewPane extends ViewPane { + + constructor( + options: IViewPaneOptions, + @IInstantiationService instantiationService: IInstantiationService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService, + @IConfigurationService configurationService: IConfigurationService, + @IContextKeyService contextKeyService: IContextKeyService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IKeybindingService keybindingService: IKeybindingService, + @IOpenerService openerService: IOpenerService, + @ITelemetryService telemetryService: ITelemetryService, + @IHoverService hoverService: IHoverService, + // Void: + @IVoidSidebarStateService private readonly _voidSidebarStateService: IVoidSidebarStateService, + @IThreadHistoryService private readonly _threadHistoryService: IThreadHistoryService, + @IVoidSettingsService private readonly _voidSettingsService: IVoidSettingsService, + // TODO chat service + ) { + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService) + } + + + + protected override renderBody(parent: HTMLElement): void { + super.renderBody(parent); + + const { root, history, chat, settings } = dom.h('div@root', [ + dom.h('div@history', []), + dom.h('div@chat', []), + dom.h('div@settings', []), + ]) + root.style.display = 'flex'; + root.style.flexDirection = 'column'; + root.style.height = '100vh'; + root.style.width = '100%'; + + + dom.append(parent, root); + + this._renderHistory(history); + + } + + + private _renderHistory(element: HTMLElement) { + //
+ // setTab('chat')} /> + //
+ this._voidSidebarStateService.onDidChange(() => { + }) + + this._threadHistoryService.onDidChangeCurrentThread(() => { + + }) + + } + + private _renderSettings(element: HTMLElement) { + //
+ // + //
+ + } + + private _renderChat(element: HTMLElement) { + //
+ // + //
+ + } + +} + + + +// ---------- Register viewpane inside the void container ---------- + +const voidThemeIcon = Codicon.search; +const voidViewIcon = registerIcon('void-view-icon', voidThemeIcon, localize('voidViewIcon', 'View icon of the Void chat view.')); + +// called VIEWLET_ID in other places for some reason +const VOID_VIEW_CONTAINER_ID = 'workbench.view.void' +const SIDEBAR_VIEW_ID = VOID_VIEW_CONTAINER_ID // not sure if we can change this + +// Register view container +const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); +const viewContainer = viewContainerRegistry.registerViewContainer({ + id: VOID_VIEW_CONTAINER_ID, + title: nls.localize2('void', 'Void'), // this is used to say "Void" (Ctrl + L) + ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [VOID_VIEW_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }]), + hideIfEmpty: false, + icon: voidViewIcon, + order: 1, +}, ViewContainerLocation.AuxiliaryBar, { doNotRegisterOpenCommand: true, }); + + + +// Register search default location to the container (sidebar) +const viewsRegistry = Registry.as(ViewExtensions.ViewsRegistry); +viewsRegistry.registerViews([{ + id: SIDEBAR_VIEW_ID, + hideByDefault: false, // start open + containerIcon: voidViewIcon, + name: nls.localize2('void chat', "Chat"), // this says ... : CHAT + ctorDescriptor: new SyncDescriptor(VoidSidebarViewPane), + canToggleVisibility: false, + canMoveView: true, + openCommandActionDescriptor: { + id: viewContainer.id, + keybindings: { + primary: KeyMod.CtrlCmd | KeyCode.KeyL, + }, + order: 1 + }, +}], viewContainer); + + + +// ---------- Register service that manages sidebar's state ---------- + +interface IVoidSidebarStateService { + readonly _serviceBrand: undefined; + setState(newState: Partial): void; + state: VoidSidebarState; + focusChat(): void; + blurChat(): void; + + onDidChange: Event; + onFocusChat: Event; + onBlurChat: Event; +} + + +const IVoidSidebarStateService = createDecorator('voidSidebarStateService'); +class VoidSidebarStateService extends Disposable implements IVoidSidebarStateService { + _serviceBrand: undefined; + + private readonly _onDidChange = new Emitter(); + readonly onDidChange: Event = this._onDidChange.event; + + private readonly _onFocusChat = new Emitter(); + readonly onFocusChat: Event = this._onFocusChat.event; + + private readonly _onBlurChat = new Emitter(); + readonly onBlurChat: Event = this._onBlurChat.event; + + + // state + state: VoidSidebarState = { + isHistoryOpen: false, + currentTab: 'chat', + } + + constructor( + @IViewsService private readonly _viewsService: IViewsService, + ) { + super() + // auto open the view on mount (can view this as initializing state...) + this._viewsService.openView(SIDEBAR_VIEW_ID); + } + + setState(newState: Partial) { + // make sure view is open if the tab changes + if ('currentTab' in newState) + this._viewsService.openView(SIDEBAR_VIEW_ID); + + this.state = { ...this.state, ...newState } + this._onDidChange.fire() + } + + focusChat() { + this._onFocusChat.fire() + } + + blurChat() { + this._onBlurChat.fire() + } + +} + +registerSingleton(IVoidSidebarStateService, VoidSidebarStateService, InstantiationType.Eager); + + + +// ---------- Register commands and keybindings ---------- + +// Action: when press ctrl+L, show the sidebar chat and add to the selection +registerAction2(class extends Action2 { + constructor() { + super({ id: 'void.ctrl+l', title: 'Show Sidebar', keybinding: { primary: KeyMod.CtrlCmd | KeyCode.KeyL, weight: KeybindingWeight.WorkbenchContrib } }); + } + async run(accessor: ServicesAccessor): Promise { + const stateService = accessor.get(IVoidSidebarStateService) + stateService.setState({ isHistoryOpen: false, currentTab: 'chat' }) + stateService.focusChat() + } +}); + + +// History menu button +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'void.historyAction', + title: 'View past chats', + icon: { id: 'history' }, + menu: [{ id: MenuId.ViewTitle, group: 'navigation', when: ContextKeyExpr.equals('view', SIDEBAR_VIEW_ID), }] + }); + } + async run(accessor: ServicesAccessor): Promise { + const stateService = accessor.get(IVoidSidebarStateService) + stateService.setState({ isHistoryOpen: !stateService.state.isHistoryOpen }) + stateService.blurChat() + } +}) + +// New chat menu button +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'void.newChatAction', + title: 'View past chats', + icon: { id: 'add' }, + menu: [{ id: MenuId.ViewTitle, group: 'navigation', when: ContextKeyExpr.equals('view', SIDEBAR_VIEW_ID), }] + }); + } + async run(accessor: ServicesAccessor): Promise { + const stateService = accessor.get(IVoidSidebarStateService) + stateService.setState({ isHistoryOpen: false, currentTab: 'chat' }) + stateService.focusChat() + + const historyService = accessor.get(IThreadHistoryService) + historyService.startNewThread() + } +}) + +// Settings (API config) menu button +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'void.viewSettings', + title: 'Void settings', + icon: { id: 'settings-gear' }, + menu: [{ id: MenuId.ViewTitle, group: 'navigation', when: ContextKeyExpr.equals('view', SIDEBAR_VIEW_ID), }] + }); + } + async run(accessor: ServicesAccessor): Promise { + const stateService = accessor.get(IVoidSidebarStateService) + stateService.setState({ isHistoryOpen: false, currentTab: 'settings' }) + stateService.blurChat() + } +}) diff --git a/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts b/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts new file mode 100644 index 00000000..71862436 --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts @@ -0,0 +1,137 @@ +import { Disposable } from '../../../../base/common/lifecycle.js'; +import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js'; +import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; +import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; + +import { URI } from '../../../../base/common/uri.js'; +import { Emitter, Event } from '../../../../base/common/event.js'; + +export type CodeSelection = { selectionStr: string, filePath: URI } + +export type ChatThreads = { + [id: string]: { + id: string; // store the id here too + createdAt: string; // ISO string + lastModified: string; // ISO string + messages: ChatMessage[]; + } +} + +type ChatMessage = + | { + role: "user"; + content: string; // content sent to the llm + displayContent: string; // content displayed to user + selection: CodeSelection | null; // the user's selection + files: URI[]; // the files sent in the message + } + | { + role: "assistant"; + content: string; // content received from LLM + displayContent: string | undefined; // content displayed to user (this is the same as content for now) + } + | { + role: "system"; + content: string; + displayContent?: undefined; + } + + +// a "thread" means a chat message history + +const createNewThread = () => { + const now = new Date().toISOString() + return { + id: new Date().getTime().toString(), + createdAt: now, + lastModified: now, + messages: [], + } +} + +const THREAD_STORAGE_KEY = 'void.threadsHistory' + +export interface IThreadHistoryService { + readonly _serviceBrand: undefined; + startNewThread(): void; + onDidChangeCurrentThread: Event; +} + +export const IThreadHistoryService = createDecorator('voidThreadHistoryService'); +class ThreadHistoryService extends Disposable implements IThreadHistoryService { + _serviceBrand: undefined; + + // the current thread id we are on + _currentThreadId: string | null = null + + // this fires when the current thread changes at all (a switch of currentThread, or a message added to it, etc) + private readonly _onDidChangeCurrentThread = new Emitter(); + readonly onDidChangeCurrentThread: Event = this._onDidChangeCurrentThread.event; + + + getAllThreads(): ChatThreads { + // storage is the source of truth for threads + const threads = this._storageService.get(THREAD_STORAGE_KEY, StorageScope.APPLICATION) + return threads ? JSON.parse(threads) : {} + } + + private _storeAllThreads(threads: ChatThreads) { + this._storageService.store(THREAD_STORAGE_KEY, JSON.stringify(threads), StorageScope.APPLICATION, StorageTarget.USER) + } + + getCurrentThread(): ChatThreads[string] | null { + const threads = this.getAllThreads() + return this._currentThreadId ? threads[this._currentThreadId] ?? null : null + } + + switchToThread(threadId: string) { + this._currentThreadId = threadId + this._onDidChangeCurrentThread.fire() + } + + + startNewThread() { + const newThread = createNewThread() + const currentThreads = this.getAllThreads() + this._storeAllThreads({ + ...currentThreads, + [newThread.id]: newThread + }) + this._currentThreadId = newThread.id + this._onDidChangeCurrentThread.fire() + } + + + addMessageToCurrentThread(message: ChatMessage) { + let currentThread: ChatThreads[string] + const allThreads = this.getAllThreads() + + if (this._currentThreadId && (this._currentThreadId in allThreads)) { + currentThread = allThreads[this._currentThreadId] + } + else { + currentThread = createNewThread() + this._currentThreadId = currentThread.id + } + + this._storeAllThreads({ + ...allThreads, + [currentThread.id]: { + ...currentThread, + lastModified: new Date().toISOString(), + messages: [...currentThread.messages, message], + } + }) + + // the current thread just changed (it had a message added to it) + this._onDidChangeCurrentThread.fire() + } + + constructor( + @IStorageService private readonly _storageService: IStorageService, + ) { + super() + } +} + +registerSingleton(IThreadHistoryService, ThreadHistoryService, InstantiationType.Eager); diff --git a/src/vs/workbench/contrib/void/browser/registerViewPane.ts b/src/vs/workbench/contrib/void/browser/registerViewPane.ts deleted file mode 100644 index c5c2c0cf..00000000 --- a/src/vs/workbench/contrib/void/browser/registerViewPane.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Registry } from '../../../../platform/registry/common/platform.js'; -import { - Extensions as ViewContainerExtensions, IViewContainersRegistry, - ViewContainerLocation, IViewsRegistry, Extensions as ViewExtensions, -} from '../../../common/views.js'; - -import * as nls from '../../../../nls.js'; - -import { VoidViewPane } from './voidViewPane.js'; - -import { Codicon } from '../../../../base/common/codicons.js'; -import { localize } from '../../../../nls.js'; -import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js'; -import { ViewPaneContainer } from '../../../browser/parts/views/viewPaneContainer.js'; - -import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js'; -import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js'; - - -const voidThemeIcon = Codicon.search; -const voidViewIcon = registerIcon('void-view-icon', voidThemeIcon, localize('voidViewIcon', 'View icon of the Void chat view.')); - - -// compare against search.contribution.ts and https://app.greptile.com/chat/w1nsmt3lauwzculipycpn?repo=github%3Amain%3Amicrosoft%2Fvscode -// and debug.contribution.ts, scm.contribution.ts (source control) - -// called VIEWLET_ID in other places for some reason -const VIEW_CONTAINER_ID = 'workbench.view.void' - -// Register view container -const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); -const viewContainer = viewContainerRegistry.registerViewContainer({ - id: VIEW_CONTAINER_ID, - title: nls.localize2('void', 'Void'), // this is used to say "Void" (Ctrl + L) - ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [VIEW_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }]), - hideIfEmpty: false, - icon: voidViewIcon, - order: 1, -}, ViewContainerLocation.AuxiliaryBar, { doNotRegisterOpenCommand: true, }); - - - -// Register search default location to the container (sidebar) -const viewsRegistry = Registry.as(ViewExtensions.ViewsRegistry); -viewsRegistry.registerViews([{ - id: VIEW_CONTAINER_ID, // not sure if we can change this - hideByDefault: false, // start open - containerIcon: voidViewIcon, - name: nls.localize2('void chat', "Chat"), // this says ... : CHAT - ctorDescriptor: new SyncDescriptor(VoidViewPane), - canToggleVisibility: false, - canMoveView: true, - openCommandActionDescriptor: { - id: viewContainer.id, - keybindings: { - primary: KeyMod.CtrlCmd | KeyCode.KeyL, // we don't need to disable the original ctrl+L (probably because it brings panel into focus first) - }, - order: 1 - // mnemonicTitle: nls.localize({ key: 'miViewSearch', comment: ['&& denotes a mnemonic'] }, "&&Search"), - } -}], viewContainer); - - -// TODO can add a configuration for the user to choose config options - see search.contribution.ts - - diff --git a/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx b/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx index b04548de..b3bf8ae3 100644 --- a/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx +++ b/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx @@ -10,35 +10,35 @@ const Sidebar = () => { const [tab, setTab] = useState<'threadSelector' | 'chat' | 'settings'>('chat') - // if they pressed the + to add a new chat - useOnVSCodeMessage('startNewThread', (m) => { - setTab('chat'); - chatInputRef.current?.focus(); - }) + // // if they pressed the + to add a new chat + // useOnVSCodeMessage('startNewThread', (m) => { + // setTab('chat'); + // chatInputRef.current?.focus(); + // }) - // ctrl+l should switch back to chat - useOnVSCodeMessage('ctrl+l', (m) => { - setTab('chat'); - chatInputRef.current?.focus(); - }) + // // ctrl+l should switch back to chat + // useOnVSCodeMessage('ctrl+l', (m) => { + // setTab('chat'); + // chatInputRef.current?.focus(); + // }) - // if they toggled thread selector - useOnVSCodeMessage('toggleThreadSelector', (m) => { - if (tab === 'threadSelector') { - setTab('chat') - chatInputRef.current?.blur(); - } else - setTab('threadSelector') - }) + // // if they toggled thread selector + // useOnVSCodeMessage('toggleThreadSelector', (m) => { + // if (tab === 'threadSelector') { + // setTab('chat') + // chatInputRef.current?.blur(); + // } else + // setTab('threadSelector') + // }) - // if they toggled settings - useOnVSCodeMessage('toggleSettings', (m) => { - if (tab === 'settings') { - setTab('chat') - chatInputRef.current?.blur(); - } else - setTab('settings') - }) + // // if they toggled settings + // useOnVSCodeMessage('toggleSettings', (m) => { + // if (tab === 'settings') { + // setTab('chat') + // chatInputRef.current?.blur(); + // } else + // setTab('settings') + // }) return <>
diff --git a/src/vs/workbench/contrib/void/browser/sidebar/contextForConfig.tsx b/src/vs/workbench/contrib/void/browser/sidebar/contextForConfig.tsx index 5437bad5..999f2282 100644 --- a/src/vs/workbench/contrib/void/browser/sidebar/contextForConfig.tsx +++ b/src/vs/workbench/contrib/void/browser/sidebar/contextForConfig.tsx @@ -1,289 +1,289 @@ -import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" -import { awaitVSCodeResponse, getVSCodeAPI, useOnVSCodeMessage } from "./getVscodeApi" +// import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" +// import { awaitVSCodeResponse, getVSCodeAPI, useOnVSCodeMessage } from "./getVscodeApi" -const configEnum = (description: string, defaultVal: EnumArr[number], enumArr: EnumArr) => { - return { - description, - defaultVal, - enumArr, - } -} +// const configEnum = (description: string, defaultVal: EnumArr[number], enumArr: EnumArr) => { +// return { +// description, +// defaultVal, +// enumArr, +// } +// } -const configString = (description: string, defaultVal: string) => { - return { - description, - defaultVal, - enumArr: undefined, - } -} +// const configString = (description: string, defaultVal: string) => { +// return { +// description, +// defaultVal, +// enumArr: undefined, +// } +// } -// fields you can customize (don't forget 'default' - it isn't included here!) -export const configFields = [ - 'anthropic', - 'openAI', - 'gemini', - 'greptile', - 'ollama', - 'openRouter', - 'openAICompatible', - 'azure', -] as const +// // fields you can customize (don't forget 'default' - it isn't included here!) +// export const configFields = [ +// 'anthropic', +// 'openAI', +// 'gemini', +// 'greptile', +// 'ollama', +// 'openRouter', +// 'openAICompatible', +// 'azure', +// ] as const -const voidConfigInfo: Record< - typeof configFields[number] | 'default', { - [prop: string]: { - description: string, - enumArr?: readonly string[] | undefined, - defaultVal: string, - }, - } -> = { - default: { - whichApi: configEnum( - "API Provider.", - 'anthropic', - configFields, - ), +// const voidConfigInfo: Record< +// typeof configFields[number] | 'default', { +// [prop: string]: { +// description: string, +// enumArr?: readonly string[] | undefined, +// defaultVal: string, +// }, +// } +// > = { +// default: { +// whichApi: configEnum( +// "API Provider.", +// 'anthropic', +// configFields, +// ), - maxTokens: configEnum( - "Max number of tokens to output.", - '1024', - [ - "default", // this will be parseInt'd into NaN and ignored by the API. Anything that's not a number has this behavior. - "1024", - "2048", - "4096", - "8192" - ] as const, - ), +// maxTokens: configEnum( +// "Max number of tokens to output.", +// '1024', +// [ +// "default", // this will be parseInt'd into NaN and ignored by the API. Anything that's not a number has this behavior. +// "1024", +// "2048", +// "4096", +// "8192" +// ] as const, +// ), - }, - anthropic: { - apikey: configString('Anthropic API key.', ''), - model: configEnum( - "Anthropic model to use.", - 'claude-3-5-sonnet-20240620', - [ - "claude-3-5-sonnet-20240620", - "claude-3-opus-20240229", - "claude-3-sonnet-20240229", - "claude-3-haiku-20240307" - ] as const, - ), - }, - openAI: { - apikey: configString('OpenAI API key.', ''), - model: configEnum( - 'OpenAI model to use.', - 'gpt-4o', - [ - "o1-preview", - "o1-mini", - "gpt-4o", - "gpt-4o-2024-05-13", - "gpt-4o-2024-08-06", - "gpt-4o-mini", - "gpt-4o-mini-2024-07-18", - "gpt-4-turbo", - "gpt-4-turbo-2024-04-09", - "gpt-4-turbo-preview", - "gpt-4-0125-preview", - "gpt-4-1106-preview", - "gpt-4", - "gpt-4-0613", - "gpt-3.5-turbo-0125", - "gpt-3.5-turbo", - "gpt-3.5-turbo-1106" - ] as const - ), - }, - greptile: { - apikey: configString('Greptile API key.', ''), - githubPAT: configString('Github PAT that Greptile uses to access your repository', ''), - remote: configEnum( - 'Repo location', - 'github', - [ - 'github', - 'gitlab' - ] as const - ), - repository: configString('Repository identifier in "owner/repository" format.', ''), - branch: configString('Name of the branch to use.', 'main'), - }, - ollama: { - endpoint: configString( - 'The endpoint of your Ollama instance. Start Ollama by running `OLLAMA_ORIGINS="vscode-webview://*" ollama serve`.', - 'http://127.0.0.1:11434' - ), - // TODO we should allow user to select model inside Void, but for now we'll just let them handle the Ollama setup on their own - // model: configEnum( - // 'Ollama model to use.', - // 'llama3.1', - // ["codegemma", "codegemma:2b", "codegemma:7b", "codellama", "codellama:7b", "codellama:13b", "codellama:34b", "codellama:70b", "codellama:code", "codellama:python", "command-r", "command-r:35b", "command-r-plus", "command-r-plus:104b", "deepseek-coder-v2", "deepseek-coder-v2:16b", "deepseek-coder-v2:236b", "falcon2", "falcon2:11b", "firefunction-v2", "firefunction-v2:70b", "gemma", "gemma:2b", "gemma:7b", "gemma2", "gemma2:2b", "gemma2:9b", "gemma2:27b", "llama2", "llama2:7b", "llama2:13b", "llama2:70b", "llama3", "llama3:8b", "llama3:70b", "llama3-chatqa", "llama3-chatqa:8b", "llama3-chatqa:70b", "llama3-gradient", "llama3-gradient:8b", "llama3-gradient:70b", "llama3.1", "llama3.1:8b", "llama3.1:70b", "llama3.1:405b", "llava", "llava:7b", "llava:13b", "llava:34b", "llava-llama3", "llava-llama3:8b", "llava-phi3", "llava-phi3:3.8b", "mistral", "mistral:7b", "mistral-large", "mistral-large:123b", "mistral-nemo", "mistral-nemo:12b", "mixtral", "mixtral:8x7b", "mixtral:8x22b", "moondream", "moondream:1.8b", "openhermes", "openhermes:v2.5", "phi3", "phi3:3.8b", "phi3:14b", "phi3.5", "phi3.5:3.8b", "qwen", "qwen:7b", "qwen:14b", "qwen:32b", "qwen:72b", "qwen:110b", "qwen2", "qwen2:0.5b", "qwen2:1.5b", "qwen2:7b", "qwen2:72b", "smollm", "smollm:135m", "smollm:360m", "smollm:1.7b"] as const - // ), - }, - openRouter: { - model: configString( - 'OpenRouter model to use.', - 'openai/gpt-4o' - ), - apikey: configString('OpenRouter API key.', ''), - }, - openAICompatible: { - endpoint: configString('The baseUrl (exluding /chat/completions).', 'http://127.0.0.1:11434/v1'), - model: configString('The name of the model to use.', 'gpt-4o'), - apikey: configString('Your API key.', ''), - }, - azure: { - // "void.azure.apiKey": { - // "type": "string", - // "description": "Azure API key." - // }, - // "void.azure.deploymentId": { - // "type": "string", - // "description": "Azure API deployment ID." - // }, - // "void.azure.resourceName": { - // "type": "string", - // "description": "Name of the Azure OpenAI resource. Either this or `baseURL` can be used. \nThe resource name is used in the assembled URL: `https://{resourceName}.openai.azure.com/openai/deployments/{modelId}{path}`" - // }, - // "void.azure.providerSettings": { - // "type": "object", - // "properties": { - // "baseURL": { - // "type": "string", - // "default": "https://${resourceName}.openai.azure.com/openai/deployments", - // "description": "Azure API base URL." - // }, - // "headers": { - // "type": "object", - // "description": "Custom headers to include in the requests." - // } - // } - // }, - }, - gemini: { - apikey: configString('Google API key.', ''), - model: configEnum( - 'Gemini model to use.', - 'gemini-1.5-flash', - [ - "gemini-1.5-flash", - "gemini-1.5-pro", - "gemini-1.5-flash-8b", - "gemini-1.0-pro" - ] as const - ), - }, -} +// }, +// anthropic: { +// apikey: configString('Anthropic API key.', ''), +// model: configEnum( +// "Anthropic model to use.", +// 'claude-3-5-sonnet-20240620', +// [ +// "claude-3-5-sonnet-20240620", +// "claude-3-opus-20240229", +// "claude-3-sonnet-20240229", +// "claude-3-haiku-20240307" +// ] as const, +// ), +// }, +// openAI: { +// apikey: configString('OpenAI API key.', ''), +// model: configEnum( +// 'OpenAI model to use.', +// 'gpt-4o', +// [ +// "o1-preview", +// "o1-mini", +// "gpt-4o", +// "gpt-4o-2024-05-13", +// "gpt-4o-2024-08-06", +// "gpt-4o-mini", +// "gpt-4o-mini-2024-07-18", +// "gpt-4-turbo", +// "gpt-4-turbo-2024-04-09", +// "gpt-4-turbo-preview", +// "gpt-4-0125-preview", +// "gpt-4-1106-preview", +// "gpt-4", +// "gpt-4-0613", +// "gpt-3.5-turbo-0125", +// "gpt-3.5-turbo", +// "gpt-3.5-turbo-1106" +// ] as const +// ), +// }, +// greptile: { +// apikey: configString('Greptile API key.', ''), +// githubPAT: configString('Github PAT that Greptile uses to access your repository', ''), +// remote: configEnum( +// 'Repo location', +// 'github', +// [ +// 'github', +// 'gitlab' +// ] as const +// ), +// repository: configString('Repository identifier in "owner/repository" format.', ''), +// branch: configString('Name of the branch to use.', 'main'), +// }, +// ollama: { +// endpoint: configString( +// 'The endpoint of your Ollama instance. Start Ollama by running `OLLAMA_ORIGINS="vscode-webview://*" ollama serve`.', +// 'http://127.0.0.1:11434' +// ), +// // TODO we should allow user to select model inside Void, but for now we'll just let them handle the Ollama setup on their own +// // model: configEnum( +// // 'Ollama model to use.', +// // 'llama3.1', +// // ["codegemma", "codegemma:2b", "codegemma:7b", "codellama", "codellama:7b", "codellama:13b", "codellama:34b", "codellama:70b", "codellama:code", "codellama:python", "command-r", "command-r:35b", "command-r-plus", "command-r-plus:104b", "deepseek-coder-v2", "deepseek-coder-v2:16b", "deepseek-coder-v2:236b", "falcon2", "falcon2:11b", "firefunction-v2", "firefunction-v2:70b", "gemma", "gemma:2b", "gemma:7b", "gemma2", "gemma2:2b", "gemma2:9b", "gemma2:27b", "llama2", "llama2:7b", "llama2:13b", "llama2:70b", "llama3", "llama3:8b", "llama3:70b", "llama3-chatqa", "llama3-chatqa:8b", "llama3-chatqa:70b", "llama3-gradient", "llama3-gradient:8b", "llama3-gradient:70b", "llama3.1", "llama3.1:8b", "llama3.1:70b", "llama3.1:405b", "llava", "llava:7b", "llava:13b", "llava:34b", "llava-llama3", "llava-llama3:8b", "llava-phi3", "llava-phi3:3.8b", "mistral", "mistral:7b", "mistral-large", "mistral-large:123b", "mistral-nemo", "mistral-nemo:12b", "mixtral", "mixtral:8x7b", "mixtral:8x22b", "moondream", "moondream:1.8b", "openhermes", "openhermes:v2.5", "phi3", "phi3:3.8b", "phi3:14b", "phi3.5", "phi3.5:3.8b", "qwen", "qwen:7b", "qwen:14b", "qwen:32b", "qwen:72b", "qwen:110b", "qwen2", "qwen2:0.5b", "qwen2:1.5b", "qwen2:7b", "qwen2:72b", "smollm", "smollm:135m", "smollm:360m", "smollm:1.7b"] as const +// // ), +// }, +// openRouter: { +// model: configString( +// 'OpenRouter model to use.', +// 'openai/gpt-4o' +// ), +// apikey: configString('OpenRouter API key.', ''), +// }, +// openAICompatible: { +// endpoint: configString('The baseUrl (exluding /chat/completions).', 'http://127.0.0.1:11434/v1'), +// model: configString('The name of the model to use.', 'gpt-4o'), +// apikey: configString('Your API key.', ''), +// }, +// azure: { +// // "void.azure.apiKey": { +// // "type": "string", +// // "description": "Azure API key." +// // }, +// // "void.azure.deploymentId": { +// // "type": "string", +// // "description": "Azure API deployment ID." +// // }, +// // "void.azure.resourceName": { +// // "type": "string", +// // "description": "Name of the Azure OpenAI resource. Either this or `baseURL` can be used. \nThe resource name is used in the assembled URL: `https://{resourceName}.openai.azure.com/openai/deployments/{modelId}{path}`" +// // }, +// // "void.azure.providerSettings": { +// // "type": "object", +// // "properties": { +// // "baseURL": { +// // "type": "string", +// // "default": "https://${resourceName}.openai.azure.com/openai/deployments", +// // "description": "Azure API base URL." +// // }, +// // "headers": { +// // "type": "object", +// // "description": "Custom headers to include in the requests." +// // } +// // } +// // }, +// }, +// gemini: { +// apikey: configString('Google API key.', ''), +// model: configEnum( +// 'Gemini model to use.', +// 'gemini-1.5-flash', +// [ +// "gemini-1.5-flash", +// "gemini-1.5-pro", +// "gemini-1.5-flash-8b", +// "gemini-1.0-pro" +// ] as const +// ), +// }, +// } -// this is the type that comes with metadata like desc, default val, etc -type VoidConfigInfo = typeof voidConfigInfo -export type VoidConfigField = keyof typeof voidConfigInfo // typeof configFields[number] +// // this is the type that comes with metadata like desc, default val, etc +// type VoidConfigInfo = typeof voidConfigInfo +// export type VoidConfigField = keyof typeof voidConfigInfo // typeof configFields[number] -// this is the type that specifies the user's actual config -export type PartialVoidConfig = { - [K in keyof typeof voidConfigInfo]?: { - [P in keyof typeof voidConfigInfo[K]]?: typeof voidConfigInfo[K][P]['defaultVal'] - } -} +// // this is the type that specifies the user's actual config +// export type PartialVoidConfig = { +// [K in keyof typeof voidConfigInfo]?: { +// [P in keyof typeof voidConfigInfo[K]]?: typeof voidConfigInfo[K][P]['defaultVal'] +// } +// } -export type VoidConfig = { - [K in keyof typeof voidConfigInfo]: { - [P in keyof typeof voidConfigInfo[K]]: typeof voidConfigInfo[K][P]['defaultVal'] - } -} +// export type VoidConfig = { +// [K in keyof typeof voidConfigInfo]: { +// [P in keyof typeof voidConfigInfo[K]]: typeof voidConfigInfo[K][P]['defaultVal'] +// } +// } -export const getVoidConfigFromPartial = (partialVoidConfig: PartialVoidConfig): VoidConfig => { - const config = {} as PartialVoidConfig - for (let field of [...configFields, 'default'] as const) { - config[field] = {} - for (let prop in voidConfigInfo[field]) { - config[field][prop] = partialVoidConfig[field]?.[prop]?.trim() || voidConfigInfo[field][prop].defaultVal - } - } - return config as VoidConfig -} +// export const getVoidConfigFromPartial = (partialVoidConfig: PartialVoidConfig): VoidConfig => { +// const config = {} as PartialVoidConfig +// for (let field of [...configFields, 'default'] as const) { +// config[field] = {} +// for (let prop in voidConfigInfo[field]) { +// config[field][prop] = partialVoidConfig[field]?.[prop]?.trim() || voidConfigInfo[field][prop].defaultVal +// } +// } +// return config as VoidConfig +// } -const defaultVoidConfig: VoidConfig = getVoidConfigFromPartial({}) +// const defaultVoidConfig: VoidConfig = getVoidConfigFromPartial({}) -// const [stateRef, setState] = useInstantState(initVal) -// setState instantly changes the value of stateRef instead of having to wait until the next render -const useInstantState = (initVal: T) => { - const stateRef = useRef(initVal) - const [_, setS] = useState(initVal) - const setState = useCallback((newVal: T) => { - setS(newVal); - stateRef.current = newVal; - }, []) - return [stateRef as React.RefObject, setState] as const // make s.current readonly - setState handles all changes -} +// // const [stateRef, setState] = useInstantState(initVal) +// // setState instantly changes the value of stateRef instead of having to wait until the next render +// const useInstantState = (initVal: T) => { +// const stateRef = useRef(initVal) +// const [_, setS] = useState(initVal) +// const setState = useCallback((newVal: T) => { +// setS(newVal); +// stateRef.current = newVal; +// }, []) +// return [stateRef as React.RefObject, setState] as const // make s.current readonly - setState handles all changes +// } -type SetConfigParamType = (field: K, param: keyof VoidConfigInfo[K], newVal: string) => void +// type SetConfigParamType = (field: K, param: keyof VoidConfigInfo[K], newVal: string) => void -type ConfigValueType = { - voidConfig: VoidConfig, - voidConfigInfo: VoidConfigInfo, - partialVoidConfig: PartialVoidConfig, - setConfigParam: SetConfigParamType -} +// type ConfigValueType = { +// voidConfig: VoidConfig, +// voidConfigInfo: VoidConfigInfo, +// partialVoidConfig: PartialVoidConfig, +// setConfigParam: SetConfigParamType +// } -const ConfigContext = createContext(undefined as unknown as ConfigValueType) +// const ConfigContext = createContext(undefined as unknown as ConfigValueType) -export function ConfigProvider({ children }: { children: ReactNode }) { - const [partialVoidConfig, setPartialVoidConfig] = useInstantState({}) // the user's selections - const [voidConfig, setVoidConfig] = useState(defaultVoidConfig) +// export function ConfigProvider({ children }: { children: ReactNode }) { +// const [partialVoidConfig, setPartialVoidConfig] = useInstantState({}) // the user's selections +// const [voidConfig, setVoidConfig] = useState(defaultVoidConfig) - // get the config on mount - useEffect(() => { - getVSCodeAPI().postMessage({ type: 'getPartialVoidConfig' }) - awaitVSCodeResponse('partialVoidConfig').then((m) => { - setPartialVoidConfig(m.partialVoidConfig) - const newFullConfig = getVoidConfigFromPartial(m.partialVoidConfig) - setVoidConfig(newFullConfig) - }) - }, [setPartialVoidConfig]) +// // get the config on mount +// useEffect(() => { +// getVSCodeAPI().postMessage({ type: 'getPartialVoidConfig' }) +// awaitVSCodeResponse('partialVoidConfig').then((m) => { +// setPartialVoidConfig(m.partialVoidConfig) +// const newFullConfig = getVoidConfigFromPartial(m.partialVoidConfig) +// setVoidConfig(newFullConfig) +// }) +// }, [setPartialVoidConfig]) - // return the provider - return ( { - const newPartialConfig: PartialVoidConfig = { - ...partialVoidConfig.current, - [field]: { - ...partialVoidConfig.current?.[field], - [param]: newVal - } - } - setPartialVoidConfig(newPartialConfig) - const newFullConfig = getVoidConfigFromPartial(newPartialConfig) - setVoidConfig(newFullConfig) - getVSCodeAPI().postMessage({ type: 'persistPartialVoidConfig', partialVoidConfig: newPartialConfig }) - } - }} - > - {children} - - ) -} +// // return the provider +// return ( { +// const newPartialConfig: PartialVoidConfig = { +// ...partialVoidConfig.current, +// [field]: { +// ...partialVoidConfig.current?.[field], +// [param]: newVal +// } +// } +// setPartialVoidConfig(newPartialConfig) +// const newFullConfig = getVoidConfigFromPartial(newPartialConfig) +// setVoidConfig(newFullConfig) +// getVSCodeAPI().postMessage({ type: 'persistPartialVoidConfig', partialVoidConfig: newPartialConfig }) +// } +// }} +// > +// {children} +// +// ) +// } -export function useVoidConfig(): ConfigValueType { - const context = useContext(ConfigContext) - if (context === undefined) { - throw new Error("useVoidConfig missing Provider") - } - return context -} +// export function useVoidConfig(): ConfigValueType { +// const context = useContext(ConfigContext) +// if (context === undefined) { +// throw new Error("useVoidConfig missing Provider") +// } +// return context +// } diff --git a/src/vs/workbench/contrib/void/browser/sidebar/contextForProps.tsx b/src/vs/workbench/contrib/void/browser/sidebar/contextForProps.tsx deleted file mode 100644 index 6775fcb1..00000000 --- a/src/vs/workbench/contrib/void/browser/sidebar/contextForProps.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" - -const PropsContext = createContext(undefined as unknown as any) - -// provider for whatever came in data-void-props -export function PropsProvider({ children, rootElement }: { children: ReactNode, rootElement: HTMLElement }) { - - const [props, setProps] = useState(null) - - // update props when rootElement changes - useEffect(() => { - let props = rootElement.getAttribute("data-void-props") - let propsObj: object | null = null - if (props !== null) { - propsObj = JSON.parse(decodeURIComponent(props)) - } - setProps(propsObj) - }, [rootElement]) - - return ( - - {children} - - ) -} - -export function useVoidProps(): T | null { - // context is the "value" from above - const context: T | null | undefined = useContext(PropsContext) - // only undefined if has no provider - if (context === undefined) { - throw new Error("useVoidProps missing Provider") - } - return context -} - diff --git a/src/vs/workbench/contrib/void/browser/sidebar/contextForThreads.tsx b/src/vs/workbench/contrib/void/browser/sidebar/contextForThreads.tsx index d2ab97be..c040be1c 100644 --- a/src/vs/workbench/contrib/void/browser/sidebar/contextForThreads.tsx +++ b/src/vs/workbench/contrib/void/browser/sidebar/contextForThreads.tsx @@ -1,106 +1,106 @@ -import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" -import { ChatMessage, ChatThreads } from "../../common/shared_types" -import { awaitVSCodeResponse, getVSCodeAPI } from "./getVscodeApi" +// import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" +// import { ChatMessage, ChatThreads } from "../../common/shared_types" +// import { awaitVSCodeResponse, getVSCodeAPI } from "./getVscodeApi" -// a "thread" means a chat message history -type ConfigForThreadsValueType = { - readonly getAllThreads: () => ChatThreads; - readonly getCurrentThread: () => ChatThreads[string] | null; - addMessageToHistory: (message: ChatMessage) => void; - switchToThread: (threadId: string) => void; - startNewThread: () => void; -} +// // a "thread" means a chat message history +// type ConfigForThreadsValueType = { +// readonly getAllThreads: () => ChatThreads; +// readonly getCurrentThread: () => ChatThreads[string] | null; +// addMessageToHistory: (message: ChatMessage) => void; +// switchToThread: (threadId: string) => void; +// startNewThread: () => void; +// } -const ThreadsContext = createContext(undefined as unknown as ConfigForThreadsValueType) +// const ThreadsContext = createContext(undefined as unknown as ConfigForThreadsValueType) -const createNewThread = () => { - const now = new Date().toISOString() - return { - id: new Date().getTime().toString(), - createdAt: now, - lastModified: now, - messages: [], - } -} +// const createNewThread = () => { +// const now = new Date().toISOString() +// return { +// id: new Date().getTime().toString(), +// createdAt: now, +// lastModified: now, +// messages: [], +// } +// } -// const [stateRef, setState] = useInstantState(initVal) -// setState instantly changes the value of stateRef instead of having to wait until the next render -const useInstantState = (initVal: T) => { - const stateRef = useRef(initVal) - const [_, setS] = useState(initVal) - const setState = useCallback((newVal: T) => { - setS(newVal); - stateRef.current = newVal; - }, []) - return [stateRef as React.RefObject, setState] as const // make s.current readonly - setState handles all changes -} +// // const [stateRef, setState] = useInstantState(initVal) +// // setState instantly changes the value of stateRef instead of having to wait until the next render +// const useInstantState = (initVal: T) => { +// const stateRef = useRef(initVal) +// const [_, setS] = useState(initVal) +// const setState = useCallback((newVal: T) => { +// setS(newVal); +// stateRef.current = newVal; +// }, []) +// return [stateRef as React.RefObject, setState] as const // make s.current readonly - setState handles all changes +// } -export function ThreadsProvider({ children }: { children: ReactNode }) { - const [allThreadsRef, setAllThreads] = useInstantState({}) - const [currentThreadIdRef, setCurrentThreadId] = useInstantState(null) +// export function ThreadsProvider({ children }: { children: ReactNode }) { +// const [allThreadsRef, setAllThreads] = useInstantState({}) +// const [currentThreadIdRef, setCurrentThreadId] = useInstantState(null) - // this loads allThreads in on mount - useEffect(() => { - getVSCodeAPI().postMessage({ type: 'getAllThreads' }) - awaitVSCodeResponse('allThreads') - .then(response => { - setAllThreads(response.threads) - }) - }, [setAllThreads]) +// // this loads allThreads in on mount +// useEffect(() => { +// getVSCodeAPI().postMessage({ type: 'getAllThreads' }) +// awaitVSCodeResponse('allThreads') +// .then(response => { +// setAllThreads(response.threads) +// }) +// }, [setAllThreads]) - return ( - allThreadsRef.current ?? {}, - getCurrentThread: () => currentThreadIdRef.current ? allThreadsRef.current?.[currentThreadIdRef.current] ?? null : null, - addMessageToHistory: (message: ChatMessage) => { - let currentThread: ChatThreads[string] - if (!(currentThreadIdRef.current === null || allThreadsRef.current === null)) { - currentThread = allThreadsRef.current[currentThreadIdRef.current] - } - else { - currentThread = createNewThread() - setCurrentThreadId(currentThread.id) - } +// return ( +// allThreadsRef.current ?? {}, +// getCurrentThread: () => currentThreadIdRef.current ? allThreadsRef.current?.[currentThreadIdRef.current] ?? null : null, +// addMessageToHistory: (message: ChatMessage) => { +// let currentThread: ChatThreads[string] +// if (!(currentThreadIdRef.current === null || allThreadsRef.current === null)) { +// currentThread = allThreadsRef.current[currentThreadIdRef.current] +// } +// else { +// currentThread = createNewThread() +// setCurrentThreadId(currentThread.id) +// } - setAllThreads({ - ...allThreadsRef.current, - [currentThread.id]: { - ...currentThread, - lastModified: new Date().toISOString(), - messages: [...currentThread.messages, message], - } - }) +// setAllThreads({ +// ...allThreadsRef.current, +// [currentThread.id]: { +// ...currentThread, +// lastModified: new Date().toISOString(), +// messages: [...currentThread.messages, message], +// } +// }) - getVSCodeAPI().postMessage({ type: "persistThread", thread: currentThread }) - }, - switchToThread: (threadId: string) => { - setCurrentThreadId(threadId); - }, - startNewThread: () => { - const newThread = createNewThread() - setAllThreads({ - ...allThreadsRef.current, - [newThread.id]: newThread - }) - setCurrentThreadId(newThread.id) - }, - }} - > - {children} - - ) -} +// getVSCodeAPI().postMessage({ type: "persistThread", thread: currentThread }) +// }, +// switchToThread: (threadId: string) => { +// setCurrentThreadId(threadId); +// }, +// startNewThread: () => { +// const newThread = createNewThread() +// setAllThreads({ +// ...allThreadsRef.current, +// [newThread.id]: newThread +// }) +// setCurrentThreadId(newThread.id) +// }, +// }} +// > +// {children} +// +// ) +// } -export function useThreads(): ConfigForThreadsValueType { - const context = useContext(ThreadsContext) - if (context === undefined) { - throw new Error("useThreads missing Provider") - } - return context -} +// export function useThreads(): ConfigForThreadsValueType { +// const context = useContext(ThreadsContext) +// if (context === undefined) { +// throw new Error("useThreads missing Provider") +// } +// return context +// } diff --git a/src/vs/workbench/contrib/void/browser/sidebar/index.tsx b/src/vs/workbench/contrib/void/browser/sidebar/index.tsx deleted file mode 100644 index 966a0a77..00000000 --- a/src/vs/workbench/contrib/void/browser/sidebar/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -// import React from "react" -// import Sidebar from "./Sidebar" -// import { mount } from "../util/mount" - -// this is the entry point that mounts the sidebar -mount() - diff --git a/src/vs/workbench/contrib/void/browser/util/mount.tsx b/src/vs/workbench/contrib/void/browser/util/mount.tsx new file mode 100644 index 00000000..4962aa88 --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/util/mount.tsx @@ -0,0 +1,61 @@ +// import React, { useEffect } from "react"; +// import * as ReactDOM from "react-dom/client" +// import { initPosthog, identifyUser } from "./posthog"; + +// const ListenersAndTracking = () => { +// // initialize posthog +// useEffect(() => { +// initPosthog() +// }, []) + +// // // when we get the deviceid, identify the user +// // useEffect(() => { +// // getVSCodeAPI().postMessage({ type: 'getDeviceId' }); +// // awaitVSCodeResponse('deviceId').then((m => { +// // identifyUser(m.deviceId) +// // })) +// // }, []) + +// // // Receive messages from the VSCode extension +// // useEffect(() => { +// // const listener = (event: MessageEvent) => { +// // const m = event.data as MessageToSidebar; +// // onMessageFromVSCode(m) +// // } +// // window.addEventListener('message', listener); +// // return () => window.removeEventListener('message', listener) +// // }, []) + +// return null +// } + + + + +// export const mount = (children: React.ReactNode) => { + +// if (typeof document === "undefined") { +// console.error("index.tsx error: document was undefined") +// return +// } + +// // mount the sidebar on the id="root" element +// const rootElement = document.getElementById("root")! +// // console.log("Void root Element:", rootElement) + +// const content = (<> +// + +// +// +// +// {children} +// +// +// +// ) + +// const root = ReactDOM.createRoot(rootElement) +// root.render(content); + +// } diff --git a/src/vs/workbench/contrib/void/browser/util/shared_types.ts b/src/vs/workbench/contrib/void/browser/util/shared_types.ts index 9fc6f820..8b5132c3 100644 --- a/src/vs/workbench/contrib/void/browser/util/shared_types.ts +++ b/src/vs/workbench/contrib/void/browser/util/shared_types.ts @@ -2,9 +2,9 @@ import * as vscode from 'vscode'; import { PartialVoidConfig } from '../webviews/common/contextForConfig' -type CodeSelection = { selectionStr: string, filePath: vscode.Uri } +// type CodeSelection = { selectionStr: string, filePath: vscode.Uri } -type File = { filepath: vscode.Uri, content: string } +// type File = { filepath: vscode.Uri, content: string } // an area that is currently being diffed type DiffArea = { @@ -57,33 +57,33 @@ type MessageFromSidebar = ( ) -type ChatThreads = { - [id: string]: { - id: string; // store the id here too - createdAt: string; // ISO string - lastModified: string; // ISO string - messages: ChatMessage[]; - } -} +// type ChatThreads = { +// [id: string]: { +// id: string; // store the id here too +// createdAt: string; // ISO string +// lastModified: string; // ISO string +// messages: ChatMessage[]; +// } +// } -type ChatMessage = - | { - role: "user"; - content: string; // content sent to the llm - displayContent: string; // content displayed to user - selection: CodeSelection | null; // the user's selection - files: vscode.Uri[]; // the files sent in the message - } - | { - role: "assistant"; - content: string; // content received from LLM - displayContent: string | undefined; // content displayed to user (this is the same as content for now) - } - | { - role: "system"; - content: string; - displayContent?: undefined; - } +// type ChatMessage = +// | { +// role: "user"; +// content: string; // content sent to the llm +// displayContent: string; // content displayed to user +// selection: CodeSelection | null; // the user's selection +// files: vscode.Uri[]; // the files sent in the message +// } +// | { +// role: "assistant"; +// content: string; // content received from LLM +// displayContent: string | undefined; // content displayed to user (this is the same as content for now) +// } +// | { +// role: "system"; +// content: string; +// displayContent?: undefined; +// } export { BaseDiff, Diff, diff --git a/src/vs/workbench/contrib/void/browser/void.contribution.ts b/src/vs/workbench/contrib/void/browser/void.contribution.ts index 54e870c0..430f269d 100644 --- a/src/vs/workbench/contrib/void/browser/void.contribution.ts +++ b/src/vs/workbench/contrib/void/browser/void.contribution.ts @@ -1,3 +1,11 @@ -import './registerViewPane.js' +// register Settings +import './registerSettings.js' +// register Sidebar chat +import './registerSidebar.js' +// register Posthog metrics +import './registerMetrics.js' + +// register Thread History +import './registerThreadsHistory.js' diff --git a/src/vs/workbench/contrib/void/browser/voidViewPane.ts b/src/vs/workbench/contrib/void/browser/voidViewPane.ts deleted file mode 100644 index 1bbf86e1..00000000 --- a/src/vs/workbench/contrib/void/browser/voidViewPane.ts +++ /dev/null @@ -1,56 +0,0 @@ - - -import * as dom from '../../../../base/browser/dom.js'; - -import { ViewPane } from '../../../browser/parts/views/viewPane.js'; - -// import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -// import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -// import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -// import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -// import { IViewPaneOptions, } from 'vs/workbench/browser/parts/views/viewPane'; -// import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -// import { IOpenerService } from 'vs/platform/opener/common/opener'; -// import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -// import { IThemeService } from 'vs/platform/theme/common/themeService'; -// import { IViewDescriptorService } from 'vs/workbench/common/views'; -// import { IHoverService } from 'vs/platform/hover/browser/hover'; - -// import { useState } from './void-imports/react.js'; -// const x = useState(); - -export class VoidViewPane extends ViewPane { - - // constructor( - // options: IViewPaneOptions, - // @IInstantiationService instantiationService: IInstantiationService, - // @IViewDescriptorService viewDescriptorService: IViewDescriptorService, - // @IConfigurationService configurationService: IConfigurationService, - // @IContextKeyService contextKeyService: IContextKeyService, - // @IThemeService themeService: IThemeService, - // @IContextMenuService contextMenuService: IContextMenuService, - // @IKeybindingService keybindingService: IKeybindingService, - // @IOpenerService openerService: IOpenerService, - // @ITelemetryService telemetryService: ITelemetryService, - // @IHoverService hoverService: IHoverService, - // ) { - // super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService); - // } - - - - protected override renderBody(parent: HTMLElement): void { - super.renderBody(parent); - - const container = dom.append(parent, dom.$('.search-view')); - container.textContent = 'Hello Void!'; - - console.log('Void container', container); - - - } -} - -// register a singleton service that mounts the ViewPane here - - diff --git a/void-imports/index.ts b/void-imports/index.ts index b8f97c95..b72cc53d 100755 --- a/void-imports/index.ts +++ b/void-imports/index.ts @@ -2,7 +2,7 @@ import * as fs from 'fs' import * as path from 'path' import * as tsup from 'tsup' -const buildFiles = (imports: string[], to_be_built_folder: string) => { +const createFiles = (imports: string[], to_be_built_folder: string) => { for (const importName of imports) { const content = `\ export * from '${importName}'; @@ -43,10 +43,11 @@ const compileFiles = async (imports: string[], to_be_built_folder: string, outDi const to_be_built_folder = 'to_be_built' -fs.rmSync(to_be_built_folder, { recursive: true, force: true }); +// const imports = ['openai', '@anthropic-ai/sdk', 'react', 'react-dom'] +const imports = ['sendLLMMessage'] -const imports = ['openai', '@anthropic-ai/sdk', 'react', 'react-dom'] -buildFiles(imports, to_be_built_folder) +// fs.rmSync(to_be_built_folder, { recursive: true, force: true }); +// createFiles(imports, to_be_built_folder) const OUT_DIR = '../src/vs/workbench/contrib/void/browser/void-imports' compileFiles(imports, to_be_built_folder, OUT_DIR) diff --git a/void-imports/package-lock.json b/void-imports/package-lock.json new file mode 100644 index 00000000..2ddf6f9c --- /dev/null +++ b/void-imports/package-lock.json @@ -0,0 +1,817 @@ +{ + "name": "void-imports", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "void-imports", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@anthropic-ai/sdk": "^0.32.1", + "@google/generative-ai": "^0.21.0", + "ollama": "^0.5.9", + "openai": "^4.71.1" + }, + "devDependencies": { + "tsx": "^4.19.2" + } + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.32.1.tgz", + "integrity": "sha512-U9JwTrDvdQ9iWuABVsMLj8nJVwAyQz6QXvgLsVhryhCEPkLsbcP/MXxm+jYcAwLoV8ESbaTTjnD4kuAFa+Hyjg==", + "license": "MIT", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@google/generative-ai": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.21.0.tgz", + "integrity": "sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@types/node": { + "version": "18.19.64", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", + "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/ollama": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.9.tgz", + "integrity": "sha512-F/KZuDRC+ZsVCuMvcOYuQ6zj42/idzCkkuknGyyGVmNStMZ/sU3jQpvhnl4SyC0+zBzLiKNZJnJeuPFuieWZvQ==", + "license": "MIT", + "dependencies": { + "whatwg-fetch": "^3.6.20" + } + }, + "node_modules/openai": { + "version": "4.71.1", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.71.1.tgz", + "integrity": "sha512-C6JNMaQ1eijM0lrjiRUL3MgThVP5RdwNAghpbJFdW0t11LzmyqON8Eh8MuUuEZ+CeD6bgYl2Fkn2BoptVxv9Ug==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tsx": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/void-imports/package.json b/void-imports/package.json new file mode 100644 index 00000000..66c07bcd --- /dev/null +++ b/void-imports/package.json @@ -0,0 +1,19 @@ +{ + "name": "void-imports", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "build": "tdx index.ts" + }, + "author": "", + "description": "", + "dependencies": { + "@anthropic-ai/sdk": "^0.32.1", + "@google/generative-ai": "^0.21.0", + "ollama": "^0.5.9", + "openai": "^4.71.1" + }, + "devDependencies": { + "tsx": "^4.19.2" + } +} diff --git a/src/vs/workbench/contrib/void/browser/util/sendLLMMessage.ts b/void-imports/sendLLMMessage.ts similarity index 96% rename from src/vs/workbench/contrib/void/browser/util/sendLLMMessage.ts rename to void-imports/sendLLMMessage.ts index d079f3ff..42e543b8 100644 --- a/src/vs/workbench/contrib/void/browser/util/sendLLMMessage.ts +++ b/void-imports/sendLLMMessage.ts @@ -2,9 +2,11 @@ import Anthropic from '@anthropic-ai/sdk'; import OpenAI from 'openai'; import { Ollama } from 'ollama/browser' import { Content, GoogleGenerativeAI, GoogleGenerativeAIError, GoogleGenerativeAIFetchError } from '@google/generative-ai'; -import { VoidConfig } from '../webviews/common/contextForConfig' -import { captureEvent } from '../webviews/common/posthog'; -import { ChatMessage } from './shared_types'; +// import { VoidConfig } from '../webviews/common/contextForConfig' +// import { captureEvent } from '../webviews/common/posthog'; +// import { ChatMessage } from './shared_types'; + +type VoidConfig = any export type AbortRef = { current: (() => void) | null } @@ -324,13 +326,13 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ // only captures number of messages and message "shape", no actual code, instructions, prompts, etc const captureChatEvent = (eventId: string, extras?: object) => { - captureEvent(eventId, { - whichApi: voidConfig.default['whichApi'], - numMessages: messages?.length, - messagesShape: messages?.map(msg => ({ role: msg.role, length: msg.content.length })), - version: '2024-11-02', - ...extras, - }) + // captureEvent(eventId, { + // whichApi: voidConfig.default['whichApi'], + // numMessages: messages?.length, + // messagesShape: messages?.map(msg => ({ role: msg.role, length: msg.content.length })), + // version: '2024-11-02', + // ...extras, + // }) } const submit_time = new Date() diff --git a/void-imports/tsconfig.json b/void-imports/tsconfig.json new file mode 100644 index 00000000..7173d1de --- /dev/null +++ b/void-imports/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "NodeNext", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["to_be_built/**/*"], + "exclude": ["node_modules"] +}