session

package
v0.2.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package session provides the core session model: id, title, created_at, and conversation history. File-based persistence lives in internal/agentapp (SessionStore).

Index

Constants

This section is empty.

Variables

View Source
var ErrSessionNotFound = errors.New("session not found")

ErrSessionNotFound is returned when a session file does not exist.

Functions

func CtxWithSessionID

func CtxWithSessionID(ctx context.Context, id string) context.Context

CtxWithSessionID returns a context that carries the given session ID.

func EnsureTitleFromFirstUserMessage

func EnsureTitleFromFirstUserMessage(s *Session, maxLen int)

EnsureTitleFromFirstUserMessage sets the session title from the first user message if the title is empty, truncated to maxLen runes. No-op otherwise.

func NewID

func NewID() string

NewID returns a new session ID.

func SessionIDFromContext

func SessionIDFromContext(ctx context.Context) (string, bool)

SessionIDFromContext returns the session ID from ctx, or ("", false) if not set.

Types

type ConversationStats

type ConversationStats struct {
	// UserMessages counts messages the user actually wrote. A background
	// event travels as a user-role message because no provider has a portable
	// role for one, and counting those as things the user said would inflate
	// the number that reads most like effort.
	UserMessages int
	// BackgroundMessages counts the user-role messages that carry a Source:
	// command results, subagent results, monitor events.
	BackgroundMessages int
	// AssistantTurns counts assistant messages, including the ones whose whole
	// content was a tool call.
	AssistantTurns int
	// ToolCalls counts calls the assistant issued. ToolResults counts the
	// results that came back; the two differ when a run was cut short between
	// the call and its result.
	ToolCalls   int
	ToolResults int
	// Tools is the per-tool breakdown, heaviest by result bytes first. A tool
	// the assistant called but whose result never arrived still appears, with
	// zero bytes.
	Tools []ToolStats
	// TextBytes is what the conversation's own text weighs — user prompts and
	// assistant replies. ToolResultBytes is what came back from tools.
	//
	// Kept apart because they are spent differently: the first is the
	// conversation, the second is what the run pulled into it, and on a long
	// agent session the second is usually the larger by an order of magnitude.
	TextBytes       int
	ToolResultBytes int
	// CompactedMessages is how many messages sit before the compaction
	// boundary — summarized away, still stored.
	CompactedMessages int
	// Notes and Todos are the durable state the session carries.
	Notes int
	Todos int
}

ConversationStats is the shape of a session's history: who said how much, which tools ran, and how many bytes each of them put back into the context.

It is derived from the stored messages alone and needs no run to be live, so it answers for a session whose traces have been removed. What it cannot answer is anything time-shaped — durations, run boundaries, which model ran — because the history carries no timestamps. That half comes from the traces.

func Stats

func Stats(s *Session) ConversationStats

Stats folds a session's stored history into its shape.

A tool result names the call it answers rather than the tool it came from, so results are attributed by walking the assistant tool calls first and looking each result's call id up. A result whose call is not in the history — the assistant message was compacted out from under it — is counted in the totals under an empty name rather than dropped: the bytes are in the context either way.

type Session

type Session struct {
	ID               string        `json:"id"`
	Title            string        `json:"title,omitempty"`
	CreatedAt        time.Time     `json:"created_at"`
	Messages         []llm.Message `json:"messages,omitempty"`
	PromptTokens     int           `json:"prompt_tokens,omitempty"`
	CompletionTokens int           `json:"completion_tokens,omitempty"`
	// CacheReadTokens and CacheWriteTokens are the session's provider-reported
	// cached prompt. They break PromptTokens down rather than add to it, so a
	// reader totalling a session must not sum all three.
	CacheReadTokens  int `json:"cache_read_tokens,omitempty"`
	CacheWriteTokens int `json:"cache_write_tokens,omitempty"`
	// Cost is what this session is estimated to have spent, accumulated as it
	// ran. It is a running total rather than something recomputed on read,
	// because the rates that applied to an earlier turn are not necessarily
	// the ones configured now. Nil means nothing here was priced.
	Cost *llm.Cost `json:"cost,omitempty"`
	// CostIncomplete says the total above is missing part of the session: a
	// turn ran against an unpriced model, or against one quoted in a different
	// currency, which BuildMax does not convert. A number that silently
	// dropped half a session is worse than one labelled incomplete.
	CostIncomplete bool `json:"cost_incomplete,omitempty"`
	// CompactionIdx is the index into Messages where the latest compaction boundary falls.
	// Messages before this index have been summarized into CompactionSummary.
	// Zero means no compaction has occurred.
	CompactionIdx     int    `json:"compaction_idx,omitempty"`
	CompactionSummary string `json:"compaction_summary,omitempty"`
	// NoteEntries and TodoEntries are durable session state: unlike a tool result, they are
	// not messages, so compaction cannot take them. The fields are named apart from the
	// Notes/Todos accessors that implement agent.NoteStore; the JSON keys are the plain names.
	NoteEntries []agent.Note `json:"notes,omitempty"`
	TodoEntries []agent.Todo `json:"todos,omitempty"`
	// AdditionalSystemPrompt records the extra system-prompt text this session actually ran
	// under. It is a record — for the trace, and so a resumed session does not silently lose
	// its identity when the flag that set it is not repeated — not the authority. Whoever
	// assembles a run resolves it afresh, and the last writer wins.
	AdditionalSystemPrompt string `json:"additional_system_prompt,omitempty"`
}

