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:
sam hoang
2025-01-23 00:31:43 +07:00
parent 7845791720
commit 22907a0578
9 changed files with 467 additions and 268 deletions

View File

@@ -1,76 +0,0 @@
import { explainCodePrompt, fixCodePrompt, improveCodePrompt } from '../code-actions';
describe('Code Action Prompts', () => {
const testFilePath = 'test/file.ts';
const testCode = 'function test() { return true; }';
describe('explainCodePrompt', () => {
it('should format explain prompt correctly', () => {
const prompt = explainCodePrompt({
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('fixCodePrompt', () => {
it('should format fix prompt without diagnostics', () => {
const prompt = fixCodePrompt({
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 = fixCodePrompt({
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('improveCodePrompt', () => {
it('should format improve prompt correctly', () => {
const prompt = improveCodePrompt({
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');
});
});
});

View File

@@ -1,87 +0,0 @@
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;
};
export 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
`;
export 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
`;
export 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.
`;
export const explainCodePrompt = (params: PromptParams) =>
createPrompt(EXPLAIN_TEMPLATE, params);
export const fixCodePrompt = (params: PromptParams) =>
createPrompt(FIX_TEMPLATE, params);
export const improveCodePrompt = (params: PromptParams) =>
createPrompt(IMPROVE_TEMPLATE, params);
// Get template based on prompt type
export const defaultTemplates = {
'EXPLAIN': EXPLAIN_TEMPLATE,
'FIX': FIX_TEMPLATE,
'IMPROVE': IMPROVE_TEMPLATE
}

View File

@@ -1,4 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import delay from "delay"
import axios from "axios"
import fs from "fs/promises"
import os from "os"
@@ -23,7 +24,6 @@ import {
modes,
CustomPrompts,
PromptComponent,
enhance,
ModeConfig,
defaultModeSlug,
getModeBySlug,
@@ -40,10 +40,7 @@ import { enhancePrompt } from "../../utils/enhance-prompt"
import { getCommitInfo, searchCommits, getWorkingState } from "../../utils/git"
import { ConfigManager } from "../config/ConfigManager"
import { CustomModesManager } from "../config/CustomModesManager"
import {
defaultTemplates,
createPrompt
} from "../prompts/code-actions"
import { enhance, codeActionPrompt } from "../../shared/support-prompt"
import { ACTION_NAMES } from "../CodeActionProvider"
@@ -189,17 +186,27 @@ export class ClineProvider implements vscode.WebviewViewProvider {
public static async handleCodeAction(
promptType: keyof typeof ACTION_NAMES,
params: Record<string, string | any[]>
params: Record<string, string | any[]>,
): Promise<void> {
const visibleProvider = ClineProvider.getVisibleInstance()
let visibleProvider = ClineProvider.getVisibleInstance()
// If no visible provider, try to show the sidebar view
if (!visibleProvider) {
await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
// Wait briefly for the view to become visible
await delay(100)
visibleProvider = ClineProvider.getVisibleInstance()
}
// If still no visible provider, return
if (!visibleProvider) {
return
}
const { utilPrompt } = await visibleProvider.getState()
const { customPrompts } = await visibleProvider.getState()
const prompt = codeActionPrompt.create(promptType, params, customPrompts)
const template = utilPrompt?.[promptType] ?? defaultTemplates[promptType]
const prompt = createPrompt(template, params)
await visibleProvider.initClineWithTask(prompt)
}
@@ -297,7 +304,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experimentalDiffStrategy,
} = await this.getState()
const modePrompt = customPrompts?.[mode]
const modePrompt = customPrompts?.[mode] as PromptComponent
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
this.cline = new Cline(
@@ -325,7 +332,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experimentalDiffStrategy,
} = await this.getState()
const modePrompt = customPrompts?.[mode]
const modePrompt = customPrompts?.[mode] as PromptComponent
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
this.cline = new Cline(
@@ -804,29 +811,49 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.postStateToWebview()
break
case "updateEnhancedPrompt":
const existingPrompts = (await this.getGlobalState("customPrompts")) || {}
case "updateSupportPrompt":
try {
if (Object.keys(message?.values ?? {}).length === 0) {
return
}
const updatedPrompts = {
...existingPrompts,
enhance: message.text,
const existingPrompts = (await this.getGlobalState("customPrompts")) || {}
const updatedPrompts = {
...existingPrompts,
...message.values,
}
await this.updateGlobalState("customPrompts", updatedPrompts)
await this.postStateToWebview()
} catch (error) {
console.error("Error update support prompt:", error)
vscode.window.showErrorMessage("Failed to update support prompt")
}
break
case "resetSupportPrompt":
try {
if (!message?.text) {
return
}
await this.updateGlobalState("customPrompts", updatedPrompts)
const existingPrompts = ((await this.getGlobalState("customPrompts")) || {}) as Record<
string,
any
>
// Get current state and explicitly include customPrompts
const currentState = await this.getState()
const updatedPrompts = {
...existingPrompts,
}
const stateWithPrompts = {
...currentState,
customPrompts: updatedPrompts,
updatedPrompts[message.text] = undefined
await this.updateGlobalState("customPrompts", updatedPrompts)
await this.postStateToWebview()
} catch (error) {
console.error("Error reset support prompt:", error)
vscode.window.showErrorMessage("Failed to reset support prompt")
}
// Post state with prompts
this.view?.webview.postMessage({
type: "state",
state: stateWithPrompts,
})
break
case "updatePrompt":
if (message.promptMode && message.customPrompt !== undefined) {