feat(compaction): make conversation compaction configurable per model preset #338
No reviewers
Labels
No labels
Epic 5
MCP
P1
PR-0
PR-1
api
api-layer
architecture
area:backend
area:frontend
arrow
authentication
backend
bug
chat
client
clipboard
common-module
compose
cross-cutting
cross-cutting-requirement
data-layer
data-models
database
desktop-client
documentation
duplicate
enhancement
epic
epic-1
epic-2
epic-3
epic-4
epic-5
epic-6
epic-7
epic-llm-config
error-handling
feature
frontend
good first issue
help wanted
implementation
infrastructure
installer
invalid
kotlin
ktor
llm
medium-priority
message
multiplatform
needs-review
needs-triage
packaging
performance
phase-1
phase-2
phase-3
phase-4
phase-5
phase3
phase:3
priority: high
question
refactor
refactoring
resource-sharing
security
server
server-module
services
session
session-management
settings
setup
shutdown
state
storage
streaming
sub-issue
tests
tooling
type:task
ui
ui/ux
user-accounts
user-management
ux
viewmodel
websocket
windows
windows-integration
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Torvian.eu/chatbot!338
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/model-preset-compaction-config"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Makes conversation compaction configurable per model preset. A preset gains a
compaction_enabledflag and an optionalcompaction_threshold_tokensoverride, and the effective configuration is resolved and validated once per turn, inside the turn-preparation transaction, instead of being read mid-turn from the user preference alone. A preset can only restrain compaction (its flag is ANDed with the user preference) and override the threshold; the auxiliary summarization model, settings, instruction and summary label stay user-preference-owned.Changes
V35__model_preset_compaction_config.sqlmigration plus the table, entity, mapper, DAO and service plumbing for the two new preset columns, defaulting existing rows to enabled with no override so current behaviour is preserved.compactionEnabled(defaulttrue) andcompactionThresholdTokens(defaultnull) toModelPresetDto, the create/update preset requests and the built-in preset tool schemas, and mapped create/update failures to typed errors.ResolvedCompactionConfig/EffectiveCompactionSettingsandDefaultEffectiveCompactionConfigResolver, which resolve and validate the preset and the stored preference inside the turn's transaction; the value is carried throughPreparedConversationTurn→ConversationTurnRequest→ConversationCompactionService.beginTurn.preset.compactionEnabledAND a present preference row ANDpreference.enabled; a preset with compaction disabled short-circuits before the preference is read or decoded. Effective threshold is the preset override when set, otherwise the preference threshold.Behaviour changes
thresholdTokensnow fails the turn at validation time instead of only when compaction ran, and it can no longer be masked by a preset threshold override.modelId/settingsIdis null now fails every turn of that session instead of running until the window exceeded the threshold.MODEL_CONFIGURATION_ERRORwith nothing persisted, instead of a mid-turnCompactionFailedafter the user message had already been saved.API contract change
PUT /api/v1/me/preferences/conversation_compactionnow rejects null auxiliary ids with400 invalid_argumentwhileenabled == true; null ids remain valid whileenabled == false.enableddefaults totrue, aPUTthat omitsenabledand sends null ids is now rejected.Implementation notes
ConversationCompactionService.beginTurnno longer returns anEither: the configuration was already resolved and validated during preparation, so the remaining failure modes surface frompreparePrimaryContextonly when compaction is actually needed.Validation
./gradlew :server:test— focused filters for the new resolver, the compaction configuration service and resolver, turn preparation, the orchestrator suites, the preset routes/DAO/service/tools and the migrator test were run green../gradlew :app:desktopTest— preset form state, form dialog and API client suites were run green../gradlew :common:desktopTest— preset request serialization and built-in tool catalog suites were run green.Risks and follow-up
PUTis the only intentionally breaking part of this change; clients that stored null auxiliary ids withenabledomitted ortruemust now setenabled: falseor provide ids.