feat(chat): add manual conversation compaction and automatic-only enablement #339
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!339
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/conversation-compaction"
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
Adds a user-triggered "Compact Conversation" action to the chat top bar, served by a dedicated per-session WebSocket, and splits compaction enablement so automatic (threshold-triggered) compaction and user-requested compaction are independent: the per-user preference and the per-preset flag are both renamed to
automaticCompactionEnabled, ANDed, default totrue, and never restrict a manual request.The branch carries 18 commits: the 9 feature commits and, after them, a 9-commit behavior-preserving refactoring series that decomposes the largest files the feature touched (tool catalog, chat view model, send-message use case, message action row, Koin modules, tests) so the feature can be reviewed against a smaller surface in future work. The refactors change no wire format, no persistence schema, no dependency-injection graph semantics and no user-visible behavior.
Changes
CompactionEvent, skip reasons, the per-sessioncompactionresource) shared by client and server.WS /api/v1/sessions/{sessionId}/compactionendpoint, where the connection is the request and a client close aborts it; every path ends with the terminalStreamCompletedmarker.CompactConversationUseCase, theCOMPACTINGturn state that reuses the composer's stop button, and the top bar action, which is now always available while a session is idle.automaticCompactionEnabled(wire models, built-in tool schemas, persistence), with the additiveV36__rename_model_preset_automatic_compaction.sqlmigration.Refactoring
These nine commits are ordered after the feature commits and are behavior-preserving: no wire, persistence or runtime behavior changes, only moved code, extracted collaborators and split test suites.
refactor(common): split the built-in tool catalog by family— the single tool catalog becomes per-family spec files (agent role, instruction, model preset, model, project, session) plus shared input-schema builders, leaving the catalog as the aggregating entry point.test(server): split session route tests by subject— the 1,760-line session route test becomes CRUD, session-state, agent-role and websocket suites on a shared base.refactor(server): extract compaction auxiliary summarizer— the auxiliary summarization call and its verification move out of the compaction service into a dedicated summarizer.test(server): split compaction service tests by path— the compaction service tests split into an automatic path and a forced path sharing one fixture.refactor(app): extract chat turn and search logic—ChatTurnControllerandSearchNavigationObserverare extracted fromChatViewModel, which keeps the public surface used by the screens.refactor(app): split send message use case— the 851-lineSendMessageUseCasebecomes a 390-line orchestrator over a tool-approval event emitter and separate streaming and non-streaming turn collectors.refactor(app): decompose the message action row— the 618-lineMessageActionRowbecomes a 151-line row over action buttons, a more-actions menu and branch-navigation controls.refactor(app): split the app koin module by feature— the app dependency graph splits into core, API, chat and settings modules.refactor(server): split the service koin module— the server service graph splits into chat, tool and MCP modules with the previous module kept as the aggregating entry point.Implementation notes
compactionEnabledfall back to the default, and the preset column is renamed byV36. Both should be mentioned in the release notes.master; the refactoring series accounts for roughly half of that churn while adding no behavior.Validation
The change set is covered by the following suites:
./gradlew :server:testClasses :server:test— compaction services, turn preparation, session and preset routes, websocket handler and the migration tests../gradlew :app:desktopTestClasses :app:desktopTest— client socket transport, chat state and turn guard, top bar/composer UI and settings tests../gradlew :common:desktopTest— compaction event serialization and tool-schema tests.Risks and follow-up
conversation_compactionrows are not migrated or legacy-decoded, so a previously disarmed row is re-armed under the new default, and a legacy armed-but-incomplete row can still reject a turn.compactionEnabledis not backwards compatible on the wire; a preference-row migration plus a legacy-decode path is the suggested follow-up.