Skip to content

Commit 30857e9

Browse files
authored
full automation (RooCodeInc#2817)
1 parent 0d07b42 commit 30857e9

File tree

1 file changed

+105
-1
lines changed

1 file changed

+105
-1
lines changed

src/services/test/TestServer.ts

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { Logger } from "../../services/logging/Logger"
44
import { WebviewProvider } from "../../core/webview"
55
import { AutoApprovalSettings } from "../../shared/AutoApprovalSettings"
66
import { updateGlobalState, getAllExtensionState } from "../../core/storage/state"
7+
import { ClineAsk, ExtensionMessage } from "../../shared/ExtensionMessage"
8+
import { WebviewMessage } from "../../shared/WebviewMessage"
79

810
// Task completion tracking
911
let taskCompletionResolver: (() => void) | null = null
@@ -211,6 +213,7 @@ export function createTestServer(webviewProvider?: WebviewProvider): http.Server
211213

212214
/**
213215
* Creates a message catcher that logs all messages sent to the webview
216+
* and automatically responds to messages that require user intervention
214217
* @param webviewProvider The webview provider instance
215218
* @returns A disposable that can be used to clean up the message catcher
216219
*/
@@ -219,7 +222,9 @@ export function createMessageCatcher(webviewProvider: WebviewProvider): vscode.D
219222

220223
if (webviewProvider && webviewProvider.controller) {
221224
const originalPostMessageToWebview = webviewProvider.controller.postMessageToWebview
222-
webviewProvider.controller.postMessageToWebview = async (message) => {
225+
226+
// Intercept outgoing messages from extension to webview
227+
webviewProvider.controller.postMessageToWebview = async (message: ExtensionMessage) => {
223228
Logger.log("Cline message received: " + JSON.stringify(message))
224229

225230
// Check for completion_result message
@@ -228,6 +233,17 @@ export function createMessageCatcher(webviewProvider: WebviewProvider): vscode.D
228233
completeTask()
229234
}
230235

236+
// Check for ask messages that require user intervention
237+
if (message.type === "partialMessage" && message.partialMessage?.type === "ask" && !message.partialMessage.partial) {
238+
const askType = message.partialMessage.ask as ClineAsk
239+
const askText = message.partialMessage.text
240+
241+
// Automatically respond to different types of asks
242+
setTimeout(() => {
243+
autoRespondToAsk(webviewProvider, askType, askText)
244+
}, 100) // Small delay to ensure the message is processed first
245+
}
246+
231247
return originalPostMessageToWebview.call(webviewProvider.controller, message)
232248
}
233249
} else {
@@ -240,6 +256,94 @@ export function createMessageCatcher(webviewProvider: WebviewProvider): vscode.D
240256
})
241257
}
242258

259+
/**
260+
* Automatically responds to ask messages to continue task execution without user intervention
261+
* @param webviewProvider The webview provider instance
262+
* @param askType The type of ask message
263+
* @param askText The text content of the ask message
264+
*/
265+
function autoRespondToAsk(webviewProvider: WebviewProvider, askType: ClineAsk, askText?: string): void {
266+
if (!webviewProvider.controller) {
267+
return
268+
}
269+
270+
Logger.log(`Auto-responding to ask type: ${askType}`)
271+
272+
// Create a response message based on the ask type
273+
const response: WebviewMessage = {
274+
type: "askResponse",
275+
askResponse: "yesButtonClicked", // Default to approving most actions
276+
}
277+
278+
// Handle specific ask types differently if needed
279+
switch (askType) {
280+
case "followup":
281+
// For follow-up questions, provide a generic response
282+
response.askResponse = "messageResponse"
283+
response.text = "I can't answer any questions right now, use your best judgment."
284+
break
285+
286+
case "api_req_failed":
287+
// Always retry API requests
288+
response.askResponse = "yesButtonClicked" // "Retry" button
289+
break
290+
291+
case "completion_result":
292+
// Accept the completion
293+
response.askResponse = "messageResponse"
294+
response.text = "Task completed successfully."
295+
break
296+
297+
case "mistake_limit_reached":
298+
// Provide guidance to continue
299+
response.askResponse = "messageResponse"
300+
response.text = "Try breaking down the task into smaller steps."
301+
break
302+
303+
case "auto_approval_max_req_reached":
304+
// Reset the count to continue
305+
response.askResponse = "yesButtonClicked" // "Reset and continue" button
306+
break
307+
308+
case "resume_task":
309+
case "resume_completed_task":
310+
// Resume the task
311+
response.askResponse = "messageResponse"
312+
break
313+
314+
case "new_task":
315+
// Decline creating a new task to keep the current task running
316+
response.askResponse = "messageResponse"
317+
response.text = "Continue with the current task."
318+
break
319+
320+
case "plan_mode_respond":
321+
// Respond to plan mode with a message to toggle to Act mode
322+
response.askResponse = "messageResponse"
323+
response.text = "PLAN_MODE_TOGGLE_RESPONSE" // Special marker to toggle to Act mode
324+
325+
// Automatically toggle to Act mode after responding
326+
setTimeout(async () => {
327+
try {
328+
if (webviewProvider.controller) {
329+
Logger.log("Auto-toggling to Act mode from Plan mode")
330+
await webviewProvider.controller.togglePlanActModeWithChatSettings({ mode: "act" })
331+
}
332+
} catch (error) {
333+
Logger.log(`Error toggling to Act mode: ${error}`)
334+
}
335+
}, 500) // Small delay to ensure the response is processed first
336+
break
337+
338+
// For all other ask types (tool, command, browser_action_launch, use_mcp_server),
339+
// we use the default "yesButtonClicked" to approve the action
340+
}
341+
342+
// Send the response message
343+
webviewProvider.controller.handleWebviewMessage(response)
344+
Logger.log(`Auto-responded to ${askType} with ${response.askResponse}`)
345+
}
346+
243347
/**
244348
* Shuts down the test server if it exists
245349
*/

0 commit comments

Comments
 (0)