Browse Source

refactor(code-actions): implement parameter object pattern for prompt generation

- Extract prompt templates into constants
- Add createPrompt utility for template string handling
- Consolidate code action handling in ClineProvider
- Update tests to use new parameter object pattern
sam hoang 1 year ago
parent
commit
1b26f91ea7

+ 17 - 4
src/core/prompts/__tests__/code-actions.test.ts

@@ -6,7 +6,10 @@ describe('Code Action Prompts', () => {
 
     describe('explainCodePrompt', () => {
         it('should format explain prompt correctly', () => {
-            const prompt = explainCodePrompt(testFilePath, testCode);
+            const prompt = explainCodePrompt({
+                filePath: testFilePath,
+                selectedText: testCode
+            });
             
             expect(prompt).toContain(`@/${testFilePath}`);
             expect(prompt).toContain(testCode);
@@ -18,7 +21,10 @@ describe('Code Action Prompts', () => {
 
     describe('fixCodePrompt', () => {
         it('should format fix prompt without diagnostics', () => {
-            const prompt = fixCodePrompt(testFilePath, testCode);
+            const prompt = fixCodePrompt({
+                filePath: testFilePath,
+                selectedText: testCode
+            });
             
             expect(prompt).toContain(`@/${testFilePath}`);
             expect(prompt).toContain(testCode);
@@ -39,7 +45,11 @@ describe('Code Action Prompts', () => {
                 }
             ];
 
-            const prompt = fixCodePrompt(testFilePath, testCode, diagnostics);
+            const prompt = fixCodePrompt({
+                filePath: testFilePath,
+                selectedText: testCode,
+                diagnostics
+            });
             
             expect(prompt).toContain('Current problems detected:');
             expect(prompt).toContain('[eslint] Missing semicolon (semi)');
@@ -50,7 +60,10 @@ describe('Code Action Prompts', () => {
 
     describe('improveCodePrompt', () => {
         it('should format improve prompt correctly', () => {
-            const prompt = improveCodePrompt(testFilePath, testCode);
+            const prompt = improveCodePrompt({
+                filePath: testFilePath,
+                selectedText: testCode
+            });
             
             expect(prompt).toContain(`@/${testFilePath}`);
             expect(prompt).toContain(testCode);

+ 41 - 18
src/core/prompts/code-actions.ts

@@ -1,8 +1,29 @@
-export const explainCodePrompt = (filePath: string, selectedText: string) => `
-Explain the following code from file path @/${filePath}:
+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')}`;
+};
+
+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);
+        }
+    }
+    return result;
+};
+
+const EXPLAIN_TEMPLATE = `
+Explain the following code from file path @/\${filePath}:
 
 \`\`\`
-${selectedText}
+\${selectedText}
 \`\`\`
 
 Please provide a clear and concise explanation of what this code does, including:
@@ -11,18 +32,12 @@ Please provide a clear and concise explanation of what this code does, including
 3. Important patterns or techniques used
 `;
 
-export const fixCodePrompt = (filePath: string, selectedText: string, diagnostics?: any[]) => {
-    const diagnosticText = diagnostics && diagnostics.length > 0
-        ? `\nCurrent problems detected:
-${diagnostics.map(d => `- [${d.source || 'Error'}] ${d.message}${d.code ? ` (${d.code})` : ''}`).join('\n')}`
-        : '';
-
-    return `
-Fix any issues in the following code from file path @/${filePath}
-${diagnosticText}
+const FIX_TEMPLATE = `
+Fix any issues in the following code from file path @/\${filePath}
+\${diagnosticText}
 
 \`\`\`
-${selectedText}
+\${selectedText}
 \`\`\`
 
 Please:
@@ -31,13 +46,12 @@ Please:
 3. Provide corrected code
 4. Explain what was fixed and why
 `;
-};
 
-export const improveCodePrompt = (filePath: string, selectedText: string) => `
-Improve the following code from file path @/${filePath}:
+const IMPROVE_TEMPLATE = `
+Improve the following code from file path @/\${filePath}:
 
 \`\`\`
-${selectedText}
+\${selectedText}
 \`\`\`
 
 Please suggest improvements for:
@@ -47,4 +61,13 @@ Please suggest improvements for:
 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);

+ 14 - 0
src/core/webview/ClineProvider.ts

@@ -181,6 +181,20 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 		return findLast(Array.from(this.activeInstances), (instance) => instance.view?.visible === true)
 	}
 
+	public static async handleCodeAction(
+		promptGenerator: (params: Record<string, string | any[]>) => string,
+		params: Record<string, string | any[]>
+	): Promise<void> {
+		const visibleProvider = ClineProvider.getVisibleInstance()
+		if (!visibleProvider) {
+			return
+		}
+
+		const prompt = promptGenerator(params)
+
+		await visibleProvider.initClineWithTask(prompt)
+	}
+
 	resolveWebviewView(
 		webviewView: vscode.WebviewView | vscode.WebviewPanel,
 		//context: vscode.WebviewViewResolveContext<unknown>, used to recreate a deallocated webview, but we don't need this since we use retainContextWhenHidden

+ 7 - 18
src/extension.ts

@@ -174,34 +174,23 @@ export function activate(context: vscode.ExtensionContext) {
 	// Register code action commands
 	context.subscriptions.push(
 		vscode.commands.registerCommand("roo-cline.explainCode", async (filePath: string, selectedText: string) => {
-			const visibleProvider = ClineProvider.getVisibleInstance()
-			if (!visibleProvider) {
-				return
-			}
-			const prompt = explainCodePrompt(filePath, selectedText)
-			await visibleProvider.initClineWithTask(prompt)
+			await ClineProvider.handleCodeAction(explainCodePrompt, { filePath, selectedText })
 		})
 	);
 
 	context.subscriptions.push(
 		vscode.commands.registerCommand("roo-cline.fixCode", async (filePath: string, selectedText: string, diagnostics?: any[]) => {
-			const visibleProvider = ClineProvider.getVisibleInstance()
-			if (!visibleProvider) {
-				return
-			}
-			const prompt = fixCodePrompt(filePath, selectedText, diagnostics)
-			await visibleProvider.initClineWithTask(prompt)
+			await ClineProvider.handleCodeAction(fixCodePrompt, {
+				filePath,
+				selectedText,
+				...(diagnostics ? { diagnostics } : {})
+			})
 		})
 	);
 
 	context.subscriptions.push(
 		vscode.commands.registerCommand("roo-cline.improveCode", async (filePath: string, selectedText: string) => {
-			const visibleProvider = ClineProvider.getVisibleInstance()
-			if (!visibleProvider) {
-				return
-			}
-			const prompt = improveCodePrompt(filePath, selectedText)
-			await visibleProvider.initClineWithTask(prompt)
+			await ClineProvider.handleCodeAction(improveCodePrompt, { filePath, selectedText })
 		})
 	);