diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f919df6..b28bad6 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -40,7 +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 { enhance, codeActionPrompt } from "../../shared/support-prompt" +import { supportPrompt } from "../../shared/support-prompt" import { ACTION_NAMES } from "../CodeActionProvider" @@ -205,7 +205,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const { customPrompts } = await visibleProvider.getState() - const prompt = codeActionPrompt.create(promptType, params, customPrompts) + const prompt = supportPrompt.create(promptType, params, customPrompts) await visibleProvider.initClineWithTask(prompt) } @@ -996,16 +996,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } - const getEnhancePrompt = (value: string | PromptComponent | undefined): string => { - if (typeof value === "string") { - return value - } - return enhance.prompt // Use the constant from modes.ts which we know is a string - } const enhancedPrompt = await enhancePrompt( configToUse, message.text, - getEnhancePrompt(customPrompts?.enhance), + supportPrompt.get(customPrompts, "ENHANCE"), ) await this.postMessageToWebview({ type: "enhancedPrompt", diff --git a/src/shared/__tests__/support-prompts.test.ts b/src/shared/__tests__/support-prompts.test.ts index 92d2342..ee7253e 100644 --- a/src/shared/__tests__/support-prompts.test.ts +++ b/src/shared/__tests__/support-prompts.test.ts @@ -1,4 +1,4 @@ -import { codeActionPrompt, type CodeActionType } from "../support-prompt" +import { supportPrompt } from "../support-prompt" describe("Code Action Prompts", () => { const testFilePath = "test/file.ts" @@ -6,7 +6,7 @@ describe("Code Action Prompts", () => { describe("EXPLAIN action", () => { it("should format explain prompt correctly", () => { - const prompt = codeActionPrompt.create("EXPLAIN", { + const prompt = supportPrompt.create("EXPLAIN", { filePath: testFilePath, selectedText: testCode, }) @@ -21,7 +21,7 @@ describe("Code Action Prompts", () => { describe("FIX action", () => { it("should format fix prompt without diagnostics", () => { - const prompt = codeActionPrompt.create("FIX", { + const prompt = supportPrompt.create("FIX", { filePath: testFilePath, selectedText: testCode, }) @@ -45,7 +45,7 @@ describe("Code Action Prompts", () => { }, ] - const prompt = codeActionPrompt.create("FIX", { + const prompt = supportPrompt.create("FIX", { filePath: testFilePath, selectedText: testCode, diagnostics, @@ -60,7 +60,7 @@ describe("Code Action Prompts", () => { describe("IMPROVE action", () => { it("should format improve prompt correctly", () => { - const prompt = codeActionPrompt.create("IMPROVE", { + const prompt = supportPrompt.create("IMPROVE", { filePath: testFilePath, selectedText: testCode, }) @@ -74,10 +74,26 @@ describe("Code Action Prompts", () => { }) }) + describe("ENHANCE action", () => { + it("should format enhance prompt correctly", () => { + const prompt = supportPrompt.create("ENHANCE", { + filePath: testFilePath, + selectedText: testCode, + }) + + expect(prompt).toBe( + "Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):", + ) + // Verify it ignores parameters since ENHANCE template doesn't use any + expect(prompt).not.toContain(testFilePath) + expect(prompt).not.toContain(testCode) + }) + }) + 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) + const template = supportPrompt.get(undefined, "EXPLAIN") + expect(template).toBe(supportPrompt.default.EXPLAIN) }) it("should return custom template when provided", () => { @@ -85,7 +101,7 @@ describe("Code Action Prompts", () => { const customPrompts = { EXPLAIN: customTemplate, } - const template = codeActionPrompt.get(customPrompts, "EXPLAIN") + const template = supportPrompt.get(customPrompts, "EXPLAIN") expect(template).toBe(customTemplate) }) @@ -93,8 +109,8 @@ describe("Code Action Prompts", () => { const customPrompts = { SOMETHING_ELSE: "Other template", } - const template = codeActionPrompt.get(customPrompts, "EXPLAIN") - expect(template).toBe(codeActionPrompt.default.EXPLAIN) + const template = supportPrompt.get(customPrompts, "EXPLAIN") + expect(template).toBe(supportPrompt.default.EXPLAIN) }) }) @@ -105,7 +121,7 @@ describe("Code Action Prompts", () => { EXPLAIN: customTemplate, } - const prompt = codeActionPrompt.create( + const prompt = supportPrompt.create( "EXPLAIN", { filePath: testFilePath, @@ -123,7 +139,7 @@ describe("Code Action Prompts", () => { EXPLAIN: "Other template", } - const prompt = codeActionPrompt.create( + const prompt = supportPrompt.create( "EXPLAIN", { filePath: testFilePath, diff --git a/src/shared/support-prompt.ts b/src/shared/support-prompt.ts index 4ce9f93..406e981 100644 --- a/src/shared/support-prompt.ts +++ b/src/shared/support-prompt.ts @@ -1,21 +1,4 @@ -// 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 | undefined): string => { - return customPrompts?.enhance ?? enhance.prompt - }, -} as const - -// Code action prompts +// Support prompts type PromptParams = Record const generateDiagnosticText = (diagnostics?: any[]) => { @@ -41,8 +24,7 @@ export const createPrompt = (template: string, params: PromptParams): string => return result } -const EXPLAIN_TEMPLATE = ` -Explain the following code from file path @/\${filePath}: +const EXPLAIN_TEMPLATE = `Explain the following code from file path @/\${filePath}: \${userInput} \`\`\` @@ -55,8 +37,7 @@ Please provide a clear and concise explanation of what this code does, including 3. Important patterns or techniques used ` -const FIX_TEMPLATE = ` -Fix any issues in the following code from file path @/\${filePath} +const FIX_TEMPLATE = `Fix any issues in the following code from file path @/\${filePath} \${diagnosticText} \${userInput} @@ -71,8 +52,7 @@ Please: 4. Explain what was fixed and why ` -const IMPROVE_TEMPLATE = ` -Improve the following code from file path @/\${filePath}: +const IMPROVE_TEMPLATE = `Improve the following code from file path @/\${filePath}: \${userInput} \`\`\` @@ -88,31 +68,36 @@ Please suggest improvements for: Provide the improved code along with explanations for each enhancement. ` +const ENHANCE_TEMPLATE = + "Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):" + // Get template based on prompt type const defaultTemplates = { EXPLAIN: EXPLAIN_TEMPLATE, FIX: FIX_TEMPLATE, IMPROVE: IMPROVE_TEMPLATE, + ENHANCE: ENHANCE_TEMPLATE, } as const -type CodeActionType = keyof typeof defaultTemplates +type SupportPromptType = keyof typeof defaultTemplates -export const codeActionPrompt = { +export const supportPrompt = { default: defaultTemplates, - get: (customPrompts: Record | undefined, type: CodeActionType): string => { + get: (customPrompts: Record | undefined, type: SupportPromptType): string => { return customPrompts?.[type] ?? defaultTemplates[type] }, - create: (type: CodeActionType, params: PromptParams, customPrompts?: Record): string => { - const template = codeActionPrompt.get(customPrompts, type) + create: (type: SupportPromptType, params: PromptParams, customPrompts?: Record): string => { + const template = supportPrompt.get(customPrompts, type) return createPrompt(template, params) }, } as const -export type { CodeActionType } +export type { SupportPromptType } -// User-friendly labels for code action types -export const codeActionLabels: Record = { +// User-friendly labels for support prompt types +export const supportPromptLabels: Record = { FIX: "Fix Issues", EXPLAIN: "Explain Code", IMPROVE: "Improve Code", + ENHANCE: "Enhance Prompt", } as const diff --git a/webview-ui/src/components/prompts/PromptsView.tsx b/webview-ui/src/components/prompts/PromptsView.tsx index a767fd4..6f5085a 100644 --- a/webview-ui/src/components/prompts/PromptsView.tsx +++ b/webview-ui/src/components/prompts/PromptsView.tsx @@ -9,12 +9,7 @@ import { } from "@vscode/webview-ui-toolkit/react" import { useExtensionState } from "../../context/ExtensionStateContext" import { Mode, PromptComponent, getRoleDefinition, getAllModes, ModeConfig } from "../../../../src/shared/modes" -import { - enhancePrompt, - codeActionPrompt, - CodeActionType, - codeActionLabels, -} from "../../../../src/shared/support-prompt" +import { supportPrompt, SupportPromptType, supportPromptLabels } from "../../../../src/shared/support-prompt" import { TOOL_GROUPS, GROUP_DISPLAY_NAMES, ToolGroup } from "../../../../src/shared/tool-groups" import { vscode } from "../../utils/vscode" @@ -50,7 +45,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { const [selectedPromptTitle, setSelectedPromptTitle] = useState("") const [isToolsEditMode, setIsToolsEditMode] = useState(false) const [isCreateModeDialogOpen, setIsCreateModeDialogOpen] = useState(false) - const [activeCodeActionTab, setActiveCodeActionTab] = useState("FIX") + const [activeSupportTab, setActiveSupportTab] = useState("EXPLAIN") // Direct update functions const updateAgentPrompt = useCallback( @@ -255,16 +250,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { return () => window.removeEventListener("message", handler) }, []) - const updateEnhancePrompt = (value: string | undefined) => { - vscode.postMessage({ - type: "updateSupportPrompt", - values: { - enhance: value, - }, - }) - } - - const updateCodeActionPrompt = (type: CodeActionType, value: string | undefined) => { + const updateSupportPrompt = (type: SupportPromptType, value: string | undefined) => { vscode.postMessage({ type: "updateSupportPrompt", values: { @@ -273,14 +259,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { }) } - const handleEnhancePromptChange = (e: Event | React.FormEvent): void => { - const value = (e as CustomEvent)?.detail?.target?.value || ((e as any).target as HTMLTextAreaElement).value - const trimmedValue = value.trim() - if (trimmedValue !== enhancePrompt.default) { - updateEnhancePrompt(trimmedValue || enhancePrompt.default) - } - } - const handleAgentReset = (modeSlug: string) => { // Only reset role definition for built-in modes const existingPrompt = customPrompts?.[modeSlug] as PromptComponent @@ -290,26 +268,15 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { }) } - const handleEnhanceReset = () => { - vscode.postMessage({ - type: "resetSupportPrompt", - text: "enhance", - }) - } - - const handleCodeActionReset = (type: CodeActionType) => { + const handleSupportReset = (type: SupportPromptType) => { vscode.postMessage({ type: "resetSupportPrompt", text: type, }) } - const getEnhancePromptValue = (): string => { - return enhancePrompt.get(customPrompts) - } - - const getCodeActionPromptValue = (type: CodeActionType): string => { - return codeActionPrompt.get(customPrompts, type) + const getSupportPromptValue = (type: SupportPromptType): string => { + return supportPrompt.get(customPrompts, type) } const handleTestEnhancement = () => { @@ -786,7 +753,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
-
Code Action Prompts
+
Support Prompts
{ paddingBottom: "4px", paddingRight: "20px", }}> - {Object.keys(codeActionPrompt.default).map((type) => ( + {Object.keys(supportPrompt.default).map((type) => ( ))}
{/* Show active tab content */} -
+
{ alignItems: "center", marginBottom: "4px", }}> -
{activeCodeActionTab} Prompt
+
{activeSupportTab} Prompt
handleCodeActionReset(activeCodeActionTab)} - title={`Reset ${activeCodeActionTab} prompt to default`}> + onClick={() => handleSupportReset(activeSupportTab)} + title={`Reset ${activeSupportTab} prompt to default`}>
+ + {activeSupportTab === "ENHANCE" && ( +
+
+ Use prompt enhancement to get tailored suggestions or improvements for your inputs. + This ensures Roo understands your intent and provides the best possible responses. +
+
+
+
API Configuration
+
+ You can select an API configuration to always use for enhancing prompts, or + just use whatever is currently selected +
+
+ { + const value = e.detail?.target?.value || e.target?.value + setEnhancementApiConfigId(value) + vscode.postMessage({ + type: "enhancementApiConfigId", + text: value, + }) + }} + style={{ width: "300px" }}> + Use currently selected API configuration + {(listApiConfigMeta || []).map((config) => ( + + {config.name} + + ))} + +
+
+ )} + { const value = (e as CustomEvent)?.detail?.target?.value || ((e as any).target as HTMLTextAreaElement).value const trimmedValue = value.trim() - updateCodeActionPrompt(activeCodeActionTab, trimmedValue || undefined) + updateSupportPrompt(activeSupportTab, trimmedValue || undefined) }} rows={4} resize="vertical" style={{ width: "100%" }} /> -
-
-

