feat: Add Task History Context to Prompt Enhancement (#6343)

This commit is contained in:
Will Li 2025-07-30 13:54:33 -07:00 • committed by GitHub
parent 4b45a4e7f2
commit 83280a0d40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 671 additions and 65 deletions

View file

@ -139,6 +139,7 @@ export const globalSettingsSchema = z.object({
customModePrompts: customModePromptsSchema.optional(),
customSupportPrompts: customSupportPromptsSchema.optional(),
enhancementApiConfigId: z.string().optional(),
includeTaskHistoryInEnhance: z.boolean().optional(),
historyPreviewCollapsed: z.boolean().optional(),
profileThresholds: z.record(z.string(), z.number()).optional(),
hasOpenedModeSelector: z.boolean().optional(),

View file

@ -1516,6 +1516,7 @@ export class ClineProvider
followupAutoApproveTimeoutMs,
includeDiagnosticMessages,
maxDiagnosticMessages,
includeTaskHistoryInEnhance,
} = await this.getState()
const telemetryKey = process.env.POSTHOG_API_KEY
@ -1641,6 +1642,7 @@ export class ClineProvider
followupAutoApproveTimeoutMs: followupAutoApproveTimeoutMs ?? 60000,
includeDiagnosticMessages: includeDiagnosticMessages ?? true,
maxDiagnosticMessages: maxDiagnosticMessages ?? 50,
includeTaskHistoryInEnhance: includeTaskHistoryInEnhance ?? false,
}
}
@ -1825,6 +1827,8 @@ export class ClineProvider
// Add diagnostic message settings
includeDiagnosticMessages: stateValues.includeDiagnosticMessages ?? true,
maxDiagnosticMessages: stateValues.maxDiagnosticMessages ?? 50,
// Add includeTaskHistoryInEnhance setting
includeTaskHistoryInEnhance: stateValues.includeTaskHistoryInEnhance ?? false,
}
}

View file

