浏览代码

feat: Move condense prompt editor to Context Management tab (#10909)

Hannes Rudolph 2 月之前
父节点
当前提交
1f7be769ee

+ 73 - 2
webview-ui/src/components/settings/ContextManagementSettings.tsx

@@ -1,11 +1,23 @@
 import { HTMLAttributes } from "react"
 import React from "react"
 import { useAppTranslation } from "@/i18n/TranslationContext"
-import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
+import { VSCodeCheckbox, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react"
 import { FoldVertical } from "lucide-react"
 
+import { supportPrompt } from "@roo/support-prompt"
+
 import { cn } from "@/lib/utils"
-import { Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Button } from "@/components/ui"
+import {
+	Input,
+	Select,
+	SelectContent,
+	SelectItem,
+	SelectTrigger,
+	SelectValue,
+	Slider,
+	Button,
+	StandardTooltip,
+} from "@/components/ui"
 
 import { SetCachedStateField } from "./types"
 import { SectionHeader } from "./SectionHeader"
@@ -32,6 +44,8 @@ type ContextManagementSettingsProps = HTMLAttributes<HTMLDivElement> & {
 	includeCurrentTime?: boolean
 	includeCurrentCost?: boolean
 	maxGitStatusFiles?: number
+	customSupportPrompts: Record<string, string | undefined>
+	setCustomSupportPrompts: (prompts: Record<string, string | undefined>) => void
 	setCachedStateField: SetCachedStateField<
 		| "autoCondenseContext"
 		| "autoCondenseContextPercent"
@@ -73,12 +87,37 @@ export const ContextManagementSettings = ({
 	includeCurrentTime,
 	includeCurrentCost,
 	maxGitStatusFiles,
+	customSupportPrompts,
+	setCustomSupportPrompts,
 	className,
 	...props
 }: ContextManagementSettingsProps) => {
 	const { t } = useAppTranslation()
 	const [selectedThresholdProfile, setSelectedThresholdProfile] = React.useState<string>("default")
 
+	// Helper function to get the CONDENSE prompt value
+	const getCondensePromptValue = (): string => {
+		return supportPrompt.get(customSupportPrompts, "CONDENSE")
+	}
+
+	// Helper function to update the CONDENSE prompt
+	const updateCondensePrompt = (value: string | undefined) => {
+		const updatedPrompts = { ...customSupportPrompts }
+		if (value === undefined) {
+			delete updatedPrompts["CONDENSE"]
+		} else {
+			updatedPrompts["CONDENSE"] = value
+		}
+		setCustomSupportPrompts(updatedPrompts)
+	}
+
+	// Helper function to reset the CONDENSE prompt to default
+	const handleCondenseReset = () => {
+		const updatedPrompts = { ...customSupportPrompts }
+		delete updatedPrompts["CONDENSE"]
+		setCustomSupportPrompts(updatedPrompts)
+	}
+
 	// Helper function to get the current threshold value based on selected profile
 	const getCurrentThresholdValue = () => {
 		if (selectedThresholdProfile === "default") {
@@ -470,6 +509,38 @@ export const ContextManagementSettings = ({
 				</SearchableSetting>
 			</Section>
 			<Section className="pt-2">
+				{/* Context Condensing Prompt Editor */}
+				<SearchableSetting
+					settingId="context-condense-prompt"
+					section="contextManagement"
+					label={t("prompts:supportPrompts.types.CONDENSE.label")}>
+					<div className="flex justify-between items-center mb-1">
+						<label className="block font-medium">{t("prompts:supportPrompts.types.CONDENSE.label")}</label>
+						<StandardTooltip content={t("prompts:supportPrompts.resetPrompt", { promptType: "CONDENSE" })}>
+							<Button variant="ghost" size="icon" onClick={handleCondenseReset}>
+								<span className="codicon codicon-discard"></span>
+							</Button>
+						</StandardTooltip>
+					</div>
+					<div className="text-sm text-vscode-descriptionForeground mb-2">
+						{t("prompts:supportPrompts.types.CONDENSE.description")}
+					</div>
+					<VSCodeTextArea
+						resize="vertical"
+						value={getCondensePromptValue()}
+						onInput={(e) => {
+							const value =
+								(e as unknown as CustomEvent)?.detail?.target?.value ??
+								((e as any).target as HTMLTextAreaElement).value
+							updateCondensePrompt(value)
+						}}
+						rows={6}
+						className="w-full"
+						data-testid="condense-prompt-textarea"
+					/>
+				</SearchableSetting>
+
+				{/* Auto Condense Context */}
 				<SearchableSetting
 					settingId="context-auto-condense"
 					section="contextManagement"

+ 7 - 5
webview-ui/src/components/settings/PromptsSettings.tsx

@@ -117,11 +117,13 @@ const PromptsSettings = ({
 							<SelectValue placeholder={t("settings:common.select")} />
 						</SelectTrigger>
 						<SelectContent>
-							{Object.keys(supportPrompt.default).map((type) => (
-								<SelectItem key={type} value={type} data-testid={`${type}-option`}>
-									{t(`prompts:supportPrompts.types.${type}.label`)}
-								</SelectItem>
-							))}
+							{Object.keys(supportPrompt.default)
+								.filter((type) => type !== "CONDENSE")
+								.map((type) => (
+									<SelectItem key={type} value={type} data-testid={`${type}-option`}>
+										{t(`prompts:supportPrompts.types.${type}.label`)}
+									</SelectItem>
+								))}
 						</SelectContent>
 					</Select>
 					<div className="text-sm text-vscode-descriptionForeground mt-1">

+ 2 - 0
webview-ui/src/components/settings/SettingsView.tsx

@@ -863,6 +863,8 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
 								includeCurrentTime={includeCurrentTime}
 								includeCurrentCost={includeCurrentCost}
 								maxGitStatusFiles={maxGitStatusFiles}
+								customSupportPrompts={customSupportPrompts || {}}
+								setCustomSupportPrompts={setCustomSupportPromptsField}
 								setCachedStateField={setCachedStateField}
 							/>
 						)}

+ 3 - 1
webview-ui/src/components/settings/__tests__/ContextManagementSettings.spec.tsx

@@ -56,6 +56,7 @@ vi.mock("@/components/ui", () => ({
 	SelectValue: ({ children, ...props }: any) => <div {...props}>{children}</div>,
 	SelectContent: ({ children, ...props }: any) => <div {...props}>{children}</div>,
 	SelectItem: ({ children, ...props }: any) => <div {...props}>{children}</div>,
+	StandardTooltip: ({ children, content }: any) => <div title={content}>{children}</div>,
 }))
 
 // Mock vscode utilities - this is necessary since we're not in a VSCode environment
@@ -87,7 +88,6 @@ describe("ContextManagementSettings", () => {
 	const defaultProps = {
 		autoCondenseContext: false,
 		autoCondenseContextPercent: 80,
-		customCondensingPrompt: undefined,
 		listApiConfigMeta: [],
 		maxOpenTabsContext: 20,
 		maxWorkspaceFiles: 200,
@@ -98,6 +98,8 @@ describe("ContextManagementSettings", () => {
 		includeDiagnosticMessages: true,
 		maxDiagnosticMessages: 50,
 		writeDelayMs: 1000,
+		customSupportPrompts: {},
+		setCustomSupportPrompts: vi.fn(),
 		setCachedStateField: vi.fn(),
 	}