Fix sending feedback with approve

This commit is contained in:
Saoud Rizwan 2025-02-16 20:38:31 -08:00
parent aab26e9a38
commit a98269f6d5
2 changed files with 40 additions and 49 deletions

View file

@ -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<feedback>\n${feedback}\n</feedback>`,
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<feedback>\n${text}\n</feedback>`,
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),
)
}
}

View file

@ -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<feedback>\n${feedback}\n</feedback>`,
toolApprovedWithFeedback: (feedback?: string) =>
`The user approved this operation and provided the following feedback:\n<feedback>\n${feedback}\n</feedback>`,
toolError: (error?: string) => `The tool execution failed with the following error:\n<error>\n${error}\n</error>`,
clineIgnoreError: (path: string) =>