Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit 61edbb3

Browse files
ctehannesrudolph
authored andcommitted
IPC fixes for task cancellation and queued messages (#11162)
1 parent 196d0d6 commit 61edbb3

8 files changed

Lines changed: 34 additions & 35 deletions

File tree

packages/evals/src/cli/runTaskInCli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ export const runTaskWithCli = async ({ run, task, publish, logger, jobToken }: R
263263

264264
if (rooTaskId && !isClientDisconnected) {
265265
logger.info("cancelling task")
266-
client.sendCommand({ commandName: TaskCommandName.CancelTask, data: rooTaskId })
266+
client.sendCommand({ commandName: TaskCommandName.CancelTask })
267267
await new Promise((resolve) => setTimeout(resolve, 5_000))
268268
}
269269

@@ -288,7 +288,7 @@ export const runTaskWithCli = async ({ run, task, publish, logger, jobToken }: R
288288

289289
if (rooTaskId && !isClientDisconnected) {
290290
logger.info("closing task")
291-
client.sendCommand({ commandName: TaskCommandName.CloseTask, data: rooTaskId })
291+
client.sendCommand({ commandName: TaskCommandName.CloseTask })
292292
await new Promise((resolve) => setTimeout(resolve, 2_000))
293293
}
294294

packages/evals/src/cli/runTaskInVscode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ export const runTaskInVscode = async ({ run, task, publish, logger, jobToken }:
270270

271271
if (rooTaskId && !isClientDisconnected) {
272272
logger.info("cancelling task")
273-
client.sendCommand({ commandName: TaskCommandName.CancelTask, data: rooTaskId })
273+
client.sendCommand({ commandName: TaskCommandName.CancelTask })
274274
await new Promise((resolve) => setTimeout(resolve, 5_000)) // Allow some time for the task to cancel.
275275
}
276276

@@ -289,7 +289,7 @@ export const runTaskInVscode = async ({ run, task, publish, logger, jobToken }:
289289

290290
if (rooTaskId && !isClientDisconnected) {
291291
logger.info("closing task")
292-
client.sendCommand({ commandName: TaskCommandName.CloseTask, data: rooTaskId })
292+
client.sendCommand({ commandName: TaskCommandName.CloseTask })
293293
await new Promise((resolve) => setTimeout(resolve, 2_000)) // Allow some time for the window to close.
294294
}
295295

packages/types/src/__tests__/ipc.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("IPC Types", () => {
2727
const result = taskCommandSchema.safeParse(resumeTaskCommand)
2828
expect(result.success).toBe(true)
2929

30-
if (result.success) {
30+
if (result.success && result.data.commandName === TaskCommandName.ResumeTask) {
3131
expect(result.data.commandName).toBe("ResumeTask")
3232
expect(result.data.data).toBe("non-existent-task-id")
3333
}
@@ -45,7 +45,7 @@ describe("IPC Types", () => {
4545
const result = taskCommandSchema.safeParse(resumeTaskCommand)
4646
expect(result.success).toBe(true)
4747

48-
if (result.success) {
48+
if (result.success && result.data.commandName === TaskCommandName.ResumeTask) {
4949
expect(result.data.commandName).toBe("ResumeTask")
5050
expect(result.data.data).toBe("task-123")
5151
}

packages/types/src/events.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { z } from "zod"
22

3-
import { clineMessageSchema, tokenUsageSchema } from "./message.js"
3+
import { clineMessageSchema, queuedMessageSchema, tokenUsageSchema } from "./message.js"
44
import { toolNamesSchema, toolUsageSchema } from "./tool.js"
55

66
/**
@@ -35,6 +35,7 @@ export enum RooCodeEventName {
3535
TaskModeSwitched = "taskModeSwitched",
3636
TaskAskResponded = "taskAskResponded",
3737
TaskUserMessage = "taskUserMessage",
38+
QueuedMessagesUpdated = "queuedMessagesUpdated",
3839

3940
// Task Analytics
4041
TaskTokenUsageUpdated = "taskTokenUsageUpdated",
@@ -100,6 +101,7 @@ export const rooCodeEventsSchema = z.object({
100101
[RooCodeEventName.TaskModeSwitched]: z.tuple([z.string(), z.string()]),
101102
[RooCodeEventName.TaskAskResponded]: z.tuple([z.string()]),
102103
[RooCodeEventName.TaskUserMessage]: z.tuple([z.string()]),
104+
[RooCodeEventName.QueuedMessagesUpdated]: z.tuple([z.string(), z.array(queuedMessageSchema)]),
103105

104106
[RooCodeEventName.TaskToolFailed]: z.tuple([z.string(), toolNamesSchema, z.string()]),
105107
[RooCodeEventName.TaskTokenUsageUpdated]: z.tuple([z.string(), tokenUsageSchema, toolUsageSchema]),
@@ -217,6 +219,11 @@ export const taskEventSchema = z.discriminatedUnion("eventName", [
217219
payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskAskResponded],
218220
taskId: z.number().optional(),
219221
}),
222+
z.object({
223+
eventName: z.literal(RooCodeEventName.QueuedMessagesUpdated),
224+
payload: rooCodeEventsSchema.shape[RooCodeEventName.QueuedMessagesUpdated],
225+
taskId: z.number().optional(),
226+
}),
220227

221228
// Task Analytics
222229
z.object({

packages/types/src/ipc.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,9 @@ export const taskCommandSchema = z.discriminatedUnion("commandName", [
6464
}),
6565
z.object({
6666
commandName: z.literal(TaskCommandName.CancelTask),
67-
data: z.string(),
6867
}),
6968
z.object({
7069
commandName: z.literal(TaskCommandName.CloseTask),
71-
data: z.string(),
7270
}),
7371
z.object({
7472
commandName: z.literal(TaskCommandName.ResumeTask),

packages/types/src/task.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ export type TaskEvents = {
154154
[RooCodeEventName.TaskModeSwitched]: [taskId: string, mode: string]
155155
[RooCodeEventName.TaskAskResponded]: []
156156
[RooCodeEventName.TaskUserMessage]: [taskId: string]
157+
[RooCodeEventName.QueuedMessagesUpdated]: [taskId: string, messages: QueuedMessage[]]
157158

158159
// Task Analytics
159160
[RooCodeEventName.TaskToolFailed]: [taskId: string, tool: ToolName, error: string]

src/core/task/Task.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
554554

555555
this.messageQueueStateChangedHandler = () => {
556556
this.emit(RooCodeEventName.TaskUserMessage, this.taskId)
557+
this.emit(RooCodeEventName.QueuedMessagesUpdated, this.taskId, this.messageQueueService.messages)
557558
this.providerRef.deref()?.postStateToWebviewWithoutTaskHistory()
558559
}
559560

src/extension/api.ts

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
3030
private readonly sidebarProvider: ClineProvider
3131
private readonly context: vscode.ExtensionContext
3232
private readonly ipc?: IpcServer
33-
private readonly taskMap = new Map<string, ClineProvider>()
3433
private readonly log: (...args: unknown[]) => void
3534
private logfile?: string
3635

@@ -65,35 +64,37 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
6564
ipc.listen()
6665
this.log(`[API] ipc server started: socketPath=${socketPath}, pid=${process.pid}, ppid=${process.ppid}`)
6766

68-
ipc.on(IpcMessageType.TaskCommand, async (_clientId, { commandName, data }) => {
69-
switch (commandName) {
67+
ipc.on(IpcMessageType.TaskCommand, async (_clientId, command) => {
68+
switch (command.commandName) {
7069
case TaskCommandName.StartNewTask:
71-
this.log(`[API] StartNewTask -> ${data.text}, ${JSON.stringify(data.configuration)}`)
72-
await this.startNewTask(data)
70+
this.log(
71+
`[API] StartNewTask -> ${command.data.text}, ${JSON.stringify(command.data.configuration)}`,
72+
)
73+
await this.startNewTask(command.data)
7374
break
7475
case TaskCommandName.CancelTask:
75-
this.log(`[API] CancelTask -> ${data}`)
76-
await this.cancelTask(data)
76+
this.log(`[API] CancelTask`)
77+
await this.cancelCurrentTask()
7778
break
7879
case TaskCommandName.CloseTask:
79-
this.log(`[API] CloseTask -> ${data}`)
80+
this.log(`[API] CloseTask`)
8081
await vscode.commands.executeCommand("workbench.action.files.saveFiles")
8182
await vscode.commands.executeCommand("workbench.action.closeWindow")
8283
break
8384
case TaskCommandName.ResumeTask:
84-
this.log(`[API] ResumeTask -> ${data}`)
85+
this.log(`[API] ResumeTask -> ${command.data}`)
8586
try {
86-
await this.resumeTask(data)
87+
await this.resumeTask(command.data)
8788
} catch (error) {
8889
const errorMessage = error instanceof Error ? error.message : String(error)
89-
this.log(`[API] ResumeTask failed for taskId ${data}: ${errorMessage}`)
90+
this.log(`[API] ResumeTask failed for taskId ${command.data}: ${errorMessage}`)
9091
// Don't rethrow - we want to prevent IPC server crashes
9192
// The error is logged for debugging purposes
9293
}
9394
break
9495
case TaskCommandName.SendMessage:
95-
this.log(`[API] SendMessage -> ${data.text}`)
96-
await this.sendMessage(data.text, data.images)
96+
this.log(`[API] SendMessage -> ${command.data.text}`)
97+
await this.sendMessage(command.data.text, command.data.images)
9798
break
9899
}
99100
})
@@ -181,15 +182,6 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
181182
await this.sidebarProvider.cancelTask()
182183
}
183184

184-
public async cancelTask(taskId: string) {
185-
const provider = this.taskMap.get(taskId)
186-
187-
if (provider) {
188-
await provider.cancelTask()
189-
this.taskMap.delete(taskId)
190-
}
191-
}
192-
193185
public async sendMessage(text?: string, images?: string[]) {
194186
await this.sidebarProvider.postMessageToWebview({ type: "invoke", invoke: "sendMessage", text, images })
195187
}
@@ -212,7 +204,6 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
212204

213205
task.on(RooCodeEventName.TaskStarted, async () => {
214206
this.emit(RooCodeEventName.TaskStarted, task.taskId)
215-
this.taskMap.set(task.taskId, provider)
216207
await this.fileLog(`[${new Date().toISOString()}] taskStarted -> ${task.taskId}\n`)
217208
})
218209

@@ -221,16 +212,13 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
221212
isSubtask: !!task.parentTaskId,
222213
})
223214

224-
this.taskMap.delete(task.taskId)
225-
226215
await this.fileLog(
227216
`[${new Date().toISOString()}] taskCompleted -> ${task.taskId} | ${JSON.stringify(tokenUsage, null, 2)} | ${JSON.stringify(toolUsage, null, 2)}\n`,
228217
)
229218
})
230219

231220
task.on(RooCodeEventName.TaskAborted, () => {
232221
this.emit(RooCodeEventName.TaskAborted, task.taskId)
233-
this.taskMap.delete(task.taskId)
234222
})
235223

236224
task.on(RooCodeEventName.TaskFocused, () => {
@@ -301,6 +289,10 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
301289
this.emit(RooCodeEventName.TaskAskResponded, task.taskId)
302290
})
303291

292+
task.on(RooCodeEventName.QueuedMessagesUpdated, (taskId, messages) => {
293+
this.emit(RooCodeEventName.QueuedMessagesUpdated, taskId, messages)
294+
})
295+
304296
// Task Analytics
305297

306298
task.on(RooCodeEventName.TaskToolFailed, (taskId, tool, error) => {

0 commit comments

Comments
 (0)