Files
yhh 1b8b56aa65 feat(studio): compaction archives earlier turns to a file instead of summarizing; a skipped ask ends the turn as finished; chat overlays follow the design board
Compaction moves the folded span into <session>.outputs/fold-<hash>.md and leaves a pointer the model reads back with read_file. The summarizer path, its retries, bounds and tests are removed.

Answering an ask with no selection ends the turn normally instead of reporting a failure.

Find bar, overview and context cards, compact dialog, image preview, root-missing banner, toasts, side panel and prompt refine are aligned to the Chat-Tools board; the agent preset picker follows the Agent-Picker board.
2026-11-05 16:25:25 -08:00

43 lines
1.7 KiB
Go

package agent
import (
"sync"
"sync/atomic"
"reasonix/internal/state/sessionstore"
)
// windowState is what the context window owns for one conversation: the
// installed projection, the compaction in flight, and the latches the
// pressure notices keep. It restarts with the conversation.
type windowState struct {
// coveredHash remembers the folded prefix's fingerprint under the rewrite
// counter that makes it valid; gauges read it off the run loop.
coveredHash atomic.Pointer[coveredHashMemo]
// compactionMu guards projection snapshots/install and the in-memory sidecar
// generation. Network summarization never runs while this lock is held.
compactionMu sync.Mutex
// compactionRunMu singleflights the expensive summary transaction without
// holding the session lock during network I/O.
compactionRunMu sync.Mutex
compaction compactionProgress
compactionState sessionstore.CompactionState
cacheState string // legacy resume telemetry; never provider-visible
// checkpointState is rebound by preflight with path, so reset leaves it
// to its owner rather than blanking it.
checkpointState string // none|restored|applied; runtime-only
}
// reset rebinds the window to a new conversation. checkpointState is left to
// preflight, which rebinds it with the transcript path.
func (w *windowState) reset() {
// Keyed on a rewrite counter that restarts with the new transcript, so a
// carried-over entry could answer for history this session never had.
w.coveredHash.Store(nil)
w.compactionMu.Lock()
w.compactionState = sessionstore.CompactionState{} // lineage change; disk reloaded on Resume
w.cacheState = CacheStateUnknown
w.compactionMu.Unlock()
w.compaction.restart()
}