Why: Linear transcripts cannot fork, and compaction rewrote history, so resume and branch navigation had nothing to point at. Evidence: go test -count=1 ./runtime/session/ Impact: Load still returns the model-visible path, including old one-message-per-line files. Compaction appends a summary entry instead of truncating the file. Refs: feature/pi-headless N1 Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
package session
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"agent-native/runtime/llm"
|
|
)
|
|
|
|
// Store is an append-only JSONL transcript. New sessions are a tree of
|
|
// entries (id / parentId). Load still returns the model-visible message
|
|
// path, and files written as one llm.Message per line remain readable.
|
|
type Store struct {
|
|
path string
|
|
mu sync.Mutex
|
|
}
|
|
|
|
func Open(path string) (*Store, error) {
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return nil, err
|
|
}
|
|
f, err := os.OpenFile(path, os.O_CREATE, 0o644)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_ = f.Close()
|
|
return &Store{path: path}, nil
|
|
}
|
|
|
|
func (s *Store) Path() string { return s.path }
|
|
|
|
// Append records one message on the active branch.
|
|
func (s *Store) Append(msg llm.Message) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
_, err := s.appendEntryLocked(Entry{Type: TypeMessage, Message: &msg})
|
|
return err
|
|
}
|
|
|
|
// Load returns the model-visible messages on the active branch.
|
|
// A compaction entry replaces earlier turns with its summary plus the
|
|
// retained tail; the file itself is never rewritten.
|
|
// Crash residue: a trailing line without a newline that is not valid JSON
|
|
// is dropped. A bad line in the middle is still an error.
|
|
func (s *Store) Load() ([]llm.Message, error) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
entries, err := s.readEntriesLocked()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return visibleMessages(entries, s.leafLocked(entries)), nil
|
|
}
|