added approve finish task button and auto approve button for subtasks

This commit is contained in:
ShayBC 2025-03-08 06:01:49 +02:00
parent b761c241ba
commit 1456db9502
7 changed files with 62 additions and 3 deletions

View file

@ -1414,6 +1414,18 @@ export class Cline {
return true
}
const askFinishSubTaskApproval = async () => {
// ask the user to approve this task has completed, and he has reviewd it, and we can declare task is finished
// and return control to the parent task to continue running the rest of the sub-tasks
const toolMessage = JSON.stringify({
tool: "finishTask",
content:
"Task completed! You can review the results and suggest any corrections or next steps. If everything looks good, confirm to continue with the next task.",
})
return await askApproval("tool", toolMessage)
}
const handleError = async (action: string, error: Error) => {
const errorString = `Error ${action}: ${JSON.stringify(serializeError(error))}`
await this.say(
@ -2941,8 +2953,13 @@ export class Cline {
if (lastMessage && lastMessage.ask !== "command") {
// havent sent a command message yet so first send completion_result then command
await this.say("completion_result", result, undefined, false)
telemetryService.captureTaskCompleted(this.taskId)
// telemetryService.captureTaskCompleted(this.taskId)
if (this.isSubTask) {
const didApprove = await askFinishSubTaskApproval()
if (!didApprove) {
break
}
// tell the provider to remove the current subtask and resume the previous task in the stack
await this.providerRef
.deref()
@ -2966,8 +2983,13 @@ export class Cline {
commandResult = execCommandResult
} else {
await this.say("completion_result", result, undefined, false)
telemetryService.captureTaskCompleted(this.taskId)
// telemetryService.captureTaskCompleted(this.taskId)
if (this.isSubTask) {
const didApprove = await askFinishSubTaskApproval()
if (!didApprove) {
break
}
// tell the provider to remove the current subtask and resume the previous task in the stack
await this.providerRef
.deref()

View file

@ -109,6 +109,7 @@ export interface ExtensionState {
alwaysAllowMcp?: boolean
alwaysApproveResubmit?: boolean
alwaysAllowModeSwitch?: boolean
alwaysAllowFinishTask?: boolean
browserToolEnabled?: boolean
requestDelaySeconds: number
rateLimitSeconds: number // Minimum time between successive requests (0 = disabled)
@ -168,6 +169,7 @@ export type ClineAsk =
| "mistake_limit_reached"
| "browser_action_launch"
| "use_mcp_server"
| "finishTask"
export type ClineSay =
| "task"
@ -207,6 +209,7 @@ export interface ClineSayTool {
| "searchFiles"
| "switchMode"
| "newTask"
| "finishTask"
path?: string
diff?: string
content?: string

View file

@ -48,6 +48,7 @@ export interface WebviewMessage {
| "alwaysAllowBrowser"
| "alwaysAllowMcp"
| "alwaysAllowModeSwitch"
| "alwaysAllowFinishTask"
| "playSound"
| "soundEnabled"
| "soundVolume"

View file

@ -30,6 +30,8 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
setAlwaysAllowMcp,
alwaysAllowModeSwitch,
setAlwaysAllowModeSwitch,
alwaysAllowFinishTask,
setAlwaysAllowFinishTask,
alwaysApproveResubmit,
setAlwaysApproveResubmit,
autoApprovalEnabled,
@ -81,6 +83,13 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
description:
"Allows automatic switching between different AI modes and creating new tasks without requiring approval.",
},
{
id: "finishTask",
label: "Finish subtasks tasks",
shortName: "Finish",
enabled: alwaysAllowFinishTask ?? false,
description: "Allows automatic completeing a sub-task without requiring user review or approval.",
},
{
id: "retryRequests",
label: "Retry failed requests",
@ -136,6 +145,12 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: newValue })
}, [alwaysAllowModeSwitch, setAlwaysAllowModeSwitch])
const handleFinishTaskChange = useCallback(() => {
const newValue = !(alwaysAllowFinishTask ?? false)
setAlwaysAllowFinishTask(newValue)
vscode.postMessage({ type: "alwaysAllowFinishTask", bool: newValue })
}, [alwaysAllowFinishTask, setAlwaysAllowFinishTask])
const handleRetryChange = useCallback(() => {
const newValue = !(alwaysApproveResubmit ?? false)
setAlwaysApproveResubmit(newValue)
@ -150,6 +165,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
useBrowser: handleBrowserChange,
useMcp: handleMcpChange,
switchModes: handleModeSwitchChange,
finishTask: handleFinishTaskChange,
retryRequests: handleRetryChange,
}

View file

@ -459,6 +459,18 @@ export const ChatRowContent = ({
</div>
</>
)
case "finishTask":
return (
<>
<div style={headerStyle}>
{toolIcon("new-file")}
<span style={{ fontWeight: "bold" }}>Roo wants to finish this task</span>
</div>
<div style={{ paddingLeft: "26px", marginTop: "4px" }}>
<code>{tool.content}</code>
</div>
</>
)
default:
return null
}

View file

@ -61,6 +61,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
setMode,
autoApprovalEnabled,
alwaysAllowModeSwitch,
alwaysAllowFinishTask,
customModes,
telemetrySetting,
} = useExtensionState()
@ -642,7 +643,8 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
(alwaysAllowModeSwitch &&
message.ask === "tool" &&
(JSON.parse(message.text || "{}")?.tool === "switchMode" ||
JSON.parse(message.text || "{}")?.tool === "newTask"))
JSON.parse(message.text || "{}")?.tool === "newTask")) ||
(alwaysAllowFinishTask && message.ask === "finishTask")
)
},
[
@ -657,6 +659,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
alwaysAllowMcp,
isMcpToolAlwaysAllowed,
alwaysAllowModeSwitch,
alwaysAllowFinishTask,
],
)

View file

@ -31,6 +31,7 @@ export interface ExtensionStateContextType extends ExtensionState {
setAlwaysAllowBrowser: (value: boolean) => void
setAlwaysAllowMcp: (value: boolean) => void
setAlwaysAllowModeSwitch: (value: boolean) => void
setAlwaysAllowFinishTask: (value: boolean) => void
setBrowserToolEnabled: (value: boolean) => void
setShowRooIgnoredFiles: (value: boolean) => void
setShowAnnouncement: (value: boolean) => void
@ -247,6 +248,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setAlwaysAllowBrowser: (value) => setState((prevState) => ({ ...prevState, alwaysAllowBrowser: value })),
setAlwaysAllowMcp: (value) => setState((prevState) => ({ ...prevState, alwaysAllowMcp: value })),
setAlwaysAllowModeSwitch: (value) => setState((prevState) => ({ ...prevState, alwaysAllowModeSwitch: value })),
setAlwaysAllowFinishTask: (value) => setState((prevState) => ({ ...prevState, alwaysAllowFinishTask: value })),
setShowAnnouncement: (value) => setState((prevState) => ({ ...prevState, shouldShowAnnouncement: value })),
setAllowedCommands: (value) => setState((prevState) => ({ ...prevState, allowedCommands: value })),
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),