@ -0,0 +1,365 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"
import { MessageEnhancer } from "../messageEnhancer"
import { ProviderSettings, ClineMessage } from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
import * as singleCompletionHandlerModule from "../../../utils/single-completion-handler"
import { ProviderSettingsManager } from "../../config/ProviderSettingsManager"
// Mock dependencies
vi.mock("../../../utils/single-completion-handler")
vi.mock("@roo-code/telemetry")
describe("MessageEnhancer", () => {
let mockProviderSettingsManager: ProviderSettingsManager
let mockSingleCompletionHandler: ReturnType<typeof vi.fn>
const mockApiConfiguration: ProviderSettings = {
apiProvider: "openai",
apiKey: "test-key",
apiModelId: "gpt-4",
}
const mockListApiConfigMeta = [
{ id: "config1", name: "Config 1" },
{ id: "config2", name: "Config 2" },
]
beforeEach(() => {
// Reset all mocks
vi.clearAllMocks()
// Mock provider settings manager
mockProviderSettingsManager = {
getProfile: vi.fn().mockResolvedValue({
name: "Enhancement Config",
apiProvider: "anthropic",
apiKey: "enhancement-key",
apiModelId: "claude-3",
}),
} as any
// Mock single completion handler
mockSingleCompletionHandler = vi.fn().mockResolvedValue("Enhanced prompt text")
vi.mocked(singleCompletionHandlerModule).singleCompletionHandler = mockSingleCompletionHandler
// Mock TelemetryService
vi.mocked(TelemetryService).hasInstance = vi.fn().mockReturnValue(true)
// Mock the instance getter
Object.defineProperty(TelemetryService, "instance", {
get: vi.fn().mockReturnValue({
capturePromptEnhanced: vi.fn(),
}),
configurable: true,
})
})
afterEach(() => {
vi.restoreAllMocks()
})
describe("enhanceMessage", () => {
it("should enhance a simple message successfully", async () => {
const result = await MessageEnhancer.enhanceMessage({
text: "Write a function to calculate fibonacci",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
providerSettingsManager: mockProviderSettingsManager,
})
expect(result.success).toBe(true)
expect(result.enhancedText).toBe("Enhanced prompt text")
expect(result.error).toBeUndefined()
// Verify single completion handler was called with correct prompt
expect(mockSingleCompletionHandler).toHaveBeenCalledWith(
mockApiConfiguration,
expect.stringContaining("Write a function to calculate fibonacci"),
)
})
it("should use enhancement API config when provided", async () => {
const result = await MessageEnhancer.enhanceMessage({
text: "Test prompt",
apiConfiguration: mockApiConfiguration,
customSupportPrompts: {},
listApiConfigMeta: mockListApiConfigMeta,
enhancementApiConfigId: "config2",
providerSettingsManager: mockProviderSettingsManager,
})
expect(result.success).toBe(true)
expect(mockProviderSettingsManager.getProfile).toHaveBeenCalledWith({ id: "config2" })
// Verify the enhancement config was used instead of default
const expectedConfig = {
apiProvider: "anthropic",
apiKey: "enhancement-key",
apiModelId: "claude-3",
}
expect(mockSingleCompletionHandler).toHaveBeenCalledWith(expectedConfig, expect.any(String))
})
it("should include task history when enabled", async () => {
const mockClineMessages: ClineMessage[] = [
{ type: "ask", text: "Create a React component", ts: 1000 },
{ type: "say", say: "text", text: "I'll create a React component for you", ts: 2000 },
{ type: "ask", text: "Add props to the component", ts: 3000 },
{ type: "say", say: "reasoning", text: "Using tool", ts: 4000 }, // Should be filtered out
]
const result = await MessageEnhancer.enhanceMessage({
text: "Improve the component",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
includeTaskHistoryInEnhance: true,
currentClineMessages: mockClineMessages,
providerSettingsManager: mockProviderSettingsManager,
})
expect(result.success).toBe(true)
// Verify the prompt includes task history
const calledPrompt = mockSingleCompletionHandler.mock.calls[0][1]
expect(calledPrompt).toContain("Improve the component")
expect(calledPrompt).toContain("previous conversation context")
expect(calledPrompt).toContain("User: Create a React component")
expect(calledPrompt).toContain("Assistant: I'll create a React component for you")
expect(calledPrompt).toContain("User: Add props to the component")
expect(calledPrompt).not.toContain("Using tool") // reasoning messages should be filtered
})
it("should limit task history to last 10 messages", async () => {
// Create 15 messages
const mockClineMessages: ClineMessage[] = Array.from({ length: 15 }, (_, i) => ({
type: i % 2 === 0 ? "ask" : "say",
say: i % 2 === 1 ? "text" : undefined,
text: `Message ${i + 1}`,
ts: i * 1000,
})) as ClineMessage[]
await MessageEnhancer.enhanceMessage({
text: "Test",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
includeTaskHistoryInEnhance: true,
currentClineMessages: mockClineMessages,
providerSettingsManager: mockProviderSettingsManager,
})
const calledPrompt = mockSingleCompletionHandler.mock.calls[0][1]
// Should include messages 6-15 (last 10)
expect(calledPrompt).toContain("Message 6")
expect(calledPrompt).toContain("Message 15")
expect(calledPrompt).not.toContain("Message 5")
})
it("should truncate long messages in task history", async () => {
const longText = "A".repeat(600) // 600 characters
const mockClineMessages: ClineMessage[] = [{ type: "ask", text: longText, ts: 1000 }]
await MessageEnhancer.enhanceMessage({
text: "Test",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
includeTaskHistoryInEnhance: true,
currentClineMessages: mockClineMessages,
providerSettingsManager: mockProviderSettingsManager,
})
const calledPrompt = mockSingleCompletionHandler.mock.calls[0][1]
// Should truncate to 500 chars + "..."
expect(calledPrompt).toContain("A".repeat(500) + "...")
expect(calledPrompt).not.toContain("A".repeat(501))
})
it("should use custom support prompts when provided", async () => {
const customSupportPrompts = {
ENHANCE: "Custom enhancement template: ${userInput}",
}
await MessageEnhancer.enhanceMessage({
text: "Test prompt",
apiConfiguration: mockApiConfiguration,
customSupportPrompts,
listApiConfigMeta: mockListApiConfigMeta,
providerSettingsManager: mockProviderSettingsManager,
})
const calledPrompt = mockSingleCompletionHandler.mock.calls[0][1]
expect(calledPrompt).toBe("Custom enhancement template: Test prompt")
})
it("should handle errors gracefully", async () => {
mockSingleCompletionHandler.mockRejectedValue(new Error("API error"))
const result = await MessageEnhancer.enhanceMessage({
text: "Test",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
providerSettingsManager: mockProviderSettingsManager,
})
expect(result.success).toBe(false)
expect(result.error).toBe("API error")
expect(result.enhancedText).toBeUndefined()
})
it("should handle non-Error exceptions", async () => {
mockSingleCompletionHandler.mockRejectedValue("String error")
const result = await MessageEnhancer.enhanceMessage({
text: "Test",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
providerSettingsManager: mockProviderSettingsManager,
})
expect(result.success).toBe(false)
expect(result.error).toBe("String error")
})
it("should fall back to default config if enhancement config is invalid", async () => {
mockProviderSettingsManager.getProfile = vi.fn().mockResolvedValue({
name: "Invalid Config",
// Missing apiProvider
})
await MessageEnhancer.enhanceMessage({
text: "Test",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
enhancementApiConfigId: "config2",
providerSettingsManager: mockProviderSettingsManager,
})
// Should use the default config
expect(mockSingleCompletionHandler).toHaveBeenCalledWith(mockApiConfiguration, expect.any(String))
})
it("should handle empty task history gracefully", async () => {
const result = await MessageEnhancer.enhanceMessage({
text: "Test",
apiConfiguration: mockApiConfiguration,
listApiConfigMeta: mockListApiConfigMeta,
includeTaskHistoryInEnhance: true,
currentClineMessages: [],
providerSettingsManager: mockProviderSettingsManager,
})
expect(result.success).toBe(true)
const calledPrompt = mockSingleCompletionHandler.mock.calls[0][1]
// Should not include task history section
expect(calledPrompt).not.toContain("previous conversation context")
})
})
describe("captureTelemetry", () => {
it("should capture telemetry when TelemetryService is available", () => {
const mockTaskId = "task-123"
const mockCaptureEvent = vi.fn()
vi.mocked(TelemetryService.instance).captureEvent = mockCaptureEvent
MessageEnhancer.captureTelemetry(mockTaskId, true)
expect(TelemetryService.hasInstance).toHaveBeenCalled()
expect(mockCaptureEvent).toHaveBeenCalledWith(expect.any(String), {
taskId: mockTaskId,
includeTaskHistory: true,
})
})
it("should handle missing TelemetryService gracefully", () => {
vi.mocked(TelemetryService).hasInstance = vi.fn().mockReturnValue(false)
// Should not throw
expect(() => MessageEnhancer.captureTelemetry("task-123", true)).not.toThrow()
})
it("should work without task ID", () => {
const mockCaptureEvent = vi.fn()
vi.mocked(TelemetryService.instance).captureEvent = mockCaptureEvent
MessageEnhancer.captureTelemetry(undefined, false)
expect(mockCaptureEvent).toHaveBeenCalledWith(expect.any(String), {
includeTaskHistory: false,
})
})
it("should default includeTaskHistory to false when not provided", () => {
const mockCaptureEvent = vi.fn()
vi.mocked(TelemetryService.instance).captureEvent = mockCaptureEvent
MessageEnhancer.captureTelemetry("task-123")
expect(mockCaptureEvent).toHaveBeenCalledWith(expect.any(String), {
taskId: "task-123",
includeTaskHistory: false,
})
})
})
describe("extractTaskHistory", () => {
it("should filter and format messages correctly", () => {
const messages: ClineMessage[] = [
{ type: "ask", text: "User message 1", ts: 1000 },
{ type: "say", say: "text", text: "Assistant message 1", ts: 2000 },
{ type: "say", say: "reasoning", text: "Tool use", ts: 3000 },
{ type: "ask", text: "", ts: 4000 }, // Empty text
{ type: "say", say: "text", text: undefined, ts: 5000 }, // No text
{ type: "ask", text: "User message 2", ts: 6000 },
]
// Access private method through any type assertion for testing
const history = (MessageEnhancer as any).extractTaskHistory(messages)
expect(history).toContain("User: User message 1")
expect(history).toContain("Assistant: Assistant message 1")
expect(history).toContain("User: User message 2")
expect(history).not.toContain("Tool use")
expect(history.split("\n").length).toBe(3) // Only 3 valid messages
})
it("should handle malformed messages gracefully", () => {
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {})
// Create messages that will cause errors when accessed
const malformedMessages = [
null,
undefined,
{ type: "ask" }, // Missing required properties
"not an object",
] as any
// Access private method through any type assertion for testing
const history = (MessageEnhancer as any).extractTaskHistory(malformedMessages)
// Should return empty string and log error
expect(history).toBe("")
expect(consoleSpy).toHaveBeenCalledWith("Failed to extract task history:", expect.any(Error))
consoleSpy.mockRestore()
})
it("should handle messages with circular references", () => {
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {})
// Create a message with circular reference
const circularMessage: any = { type: "ask", text: "Test" }
circularMessage.self = circularMessage
const messages = [circularMessage] as ClineMessage[]
// Access private method through any type assertion for testing
const history = (MessageEnhancer as any).extractTaskHistory(messages)
// Should handle gracefully
expect(history).toBe("User: Test")
consoleSpy.mockRestore()
})
})
})

