fix(condense): remove custom condensing model option (#10901)

* fix(condense): remove custom condensing model option

Remove the ability to specify a different model/API configuration for
condensing conversations. Modern conversations include provider-specific
data (tool calls, reasoning blocks, thought signatures) that only the
originating model can properly understand and summarize.

Changes:
- Remove condensingApiHandler parameter from summarizeConversation()
- Remove condensingApiConfigId from context management and Task
- Remove API config dropdown for CONDENSE in settings UI
- Update telemetry to remove usedCustomApiHandler parameter
- Update related tests

Users can still customize the CONDENSE prompt text; only model selection
is removed.

* fix: remove condensingApiConfigId from types and test fixtures

---------

Co-authored-by: Roo Code <roomote@roocode.com>
This commit is contained in:
Hannes Rudolph 2026-01-22 18:06:04 -07:00 committed by GitHub
parent f98dc1389e
commit 9d65772d24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 74 additions and 385 deletions

View file

@ -127,17 +127,11 @@ export class TelemetryService {
this.captureEvent(TelemetryEventName.CHECKPOINT_RESTORED, { taskId })
}
public captureContextCondensed(
taskId: string,
isAutomaticTrigger: boolean,
usedCustomPrompt?: boolean,
usedCustomApiHandler?: boolean,
): void {
public captureContextCondensed(taskId: string, isAutomaticTrigger: boolean, usedCustomPrompt?: boolean): void {
this.captureEvent(TelemetryEventName.CONTEXT_CONDENSED, {
taskId,
isAutomaticTrigger,
...(usedCustomPrompt !== undefined && { usedCustomPrompt }),
...(usedCustomApiHandler !== undefined && { usedCustomApiHandler }),
})
}

View file

@ -63,7 +63,6 @@ export const globalSettingsSchema = z.object({
openRouterImageApiKey: z.string().optional(),
openRouterImageGenerationSelectedModel: z.string().optional(),
condensingApiConfigId: z.string().optional(),
customCondensingPrompt: z.string().optional(),
autoApprovalEnabled: z.boolean().optional(),

View file

@ -324,7 +324,6 @@ export type ExtensionState = Pick<
| "customModePrompts"
| "customSupportPrompts"
| "enhancementApiConfigId"
| "condensingApiConfigId"
| "customCondensingPrompt"
| "codebaseIndexConfig"
| "codebaseIndexModels"

View file

@ -1055,7 +1055,7 @@ describe("summarizeConversation", () => {
expect(mockApiHandler.createMessage).not.toHaveBeenCalled()
})
it("should return error when both condensing and main API handlers are invalid", async () => {
it("should return error when API handler is invalid", async () => {
const messages: ApiMessage[] = [
{ role: "user", content: "Hello", ts: 1 },
{ role: "assistant", content: "Hi there", ts: 2 },
@ -1066,14 +1066,8 @@ describe("summarizeConversation", () => {
{ role: "user", content: "Tell me more", ts: 7 },
]
// Create invalid handlers (missing createMessage)
const invalidMainHandler = {
countTokens: vi.fn(),
getModel: vi.fn(),
// createMessage is missing
} as unknown as ApiHandler
const invalidCondensingHandler = {
// Create invalid handler (missing createMessage)
const invalidHandler = {
countTokens: vi.fn(),
getModel: vi.fn(),
// createMessage is missing
@ -1086,16 +1080,13 @@ describe("summarizeConversation", () => {
const result = await summarizeConversation(
messages,
invalidMainHandler,
invalidHandler,
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
invalidCondensingHandler,
)
// Should return original messages when both handlers are invalid
// Should return original messages when handler is invalid
expect(result.messages).toEqual(messages)
expect(result.cost).toBe(0)
expect(result.summary).toBe("")
@ -1103,9 +1094,7 @@ describe("summarizeConversation", () => {
expect(result.newContextTokens).toBeUndefined()
// Verify error was logged
expect(mockError).toHaveBeenCalledWith(
expect.stringContaining("Main API handler is also invalid for condensing"),
)
expect(mockError).toHaveBeenCalledWith(expect.stringContaining("API handler is invalid for condensing"))
// Restore console.error
console.error = originalError
@ -1157,10 +1146,6 @@ describe("summarizeConversation", () => {
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false, // isAutomaticTrigger
undefined, // customCondensingPrompt
undefined, // condensingApiHandler
true, // useNativeTools - required for tool_use block preservation
)
// Find the summary message
@ -1236,10 +1221,6 @@ describe("summarizeConversation", () => {
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
undefined,
true,
)
expect(result.error).toBeUndefined()
@ -1315,10 +1296,6 @@ describe("summarizeConversation", () => {
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
undefined,
true,
)
// Find the summary message (it has isSummary: true)
@ -1389,10 +1366,6 @@ describe("summarizeConversation", () => {
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false, // isAutomaticTrigger
undefined, // customCondensingPrompt
undefined, // condensingApiHandler
true, // useNativeTools - required for tool_use block preservation
)
// Find the summary message
@ -1458,10 +1431,6 @@ describe("summarizeConversation", () => {
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false, // isAutomaticTrigger
undefined, // customCondensingPrompt
undefined, // condensingApiHandler
false, // useNativeTools - not using tools in this test
)
// Find the summary message
@ -1489,7 +1458,6 @@ describe("summarizeConversation", () => {
describe("summarizeConversation with custom settings", () => {
// Mock necessary dependencies
let mockMainApiHandler: ApiHandler
let mockCondensingApiHandler: ApiHandler
const defaultSystemPrompt = "Default prompt"
const taskId = "test-task"
@ -1511,7 +1479,7 @@ describe("summarizeConversation with custom settings", () => {
// Reset telemetry mock
;(TelemetryService.instance.captureContextCondensed as Mock).mockClear()
// Setup mock API handlers
// Setup mock API handler
mockMainApiHandler = {
createMessage: vi.fn().mockImplementation(() => {
return (async function* () {
@ -1534,29 +1502,6 @@ describe("summarizeConversation with custom settings", () => {
},
}),
} as unknown as ApiHandler
mockCondensingApiHandler = {
createMessage: vi.fn().mockImplementation(() => {
return (async function* () {
yield { type: "text" as const, text: "Summary from condensing handler" }
yield { type: "usage" as const, totalCost: 0.03, outputTokens: 80 }
})()
}),
countTokens: vi.fn().mockImplementation(() => Promise.resolve(40)),
getModel: vi.fn().mockReturnValue({
id: "condensing-model",
info: {
contextWindow: 4000,
supportsImages: true,
supportsVision: false,
maxTokens: 2000,
supportsPromptCache: false,
maxCachePoints: 0,
minTokensPerCachePoint: 0,
cachableFields: [],
},
}),
} as unknown as ApiHandler
})
/**
@ -1619,84 +1564,6 @@ describe("summarizeConversation with custom settings", () => {
expect(createMessageCalls[0][0]).toContain("Your task is to create a detailed summary")
})
/**
* Test that condensing API handler is used when provided and valid
*/
it("should use condensingApiHandler when provided and valid", async () => {
await summarizeConversation(
sampleMessages,
mockMainApiHandler,
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
mockCondensingApiHandler,
)
// Verify the condensing handler was used
expect((mockCondensingApiHandler.createMessage as Mock).mock.calls.length).toBe(1)
expect((mockMainApiHandler.createMessage as Mock).mock.calls.length).toBe(0)
})
/**
* Test fallback to main API handler when condensing handler is not provided
*/
it("should fall back to mainApiHandler if condensingApiHandler is not provided", async () => {
await summarizeConversation(
sampleMessages,
mockMainApiHandler,
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
undefined,
)
// Verify the main handler was used
expect((mockMainApiHandler.createMessage as Mock).mock.calls.length).toBe(1)
})
/**
* Test fallback to main API handler when condensing handler is invalid
*/
it("should fall back to mainApiHandler if condensingApiHandler is invalid", async () => {
// Create an invalid handler (missing createMessage)
const invalidHandler = {
countTokens: vi.fn(),
getModel: vi.fn(),
// createMessage is missing
} as unknown as ApiHandler
// Mock console.warn to verify warning message
const originalWarn = console.warn
const mockWarn = vi.fn()
console.warn = mockWarn
await summarizeConversation(
sampleMessages,
mockMainApiHandler,
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
invalidHandler,
)
// Verify the main handler was used as fallback
expect((mockMainApiHandler.createMessage as Mock).mock.calls.length).toBe(1)
// Verify warning was logged
expect(mockWarn).toHaveBeenCalledWith(
expect.stringContaining("Chosen API handler for condensing does not support message creation"),
)
// Restore console.warn
console.warn = originalWarn
})
/**
* Test that telemetry is called for custom prompt usage
*/
@ -1716,38 +1583,13 @@ describe("summarizeConversation with custom settings", () => {
taskId,
false,
true, // usedCustomPrompt
false, // usedCustomApiHandler
)
})
/**
* Test that telemetry is called for custom API handler usage
* Test that telemetry is called with isAutomaticTrigger flag
*/
it("should capture telemetry when using custom API handler", async () => {
await summarizeConversation(
sampleMessages,
mockMainApiHandler,
defaultSystemPrompt,
taskId,
DEFAULT_PREV_CONTEXT_TOKENS,
false,
undefined,
mockCondensingApiHandler,
)
// Verify telemetry was called with custom API handler flag
expect(TelemetryService.instance.captureContextCondensed).toHaveBeenCalledWith(
taskId,
false,
false, // usedCustomPrompt
true, // usedCustomApiHandler
)
})
/**
* Test that telemetry is called with both custom prompt and API handler
*/
it("should capture telemetry when using both custom prompt and API handler", async () => {
it("should capture telemetry with isAutomaticTrigger flag", async () => {
await summarizeConversation(
sampleMessages,
mockMainApiHandler,
@ -1756,15 +1598,13 @@ describe("summarizeConversation with custom settings", () => {
DEFAULT_PREV_CONTEXT_TOKENS,
true, // isAutomaticTrigger
"Custom prompt",
mockCondensingApiHandler,
)
// Verify telemetry was called with both flags
// Verify telemetry was called with isAutomaticTrigger flag
expect(TelemetryService.instance.captureContextCondensed).toHaveBeenCalledWith(
taskId,
true, // isAutomaticTrigger
true, // usedCustomPrompt
true, // usedCustomApiHandler
)
})
})

View file

@ -169,24 +169,12 @@ export type SummarizeResponse = {
* Summarizes the conversation messages using an LLM call
*
* @param {ApiMessage[]} messages - The conversation messages
* @param {ApiHandler} apiHandler - The API handler to use for token counting.
* @param {string} systemPrompt - The system prompt for API requests, which should be considered in the context token count
* @param {string} taskId - The task ID for the conversation, used for telemetry
* @param {boolean} isAutomaticTrigger - Whether the summarization is triggered automatically
* @returns {SummarizeResponse} - The result of the summarization operation (see above)
*/
/**
* Summarizes the conversation messages using an LLM call
*
* @param {ApiMessage[]} messages - The conversation messages
* @param {ApiHandler} apiHandler - The API handler to use for token counting (fallback if condensingApiHandler not provided)
* @param {ApiHandler} apiHandler - The API handler to use for summarization and token counting
* @param {string} systemPrompt - The system prompt for API requests (fallback if customCondensingPrompt not provided)
* @param {string} taskId - The task ID for the conversation, used for telemetry
* @param {number} prevContextTokens - The number of tokens currently in the context, used to ensure we don't grow the context
* @param {boolean} isAutomaticTrigger - Whether the summarization is triggered automatically
* @param {string} customCondensingPrompt - Optional custom prompt to use for condensing
* @param {ApiHandler} condensingApiHandler - Optional specific API handler to use for condensing
* @param {boolean} useNativeTools - Whether to preserve tool_use/tool_result pairing in summarization
* @returns {SummarizeResponse} - The result of the summarization operation (see above)
*/
export async function summarizeConversation(
@ -197,14 +185,11 @@ export async function summarizeConversation(
prevContextTokens: number,
isAutomaticTrigger?: boolean,
customCondensingPrompt?: string,
condensingApiHandler?: ApiHandler,
useNativeTools?: boolean,
): Promise<SummarizeResponse> {
TelemetryService.instance.captureContextCondensed(
taskId,
isAutomaticTrigger ?? false,
!!customCondensingPrompt?.trim(),
!!condensingApiHandler,
)
const response: SummarizeResponse = { messages, cost: 0, summary: "" }
@ -213,13 +198,10 @@ export async function summarizeConversation(
const firstMessage = messages[0]
// Get keepMessages and any tool_use/reasoning blocks that need to be preserved for tool_result pairing.
const { keepMessages, toolUseBlocksToPreserve, reasoningBlocksToPreserve } = useNativeTools
? getKeepMessagesWithToolBlocks(messages, N_MESSAGES_TO_KEEP)
: {
keepMessages: messages.slice(-N_MESSAGES_TO_KEEP),
toolUseBlocksToPreserve: [],
reasoningBlocksToPreserve: [],
}
const { keepMessages, toolUseBlocksToPreserve, reasoningBlocksToPreserve } = getKeepMessagesWithToolBlocks(
messages,
N_MESSAGES_TO_KEEP,
)
const keepStartIndex = Math.max(messages.length - N_MESSAGES_TO_KEEP, 0)
const includeFirstKeptMessageInSummary = toolUseBlocksToPreserve.length > 0
@ -258,29 +240,14 @@ export async function summarizeConversation(
// Use custom prompt if provided and non-empty, otherwise use the default SUMMARY_PROMPT
const promptToUse = customCondensingPrompt?.trim() ? customCondensingPrompt.trim() : SUMMARY_PROMPT
// Use condensing API handler if provided, otherwise use main API handler
let handlerToUse = condensingApiHandler || apiHandler
// Check if the chosen handler supports the required functionality
if (!handlerToUse || typeof handlerToUse.createMessage !== "function") {
console.warn(
"Chosen API handler for condensing does not support message creation or is invalid, falling back to main apiHandler.",
)
handlerToUse = apiHandler // Fallback to the main, presumably valid, apiHandler
// Ensure the main apiHandler itself is valid before this point or add another check.
if (!handlerToUse || typeof handlerToUse.createMessage !== "function") {
// This case should ideally not happen if main apiHandler is always valid.
// Consider throwing an error or returning a specific error response.
console.error("Main API handler is also invalid for condensing. Cannot proceed.")
// Return an appropriate error structure for SummarizeResponse
const error = t("common:errors.condense_handler_invalid")
return { ...response, error }
}
// Validate that the API handler supports message creation
if (!apiHandler || typeof apiHandler.createMessage !== "function") {
console.error("API handler is invalid for condensing. Cannot proceed.")
const error = t("common:errors.condense_handler_invalid")
return { ...response, error }
}
const stream = handlerToUse.createMessage(promptToUse, requestMessages)
const stream = apiHandler.createMessage(promptToUse, requestMessages)
let summary = ""
let cost = 0

View file

@ -620,8 +620,6 @@ describe("Context Management", () => {
70001,
true,
undefined, // customCondensingPrompt
undefined, // condensingApiHandler
undefined, // useNativeTools
)
// Verify the result contains the summary information
@ -796,8 +794,6 @@ describe("Context Management", () => {
60000,
true,
undefined, // customCondensingPrompt
undefined, // condensingApiHandler
undefined, // useNativeTools
)
// Verify the result contains the summary information

View file

@ -216,10 +216,8 @@ export type ContextManagementOptions = {
systemPrompt: string
taskId: string
customCondensingPrompt?: string
condensingApiHandler?: ApiHandler
profileThresholds: Record<string, number>
currentProfileId: string
useNativeTools?: boolean
}
export type ContextManagementResult = SummarizeResponse & {
@ -246,10 +244,8 @@ export async function manageContext({
systemPrompt,
taskId,
customCondensingPrompt,
condensingApiHandler,
profileThresholds,
currentProfileId,
useNativeTools,
}: ContextManagementOptions): Promise<ContextManagementResult> {
let error: string | undefined
let cost = 0
@ -302,8 +298,6 @@ export async function manageContext({
prevContextTokens,
true, // automatic trigger
customCondensingPrompt,
condensingApiHandler,
useNativeTools,
)
if (result.error) {
error = result.error

View file

@ -1572,32 +1572,9 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
// Get condensing configuration
const state = await this.providerRef.deref()?.getState()
// These properties may not exist in the state type yet, but are used for condensing configuration
const customCondensingPrompt = state?.customSupportPrompts?.CONDENSE
const condensingApiConfigId = state?.condensingApiConfigId
const listApiConfigMeta = state?.listApiConfigMeta
// Determine API handler to use
let condensingApiHandler: ApiHandler | undefined
if (condensingApiConfigId && listApiConfigMeta && Array.isArray(listApiConfigMeta)) {
// Find matching config by ID
const matchingConfig = listApiConfigMeta.find((config) => config.id === condensingApiConfigId)
if (matchingConfig) {
const profile = await this.providerRef.deref()?.providerSettingsManager.getProfile({
id: condensingApiConfigId,
})
// Ensure profile and apiProvider exist before trying to build handler
if (profile && profile.apiProvider) {
condensingApiHandler = buildApiHandler(profile)
}
}
}
const { contextTokens: prevContextTokens } = this.getTokenUsage()
// Pass through so summarization preserves tool_use/tool_result integrity.
const useNativeTools = true
const {
messages,
summary,
@ -1613,8 +1590,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
prevContextTokens,
false, // manual trigger
customCondensingPrompt, // User's custom prompt
condensingApiHandler, // Specific handler for condensing
useNativeTools,
)
if (error) {
this.say(
@ -3706,9 +3681,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
`Current tokens: ${contextTokens}, Context window: ${contextWindow}. ` +
`Forcing truncation to ${FORCED_CONTEXT_REDUCTION_PERCENT}% of current context.`,
)
const useNativeTools = true
// Send condenseTaskContextStarted to show in-progress indicator
await this.providerRef.deref()?.postMessageToWebview({ type: "condenseTaskContextStarted", text: this.taskId })
@ -3725,7 +3697,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
taskId: this.taskId,
profileThresholds,
currentProfileId,
useNativeTools,
})
if (truncateResult.messages !== this.apiConversationHistory) {
@ -3822,27 +3793,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
// Get condensing configuration for automatic triggers.
const customCondensingPrompt = state?.customSupportPrompts?.CONDENSE
const condensingApiConfigId = state?.condensingApiConfigId
const listApiConfigMeta = state?.listApiConfigMeta
// Determine API handler to use for condensing.
let condensingApiHandler: ApiHandler | undefined
if (condensingApiConfigId && listApiConfigMeta && Array.isArray(listApiConfigMeta)) {
// Find matching config by ID
const matchingConfig = listApiConfigMeta.find((config) => config.id === condensingApiConfigId)
if (matchingConfig) {
const profile = await this.providerRef.deref()?.providerSettingsManager.getProfile({
id: condensingApiConfigId,
})
// Ensure profile and apiProvider exist before trying to build handler.
if (profile && profile.apiProvider) {
condensingApiHandler = buildApiHandler(profile)
}
}
}
if (!options.skipProviderRateLimit) {
await this.maybeWaitForProviderRateLimit(retryAttempt)
@ -3873,9 +3823,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
// Get the current profile ID using the helper method
const currentProfileId = this.getCurrentProfileId(state)
const useNativeTools = true
// Check if context management will likely run (threshold check)
// This allows us to show an in-progress indicator to the user
// We use the centralized willManageContext helper to avoid duplicating threshold logic
@ -3919,10 +3866,8 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
systemPrompt,
taskId: this.taskId,
customCondensingPrompt,
condensingApiHandler,
profileThresholds,
currentProfileId,
useNativeTools,
})
if (truncateResult.messages !== this.apiConversationHistory) {
await this.overwriteApiConversationHistory(truncateResult.messages)

View file

@ -2035,7 +2035,6 @@ export class ClineProvider
organizationAllowList,
organizationSettingsVersion,
maxConcurrentFileReads,
condensingApiConfigId,
customCondensingPrompt,
codebaseIndexConfig,
codebaseIndexModels,
@ -2188,7 +2187,6 @@ export class ClineProvider
publicSharingEnabled: publicSharingEnabled ?? false,
organizationAllowList,
organizationSettingsVersion,
condensingApiConfigId,
customCondensingPrompt,
codebaseIndexModels: codebaseIndexModels ?? EMBEDDING_MODEL_PROFILES,
codebaseIndexConfig: {
@ -2432,7 +2430,6 @@ export class ClineProvider
publicSharingEnabled,
organizationAllowList,
organizationSettingsVersion,
condensingApiConfigId: stateValues.condensingApiConfigId,
customCondensingPrompt: stateValues.customCondensingPrompt,
codebaseIndexModels: stateValues.codebaseIndexModels ?? EMBEDDING_MODEL_PROFILES,
codebaseIndexConfig: {

View file

@ -38,8 +38,6 @@ const PromptsSettings = ({
listApiConfigMeta,
enhancementApiConfigId,
setEnhancementApiConfigId,
condensingApiConfigId,
setCondensingApiConfigId,
includeTaskHistoryInEnhance: contextIncludeTaskHistoryInEnhance,
setIncludeTaskHistoryInEnhance: contextSetIncludeTaskHistoryInEnhance,
} = useExtensionState()
@ -157,50 +155,30 @@ const PromptsSettings = ({
className="w-full"
/>
{(activeSupportOption === "ENHANCE" || activeSupportOption === "CONDENSE") && (
{activeSupportOption === "ENHANCE" && (
<div className="mt-4 flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
<div>
<label className="block font-medium mb-1">
{activeSupportOption === "ENHANCE"
? t("prompts:supportPrompts.enhance.apiConfiguration")
: t("prompts:supportPrompts.condense.apiConfiguration")}
{t("prompts:supportPrompts.enhance.apiConfiguration")}
</label>
<Select
value={
activeSupportOption === "ENHANCE"
? enhancementApiConfigId || "-"
: condensingApiConfigId || "-"
}
value={enhancementApiConfigId || "-"}
onValueChange={(value) => {
const newConfigId = value === "-" ? "" : value
if (activeSupportOption === "ENHANCE") {
setEnhancementApiConfigId(newConfigId)
vscode.postMessage({
type: "enhancementApiConfigId",
text: value,
})
} else {
setCondensingApiConfigId(newConfigId)
vscode.postMessage({
type: "updateSettings",
updatedSettings: { condensingApiConfigId: newConfigId },
})
}
setEnhancementApiConfigId(newConfigId)
vscode.postMessage({
type: "enhancementApiConfigId",
text: value,
})
}}>
<SelectTrigger data-testid="api-config-select" className="w-full">
<SelectValue
placeholder={
activeSupportOption === "ENHANCE"
? t("prompts:supportPrompts.enhance.useCurrentConfig")
: t("prompts:supportPrompts.condense.useCurrentConfig")
}
placeholder={t("prompts:supportPrompts.enhance.useCurrentConfig")}
/>
</SelectTrigger>
<SelectContent>
<SelectItem value="-">
{activeSupportOption === "ENHANCE"
? t("prompts:supportPrompts.enhance.useCurrentConfig")
: t("prompts:supportPrompts.condense.useCurrentConfig")}
{t("prompts:supportPrompts.enhance.useCurrentConfig")}
</SelectItem>
{(listApiConfigMeta || []).map((config) => (
<SelectItem
@ -213,66 +191,55 @@ const PromptsSettings = ({
</SelectContent>
</Select>
<div className="text-sm text-vscode-descriptionForeground mt-1">
{activeSupportOption === "ENHANCE"
? t("prompts:supportPrompts.enhance.apiConfigDescription")
: t("prompts:supportPrompts.condense.apiConfigDescription")}
{t("prompts:supportPrompts.enhance.apiConfigDescription")}
</div>
</div>
{activeSupportOption === "ENHANCE" && (
<>
<div>
<VSCodeCheckbox
checked={includeTaskHistoryInEnhance}
onChange={(e: Event | FormEvent<HTMLElement>) => {
const target = (
"target" in e ? e.target : null
) as HTMLInputElement | null
<div>
<VSCodeCheckbox
checked={includeTaskHistoryInEnhance}
onChange={(e: Event | FormEvent<HTMLElement>) => {
const target = ("target" in e ? e.target : null) as HTMLInputElement | null
if (!target) {
return
}
if (!target) {
return
}
setIncludeTaskHistoryInEnhance(target.checked)
setIncludeTaskHistoryInEnhance(target.checked)
vscode.postMessage({
type: "updateSettings",
updatedSettings: { includeTaskHistoryInEnhance: target.checked },
})
}}>
<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>
vscode.postMessage({
type: "updateSettings",
updatedSettings: { includeTaskHistoryInEnhance: target.checked },
})
}}>
<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>
<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="primary"
onClick={handleTestEnhancement}
disabled={isEnhancing}>
{t("prompts:supportPrompts.enhance.previewButton")}
</Button>
</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="primary" onClick={handleTestEnhancement} disabled={isEnhancing}>
{t("prompts:supportPrompts.enhance.previewButton")}
</Button>
</div>
</div>
</div>
)}
</div>

View file

@ -197,7 +197,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
maxTotalImageSize,
terminalCompressProgressBar,
maxConcurrentFileReads,
condensingApiConfigId,
customSupportPrompts,
profileThresholds,
alwaysAllowFollowupQuestions,
@ -419,7 +418,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
alwaysAllowSubtasks,
alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions ?? false,
followupAutoApproveTimeoutMs,
condensingApiConfigId: condensingApiConfigId || "",
includeTaskHistoryInEnhance: includeTaskHistoryInEnhance ?? true,
reasoningBlockCollapsed: reasoningBlockCollapsed ?? true,
enterBehavior: enterBehavior ?? "send",

View file

@ -87,7 +87,6 @@ describe("ContextManagementSettings", () => {
const defaultProps = {
autoCondenseContext: false,
autoCondenseContextPercent: 80,
condensingApiConfigId: undefined,
customCondensingPrompt: undefined,
listApiConfigMeta: [],
maxOpenTabsContext: 20,

View file

@ -192,7 +192,6 @@ describe("SettingsView - Change Detection Fix", () => {
maxTotalImageSize: 20,
terminalCompressProgressBar: false,
maxConcurrentFileReads: 5,
condensingApiConfigId: "",
customCondensingPrompt: "",
customSupportPrompts: {},
profileThresholds: {},

View file

@ -197,7 +197,6 @@ describe("SettingsView - Unsaved Changes Detection", () => {
maxTotalImageSize: 20,
terminalCompressProgressBar: false,
maxConcurrentFileReads: 5,
condensingApiConfigId: "",
customCondensingPrompt: "",
customSupportPrompts: {},
profileThresholds: {},

View file

@ -56,8 +56,6 @@ export interface ExtensionStateContextType extends ExtensionState {
setAlwaysAllowFollowupQuestions: (value: boolean) => void // Setter for the new property
followupAutoApproveTimeoutMs: number | undefined // Timeout in ms for auto-approving follow-up questions
setFollowupAutoApproveTimeoutMs: (value: number) => void // Setter for the timeout
condensingApiConfigId?: string
setCondensingApiConfigId: (value: string) => void
marketplaceItems?: any[]
marketplaceInstalledMetadata?: MarketplaceInstalledMetadata
profileThresholds: Record<string, number>
@ -232,7 +230,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
customSupportPrompts: {},
experiments: experimentDefault,
enhancementApiConfigId: "",
condensingApiConfigId: "", // Default empty string for condensing API config ID
hasOpenedModeSelector: false, // Default to false (not opened yet)
autoApprovalEnabled: false,
customModes: [],
@ -616,7 +613,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setAutoCondenseContext: (value) => setState((prevState) => ({ ...prevState, autoCondenseContext: value })),
setAutoCondenseContextPercent: (value) =>
setState((prevState) => ({ ...prevState, autoCondenseContextPercent: value })),
setCondensingApiConfigId: (value) => setState((prevState) => ({ ...prevState, condensingApiConfigId: value })),
setProfileThresholds: (value) => setState((prevState) => ({ ...prevState, profileThresholds: value })),
includeDiagnosticMessages: state.includeDiagnosticMessages,
setIncludeDiagnosticMessages: (value) => {