From e4107e125710ae5934e567ef5bc1f697b6a2fd6a Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sun, 24 Nov 2024 17:53:57 -0800 Subject: [PATCH] add server? --- .../windows/electron-main/windowImpl.ts | 16 +++ .../browser/react/src/util/ErrorDisplay.tsx | 2 +- .../react/src/util/mountFnGenerator.tsx | 2 - .../browser/react/src/util/sendLLMMessage.tsx | 43 ++----- .../void/browser/registerSendLLMMessage.ts | 110 ++++++++++++++++++ 5 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 src/vs/workbench/contrib/void/browser/registerSendLLMMessage.ts diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index ae108b99..0b426a16 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -741,8 +741,24 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { cb({ cancel: false, requestHeaders: Object.assign(details.requestHeaders, headers) }); }); + + + // // Void: send from https:// + // this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, async (details, cb) => { + // // const voidConfig = this.voidConfigStateService.state.voidConfig + // // const whichApi = voidConfig.default['whichApi'] + // const endpoint = 'http://127.' //string | undefined = voidConfig[whichApi as VoidConfigField].endpoint + + // if (endpoint && details.url.startsWith(endpoint)) { + // details.requestHeaders['Origin'] = 'https://app.voideditor.com' + // } + // cb({ cancel: false, requestHeaders: details.requestHeaders }); + // }); } + + + private marketplaceHeadersPromise: Promise | undefined; private getMarketplaceHeaders(): Promise { if (!this.marketplaceHeadersPromise) { diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx index db59bff6..8ff04ebf 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx @@ -19,7 +19,7 @@ const getErrorDetails = (error: unknown) => { // If fetch() fails, it gives an opaque message. We add extra details to the error. if ((error instanceof Error) && (error.cause + '').includes('TypeError: Failed to fetch')) { e = error as any - e.voidMessage = opaqueMessage + e['Void Team'] = opaqueMessage } else if (error instanceof Error) { e = error diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx index f075e9ac..6ab7a361 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx @@ -1,8 +1,6 @@ import React, { useEffect, useState } from 'react'; import * as ReactDOM from 'react-dom/client' import { ReactServicesType, VoidSidebarState } from '../../../registerSidebar.js'; -import { ConfigState } from '../../../registerConfig.js'; -import { ThreadsState } from '../../../registerThreads.js'; import { _registerServices } from './services.js'; 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 d40966ef..509dd534 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,26 +4,11 @@ import { Ollama } from 'ollama/browser' import { Content, GoogleGenerativeAI, GoogleGenerativeAIFetchError } from '@google/generative-ai'; import { posthog } from 'posthog-js' import type { VoidConfig } from '../../../registerConfig.js'; - -export type AbortRef = { current: (() => void) | null } - -export type OnText = (newText: string, fullText: string) => void - -export type OnFinalMessage = (input: string) => void - -export type LLMMessageAnthropic = { - role: 'user' | 'assistant'; - content: string; -} - -export type LLMMessage = { - role: 'system' | 'user' | 'assistant'; - content: string; -} +import type { LLMMessage, LLMMessageOnText, OnFinalMessage, SendLLMMessageFnType, } from '../../../registerSendLLMMessage.js'; type SendLLMMessageFnTypeInternal = (params: { messages: LLMMessage[]; - onText: OnText; + onText: LLMMessageOnText; onFinalMessage: OnFinalMessage; onError: (error: Error | string) => void; voidConfig: VoidConfig; @@ -31,18 +16,6 @@ type SendLLMMessageFnTypeInternal = (params: { _setAborter: (aborter: () => void) => void; }) => void -type SendLLMMessageFnTypeExternal = (params: { - messages: LLMMessage[]; - onText: OnText; - onFinalMessage: (fullText: string) => void; - onError: (error: Error | string) => void; - voidConfig: VoidConfig | null; - abortRef: AbortRef; - - logging: { - loggingName: string, - }; -}) => void const parseMaxTokensStr = (maxTokensStr: string) => { // parse the string but only if the full string is a valid number, eg parseInt('100abc') should return NaN @@ -53,6 +26,10 @@ const parseMaxTokensStr = (maxTokensStr: string) => { } // Anthropic +type LLMMessageAnthropic = { + role: 'user' | 'assistant'; + content: string; +} const sendAnthropicMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter }) => { const anthropic = new Anthropic({ apiKey: voidConfig.anthropic.apikey, dangerouslyAllowBrowser: true }); // defaults to process.env["ANTHROPIC_API_KEY"] @@ -298,7 +275,7 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin -export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ +export const sendLLMMessage: SendLLMMessageFnType = ({ messages, onText: onText_, onFinalMessage: onFinalMessage_, @@ -573,7 +550,7 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ // export type AbortRef = { current: (() => void) } -// export type OnText = (newText: string, fullText: string) => void +// export type LLMMessageOnText = (newText: string, fullText: string) => void // export type OnFinalMessage = (input: string) => void @@ -593,7 +570,7 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ // mode: 'chat' | 'fim', // messages: LLMMessage[], // options?: LLMMessageOptions, -// onText: OnText, +// onText: LLMMessageOnText, // onFinalMessage: OnFinalMessage, // onError: (error: string) => void, // abortRef: AbortRef, @@ -606,7 +583,7 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ // | { mode: 'fim', messages?: undefined, fimInfo: FimInfo, } // ) & { // options?: LLMMessageOptions, -// onText: OnText, +// onText: LLMMessageOnText, // onFinalMessage: OnFinalMessage, // onError: (error: string) => void, // abortRef: AbortRef, diff --git a/src/vs/workbench/contrib/void/browser/registerSendLLMMessage.ts b/src/vs/workbench/contrib/void/browser/registerSendLLMMessage.ts new file mode 100644 index 00000000..e2dff4d2 --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/registerSendLLMMessage.ts @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Glass Devtools, Inc. All rights reserved. + * Void Editor additions licensed under the AGPLv3 License. + *--------------------------------------------------------------------------------------------*/ + +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 { Server as UtilityProcessServer } from '../../../../base/parts/ipc/node/ipc.mp.js'; +import { IChannel, IServerChannel, StaticRouter } from '../../../../base/parts/ipc/common/ipc.js'; +import { Event } from '../../../../base/common/event.js'; +import { VoidConfig } from './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 SendLLMMessageFnType = (params: { + messages: LLMMessage[]; + onText: LLMMessageOnText; + onFinalMessage: (fullText: string) => void; + onError: (error: Error | string) => void; + voidConfig: VoidConfig | null; + abortRef: LLMMessageAbortRef; + + logging: { + loggingName: string, + }; +}) => void + +export const ISendLLMMessageService = createDecorator('sendLLMMessageService'); + +export interface ISendLLMMessageService { + readonly _serviceBrand: undefined; + + sendMessage(params: { + messages: LLMMessage[]; + onText: LLMMessageOnText; + onFinalMessage: OnFinalMessage; + onError: (error: Error | string) => void; + voidConfig: VoidConfig; + }): Promise; +} + +class SendLLMMessageChannel implements IServerChannel { + constructor() { + + + } + + listen(_: unknown, event: string): Event { + throw new Error('No events available'); + } + + call(context: any, command: string, args?: any[]): Promise { + switch (command) { + case 'sendMessage': + console.log('ARGS', args) + // this.service.sendMessage(args![0]); + default: + throw new Error(`Invalid command ${command}`); + } + } +} + +export class SendLLMMessageService extends Disposable implements ISendLLMMessageService { + _serviceBrand: undefined; + private readonly server: UtilityProcessServer; + private channel: IChannel | undefined; + + constructor() { + super(); + + // Create the utility process server + this.server = this._register(new UtilityProcessServer()); + + // Register our channel + this.server.registerChannel('sendLLMMessage', new SendLLMMessageChannel()); + + // Get the channel from the utility process + this.channel = this.server.getChannel('sendLLMMessage', new StaticRouter(() => true)); + } + + async sendMessage(params: { + messages: LLMMessage[]; + onText: LLMMessageOnText; + onFinalMessage: OnFinalMessage; + onError: (error: Error | string) => void; + voidConfig: VoidConfig; + }): Promise { + if (!this.channel) { + throw new Error('LLM Message service not initialized'); + } + + try { + await this.channel.call('sendMessage', [params]); + } catch (error) { + params.onError(error instanceof Error ? error : new Error(String(error))); + } + } +} + +registerSingleton(ISendLLMMessageService, SendLLMMessageService, InstantiationType.Eager);