Repository navigation
fix(compression): settings tab saves only the fields that changed - #14723
Merged
diegosouzapw merged 9 commits intoSep 29, 2026
Conversation
CompressionSettingsTab loads the compression config once and each save PUTs that whole snapshot, and updateCompressionSettings overwrites every key it receives. A setting changed elsewhere after the tab loaded is written back to its old value by the next save in the tab. The cases drive the tab against a fake route that overwrites each key it gets: Auto-Clarity turned off on the caveman page comes back on after the embedded tab saves the cache TTL, outputStyles saved from another tab reset to [], and a failed save leaves the new value on screen, alone or next to a newer save that succeeds. All four fail on this commit.
CompressionSettingsTab loaded the compression config once on mount and every save sent that whole snapshot. updateCompressionSettings overwrites each key it receives, so a setting changed elsewhere after the tab loaded went back to the tab's stale value. On the caveman context page, turning the Auto-Clarity checkbox off and then editing any field in the embedded tab turned autoClarity back on while the checkbox still showed it off. outputStyles saved from another browser tab reset the same way. save() now sends only the fields it is called with, as CompressionPanel does. Saves go out one at a time, and the form shows the last saved config plus the saves still queued, so a failed save rolls back only its own fields and leaves a newer save alone. A key the tab changes still goes out as its whole nested object (cavemanOutputMode, cavemanConfig, aggressive, ultra) because the server stores each key as one row.
4 of 5 tasks
A queued save that succeeded after a failed one replaced the error with "saved", and an earlier save's 2-second timeout cleared a later error, so a field that had just rolled back showed no failure. The error now stays on screen until the next edit starts a new save. The rollback test now checks the status after a failed save and a queued success, and a new test covers an earlier success's timeout firing after a later failure.
…ression-settings-tab-partial-save
…ression-settings-tab-partial-save
…ression-settings-tab-partial-save
Collaborator
|
Thanks for this, the partial-save approach and the per-save rollback look right, and the tests fail without the change and pass with it. One follow-up you may want (not blocking): nested objects such as |
The settings tab sends each nested object (cavemanOutputMode, aggressive, and the rest) whole, built from the copy it loaded, so a save writes back any sibling field another tab changed since then. Two new cases fail on the current code: toggling Auto-Clarity writes back a stale output-mode intensity, and editing an aggressive threshold writes back a stale sibling threshold and maxTokensPerMessage. The caveman-page case gets a 30-second timeout, because rendering the whole page takes over 5 seconds on a cold run.
The settings tab sent each nested object (cavemanConfig, cavemanOutputMode, aggressive, ultra) whole, built from the copy it loaded, so saving one field wrote back every sibling field another tab or the panel had changed since. Toggling Auto-Clarity, for example, wrote back a stale output-mode level. Each save now names only the fields it changes. Before the PUT, save() reads the server's current row for any nested object it touches and fills in the other fields from that row. The PUT still carries whole objects, because the server stores each one as a single row, but no stale siblings. The form still shows the queued edits on top of the last saved state, and a failed save still rolls back only its own fields.
diegosouzapw
merged commit Sep 29, 2026
19d135c
into
cheaper-inference:release/v3.8.51
10 of 16 checks passed
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The compression settings tab (
CompressionSettingsTab.tsx) read the config once on mount, and every save sent that whole snapshot toPUT /api/settings/compression.updateCompressionSettingsoverwrites every key it receives. So each save from the tab also wrote back the tab's old copy of any setting changed somewhere else since it loaded.The caveman context page has its own Auto-Clarity checkbox and embeds this tab in its Advanced view. Turn the checkbox off, change any field in the tab, and
autoClaritywas stored astrueagain while the checkbox still showed it off.outputStylessaved from another browser tab went back to[]the same way.The tab now sends only what each save changes, including inside nested objects, and a failed save rolls back on screen with its error left visible.
Related Issues
The Fix
save()sends only the keys it is called with, where it used to send{ ...config, ...updates }.cavemanConfig,cavemanOutputMode,aggressive,ultra) are stored as one row each, so the PUT still carries each nested object whole. Each call site names only the field it changes, andsave()fills in the object's other fields from the server's current row, read just before the PUT. A sibling field changed in the panel or another tab since this tab loaded is not written back. This addresses the review note aboutcavemanOutputMode.Validation
saveFailedtextintensity("full" for "ultra"), a stalemaxTokensPerMessage(2048 for 4096) and a stalemoderatethreshold (3 for 9)compressionPanel.test.tsx"derived-pipeline preview reflects the enabled engines" (expectsrtk), which never loads the settings tabcompressionPanelcase pluspool-card,quota-share-delete-errorandquota-share-page, whosenext-intlmock lacksuseLocale;compression-settings-page(2/2) andcompression-settings-tab-consolidation(5/5) passThese
.tsxtests run undervitest.config.ts(npm run test:vitest:ui). CI runs that suite inci.yml, which triggers for pull requests intomain, so the runs above are local; the suite next runs in CI on the release pull request.Tests Added Or Updated
tests/unit/ui/compression-settings-tab-partial-save.test.tsx(new) runs the tab against a fake route that overwrites each key it gets, asupdateCompressionSettingsdoes:outputStylessaved from another tab survives a save from this one, and the PUT body is{ cacheMinutes: 10 }.intensitychanged elsewhere.aggressivethreshold keeps a sibling threshold andmaxTokensPerMessagechanged elsewhere, and the tab then shows the stored row.Reviewer Notes
compressRoles,skipRules,preservePatterns) are computed from what the tab shows, like any edited field, so an array changed elsewhere is replaced by the edited copy.cavemanOutputMode, so after the page checkbox changes the setting the two controls can disagree for a moment.