7d60a1af85
- Updated documentation to reflect product name change from 'pi' to 'omp' throughout guides and API references. - Restructured extension and hook documentation to clarify discovery mechanisms, loading behavior, and configuration across multiple config systems (.omp, .pi, .claude, .codex). - Updated SDK API documentation with new method signatures: discoverHooks() -> discoverExtensions(), SessionManager methods now async, settings format changed to YAML. - Expanded session architecture documentation with new entry types (TtsrInjectionEntry, SessionInitEntry), updated field names (fromHook -> fromExtension), and clarified session file format versioning. - Simplified session-tree-plan.md from detailed implementation checklist to architecture summary, removing completed tasks and rollout details.
5.4 KiB
5.4 KiB
Session Tree Architecture (Current)
Reference: session.md, tree.md
This document summarizes the current session tree implementation and extension touchpoints. It replaces the historical rollout checklist.
Session file format (v3)
- JSONL file with a SessionHeader (version 3). Header is metadata only and does not participate in the tree.
- Every SessionEntry derives from SessionEntryBase:
id,parentId,timestamp. - Entries are append-only; branching only moves the leaf pointer.
- Entry types:
message,compaction,branch_summary,custom,custom_message,label,model_change,thinking_level_change,ttsr_injection,session_init.
SessionManager core
- Tracks
byId,labelsById,leafId, and usage statistics. - Tree APIs:
getLeafId(),getLeafEntry(),getEntry(id),getChildren(id)getBranch(fromId?)→ root-to-leaf pathgetTree()→SessionTreeNode { entry, children, label }getLabel(id)
buildSessionContext()walks from the current leaf and resolves compaction.custom_messageandbranch_summaryentries are converted to AgentMessage roles and later to user-role LLM messages viaconvertToLlm().- Appenders (all return entry id and advance the leaf):
appendMessage,appendCompaction,appendCustomEntry,appendCustomMessageEntry,appendLabelChange,appendModelChange,appendThinkingLevelChange,appendSessionInit,appendTtsrInjection. getSessionFile()returnsstring | undefinedfor in-memory sessions.flush()persists pending writes.
Migration
CURRENT_SESSION_VERSION = 3.- v1 → v2: assigns
id/parentIdand converts compactionfirstKeptEntryIndextofirstKeptEntryId. - v2 → v3: renames message role
hookMessage→custom. SessionManager.open()/setSessionFile()rewrite the file after migration.
Branching
branch(entryId)moves the leaf pointer to a prior entry.resetLeaf()sets the leaf tonullso the next append creates a new root entry.branchWithSummary(branchFromId, summary, details?, fromExtension?)appendsbranch_summaryand switches the leaf.createBranchedSession(leafId)writes a new session file containing the selected path;LabelEntryvalues are rebuilt from resolved labels. In-memory sessions replace their entries and returnundefined.
Compaction integration
CompactionEntry/CompactionResultare generic with optionaldetailsandpreserveData;firstKeptEntryIdis the compaction anchor.session_before_compactprovidesCompactionPreparation,branchEntries,customInstructions, andsignal.session.compactingallows overriding the compaction prompt/context.session_compactemits the finalCompactionEntryandfromExtensionflag.
Labels
LabelEntrystorestargetId+label;labelsByIdmaps targetId → label.appendLabelChange(targetId, label?)sets or clears labels.- Tree selector shows labels and supports the "labeled-only" filter. Press Shift+L in
/treeto edit the selected label.
Custom messages
CustomMessageEntrystorescustomType,content,display,details; converted to AgentMessage rolecustom.buildSessionContext()includescustom_messageentries;convertToLlm()maps them to user-role LLM messages.- TUI rendering:
display=falsehides the entry;display=trueusescustomMessageBg/customMessageText/customMessageLabeltheme tokens. - Extensions can override rendering via
registerMessageRenderer(customType, renderer).
Extension API touchpoints
sendMessage(...)appends aCustomMessageEntry. options:triggerTurn,deliverAs("steer" | "followUp" | "nextTurn").sendUserMessage(...)always triggers a turn with a real user message.appendEntry(customType, data)persists extension state (CustomEntry, not sent to the LLM).registerCommand(name, { description?, handler })registers/commands. Handlers returnvoid; trigger turns explicitly withsendMessage/sendUserMessage.ExtensionContextexposessessionManager(read-only),modelRegistry,model,getContextUsage(),compact(), and abort/idle helpers.ExtensionCommandContextaddswaitForIdle(),newSession(),branch(),navigateTree().
Agent context events
context: called before each LLM call withAgentMessage[]; returning{ messages }replaces the prompt messages for this call (not persisted).before_agent_start: fired after the user prompt but before the agent loop; event includesprompt,images, andsystemPrompt.- Result can add a
CustomMessageand/or replace thesystemPromptfor the turn. Multiple extensions can contribute messages;systemPromptupdates chain in order.
- Result can add a
Tree UI + commands
/tree: in-place navigation with search, filter modes (default/no-tools/user-only/labeled-only/all), labels, and active-path highlighting./branch: creates a new session file from the current path.- Tree navigation emits
session_before_treewithTreePreparation(targetId,oldLeafId,commonAncestorId,entriesToSummarize,userWantsSummary) andsession_treewithSessionTreeEvent(newLeafId,oldLeafId,summaryEntry?,fromExtension?).
HTML export
- Session HTML export includes a sidebar tree with search, the same filter modes as
/tree, and a responsive hamburger toggle. - URL parameters
leafId/targetIdallow deep-linking to a branch and specific entry.