Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/core/mentions/__tests__/processUserContentMentions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ describe("processUserContentMentions", () => {
})
})

it("should not process text blocks without task or feedback tags", async () => {
it("should process text blocks without special tags", async () => {
const userContent = [
{
type: "text" as const,
Expand All @@ -177,8 +177,11 @@ describe("processUserContentMentions", () => {
fileContextTracker: mockFileContextTracker,
})

expect(parseMentions).not.toHaveBeenCalled()
expect(result[0]).toEqual(userContent[0])
expect(parseMentions).toHaveBeenCalled()
expect(result[0]).toEqual({
type: "text",
text: "parsed: Regular text without special tags",
})
})

it("should process tool_result blocks with string content", async () => {
Expand Down Expand Up @@ -230,7 +233,7 @@ describe("processUserContentMentions", () => {
fileContextTracker: mockFileContextTracker,
})

expect(parseMentions).toHaveBeenCalledTimes(1)
expect(parseMentions).toHaveBeenCalledTimes(2)
expect(result[0]).toEqual({
type: "tool_result",
tool_use_id: "123",
Expand All @@ -241,7 +244,7 @@ describe("processUserContentMentions", () => {
},
{
type: "text",
text: "Regular text",
text: "parsed: Regular text",
},
],
})
Expand Down
18 changes: 5 additions & 13 deletions src/core/mentions/processUserContentMentions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,13 @@ export async function processUserContentMentions({
}) {
// Process userContent array, which contains various block types:
// TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam.
// We need to apply parseMentions() to:
// 1. All TextBlockParam's text (first user message with task)
// 2. ToolResultBlockParam's content/context text arrays if it contains
// "<feedback>" (see formatToolDeniedFeedback, attemptCompletion,
// executeCommand, and consecutiveMistakeCount >= 3) or "<answer>"
// (see askFollowupQuestion), we place all user generated content in
// these tags so they can effectively be used as markers for when we
// should parse mentions).
// We apply parseMentions() to all text content:
// 1. All TextBlockParam's text
// 2. ToolResultBlockParam's string content
// 3. ToolResultBlockParam's array content where blocks are text type
return Promise.all(
userContent.map(async (block) => {
const shouldProcessMentions = (text: string) =>
text.includes("<task>") ||
text.includes("<feedback>") ||
text.includes("<answer>") ||
text.includes("<user_message>")
const shouldProcessMentions = (_text: string) => true

if (block.type === "text") {
if (shouldProcessMentions(block.text)) {
Expand Down
6 changes: 3 additions & 3 deletions src/core/prompts/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ 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>`,
`The user denied this operation and provided the following feedback:\n${feedback}`,

toolApprovedWithFeedback: (feedback?: string) =>
`The user approved this operation and provided the following context:\n<feedback>\n${feedback}\n</feedback>`,
`The user approved this operation and provided the following context:\n${feedback}`,

toolError: (error?: string) => `The tool execution failed with the following error:\n<error>\n${error}\n</error>`,

Expand All @@ -31,7 +31,7 @@ Otherwise, if you have not completed the task and do not need additional informa
(This is an automated message, so do not respond to it conversationally.)`,

tooManyMistakes: (feedback?: string) =>
`You seem to be having trouble proceeding. The user has provided the following feedback to help guide you:\n<feedback>\n${feedback}\n</feedback>`,
`You seem to be having trouble proceeding. The user has provided the following feedback to help guide you:\n${feedback}`,

missingToolParameterError: (paramName: string) =>
`Missing value for required parameter '${paramName}'. Please retry with complete response.\n\n${toolUseInstructionsReminder}`,
Expand Down
4 changes: 2 additions & 2 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
await this.initiateTaskLoop([
{
type: "text",
text: `<task>\n${task}\n</task>`,
text: task ?? "",
},
...imageBlocks,
])
Expand Down Expand Up @@ -1475,7 +1475,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
if (responseText) {
newUserContent.push({
type: "text",
text: `\n\nNew instructions for task continuation:\n<user_message>\n${responseText}\n</user_message>`,
text: `\n\nNew instructions for task continuation:\n${responseText}`,
})
}

Expand Down
10 changes: 6 additions & 4 deletions src/core/task/__tests__/Task.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,8 +918,9 @@ describe("Cline", () => {
fileContextTracker: cline.fileContextTracker,
})

// Regular text should not be processed
expect((processedContent[0] as Anthropic.TextBlockParam).text).toBe(
// Regular text should be processed
expect((processedContent[0] as Anthropic.TextBlockParam).text).toContain("processed:")
expect((processedContent[0] as Anthropic.TextBlockParam).text).toContain(
"Regular text with 'some/path' (see below for file content)",
)

Expand All @@ -937,10 +938,11 @@ describe("Cline", () => {
"<feedback>Check 'some/path' (see below for file content)</feedback>",
)

// Regular tool result should not be processed
// Regular tool result should be processed now
const toolResult2 = processedContent[3] as Anthropic.ToolResultBlockParam
const content2 = Array.isArray(toolResult2.content) ? toolResult2.content[0] : toolResult2.content
expect((content2 as Anthropic.TextBlockParam).text).toBe(
expect((content2 as Anthropic.TextBlockParam).text).toContain("processed:")
expect((content2 as Anthropic.TextBlockParam).text).toContain(
"Regular tool result with 'path' (see below for file content)",
)

Expand Down
2 changes: 1 addition & 1 deletion src/core/tools/attemptCompletionTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export async function attemptCompletionTool(

toolResults.push({
type: "text",
text: `The user has provided feedback on the results. Consider their input to continue the task, and then attempt completion again.\n<feedback>\n${text}\n</feedback>`,
text: `The user has provided feedback on the results. Consider their input to continue the task, and then attempt completion again.\n${text}`,
})

toolResults.push(...formatResponse.imageBlocks(images))
Expand Down
3 changes: 1 addition & 2 deletions src/core/tools/executeCommandTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,7 @@ export async function executeCommand(
[
`Command is still running in terminal from '${terminal.getCurrentWorkingDirectory().toPosix()}'.`,
result.length > 0 ? `Here's the output so far:\n${result}\n` : "\n",
`The user provided the following feedback:`,
`<feedback>\n${text}\n</feedback>`,
`The user provided the following feedback:\n${text}`,
].join("\n"),
images,
),
Expand Down
4 changes: 1 addition & 3 deletions src/services/command/built-in-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ const BUILT_IN_COMMANDS: Record<string, BuiltInCommandDefinition> = {
init: {
name: "init",
description: "Analyze codebase and create concise AGENTS.md files for AI assistants",
content: `<task>
Please analyze this codebase and create an AGENTS.md file containing:
content: `Please analyze this codebase and create an AGENTS.md file containing:
1. Build/lint/test commands - especially for running a single test
2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
</task>

<initialization>
<purpose>
Expand Down