From a98269f6d5031db212dee9303badf771b57d999c Mon Sep 17 00:00:00 2001
From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
Date: Sun, 16 Feb 2025 20:38:31 -0800
Subject: [PATCH] Fix sending feedback with approve
---
src/core/Cline.ts | 83 +++++++++++++++++------------------
src/core/prompts/responses.ts | 6 ---
2 files changed, 40 insertions(+), 49 deletions(-)
diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index 4bfcf59520..acecbd4fe6 100644
--- a/src/core/Cline.ts
+++ b/src/core/Cline.ts
@@ -1539,33 +1539,44 @@ export class Cline {
this.didAlreadyUseTool = true
}
+ // The user can approve, reject, or provide feedback (rejection). However the user may also send a message along with an approval, in which case we add a separate user message with this feedback.
+ const pushAdditionalToolFeedback = (feedback?: string, images?: string[]) => {
+ if (!feedback && !images) {
+ return
+ }
+ const content = formatResponse.toolResult(
+ `The user provided the following feedback:\n\n${feedback}\n`,
+ images,
+ )
+ if (typeof content === "string") {
+ this.userMessageContent.push({
+ type: "text",
+ text: content,
+ })
+ } else {
+ this.userMessageContent.push(...content)
+ }
+ }
+
const askApproval = async (type: ClineAsk, partialMessage?: string) => {
const { response, text, images } = await this.ask(type, partialMessage, false)
if (response !== "yesButtonClicked") {
- // User did NOT approve (rejected)
- if (response === "messageResponse") {
- // Rejection WITH feedback
- await this.say("user_feedback", text, images)
- pushToolResult(formatResponse.toolResult(formatResponse.toolDeniedWithFeedback(text), images))
-
- this.didRejectTool = true
- return false
- }
- // Rejection WITHOUT explicit feedback
+ // User pressed reject button or responded with a message, which we treat as a rejection
pushToolResult(formatResponse.toolDenied())
-
+ if (text || images?.length) {
+ pushAdditionalToolFeedback(text, images)
+ await this.say("user_feedback", text, images)
+ }
this.didRejectTool = true // Prevent further tool uses in this message
return false
+ } else {
+ // User hit the approve button, and may have provided feedback
+ if (text || images?.length) {
+ pushAdditionalToolFeedback(text, images)
+ await this.say("user_feedback", text, images)
+ }
+ return true
}
-
- // Handle yesButtonClicked with text (Acceptance WITH feedback)
- if (text) {
- await this.say("user_feedback", text, images)
- pushToolResult(formatResponse.toolResult(formatResponse.toolApprovedWithFeedback(text), images)) // Structured feedback to model on approval
- }
-
- // User approved without feedback
- return true
}
const showNotificationForApprovalIfAutoApprovalEnabled = (message: string) => {
@@ -1804,37 +1815,23 @@ export class Cline {
let didApprove = true
const { response, text, images } = await this.ask("tool", completeMessage, false)
if (response !== "yesButtonClicked") {
- // User did NOT approve (rejected)
-
+ // User either sent a message or pressed reject button
// TODO: add similar context for other tool denial responses, to emphasize ie that a command was not run
const fileDeniedNote = fileExists
? "The file was not updated, and maintains its original contents."
: "The file was not created."
- if (response === "messageResponse") {
- // Rejection WITH feedback
+ pushToolResult(`The user denied this operation. ${fileDeniedNote}`)
+ if (text || images?.length) {
+ pushAdditionalToolFeedback(text, images)
await this.say("user_feedback", text, images)
- pushToolResult(
- formatResponse.toolResult(
- `The user denied this operation. ${fileDeniedNote}\nThe user provided the following feedback:\n\n${text}\n`,
- images,
- ),
- )
- this.didRejectTool = true
- didApprove = false
- } else {
- pushToolResult(`The user denied this operation. ${fileDeniedNote}`)
- this.didRejectTool = true
- didApprove = false
}
+ this.didRejectTool = true
+ didApprove = false
} else {
- // User approved
-
- // Handle yesButtonClicked with text (Acceptance WITH feedback)
- if (text) {
+ // User hit the approve button, and may have provided feedback
+ if (text || images?.length) {
+ pushAdditionalToolFeedback(text, images)
await this.say("user_feedback", text, images)
- pushToolResult(
- formatResponse.toolResult(formatResponse.toolApprovedWithFeedback(text), images),
- )
}
}
diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts
index 8a14acc02b..bf5db6bbe7 100644
--- a/src/core/prompts/responses.ts
+++ b/src/core/prompts/responses.ts
@@ -6,12 +6,6 @@ import { ClineIgnoreController, LOCK_TEXT_SYMBOL } from "../ignore/ClineIgnoreCo
export const formatResponse = {
toolDenied: () => `The user denied this operation.`,
- toolDeniedWithFeedback: (feedback?: string) =>
- `The user denied this operation and provided the following feedback:\n\n${feedback}\n`,
-
- toolApprovedWithFeedback: (feedback?: string) =>
- `The user approved this operation and provided the following feedback:\n\n${feedback}\n`,
-
toolError: (error?: string) => `The tool execution failed with the following error:\n\n${error}\n`,
clineIgnoreError: (path: string) =>