Skip to content

Commit cf54304

Browse files
authored
Merge pull request #5907 from continuedev/dallin/cancelable-apply-2
2 parents 0d02784 + ae97f1d commit cf54304

File tree

25 files changed

+190
-98
lines changed

25 files changed

+190
-98
lines changed

core/commands/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export function slashFromCustomCommand(
2525
config,
2626
selectedCode,
2727
fetch,
28+
abortController,
2829
}) {
2930
// Render prompt template
3031
let renderedPrompt: string;
@@ -63,7 +64,7 @@ export function slashFromCustomCommand(
6364

6465
for await (const chunk of llm.streamChat(
6566
messages,
66-
new AbortController().signal,
67+
abortController.signal,
6768
completionOptions,
6869
)) {
6970
yield renderChatMessage(chunk);

core/commands/slash/commit.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { renderChatMessage } from "../../util/messageContent.js";
44
const CommitMessageCommand: SlashCommand = {
55
name: "commit",
66
description: "Generate a commit message for current changes",
7-
run: async function* ({ ide, llm, params }) {
7+
run: async function* ({ ide, llm, params, abortController }) {
88
const includeUnstaged = params?.includeUnstaged ?? false;
99
const diff = await ide.getDiff(includeUnstaged);
1010

@@ -16,7 +16,7 @@ const CommitMessageCommand: SlashCommand = {
1616
const prompt = `${diff.join("\n")}\n\nGenerate a commit message for the above set of changes. First, give a single sentence, no more than 80 characters. Then, after 2 line breaks, give a list of no more than 5 short bullet points, each no more than 40 characters. Output nothing except for the commit message, and don't surround it in quotes.`;
1717
for await (const chunk of llm.streamChat(
1818
[{ role: "user", content: prompt }],
19-
new AbortController().signal,
19+
abortController.signal,
2020
)) {
2121
yield renderChatMessage(chunk);
2222
}

core/commands/slash/draftIssue.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Body:\n\n`;
2424
const DraftIssueCommand: SlashCommand = {
2525
name: "issue",
2626
description: "Draft a GitHub issue",
27-
run: async function* ({ input, llm, history, params }) {
27+
run: async function* ({ input, llm, history, params, abortController }) {
2828
if (params?.repositoryUrl === undefined) {
2929
yield "This command requires a repository URL to be set in the config file.";
3030
return;
@@ -46,7 +46,7 @@ const DraftIssueCommand: SlashCommand = {
4646

4747
for await (const chunk of llm.streamChat(
4848
messages,
49-
new AbortController().signal,
49+
abortController.signal,
5050
)) {
5151
body += chunk.content;
5252
yield renderChatMessage(chunk);

core/commands/slash/mcp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function constructMcpSlashCommand(
6060

6161
for await (const chunk of context.llm.streamChat(
6262
messages,
63-
new AbortController().signal,
63+
context.abortController.signal,
6464
context.completionOptions,
6565
)) {
6666
yield renderChatMessage(chunk);

core/commands/slash/onboard.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ const MAX_EXPLORE_DEPTH = 2;
4141
const OnboardSlashCommand: SlashCommand = {
4242
name: "onboard",
4343
description: "Familiarize yourself with the codebase",
44-
run: async function* ({ llm, ide }) {
44+
run: async function* ({ llm, ide, abortController }) {
4545
const [workspaceDir] = await ide.getWorkspaceDirs();
4646

4747
const context = await gatherProjectContext(workspaceDir, ide);
4848
const prompt = createOnboardingPrompt(context);
4949

5050
for await (const chunk of llm.streamChat(
5151
[{ role: "user", content: prompt }],
52-
new AbortController().signal,
52+
abortController.signal,
5353
)) {
5454
yield renderChatMessage(chunk);
5555
}

core/commands/slash/review.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ function getLastUserHistory(history: ChatMessage[]): string {
3838
const ReviewMessageCommand: SlashCommand = {
3939
name: "review",
4040
description: "Review code and give feedback",
41-
run: async function* ({ llm, history }) {
41+
run: async function* ({ llm, history, abortController }) {
4242
const reviewText = getLastUserHistory(history).replace("\\review", "");
4343

4444
const content = `${prompt} \r\n ${reviewText}`;
4545

4646
for await (const chunk of llm.streamChat(
4747
[{ role: "user", content: content }],
48-
new AbortController().signal,
48+
abortController.signal,
4949
)) {
5050
yield renderChatMessage(chunk);
5151
}

core/core.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import {
5858
import { createNewWorkspaceBlockFile } from "./config/workspace/workspaceBlocks";
5959
import { MCPManagerSingleton } from "./context/mcp/MCPManagerSingleton";
6060
import { setMdmLicenseKey } from "./control-plane/mdm/mdm";
61+
import { ApplyAbortManager } from "./edit/applyAbortManager";
6162
import { streamDiffLines } from "./edit/streamDiffLines";
6263
import { shouldIgnore } from "./indexing/shouldIgnore";
6364
import { walkDirCache } from "./indexing/walkDir";
@@ -67,7 +68,6 @@ import { llmStreamChat } from "./llm/streamChat";
6768
import type { FromCoreProtocol, ToCoreProtocol } from "./protocol";
6869
import { OnboardingModes } from "./protocol/core";
6970
import type { IMessenger, Message } from "./protocol/messenger";
70-
import { StreamAbortManager } from "./util/abortManager";
7171
import { getUriPathBasename } from "./util/uri";
7272

7373
const hasRulesFiles = (uris: string[]): boolean => {
@@ -512,6 +512,11 @@ export class Core {
512512
throw new Error("No model selected");
513513
}
514514

515+
const abortManager = ApplyAbortManager.getInstance();
516+
const abortController = abortManager.get(
517+
data.fileUri ?? "current-file-stream",
518+
); // not super important since currently cancelling apply will cancel all streams it's one file at a time
519+
515520
return streamDiffLines({
516521
highlighted: data.highlighted,
517522
prefix: data.prefix,
@@ -525,13 +530,13 @@ export class Core {
525530
language: data.language,
526531
onlyOneInsertion: false,
527532
overridePrompt: undefined,
528-
abortControllerId: data.fileUri ?? "current-file-stream", // not super important since currently cancelling apply will cancel all streams it's one file at a time
533+
abortController,
529534
});
530535
});
531536

532537
on("cancelApply", async (msg) => {
533-
const abortManager = StreamAbortManager.getInstance();
534-
abortManager.clear();
538+
const abortManager = ApplyAbortManager.getInstance();
539+
abortManager.clear(); // for now abort all streams
535540
});
536541

537542
on("onboarding/complete", this.handleCompleteOnboarding.bind(this));

core/util/abortManager.ts renamed to core/edit/applyAbortManager.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
export class StreamAbortManager {
2-
private static instance: StreamAbortManager;
1+
export class ApplyAbortManager {
2+
private static instance: ApplyAbortManager;
33
private controllers: Map<string, AbortController>;
44

55
private constructor() {
66
this.controllers = new Map();
77
}
88

9-
public static getInstance(): StreamAbortManager {
10-
if (!StreamAbortManager.instance) {
11-
StreamAbortManager.instance = new StreamAbortManager();
9+
public static getInstance(): ApplyAbortManager {
10+
if (!ApplyAbortManager.instance) {
11+
ApplyAbortManager.instance = new ApplyAbortManager();
1212
}
13-
return StreamAbortManager.instance;
13+
return ApplyAbortManager.instance;
1414
}
1515

1616
public get(id: string): AbortController {

core/edit/lazy/applyCodeBlock.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export async function applyCodeBlock(
1616
newLazyFile: string,
1717
filename: string,
1818
llm: ILLM,
19+
abortController: AbortController,
1920
): Promise<{
2021
isInstantApply: boolean;
2122
diffLinesGenerator: AsyncGenerator<DiffLine>;
@@ -51,6 +52,12 @@ export async function applyCodeBlock(
5152

5253
return {
5354
isInstantApply: false,
54-
diffLinesGenerator: streamLazyApply(oldFile, filename, newLazyFile, llm),
55+
diffLinesGenerator: streamLazyApply(
56+
oldFile,
57+
filename,
58+
newLazyFile,
59+
llm,
60+
abortController,
61+
),
5562
};
5663
}

core/edit/lazy/replace.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export async function* getReplacementWithLlm(
5959
linesBefore: string[],
6060
linesAfter: string[],
6161
llm: ILLM,
62+
abortController: AbortController,
6263
): AsyncGenerator<string> {
6364
const userPrompt = dedent`
6465
ORIGINAL CODE:
@@ -88,7 +89,7 @@ export async function* getReplacementWithLlm(
8889
{ role: "user", content: userPrompt },
8990
{ role: "assistant", content: assistantPrompt },
9091
],
91-
new AbortController().signal,
92+
abortController.signal,
9293
);
9394

9495
let lines = streamLines(completion);

0 commit comments

Comments
 (0)