session

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const CurrentVersion = 3

CurrentVersion is the session format version for JSONL tree sessions.

Variables

This section is empty.

Functions

func DefaultSessionDir

func DefaultSessionDir(cwd string) string

DefaultSessionDir returns the default session storage directory for a cwd. Following pi's convention: ~/.kit/sessions/--<cwd-path>--/

func DeleteSession

func DeleteSession(path string) error

DeleteSession removes a session file from disk.

func GenerateEntryID

func GenerateEntryID() string

GenerateEntryID creates a unique entry identifier (16 hex chars).

func GenerateSessionID

func GenerateSessionID() string

GenerateSessionID creates a unique session identifier (32 hex chars).

func MarshalEntry

func MarshalEntry(entry any) ([]byte, error)

MarshalEntry serializes any entry to a JSON line (no trailing newline).

func UnmarshalEntry

func UnmarshalEntry(data []byte) (any, error)

UnmarshalEntry deserializes a JSON line into the appropriate entry type. Returns one of: *SessionHeader, *MessageEntry, *ModelChangeEntry, *BranchSummaryEntry, *LabelEntry, *SessionInfoEntry.

Types

type BranchSummaryEntry

type BranchSummaryEntry struct {
	Entry
	FromID  string `json:"from_id"` // leaf of the summarized branch
	Summary string `json:"summary"`
}

BranchSummaryEntry provides LLM-generated context from an abandoned branch. When the user navigates away from a branch, a summary of that branch's conversation is stored so the LLM retains context about what was explored.

func NewBranchSummaryEntry

func NewBranchSummaryEntry(parentID, fromID, summary string) *BranchSummaryEntry

NewBranchSummaryEntry creates a BranchSummaryEntry.

type Entry

