mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-22 13:21:07 -05:00
refactor: consolidate prompt functionality into support-prompt module
- Move code action prompts from core/prompts to shared/support-prompt - Migrate enhance prompt functionality from modes to support-prompt - Add UI for managing code action prompts in PromptsView - Update types and interfaces for better prompt management
This commit is contained in:
@@ -68,7 +68,8 @@ export interface WebviewMessage {
|
||||
| "requestVsCodeLmModels"
|
||||
| "mode"
|
||||
| "updatePrompt"
|
||||
| "updateEnhancedPrompt"
|
||||
| "updateSupportPrompt"
|
||||
| "resetSupportPrompt"
|
||||
| "getSystemPrompt"
|
||||
| "systemPrompt"
|
||||
| "enhancementApiConfigId"
|
||||
|
||||
138
src/shared/__tests__/support-prompts.test.ts
Normal file
138
src/shared/__tests__/support-prompts.test.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
import { codeActionPrompt, type CodeActionType } from "../support-prompt"
|
||||
|
||||
describe("Code Action Prompts", () => {
|
||||
const testFilePath = "test/file.ts"
|
||||
const testCode = "function test() { return true; }"
|
||||
|
||||
describe("EXPLAIN action", () => {
|
||||
it("should format explain prompt correctly", () => {
|
||||
const prompt = codeActionPrompt.create("EXPLAIN", {
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
})
|
||||
|
||||
expect(prompt).toContain(`@/${testFilePath}`)
|
||||
expect(prompt).toContain(testCode)
|
||||
expect(prompt).toContain("purpose and functionality")
|
||||
expect(prompt).toContain("Key components")
|
||||
expect(prompt).toContain("Important patterns")
|
||||
})
|
||||
})
|
||||
|
||||
describe("FIX action", () => {
|
||||
it("should format fix prompt without diagnostics", () => {
|
||||
const prompt = codeActionPrompt.create("FIX", {
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
})
|
||||
|
||||
expect(prompt).toContain(`@/${testFilePath}`)
|
||||
expect(prompt).toContain(testCode)
|
||||
expect(prompt).toContain("Address all detected problems")
|
||||
expect(prompt).not.toContain("Current problems detected")
|
||||
})
|
||||
|
||||
it("should format fix prompt with diagnostics", () => {
|
||||
const diagnostics = [
|
||||
{
|
||||
source: "eslint",
|
||||
message: "Missing semicolon",
|
||||
code: "semi",
|
||||
},
|
||||
{
|
||||
message: "Unused variable",
|
||||
severity: 1,
|
||||
},
|
||||
]
|
||||
|
||||
const prompt = codeActionPrompt.create("FIX", {
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
diagnostics,
|
||||
})
|
||||
|
||||
expect(prompt).toContain("Current problems detected:")
|
||||
expect(prompt).toContain("[eslint] Missing semicolon (semi)")
|
||||
expect(prompt).toContain("[Error] Unused variable")
|
||||
expect(prompt).toContain(testCode)
|
||||
})
|
||||
})
|
||||
|
||||
describe("IMPROVE action", () => {
|
||||
it("should format improve prompt correctly", () => {
|
||||
const prompt = codeActionPrompt.create("IMPROVE", {
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
})
|
||||
|
||||
expect(prompt).toContain(`@/${testFilePath}`)
|
||||
expect(prompt).toContain(testCode)
|
||||
expect(prompt).toContain("Code readability")
|
||||
expect(prompt).toContain("Performance optimization")
|
||||
expect(prompt).toContain("Best practices")
|
||||
expect(prompt).toContain("Error handling")
|
||||
})
|
||||
})
|
||||
|
||||
describe("get template", () => {
|
||||
it("should return default template when no custom prompts provided", () => {
|
||||
const template = codeActionPrompt.get(undefined, "EXPLAIN")
|
||||
expect(template).toBe(codeActionPrompt.default.EXPLAIN)
|
||||
})
|
||||
|
||||
it("should return custom template when provided", () => {
|
||||
const customTemplate = "Custom template for explaining code"
|
||||
const customPrompts = {
|
||||
EXPLAIN: customTemplate,
|
||||
}
|
||||
const template = codeActionPrompt.get(customPrompts, "EXPLAIN")
|
||||
expect(template).toBe(customTemplate)
|
||||
})
|
||||
|
||||
it("should return default template when custom prompts does not include type", () => {
|
||||
const customPrompts = {
|
||||
SOMETHING_ELSE: "Other template",
|
||||
}
|
||||
const template = codeActionPrompt.get(customPrompts, "EXPLAIN")
|
||||
expect(template).toBe(codeActionPrompt.default.EXPLAIN)
|
||||
})
|
||||
})
|
||||
|
||||
describe("create with custom prompts", () => {
|
||||
it("should use custom template when provided", () => {
|
||||
const customTemplate = "Custom template for ${filePath}"
|
||||
const customPrompts = {
|
||||
EXPLAIN: customTemplate,
|
||||
}
|
||||
|
||||
const prompt = codeActionPrompt.create(
|
||||
"EXPLAIN",
|
||||
{
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
},
|
||||
customPrompts,
|
||||
)
|
||||
|
||||
expect(prompt).toContain(`Custom template for ${testFilePath}`)
|
||||
expect(prompt).not.toContain("purpose and functionality")
|
||||
})
|
||||
|
||||
it("should use default template when custom prompts does not include type", () => {
|
||||
const customPrompts = {
|
||||
EXPLAIN: "Other template",
|
||||
}
|
||||
|
||||
const prompt = codeActionPrompt.create(
|
||||
"EXPLAIN",
|
||||
{
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
},
|
||||
customPrompts,
|
||||
)
|
||||
|
||||
expect(prompt).toContain("Other template")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -12,6 +12,16 @@ export type ModeConfig = {
|
||||
groups: readonly ToolGroup[] // Now uses groups instead of tools array
|
||||
}
|
||||
|
||||
// Mode-specific prompts only
|
||||
export type PromptComponent = {
|
||||
roleDefinition?: string
|
||||
customInstructions?: string
|
||||
}
|
||||
|
||||
export type CustomPrompts = {
|
||||
[key: string]: PromptComponent | undefined | string
|
||||
}
|
||||
|
||||
// Helper to get all tools for a mode
|
||||
export function getToolsForMode(groups: readonly ToolGroup[]): string[] {
|
||||
const tools = new Set<string>()
|
||||
@@ -130,33 +140,6 @@ export function isToolAllowedForMode(
|
||||
return mode.groups.some((group) => TOOL_GROUPS[group].includes(tool as string))
|
||||
}
|
||||
|
||||
export type PromptComponent = {
|
||||
roleDefinition?: string
|
||||
customInstructions?: string
|
||||
}
|
||||
|
||||
// Mode-specific prompts only
|
||||
export type CustomPrompts = {
|
||||
[key: string]: PromptComponent | undefined
|
||||
}
|
||||
|
||||
// Separate enhance prompt type and definition
|
||||
export type EnhanceConfig = {
|
||||
prompt: string
|
||||
}
|
||||
|
||||
export const enhance: EnhanceConfig = {
|
||||
prompt: "Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):",
|
||||
} as const
|
||||
|
||||
// Completely separate enhance prompt handling
|
||||
export const enhancePrompt = {
|
||||
default: enhance.prompt,
|
||||
get: (customPrompts: Record<string, any> | undefined): string => {
|
||||
return customPrompts?.enhance ?? enhance.prompt
|
||||
},
|
||||
} as const
|
||||
|
||||
// Create the mode-specific default prompts
|
||||
export const defaultPrompts: Readonly<CustomPrompts> = Object.freeze(
|
||||
Object.fromEntries(modes.map((mode) => [mode.slug, { roleDefinition: mode.roleDefinition }])),
|
||||
|
||||
118
src/shared/support-prompt.ts
Normal file
118
src/shared/support-prompt.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
// Separate enhance prompt type and definition
|
||||
export type EnhanceConfig = {
|
||||
prompt: string
|
||||
}
|
||||
|
||||
export const enhance: EnhanceConfig = {
|
||||
prompt: "Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):",
|
||||
} as const
|
||||
|
||||
// Completely separate enhance prompt handling
|
||||
export const enhancePrompt = {
|
||||
default: enhance.prompt,
|
||||
get: (customPrompts: Record<string, any> | undefined): string => {
|
||||
return customPrompts?.enhance ?? enhance.prompt
|
||||
},
|
||||
} as const
|
||||
|
||||
// Code action prompts
|
||||
type PromptParams = Record<string, string | any[]>
|
||||
|
||||
const generateDiagnosticText = (diagnostics?: any[]) => {
|
||||
if (!diagnostics?.length) return ""
|
||||
return `\nCurrent problems detected:\n${diagnostics
|
||||
.map((d) => `- [${d.source || "Error"}] ${d.message}${d.code ? ` (${d.code})` : ""}`)
|
||||
.join("\n")}`
|
||||
}
|
||||
|
||||
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[]))
|
||||
} else {
|
||||
result = result.replaceAll(`\${${key}}`, value as string)
|
||||
}
|
||||
}
|
||||
|
||||
// Replace any remaining user_input placeholders with empty string
|
||||
result = result.replaceAll("${userInput}", "")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const EXPLAIN_TEMPLATE = `
|
||||
Explain the following code from file path @/\${filePath}:
|
||||
\${userInput}
|
||||
|
||||
\`\`\`
|
||||
\${selectedText}
|
||||
\`\`\`
|
||||
|
||||
Please provide a clear and concise explanation of what this code does, including:
|
||||
1. The purpose and functionality
|
||||
2. Key components and their interactions
|
||||
3. Important patterns or techniques used
|
||||
`
|
||||
|
||||
const FIX_TEMPLATE = `
|
||||
Fix any issues in the following code from file path @/\${filePath}
|
||||
\${diagnosticText}
|
||||
\${userInput}
|
||||
|
||||
\`\`\`
|
||||
\${selectedText}
|
||||
\`\`\`
|
||||
|
||||
Please:
|
||||
1. Address all detected problems listed above (if any)
|
||||
2. Identify any other potential bugs or issues
|
||||
3. Provide corrected code
|
||||
4. Explain what was fixed and why
|
||||
`
|
||||
|
||||
const IMPROVE_TEMPLATE = `
|
||||
Improve the following code from file path @/\${filePath}:
|
||||
\${userInput}
|
||||
|
||||
\`\`\`
|
||||
\${selectedText}
|
||||
\`\`\`
|
||||
|
||||
Please suggest improvements for:
|
||||
1. Code readability and maintainability
|
||||
2. Performance optimization
|
||||
3. Best practices and patterns
|
||||
4. Error handling and edge cases
|
||||
|
||||
Provide the improved code along with explanations for each enhancement.
|
||||
`
|
||||
|
||||
// Get template based on prompt type
|
||||
const defaultTemplates = {
|
||||
EXPLAIN: EXPLAIN_TEMPLATE,
|
||||
FIX: FIX_TEMPLATE,
|
||||
IMPROVE: IMPROVE_TEMPLATE,
|
||||
} as const
|
||||
|
||||
type CodeActionType = keyof typeof defaultTemplates
|
||||
|
||||
export const codeActionPrompt = {
|
||||
default: defaultTemplates,
|
||||
get: (customPrompts: Record<string, any> | undefined, type: CodeActionType): string => {
|
||||
return customPrompts?.[type] ?? defaultTemplates[type]
|
||||
},
|
||||
create: (type: CodeActionType, params: PromptParams, customPrompts?: Record<string, any>): string => {
|
||||
const template = codeActionPrompt.get(customPrompts, type)
|
||||
return createPrompt(template, params)
|
||||
},
|
||||
} as const
|
||||
|
||||
export type { CodeActionType }
|
||||
|
||||
// User-friendly labels for code action types
|
||||
export const codeActionLabels: Record<CodeActionType, string> = {
|
||||
FIX: "Fix Issues",
|
||||
EXPLAIN: "Explain Code",
|
||||
IMPROVE: "Improve Code",
|
||||
} as const
|
||||
Reference in New Issue
Block a user