View file

@ -0,0 +1,143 @@
import { ProviderSettings, ClineMessage, GlobalState, TelemetryEventName } from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
import { supportPrompt } from "../../shared/support-prompt"
import { singleCompletionHandler } from "../../utils/single-completion-handler"
import { ProviderSettingsManager } from "../config/ProviderSettingsManager"
import { ClineProvider } from "./ClineProvider"
export interface MessageEnhancerOptions {
text: string
apiConfiguration: ProviderSettings
customSupportPrompts?: Record<string, any>
listApiConfigMeta: Array<{ id: string; name?: string }>
enhancementApiConfigId?: string
includeTaskHistoryInEnhance?: boolean
currentClineMessages?: ClineMessage[]
providerSettingsManager: ProviderSettingsManager
}
export interface MessageEnhancerResult {
success: boolean
enhancedText?: string
error?: string
}
/**
* Enhances a message prompt using AI, optionally including task history for context
*/
export class MessageEnhancer {
/**
* Enhances a message prompt using the configured AI provider
* @param options Configuration options for message enhancement
* @returns Enhanced message result with success status
*/
static async enhanceMessage(options: MessageEnhancerOptions): Promise<MessageEnhancerResult> {
try {
const {
text,
apiConfiguration,
customSupportPrompts,
listApiConfigMeta,
enhancementApiConfigId,
includeTaskHistoryInEnhance,
currentClineMessages,
providerSettingsManager,
} = options
// Determine which API configuration to use
let configToUse: ProviderSettings = apiConfiguration
// Try to get enhancement config first, fall back to current config
if (enhancementApiConfigId && listApiConfigMeta.find(({ id }) => id === enhancementApiConfigId)) {
const { name: _, ...providerSettings } = await providerSettingsManager.getProfile({
id: enhancementApiConfigId,
})
if (providerSettings.apiProvider) {
configToUse = providerSettings
}
}
// Prepare the prompt to enhance
let promptToEnhance = text
// Include task history if enabled and available
if (includeTaskHistoryInEnhance && currentClineMessages && currentClineMessages.length > 0) {
const taskHistory = this.extractTaskHistory(currentClineMessages)
if (taskHistory) {
promptToEnhance = `${text}\n\nUse the following previous conversation context as needed:\n${taskHistory}`
}
}
// Create the enhancement prompt using the support prompt system
const enhancementPrompt = supportPrompt.create(
"ENHANCE",
{ userInput: promptToEnhance },
customSupportPrompts,
)
// Call the single completion handler to get the enhanced prompt
const enhancedText = await singleCompletionHandler(configToUse, enhancementPrompt)
return {
success: true,
enhancedText,
}
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error),
}
}
}
/**
* Extracts relevant task history from Cline messages for context
* @param messages Array of Cline messages
* @returns Formatted task history string
*/
private static extractTaskHistory(messages: ClineMessage[]): string {
try {
const relevantMessages = messages
.filter((msg) => {
// Include user messages (type: "ask" with text) and assistant messages (type: "say" with say: "text")
if (msg.type === "ask" && msg.text) {
return true
}
if (msg.type === "say" && msg.say === "text" && msg.text) {
return true
}
return false
})
.slice(-10) // Limit to last 10 messages to avoid context explosion
return relevantMessages
.map((msg) => {
const role = msg.type === "ask" ? "User" : "Assistant"
const content = msg.text || ""
// Truncate long messages
return `${role}: ${content.slice(0, 500)}${content.length > 500 ? "..." : ""}`
})
.join("\n")
} catch (error) {
// Log error but don't fail the enhancement
console.error("Failed to extract task history:", error)
return ""
}
}
/**
* Captures telemetry for prompt enhancement
* @param taskId Optional task ID for telemetry tracking
* @param includeTaskHistory Whether task history was included in the enhancement
*/
static captureTelemetry(taskId?: string, includeTaskHistory?: boolean): void {
if (TelemetryService.hasInstance()) {
// Use captureEvent directly to include the includeTaskHistory property
TelemetryService.instance.captureEvent(TelemetryEventName.PROMPT_ENHANCED, {
...(taskId && { taskId }),
includeTaskHistory: includeTaskHistory ?? false,
})
}
}
}

