mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
add new logging algo and move applyDiffLazily to diffProvider
This commit is contained in:
parent
e4e1c7fb6c
commit
36c3cd53e1
11 changed files with 337 additions and 443 deletions
28
extensions/void/package-lock.json
generated
28
extensions/void/package-lock.json
generated
|
|
@ -8,7 +8,7 @@
|
|||
"name": "void",
|
||||
"version": "0.0.1",
|
||||
"devDependencies": {
|
||||
"@anthropic-ai/sdk": "^0.29.2",
|
||||
"@anthropic-ai/sdk": "^0.31.0",
|
||||
"@eslint/js": "^9.9.1",
|
||||
"@google/generative-ai": "^0.21.0",
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"marked": "^14.1.0",
|
||||
"ollama": "^0.5.9",
|
||||
"openai": "^4.68.4",
|
||||
"openai": "^4.70.2",
|
||||
"postcss": "^8.4.41",
|
||||
"posthog-js": "^1.176.0",
|
||||
"react": "^18.3.1",
|
||||
|
|
@ -69,9 +69,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/sdk": {
|
||||
"version": "0.29.2",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.29.2.tgz",
|
||||
"integrity": "sha512-5dwiOPO/AZvhY4bJIG9vjFKU9Kza3hA6VEsbIQg6L9vny2RQIpCFhV50nB9IrG2edZaHZb4HuQ9Wmsn5zgWyZg==",
|
||||
"version": "0.31.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.31.0.tgz",
|
||||
"integrity": "sha512-9EX90YMUtj0d1aHPsnjgurUWAUoNQA/kMaN+UUN7eL3jhl1cijBIGKHQPrR4/ctvD9A065QnzzJDy5Oxb/Bk8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -85,9 +85,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/sdk/node_modules/@types/node": {
|
||||
"version": "18.19.59",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.59.tgz",
|
||||
"integrity": "sha512-vizm2EqwV/7Zay+A6J3tGl9Lhr7CjZe2HmWS988sefiEmsyP9CeXEleho6i4hJk/8UtZAo0bWN4QPZZr83RxvQ==",
|
||||
"version": "18.19.64",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz",
|
||||
"integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -6288,9 +6288,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/openai": {
|
||||
"version": "4.68.4",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-4.68.4.tgz",
|
||||
"integrity": "sha512-LRinV8iU9VQplkr25oZlyrsYGPGasIwYN8KFMAAFTHHLHjHhejtJ5BALuLFrkGzY4wfbKhOhuT+7lcHZ+F3iEA==",
|
||||
"version": "4.70.2",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-4.70.2.tgz",
|
||||
"integrity": "sha512-Q2ymi/KPUYv+LJ9rFxeYxpkVAhcrZFTVvnJbdF1pUHg9eMC6lY8PU4TO1XOK5UZzOZuuVicouRwVMi1iDrT4qw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
|
|
@ -6315,9 +6315,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/openai/node_modules/@types/node": {
|
||||
"version": "18.19.59",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.59.tgz",
|
||||
"integrity": "sha512-vizm2EqwV/7Zay+A6J3tGl9Lhr7CjZe2HmWS988sefiEmsyP9CeXEleho6i4hJk/8UtZAo0bWN4QPZZr83RxvQ==",
|
||||
"version": "18.19.64",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz",
|
||||
"integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@
|
|||
"test": "vscode-test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anthropic-ai/sdk": "^0.29.2",
|
||||
"@anthropic-ai/sdk": "^0.31.0",
|
||||
"@eslint/js": "^9.9.1",
|
||||
"@google/generative-ai": "^0.21.0",
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
|
|
@ -141,7 +141,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"marked": "^14.1.0",
|
||||
"ollama": "^0.5.9",
|
||||
"openai": "^4.68.4",
|
||||
"openai": "^4.70.2",
|
||||
"postcss": "^8.4.41",
|
||||
"posthog-js": "^1.176.0",
|
||||
"react": "^18.3.1",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import OpenAI from 'openai';
|
|||
import { Ollama } from 'ollama'
|
||||
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';
|
||||
|
||||
export type AbortRef = { current: (() => void) | null }
|
||||
|
||||
|
|
@ -26,7 +28,8 @@ type SendLLMMessageFnTypeInternal = (params: {
|
|||
onFinalMessage: OnFinalMessage;
|
||||
onError: (error: string) => void;
|
||||
voidConfig: VoidConfig;
|
||||
abortRef: AbortRef;
|
||||
|
||||
_setAborter: (aborter: () => void) => void;
|
||||
}) => void
|
||||
|
||||
type SendLLMMessageFnTypeExternal = (params: {
|
||||
|
|
@ -36,6 +39,10 @@ type SendLLMMessageFnTypeExternal = (params: {
|
|||
onError: (error: string) => void;
|
||||
voidConfig: VoidConfig | null;
|
||||
abortRef: AbortRef;
|
||||
|
||||
logging: {
|
||||
loggingName: string,
|
||||
};
|
||||
}) => void
|
||||
|
||||
const parseMaxTokensStr = (maxTokensStr: string) => {
|
||||
|
|
@ -47,7 +54,7 @@ const parseMaxTokensStr = (maxTokensStr: string) => {
|
|||
}
|
||||
|
||||
// Anthropic
|
||||
const sendAnthropicMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig }) => {
|
||||
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"]
|
||||
|
||||
|
|
@ -67,17 +74,14 @@ const sendAnthropicMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFi
|
|||
max_tokens: parseMaxTokensStr(voidConfig.default.maxTokens)!, // this might be undefined, but it will just throw an error for the user
|
||||
});
|
||||
|
||||
let did_abort = false
|
||||
|
||||
// when receive text
|
||||
stream.on('text', (newText, fullText) => {
|
||||
if (did_abort) return
|
||||
onText(newText, fullText)
|
||||
})
|
||||
|
||||
// when we get the final message on this stream (or when error/fail)
|
||||
stream.on('finalMessage', (claude_response) => {
|
||||
if (did_abort) return
|
||||
// stringify the response's content
|
||||
const content = claude_response.content.map(c => c.type === 'text' ? c.text : c.type).join('\n');
|
||||
onFinalMessage(content)
|
||||
|
|
@ -93,25 +97,16 @@ const sendAnthropicMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFi
|
|||
}
|
||||
})
|
||||
|
||||
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
|
||||
const abort = () => {
|
||||
did_abort = true
|
||||
stream.controller.abort() // TODO need to test this to make sure it works, it might throw an error
|
||||
}
|
||||
// TODO need to test this to make sure it works, it might throw an error
|
||||
_setAborter(() => stream.controller.abort())
|
||||
|
||||
return { abort }
|
||||
};
|
||||
|
||||
// Gemini
|
||||
const sendGeminiMsg: SendLLMMessageFnTypeInternal = async ({ messages, onText, onFinalMessage, onError, voidConfig, abortRef }) => {
|
||||
const sendGeminiMsg: SendLLMMessageFnTypeInternal = async ({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter }) => {
|
||||
|
||||
let didAbort = false
|
||||
let fullText = ''
|
||||
|
||||
abortRef.current = () => {
|
||||
didAbort = true
|
||||
}
|
||||
|
||||
const genAI = new GoogleGenerativeAI(voidConfig.gemini.apikey);
|
||||
const model = genAI.getGenerativeModel({ model: voidConfig.gemini.model });
|
||||
|
||||
|
|
@ -132,12 +127,9 @@ const sendGeminiMsg: SendLLMMessageFnTypeInternal = async ({ messages, onText, o
|
|||
|
||||
model.generateContentStream({ contents: geminiMessages, systemInstruction: systemMessage, })
|
||||
.then(async response => {
|
||||
abortRef.current = () => {
|
||||
// response.stream.return(fullText)
|
||||
didAbort = true;
|
||||
}
|
||||
_setAborter(() => response.stream.return(fullText))
|
||||
|
||||
for await (const chunk of response.stream) {
|
||||
if (didAbort) return;
|
||||
const newText = chunk.text();
|
||||
fullText += newText;
|
||||
onText(newText, fullText);
|
||||
|
|
@ -160,16 +152,10 @@ const sendGeminiMsg: SendLLMMessageFnTypeInternal = async ({ messages, onText, o
|
|||
}
|
||||
|
||||
// OpenAI, OpenRouter, OpenAICompatible
|
||||
const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, abortRef }) => {
|
||||
const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter }) => {
|
||||
|
||||
let didAbort = false
|
||||
let fullText = ''
|
||||
|
||||
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
|
||||
abortRef.current = () => {
|
||||
didAbort = true;
|
||||
};
|
||||
|
||||
let openai: OpenAI
|
||||
let options: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming
|
||||
|
||||
|
|
@ -201,13 +187,9 @@ const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinal
|
|||
openai.chat.completions
|
||||
.create(options)
|
||||
.then(async response => {
|
||||
abortRef.current = () => {
|
||||
// response.controller.abort()
|
||||
didAbort = true;
|
||||
}
|
||||
_setAborter(() => response.controller.abort())
|
||||
// when receive text
|
||||
for await (const chunk of response) {
|
||||
if (didAbort) return;
|
||||
const newText = chunk.choices[0]?.delta?.content || '';
|
||||
fullText += newText;
|
||||
onText(newText, fullText);
|
||||
|
|
@ -232,16 +214,10 @@ const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinal
|
|||
};
|
||||
|
||||
// Ollama
|
||||
export const sendOllamaMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, abortRef }) => {
|
||||
export const sendOllamaMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter }) => {
|
||||
|
||||
let didAbort = false
|
||||
let fullText = ''
|
||||
|
||||
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
|
||||
abortRef.current = () => {
|
||||
didAbort = true;
|
||||
};
|
||||
|
||||
const ollama = new Ollama({ host: voidConfig.ollama.endpoint })
|
||||
|
||||
ollama.chat({
|
||||
|
|
@ -251,13 +227,9 @@ export const sendOllamaMsg: SendLLMMessageFnTypeInternal = ({ messages, onText,
|
|||
options: { num_predict: parseMaxTokensStr(voidConfig.default.maxTokens) } // this is max_tokens
|
||||
})
|
||||
.then(async stream => {
|
||||
abortRef.current = () => {
|
||||
// stream.abort()
|
||||
didAbort = true
|
||||
}
|
||||
_setAborter(() => stream.abort())
|
||||
// iterate through the stream
|
||||
for await (const chunk of stream) {
|
||||
if (didAbort) return;
|
||||
const newText = chunk.message.content;
|
||||
fullText += newText;
|
||||
onText(newText, fullText);
|
||||
|
|
@ -276,16 +248,10 @@ export const sendOllamaMsg: SendLLMMessageFnTypeInternal = ({ messages, onText,
|
|||
// https://docs.greptile.com/api-reference/query
|
||||
// https://docs.greptile.com/quickstart#sample-response-streamed
|
||||
|
||||
const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, abortRef }) => {
|
||||
const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter }) => {
|
||||
|
||||
let didAbort = false
|
||||
let fullText = ''
|
||||
|
||||
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
|
||||
abortRef.current = () => {
|
||||
didAbort = true
|
||||
}
|
||||
|
||||
fetch('https://api.greptile.com/v2/query', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
@ -306,12 +272,10 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin
|
|||
return JSON.parse(`[${text.trim().split('\n').join(',')}]`)
|
||||
})
|
||||
// TODO make this actually stream, right now it just sends one message at the end
|
||||
// TODO add _setAborter() when add streaming
|
||||
.then(async responseArr => {
|
||||
if (didAbort)
|
||||
return
|
||||
|
||||
for (const response of responseArr) {
|
||||
|
||||
const type: string = response['type']
|
||||
const message = response['message']
|
||||
|
||||
|
|
@ -340,26 +304,90 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin
|
|||
|
||||
}
|
||||
|
||||
export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText, onFinalMessage, onError, voidConfig, abortRef }) => {
|
||||
|
||||
|
||||
|
||||
|
||||
export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({
|
||||
messages,
|
||||
onText: onText_,
|
||||
onFinalMessage: onFinalMessage_,
|
||||
onError: onError_,
|
||||
abortRef: abortRef_,
|
||||
voidConfig,
|
||||
logging: { loggingName }
|
||||
}) => {
|
||||
if (!voidConfig) return;
|
||||
|
||||
// trim message content (Anthropic and other providers give an error if there is trailing whitespace)
|
||||
messages = messages.map(m => ({ ...m, content: m.content.trim() }))
|
||||
|
||||
// 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,
|
||||
})
|
||||
}
|
||||
const submit_time = new Date()
|
||||
|
||||
let _fullTextSoFar = ''
|
||||
let _aborter: (() => void) | null = null
|
||||
let _setAborter = (fn: () => void) => { _aborter = fn }
|
||||
let _didAbort = false
|
||||
|
||||
const onText = (newText: string, fullText: string) => {
|
||||
if (_didAbort) return
|
||||
onText_(newText, fullText)
|
||||
_fullTextSoFar = fullText
|
||||
}
|
||||
|
||||
const onFinalMessage = (fullText: string) => {
|
||||
if (_didAbort) return
|
||||
captureChatEvent(`${loggingName} - Received Full Message`, { messageLength: fullText.length, duration: new Date().getMilliseconds() - submit_time.getMilliseconds() })
|
||||
onFinalMessage_(fullText)
|
||||
}
|
||||
|
||||
const onError = (error: string) => {
|
||||
if (_didAbort) return
|
||||
captureChatEvent(`${loggingName} - Error`, { error })
|
||||
onError_(error)
|
||||
}
|
||||
|
||||
const onAbort = () => {
|
||||
captureChatEvent(`${loggingName} - Abort`, { messageLengthSoFar: _fullTextSoFar.length })
|
||||
_aborter?.()
|
||||
_didAbort = true
|
||||
}
|
||||
abortRef_.current = onAbort
|
||||
|
||||
captureChatEvent(`${loggingName} - Sending Message`, { messageLength: messages[messages.length - 1]?.content.length })
|
||||
|
||||
switch (voidConfig.default.whichApi) {
|
||||
case 'anthropic':
|
||||
return sendAnthropicMsg({ messages, onText, onFinalMessage, onError, voidConfig, abortRef });
|
||||
sendAnthropicMsg({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter, });
|
||||
break;
|
||||
case 'openAI':
|
||||
case 'openRouter':
|
||||
case 'openAICompatible':
|
||||
return sendOpenAIMsg({ messages, onText, onFinalMessage, onError, voidConfig, abortRef });
|
||||
sendOpenAIMsg({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter, });
|
||||
break;
|
||||
case 'gemini':
|
||||
return sendGeminiMsg({ messages, onText, onFinalMessage, onError, voidConfig, abortRef });
|
||||
sendGeminiMsg({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter, });
|
||||
break;
|
||||
case 'ollama':
|
||||
return sendOllamaMsg({ messages, onText, onFinalMessage, onError, voidConfig, abortRef });
|
||||
sendOllamaMsg({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter, });
|
||||
break;
|
||||
case 'greptile':
|
||||
return sendGreptileMsg({ messages, onText, onFinalMessage, onError, voidConfig, abortRef });
|
||||
sendGreptileMsg({ messages, onText, onFinalMessage, onError, voidConfig, _setAborter, });
|
||||
break;
|
||||
default:
|
||||
onError(`Error: whichApi was ${voidConfig.default.whichApi}, which is not recognized!`)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ import { findDiffs } from './findDiffs';
|
|||
import { throttle } from 'lodash';
|
||||
import { DiffArea, BaseDiff, Diff } from '../common/shared_types';
|
||||
import { readFileContentOfUri } from './extensionLib/readFileContentOfUri';
|
||||
import { updateWebviewHTML } from './extensionLib/updateWebviewHTML';
|
||||
import { AbortRef, sendLLMMessage } from '../common/sendLLMMessage';
|
||||
import { writeFileWithDiffInstructions } from '../common/systemPrompts';
|
||||
import { VoidConfig } from '../webviews/common/contextForConfig';
|
||||
|
||||
|
||||
const THROTTLE_TIME = 100
|
||||
|
|
@ -397,8 +399,66 @@ export class DiffProvider implements vscode.CodeLensProvider {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async startStreamingInDiffArea({ docUri, oldFileStr, diffRepr, diffArea, voidConfig, abortRef }: { docUri: vscode.Uri, oldFileStr: string, diffRepr: string, voidConfig: VoidConfig, diffArea: DiffArea, abortRef: AbortRef }) {
|
||||
|
||||
|
||||
const promptContent = `\
|
||||
ORIGINAL_FILE
|
||||
\`\`\`
|
||||
${oldFileStr}
|
||||
\`\`\`
|
||||
|
||||
DIFF
|
||||
\`\`\`
|
||||
${diffRepr}
|
||||
\`\`\`
|
||||
|
||||
INSTRUCTIONS
|
||||
Please finish writing the new file by applying the diff to the original file. Return ONLY the completion of the file, without any explanation.
|
||||
|
||||
`
|
||||
// ask LLM to rewrite file with diff (if there is significant matchup with the original file, we stop rewriting)
|
||||
const START = new Date().getTime()
|
||||
|
||||
// make LLM complete the file to include the diff
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
sendLLMMessage({
|
||||
logging: { loggingName: 'streamChunk' },
|
||||
messages: [
|
||||
{ role: 'system', content: writeFileWithDiffInstructions, },
|
||||
// TODO include more context too
|
||||
{ role: 'user', content: promptContent, }
|
||||
],
|
||||
onText: (newText, fullText) => {
|
||||
this._updateStream(docUri.toString(), diffArea, fullText)
|
||||
},
|
||||
onFinalMessage: (fullText) => {
|
||||
this._updateStream(docUri.toString(), diffArea, fullText)
|
||||
resolve();
|
||||
},
|
||||
onError: (e) => {
|
||||
console.error('Error rewriting file with diff', e);
|
||||
resolve();
|
||||
},
|
||||
voidConfig,
|
||||
abortRef,
|
||||
})
|
||||
})
|
||||
|
||||
const END = new Date().getTime()
|
||||
console.log('EDIT CHUNK time: ', END - START);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// used by us only
|
||||
public updateStream = throttle(async (docUriStr: string, diffArea: DiffArea, newDiffAreaCode: string) => {
|
||||
private _updateStream = throttle(async (docUriStr: string, diffArea: DiffArea, newDiffAreaCode: string) => {
|
||||
|
||||
const editor = vscode.window.activeTextEditor // TODO the editor should be that of `docUri` and not necessarily the current editor
|
||||
if (!editor) {
|
||||
|
|
|
|||
|
|
@ -1,180 +1,181 @@
|
|||
import type * as vscode from 'vscode';
|
||||
// import type * as vscode from 'vscode';
|
||||
|
||||
import { AbortRef, sendLLMMessage } from '../common/sendLLMMessage';
|
||||
import { DiffArea } from '../common/shared_types';
|
||||
import { writeFileWithDiffInstructions, searchDiffChunkInstructions } from '../common/systemPrompts';
|
||||
import { VoidConfig } from '../webviews/common/contextForConfig';
|
||||
import { DiffProvider } from './DiffProvider';
|
||||
import { readFileContentOfUri } from './extensionLib/readFileContentOfUri';
|
||||
// import { AbortRef, sendLLMMessage } from '../common/sendLLMMessage';
|
||||
// import { DiffArea } from '../common/shared_types';
|
||||
// import { writeFileWithDiffInstructions, searchDiffChunkInstructions } from '../common/systemPrompts';
|
||||
// import { VoidConfig } from '../webviews/common/contextForConfig';
|
||||
// import { DiffProvider } from './DiffProvider';
|
||||
// import { readFileContentOfUri } from './extensionLib/readFileContentOfUri';
|
||||
|
||||
const LINES_PER_CHUNK = 20 // number of lines to search at a time
|
||||
// const LINES_PER_CHUNK = 20 // number of lines to search at a time
|
||||
|
||||
|
||||
type CompetedReturn = { isFinished: true, } | { isFinished?: undefined, }
|
||||
const streamChunk = ({ diffProvider, docUri, oldFileStr, completedStr, diffRepr, diffArea, voidConfig, abortRef }: { diffProvider: DiffProvider, docUri: vscode.Uri, oldFileStr: string, completedStr: string, diffRepr: string, voidConfig: VoidConfig, diffArea: DiffArea, abortRef: AbortRef }) => {
|
||||
// type CompetedReturn = { isFinished: true, } | { isFinished?: undefined, }
|
||||
// const streamChunk = ({ diffProvider, docUri, oldFileStr, completedStr, diffRepr, diffArea, voidConfig, abortRef }: { diffProvider: DiffProvider, docUri: vscode.Uri, oldFileStr: string, completedStr: string, diffRepr: string, voidConfig: VoidConfig, diffArea: DiffArea, abortRef: AbortRef }) => {
|
||||
|
||||
const promptContent = `ORIGINAL_FILE
|
||||
\`\`\`
|
||||
${oldFileStr}
|
||||
\`\`\`
|
||||
// const promptContent = `ORIGINAL_FILE
|
||||
// \`\`\`
|
||||
// ${oldFileStr}
|
||||
// \`\`\`
|
||||
|
||||
DIFF
|
||||
\`\`\`
|
||||
${diffRepr}
|
||||
\`\`\`
|
||||
|
||||
INSTRUCTIONS
|
||||
Please finish writing the new file \`NEW_FILE\`. Return ONLY the completion of the file, without any explanation.
|
||||
|
||||
NEW_FILE
|
||||
\`\`\`
|
||||
${completedStr}
|
||||
\`\`\`
|
||||
`
|
||||
// create a promise that can be awaited
|
||||
return new Promise<CompetedReturn>((resolve, reject) => {
|
||||
|
||||
let isAnyChangeSoFar = false
|
||||
|
||||
// make LLM complete the file to include the diff
|
||||
sendLLMMessage({
|
||||
messages: [{ role: 'system', content: writeFileWithDiffInstructions, }, { role: 'user', content: promptContent, }],
|
||||
onText: (newText, fullText) => {
|
||||
const fullCompletedStr = completedStr + fullText
|
||||
|
||||
diffProvider.updateStream(docUri.toString(), diffArea, fullCompletedStr)
|
||||
|
||||
// if there was any change from the original file
|
||||
if (!oldFileStr.includes(fullCompletedStr)) {
|
||||
isAnyChangeSoFar = true
|
||||
}
|
||||
|
||||
|
||||
const isRecentMatchup = false
|
||||
// the final NUM_MATCHUP_TOKENS characters of fullCompletedStr are the same as the final NUM_MATCHUP_TOKENS characters of the last item in the diffs of oldFileStr that had 0 changes
|
||||
|
||||
if (isAnyChangeSoFar && isRecentMatchup) {
|
||||
diffProvider.updateStream(docUri.toString(), diffArea, fullCompletedStr)
|
||||
|
||||
// TODO resolve the promise
|
||||
// resolve({ speculativeIndex: newCurrentLine + 1 });
|
||||
|
||||
// abort the LLM call
|
||||
abortRef.current?.()
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
onFinalMessage: (fullText) => {
|
||||
const newCompletedStr = completedStr + fullText
|
||||
diffProvider.updateStream(docUri.toString(), diffArea, newCompletedStr)
|
||||
resolve({ isFinished: true });
|
||||
},
|
||||
onError: (e) => {
|
||||
resolve({ isFinished: true });
|
||||
console.error('Error rewriting file with diff', e);
|
||||
},
|
||||
voidConfig,
|
||||
abortRef,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// const shouldApplyDiff = ({ diffRepr, oldFileStr: fileStr, speculationStr, voidConfig, abortRef }: { diffRepr: string, oldFileStr: string, speculationStr: string, voidConfig: VoidConfig, abortRef: AbortRef }) => {
|
||||
|
||||
// const promptContent = `DIFF
|
||||
// DIFF
|
||||
// \`\`\`
|
||||
// ${diffRepr}
|
||||
// \`\`\`
|
||||
|
||||
// FILES
|
||||
// \`\`\`
|
||||
// ${fileStr}
|
||||
// \`\`\`
|
||||
// INSTRUCTIONS
|
||||
// Please finish writing the new file \`NEW_FILE\`. Return ONLY the completion of the file, without any explanation.
|
||||
|
||||
// SELECTION
|
||||
// NEW_FILE
|
||||
// \`\`\`
|
||||
// ${speculationStr}
|
||||
// ${completedStr}
|
||||
// \`\`\`
|
||||
|
||||
// Return \`true\` if ANY part of the chunk should be modified, and \`false\` if it should not be modified. You should respond only with \`true\` or \`false\` and nothing else.
|
||||
// `
|
||||
// // create a promise that can be awaited
|
||||
// return new Promise<CompetedReturn>((resolve, reject) => {
|
||||
|
||||
// // create new promise
|
||||
// return new Promise<boolean>((resolve, reject) => {
|
||||
// // send message to LLM
|
||||
// let isAnyChangeSoFar = false
|
||||
|
||||
// // make LLM complete the file to include the diff
|
||||
// sendLLMMessage({
|
||||
// messages: [{ role: 'system', content: searchDiffChunkInstructions, }, { role: 'user', content: promptContent, }],
|
||||
// onFinalMessage: (finalMessage) => {
|
||||
// logging: { loggingName: 'applyDiffLazily' },
|
||||
// messages: [{ role: 'system', content: writeFileWithDiffInstructions, }, { role: 'user', content: promptContent, }],
|
||||
// onText: (newText, fullText) => {
|
||||
// const fullCompletedStr = completedStr + fullText
|
||||
|
||||
// const containsTrue = finalMessage
|
||||
// .slice(-10) // check for `true` in last 10 characters
|
||||
// .toLowerCase()
|
||||
// .includes('true')
|
||||
// diffProvider.updateStream(docUri.toString(), diffArea, fullCompletedStr)
|
||||
|
||||
// resolve(containsTrue)
|
||||
// // if there was any change from the original file
|
||||
// if (!oldFileStr.includes(fullCompletedStr)) {
|
||||
// isAnyChangeSoFar = true
|
||||
// }
|
||||
|
||||
|
||||
// const isRecentMatchup = false
|
||||
// // the final NUM_MATCHUP_TOKENS characters of fullCompletedStr are the same as the final NUM_MATCHUP_TOKENS characters of the last item in the diffs of oldFileStr that had 0 changes
|
||||
|
||||
// if (isAnyChangeSoFar && isRecentMatchup) {
|
||||
// diffProvider.updateStream(docUri.toString(), diffArea, fullCompletedStr)
|
||||
|
||||
// // TODO resolve the promise
|
||||
// // resolve({ speculativeIndex: newCurrentLine + 1 });
|
||||
|
||||
// // abort the LLM call
|
||||
// abortRef.current?.()
|
||||
|
||||
// }
|
||||
|
||||
// },
|
||||
|
||||
// onFinalMessage: (fullText) => {
|
||||
// const newCompletedStr = completedStr + fullText
|
||||
// diffProvider.updateStream(docUri.toString(), diffArea, newCompletedStr)
|
||||
// resolve({ isFinished: true });
|
||||
// },
|
||||
// onError: (e) => {
|
||||
// resolve(false);
|
||||
// console.error('Error in shouldApplyDiff: ', e)
|
||||
// resolve({ isFinished: true });
|
||||
// console.error('Error rewriting file with diff', e);
|
||||
// },
|
||||
// onText: () => { },
|
||||
// voidConfig,
|
||||
// abortRef,
|
||||
// })
|
||||
|
||||
// })
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// // const shouldApplyDiff = ({ diffRepr, oldFileStr: fileStr, speculationStr, voidConfig, abortRef }: { diffRepr: string, oldFileStr: string, speculationStr: string, voidConfig: VoidConfig, abortRef: AbortRef }) => {
|
||||
|
||||
// lazily applies the diff to the file
|
||||
// we chunk the text in the file, and ask an LLM whether it should edit each chunk
|
||||
export const applyDiffLazily = async ({ docUri, oldFileStr, voidConfig, abortRef, diffRepr, diffProvider, diffArea }: { docUri: vscode.Uri, oldFileStr: string, diffRepr: string, voidConfig: VoidConfig, diffProvider: DiffProvider, diffArea: DiffArea, abortRef: AbortRef }) => {
|
||||
// // const promptContent = `DIFF
|
||||
// // \`\`\`
|
||||
// // ${diffRepr}
|
||||
// // \`\`\`
|
||||
|
||||
// // FILES
|
||||
// // \`\`\`
|
||||
// // ${fileStr}
|
||||
// // \`\`\`
|
||||
|
||||
// // SELECTION
|
||||
// // \`\`\`
|
||||
// // ${speculationStr}
|
||||
// // \`\`\`
|
||||
|
||||
// // Return \`true\` if ANY part of the chunk should be modified, and \`false\` if it should not be modified. You should respond only with \`true\` or \`false\` and nothing else.
|
||||
// // `
|
||||
|
||||
// // // create new promise
|
||||
// // return new Promise<boolean>((resolve, reject) => {
|
||||
// // // send message to LLM
|
||||
// // sendLLMMessage({
|
||||
// // messages: [{ role: 'system', content: searchDiffChunkInstructions, }, { role: 'user', content: promptContent, }],
|
||||
// // onFinalMessage: (finalMessage) => {
|
||||
|
||||
// // const containsTrue = finalMessage
|
||||
// // .slice(-10) // check for `true` in last 10 characters
|
||||
// // .toLowerCase()
|
||||
// // .includes('true')
|
||||
|
||||
// // resolve(containsTrue)
|
||||
// // },
|
||||
// // onError: (e) => {
|
||||
// // resolve(false);
|
||||
// // console.error('Error in shouldApplyDiff: ', e)
|
||||
// // },
|
||||
// // onText: () => { },
|
||||
// // voidConfig,
|
||||
// // abortRef,
|
||||
// // })
|
||||
|
||||
// // })
|
||||
|
||||
// // }
|
||||
|
||||
|
||||
// stateful variables
|
||||
let speculativeIndex = 0
|
||||
let writtenTextSoFar: string[] = []
|
||||
|
||||
while (speculativeIndex < oldFileStr.split('\n').length) {
|
||||
|
||||
const chunkStr = oldFileStr.split('\n').slice(speculativeIndex, speculativeIndex + LINES_PER_CHUNK).join('\n')
|
||||
|
||||
// ask LLM if we should apply the diff to the chunk
|
||||
const START = new Date().getTime()
|
||||
let shouldApplyDiff_ = true; //await shouldApplyDiff({ oldFileStr, speculationStr: chunkStr, diffRepr, voidConfig, abortRef })
|
||||
const END = new Date().getTime()
|
||||
|
||||
// if should not change the chunk
|
||||
if (!shouldApplyDiff_) {
|
||||
console.log('KEEP CHUNK time: ', END - START)
|
||||
speculativeIndex += LINES_PER_CHUNK
|
||||
writtenTextSoFar.push(chunkStr)
|
||||
// diffProvider.updateStream(docUri.toString(), diffArea, writtenTextSoFar.join('\n'))
|
||||
continue;
|
||||
}
|
||||
|
||||
// ask LLM to rewrite file with diff (if there is significant matchup with the original file, we stop rewriting)
|
||||
const START2 = new Date().getTime()
|
||||
const completedStr = (await readFileContentOfUri(docUri)).split('\n').slice(0, speculativeIndex).join('\n');
|
||||
const result = await streamChunk({ diffProvider, docUri, oldFileStr, completedStr, diffRepr, voidConfig, diffArea, abortRef, })
|
||||
const END2 = new Date().getTime()
|
||||
|
||||
console.log('EDIT CHUNK time: ', END2 - START2);
|
||||
|
||||
// if we are finished, stop the loop
|
||||
if (result.isFinished) {
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// speculativeIndex = result.speculativeIndex
|
||||
|
||||
}
|
||||
// // lazily applies the diff to the file
|
||||
// // we chunk the text in the file, and ask an LLM whether it should edit each chunk
|
||||
// export const applyDiffLazily = async ({ docUri, oldFileStr, voidConfig, abortRef, diffRepr, diffProvider, diffArea }: { docUri: vscode.Uri, oldFileStr: string, diffRepr: string, voidConfig: VoidConfig, diffProvider: DiffProvider, diffArea: DiffArea, abortRef: AbortRef }) => {
|
||||
|
||||
|
||||
}
|
||||
// // stateful variables
|
||||
// let speculativeIndex = 0
|
||||
// let writtenTextSoFar: string[] = []
|
||||
|
||||
// while (speculativeIndex < oldFileStr.split('\n').length) {
|
||||
|
||||
// const chunkStr = oldFileStr.split('\n').slice(speculativeIndex, speculativeIndex + LINES_PER_CHUNK).join('\n')
|
||||
|
||||
// // ask LLM if we should apply the diff to the chunk
|
||||
// const START = new Date().getTime()
|
||||
// let shouldApplyDiff_ = true; //await shouldApplyDiff({ oldFileStr, speculationStr: chunkStr, diffRepr, voidConfig, abortRef })
|
||||
// const END = new Date().getTime()
|
||||
|
||||
// // if should not change the chunk
|
||||
// if (!shouldApplyDiff_) {
|
||||
// console.log('KEEP CHUNK time: ', END - START)
|
||||
// speculativeIndex += LINES_PER_CHUNK
|
||||
// writtenTextSoFar.push(chunkStr)
|
||||
// // diffProvider.updateStream(docUri.toString(), diffArea, writtenTextSoFar.join('\n'))
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // ask LLM to rewrite file with diff (if there is significant matchup with the original file, we stop rewriting)
|
||||
// const START2 = new Date().getTime()
|
||||
// const completedStr = (await readFileContentOfUri(docUri)).split('\n').slice(0, speculativeIndex).join('\n');
|
||||
// const result = await streamChunk({ diffProvider, docUri, oldFileStr, completedStr, diffRepr, voidConfig, diffArea, abortRef, })
|
||||
// const END2 = new Date().getTime()
|
||||
|
||||
// console.log('EDIT CHUNK time: ', END2 - START2);
|
||||
|
||||
// // if we are finished, stop the loop
|
||||
// if (result.isFinished) {
|
||||
// break;
|
||||
// }
|
||||
|
||||
// // TODO
|
||||
// // speculativeIndex = result.speculativeIndex
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ Complete the following:
|
|||
|
||||
// update stream
|
||||
sendLLMMessage({
|
||||
logging: { loggingName: 'Ctrl+K' },
|
||||
messages: [{ role: 'user', content: promptContent, }],
|
||||
onText: async (tokenStr, completionStr) => {
|
||||
// TODO update stream
|
||||
|
|
@ -97,4 +98,4 @@ Complete the following:
|
|||
|
||||
|
||||
|
||||
export { applyCtrlK }
|
||||
export { applyCtrlK }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { v4 as uuidv4 } from 'uuid'
|
|||
import { AbortRef } from '../common/sendLLMMessage';
|
||||
import { MessageToSidebar, MessageFromSidebar, DiffArea, ChatThreads } from '../common/shared_types';
|
||||
import { getVoidConfigFromPartial } from '../webviews/common/contextForConfig';
|
||||
import { applyDiffLazily } from './applyDiffLazily';
|
||||
import { DiffProvider } from './DiffProvider';
|
||||
import { readFileContentOfUri } from './extensionLib/readFileContentOfUri';
|
||||
import { SidebarWebviewProvider } from './providers/SidebarWebviewProvider';
|
||||
|
|
@ -131,7 +130,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
const fileStr = await readFileContentOfUri(docUri)
|
||||
const voidConfig = getVoidConfigFromPartial(context.globalState.get('partialVoidConfig') ?? {})
|
||||
|
||||
await applyDiffLazily({ docUri, oldFileStr: fileStr, diffRepr: m.diffRepr, voidConfig, diffProvider, diffArea, abortRef: abortApplyRef })
|
||||
await diffProvider.startStreamingInDiffArea({ docUri, oldFileStr: fileStr, diffRepr: m.diffRepr, voidConfig, diffArea, abortRef: abortApplyRef })
|
||||
}
|
||||
else if (m.type === 'getPartialVoidConfig') {
|
||||
const partialVoidConfig = context.globalState.get('partialVoidConfig') ?? {}
|
||||
|
|
|
|||
|
|
@ -167,21 +167,6 @@ export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject<HT
|
|||
|
||||
|
||||
|
||||
// only captures number of messages and message "shape", no actual code, instructions, prompts, etc
|
||||
const captureChatEvent = useCallback((eventId: string, extras?: object) => {
|
||||
const whichApi = voidConfig.default['whichApi']
|
||||
const messages = getCurrentThread()?.messages
|
||||
|
||||
captureEvent(eventId, {
|
||||
whichApi: whichApi,
|
||||
numMessages: messages?.length,
|
||||
messagesShape: messages?.map(msg => ({ role: msg.role, length: msg.displayContent?.length })),
|
||||
version: '2024-10-19',
|
||||
...extras,
|
||||
})
|
||||
}, [getCurrentThread, voidConfig.default])
|
||||
|
||||
|
||||
// if they pressed the + to add a new chat
|
||||
useOnVSCodeMessage('startNewThread', (m) => {
|
||||
const allThreads = getAllThreads()
|
||||
|
|
@ -235,15 +220,12 @@ export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject<HT
|
|||
const newHistoryElt: ChatMessage = { role: 'user', content: userContent, displayContent: instructions, selection, files }
|
||||
addMessageToHistory(newHistoryElt)
|
||||
|
||||
captureChatEvent('Chat - Sending Message', { messageLength: instructions.length })
|
||||
const submit_time = new Date()
|
||||
|
||||
// send message to LLM
|
||||
sendLLMMessage({
|
||||
logging: { loggingName: 'Chat' },
|
||||
messages: [...(getCurrentThread()?.messages ?? []).map(m => ({ role: m.role, content: m.content })),],
|
||||
onText: (newText, fullText) => setMessageStream(fullText),
|
||||
onFinalMessage: (content) => {
|
||||
captureChatEvent('Chat - Received Full Message', { messageLength: content.length, duration: new Date().getMilliseconds() - submit_time.getMilliseconds() })
|
||||
|
||||
// add assistant's message to chat history, and clear selection
|
||||
const newHistoryElt: ChatMessage = { role: 'assistant', content, displayContent: content }
|
||||
|
|
@ -252,8 +234,6 @@ export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject<HT
|
|||
setIsLoading(false)
|
||||
},
|
||||
onError: (error) => {
|
||||
captureChatEvent('Chat - Error', { error })
|
||||
|
||||
// add assistant's message to chat history, and clear selection
|
||||
let content = messageStream; // just use the current content
|
||||
const newHistoryElt: ChatMessage = { role: 'assistant', content, displayContent: content, }
|
||||
|
|
@ -271,9 +251,6 @@ export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject<HT
|
|||
}
|
||||
|
||||
const onAbort = useCallback(() => {
|
||||
|
||||
captureChatEvent('Chat - Abort', { messageLengthSoFar: messageStream.length })
|
||||
|
||||
// abort claude
|
||||
abortFnRef.current?.()
|
||||
|
||||
|
|
@ -285,7 +262,7 @@ export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject<HT
|
|||
setMessageStream('')
|
||||
setIsLoading(false)
|
||||
|
||||
}, [captureChatEvent, messageStream, addMessageToHistory])
|
||||
}, [messageStream, addMessageToHistory])
|
||||
|
||||
|
||||
return <>
|
||||
|
|
|
|||
197
package-lock.json
generated
197
package-lock.json
generated
|
|
@ -10,8 +10,6 @@
|
|||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.31.0",
|
||||
"@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",
|
||||
|
|
@ -45,9 +43,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",
|
||||
"openai": "^4.70.2",
|
||||
"tas-client-umd": "0.2.0",
|
||||
"v8-inspect-profiler": "^0.1.1",
|
||||
"vscode-oniguruma": "1.7.0",
|
||||
|
|
@ -184,30 +180,6 @@
|
|||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/sdk": {
|
||||
"version": "0.31.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.31.0.tgz",
|
||||
"integrity": "sha512-9EX90YMUtj0d1aHPsnjgurUWAUoNQA/kMaN+UUN7eL3jhl1cijBIGKHQPrR4/ctvD9A065QnzzJDy5Oxb/Bk8A==",
|
||||
"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/@anthropic-ai/sdk/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/@azure-rest/ai-translation-text": {
|
||||
"version": "1.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure-rest/ai-translation-text/-/ai-translation-text-1.0.0-beta.1.tgz",
|
||||
|
|
@ -1163,15 +1135,6 @@
|
|||
"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",
|
||||
|
|
@ -2268,6 +2231,7 @@
|
|||
"version": "20.14.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.13.tgz",
|
||||
"integrity": "sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
|
|
@ -2276,6 +2240,7 @@
|
|||
"version": "2.6.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz",
|
||||
"integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
|
|
@ -3606,18 +3571,6 @@
|
|||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"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/accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
|
|
@ -3681,18 +3634,6 @@
|
|||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"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/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
|
|
@ -4238,7 +4179,8 @@
|
|||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/atob": {
|
||||
"version": "2.1.2",
|
||||
|
|
@ -5273,6 +5215,7 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
|
|
@ -5284,6 +5227,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
|
|
@ -6949,15 +6893,6 @@
|
|||
"through": "~2.3.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/events": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
|
||||
|
|
@ -7789,6 +7724,7 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
|
|
@ -7798,25 +7734,6 @@
|
|||
"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/fragment-cache": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
|
||||
|
|
@ -10902,15 +10819,6 @@
|
|||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"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/husky": {
|
||||
"version": "0.13.4",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-0.13.4.tgz",
|
||||
|
|
@ -13328,6 +13236,7 @@
|
|||
"version": "1.45.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
|
|
@ -13336,6 +13245,7 @@
|
|||
"version": "2.1.28",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.45.0"
|
||||
},
|
||||
|
|
@ -13924,29 +13834,11 @@
|
|||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
|
||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A=="
|
||||
},
|
||||
"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.6.8",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz",
|
||||
"integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
|
|
@ -14474,15 +14366,6 @@
|
|||
"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",
|
||||
|
|
@ -14549,41 +14432,6 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/openai": {
|
||||
"version": "4.70.2",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-4.70.2.tgz",
|
||||
"integrity": "sha512-Q2ymi/KPUYv+LJ9rFxeYxpkVAhcrZFTVvnJbdF1pUHg9eMC6lY8PU4TO1XOK5UZzOZuuVicouRwVMi1iDrT4qw==",
|
||||
"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/openai/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/opn": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz",
|
||||
|
|
@ -19007,7 +18855,8 @@
|
|||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tree-kill": {
|
||||
"version": "1.2.2",
|
||||
|
|
@ -19433,7 +19282,8 @@
|
|||
"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=="
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/union-value": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -19910,15 +19760,6 @@
|
|||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"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/web-tree-sitter": {
|
||||
"version": "0.20.8",
|
||||
"resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.8.tgz",
|
||||
|
|
@ -19928,7 +19769,8 @@
|
|||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.94.0",
|
||||
|
|
@ -20185,16 +20027,11 @@
|
|||
"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",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0= sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@
|
|||
"update-build-ts-version": "npm install typescript@next && tsc -p ./build/tsconfig.build.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.31.0",
|
||||
"@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",
|
||||
|
|
@ -107,9 +105,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",
|
||||
"openai": "^4.70.2",
|
||||
"tas-client-umd": "0.2.0",
|
||||
"v8-inspect-profiler": "^0.1.1",
|
||||
"vscode-oniguruma": "1.7.0",
|
||||
|
|
|
|||
|
|
@ -27,11 +27,6 @@ class InlineDiffService extends Disposable implements IInlineDiffService {
|
|||
initStream() {
|
||||
|
||||
|
||||
|
||||
|
||||
// start streaming
|
||||
// const streamChunk = ({ diffProvider, docUri, oldFileStr, completedStr, diffRepr, diffArea, voidConfig, abortRef }: { diffProvider: DiffProvider, docUri: vscode.Uri, oldFileStr: string, completedStr: string, diffRepr: string, voidConfig: VoidConfig, diffArea: DiffArea, abortRef: AbortRef }) => {
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue