add new logging algo and move applyDiffLazily to diffProvider

This commit is contained in:
Andrew 2024-11-03 00:31:32 -07:00
parent e4e1c7fb6c
commit 36c3cd53e1
11 changed files with 337 additions and 443 deletions

View file

@ -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": {

View file

@ -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",

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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
// }
// }

View file

@ -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 }

View file

@ -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') ?? {}

View file

@ -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
View file

@ -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"

View file

@ -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",

View file

@ -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 }) => {
// }
}