Documentation
¶
Overview ¶
Package session persists conversations to disk so they survive restarts and can be resumed. Each session is a single JSON file under the sessions directory; file-change checkpoints for a session live in a sibling "<id>.ckpt" directory.
Index ¶
- func Clear(dir string) error
- func CompactionArchives(dir, id string) ([]string, error)
- func Delete(dir, id string) error
- func Hold(dir, id string) (*lock.File, error)
- type Blocked
- type Card
- type FunctionCall
- type Message
- type Session
- func (s *Session) AppendMessage(msg provider.Message)
- func (s *Session) CkptDir() string
- func (s *Session) ConnectorName() string
- func (s *Session) CooldownsFile() string
- func (s *Session) GetMessages() []provider.Message
- func (s *Session) ModelName() string
- func (s *Session) Paused() *continuity.Pause
- func (s *Session) ProviderStateName() string
- func (s *Session) Save() error
- func (s *Session) SessionEffort() string
- func (s *Session) SessionID() string
- func (s *Session) SessionMode() string
- func (s *Session) SessionTitle() string
- func (s *Session) SetAutoTitle(title string) bool
- func (s *Session) SetConnector(n string)
- func (s *Session) SetEffort(level string)
- func (s *Session) SetMessages(msgs []provider.Message)
- func (s *Session) SetMode(mode string)
- func (s *Session) SetModelName(m string)
- func (s *Session) SetPaused(p *continuity.Pause)
- func (s *Session) SetProviderStateName(v string)
- func (s *Session) SetTitle(title string)
- func (s *Session) SetTitleFromInput(input string)
- func (s *Session) TitleIsAuto() bool
- type SharedCheckout
- type State
- type ToolCall
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CompactionArchives ¶ added in v1.2.0
CompactionArchives are the pre-compaction conversations kept for one session.
func Delete ¶
Delete removes a session file, its checkpoint directory, and every pre-compaction archive belonging to it.
The archives hold the conversation a compaction replaced, so leaving them behind would mean deleting a session that is still readable on disk.
func Hold ¶ added in v1.2.1
Hold marks a session as being run by this process, until the returned handle is closed.
An advisory lock rather than a flag in a file, because the interesting case is the one nobody writes code for: a session whose process was killed. The OS drops a lock when the process goes, so a crashed session stops looking live without anything having to notice that it crashed.
Types ¶
type Blocked ¶ added in v1.2.2
Blocked is what a session is waiting for.
func BlockedOn ¶ added in v1.2.2
BlockedOn reports whether a session is stopped at an unanswered permission prompt.
"Blocked" is the decisive field on a card: a session waiting on a prompt is not slow, it has *stopped*, and it will stay stopped until a person answers. That is the one thing worth seeing when scanning a list of sessions.
The rule is the doc's: the last `permission.requested` with no matching `permission.resolved`. Requests are correlated by id rather than by position, because answering one prompt does not unblock a later one.
type Card ¶ added in v1.2.1
type Card struct {
ID string
Title string
Model string
Effort string
Connector string
CWD string
Updated time.Time
State State
}
Card is one session as a list shows it: who and when, never what was said.
Deliberately not a *Session. Loading a megabyte of transcript to render one line is the difference between a list that can be polled and one that cannot, and a type that cannot carry a transcript cannot accidentally leak one into a view.
type FunctionCall ¶ added in v1.1.7
FunctionCall is the serialized function invocation.
type Message ¶ added in v1.1.7
type Message struct {
Role string `json:"role"`
Content string `json:"content,omitempty"`
Reasoning string `json:"reasoning,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
}
Message is the frozen persisted session message shape on disk.
type Session ¶
type Session struct {
ID string `json:"id"`
Model string `json:"model"`
Title string `json:"title"`
CreatedAt time.Time `json:"created_at"`
// CWD is the directory the session was started in. Sessions written before
// this field existed have none, which is why every match here is explicit
// rather than a comparison against the empty string.
CWD string `json:"cwd,omitempty"`
// Effort is the level the session's dial ran at, persisted so a resume
// lands at the same width of effort instead of the configured default.
// Written before this field existed are sessions with none.
Effort string `json:"effort,omitempty"`
// Mode is the mode the session was left in — chat, code or agent —
// persisted so a resume lands in it instead of the default. Plan 06 §3
// promised this from the start ("written on switch and on save; resume
// restores it") and nothing had built it: the F7.2 transcript re-issued
// /mode agent on every wake. Sessions written before this field have none.
Mode string `json:"mode,omitempty"`
// Connector records the subscription connector the session ran on, when
// it ran on one. A plan model re-derives its connector from its name, so
// this is display state, never routing state.
Connector string `json:"connector,omitempty"`
// ProviderState is opaque provider-side state worth resuming: for Claude,
// the vendor conversation handle. Kolk mints the handle itself, so a later
// Kolkrabbi process can --resume the same vendor conversation without the
// child having ever reported anything secret. Names a conversation, never
// a credential.
ProviderState string `json:"provider_state,omitempty"`
// Pause is the limit this session is stopped on, when it is (plan 35 §2.2).
Pause *continuity.Pause `json:"pause,omitempty"`
// TitleAuto marks a title Kolkrabbi derived rather than one the user chose.
TitleAuto bool `json:"title_auto,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
Messages []Message `json:"messages"`
// contains filtered or unexported fields
}
func LatestForDir ¶ added in v1.2.0
LatestForDir resumes this project's most recent session, falling back to the most recent overall.
Standing in a directory and asking to resume means the work done here, not whatever happened to be typed last in another window. A session with no recorded directory belongs to no project and is only ever reachable through the fallback: matching it against every directory would make one old session hijack resume everywhere.
func (*Session) AppendMessage ¶ added in v1.1.7
func (*Session) ConnectorName ¶ added in v1.2.18
func (*Session) CooldownsFile ¶ added in v1.3.1
CooldownsFile holds this session's own remembered limits (model and endpoint scope); the user-wide ones live with the connectors.
func (*Session) GetMessages ¶ added in v1.1.7
func (*Session) Paused ¶ added in v1.3.1
func (s *Session) Paused() *continuity.Pause
Paused and SetPaused read and record the limit the session is stopped on, under the same lock the messages use, so a save sees a consistent pair.
func (*Session) ProviderStateName ¶ added in v1.2.18
func (*Session) Save ¶
Save writes the session atomically and durably.
A transcript is the one thing here a person cannot reconstruct, so this goes through internal/atomicfile rather than a hand-rolled tmp-and-rename: that buys an fsync (a rename is atomic against other processes but not against power loss) and a unique temp name (a REPL in one terminal and `kolk -p` in another used to write the same "x.json.tmp" and shred each other).
func (*Session) SessionEffort ¶ added in v1.2.18
func (*Session) SessionMode ¶ added in v1.3.1
func (*Session) SessionTitle ¶ added in v1.1.7
func (*Session) SetAutoTitle ¶ added in v1.2.0
SetAutoTitle replaces a derived title with a better derived one, and does nothing to a title the user chose.
func (*Session) SetConnector ¶ added in v1.2.18
func (*Session) SetMessages ¶ added in v1.1.7
func (*Session) SetModelName ¶ added in v1.1.7
func (*Session) SetPaused ¶ added in v1.3.1
func (s *Session) SetPaused(p *continuity.Pause)
func (*Session) SetProviderStateName ¶ added in v1.2.18
func (*Session) SetTitleFromInput ¶
SetTitleFromInput sets a human-readable title from the first user message. SetTitleFromInput derives a first title from what the user typed. The title is marked automatic so Kolkrabbi may later improve on its own guess without ever overwriting a name a person chose.
func (*Session) TitleIsAuto ¶ added in v1.2.0
TitleIsAuto reports whether the current title was derived rather than chosen.
type SharedCheckout ¶ added in v1.2.2
type SharedCheckout struct {
}
SharedCheckout is one directory that more than one live session is working in.
func SharedCheckouts ¶ added in v1.2.2
func SharedCheckouts(cards []Card) []SharedCheckout
SharedCheckouts reports the directories where live sessions overlap.
Two sessions in one checkout will edit each other's files, and each one's `/undo` restores over the other's work — the shadow store snapshots a whole tree, so a rewind in one session takes back what the other did in the same tree. Item 27 does not refuse the overlap, because two terminals in one repository is a thing people do on purpose. What it refuses is **silence** about it: this should be something a person is told once, not something discovered when an undo restores someone else's work.
Only live sessions count. An idle one holds no lock and runs no turns, so it is not competing for anything, and a session with no recorded directory cannot be said to share one — guessing would produce a warning about nothing, which is how warnings come to be ignored.
type State ¶ added in v1.2.1
type State int
State is whether a process is currently running a session.
const ( // StateUnknown means this platform cannot say. Reported honestly rather // than guessed at: a dashboard that shows "idle" for every session on // Windows is worse than one that admits it does not know. StateUnknown State = iota // StateIdle means nothing is running it. StateIdle // StateLive means a process holds it right now. StateLive )
func Live ¶ added in v1.2.1
Live reports whether a session is being run right now.
It probes the lock without taking or creating it. Taking it would lock out the session being described; creating it would leave a file behind for every session a listing touches, which a benchmark against a real directory of 549 sessions turned into 549 stray files and half a second of syscalls.
type ToolCall ¶ added in v1.1.7
type ToolCall struct {
ID string `json:"id"`
Type string `json:"type"`
Function FunctionCall `json:"function"`
}
ToolCall is the serialized tool call.