Skip to content

Commit 83ed754

Browse files
committed
fix: prevent context compression trigger when saving unchanged settings
- Modified SettingsView handleSubmit to only send messages for changed settings - Added hasChanged helper function to compare cached vs original values - Fixes issue where saving settings with no changes would trigger context compression - Resolves #4430
1 parent c4c4780 commit 83ed754

File tree

1 file changed

+227
-73
lines changed

1 file changed

+227
-73
lines changed

webview-ui/src/components/settings/SettingsView.tsx

Lines changed: 227 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -296,79 +296,233 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
296296

297297
const handleSubmit = () => {
298298
if (isSettingValid) {
299-
vscode.postMessage({ type: "language", text: language })
300-
vscode.postMessage({ type: "alwaysAllowReadOnly", bool: alwaysAllowReadOnly })
301-
vscode.postMessage({
302-
type: "alwaysAllowReadOnlyOutsideWorkspace",
303-
bool: alwaysAllowReadOnlyOutsideWorkspace,
304-
})
305-
vscode.postMessage({ type: "alwaysAllowWrite", bool: alwaysAllowWrite })
306-
vscode.postMessage({ type: "alwaysAllowWriteOutsideWorkspace", bool: alwaysAllowWriteOutsideWorkspace })
307-
vscode.postMessage({ type: "alwaysAllowWriteProtected", bool: alwaysAllowWriteProtected })
308-
vscode.postMessage({ type: "alwaysAllowExecute", bool: alwaysAllowExecute })
309-
vscode.postMessage({ type: "alwaysAllowBrowser", bool: alwaysAllowBrowser })
310-
vscode.postMessage({ type: "alwaysAllowMcp", bool: alwaysAllowMcp })
311-
vscode.postMessage({ type: "allowedCommands", commands: allowedCommands ?? [] })
312-
vscode.postMessage({ type: "deniedCommands", commands: deniedCommands ?? [] })
313-
vscode.postMessage({ type: "allowedMaxRequests", value: allowedMaxRequests ?? undefined })
314-
vscode.postMessage({ type: "allowedMaxCost", value: allowedMaxCost ?? undefined })
315-
vscode.postMessage({ type: "autoCondenseContext", bool: autoCondenseContext })
316-
vscode.postMessage({ type: "autoCondenseContextPercent", value: autoCondenseContextPercent })
317-
vscode.postMessage({ type: "browserToolEnabled", bool: browserToolEnabled })
318-
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
319-
vscode.postMessage({ type: "ttsEnabled", bool: ttsEnabled })
320-
vscode.postMessage({ type: "ttsSpeed", value: ttsSpeed })
321-
vscode.postMessage({ type: "soundVolume", value: soundVolume })
322-
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
323-
vscode.postMessage({ type: "enableCheckpoints", bool: enableCheckpoints })
324-
vscode.postMessage({ type: "browserViewportSize", text: browserViewportSize })
325-
vscode.postMessage({ type: "remoteBrowserHost", text: remoteBrowserHost })
326-
vscode.postMessage({ type: "remoteBrowserEnabled", bool: remoteBrowserEnabled })
327-
vscode.postMessage({ type: "fuzzyMatchThreshold", value: fuzzyMatchThreshold ?? 1.0 })
328-
vscode.postMessage({ type: "writeDelayMs", value: writeDelayMs })
329-
vscode.postMessage({ type: "screenshotQuality", value: screenshotQuality ?? 75 })
330-
vscode.postMessage({ type: "terminalOutputLineLimit", value: terminalOutputLineLimit ?? 500 })
331-
vscode.postMessage({ type: "terminalOutputCharacterLimit", value: terminalOutputCharacterLimit ?? 50000 })
332-
vscode.postMessage({ type: "terminalShellIntegrationTimeout", value: terminalShellIntegrationTimeout })
333-
vscode.postMessage({ type: "terminalShellIntegrationDisabled", bool: terminalShellIntegrationDisabled })
334-
vscode.postMessage({ type: "terminalCommandDelay", value: terminalCommandDelay })
335-
vscode.postMessage({ type: "terminalPowershellCounter", bool: terminalPowershellCounter })
336-
vscode.postMessage({ type: "terminalZshClearEolMark", bool: terminalZshClearEolMark })
337-
vscode.postMessage({ type: "terminalZshOhMy", bool: terminalZshOhMy })
338-
vscode.postMessage({ type: "terminalZshP10k", bool: terminalZshP10k })
339-
vscode.postMessage({ type: "terminalZdotdir", bool: terminalZdotdir })
340-
vscode.postMessage({ type: "terminalCompressProgressBar", bool: terminalCompressProgressBar })
341-
vscode.postMessage({ type: "mcpEnabled", bool: mcpEnabled })
342-
vscode.postMessage({ type: "alwaysApproveResubmit", bool: alwaysApproveResubmit })
343-
vscode.postMessage({ type: "requestDelaySeconds", value: requestDelaySeconds })
344-
vscode.postMessage({ type: "maxOpenTabsContext", value: maxOpenTabsContext })
345-
vscode.postMessage({ type: "maxWorkspaceFiles", value: maxWorkspaceFiles ?? 200 })
346-
vscode.postMessage({ type: "showRooIgnoredFiles", bool: showRooIgnoredFiles })
347-
vscode.postMessage({ type: "maxReadFileLine", value: maxReadFileLine ?? -1 })
348-
vscode.postMessage({ type: "maxImageFileSize", value: maxImageFileSize ?? 5 })
349-
vscode.postMessage({ type: "maxTotalImageSize", value: maxTotalImageSize ?? 20 })
350-
vscode.postMessage({ type: "maxConcurrentFileReads", value: cachedState.maxConcurrentFileReads ?? 5 })
351-
vscode.postMessage({ type: "includeDiagnosticMessages", bool: includeDiagnosticMessages })
352-
vscode.postMessage({ type: "maxDiagnosticMessages", value: maxDiagnosticMessages ?? 50 })
353-
vscode.postMessage({ type: "currentApiConfigName", text: currentApiConfigName })
354-
vscode.postMessage({ type: "updateExperimental", values: experiments })
355-
vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch })
356-
vscode.postMessage({ type: "alwaysAllowSubtasks", bool: alwaysAllowSubtasks })
357-
vscode.postMessage({ type: "alwaysAllowFollowupQuestions", bool: alwaysAllowFollowupQuestions })
358-
vscode.postMessage({ type: "alwaysAllowUpdateTodoList", bool: alwaysAllowUpdateTodoList })
359-
vscode.postMessage({ type: "followupAutoApproveTimeoutMs", value: followupAutoApproveTimeoutMs })
360-
vscode.postMessage({ type: "condensingApiConfigId", text: condensingApiConfigId || "" })
361-
vscode.postMessage({ type: "updateCondensingPrompt", text: customCondensingPrompt || "" })
362-
vscode.postMessage({ type: "updateSupportPrompt", values: customSupportPrompts || {} })
363-
vscode.postMessage({ type: "includeTaskHistoryInEnhance", bool: includeTaskHistoryInEnhance ?? true })
364-
vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration })
365-
vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting })
366-
vscode.postMessage({ type: "profileThresholds", values: profileThresholds })
367-
vscode.postMessage({ type: "openRouterImageApiKey", text: openRouterImageApiKey })
368-
vscode.postMessage({
369-
type: "openRouterImageGenerationSelectedModel",
370-
text: openRouterImageGenerationSelectedModel,
371-
})
299+
// Helper function to check if a value has changed
300+
const hasChanged = (cachedValue: any, originalValue: any): boolean => {
301+
// Handle objects and arrays with deep comparison
302+
if (typeof cachedValue === "object" && cachedValue !== null) {
303+
return JSON.stringify(cachedValue) !== JSON.stringify(originalValue)
304+
}
305+
return cachedValue !== originalValue
306+
}
307+
308+
// Only send messages for settings that have actually changed
309+
if (hasChanged(language, extensionState.language)) {
310+
vscode.postMessage({ type: "language", text: language })
311+
}
312+
if (hasChanged(alwaysAllowReadOnly, extensionState.alwaysAllowReadOnly)) {
313+
vscode.postMessage({ type: "alwaysAllowReadOnly", bool: alwaysAllowReadOnly })
314+
}
315+
if (hasChanged(alwaysAllowReadOnlyOutsideWorkspace, extensionState.alwaysAllowReadOnlyOutsideWorkspace)) {
316+
vscode.postMessage({
317+
type: "alwaysAllowReadOnlyOutsideWorkspace",
318+
bool: alwaysAllowReadOnlyOutsideWorkspace,
319+
})
320+
}
321+
if (hasChanged(alwaysAllowWrite, extensionState.alwaysAllowWrite)) {
322+
vscode.postMessage({ type: "alwaysAllowWrite", bool: alwaysAllowWrite })
323+
}
324+
if (hasChanged(alwaysAllowWriteOutsideWorkspace, extensionState.alwaysAllowWriteOutsideWorkspace)) {
325+
vscode.postMessage({ type: "alwaysAllowWriteOutsideWorkspace", bool: alwaysAllowWriteOutsideWorkspace })
326+
}
327+
if (hasChanged(alwaysAllowWriteProtected, extensionState.alwaysAllowWriteProtected)) {
328+
vscode.postMessage({ type: "alwaysAllowWriteProtected", bool: alwaysAllowWriteProtected })
329+
}
330+
if (hasChanged(alwaysAllowExecute, extensionState.alwaysAllowExecute)) {
331+
vscode.postMessage({ type: "alwaysAllowExecute", bool: alwaysAllowExecute })
332+
}
333+
if (hasChanged(alwaysAllowBrowser, extensionState.alwaysAllowBrowser)) {
334+
vscode.postMessage({ type: "alwaysAllowBrowser", bool: alwaysAllowBrowser })
335+
}
336+
if (hasChanged(alwaysAllowMcp, extensionState.alwaysAllowMcp)) {
337+
vscode.postMessage({ type: "alwaysAllowMcp", bool: alwaysAllowMcp })
338+
}
339+
if (hasChanged(allowedCommands, extensionState.allowedCommands)) {
340+
vscode.postMessage({ type: "allowedCommands", commands: allowedCommands ?? [] })
341+
}
342+
if (hasChanged(deniedCommands, extensionState.deniedCommands)) {
343+
vscode.postMessage({ type: "deniedCommands", commands: deniedCommands ?? [] })
344+
}
345+
if (hasChanged(allowedMaxRequests, extensionState.allowedMaxRequests)) {
346+
vscode.postMessage({ type: "allowedMaxRequests", value: allowedMaxRequests ?? undefined })
347+
}
348+
if (hasChanged(allowedMaxCost, extensionState.allowedMaxCost)) {
349+
vscode.postMessage({ type: "allowedMaxCost", value: allowedMaxCost ?? undefined })
350+
}
351+
// Only send autoCondenseContext if it has actually changed
352+
if (hasChanged(autoCondenseContext, extensionState.autoCondenseContext)) {
353+
vscode.postMessage({ type: "autoCondenseContext", bool: autoCondenseContext })
354+
}
355+
// Only send autoCondenseContextPercent if it has actually changed
356+
if (hasChanged(autoCondenseContextPercent, extensionState.autoCondenseContextPercent)) {
357+
vscode.postMessage({ type: "autoCondenseContextPercent", value: autoCondenseContextPercent })
358+
}
359+
if (hasChanged(browserToolEnabled, extensionState.browserToolEnabled)) {
360+
vscode.postMessage({ type: "browserToolEnabled", bool: browserToolEnabled })
361+
}
362+
if (hasChanged(soundEnabled, extensionState.soundEnabled)) {
363+
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
364+
}
365+
if (hasChanged(ttsEnabled, extensionState.ttsEnabled)) {
366+
vscode.postMessage({ type: "ttsEnabled", bool: ttsEnabled })
367+
}
368+
if (hasChanged(ttsSpeed, extensionState.ttsSpeed)) {
369+
vscode.postMessage({ type: "ttsSpeed", value: ttsSpeed })
370+
}
371+
if (hasChanged(soundVolume, extensionState.soundVolume)) {
372+
vscode.postMessage({ type: "soundVolume", value: soundVolume })
373+
}
374+
if (hasChanged(diffEnabled, extensionState.diffEnabled)) {
375+
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
376+
}
377+
if (hasChanged(enableCheckpoints, extensionState.enableCheckpoints)) {
378+
vscode.postMessage({ type: "enableCheckpoints", bool: enableCheckpoints })
379+
}
380+
if (hasChanged(browserViewportSize, extensionState.browserViewportSize)) {
381+
vscode.postMessage({ type: "browserViewportSize", text: browserViewportSize })
382+
}
383+
if (hasChanged(remoteBrowserHost, extensionState.remoteBrowserHost)) {
384+
vscode.postMessage({ type: "remoteBrowserHost", text: remoteBrowserHost })
385+
}
386+
if (hasChanged(remoteBrowserEnabled, extensionState.remoteBrowserEnabled)) {
387+
vscode.postMessage({ type: "remoteBrowserEnabled", bool: remoteBrowserEnabled })
388+
}
389+
if (hasChanged(fuzzyMatchThreshold, extensionState.fuzzyMatchThreshold)) {
390+
vscode.postMessage({ type: "fuzzyMatchThreshold", value: fuzzyMatchThreshold ?? 1.0 })
391+
}
392+
if (hasChanged(writeDelayMs, extensionState.writeDelayMs)) {
393+
vscode.postMessage({ type: "writeDelayMs", value: writeDelayMs })
394+
}
395+
if (hasChanged(screenshotQuality, extensionState.screenshotQuality)) {
396+
vscode.postMessage({ type: "screenshotQuality", value: screenshotQuality ?? 75 })
397+
}
398+
if (hasChanged(terminalOutputLineLimit, extensionState.terminalOutputLineLimit)) {
399+
vscode.postMessage({ type: "terminalOutputLineLimit", value: terminalOutputLineLimit ?? 500 })
400+
}
401+
if (hasChanged(terminalOutputCharacterLimit, extensionState.terminalOutputCharacterLimit)) {
402+
vscode.postMessage({
403+
type: "terminalOutputCharacterLimit",
404+
value: terminalOutputCharacterLimit ?? 50000,
405+
})
406+
}
407+
if (hasChanged(terminalShellIntegrationTimeout, extensionState.terminalShellIntegrationTimeout)) {
408+
vscode.postMessage({ type: "terminalShellIntegrationTimeout", value: terminalShellIntegrationTimeout })
409+
}
410+
if (hasChanged(terminalShellIntegrationDisabled, extensionState.terminalShellIntegrationDisabled)) {
411+
vscode.postMessage({ type: "terminalShellIntegrationDisabled", bool: terminalShellIntegrationDisabled })
412+
}
413+
if (hasChanged(terminalCommandDelay, extensionState.terminalCommandDelay)) {
414+
vscode.postMessage({ type: "terminalCommandDelay", value: terminalCommandDelay })
415+
}
416+
if (hasChanged(terminalPowershellCounter, extensionState.terminalPowershellCounter)) {
417+
vscode.postMessage({ type: "terminalPowershellCounter", bool: terminalPowershellCounter })
418+
}
419+
if (hasChanged(terminalZshClearEolMark, extensionState.terminalZshClearEolMark)) {
420+
vscode.postMessage({ type: "terminalZshClearEolMark", bool: terminalZshClearEolMark })
421+
}
422+
if (hasChanged(terminalZshOhMy, extensionState.terminalZshOhMy)) {
423+
vscode.postMessage({ type: "terminalZshOhMy", bool: terminalZshOhMy })
424+
}
425+
if (hasChanged(terminalZshP10k, extensionState.terminalZshP10k)) {
426+
vscode.postMessage({ type: "terminalZshP10k", bool: terminalZshP10k })
427+
}
428+
if (hasChanged(terminalZdotdir, extensionState.terminalZdotdir)) {
429+
vscode.postMessage({ type: "terminalZdotdir", bool: terminalZdotdir })
430+
}
431+
if (hasChanged(terminalCompressProgressBar, extensionState.terminalCompressProgressBar)) {
432+
vscode.postMessage({ type: "terminalCompressProgressBar", bool: terminalCompressProgressBar })
433+
}
434+
if (hasChanged(mcpEnabled, extensionState.mcpEnabled)) {
435+
vscode.postMessage({ type: "mcpEnabled", bool: mcpEnabled })
436+
}
437+
if (hasChanged(alwaysApproveResubmit, extensionState.alwaysApproveResubmit)) {
438+
vscode.postMessage({ type: "alwaysApproveResubmit", bool: alwaysApproveResubmit })
439+
}
440+
if (hasChanged(requestDelaySeconds, extensionState.requestDelaySeconds)) {
441+
vscode.postMessage({ type: "requestDelaySeconds", value: requestDelaySeconds })
442+
}
443+
if (hasChanged(maxOpenTabsContext, extensionState.maxOpenTabsContext)) {
444+
vscode.postMessage({ type: "maxOpenTabsContext", value: maxOpenTabsContext })
445+
}
446+
if (hasChanged(maxWorkspaceFiles, extensionState.maxWorkspaceFiles)) {
447+
vscode.postMessage({ type: "maxWorkspaceFiles", value: maxWorkspaceFiles ?? 200 })
448+
}
449+
if (hasChanged(showRooIgnoredFiles, extensionState.showRooIgnoredFiles)) {
450+
vscode.postMessage({ type: "showRooIgnoredFiles", bool: showRooIgnoredFiles })
451+
}
452+
if (hasChanged(maxReadFileLine, extensionState.maxReadFileLine)) {
453+
vscode.postMessage({ type: "maxReadFileLine", value: maxReadFileLine ?? -1 })
454+
}
455+
if (hasChanged(maxImageFileSize, extensionState.maxImageFileSize)) {
456+
vscode.postMessage({ type: "maxImageFileSize", value: maxImageFileSize ?? 5 })
457+
}
458+
if (hasChanged(maxTotalImageSize, extensionState.maxTotalImageSize)) {
459+
vscode.postMessage({ type: "maxTotalImageSize", value: maxTotalImageSize ?? 20 })
460+
}
461+
if (hasChanged(maxConcurrentFileReads, extensionState.maxConcurrentFileReads)) {
462+
vscode.postMessage({ type: "maxConcurrentFileReads", value: cachedState.maxConcurrentFileReads ?? 5 })
463+
}
464+
if (hasChanged(includeDiagnosticMessages, extensionState.includeDiagnosticMessages)) {
465+
vscode.postMessage({ type: "includeDiagnosticMessages", bool: includeDiagnosticMessages })
466+
}
467+
if (hasChanged(maxDiagnosticMessages, extensionState.maxDiagnosticMessages)) {
468+
vscode.postMessage({ type: "maxDiagnosticMessages", value: maxDiagnosticMessages ?? 50 })
469+
}
470+
if (hasChanged(currentApiConfigName, extensionState.currentApiConfigName)) {
471+
vscode.postMessage({ type: "currentApiConfigName", text: currentApiConfigName })
472+
}
473+
if (hasChanged(experiments, extensionState.experiments)) {
474+
vscode.postMessage({ type: "updateExperimental", values: experiments })
475+
}
476+
if (hasChanged(alwaysAllowModeSwitch, extensionState.alwaysAllowModeSwitch)) {
477+
vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch })
478+
}
479+
if (hasChanged(alwaysAllowSubtasks, extensionState.alwaysAllowSubtasks)) {
480+
vscode.postMessage({ type: "alwaysAllowSubtasks", bool: alwaysAllowSubtasks })
481+
}
482+
if (hasChanged(alwaysAllowFollowupQuestions, extensionState.alwaysAllowFollowupQuestions)) {
483+
vscode.postMessage({ type: "alwaysAllowFollowupQuestions", bool: alwaysAllowFollowupQuestions })
484+
}
485+
if (hasChanged(alwaysAllowUpdateTodoList, extensionState.alwaysAllowUpdateTodoList)) {
486+
vscode.postMessage({ type: "alwaysAllowUpdateTodoList", bool: alwaysAllowUpdateTodoList })
487+
}
488+
if (hasChanged(followupAutoApproveTimeoutMs, extensionState.followupAutoApproveTimeoutMs)) {
489+
vscode.postMessage({ type: "followupAutoApproveTimeoutMs", value: followupAutoApproveTimeoutMs })
490+
}
491+
if (hasChanged(condensingApiConfigId, extensionState.condensingApiConfigId)) {
492+
vscode.postMessage({ type: "condensingApiConfigId", text: condensingApiConfigId || "" })
493+
}
494+
if (hasChanged(customCondensingPrompt, extensionState.customCondensingPrompt)) {
495+
vscode.postMessage({ type: "updateCondensingPrompt", text: customCondensingPrompt || "" })
496+
}
497+
if (hasChanged(customSupportPrompts, extensionState.customSupportPrompts)) {
498+
vscode.postMessage({ type: "updateSupportPrompt", values: customSupportPrompts || {} })
499+
}
500+
if (hasChanged(includeTaskHistoryInEnhance, extensionState.includeTaskHistoryInEnhance)) {
501+
vscode.postMessage({ type: "includeTaskHistoryInEnhance", bool: includeTaskHistoryInEnhance ?? true })
502+
}
503+
if (hasChanged(apiConfiguration, extensionState.apiConfiguration)) {
504+
vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration })
505+
}
506+
if (hasChanged(telemetrySetting, extensionState.telemetrySetting)) {
507+
vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting })
508+
}
509+
if (hasChanged(profileThresholds, extensionState.profileThresholds)) {
510+
vscode.postMessage({ type: "profileThresholds", values: profileThresholds })
511+
}
512+
if (hasChanged(openRouterImageApiKey, extensionState.openRouterImageApiKey)) {
513+
vscode.postMessage({ type: "openRouterImageApiKey", text: openRouterImageApiKey })
514+
}
515+
if (
516+
hasChanged(
517+
openRouterImageGenerationSelectedModel,
518+
extensionState.openRouterImageGenerationSelectedModel,
519+
)
520+
) {
521+
vscode.postMessage({
522+
type: "openRouterImageGenerationSelectedModel",
523+
text: openRouterImageGenerationSelectedModel,
524+
})
525+
}
372526
setChangeDetected(false)
373527
}
374528
}

0 commit comments

Comments
 (0)