View file

@ -22,6 +22,7 @@ import { changeLanguage, t } from "../../i18n"
import { Package } from "../../shared/package"
import { RouterName, toRouterName, ModelRecord } from "../../shared/api"
import { supportPrompt } from "../../shared/support-prompt"
import { MessageEnhancer } from "./messageEnhancer"
import { checkoutDiffPayloadSchema, checkoutRestorePayloadSchema, WebviewMessage } from "../../shared/WebviewMessage"
import { checkExistKey } from "../../shared/checkExistApiConfig"
@ -35,7 +36,6 @@ import { discoverChromeHostUrl, tryChromeHostUrl } from "../../services/browser/
import { searchWorkspaceFiles } from "../../services/search/file-search"
import { fileExistsAtPath } from "../../utils/fs"
import { playTts, setTtsEnabled, setTtsSpeed, stopTts } from "../../utils/tts"
import { singleCompletionHandler } from "../../utils/single-completion-handler"
import { searchCommits } from "../../utils/git"
import { exportSettings, importSettingsWithFeedback } from "../config/importExport"
import { getOpenAiModels } from "../../api/providers/openai"
@ -1311,6 +1311,10 @@ export const webviewMessageHandler = async (
await updateGlobalState("enhancementApiConfigId", message.text)
await provider.postStateToWebview()
break
case "includeTaskHistoryInEnhance":
await updateGlobalState("includeTaskHistoryInEnhance", message.bool ?? false)
await provider.postStateToWebview()
break
case "condensingApiConfigId":
await updateGlobalState("condensingApiConfigId", message.text)
await provider.postStateToWebview()
@ -1335,32 +1339,34 @@ export const webviewMessageHandler = async (
case "enhancePrompt":
if (message.text) {
try {
const { apiConfiguration, customSupportPrompts, listApiConfigMeta, enhancementApiConfigId } =
await provider.getState()
const state = await provider.getState()
const {
apiConfiguration,
customSupportPrompts,
listApiConfigMeta,
enhancementApiConfigId,
includeTaskHistoryInEnhance,
} = state
// Try to get enhancement config first, fall back to current config.
let configToUse: ProviderSettings = apiConfiguration
if (enhancementApiConfigId && !!listApiConfigMeta.find(({ id }) => id === enhancementApiConfigId)) {
const { name: _, ...providerSettings } = await provider.providerSettingsManager.getProfile({
id: enhancementApiConfigId,
})
if (providerSettings.apiProvider) {
configToUse = providerSettings
}
}
const enhancedPrompt = await singleCompletionHandler(
configToUse,
supportPrompt.create("ENHANCE", { userInput: message.text }, customSupportPrompts),
)
// Capture telemetry for prompt enhancement.
const currentCline = provider.getCurrentCline()
TelemetryService.instance.capturePromptEnhanced(currentCline?.taskId)
const result = await MessageEnhancer.enhanceMessage({
text: message.text,
apiConfiguration,
customSupportPrompts,
listApiConfigMeta,
enhancementApiConfigId,
includeTaskHistoryInEnhance,
currentClineMessages: currentCline?.clineMessages,
providerSettingsManager: provider.providerSettingsManager,
})
await provider.postMessageToWebview({ type: "enhancedPrompt", text: enhancedPrompt })
if (result.success && result.enhancedText) {
// Capture telemetry for prompt enhancement
MessageEnhancer.captureTelemetry(currentCline?.taskId, includeTaskHistoryInEnhance)
await provider.postMessageToWebview({ type: "enhancedPrompt", text: result.enhancedText })
} else {
throw new Error(result.error || "Unknown error")
}
} catch (error) {
provider.log(
`Error enhancing prompt: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`,

View file

@ -140,6 +140,7 @@ export interface WebviewMessage {
| "copySystemPrompt"
| "systemPrompt"
| "enhancementApiConfigId"
| "includeTaskHistoryInEnhance"
| "updateExperimental"
| "autoApprovalEnabled"
| "updateCustomMode"

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react"
import { VSCodeTextArea } from "@vscode/webview-ui-toolkit/react"
import { VSCodeTextArea, VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
import { supportPrompt, SupportPromptType } from "@roo/support-prompt"
@ -22,9 +22,16 @@ import { MessageSquare } from "lucide-react"
interface PromptsSettingsProps {
customSupportPrompts: Record<string, string | undefined>
setCustomSupportPrompts: (prompts: Record<string, string | undefined>) => void
includeTaskHistoryInEnhance?: boolean
setIncludeTaskHistoryInEnhance?: (value: boolean) => void
}
const PromptsSettings = ({ customSupportPrompts, setCustomSupportPrompts }: PromptsSettingsProps) => {
const PromptsSettings = ({
customSupportPrompts,
setCustomSupportPrompts,
includeTaskHistoryInEnhance: propsIncludeTaskHistoryInEnhance,
setIncludeTaskHistoryInEnhance: propsSetIncludeTaskHistoryInEnhance,
}: PromptsSettingsProps) => {
const { t } = useAppTranslation()
const {
listApiConfigMeta,
@ -34,8 +41,14 @@ const PromptsSettings = ({ customSupportPrompts, setCustomSupportPrompts }: Prom
setCondensingApiConfigId,
customCondensingPrompt,
setCustomCondensingPrompt,
includeTaskHistoryInEnhance: contextIncludeTaskHistoryInEnhance,
setIncludeTaskHistoryInEnhance: contextSetIncludeTaskHistoryInEnhance,
} = useExtensionState()
// Use props if provided, otherwise fall back to context
const includeTaskHistoryInEnhance = propsIncludeTaskHistoryInEnhance ?? contextIncludeTaskHistoryInEnhance
const setIncludeTaskHistoryInEnhance = propsSetIncludeTaskHistoryInEnhance ?? contextSetIncludeTaskHistoryInEnhance
const [testPrompt, setTestPrompt] = useState("")
const [isEnhancing, setIsEnhancing] = useState(false)
const [activeSupportOption, setActiveSupportOption] = useState<SupportPromptType>("ENHANCE")
@ -219,28 +232,50 @@ const PromptsSettings = ({ customSupportPrompts, setCustomSupportPrompts }: Prom
</div>
{activeSupportOption === "ENHANCE" && (
<div>
<label className="block font-medium mb-1">
{t("prompts:supportPrompts.enhance.testEnhancement")}
</label>
<VSCodeTextArea
resize="vertical"
value={testPrompt}
onChange={(e) => setTestPrompt((e.target as HTMLTextAreaElement).value)}
placeholder={t("prompts:supportPrompts.enhance.testPromptPlaceholder")}
rows={3}
className="w-full"
data-testid="test-prompt-textarea"
/>
<div className="mt-2 flex justify-start items-center gap-2">
<Button
variant="default"
onClick={handleTestEnhancement}
disabled={isEnhancing}>
{t("prompts:supportPrompts.enhance.previewButton")}
</Button>
<>
<div>
<VSCodeCheckbox
checked={includeTaskHistoryInEnhance || false}
onChange={(e: any) => {
const value = e.target.checked
setIncludeTaskHistoryInEnhance(value)
vscode.postMessage({
type: "includeTaskHistoryInEnhance",
bool: value,
})
}}>
<span className="font-medium">
{t("prompts:supportPrompts.enhance.includeTaskHistory")}
</span>
</VSCodeCheckbox>
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-3">
{t("prompts:supportPrompts.enhance.includeTaskHistoryDescription")}
</div>
</div>
</div>
<div>
<label className="block font-medium mb-1">
{t("prompts:supportPrompts.enhance.testEnhancement")}
</label>
<VSCodeTextArea
resize="vertical"
value={testPrompt}
onChange={(e) => setTestPrompt((e.target as HTMLTextAreaElement).value)}
placeholder={t("prompts:supportPrompts.enhance.testPromptPlaceholder")}
rows={3}
className="w-full"
data-testid="test-prompt-textarea"
/>
<div className="mt-2 flex justify-start items-center gap-2">
<Button
variant="default"
onClick={handleTestEnhancement}
disabled={isEnhancing}>
{t("prompts:supportPrompts.enhance.previewButton")}
</Button>
</div>
</div>
</>
)}
</div>
)}

View file

@ -181,6 +181,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
followupAutoApproveTimeoutMs,
includeDiagnosticMessages,
maxDiagnosticMessages,
includeTaskHistoryInEnhance,
} = cachedState
const apiConfiguration = useMemo(() => cachedState.apiConfiguration ?? {}, [cachedState.apiConfiguration])
@ -338,6 +339,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
vscode.postMessage({ type: "condensingApiConfigId", text: condensingApiConfigId || "" })
vscode.postMessage({ type: "updateCondensingPrompt", text: customCondensingPrompt || "" })
vscode.postMessage({ type: "updateSupportPrompt", values: customSupportPrompts || {} })
vscode.postMessage({ type: "includeTaskHistoryInEnhance", bool: includeTaskHistoryInEnhance ?? false })
vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration })
vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting })
vscode.postMessage({ type: "profileThresholds", values: profileThresholds })
@ -705,6 +707,10 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
<PromptsSettings
customSupportPrompts={customSupportPrompts || {}}
setCustomSupportPrompts={setCustomSupportPromptsField}
includeTaskHistoryInEnhance={includeTaskHistoryInEnhance}
setIncludeTaskHistoryInEnhance={(value) =>
setCachedStateField("includeTaskHistoryInEnhance", value)
}
/>
)}

View file

@ -144,6 +144,8 @@ export interface ExtensionStateContextType extends ExtensionState {
setIncludeDiagnosticMessages: (value: boolean) => void
maxDiagnosticMessages?: number
setMaxDiagnosticMessages: (value: number) => void
includeTaskHistoryInEnhance?: boolean
setIncludeTaskHistoryInEnhance: (value: boolean) => void
}
export const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
@ -262,6 +264,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
project: {},
global: {},
})
const [includeTaskHistoryInEnhance, setIncludeTaskHistoryInEnhance] = useState(false)
const setListApiConfigMeta = useCallback(
(value: ProviderSettingsEntry[]) => setState((prevState) => ({ ...prevState, listApiConfigMeta: value })),
@ -295,6 +298,10 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
if ((newState as any).followupAutoApproveTimeoutMs !== undefined) {
setFollowupAutoApproveTimeoutMs((newState as any).followupAutoApproveTimeoutMs)
}
// Update includeTaskHistoryInEnhance if present in state message
if ((newState as any).includeTaskHistoryInEnhance !== undefined) {
setIncludeTaskHistoryInEnhance((newState as any).includeTaskHistoryInEnhance)
}
// Handle marketplace data if present in state message
if (newState.marketplaceItems !== undefined) {
setMarketplaceItems(newState.marketplaceItems)
@ -506,6 +513,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setMaxDiagnosticMessages: (value) => {
setState((prevState) => ({ ...prevState, maxDiagnosticMessages: value }))
},
includeTaskHistoryInEnhance,
setIncludeTaskHistoryInEnhance,
}
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Utilitzar la configuració d'API seleccionada actualment",
"testPromptPlaceholder": "Introduïu un prompt per provar la millora",
"previewButton": "Previsualització de la millora del prompt",
"testEnhancement": "Prova la millora"
"testEnhancement": "Prova la millora",
"includeTaskHistory": "Inclou l'historial de tasques com a context",
"includeTaskHistoryDescription": "Quan està activat, els últims 10 missatges de la conversa actual s'inclouran com a context en millorar els prompts, ajudant a generar suggeriments més rellevants i conscients del context."
},
"condense": {
"apiConfiguration": "Configuració de l'API per a la condensació de context",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Aktuell ausgewählte API-Konfiguration verwenden",
"testPromptPlaceholder": "Gib einen Prompt ein, um die Verbesserung zu testen",
"previewButton": "Vorschau der Prompt-Verbesserung",
"testEnhancement": "Verbesserung testen"
"testEnhancement": "Verbesserung testen",
"includeTaskHistory": "Aufgabenverlauf als Kontext einbeziehen",
"includeTaskHistoryDescription": "Wenn aktiviert, werden die letzten 10 Nachrichten aus der aktuellen Unterhaltung als Kontext beim Verbessern von Prompts einbezogen, um relevantere und kontextbewusste Vorschläge zu generieren."
},
"condense": {
"apiConfiguration": "API-Konfiguration für die Kontextverdichtung",

View file

@ -93,7 +93,9 @@
"useCurrentConfig": "Use currently selected API configuration",
"testPromptPlaceholder": "Enter a prompt to test the enhancement",
"previewButton": "Preview Prompt Enhancement",
"testEnhancement": "Test Enhancement"
"testEnhancement": "Test Enhancement",
"includeTaskHistory": "Include task history as context",
"includeTaskHistoryDescription": "When enabled, the last 10 messages from the current conversation will be included as context when enhancing prompts, helping to generate more relevant and context-aware suggestions."
},
"condense": {
"apiConfiguration": "API Configuration for Context Condensing",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Usar la configuración de API actualmente seleccionada",
"testPromptPlaceholder": "Ingresa una solicitud para probar la mejora",
"previewButton": "Vista previa de la mejora de solicitud",
"testEnhancement": "Probar mejora"
"testEnhancement": "Probar mejora",
"includeTaskHistory": "Incluir historial de tareas como contexto",
"includeTaskHistoryDescription": "Cuando está habilitado, los últimos 10 mensajes de la conversación actual se incluirán como contexto al mejorar solicitudes, ayudando a generar sugerencias más relevantes y conscientes del contexto."
},
"condense": {
"apiConfiguration": "Configuración de API para la condensación de contexto",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Utiliser la configuration API actuellement sélectionnée",
"testPromptPlaceholder": "Entrez un prompt pour tester l'amélioration",
"previewButton": "Aperçu de l'amélioration du prompt",
"testEnhancement": "Tester l'amélioration"
"testEnhancement": "Tester l'amélioration",
"includeTaskHistory": "Inclure l'historique des tâches comme contexte",
"includeTaskHistoryDescription": "Lorsque activé, les 10 derniers messages de la conversation actuelle seront inclus comme contexte lors de l'amélioration des prompts, aidant à générer des suggestions plus pertinentes et conscientes du contexte."
},
"condense": {
"apiConfiguration": "Configuration de l'API pour la condensation du contexte",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "वर्तमान में चयनित API कॉन्फ़िगरेशन का उपयोग करें",
"testPromptPlaceholder": "वृद्धि का परीक्षण करने के लिए एक प्रॉम्प्ट दर्ज करें",
"previewButton": "प्रॉम्प्ट वृद्धि का पूर्वावलोकन",
"testEnhancement": "वृद्धि का परीक्षण करें"
"testEnhancement": "वृद्धि का परीक्षण करें",
"includeTaskHistory": "कार्य इतिहास को संदर्भ के रूप में शामिल करें",
"includeTaskHistoryDescription": "जब सक्षम किया जाता है, तो वर्तमान बातचीत के अंतिम 10 संदेश प्रॉम्प्ट को बेहतर बनाते समय संदर्भ के रूप में शामिल किए जाएंगे, जो अधिक प्रासंगिक और संदर्भ-जागरूक सुझाव उत्पन्न करने में मदद करेगा।"
},
"condense": {
"apiConfiguration": "संदर्भ संघनन के लिए API कॉन्फ़िगरेशन",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Gunakan konfigurasi API yang sedang dipilih",
"testPromptPlaceholder": "Masukkan prompt untuk menguji peningkatan",
"previewButton": "Pratinjau Peningkatan Prompt",
"testEnhancement": "Uji Peningkatan"
"testEnhancement": "Uji Peningkatan",
"includeTaskHistory": "Sertakan riwayat tugas sebagai konteks",
"includeTaskHistoryDescription": "Ketika diaktifkan, 10 pesan terakhir dari percakapan saat ini akan disertakan sebagai konteks saat meningkatkan prompt, membantu menghasilkan saran yang lebih relevan dan sadar konteks."
},
"condense": {
"apiConfiguration": "Konfigurasi API untuk Peringkasan Konteks",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Usa la configurazione API attualmente selezionata",
"testPromptPlaceholder": "Inserisci un prompt per testare il miglioramento",
"previewButton": "Anteprima miglioramento prompt",
"testEnhancement": "Testa miglioramento"
"testEnhancement": "Testa miglioramento",
"includeTaskHistory": "Includi cronologia attività come contesto",
"includeTaskHistoryDescription": "Quando abilitato, gli ultimi 10 messaggi della conversazione corrente verranno inclusi come contesto durante il miglioramento dei prompt, aiutando a generare suggerimenti più rilevanti e consapevoli del contesto."
},
"condense": {
"apiConfiguration": "Configurazione API per la condensazione del contesto",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "現在選択されているAPI設定を使用",
"testPromptPlaceholder": "強化をテストするプロンプトを入力してください",
"previewButton": "プロンプト強化のプレビュー",
"testEnhancement": "強化をテスト"
"testEnhancement": "強化をテスト",
"includeTaskHistory": "タスク履歴をコンテキストとして含める",
"includeTaskHistoryDescription": "有効にすると、現在の会話の最後の10メッセージがプロンプト強化時にコンテキストとして含まれ、より関連性が高くコンテキストを意識した提案の生成に役立ちます。"
},
"condense": {
"apiConfiguration": "コンテキスト圧縮のためのAPI構成",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "현재 선택된 API 구성 사용",
"testPromptPlaceholder": "향상을 테스트할 프롬프트 입력",
"previewButton": "프롬프트 향상 미리보기",
"testEnhancement": "향상 테스트"
"testEnhancement": "향상 테스트",
"includeTaskHistory": "작업 기록을 컨텍스트로 포함",
"includeTaskHistoryDescription": "활성화하면 현재 대화의 마지막 10개 메시지가 프롬프트 향상 시 컨텍스트로 포함되어 더 관련성 높고 컨텍스트를 인식하는 제안을 생성하는 데 도움이 됩니다."
},
"condense": {
"apiConfiguration": "컨텍스트 압축을 위한 API 구성",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Huidige API-configuratie gebruiken",
"testPromptPlaceholder": "Voer een prompt in om de verbetering te testen",
"previewButton": "Voorbeeld promptverbetering",
"testEnhancement": "Test verbetering"
"testEnhancement": "Test verbetering",
"includeTaskHistory": "Taakgeschiedenis als context opnemen",
"includeTaskHistoryDescription": "Wanneer ingeschakeld, worden de laatste 10 berichten van het huidige gesprek opgenomen als context bij het verbeteren van prompts, wat helpt bij het genereren van meer relevante en contextbewuste suggesties."
},
"condense": {
"apiConfiguration": "API-configuratie voor contextcondensatie",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Użyj aktualnie wybranej konfiguracji API",
"testPromptPlaceholder": "Wprowadź podpowiedź, aby przetestować ulepszenie",
"previewButton": "Podgląd ulepszenia podpowiedzi",
"testEnhancement": "Testuj ulepszenie"
"testEnhancement": "Testuj ulepszenie",
"includeTaskHistory": "Uwzględnij historię zadań jako kontekst",
"includeTaskHistoryDescription": "Gdy włączone, ostatnie 10 wiadomości z bieżącej rozmowy zostanie uwzględnione jako kontekst podczas ulepszania podpowiedzi, pomagając generować bardziej trafne i świadome kontekstu sugestie."
},
"condense": {
"apiConfiguration": "Konfiguracja API do kondensacji kontekstu",

View file

@ -94,7 +94,9 @@
"useCurrentConfig": "Usar configuração de API atualmente selecionada",
"testPromptPlaceholder": "Digite um prompt para testar o aprimoramento",
"previewButton": "Visualizar aprimoramento do prompt",
"testEnhancement": "Testar aprimoramento"
"testEnhancement": "Testar aprimoramento",
"includeTaskHistory": "Incluir histórico de tarefas como contexto",
"includeTaskHistoryDescription": "Quando habilitado, as últimas 10 mensagens da conversa atual serão incluídas como contexto ao aprimorar prompts, ajudando a gerar sugestões mais relevantes e conscientes do contexto."
},
"condense": {
"apiConfiguration": "Configuração da API para condensação de contexto",

View file

@ -91,7 +91,9 @@
"useCurrentConfig": "Использовать текущую конфигурацию API",
"testPromptPlaceholder": "Введите промпт для тестирования улучшения",
"previewButton": "Просмотреть улучшенный промпт",
"testEnhancement": "Тестировать улучшение"
"testEnhancement": "Тестировать улучшение",
"includeTaskHistory": "Включить историю задач как контекст",
"includeTaskHistoryDescription": "При включении последние 10 сообщений из текущего разговора будут включены как контекст при улучшении промптов, помогая генерировать более релевантные и контекстно-осведомленные предложения."
},
"condense": {
"apiConfiguration": "Конфигурация API для сжатия контекста",

View file

@ -91,7 +91,9 @@
"useCurrentConfig": "Şu anda seçili API yapılandırmasını kullan",
"testPromptPlaceholder": "Geliştirmeyi test etmek için bir prompt girin",
"previewButton": "Prompt geliştirmesini önizle",
"testEnhancement": "Geliştirmeyi test et"
"testEnhancement": "Geliştirmeyi test et",
"includeTaskHistory": "Görev geçmişini bağlam olarak dahil et",
"includeTaskHistoryDescription": "Etkinleştirildiğinde, mevcut konuşmanın son 10 mesajı promptları geliştirirken bağlam olarak dahil edilecek ve daha alakalı ve bağlam farkında öneriler üretmeye yardımcı olacaktır."
},
"condense": {
"apiConfiguration": "Bağlam Yoğunlaştırma için API Yapılandırması",

View file

@ -91,7 +91,9 @@
"useCurrentConfig": "Sử dụng cấu hình API hiện tại đã chọn",
"testPromptPlaceholder": "Nhập lời nhắc để kiểm tra việc nâng cao",
"previewButton": "Xem trước nâng cao lời nhắc",
"testEnhancement": "Kiểm tra cải tiến"
"testEnhancement": "Kiểm tra cải tiến",
"includeTaskHistory": "Bao gồm lịch sử tác vụ làm ngữ cảnh",
"includeTaskHistoryDescription": "Khi được bật, 10 tin nhắn cuối cùng từ cuộc trò chuyện hiện tại sẽ được bao gồm làm ngữ cảnh khi nâng cao lời nhắc, giúp tạo ra các gợi ý phù hợp và nhận thức ngữ cảnh hơn."
},
"condense": {
"apiConfiguration": "Cấu hình API để cô đọng ngữ cảnh",

View file

@ -91,7 +91,9 @@
"useCurrentConfig": "使用当前选择的API配置",
"testPromptPlaceholder": "输入提示词以测试增强效果",
"previewButton": "测试提示词增强",
"testEnhancement": "测试增强"
"testEnhancement": "测试增强",
"includeTaskHistory": "包含任务历史作为上下文",
"includeTaskHistoryDescription": "启用后,当前对话的最后 10 条消息将作为上下文包含在增强提示词时,有助于生成更相关和上下文感知的建议。"
},
"condense": {
"apiConfiguration": "用于上下文压缩的 API 配置",

View file

@ -91,7 +91,9 @@
"useCurrentConfig": "使用目前選擇的 API 設定",
"testPromptPlaceholder": "輸入提示詞以測試增強效果",
"previewButton": "預覽提示詞增強",
"testEnhancement": "測試增強"
"testEnhancement": "測試增強",
"includeTaskHistory": "包含工作歷史作為內容",
"includeTaskHistoryDescription": "啟用後,目前對話的最後 10 則訊息將作為內容包含在增強提示詞時,有助於產生更相關和內容感知的建議。"
},
"condense": {
"apiConfiguration": "用於上下文壓縮的 API 設定",