session

package
v0.4.10 Latest Latest
Warning

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

Go to latest
Published: Jun 2, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MaxOutputBytes is the maximum byte size of a tool output before truncation.
	MaxOutputBytes = 50 * 1024 // 50 KB
	// MaxOutputLines is the maximum line count of a tool output before truncation.
	MaxOutputLines = 2000
	// HeadLines is the number of lines to preserve from the beginning.
	HeadLines = 200
	// TailLines is the number of lines to preserve from the end.
	TailLines = 500
)

Variables

This section is empty.

Functions

func DeleteSession

func DeleteSession(project, uuid string) error

DeleteSession removes a session file and its index entry.

func GetLastEnvironment

func GetLastEnvironment(entries []Entry) string

GetLastEnvironment scans the session entries to find the last successful switch_env call, and returns the target environment alias. If none is found, it returns "local".

func ListAllSessions added in v0.3.4

func ListAllSessions() (map[string][]SessionMeta, error)

ListAllSessions returns all sessions across all projects, keyed by project path.

func PruneOldToolOutputs added in v0.4.6

func PruneOldToolOutputs(msgs []adk.Message, protectTurns int) []adk.Message

PruneOldToolOutputs replaces old tool result outputs with actionable placeholders, protecting the most recent turns from pruning. This implements the Tier 1.5 "placeholder compression" strategy: recent tool outputs are preserved verbatim; older ones are replaced with hints telling the model how to recover the data.

protectTurns is the number of recent user turns to protect (default 2). Returns the pruned messages slice (same backing array, modified in place).

func ReconstructHistory

func ReconstructHistory(entries []Entry) []adk.Message

ReconstructHistory converts a slice of recorded session entries back into LLM history messages suitable for resuming a conversation. It reconstructs tool call and tool result messages so that resumed sessions retain full context.

Subagent-internal entries (tool_call / tool_result / assistant recorded between subagent_start and subagent_result) are skipped — only the main agent's own messages are included.

Because the runner records assistant text AFTER tool calls in the JSONL, an EntryAssistant that follows tool-call entries is merged back into the preceding assistant message as its Content field.

func TruncateToolOutput added in v0.4.6

func TruncateToolOutput(output, sessionUUID, toolCallID string) string

TruncateToolOutput truncates a tool output string if it exceeds size limits. It preserves head + tail lines and writes the full content to disk. Returns the (possibly truncated) output. If no truncation is needed, the original string is returned unchanged.

sessionUUID is used to namespace the overflow files. toolCallID identifies the specific tool call.

func ValidateSessionID added in v0.3.3

func ValidateSessionID(id string) error

ValidateSessionID checks that a session ID is safe for use as a filename. It rejects empty IDs, path traversal sequences, and path separators.

Types

type Entry

type Entry struct {
	Type       EntryType `json:"type"`
	UUID       string    `json:"uuid,omitempty"`
	Project    string    `json:"project,omitempty"`
	Provider   string    `json:"provider,omitempty"`
	Model      string    `json:"model,omitempty"`
	Content    string    `json:"content,omitempty"`
	Name       string    `json:"name,omitempty"`         // tool name
	Args       string    `json:"args,omitempty"`         // tool args JSON
	Output     string    `json:"output,omitempty"`       // tool output
	Error      string    `json:"error,omitempty"`        // tool error
	ToolCallID string    `json:"tool_call_id,omitempty"` // links tool_call ↔ tool_result
	Timestamp  string    `json:"timestamp"`

	// Images attached to a user message.
	Images []EntryImage `json:"images,omitempty"`

	// plan_update fields
	PlanStatus  string `json:"plan_status,omitempty"`
	PlanTitle   string `json:"plan_title,omitempty"`
	PlanContent string `json:"plan_content,omitempty"`
	Feedback    string `json:"feedback,omitempty"`

	// todo_snapshot fields
	Todos []TodoSnapshotItem `json:"todos,omitempty"`

	// subagent_start / subagent_result fields
	SubagentName string `json:"subagent_name,omitempty"`
	SubagentType string `json:"subagent_type,omitempty"`

	// mode_change field
	Mode string `json:"mode,omitempty"`

	// compact fields
	Summary    string `json:"summary,omitempty"`
	CompactedN int    `json:"compacted_n,omitempty"`

	// system_prompt fields
	EnvInfo string `json:"env_info,omitempty"` // serialized environment snapshot
}