Session holds conversation history (user, assistant, tool messages) and metadata. The system message is not stored; it is prepended at call time by the agent. JSON tags match the on-disk session file format (snake_case).

func NewSession

func NewSession(title string) *Session

NewSession creates a new session with a generated UUID, the given title, created_at set to the current time, and empty history. Title may be empty.

func NewSessionFromData

func NewSessionFromData(id, title string, createdAt time.Time, messages []llm.Message, promptTokens, completionTokens int) *Session

NewSessionFromData constructs a Session from persisted data.

func (*Session) AddCompaction

func (s *Session) AddCompaction(summary string, summarizedCount int)

AddCompaction advances the compaction boundary by summarizedCount messages and stores the summary. The summary is expected to subsume any earlier one, so replacing is correct. Implements agent.CompactionHistory so RunLoop can persist the boundary across turns.

func (*Session) Append

func (s *Session) Append(msg llm.Message) error

Append adds one message to the session's history.

func (*Session) CacheReadShare

func (s *Session) CacheReadShare() (share float64, ok bool)

CacheReadShare is the fraction of the session's prompt that was served from a provider's cache, and ok=false when there is nothing to divide or the provider reported no cache usage at all. A zero share and an unreported one are different facts: only the first says the cache missed.

func (*Session) HistoryMessages

func (s *Session) HistoryMessages() []llm.Message

HistoryMessages returns the LLM-facing message slice. When a compaction boundary exists, only messages from CompactionIdx onward are returned; earlier messages have been summarized.

func (*Session) Notes

func (s *Session) Notes() []agent.Note

Notes returns the session's durable notes. Implements agent.NoteStore.

func (*Session) PriorSummary

func (s *Session) PriorSummary() string

PriorSummary returns the summary stored by the most recent compaction, or "" when this session has never been compacted. Implements agent.CompactionHistory so RunLoop can feed the previous summary back into the next compaction instead of discarding what it covered.

func (*Session) SetNotes

func (s *Session) SetNotes(notes []agent.Note, iter int)

SetNotes replaces the session's notes, preserving the age of entries whose text is unchanged so a rewrite of the list does not make every entry look new. Implements agent.NoteStore.

func (*Session) SetTodos

func (s *Session) SetTodos(todos []agent.Todo, iter int)

SetTodos replaces the session's task list, preserving the age of entries whose content and status are both unchanged. Implements agent.NoteStore.

func (*Session) Todos

func (s *Session) Todos() []agent.Todo

Todos returns the session's durable task list. Implements agent.NoteStore.

func (*Session) Usage

func (s *Session) Usage() llm.Usage

Usage is the session's accumulated token usage.

type SessionItem

type SessionItem struct {
	ID        string `json:"id"`
	Title     string `json:"title,omitempty"`
	Workspace string `json:"workspace,omitempty"`
	CreatedAt string `json:"created_at"` // RFC3339
	Pinned    bool   `json:"pinned,omitempty"`
}

SessionItem is one session's metadata in the session index file (sessions.json).

type ToolStats

type ToolStats struct {
	Name string
	// Calls is how many times the assistant asked for it.
	Calls int
	// ResultBytes is what its results put back into the context. This is the
	// number that answers which tool is filling the context window, and it is
	// not derivable from the call count: one search can outweigh fifty reads.
	ResultBytes int
	// MaxResultBytes is the largest single result, so one outlier is not
	// hidden inside an average.
	MaxResultBytes int
}

ToolStats is one tool's share of a session.

Jump to

Keyboard shortcuts

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