Prompt Enhancement

- -
- Use prompt enhancement to get tailored suggestions or improvements for your inputs. This ensures Roo - understands your intent and provides the best possible responses. -
- -
-
-
-
-
API Configuration
-
- You can select an API configuration to always use for enhancing prompts, or just use - whatever is currently selected -
-
- { - const value = e.detail?.target?.value || e.target?.value - setEnhancementApiConfigId(value) - vscode.postMessage({ - type: "enhancementApiConfigId", - text: value, - }) - }} - style={{ width: "300px" }}> - Use currently selected API configuration - {(listApiConfigMeta || []).map((config) => ( - - {config.name} - - ))} - -
- -
-
-
Enhancement Prompt
-
+ {activeSupportTab === "ENHANCE" && ( +
+ setTestPrompt((e.target as HTMLTextAreaElement).value)} + placeholder="Enter a prompt to test the enhancement" + rows={3} + resize="vertical" + style={{ width: "100%" }} + data-testid="test-prompt-textarea" + /> +
- + onClick={handleTestEnhancement} + disabled={isEnhancing} + appearance="primary"> + Preview Prompt Enhancement
-
- This prompt will be used to refine your input when you hit the sparkle icon in chat. -
-
- - -
- setTestPrompt((e.target as HTMLTextAreaElement).value)} - placeholder="Enter a prompt to test the enhancement" - rows={3} - resize="vertical" - style={{ width: "100%" }} - data-testid="test-prompt-textarea" - /> -
- - Preview Prompt Enhancement - -
-
+ )}
- - {/* Bottom padding */} -
{isCreateModeDialogOpen && ( diff --git a/webview-ui/src/components/prompts/__tests__/PromptsView.test.tsx b/webview-ui/src/components/prompts/__tests__/PromptsView.test.tsx index 5619d26..93e8698 100644 --- a/webview-ui/src/components/prompts/__tests__/PromptsView.test.tsx +++ b/webview-ui/src/components/prompts/__tests__/PromptsView.test.tsx @@ -166,6 +166,10 @@ describe("PromptsView", () => { it("handles API configuration selection", () => { renderPromptsView() + // Click the ENHANCE tab first to show the API config dropdown + const enhanceTab = screen.getByTestId("ENHANCE-tab") + fireEvent.click(enhanceTab) + const dropdown = screen.getByTestId("api-config-dropdown") fireEvent( dropdown,