Fix task resumption in the API module (#11369)

This commit is contained in:
Chris Estreich 2026-02-10 00:28:17 -08:00 committed by GitHub
parent 5773af8ddd
commit b02924530c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 1 deletions

View file

@ -28,6 +28,7 @@ describe("API - SendMessage Command", () => {
postMessageToWebview: mockPostMessageToWebview,
on: vi.fn(),
getCurrentTaskStack: vi.fn().mockReturnValue([]),
getCurrentTask: vi.fn().mockReturnValue(undefined),
viewLaunched: true,
} as unknown as ClineProvider

View file

@ -4,6 +4,7 @@ import * as path from "path"
import * as os from "os"
import * as vscode from "vscode"
import pWaitFor from "p-wait-for"
import {
type RooCodeAPI,
@ -208,9 +209,19 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
}
public async resumeTask(taskId: string): Promise<void> {
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
await this.waitForWebviewLaunch(5_000)
const { historyItem } = await this.sidebarProvider.getTaskWithId(taskId)
await this.sidebarProvider.createTaskWithHistoryItem(historyItem)
await this.sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
if (this.sidebarProvider.viewLaunched) {
await this.sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
} else {
this.log(
`[API#resumeTask] webview not launched after resume for task ${taskId}; continuing in headless mode`,
)
}
}
public async isTaskInHistory(taskId: string): Promise<boolean> {
@ -237,6 +248,21 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
}
public async sendMessage(text?: string, images?: string[]) {
const currentTask = this.sidebarProvider.getCurrentTask()
// In headless/sandbox flows the webview may not be launched, so routing
// through invoke=sendMessage drops the message. Deliver directly to the
// task ask-response channel instead.
if (!this.sidebarProvider.viewLaunched) {
if (!currentTask) {
this.log("[API#sendMessage] no current task in headless mode; message dropped")
return
}
await currentTask.submitUserMessage(text ?? "", images)
return
}
await this.sidebarProvider.postMessageToWebview({ type: "invoke", invoke: "sendMessage", text, images })
}
@ -252,6 +278,20 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
return this.sidebarProvider.viewLaunched
}
private async waitForWebviewLaunch(timeoutMs: number): Promise<boolean> {
try {
await pWaitFor(() => this.sidebarProvider.viewLaunched, {
timeout: timeoutMs,
interval: 50,
})
return true
} catch {
this.log(`[API#waitForWebviewLaunch] webview did not launch within ${timeoutMs}ms`)
return false
}
}
private registerListeners(provider: ClineProvider) {
provider.on(RooCodeEventName.TaskCreated, (task) => {
// Task Lifecycle