type Entry struct {
	Type      EntryType `json:"type"`
	ID        string    `json:"id"`
	ParentID  string    `json:"parent_id,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

Entry is the common structure shared by all tree entries (everything except the session header). Every entry has an ID, an optional ParentID (empty for root entries), a type tag, and a timestamp.

func NewEntry

func NewEntry(entryType EntryType, parentID string) Entry

NewEntry creates a base Entry with a generated ID and current timestamp.

type EntryType

type EntryType string

EntryType identifies the kind of entry stored in a JSONL session file. Following pi's design, sessions are append-only JSONL files where each line is a typed entry linked by id/parent_id to form a tree structure.

const (
	EntryTypeSession       EntryType = "session"
	EntryTypeMessage       EntryType = "message"
	EntryTypeModelChange   EntryType = "model_change"
	EntryTypeBranchSummary EntryType = "branch_summary"
	EntryTypeLabel         EntryType = "label"
	EntryTypeSessionInfo   EntryType = "session_info"
)

type LabelEntry

type LabelEntry struct {
	Entry
	TargetID string `json:"target_id"`
	Label    string `json:"label"`
}

LabelEntry bookmarks a specific entry with a user-defined label.

func NewLabelEntry

func NewLabelEntry(parentID, targetID, label string) *LabelEntry

NewLabelEntry creates a LabelEntry.

type MessageEntry

type MessageEntry struct {
	Entry
	Role     string          `json:"role"`
	Parts    json.RawMessage `json:"parts"` // type-tagged parts array
	Model    string          `json:"model,omitempty"`
	Provider string          `json:"provider,omitempty"`
}

MessageEntry stores a conversation message as a tree entry. The message content uses the same type-tagged parts format as the existing session persistence layer, enabling reuse of MarshalParts/UnmarshalParts.

func NewMessageEntry

func NewMessageEntry(parentID string, msg message.Message) (*MessageEntry, error)

NewMessageEntry creates a MessageEntry from a message.Message, linking it to the given parent entry in the tree.

func NewMessageEntryFromRaw

func NewMessageEntryFromRaw(parentID, role string, parts json.RawMessage, model, provider string) *MessageEntry

NewMessageEntryFromRaw creates a MessageEntry with pre-marshaled parts.

func (*MessageEntry) ToMessage

func (e *MessageEntry) ToMessage() (message.Message, error)

ToMessage converts a MessageEntry back to a message.Message by unmarshaling the type-tagged parts.

type ModelChangeEntry

type ModelChangeEntry struct {
	Entry
	Provider string `json:"provider"`
	ModelID  string `json:"model_id"`
}

ModelChangeEntry records a provider/model switch in the session tree.

func NewModelChangeEntry

func NewModelChangeEntry(parentID, provider, modelID string) *ModelChangeEntry

NewModelChangeEntry creates a ModelChangeEntry.

type SessionHeader

type SessionHeader struct {
	Type          EntryType `json:"type"`                     // always "session"
	Version       int       `json:"version"`                  // format version (3)
	ID            string    `json:"id"`                       // session UUID
	Timestamp     time.Time `json:"timestamp"`                // creation time
	Cwd           string    `json:"cwd"`                      // working directory
	ParentSession string    `json:"parent_session,omitempty"` // path to parent if forked
}

SessionHeader is the first line in a JSONL session file. It carries metadata about the session and does NOT participate in the tree structure (it has no ID or ParentID).

type SessionInfo

type SessionInfo struct {
	// Path is the absolute path to the JSONL session file.
	Path string

	// ID is the session UUID from the header.
	ID string

	// Cwd is the working directory the session was created in.
	Cwd string

	// Name is the user-defined display name (from session_info entries).
	Name string

	// ParentSessionPath is the parent session path if this session was forked.
	ParentSessionPath string

	// Created is when the session was first created.
	Created time.Time

	// Modified is the timestamp of the last activity (latest message).
	Modified time.Time

	// MessageCount is the number of message entries in the session.
	MessageCount int

	// FirstMessage is a preview of the first user message.
	FirstMessage string
}

SessionInfo contains metadata about a discovered session, used for listing and session picker display. Follows pi's SessionInfo design.

func ListAllSessions

func ListAllSessions() ([]SessionInfo, error)

ListAllSessions finds all sessions across all working directories, sorted by modification time (newest first).

func ListSessions

func ListSessions(cwd string) ([]SessionInfo, error)

ListSessions finds all sessions for a given working directory, sorted by modification time (newest first).

type SessionInfoEntry

type SessionInfoEntry struct {
	Entry
	Name string `json:"name"`
}

SessionInfoEntry stores a user-defined display name for the session.

func NewSessionInfoEntry

func NewSessionInfoEntry(parentID, name string) *SessionInfoEntry

NewSessionInfoEntry creates a SessionInfoEntry.

type TreeManager

type TreeManager struct {
	// contains filtered or unexported fields
}

TreeManager manages a tree-structured JSONL session. It is the replacement for the linear session.Manager, following pi's design decisions:

  • JSONL append-only format (one JSON object per line)
  • Tree structure via id/parent_id on every entry
  • Leaf pointer tracking current position
  • Context building walks from leaf to root
  • Auto-discovery by working directory

func ContinueRecent

func ContinueRecent(cwd string) (*TreeManager, error)

ContinueRecent finds the most recently modified session for the given cwd, or creates a new one if none exists.

func CreateTreeSession

func CreateTreeSession(cwd string) (*TreeManager, error)

CreateTreeSession creates a new tree session persisted at the default location for the given working directory.

func InMemoryTreeSession

func InMemoryTreeSession(cwd string) *TreeManager

InMemoryTreeSession creates a tree session that is not persisted to disk.

func OpenTreeSession

func OpenTreeSession(path string) (*TreeManager, error)

OpenTreeSession opens an existing JSONL session file.

func (*TreeManager) AddFantasyMessages

func (tm *TreeManager) AddFantasyMessages(msgs []fantasy.Message) error

AddFantasyMessages appends multiple fantasy messages as entries. This is used when syncing from the agent's ConversationMessages after a step.

func (*TreeManager) AppendBranchSummary

func (tm *TreeManager) AppendBranchSummary(fromID, summary string) (string, error)

AppendBranchSummary adds a summary of an abandoned branch.

func (*TreeManager) AppendFantasyMessage

func (tm *TreeManager) AppendFantasyMessage(msg fantasy.Message) (string, error)

AppendFantasyMessage converts a fantasy.Message and appends it.

func (*TreeManager) AppendLabel

func (tm *TreeManager) AppendLabel(targetID, label string) (string, error)

AppendLabel sets a label on a target entry.

func (*TreeManager) AppendMessage

func (tm *TreeManager) AppendMessage(msg message.Message) (string, error)

AppendMessage adds a message entry to the tree and persists it.

func (*TreeManager) AppendModelChange

func (tm *TreeManager) AppendModelChange(provider, modelID string) (string, error)

AppendModelChange records a model/provider change.

func (*TreeManager) AppendSessionInfo

func (tm *TreeManager) AppendSessionInfo(name string) (string, error)

AppendSessionInfo sets a display name for the session.

func (*TreeManager) Branch

func (tm *TreeManager) Branch(entryID string) error

Branch moves the leaf pointer to the given entry ID, creating a branch point. Subsequent appends will extend from this new position.

func (*TreeManager) BuildContext

func (tm *TreeManager) BuildContext() (messages []fantasy.Message, provider string, modelID string)

BuildContext walks from the current leaf to the root and returns the conversation messages suitable for sending to the LLM. Branch summaries are converted to user messages to provide context from abandoned branches. Also returns the latest model/provider settings encountered on the path.

func (*TreeManager) Close

func (tm *TreeManager) Close() error

Close closes the underlying file handle.

func (*TreeManager) EntryCount

func (tm *TreeManager) EntryCount() int

EntryCount returns the number of entries (excluding header).

func (*TreeManager) GetBranch

func (tm *TreeManager) GetBranch(fromID string) []any

GetBranch returns the path of entries from the given entry to the root, ordered from root to the entry. If fromID is empty, uses the current leaf.

func (*TreeManager) GetChildren

func (tm *TreeManager) GetChildren(parentID string) []string

GetChildren returns direct child entry IDs for a given parent.

func (*TreeManager) GetCwd

func (tm *TreeManager) GetCwd() string

GetCwd returns the working directory this session was created in.

func (*TreeManager) GetEntries

func (tm *TreeManager) GetEntries() []any

GetEntries returns all entries (excluding the session header).

func (*TreeManager) GetEntry

func (tm *TreeManager) GetEntry(id string) any

GetEntry returns the entry with the given ID, or nil if not found.

func (*TreeManager) GetFantasyMessages

func (tm *TreeManager) GetFantasyMessages() []fantasy.Message

GetFantasyMessages builds the context and returns just the messages. This satisfies the same conceptual role as the old Manager.GetMessages().

func (*TreeManager) GetFilePath

func (tm *TreeManager) GetFilePath() string

GetFilePath returns the JSONL file path, or empty for in-memory sessions.

func (*TreeManager) GetHeader

func (tm *TreeManager) GetHeader() SessionHeader

GetHeader returns a copy of the session header.

func (*TreeManager) GetLabel

func (tm *TreeManager) GetLabel(id string) string

GetLabel returns the label for an entry, or empty string if none.

func (*TreeManager) GetLeafID

func (tm *TreeManager) GetLeafID() string

GetLeafID returns the current leaf position.

func (*TreeManager) GetSessionID

func (tm *TreeManager) GetSessionID() string

GetSessionID returns the session UUID.

func (*TreeManager) GetSessionName

func (tm *TreeManager) GetSessionName() string

GetSessionName returns the user-defined display name, or empty string.

func (*TreeManager) GetTree

func (tm *TreeManager) GetTree() []*TreeNode

GetTree builds the full tree structure from root entries.

func (*TreeManager) IsPersisted

func (tm *TreeManager) IsPersisted() bool

IsPersisted returns true if this session writes to disk.

func (*TreeManager) MessageCount

func (tm *TreeManager) MessageCount() int

MessageCount returns the number of message entries.

func (*TreeManager) ResetLeaf

func (tm *TreeManager) ResetLeaf()

ResetLeaf moves the leaf pointer to before the first entry (empty conversation).

type TreeNode

type TreeNode struct {
	Entry    any         // the underlying entry (*MessageEntry, *ModelChangeEntry, etc.)
	ID       string      // entry ID
	ParentID string      // parent entry ID
	Children []*TreeNode // child nodes
}

TreeNode represents a node in the session tree for display purposes. It mirrors pi's SessionTreeNode design.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL