From e4d747d0a6cd88644ab00d34c72f8a0c7b3a6784 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Sun, 26 Jan 2025 23:49:16 -0800 Subject: [PATCH] andrew ollamaFIM progress --- remote/package.json | 1 + .../platform/void/common/llmMessageService.ts | 25 ++-- .../platform/void/common/llmMessageTypes.ts | 82 ++++++------ .../void/electron-main/llmMessage/ollama.ts | 10 +- .../llmMessage/sendLLMMessage.ts | 36 +++-- .../void/electron-main/llmMessageChannel.ts | 6 +- .../void/browser/autocompleteService.ts | 125 +++++++++++++++--- .../void/browser/inlineDiffsService.ts | 17 ++- .../contrib/void/browser/prompt/prompts.ts | 2 +- 9 files changed, 205 insertions(+), 99 deletions(-) diff --git a/remote/package.json b/remote/package.json index 98776776..cf913ad2 100644 --- a/remote/package.json +++ b/remote/package.json @@ -26,6 +26,7 @@ "cookie": "^0.4.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", + "debounced": "1.0.2", "jschardet": "3.1.3", "kerberos": "2.1.1", "minimist": "^1.2.6", diff --git a/src/vs/platform/void/common/llmMessageService.ts b/src/vs/platform/void/common/llmMessageService.ts index 40855c8d..fcec27f9 100644 --- a/src/vs/platform/void/common/llmMessageService.ts +++ b/src/vs/platform/void/common/llmMessageService.ts @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainLLMMessageParams, MainLLMMessageAbortParams, ServiceModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, MainModelListParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from './llmMessageTypes.js'; +import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainSendLLMMessageParams, MainLLMMessageAbortParams, ServiceModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, MainModelListParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from './llmMessageTypes.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'; @@ -96,31 +96,29 @@ export class LLMMessageService extends Disposable implements ILLMMessageService onError({ message: 'Please add a Provider in Settings!', fullError: null }) return null } + const { providerName, modelName } = modelSelection - // add ai instructions here because we don't have access to voidSettingsService on the other side of the proxy - const aiInstructions = this.voidSettingsService.state.globalSettings.aiInstructions - if (aiInstructions) - proxyParams.messages.unshift({ role: 'system', content: aiInstructions }) - // add state for request id - const requestId_ = generateUuid(); - this.onTextHooks_llm[requestId_] = onText - this.onFinalMessageHooks_llm[requestId_] = onFinalMessage - this.onErrorHooks_llm[requestId_] = onError + const requestId = generateUuid(); + this.onTextHooks_llm[requestId] = onText + this.onFinalMessageHooks_llm[requestId] = onFinalMessage + this.onErrorHooks_llm[requestId] = onError + const { aiInstructions } = this.voidSettingsService.state.globalSettings const { settingsOfProvider } = this.voidSettingsService.state // params will be stripped of all its functions over the IPC channel this.channel.call('sendLLMMessage', { ...proxyParams, - requestId: requestId_, + aiInstructions, + requestId, providerName, modelName, settingsOfProvider, - } satisfies MainLLMMessageParams); + } satisfies MainSendLLMMessageParams); - return requestId_ + return requestId } @@ -147,6 +145,7 @@ export class LLMMessageService extends Disposable implements ILLMMessageService } satisfies MainModelListParams) } + openAICompatibleList = (params: ServiceModelListParams) => { const { onSuccess, onError, ...proxyParams } = params diff --git a/src/vs/platform/void/common/llmMessageTypes.ts b/src/vs/platform/void/common/llmMessageTypes.ts index 77b31c07..296c0a56 100644 --- a/src/vs/platform/void/common/llmMessageTypes.ts +++ b/src/vs/platform/void/common/llmMessageTypes.ts @@ -3,7 +3,6 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import { IRange } from '../../../editor/common/core/range' import { ProviderName, SettingsOfProvider } from './voidSettingsTypes.js' @@ -36,66 +35,67 @@ export type _InternalLLMMessage = { } -export type ServiceSendLLMFeatureParams = { - useProviderFor: 'Ctrl+K'; - range: IRange; -} | { - useProviderFor: 'Ctrl+L'; -} | { - useProviderFor: 'Autocomplete'; - range: IRange; -} - -// params to the true sendLLMMessage function -export type LLMMMessageParams = { - onText: OnText; - onFinalMessage: OnFinalMessage; - onError: OnError; - abortRef: AbortRef; - +type SendLLMType = { + type: 'sendLLMMessage'; messages: LLMMessage[]; - - logging: { - loggingName: string, - }; - providerName: ProviderName; - modelName: string; - settingsOfProvider: SettingsOfProvider; +} | { + type: 'ollamaFIM'; + messages: { + prefix: string; + suffix: string; + } } +// service types export type ServiceSendLLMMessageParams = { onText: OnText; onFinalMessage: OnFinalMessage; onError: OnError; + logging: { loggingName: string, }; + useProviderFor: 'Ctrl+K' | 'Ctrl+L' | 'Autocomplete'; +} & SendLLMType + +// params to the true sendLLMMessage function +export type SendLLMMMessageParams = { + onText: OnText; + onFinalMessage: OnFinalMessage; + onError: OnError; + logging: { loggingName: string, }; + abortRef: AbortRef; + + aiInstructions: string; + + providerName: ProviderName; + modelName: string; + settingsOfProvider: SettingsOfProvider; +} & SendLLMType - messages: LLMMessage[]; - logging: { - loggingName: string, - }; -} & ServiceSendLLMFeatureParams // can't send functions across a proxy, use listeners instead export type BlockedMainLLMMessageParams = 'onText' | 'onFinalMessage' | 'onError' | 'abortRef' +export type MainSendLLMMessageParams = Omit & { requestId: string } & SendLLMType -export type MainLLMMessageParams = Omit & { requestId: string } export type MainLLMMessageAbortParams = { requestId: string } export type EventLLMMessageOnTextParams = Parameters[0] & { requestId: string } export type EventLLMMessageOnFinalMessageParams = Parameters[0] & { requestId: string } export type EventLLMMessageOnErrorParams = Parameters[0] & { requestId: string } -export type _InternalSendLLMMessageFnType = (params: { - messages: _InternalLLMMessage[]; - onText: OnText; - onFinalMessage: OnFinalMessage; - onError: OnError; - settingsOfProvider: SettingsOfProvider; - providerName: ProviderName; - modelName: string; +export type _InternalSendLLMMessageFnType = ( + params: { + onText: OnText; + onFinalMessage: OnFinalMessage; + onError: OnError; + messages: _InternalLLMMessage[]; - _setAborter: (aborter: () => void) => void; -}) => void + settingsOfProvider: SettingsOfProvider; + providerName: ProviderName; + modelName: string; + + _setAborter: (aborter: () => void) => void; + } +) => void // service -> main -> internal -> event (back to main) // (browser) diff --git a/src/vs/platform/void/electron-main/llmMessage/ollama.ts b/src/vs/platform/void/electron-main/llmMessage/ollama.ts index 95792700..eff63514 100644 --- a/src/vs/platform/void/electron-main/llmMessage/ollama.ts +++ b/src/vs/platform/void/electron-main/llmMessage/ollama.ts @@ -25,6 +25,7 @@ export const ollamaList: _InternalModelListFnType = async ( const ollama = new Ollama({ host: thisConfig.endpoint }) ollama.list() .then((response) => { + console.log('MODELS!!!!!!!!!!!!!!!!!', response) const { models } = response onSuccess({ models }) }) @@ -38,6 +39,7 @@ export const ollamaList: _InternalModelListFnType = async ( } + // Ollama export const sendOllamaMsg: _InternalSendLLMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { @@ -68,14 +70,6 @@ export const sendOllamaMsg: _InternalSendLLMMessageFnType = ({ messages, onText, }) // when error/fail .catch((error) => { - // if (typeof error === 'object') { - // const e = error.error as ErrorResponse['error'] - // if (e) { - // const name = error.name ?? 'Error' - // onError({ error: `${name}: ${e}` }) - // return; - // } - // } onError({ message: error + '', fullError: error }) }) diff --git a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts index 1f88b26c..b0cdedec 100644 --- a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts +++ b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import { LLMMMessageParams, OnText, OnFinalMessage, OnError, LLMMessage, _InternalLLMMessage } from '../../common/llmMessageTypes.js'; +import { SendLLMMMessageParams, OnText, OnFinalMessage, OnError, LLMMessage, _InternalLLMMessage } from '../../common/llmMessageTypes.js'; import { IMetricsService } from '../../common/metricsService.js'; import { sendAnthropicMsg } from './anthropic.js'; @@ -48,6 +48,8 @@ const cleanMessages = (messages: LLMMessage[]): _InternalLLMMessage[] => { export const sendLLMMessage = ({ + type, + aiInstructions, messages: messages_, onText: onText_, onFinalMessage: onFinalMessage_, @@ -57,21 +59,31 @@ export const sendLLMMessage = ({ settingsOfProvider, providerName, modelName, -}: LLMMMessageParams, +}: SendLLMMMessageParams, metricsService: IMetricsService ) => { - const messages = cleanMessages(messages_) + messages.unshift({ role: 'system', content: aiInstructions }) + + const messages = type === 'sendLLMMessage' ? cleanMessages(messages_) : [] + + + const prefixAndSuffix = type === 'ollamaFIM' ? messages_ : null // only captures number of messages and message "shape", no actual code, instructions, prompts, etc - const captureChatEvent = (eventId: string, extras?: object) => { + const captureLLMEvent = (eventId: string, extras?: object) => { metricsService.capture(eventId, { providerName, modelName, - numMessages: messages?.length, - messagesShape: messages?.map(msg => ({ role: msg.role, length: msg.content.length })), - origNumMessages: messages_?.length, - origMessagesShape: messages_?.map(msg => ({ role: msg.role, length: msg.content.length })), + ...type === 'sendLLMMessage' ? { + numMessages: messages?.length, + messagesShape: messages?.map(msg => ({ role: msg.role, length: msg.content.length })), + origNumMessages: messages_?.length, + origMessagesShape: messages_?.map(msg => ({ role: msg.role, length: msg.content.length })), + + } : type === 'ollamaFIM' ? { + + } : {}, ...extras, }) @@ -91,26 +103,26 @@ export const sendLLMMessage = ({ const onFinalMessage: OnFinalMessage = ({ fullText }) => { if (_didAbort) return - captureChatEvent(`${loggingName} - Received Full Message`, { messageLength: fullText.length, duration: new Date().getMilliseconds() - submit_time.getMilliseconds() }) + captureLLMEvent(`${loggingName} - Received Full Message`, { messageLength: fullText.length, duration: new Date().getMilliseconds() - submit_time.getMilliseconds() }) onFinalMessage_({ fullText }) } const onError: OnError = ({ message: error, fullError }) => { if (_didAbort) return console.error('sendLLMMessage onError:', error) - captureChatEvent(`${loggingName} - Error`, { error }) + captureLLMEvent(`${loggingName} - Error`, { error }) onError_({ message: error, fullError }) } const onAbort = () => { - captureChatEvent(`${loggingName} - Abort`, { messageLengthSoFar: _fullTextSoFar.length }) + captureLLMEvent(`${loggingName} - Abort`, { messageLengthSoFar: _fullTextSoFar.length }) try { _aborter?.() } // aborter sometimes automatically throws an error catch (e) { } _didAbort = true } abortRef_.current = onAbort - captureChatEvent(`${loggingName} - Sending Message`, { messageLength: messages[messages.length - 1]?.content.length }) + captureLLMEvent(`${loggingName} - Sending Message`, { messageLength: messages[messages.length - 1]?.content.length }) try { switch (providerName) { diff --git a/src/vs/platform/void/electron-main/llmMessageChannel.ts b/src/vs/platform/void/electron-main/llmMessageChannel.ts index 2430fce2..56235501 100644 --- a/src/vs/platform/void/electron-main/llmMessageChannel.ts +++ b/src/vs/platform/void/electron-main/llmMessageChannel.ts @@ -8,7 +8,7 @@ import { IServerChannel } from '../../../base/parts/ipc/common/ipc.js'; import { Emitter, Event } from '../../../base/common/event.js'; -import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, MainLLMMessageParams, AbortRef, LLMMMessageParams, MainLLMMessageAbortParams, MainModelListParams, ModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from '../common/llmMessageTypes.js'; +import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, MainSendLLMMessageParams, AbortRef, SendLLMMMessageParams, MainLLMMessageAbortParams, MainModelListParams, ModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from '../common/llmMessageTypes.js'; import { sendLLMMessage } from './llmMessage/sendLLMMessage.js' import { IMetricsService } from '../common/metricsService.js'; import { ollamaList } from './llmMessage/ollama.js'; @@ -91,13 +91,13 @@ export class LLMMessageChannel implements IServerChannel { } // the only place sendLLMMessage is actually called - private async _callSendLLMMessage(params: MainLLMMessageParams) { + private async _callSendLLMMessage(params: MainSendLLMMessageParams) { const { requestId } = params; if (!(requestId in this._abortRefOfRequestId_llm)) this._abortRefOfRequestId_llm[requestId] = { current: null } - const mainThreadParams: LLMMMessageParams = { + const mainThreadParams: SendLLMMMessageParams = { ...params, onText: ({ newText, fullText }) => { this._onText_llm.fire({ requestId, newText, fullText }); }, onFinalMessage: ({ fullText }) => { this._onFinalMessage_llm.fire({ requestId, fullText }); }, diff --git a/src/vs/workbench/contrib/void/browser/autocompleteService.ts b/src/vs/workbench/contrib/void/browser/autocompleteService.ts index 79dbc739..63c2e854 100644 --- a/src/vs/workbench/contrib/void/browser/autocompleteService.ts +++ b/src/vs/workbench/contrib/void/browser/autocompleteService.ts @@ -5,11 +5,10 @@ import { Disposable } from '../../../../base/common/lifecycle.js'; import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js'; -import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js'; import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; import { ITextModel } from '../../../../editor/common/model.js'; import { Position } from '../../../../editor/common/core/position.js'; -import { InlineCompletion, InlineCompletionContext } from '../../../../editor/common/languages.js'; +import { InlineCompletion, InlineCompletionContext, LocationLink } from '../../../../editor/common/languages.js'; import { CancellationToken } from '../../../../base/common/cancellation.js'; import { Range } from '../../../../editor/common/core/range.js'; import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js'; @@ -19,6 +18,7 @@ import { EditorResourceAccessor } from '../../../common/editor.js'; import { IModelService } from '../../../../editor/common/services/model.js'; import { extractCodeFromRegular } from './helpers/extractCodeFromResult.js'; import { isWindows } from '../../../../base/common/platform.js'; +import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; // The extension this was called from is here - https://github.com/voideditor/void/blob/autocomplete/extensions/void/src/extension/extension.ts @@ -499,7 +499,7 @@ const getAutocompletionMatchup = ({ prefix, autocompletion }: { prefix: string, } -const getCompletionOptions = (prefixAndSuffix: PrefixAndSuffixInfo) => { +const getCompletionOptions = (prefixAndSuffix: PrefixAndSuffixInfo, relevantContext: string) => { const { prefix, suffix, prefixToTheLeftOfCursor, suffixToTheRightOfCursor, suffixLines } = prefixAndSuffix @@ -520,6 +520,8 @@ const getCompletionOptions = (prefixAndSuffix: PrefixAndSuffixInfo) => { predictionType = 'single-line' } + llmPrefix = llmPrefix + '\n\n/* Relevant context:\n' + relevantContext + '\n*/\n' + // default parameters let shouldGenerate = true let stopTokens: string[] = allLinebreakSymbols // default to multi-line prediction @@ -545,6 +547,9 @@ export interface IAutocompleteService { export const IAutocompleteService = createDecorator('AutocompleteService'); export class AutocompleteService extends Disposable implements IAutocompleteService { + + static readonly ID = 'void.autocompleteService' + _serviceBrand: undefined; private _autocompletionId: number = 0; @@ -562,11 +567,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ token: CancellationToken, ): Promise { - const disabled = true const testMode = false - if (disabled) return []; - const docUriStr = model.uri.toString(); const prefixAndSuffix = getPrefixAndSuffixInfo(model, position) @@ -670,7 +672,15 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ } } - const { shouldGenerate, predictionType, stopTokens, llmPrefix, llmSuffix } = getCompletionOptions(prefixAndSuffix) // TODO use stop tokens + + // NEW: gather relevant context from the code around the user's selection and definitions + const relevantContext = await this._gatherRelevantContextForPosition( + model, + position, + 3, //recursion depth + 1 // number of lines to view in each recursion + ); + const { shouldGenerate, predictionType, llmPrefix, llmSuffix } = getCompletionOptions(prefixAndSuffix, relevantContext) // TODO use stop tokens if (!shouldGenerate) return [] @@ -700,12 +710,14 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ newAutocompletion.llmPromise = new Promise((resolve, reject) => { const requestId = this._llmMessageService.sendLLMMessage({ - prefix: llmPrefix, - suffix: llmSuffix, - stopTokens: stopTokens, + type: 'ollamaFIM', + // TODO: Incorporate relevant context directly into the prefix + messages: { + prefix: llmPrefix, + suffix: llmSuffix, + }, logging: { loggingName: 'Autocomplete' }, - messages: [], - onText: async ({ newText, fullText }) => { + onText: async ({ fullText }) => { newAutocompletion.insertText = fullText @@ -735,7 +747,6 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ reject(message) }, useProviderFor: 'Autocomplete', - range: { startLineNumber: position.lineNumber, startColumn: position.column, endLineNumber: position.lineNumber, endColumn: position.column }, }) newAutocompletion.requestId = requestId @@ -770,6 +781,84 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ } + // helper method to gather ~N lines above and below the user's current line, + // and recursively gather lines around any symbol definitions encountered. + private async _gatherRelevantContextForPosition( + model: ITextModel, + position: Position, + recursionDepth: number, + linesAround: number + ): Promise { + // We'll do a BFS-like approach: for each position or definition, gather lines around it, + // then attempt to find the definition of any symbols in that range, up to 'recursionDepth' times. + + // A set of "key" strings to avoid repeating the same location or line chunk + const visitedRanges = new Set(); + const collectedSnippets: string[] = []; + + // A queue of tasks, each being a tuple of: (model, position, depth) + const tasks: Array<{ model: ITextModel, position: Position, depth: number }> = []; + tasks.push({ model, position, depth: recursionDepth }); + + const getSnippetAroundLine = (model: ITextModel, lineNumber: number, linesAround: number): string => { + const startLine = Math.max(1, lineNumber - linesAround); + const endLine = Math.min(model.getLineCount(), lineNumber + linesAround); + const lines: string[] = []; + for (let i = startLine; i <= endLine; i++) { + lines.push(model.getLineContent(i)); + } + return lines.join('\n'); + }; + + while (tasks.length > 0) { + const { model: currentModel, position: currentPos, depth } = tasks.shift()!; + + if (depth < 0) { + continue; + } + + // Gather snippet around the current line + const snippet = getSnippetAroundLine(currentModel, currentPos.lineNumber, linesAround); + const snippetKey = `${currentModel.uri.toString()}:${currentPos.lineNumber}`; + if (!visitedRanges.has(snippetKey)) { + visitedRanges.add(snippetKey); + collectedSnippets.push(`-- Snippet around line ${currentPos.lineNumber} --\n${snippet}\n`); + } + + // Attempt to gather definitions for the symbol at this position + // We just pick all definition providers and see if any has a definition + const providers = this._langFeatureService.definitionProvider.ordered(currentModel); + for (const provider of providers) { + try { + const definitions = await provider.provideDefinition(currentModel, currentPos, CancellationToken.None); + if (!definitions) continue; + + // definitions can be a single LocationLink or an array + const defArray: LocationLink[] = Array.isArray(definitions) ? definitions : [definitions]; + for (const def of defArray) { + if (!def.uri) continue; + if (typeof def.range === 'undefined') continue; + const definitionModel = this._modelService.getModel(def.uri); + if (!definitionModel) continue; + + // We'll queue up a new task for that definition range + const defPos = new Position(def.range.startLineNumber, def.range.startColumn); + const defKey = `${def.uri.toString()}:${defPos.lineNumber}`; + if (!visitedRanges.has(defKey)) { + tasks.push({ model: definitionModel, position: defPos, depth: depth - 1 }); + } + } + } catch (err) { + // If a provider fails, ignore + } + } + } + + // Return the joined context + return collectedSnippets.join('\n'); + } + + constructor( @ILanguageFeaturesService private _langFeatureService: ILanguageFeaturesService, @ILLMMessageService private readonly _llmMessageService: ILLMMessageService, @@ -780,12 +869,14 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ this._langFeatureService.inlineCompletionsProvider.register('*', { provideInlineCompletions: async (model, position, context, token) => { + console.log('AAAAAAAAA') const items = await this._provideInlineCompletionItems(model, position, context, token) // console.log('item: ', items?.[0]?.insertText) return { items: items, } }, freeInlineCompletions: (completions) => { + console.log('BBBBBBBB') // get the `docUriStr` and the `position` of the cursor const activePane = this._editorService.activeEditorPane; @@ -807,9 +898,7 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ // autocompletion.prefix + autocompletion.insertedText ~== insertedText completions.items.forEach(item => { this._autocompletionsOfDocument[docUriStr].items.forEach((autocompletion: Autocompletion) => { - if (removeLeftTabsAndTrimEnds(prefix) - === removeLeftTabsAndTrimEnds(autocompletion.prefix + autocompletion.insertText) - ) { + if (removeLeftTabsAndTrimEnds(prefix) === removeLeftTabsAndTrimEnds(autocompletion.prefix + autocompletion.insertText)) { this._autocompletionsOfDocument[docUriStr].delete(autocompletion.id); } }); @@ -822,7 +911,7 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ } - -registerSingleton(IAutocompleteService, AutocompleteService, InstantiationType.Eager); +registerWorkbenchContribution2(AutocompleteService.ID, AutocompleteService, WorkbenchPhase.BlockRestore); + diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index fdbf84bb..b7d43a6d 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -25,7 +25,7 @@ import * as dom from '../../../../base/browser/dom.js'; import { Widget } from '../../../../base/browser/ui/widget.js'; import { URI } from '../../../../base/common/uri.js'; import { IConsistentEditorItemService, IConsistentItemService } from './helperServices/consistentItemService.js'; -import { ctrlKStream_prefixAndSuffix, ctrlKStream_userMessage, ctrlKStream_systemMessage, fastApply_userMessage, fastApply_systemMessage, defaultFimTags } from './prompt/prompts.js'; +import { voidPrefixAndSuffix, ctrlKStream_userMessage, ctrlKStream_systemMessage, fastApply_userMessage, fastApply_systemMessage, defaultFimTags } from './prompt/prompts.js'; import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js'; import { mountCtrlK } from '../browser/react/out/quick-edit-tsx/index.js' @@ -1304,13 +1304,24 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const instructions = _mountInfo?.textAreaRef.current?.value ?? '' // __TODO__ use Ollama's FIM api, if (isOllamaFIM) {...} else: - const { prefix, suffix } = ctrlKStream_prefixAndSuffix({ fullFileStr: currentFileStr, startLine, endLine }) + const { prefix, suffix } = voidPrefixAndSuffix({ fullFileStr: currentFileStr, startLine, endLine }) + // if (isOllamaFIM) { + // messages = { + // type: 'ollamaFIM', + // prefix, + // suffix, + // } + + // } + // else { const language = filenameToVscodeLanguage(uri.fsPath) ?? '' const userContent = ctrlKStream_userMessage({ selection: originalCode, instructions: instructions, prefix, suffix, isOllamaFIM: false, fimTags: modelFimTags, language }) + // type: 'messages', messages = [ { role: 'system', content: ctrlKStream_systemMessage({ fimTags: modelFimTags }), }, { role: 'user', content: userContent, } ] + // } } else { throw new Error(`featureName ${featureName} is invalid`) } @@ -1356,6 +1367,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { let prevIgnoredSuffix = '' streamRequestIdRef.current = this._llmMessageService.sendLLMMessage({ + type: 'sendLLMMessage', useProviderFor: featureName, logging: { loggingName: `startApplying - ${featureName}` }, messages, @@ -1400,7 +1412,6 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { onDone(true) }, - range: { startLineNumber: startLine, endLineNumber: endLine, startColumn: 1, endColumn: Number.MAX_SAFE_INTEGER }, }) return diffZone diff --git a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts index 949e0604..7dc23d53 100644 --- a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts @@ -220,7 +220,7 @@ Please finish writing the new file by applying the change to the original file. -export const ctrlKStream_prefixAndSuffix = ({ fullFileStr, startLine, endLine }: { fullFileStr: string, startLine: number, endLine: number }) => { +export const voidPrefixAndSuffix = ({ fullFileStr, startLine, endLine }: { fullFileStr: string, startLine: number, endLine: number }) => { const fullFileLines = fullFileStr.split('\n')