diff --git a/src/shared/__tests__/support-prompts.test.ts b/src/shared/__tests__/support-prompts.test.ts index 3d286d0230..ea6a193d5a 100644 --- a/src/shared/__tests__/support-prompts.test.ts +++ b/src/shared/__tests__/support-prompts.test.ts @@ -86,6 +86,123 @@ describe("Code Action Prompts", () => { }) }) + describe("ADD_TO_CONTEXT action", () => { + it("should format ADD_TO_CONTEXT prompt correctly with all parameters", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + name: "Roo", + place: "Workspace", + filePath: testFilePath, + selectedText: testCode, + startLine: "1", + endLine: "1", + diagnostics: [], + }) + const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should format ADD_TO_CONTEXT prompt with diagnostics", () => { + const diagnostics = [{ message: "Error 1" }, { source: "Linter", message: "Warning 2" }] + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + filePath: testFilePath, + selectedText: testCode, + startLine: "10", + endLine: "20", + diagnostics, + }) + const expected = `${testFilePath}:10-20\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should not replace placeholders within parameter values", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + value1: "This is ${value2}", + value2: "Actual Value 2", + filePath: testFilePath, + selectedText: testCode, + startLine: "5", + endLine: "15", + }) + const expected = `${testFilePath}:5-15\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should replace remaining placeholders (not in params) with empty strings", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + name: "Roo", + filePath: testFilePath, + selectedText: testCode, + startLine: "1", + endLine: "1", + }) // 'status' is missing + const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should handle placeholders in values that are not in the template", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + data: "Some data with ${extraInfo}", + filePath: testFilePath, + selectedText: testCode, + startLine: "1", + endLine: "1", + }) + const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should handle minimal params object", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + filePath: testFilePath, + selectedText: testCode, + startLine: "1", + endLine: "1", + }) + const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should handle params with non-string values", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + count: "5", + isActive: "true", + filePath: testFilePath, + selectedText: testCode, + startLine: "1", + endLine: "1", + }) // Convert to strings + const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should handle keys with special regex characters", () => { + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + "key.with.dots": "Dotty", + value: "Simple", + filePath: testFilePath, + selectedText: testCode, + startLine: "1", + endLine: "1", + }) + const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\`` + expect(prompt).toBe(expected) + }) + + it("should handle bash script selection", () => { + const bashText = + 'if [ "${#usecase_deployments[@]}" -gt 0 ] && [ ${{ parameters.single_deployment_per_environment }} = true ]; then' + const prompt = supportPrompt.create("ADD_TO_CONTEXT", { + selectedText: bashText, + filePath: testFilePath, + startLine: "1", + endLine: "1", + diagnostics: [], + }) + const expected = `${testFilePath}:1-1\n\`\`\`\n${bashText}\n\`\`\`` + expect(prompt).toBe(expected) + }) + }) + describe("get template", () => { it("should return default template when no custom prompts provided", () => { const template = supportPrompt.get(undefined, "EXPLAIN") diff --git a/src/shared/support-prompt.ts b/src/shared/support-prompt.ts index ee8c4fa3e8..2dfa478e15 100644 --- a/src/shared/support-prompt.ts +++ b/src/shared/support-prompt.ts @@ -9,19 +9,23 @@ const generateDiagnosticText = (diagnostics?: any[]) => { } export const createPrompt = (template: string, params: PromptParams): string => { - let result = template - for (const [key, value] of Object.entries(params)) { - if (key === "diagnostics") { - result = result.replaceAll("${diagnosticText}", generateDiagnosticText(value as any[])) + return template.replace(/\${(.*?)}/g, (_, key) => { + if (key === "diagnosticText") { + return generateDiagnosticText(params["diagnostics"] as any[]) + } else if (params.hasOwnProperty(key)) { + // Ensure the value is treated as a string for replacement + const value = params[key] + if (typeof value === "string") { + return value + } else { + // Convert non-string values to string for replacement + return String(value) + } } else { - result = result.replaceAll(`\${${key}}`, value as string) + // If the placeholder key is not in params, replace with empty string + return "" } - } - - // Replace any remaining placeholders with empty strings - result = result.replaceAll(/\${[^}]*}/g, "") - - return result + }) } interface SupportPromptConfig {