( llm: ILLM, abortController: AbortController, type: StreamDiffLinesType, prompt: ChatMessage[] | string, prediction: Prediction | undefined, currentBuffer = "", isContinuation = false, )
| 22 | const RECURSIVE_PROMPT = `Continue EXACTLY where you left`; |
| 23 | |
| 24 | export async function* recursiveStream( |
| 25 | llm: ILLM, |
| 26 | abortController: AbortController, |
| 27 | type: StreamDiffLinesType, |
| 28 | prompt: ChatMessage[] | string, |
| 29 | prediction: Prediction | undefined, |
| 30 | currentBuffer = "", |
| 31 | isContinuation = false, |
| 32 | ): AsyncGenerator<string | ChatMessage> { |
| 33 | const maxTokens = llm.completionOptions?.maxTokens ?? DEFAULT_MAX_TOKENS; |
| 34 | const safeTokens = maxTokens * INFINITE_STREAM_SAFETY; |
| 35 | let totalTokens = 0; |
| 36 | let buffer = currentBuffer; |
| 37 | // let whiteSpaceAtEndOfBuffer = buffer.match(/\s*$/)?.[0] ?? ""; // attempts at fixing whitespace bug with recursive boundaries |
| 38 | |
| 39 | const injectApplyToken = type === "apply" && shouldInjectApplyToken(llm); |
| 40 | if (typeof prompt === "string") { |
| 41 | const finalPrompt = injectApplyToken ? prompt + APPLY_UNIQUE_TOKEN : prompt; |
| 42 | |
| 43 | const generator = llm.streamComplete(finalPrompt, abortController.signal, { |
| 44 | raw: true, |
| 45 | prediction: undefined, |
| 46 | reasoning: false, |
| 47 | }); |
| 48 | |
| 49 | for await (const chunk of generator) { |
| 50 | yield chunk; |
| 51 | buffer += chunk; |
| 52 | totalTokens += countTokens(chunk); |
| 53 | |
| 54 | if (totalTokens >= safeTokens) { |
| 55 | throw new Error( |
| 56 | "Token limit reached. File/range likely too large for this edit", |
| 57 | ); |
| 58 | // const continuationPrompt = `${RECURSIVE_PROMPT}:\n\n${buffer}`; |
| 59 | |
| 60 | // await generator.return(DUD_PROMPT_LOG); // kill the previous generator |
| 61 | |
| 62 | // // TODO - Prediction capabilities lost because of partial input |
| 63 | // yield* recursiveStream( |
| 64 | // llm, |
| 65 | // abortController, |
| 66 | // continuationPrompt, |
| 67 | // undefined, |
| 68 | // buffer, |
| 69 | // true, |
| 70 | // ); // Recursively stream the continuation |
| 71 | |
| 72 | // return; |
| 73 | } |
| 74 | } |
| 75 | } else { |
| 76 | const promptMessages = injectApplyToken |
| 77 | ? appendTokenToLastMessage(prompt, APPLY_UNIQUE_TOKEN) |
| 78 | : prompt; |
| 79 | |
| 80 | const generator = llm.streamChat(promptMessages, abortController.signal, { |
| 81 | raw: true, |
no test coverage detected