Skip to content

Commit 3df1150

Browse files
committed
fix: prevent unnecessary state updates when settings haven't changed
- Only update global state and call postStateToWebview() when autoCondenseContext or autoCondenseContextPercent values actually change - This prevents context compression from being triggered when saving unchanged settings - Reverted changes to SettingsView.tsx as they don't address the root cause
1 parent 83ed754 commit 3df1150

File tree

2 files changed

+92
-233
lines changed

2 files changed

+92
-233
lines changed

src/core/webview/webviewMessageHandler.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -580,14 +580,24 @@ export const webviewMessageHandler = async (
580580
case "askResponse":
581581
provider.getCurrentTask()?.handleWebviewAskResponse(message.askResponse!, message.text, message.images)
582582
break
583-
case "autoCondenseContext":
584-
await updateGlobalState("autoCondenseContext", message.bool)
585-
await provider.postStateToWebview()
583+
case "autoCondenseContext": {
584+
const currentValue = getGlobalState("autoCondenseContext")
585+
// Only update if the value has actually changed
586+
if (currentValue !== message.bool) {
587+
await updateGlobalState("autoCondenseContext", message.bool)
588+
await provider.postStateToWebview()
589+
}
586590
break
587-
case "autoCondenseContextPercent":
588-
await updateGlobalState("autoCondenseContextPercent", message.value)
589-
await provider.postStateToWebview()
591+
}
592+
case "autoCondenseContextPercent": {
593+
const currentValue = getGlobalState("autoCondenseContextPercent")
594+
// Only update if the value has actually changed
595+
if (currentValue !== message.value) {
596+
await updateGlobalState("autoCondenseContextPercent", message.value)
597+
await provider.postStateToWebview()
598+
}
590599
break
600+
}
591601
case "terminalOperation":
592602
if (message.terminalOperation) {
593603
provider.getCurrentTask()?.handleTerminalOperation(message.terminalOperation)

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

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

297297
const handleSubmit = () => {
298298
if (isSettingValid) {
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-
}
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({
332+
type: "terminalOutputCharacterLimit",
333+
value: terminalOutputCharacterLimit ?? 50000,
334+
})
335+
vscode.postMessage({ type: "terminalShellIntegrationTimeout", value: terminalShellIntegrationTimeout })
336+
vscode.postMessage({ type: "terminalShellIntegrationDisabled", bool: terminalShellIntegrationDisabled })
337+
vscode.postMessage({ type: "terminalCommandDelay", value: terminalCommandDelay })
338+
vscode.postMessage({ type: "terminalPowershellCounter", bool: terminalPowershellCounter })
339+
vscode.postMessage({ type: "terminalZshClearEolMark", bool: terminalZshClearEolMark })
340+
vscode.postMessage({ type: "terminalZshOhMy", bool: terminalZshOhMy })
341+
vscode.postMessage({ type: "terminalZshP10k", bool: terminalZshP10k })
342+
vscode.postMessage({ type: "terminalZdotdir", bool: terminalZdotdir })
343+
vscode.postMessage({ type: "terminalCompressProgressBar", bool: terminalCompressProgressBar })
344+
vscode.postMessage({ type: "mcpEnabled", bool: mcpEnabled })
345+
vscode.postMessage({ type: "alwaysApproveResubmit", bool: alwaysApproveResubmit })
346+
vscode.postMessage({ type: "requestDelaySeconds", value: requestDelaySeconds })
347+
vscode.postMessage({ type: "maxOpenTabsContext", value: maxOpenTabsContext })
348+
vscode.postMessage({ type: "maxWorkspaceFiles", value: maxWorkspaceFiles ?? 200 })
349+
vscode.postMessage({ type: "showRooIgnoredFiles", bool: showRooIgnoredFiles })
350+
vscode.postMessage({ type: "maxReadFileLine", value: maxReadFileLine ?? -1 })
351+
vscode.postMessage({ type: "maxImageFileSize", value: maxImageFileSize ?? 5 })
352+
vscode.postMessage({ type: "maxTotalImageSize", value: maxTotalImageSize ?? 20 })
353+
vscode.postMessage({ type: "maxConcurrentFileReads", value: cachedState.maxConcurrentFileReads ?? 5 })
354+
vscode.postMessage({ type: "includeDiagnosticMessages", bool: includeDiagnosticMessages })
355+
vscode.postMessage({ type: "maxDiagnosticMessages", value: maxDiagnosticMessages ?? 50 })
356+
vscode.postMessage({ type: "currentApiConfigName", text: currentApiConfigName })
357+
vscode.postMessage({ type: "updateExperimental", values: experiments })
358+
vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch })
359+
vscode.postMessage({ type: "alwaysAllowSubtasks", bool: alwaysAllowSubtasks })
360+
vscode.postMessage({ type: "alwaysAllowFollowupQuestions", bool: alwaysAllowFollowupQuestions })
361+
vscode.postMessage({ type: "alwaysAllowUpdateTodoList", bool: alwaysAllowUpdateTodoList })
362+
vscode.postMessage({ type: "followupAutoApproveTimeoutMs", value: followupAutoApproveTimeoutMs })
363+
vscode.postMessage({ type: "condensingApiConfigId", text: condensingApiConfigId || "" })
364+
vscode.postMessage({ type: "updateCondensingPrompt", text: customCondensingPrompt || "" })
365+
vscode.postMessage({ type: "updateSupportPrompt", values: customSupportPrompts || {} })
366+
vscode.postMessage({ type: "includeTaskHistoryInEnhance", bool: includeTaskHistoryInEnhance ?? true })
367+
vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration })
368+
vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting })
369+
vscode.postMessage({ type: "profileThresholds", values: profileThresholds })
370+
vscode.postMessage({ type: "openRouterImageApiKey", text: openRouterImageApiKey })
371+
vscode.postMessage({
372+
type: "openRouterImageGenerationSelectedModel",
373+
text: openRouterImageGenerationSelectedModel,
374+
})
526375
setChangeDetected(false)
527376
}
528377
}

0 commit comments

Comments
 (0)