diff --git a/src/vs/platform/void/common/llmMessageTypes.ts b/src/vs/platform/void/common/llmMessageTypes.ts index 296c0a56..9b5f21a9 100644 --- a/src/vs/platform/void/common/llmMessageTypes.ts +++ b/src/vs/platform/void/common/llmMessageTypes.ts @@ -34,16 +34,18 @@ export type _InternalLLMMessage = { content: string; } +type _InternalOllamaFIMMessages = { + prefix: string; + suffix: string; + stopTokens: string[]; +} type SendLLMType = { type: 'sendLLMMessage'; messages: LLMMessage[]; } | { type: 'ollamaFIM'; - messages: { - prefix: string; - suffix: string; - } + messages: _InternalOllamaFIMMessages; } // service types @@ -56,7 +58,7 @@ export type ServiceSendLLMMessageParams = { } & SendLLMType // params to the true sendLLMMessage function -export type SendLLMMMessageParams = { +export type SendLLMMessageParams = { onText: OnText; onFinalMessage: OnFinalMessage; onError: OnError; @@ -74,7 +76,7 @@ export type SendLLMMMessageParams = { // 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 MainSendLLMMessageParams = Omit & { requestId: string } & SendLLMType export type MainLLMMessageAbortParams = { requestId: string } @@ -82,18 +84,32 @@ export type EventLLMMessageOnTextParams = Parameters[0] & { requestId: s export type EventLLMMessageOnFinalMessageParams = Parameters[0] & { requestId: string } export type EventLLMMessageOnErrorParams = Parameters[0] & { requestId: string } + export type _InternalSendLLMMessageFnType = ( params: { onText: OnText; onFinalMessage: OnFinalMessage; onError: OnError; - messages: _InternalLLMMessage[]; - - settingsOfProvider: SettingsOfProvider; providerName: ProviderName; + settingsOfProvider: SettingsOfProvider; modelName: string; - _setAborter: (aborter: () => void) => void; + + messages: _InternalLLMMessage[]; + } +) => void + +export type _InternalOllamaFIMMessageFnType = ( + params: { + onText: OnText; + onFinalMessage: OnFinalMessage; + onError: OnError; + providerName: ProviderName; + settingsOfProvider: SettingsOfProvider; + modelName: string; + _setAborter: (aborter: () => void) => void; + + messages: _InternalOllamaFIMMessages; } ) => void diff --git a/src/vs/platform/void/electron-main/llmMessage/ollama.ts b/src/vs/platform/void/electron-main/llmMessage/ollama.ts index eff63514..e5753973 100644 --- a/src/vs/platform/void/electron-main/llmMessage/ollama.ts +++ b/src/vs/platform/void/electron-main/llmMessage/ollama.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------*/ import { Ollama } from 'ollama'; -import { _InternalModelListFnType, _InternalSendLLMMessageFnType, OllamaModelResponse } from '../../common/llmMessageTypes.js'; +import { _InternalModelListFnType, _InternalOllamaFIMMessageFnType, _InternalSendLLMMessageFnType, OllamaModelResponse } from '../../common/llmMessageTypes.js'; import { defaultProviderSettings } from '../../common/voidSettingsTypes.js'; export const ollamaList: _InternalModelListFnType = async ({ onSuccess: onSuccess_, onError: onError_, settingsOfProvider }) => { @@ -25,7 +25,7 @@ export const ollamaList: _InternalModelListFnType = async ( const ollama = new Ollama({ host: thisConfig.endpoint }) ollama.list() .then((response) => { - console.log('MODELS!!!!!!!!!!!!!!!!!', response) + // console.log('MODELS!!!!!!!!!!!!!!!!!', response) const { models } = response onSuccess({ models }) }) @@ -39,6 +39,44 @@ export const ollamaList: _InternalModelListFnType = async ( } +export const sendOllamaFIM: _InternalOllamaFIMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { + + const thisConfig = settingsOfProvider.ollama + // if endpoint is empty, normally ollama will send to 11434, but we want it to fail - the user should type it in + if (!thisConfig.endpoint) throw new Error(`Ollama Endpoint was empty (please enter ${defaultProviderSettings.ollama.endpoint} if you want the default).`) + + let fullText = '' + + const ollama = new Ollama({ host: thisConfig.endpoint }) + + ollama.generate({ + model: modelName, + prompt: messages.prefix, + suffix: messages.suffix, + options: { + stop: messages.stopTokens, + }, + raw: true, + stream: true, + // options: { num_predict: parseMaxTokensStr(thisConfig.maxTokens) } // this is max_tokens + }) + .then(async stream => { + _setAborter(() => stream.abort()) + // iterate through the stream + for await (const chunk of stream) { + const newText = chunk.response; + fullText += newText; + onText({ newText, fullText }); + } + onFinalMessage({ fullText }); + console.log('!!!!! OLLAMA RESULT', JSON.stringify(fullText)) + }) + // when error/fail + .catch((error) => { + onError({ message: error + '', fullError: error }) + }) +}; + // Ollama export const sendOllamaMsg: _InternalSendLLMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { diff --git a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts index b0cdedec..4b2884ca 100644 --- a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts +++ b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts @@ -3,11 +3,11 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import { SendLLMMMessageParams, OnText, OnFinalMessage, OnError, LLMMessage, _InternalLLMMessage } from '../../common/llmMessageTypes.js'; +import { SendLLMMessageParams, OnText, OnFinalMessage, OnError, LLMMessage, _InternalLLMMessage } from '../../common/llmMessageTypes.js'; import { IMetricsService } from '../../common/metricsService.js'; import { sendAnthropicMsg } from './anthropic.js'; -import { sendOllamaMsg } from './ollama.js'; +import { sendOllamaFIM, sendOllamaMsg } from './ollama.js'; import { sendOpenAIMsg } from './openai.js'; import { sendGeminiMsg } from './gemini.js'; import { sendGroqMsg } from './groq.js'; @@ -59,16 +59,13 @@ export const sendLLMMessage = ({ settingsOfProvider, providerName, modelName, -}: SendLLMMMessageParams, +}: SendLLMMessageParams, metricsService: IMetricsService ) => { - messages.unshift({ role: 'system', content: aiInstructions }) + // messages.unshift({ role: 'system', content: aiInstructions }) - const messages = type === 'sendLLMMessage' ? cleanMessages(messages_) : [] - - - const prefixAndSuffix = type === 'ollamaFIM' ? messages_ : null + const messagesArr = type === 'sendLLMMessage' ? cleanMessages(messages_) : [] // only captures number of messages and message "shape", no actual code, instructions, prompts, etc const captureLLMEvent = (eventId: string, extras?: object) => { @@ -76,8 +73,8 @@ export const sendLLMMessage = ({ providerName, modelName, ...type === 'sendLLMMessage' ? { - numMessages: messages?.length, - messagesShape: messages?.map(msg => ({ role: msg.role, length: msg.content.length })), + numMessages: messagesArr?.length, + messagesShape: messagesArr?.map(msg => ({ role: msg.role, length: msg.content.length })), origNumMessages: messages_?.length, origMessagesShape: messages_?.map(msg => ({ role: msg.role, length: msg.content.length })), @@ -122,27 +119,30 @@ export const sendLLMMessage = ({ } abortRef_.current = onAbort - captureLLMEvent(`${loggingName} - Sending Message`, { messageLength: messages[messages.length - 1]?.content.length }) + captureLLMEvent(`${loggingName} - Sending Message`, { messageLength: messagesArr[messagesArr.length - 1]?.content.length }) try { switch (providerName) { case 'anthropic': - sendAnthropicMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); + sendAnthropicMsg({ messages: messagesArr, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); break; case 'openAI': case 'openRouter': case 'deepseek': case 'openAICompatible': - sendOpenAIMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); + sendOpenAIMsg({ messages: messagesArr, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); break; case 'gemini': - sendGeminiMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); + sendGeminiMsg({ messages: messagesArr, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); break; case 'ollama': - sendOllamaMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); + if (type === 'ollamaFIM') + sendOllamaFIM({ messages: messages_, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }) + else + sendOllamaMsg({ messages: messagesArr, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); break; case 'groq': - sendGroqMsg({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); + sendGroqMsg({ messages: messagesArr, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }); break; default: onError({ message: `Error: Void provider was "${providerName}", which is not recognized.`, fullError: null }) diff --git a/src/vs/platform/void/electron-main/llmMessageChannel.ts b/src/vs/platform/void/electron-main/llmMessageChannel.ts index 56235501..2c44e2ec 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, MainSendLLMMessageParams, AbortRef, SendLLMMMessageParams, MainLLMMessageAbortParams, MainModelListParams, ModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from '../common/llmMessageTypes.js'; +import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, MainSendLLMMessageParams, AbortRef, SendLLMMessageParams, 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'; @@ -97,7 +97,7 @@ export class LLMMessageChannel implements IServerChannel { if (!(requestId in this._abortRefOfRequestId_llm)) this._abortRefOfRequestId_llm[requestId] = { current: null } - const mainThreadParams: SendLLMMMessageParams = { + const mainThreadParams: SendLLMMessageParams = { ...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 63c2e854..a6dfde14 100644 --- a/src/vs/workbench/contrib/void/browser/autocompleteService.ts +++ b/src/vs/workbench/contrib/void/browser/autocompleteService.ts @@ -135,6 +135,12 @@ class LRUCache { } } +type AutocompletionPredictionType = + | 'single-line-fill-middle' + | 'single-line-redo-suffix' + // | 'multi-line-start-here' + | 'multi-line-start-on-next-line' + | 'do-not-predict' type Autocompletion = { id: number, @@ -145,7 +151,7 @@ type Autocompletion = { startTime: number, endTime: number | undefined, status: 'pending' | 'finished' | 'error', - type: 'single-line' | 'single-line-redo-suffix' | 'multi-line' + type: AutocompletionPredictionType, llmPromise: Promise | undefined, insertText: string, requestId: string | null, @@ -345,25 +351,26 @@ const postprocessAutocompletion = ({ autocompletionMatchup, autocompletion, pref // returns the text in the autocompletion to display, assuming the prefix is already matched const toInlineCompletions = ({ autocompletionMatchup, autocompletion, prefixAndSuffix, position, debug }: { autocompletionMatchup: AutocompletionMatchupBounds, autocompletion: Autocompletion, prefixAndSuffix: PrefixAndSuffixInfo, position: Position, debug?: boolean }): { insertText: string, range: Range }[] => { - // postprocess the insertText let trimmedInsertText = postprocessAutocompletion({ autocompletionMatchup, autocompletion, prefixAndSuffix, }) - - // postprocess `rangeToReplace` let rangeToReplace: Range = new Range(position.lineNumber, position.column, position.lineNumber, position.column) - if (autocompletion.type === 'single-line-redo-suffix' // did we redo the line? if so, replace the whole suffix + + // handle special cases + + // if we are predicting starting on the next line, add a newline character + if (autocompletion.type === 'multi-line-start-on-next-line') { + trimmedInsertText = _ln + trimmedInsertText + } + // if we redid the suffix, replace the suffix + if (autocompletion.type === 'single-line-redo-suffix' && isSubsequence({ // check that the old text contains the same brackets + symbols as the new text subsequence: removeAllWhitespace(prefixAndSuffix.suffixToTheRightOfCursor), - of: removeAllWhitespace(autocompletion.insertText), // should not be `trimmedInsertText` + of: removeAllWhitespace(autocompletion.insertText), // note that this should not be `trimmedInsertText` }) ) { rangeToReplace = new Range(position.lineNumber, position.column, position.lineNumber, Number.MAX_SAFE_INTEGER) - } else { // did not matchup, do not show the autocompletion - return [{ - insertText: '', - range: rangeToReplace - }] } + return [{ insertText: trimmedInsertText, range: rangeToReplace, @@ -499,44 +506,86 @@ const getAutocompletionMatchup = ({ prefix, autocompletion }: { prefix: string, } -const getCompletionOptions = (prefixAndSuffix: PrefixAndSuffixInfo, relevantContext: string) => { +// const x = [] +// const +// c[[]] +// asd[[]] = +// const [{{}}] +// +type CompletionOptions = { + predictionType: AutocompletionPredictionType, + shouldGenerate: boolean, + llmPrefix: string, + llmSuffix: string, + stopTokens: string[], +} +const getCompletionOptions = (prefixAndSuffix: PrefixAndSuffixInfo, relevantContext: string, justAcceptedAutocompletion: boolean): CompletionOptions => { const { prefix, suffix, prefixToTheLeftOfCursor, suffixToTheRightOfCursor, suffixLines } = prefixAndSuffix - // single line prediction unless the current line is blank - let predictionType: Autocompletion['type'] - let llmPrefix = prefix - let llmSuffix = suffix + let completionOptions: CompletionOptions - if (!prefixToTheLeftOfCursor.trim() && !suffixToTheRightOfCursor.trim()) { // line is empty - predictionType = 'multi-line' + // if line is empty, do multiline completion + const isLineEmpty = !prefixToTheLeftOfCursor.trim() && !suffixToTheRightOfCursor.trim() + const isLinePrefixEmpty = removeAllWhitespace(prefixToTheLeftOfCursor).length === 0 + const isLineSuffixEmpty = removeAllWhitespace(suffixToTheRightOfCursor).length === 0 - } else if (removeAllWhitespace(prefixAndSuffix.suffixToTheRightOfCursor).length < 4) { // suffix is less than 4 characters - predictionType = 'single-line-redo-suffix' + // TODO add context to prefix + // llmPrefix = '\n\n/* Relevant context:\n' + relevantContext + '\n*/\n' + llmPrefix + + // if we just accepted an autocompletion, predict a multiline completion starting on the next line + if (justAcceptedAutocompletion && isLineSuffixEmpty) { + const prefixWithNewline = prefix + _ln + completionOptions = { + predictionType: 'multi-line-start-on-next-line', + shouldGenerate: true, + llmPrefix: prefixWithNewline, + llmSuffix: suffix, + stopTokens: [`${_ln}${_ln}`] // double newlines + } + } + // if the current line is empty, predict a single-line completion + else if (isLineEmpty) { + completionOptions = { + predictionType: 'single-line-fill-middle', + shouldGenerate: true, + llmPrefix: prefix, + llmSuffix: suffix, + stopTokens: allLinebreakSymbols + } + } + // if suffix is 3 or less characters, attempt to complete the line ignorning it + else if (removeAllWhitespace(suffixToTheRightOfCursor).length <= 3) { const suffixLinesIgnoringThisLine = suffixLines.slice(1) - llmSuffix = suffixLinesIgnoringThisLine.length === 0 ? '' : _ln + suffixLinesIgnoringThisLine.join(_ln) - + const suffixStringIgnoringThisLine = suffixLinesIgnoringThisLine.length === 0 ? '' : _ln + suffixLinesIgnoringThisLine.join(_ln) + completionOptions = { + predictionType: 'single-line-redo-suffix', + shouldGenerate: true, + llmPrefix: prefix, + llmSuffix: suffixStringIgnoringThisLine, + stopTokens: allLinebreakSymbols + } + } + // else attempt to complete the middle of the line if there is a prefix (the completion looks bad if there is no prefix) + else if (!isLinePrefixEmpty) { + completionOptions = { + predictionType: 'single-line-fill-middle', + shouldGenerate: true, + llmPrefix: prefix, + llmSuffix: suffix, + stopTokens: allLinebreakSymbols + } } else { - predictionType = 'single-line' + completionOptions = { + predictionType: 'do-not-predict', + shouldGenerate: false, + llmPrefix: prefix, + llmSuffix: suffix, + stopTokens: [] + } } - llmPrefix = llmPrefix + '\n\n/* Relevant context:\n' + relevantContext + '\n*/\n' - - // default parameters - let shouldGenerate = true - let stopTokens: string[] = allLinebreakSymbols // default to multi-line prediction - - // Case 1: User is on a line with text to the left or right - if (prefixToTheLeftOfCursor.trim() !== '' || suffixToTheRightOfCursor.trim() !== '') { - stopTokens = allLinebreakSymbols // single line prediction - } - - // Don't generate if at the very beginning of a line - if (prefixToTheLeftOfCursor === '') { - shouldGenerate = false - } - - return { shouldGenerate, predictionType, stopTokens, llmPrefix, llmSuffix } + return completionOptions } @@ -555,8 +604,9 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ private _autocompletionId: number = 0; private _autocompletionsOfDocument: { [docUriStr: string]: LRUCache } = {} - private _lastCompletionTime = 0 - private _lastPrefix: string = '' + private _lastCompletionStart = 0 + private _lastCompletionAccept = 0 + // private _lastPrefix: string = '' // used internally by vscode // fires after every keystroke and returns the completion to show @@ -567,6 +617,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ token: CancellationToken, ): Promise { + console.log('START1') + const testMode = false const docUriStr = model.uri.toString(); @@ -585,7 +637,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ } ) } - this._lastPrefix = prefix + // this._lastPrefix = prefix + console.log('START2') // print all pending autocompletions // let _numPending = 0 @@ -604,19 +657,24 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ } } + console.log('START3') + // if there is a cached autocompletion, return it if (cachedAutocompletion && autocompletionMatchup) { + console.log('AAA') + + // console.log('id: ' + cachedAutocompletion.id) if (cachedAutocompletion.status === 'finished') { - // console.log('A1') + console.log('A1') const inlineCompletions = toInlineCompletions({ autocompletionMatchup, autocompletion: cachedAutocompletion, prefixAndSuffix, position, debug: true }) return inlineCompletions } else if (cachedAutocompletion.status === 'pending') { - // console.log('A2') + console.log('A2') try { await cachedAutocompletion.llmPromise; @@ -629,7 +687,9 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ } } else if (cachedAutocompletion.status === 'error') { - // console.log('A3') + console.log('A3') + } else { + console.log('A4') } return [] @@ -638,10 +698,10 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ // else if no more typing happens, then go forwards with the request // wait DEBOUNCE_TIME for the user to stop typing const thisTime = Date.now() - this._lastCompletionTime = thisTime + this._lastCompletionStart = thisTime const didTypingHappenDuringDebounce = await new Promise((resolve, reject) => setTimeout(() => { - if (this._lastCompletionTime === thisTime) { + if (this._lastCompletionStart === thisTime) { resolve(false) } else { resolve(true) @@ -651,6 +711,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ // if more typing happened, then do not go forwards with the request if (didTypingHappenDuringDebounce) { + console.log('START4') + return [] } @@ -667,20 +729,24 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ if (numPending >= MAX_PENDING_REQUESTS) { // cancel the oldest pending request and remove it from cache this._autocompletionsOfDocument[docUriStr].delete(oldestPending.id) + console.log('START5') break } } } + console.log('START6') - // NEW: gather relevant context from the code around the user's selection and definitions + // 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 + const justAcceptedAutocompletion = thisTime - this._lastCompletionAccept < 500 + + const { shouldGenerate, predictionType, llmPrefix, llmSuffix, stopTokens } = getCompletionOptions(prefixAndSuffix, relevantContext, justAcceptedAutocompletion) if (!shouldGenerate) return [] @@ -688,6 +754,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ return [] } + + // console.log('B') // create a new autocompletion and add it to cache @@ -706,15 +774,20 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ requestId: null, } + console.log('BBBBBBB') + console.log('PREFIX', JSON.stringify(llmPrefix)) + console.log('SUFFIX', JSON.stringify(llmSuffix)) + console.log('PREDICTION_TYPE', predictionType) + // set parameters of `newAutocompletion` appropriately newAutocompletion.llmPromise = new Promise((resolve, reject) => { const requestId = this._llmMessageService.sendLLMMessage({ type: 'ollamaFIM', - // TODO: Incorporate relevant context directly into the prefix messages: { prefix: llmPrefix, suffix: llmSuffix, + stopTokens: stopTokens, }, logging: { loggingName: 'Autocomplete' }, onText: async ({ fullText }) => { @@ -722,12 +795,13 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ newAutocompletion.insertText = fullText // if generation doesn't match the prefix for the first few tokens generated, reject it - if (!getAutocompletionMatchup({ prefix: this._lastPrefix, autocompletion: newAutocompletion })) { - reject('LLM response did not match user\'s text.') - } + // if (!getAutocompletionMatchup({ prefix: this._lastPrefix, autocompletion: newAutocompletion })) { + // reject('LLM response did not match user\'s text.') + // } }, onFinalMessage: ({ fullText }) => { + console.log('FULL TEXT', JSON.stringify(fullText)) // newAutocompletion.prefix = prefix // newAutocompletion.suffix = suffix // newAutocompletion.startTime = Date.now() @@ -738,6 +812,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ const [text, _] = extractCodeFromRegular({ text: fullText, recentlyAddedTextLen: 0 }) newAutocompletion.insertText = postprocessResult(text) + console.log('RESULT', JSON.stringify(newAutocompletion.insertText)) + resolve(newAutocompletion.insertText) }, @@ -869,14 +945,12 @@ 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; @@ -899,6 +973,8 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ completions.items.forEach(item => { this._autocompletionsOfDocument[docUriStr].items.forEach((autocompletion: Autocompletion) => { if (removeLeftTabsAndTrimEnds(prefix) === removeLeftTabsAndTrimEnds(autocompletion.prefix + autocompletion.insertText)) { + console.log('ACCEPT AUTCOMPLETE', autocompletion.id) + this._lastCompletionAccept = Date.now() this._autocompletionsOfDocument[docUriStr].delete(autocompletion.id); } }); diff --git a/src/vs/workbench/contrib/void/browser/chatThreadService.ts b/src/vs/workbench/contrib/void/browser/chatThreadService.ts index 8c9ad0e5..468708b3 100644 --- a/src/vs/workbench/contrib/void/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/void/browser/chatThreadService.ts @@ -202,6 +202,7 @@ class ChatThreadService extends Disposable implements IChatThreadService { this._setStreamState(threadId, { error: undefined }) const llmCancelToken = this._llmMessageService.sendLLMMessage({ + type: 'sendLLMMessage', logging: { loggingName: 'Chat' }, messages: [ { role: 'system', content: chat_systemMessage },