Entry is one line of the JSONL session file.

func LoadSession

func LoadSession(id string) ([]Entry, error)

LoadSession reads all entries from a session JSONL file identified by uuid.

type EntryImage added in v0.4.1

type EntryImage struct {
	MimeType string `json:"media_type"`
	Data     string `json:"data"` // base64-encoded
}

EntryImage stores a single image attached to a user message.

type EntryType

type EntryType string

EntryType identifies the kind of JSONL record.

const (
	EntrySessionStart EntryType = "session_start"
	EntryUser         EntryType = "user"
	EntryAssistant    EntryType = "assistant"
	EntryToolCall     EntryType = "tool_call"
	EntryToolResult   EntryType = "tool_result"

	// Extended entry types for structured state tracking.
	EntryPlanUpdate     EntryType = "plan_update"
	EntryTodoSnapshot   EntryType = "todo_snapshot"
	EntrySubagentStart  EntryType = "subagent_start"
	EntrySubagentResult EntryType = "subagent_result"
	EntrySubagentAsync  EntryType = "subagent_async"
	EntryModeChange     EntryType = "mode_change"
	EntryCompact        EntryType = "compact"
	EntryBudgetWarning  EntryType = "budget_warning"
	EntrySystemPrompt   EntryType = "system_prompt"
)

type PlanSnapshot

type PlanSnapshot struct {
	Status   string
	Title    string
	Content  string
	Feedback string
}

PlanSnapshot holds the last known plan state from a session.

type Recorder

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

Recorder appends events to a JSONL session file synchronously. The file and index entry are created lazily on the first real message so that sessions with no conversation are never persisted. Call Close() (or defer it) to finalize.

func NewRecorder

func NewRecorder(project, provider, model string) (*Recorder, error)

NewRecorder returns a Recorder that will create the session file only when the first message is recorded. Never returns an error — recording is best-effort and must not break normal operation.

func NewTeammateRecorder

func NewTeammateRecorder(leaderUUID, agentID, model string) (*Recorder, error)

NewTeammateRecorder creates a Recorder that stores its JSONL transcript under the leader session's subagents directory:

~/.jcode/sessions/{leaderUUID}/subagents/agent-{agentID}.jsonl

This mirrors Claude Code's per-agent transcript pattern.

func (*Recorder) Close

func (r *Recorder) Close()

Close flushes and closes the underlying file. Safe to call multiple times. If no messages were ever recorded the file is never created.

func (*Recorder) HasRecording added in v0.0.4

func (r *Recorder) HasRecording() bool

HasRecording reports whether any message has been recorded (i.e. the session file has been created). Returns false for sessions where the user quit without any conversation.

func (*Recorder) RecordAssistant

func (r *Recorder) RecordAssistant(content string)

RecordAssistant appends an assistant message entry.

func (*Recorder) RecordCompact

func (r *Recorder) RecordCompact(summary string, compactedN int)

RecordCompact appends a compact/summarization event entry.

func (*Recorder) RecordModeChange

func (r *Recorder) RecordModeChange(mode string)

RecordModeChange appends a mode transition entry.

func (*Recorder) RecordPlanUpdate

func (r *Recorder) RecordPlanUpdate(status, title, content, feedback string)

RecordPlanUpdate appends a plan state change entry.

func (*Recorder) RecordSubagentAsync

func (r *Recorder) RecordSubagentAsync(name, taskID, agentType string)

