diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 8f4a62ad..72a5c2ce 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -121,8 +121,7 @@ import { normalizeNFC } from '../../base/common/normalization.js'; import { ICSSDevelopmentService, CSSDevelopmentService } from '../../platform/cssDev/node/cssDevService.js'; import { ExtensionSignatureVerificationService, IExtensionSignatureVerificationService } from '../../platform/extensionManagement/node/extensionSignatureVerificationService.js'; -import { ISendLLMMessageService } from '../../platform/void/common/sendLLMMessage.js'; -import { SendLLMMessageService } from '../../platform/void/electron-main/sendLLMMessage.js'; +import { LLMMessageChannel } from '../../platform/void/electron-main/LLMMessageChannel.js'; /** * The main VS Code application. There will only ever be one instance, @@ -1011,9 +1010,6 @@ export class CodeApplication extends Disposable { break; } - // Void - services.set(ISendLLMMessageService, new SyncDescriptor(SendLLMMessageService)); - // Windows services.set(IWindowsMainService, new SyncDescriptor(WindowsMainService, [machineId, sqmId, devDeviceId, this.userEnv], false)); services.set(IAuxiliaryWindowsMainService, new SyncDescriptor(AuxiliaryWindowsMainService, undefined, false)); @@ -1197,10 +1193,6 @@ export class CodeApplication extends Disposable { const keyboardLayoutChannel = ProxyChannel.fromService(accessor.get(IKeyboardLayoutMainService), disposables); mainProcessElectronServer.registerChannel('keyboardLayout', keyboardLayoutChannel); - // Void - const sendLLMMessageChannel = ProxyChannel.fromService(accessor.get(ISendLLMMessageService), disposables); - mainProcessElectronServer.registerChannel('void-channel-sendLLMMessage', sendLLMMessageChannel); - // Native host (main & shared process) this.nativeHostMainService = accessor.get(INativeHostMainService); const nativeHostChannel = ProxyChannel.fromService(this.nativeHostMainService, disposables); @@ -1245,6 +1237,11 @@ export class CodeApplication extends Disposable { mainProcessElectronServer.registerChannel('logger', loggerChannel); sharedProcessClient.then(client => client.registerChannel('logger', loggerChannel)); + // Void + // const sendLLMMessageChannel = ProxyChannel.fromService(accessor.get(ISendLLMMessageService), disposables); + const sendLLMMessageChannel = new LLMMessageChannel(); + mainProcessElectronServer.registerChannel('void-channel-sendLLMMessage', sendLLMMessageChannel); + // Extension Host Debug Broadcasting const electronExtensionHostDebugBroadcastChannel = new ElectronExtensionHostDebugBroadcastChannel(accessor.get(IWindowsMainService)); mainProcessElectronServer.registerChannel('extensionhostdebugservice', electronExtensionHostDebugBroadcastChannel); diff --git a/src/vs/platform/void/browser/sendLLMMessage.ts b/src/vs/platform/void/browser/sendLLMMessage.ts index 14824b36..65e68e27 100644 --- a/src/vs/platform/void/browser/sendLLMMessage.ts +++ b/src/vs/platform/void/browser/sendLLMMessage.ts @@ -3,30 +3,68 @@ * Void Editor additions licensed under the AGPLv3 License. *--------------------------------------------------------------------------------------------*/ -import { ISendLLMMessageService, SendLLMMessageParams } from '../common/sendLLMMessage.js'; -import { ProxyChannel } from '../../../base/parts/ipc/common/ipc.js'; +import { LLMMessageOnTextEvent, OnErrorEvent, OnFinalMessageEvent, SendLLMMessageParams, SendLLMMessageProxyParams } from '../common/sendLLMTypes.js'; +import { IChannel } from '../../../base/parts/ipc/common/ipc.js'; import { IMainProcessService } from '../../ipc/common/mainProcessService.js'; import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js'; +import { generateUuid } from '../../../base/common/uuid.js'; +import { createDecorator } from '../../instantiation/common/instantiation.js'; +import { Event } from '../../../base/common/event.js'; // BROWSER IMPLEMENTATION OF SENDLLMMESSAGE -// Uses a proxy to the actual Node implementation of SendLLMMessageService +export const ISendLLMMessageService = createDecorator('sendLLMMessageService'); + +// defines an interface that node/ creates and browser/ uses +export interface ISendLLMMessageService { + readonly _serviceBrand: undefined; + sendLLMMessage: (params: SendLLMMessageParams) => void; +} + export class SendLLMMessageService implements ISendLLMMessageService { static readonly ID = 'void.contrib.browserSendLLMMessageService'; readonly _serviceBrand: undefined; - - readonly _proxySendLLMService: ISendLLMMessageService + readonly channel: IChannel; constructor( - @IMainProcessService mainProcessService: IMainProcessService + @IMainProcessService mainProcessService: IMainProcessService // used as a renderer (only usable on client side) ) { - this._proxySendLLMService = ProxyChannel.toService(mainProcessService.getChannel('void-channel-sendLLMMessage')); + + this.channel = mainProcessService.getChannel('void-channel-sendLLMMessage') + // const service = ProxyChannel.toService(mainProcessService.getChannel('void-channel-sendLLMMessage')); // lets you call it like a service, not needed here } sendLLMMessage(params: SendLLMMessageParams) { - this._proxySendLLMService.sendLLMMessage(params); + const requestId_ = generateUuid(); + const { onText, onFinalMessage, onError, ...proxyParams } = params; + + // listen for listenerName='onText' | 'onFinalMessage' | 'onError', and call the original function on it + + const onTextEvent: Event = this.channel.listen('onText') + onTextEvent(e => { + console.log('event TEXT EVENT!!!:', JSON.stringify(e, null, 5)) + if (requestId_ !== e.requestId) return; + onText(e) + }) + + const onFinalMessageEvent: Event = this.channel.listen('onFinalMessage') + onFinalMessageEvent(e => { + console.log('FINAL MESSAGE EVENT!!!:', JSON.stringify(e, null, 5)) + if (requestId_ !== e.requestId) return; + onFinalMessage(e) + }) + + const onErrorEvent: Event = this.channel.listen('onError') + onErrorEvent(e => { + console.log('ERROR EVENT!!!:', JSON.stringify(e, null, 5)) + if (requestId_ !== e.requestId) return; + onError(e) + }) + + // params will be stripped of all its functions + this.channel.call('sendLLMMessage', { ...proxyParams, requestId: requestId_ } satisfies SendLLMMessageProxyParams); } } diff --git a/src/vs/platform/void/common/sendLLMMessage.ts b/src/vs/platform/void/common/sendLLMMessage.ts deleted file mode 100644 index 3e154790..00000000 --- a/src/vs/platform/void/common/sendLLMMessage.ts +++ /dev/null @@ -1,43 +0,0 @@ -// void/common/sendLLMMessage.ts - -import { createDecorator } from '../../instantiation/common/instantiation.js'; -import { VoidConfig } from '../../../workbench/contrib/void/browser/registerConfig.js'; - - - -export type LLMMessageAbortRef = { current: (() => void) | null } - -export type LLMMessageOnText = (newText: string, fullText: string) => void - -export type OnFinalMessage = (input: string) => void - -export type LLMMessage = { - role: 'system' | 'user' | 'assistant'; - content: string; -} - -export type SendLLMMessageParams = { - messages: LLMMessage[]; - onText: LLMMessageOnText; - onFinalMessage: (fullText: string) => void; - onError: (error: Error | string) => void; - voidConfig: VoidConfig | null; - abortRef: LLMMessageAbortRef; - - logging: { - loggingName: string, - }; -} - - - -export const ISendLLMMessageService = createDecorator('sendLLMMessageService'); - -// defines an interface that node/ creates and browser/ uses -export interface ISendLLMMessageService { - readonly _serviceBrand: undefined; - - sendLLMMessage: (params: SendLLMMessageParams) => void; - -} - diff --git a/src/vs/platform/void/common/sendLLMTypes.ts b/src/vs/platform/void/common/sendLLMTypes.ts new file mode 100644 index 00000000..bbb163af --- /dev/null +++ b/src/vs/platform/void/common/sendLLMTypes.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Glass Devtools, Inc. All rights reserved. + * Void Editor additions licensed under the AGPLv3 License. + *--------------------------------------------------------------------------------------------*/ + +import { VoidConfig } from '../../../workbench/contrib/void/browser/registerConfig.js'; + +// ---------- definitions ---------- + +export type LLMMessageOnText = (p: { newText: string, fullText: string }) => void + +export type OnFinalMessage = (p: { fullText: string }) => void + +export type OnError = (p: { error: Error | string }) => void + +export type LLMMessageAbortRef = { current: (() => void) | null } + +export type LLMMessage = { + role: 'system' | 'user' | 'assistant'; + content: string; +} + +export type SendLLMMessageParams = { + onText: LLMMessageOnText; + onFinalMessage: OnFinalMessage; + onError: OnError; + + messages: LLMMessage[]; + voidConfig: VoidConfig | null; + abortRef: LLMMessageAbortRef; + + logging: { + loggingName: string, + }; +} + +// can't send functions across a proxy, use listeners instead +export const listenerNames = ['onText', 'onFinalMessage', 'onError'] as const +export type SendLLMMessageProxyParams = Omit & { requestId: string } + +export type LLMMessageOnTextEvent = Parameters[0] & { requestId: string } +export type OnFinalMessageEvent = Parameters[0] & { requestId: string } +export type OnErrorEvent = Parameters[0] & { requestId: string } diff --git a/src/vs/platform/void/electron-main/LLMMessageChannel.ts b/src/vs/platform/void/electron-main/LLMMessageChannel.ts new file mode 100644 index 00000000..3c4b0c8b --- /dev/null +++ b/src/vs/platform/void/electron-main/LLMMessageChannel.ts @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Glass Devtools, Inc. All rights reserved. + * Void Editor additions licensed under the AGPLv3 License. + *--------------------------------------------------------------------------------------------*/ + +// this channel is registered in `app.ts` +// code convention is to make a service responsible for this stuff, and not a channel, but this is simpler. +// you could create one instance in electron-main/my-service.ts and one in browser/my-service.ts (and define the interface IMyService in common/my-service.ts), but we just use a channel here +// registerSingleton(ISendLLMMessageService, SendLLMMessageService, InstantiationType.Delayed); + +import { IServerChannel } from '../../../base/parts/ipc/common/ipc.js'; +import { Emitter, Event } from '../../../base/common/event.js'; +import { sendLLMMessage } from '../../../workbench/contrib/void/browser/react/out/util/sendLLMMessage.js'; +import { listenerNames, LLMMessageOnTextEvent, OnErrorEvent, OnFinalMessageEvent, SendLLMMessageParams, SendLLMMessageProxyParams } from '../common/sendLLMTypes.js'; + +// NODE IMPLEMENTATION OF SENDLLMMESSAGE + +export class LLMMessageChannel implements IServerChannel { + private readonly _onText = new Emitter(); + readonly onText = this._onText.event; + + private readonly _onFinalMessage = new Emitter(); + readonly onFinalMessage = this._onFinalMessage.event; + + private readonly _onError = new Emitter(); + readonly onError = this._onError.event; + + constructor() { } + + // browser uses this + listen(_: unknown, event: typeof listenerNames[number]): Event { + console.log('event LISTENING!!!:', event) + if (event === 'onText') { + return this.onText; + } + else if (event === 'onFinalMessage') { + return this.onFinalMessage; + } + else if (event === 'onError') { + return this.onError; + } + else { + throw new Error(`Event not found: ${event}`); + } + } + + // both use this + async call(_: unknown, command: string, params: SendLLMMessageProxyParams): Promise { + + if (command !== 'sendLLMMessage') throw new Error(`Invalid call in sendLLMMessage channel: ${command}.\nArgs:\n${JSON.stringify(params, null, 5)}`); + + try { + const { requestId } = params; + const mainThreadParams: SendLLMMessageParams = { + ...params, + onText: ({ newText, fullText }) => { this._onText.fire({ requestId, newText, fullText }); }, + onFinalMessage: ({ fullText }) => { this._onFinalMessage.fire({ requestId, fullText }); }, + onError: ({ error }) => { this._onError.fire({ requestId, error }); }, + } + sendLLMMessage(mainThreadParams); + } + catch (e) { + console.log('sendLLM channel: call error', e) + } + } +} diff --git a/src/vs/platform/void/electron-main/sendLLMMessage.ts b/src/vs/platform/void/electron-main/sendLLMMessage.ts deleted file mode 100644 index de2c67fb..00000000 --- a/src/vs/platform/void/electron-main/sendLLMMessage.ts +++ /dev/null @@ -1,20 +0,0 @@ -// import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; -import { ISendLLMMessageService } from '../common/sendLLMMessage.js'; -import { sendLLMMessage } from '../../../workbench/contrib/void/browser/react/out/util/sendLLMMessage.js'; -// import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js'; -// import { ipcMain } from 'electron'; - -// NODE IMPLEMENTATION OF SENDLLMMESSAGE -export class SendLLMMessageService implements ISendLLMMessageService { - readonly _serviceBrand: undefined; - - async sendLLMMessage(data: any) { - console.log('NODE sendLLMMessage', data); - // ipcMain.emit('vscode:sendLLMMessage', data) - - return sendLLMMessage(data) - } -} - -// we don't need to register this, it's registered in app.ts: -// registerSingleton(ISendLLMMessageService, SendLLMMessageService, InstantiationType.Delayed); diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 1b18f93c..74049ef1 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -17,6 +17,7 @@ import { URI } from '../../../../../../../base/common/uri.js'; import { EndOfLinePreference } from '../../../../../../../editor/common/model.js'; import { IDisposable } from '../../../../../../../base/common/lifecycle.js'; import { ErrorDisplay } from '../util/ErrorDisplay.js'; +import { SendLLMMessageParams } from '../../../../../../../platform/void/common/sendLLMTypes.js'; // import { } from '@vscode/webview-ui-toolkit/react'; @@ -209,11 +210,12 @@ export const SidebarChat = () => { // send message to LLM - sendLLMMessageService.sendLLMMessage({ + + const object: SendLLMMessageParams = { logging: { loggingName: 'Chat' }, messages: [...(currentThread?.messages ?? []).map(m => ({ role: m.role, content: m.content })),], - onText: (newText, fullText) => setMessageStream(fullText), - onFinalMessage: (content) => { + onText: ({ newText, fullText }) => setMessageStream(fullText), + onFinalMessage: ({ fullText: content }) => { console.log('chat: running final message') // add assistant's message to chat history, and clear selection @@ -222,7 +224,7 @@ export const SidebarChat = () => { setMessageStream('') setIsLoading(false) }, - onError: (error) => { + onError: ({ error }) => { console.log('chat: running error') // add assistant's message to chat history, and clear selection @@ -237,7 +239,11 @@ export const SidebarChat = () => { }, voidConfig, abortRef: abortFnRef, - }) + } + + console.log('object!!!!!2', Object.keys(object)) + + sendLLMMessageService.sendLLMMessage(object) setIsLoading(true) diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/sendLLMMessage.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/sendLLMMessage.tsx index eb9a9cef..8dcf6769 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/sendLLMMessage.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/sendLLMMessage.tsx @@ -4,14 +4,14 @@ import { Ollama } from 'ollama/browser' import { Content, GoogleGenerativeAI, GoogleGenerativeAIFetchError } from '@google/generative-ai'; import { posthog } from 'posthog-js' import type { VoidConfig } from '../../../registerConfig.js'; -import type { LLMMessage, LLMMessageOnText, OnFinalMessage, } from '../../../../../../../platform/void/common/sendLLMMessage.js'; -import { SendLLMMessageParams } from '../../../../../../../platform/void/common/sendLLMMessage.js'; +import type { LLMMessage, LLMMessageOnText, OnError, OnFinalMessage, } from '../../../../../../../platform/void/common/sendLLMTypes.js'; +import { SendLLMMessageParams } from '../../../../../../../platform/void/common/sendLLMTypes.js'; type SendLLMMessageFnTypeInternal = (params: { messages: LLMMessage[]; onText: LLMMessageOnText; onFinalMessage: OnFinalMessage; - onError: (error: Error | string) => void; + onError: OnError; voidConfig: VoidConfig; _setAborter: (aborter: () => void) => void; @@ -54,23 +54,23 @@ const sendAnthropicMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFi // when receive text stream.on('text', (newText, fullText) => { - onText(newText, fullText) + onText({ newText, fullText }) }) // when we get the final message on this stream (or when error/fail) stream.on('finalMessage', (claude_response) => { // stringify the response's content const content = claude_response.content.map(c => c.type === 'text' ? c.text : c.type).join('\n'); - onFinalMessage(content) + onFinalMessage({ fullText: content }) }) stream.on('error', (error) => { // the most common error will be invalid API key (401), so we handle this with a nice message if (error instanceof Anthropic.APIError && error.status === 401) { - onError('Invalid API key.') + onError({ error: 'Invalid API key.' }) } else { - onError(error) + onError({ error }) } }) @@ -109,16 +109,16 @@ const sendGeminiMsg: SendLLMMessageFnTypeInternal = async ({ messages, onText, o for await (const chunk of response.stream) { const newText = chunk.text(); fullText += newText; - onText(newText, fullText); + onText({ newText, fullText }); } - onFinalMessage(fullText); + onFinalMessage({ fullText }); }) .catch((error) => { if (error instanceof GoogleGenerativeAIFetchError && error.status === 400) { - onError('Invalid API key.'); + onError({ error: 'Invalid API key.' }); } else { - onError(error); + onError({ error }); } }) } @@ -164,14 +164,14 @@ const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinal for await (const chunk of response) { const newText = chunk.choices[0]?.delta?.content || ''; fullText += newText; - onText(newText, fullText); + onText({ newText, fullText }); } - onFinalMessage(fullText); + onFinalMessage({ fullText }); }) // when error/fail - this catches errors of both .create() and .then(for await) .catch(error => { if (error instanceof OpenAI.APIError && error.status === 401) { - onError('Invalid API key.'); + onError({ error: 'Invalid API key.' }); } else { onError(error); @@ -199,9 +199,9 @@ export const sendOllamaMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, for await (const chunk of stream) { const newText = chunk.message.content; fullText += newText; - onText(newText, fullText); + onText({ newText, fullText }); } - onFinalMessage(fullText); + onFinalMessage({ fullText }); }) // when error/fail @@ -249,17 +249,17 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin // when receive text if (type === 'message') { fullText += message - onText(message, fullText) + onText({ newText: message, fullText }) } else if (type === 'sources') { const { filepath, linestart: _, lineend: _2 } = message as { filepath: string; linestart: number | null; lineend: number | null } fullText += filepath - onText(filepath, fullText) + onText({ newText: filepath, fullText }) } // type: 'status' with an empty 'message' means last message else if (type === 'status') { if (!message) { - onFinalMessage(fullText) + onFinalMessage({ fullText }) } } } @@ -307,23 +307,23 @@ export const sendLLMMessage = ({ let _setAborter = (fn: () => void) => { _aborter = fn } let _didAbort = false - const onText = (newText: string, fullText: string) => { + const onText: LLMMessageOnText = ({ newText, fullText }) => { if (_didAbort) return - onText_(newText, fullText) + onText_({ newText, fullText }) _fullTextSoFar = fullText } - const onFinalMessage = (fullText: string) => { + const onFinalMessage: OnFinalMessage = ({ fullText }) => { if (_didAbort) return captureChatEvent(`${loggingName} - Received Full Message`, { messageLength: fullText.length, duration: new Date().getMilliseconds() - submit_time.getMilliseconds() }) - onFinalMessage_(fullText) + onFinalMessage_({ fullText }) } - const onError = (error: Error | string) => { + const onError: OnError = ({ error }) => { console.error('sendLLMMessage onError:', error) if (_didAbort) return captureChatEvent(`${loggingName} - Error`, { error }) - onError_(error) + onError_({ error }) } const onAbort = () => { @@ -355,14 +355,14 @@ export const sendLLMMessage = ({ sendGreptileMsg({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter, }); break; default: - onError(`Error: whichApi was ${voidConfig.default.whichApi}, which is not recognized!`) + onError({ error: `Error: whichApi was ${voidConfig.default.whichApi}, which is not recognized!` }) break; } } - catch (e) { - if (e instanceof Error) { onError(e) } - else { onError(`Unexpected Error in sendLLMMessage: ${e}`); } + catch (error) { + if (error instanceof Error) { onError({ error }) } + else { onError({ error: `Unexpected Error in sendLLMMessage: ${error}` }); } ; (_aborter as any)?.() _didAbort = true } diff --git a/src/vs/workbench/contrib/void/browser/registerInlineDiffs.ts b/src/vs/workbench/contrib/void/browser/registerInlineDiffs.ts index b3885525..69d2482c 100644 --- a/src/vs/workbench/contrib/void/browser/registerInlineDiffs.ts +++ b/src/vs/workbench/contrib/void/browser/registerInlineDiffs.ts @@ -28,7 +28,8 @@ import { ILanguageService } from '../../../../editor/common/languages/language.j import * as dom from '../../../../base/browser/dom.js'; import { Widget } from '../../../../base/browser/ui/widget.js'; import { URI } from '../../../../base/common/uri.js'; -import { ISendLLMMessageService } from '../../../../platform/void/common/sendLLMMessage.js'; +import { SendLLMMessageParams } from '../../../../platform/void/common/sendLLMTypes.js'; +import { ISendLLMMessageService } from '../../../../platform/void/browser/sendLLMMessage.js'; // import { ISendLLMMessageService } from '../../../../platform/void/common/sendLLMMessage.js'; // import { sendLLMMessage } from './react/out/util/sendLLMMessage.js'; @@ -732,18 +733,19 @@ Please finish writing the new file by applying the diff to the original file. Re const abortRef = { current: null } as { current: null | (() => void) } await new Promise((resolve, reject) => { - this._sendLLMMessageService.sendLLMMessage({ + + const object: SendLLMMessageParams = { logging: { loggingName: 'streamChunk' }, messages: [ { role: 'system', content: writeFileWithDiffInstructions, }, // TODO include more context too { role: 'user', content: promptContent, } ], - onText: (newText: string, fullText: string) => { + onText: ({ newText, fullText }) => { this._writeDiffAreaLLMText(diffArea, fullText) this._refreshDiffsInURI(uri) }, - onFinalMessage: (fullText: string) => { + onFinalMessage: ({ fullText }) => { this._writeText(uri, fullText, { startLineNumber: diffArea.startLine, startColumn: 1, endLineNumber: diffArea.endLine, endColumn: Number.MAX_SAFE_INTEGER }, // 1-indexed ) @@ -760,7 +762,10 @@ Please finish writing the new file by applying the diff to the original file. Re }, voidConfig, abortRef, - }) + } + + console.log('object!!!!!', Object.keys(object)) + this._sendLLMMessageService.sendLLMMessage(object) }) onFinishEdit() diff --git a/src/vs/workbench/contrib/void/browser/registerSidebar.ts b/src/vs/workbench/contrib/void/browser/registerSidebar.ts index 104a2354..c3e6a768 100644 --- a/src/vs/workbench/contrib/void/browser/registerSidebar.ts +++ b/src/vs/workbench/contrib/void/browser/registerSidebar.ts @@ -47,7 +47,9 @@ import { IVoidConfigStateService } from './registerConfig.js'; import { IFileService } from '../../../../platform/files/common/files.js'; import { IInlineDiffsService } from './registerInlineDiffs.js'; import { IModelService } from '../../../../editor/common/services/model.js'; -import { ISendLLMMessageService } from '../../../../platform/void/common/sendLLMMessage.js'; +import { ISendLLMMessageService } from '../../../../platform/void/browser/sendLLMMessage.js'; + + // import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';