RecordSubagentAsync appends an async subagent launch entry with the task ID.

func (*Recorder) RecordSubagentResult

func (r *Recorder) RecordSubagentResult(name, output string, err error)

RecordSubagentResult appends a subagent completion entry.

func (*Recorder) RecordSubagentStart

func (r *Recorder) RecordSubagentStart(name, agentType string)

RecordSubagentStart appends a subagent launch entry.

func (*Recorder) RecordSystemPrompt added in v0.4.6

func (r *Recorder) RecordSystemPrompt(prompt, envInfo string)

RecordSystemPrompt buffers the system prompt so it can be written together with the first real message. This avoids creating a session file when the user opens and immediately closes jcode without any conversation.

func (*Recorder) RecordTodoSnapshot

func (r *Recorder) RecordTodoSnapshot(todos []TodoSnapshotItem)

RecordTodoSnapshot appends a full todo list snapshot entry.

func (*Recorder) RecordToolCall

func (r *Recorder) RecordToolCall(name, args, toolCallID string)

RecordToolCall appends a tool-call entry.

func (*Recorder) RecordToolResult

func (r *Recorder) RecordToolResult(name, output, toolCallID string, err error)

RecordToolResult appends a tool-result entry. Large outputs are automatically truncated (head+tail preserved) and the full content is saved to an overflow file on disk.

func (*Recorder) RecordUser

func (r *Recorder) RecordUser(content string, images ...EntryImage)

RecordUser appends a user message entry. On the first user message, the title is auto-generated from the content. Optional images are persisted alongside the text so they survive session restore.

func (*Recorder) SetUUID added in v0.3.3

func (r *Recorder) SetUUID(id string)

SetUUID overrides the session identifier. Used when resuming an existing session so that new messages are appended to the same session file. If the session file does not yet exist on disk, the recorder is NOT marked as resuming, so the first user message will still generate a title.

func (*Recorder) TruncateAtUserMessage added in v0.4.2

func (r *Recorder) TruncateAtUserMessage(beforeCount int) error

TruncateAtUserMessage rewrites the session file keeping only entries that appear before the (beforeCount)th user message (0-indexed). If beforeCount == 0, the file is truncated to the session_start header only. The recorder is reset to append mode on the (now shorter) file. This preserves the session UUID and index entry — no new session is created.

func (*Recorder) UUID

func (r *Recorder) UUID() string

UUID returns the session identifier.

type SessionMeta

type SessionMeta struct {
	UUID      string `json:"uuid"`
	Project   string `json:"project"`
	Provider  string `json:"provider"`
	Model     string `json:"model"`
	StartTime string `json:"start_time"` // RFC3339
	Title     string `json:"title,omitempty"`
}

SessionMeta is stored in the index for fast listing.

func ListSessions

func ListSessions(project string) ([]SessionMeta, error)

ListSessions returns all sessions recorded for a given project path, newest last.

type SessionState

type SessionState struct {
	History      []adk.Message
	Plan         *PlanSnapshot      // nil if no plan events found
	Todos        []TodoSnapshotItem // last todo snapshot, nil if none
	Mode         string             // last mode (normal/planning/executing), empty = normal
	EnvTarget    string             // last environment (local/ssh alias)
	SystemPrompt string             // recorded system prompt for KV-cache-friendly resume
	EnvInfo      string             // environment snapshot at recording time
}

SessionState is the full recoverable state from a session file, including conversation history, plan, todos, mode, and environment.

func ReconstructState

func ReconstructState(entries []Entry) *SessionState

ReconstructState rebuilds the full session state from recorded entries. It is compact-aware: if a compact entry is found, messages before it are replaced with the compact summary.

Subagent-internal entries are skipped (same logic as ReconstructHistory).

type TodoSnapshotItem

type TodoSnapshotItem struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Status string `json:"status"`
}

TodoSnapshotItem is a single todo entry stored in a todo_snapshot event.

Jump to

Keyboard shortcuts

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