chore(vendor): import pi 1.3.0
Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
@@ -2,13 +2,16 @@
|
||||
|
||||
Sessions are stored as JSONL (JSON Lines) files. Each line is a JSON object with a `type` field. Session entries form a tree structure via `id`/`parentId` fields, enabling in-place branching without creating new files.
|
||||
|
||||
For programmatic creation, persistence, and tree navigation, see the [`SessionManager` API](sdk.md#sessionmanager-api).
|
||||
|
||||
|
||||
## File Location
|
||||
|
||||
```
|
||||
~/.pi/agent/sessions/--<path>--/<timestamp>_<uuid>.jsonl
|
||||
~/.pi/agent/sessions/--<path>--/<timestamp>_<session-id>.jsonl
|
||||
```
|
||||
|
||||
Where `<path>` is the working directory with `/` replaced by `-`.
|
||||
By default, `<session-id>` is a UUID. Callers can supply a custom ID through the SDK or `--session-id`. For `<path>`, Pi removes the leading path separator and replaces `/`, `\\`, and `:` with `-`.
|
||||
|
||||
## Deleting Sessions
|
||||
|
||||
@@ -28,148 +31,20 @@ Existing sessions are automatically migrated to the current version (v3) when lo
|
||||
|
||||
## Source Files
|
||||
|
||||
Source on GitHub ([pi-mono](https://github.com/earendil-works/pi-mono)):
|
||||
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
|
||||
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
|
||||
- [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
|
||||
- [`packages/agent/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
|
||||
Source on GitHub ([pi](https://github.com/earendil-works/pi)):
|
||||
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
|
||||
- [Message Types](message-types.md) - Shared message and content-block reference
|
||||
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types
|
||||
- [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi/blob/main/packages/ai/src/types.ts) - Base message and content-block types
|
||||
- [`packages/agent/src/types.ts`](https://github.com/earendil-works/pi/blob/main/packages/agent/src/types.ts) - Extensible `AgentMessage` union
|
||||
|
||||
For TypeScript definitions in your project, inspect `node_modules/@earendil-works/pi-coding-agent/dist/` and `node_modules/@earendil-works/pi-ai/dist/`.
|
||||
|
||||
## Message Types
|
||||
## Messages
|
||||
|
||||
Session entries contain `AgentMessage` objects. Understanding these types is essential for parsing sessions and writing extensions.
|
||||
A `message` entry stores an [`AgentMessage`](message-types.md). Message content blocks, roles, usage, and message timestamps are defined in [Message Types](message-types.md).
|
||||
|
||||
### Content Blocks
|
||||
|
||||
Messages contain arrays of typed content blocks:
|
||||
|
||||
```typescript
|
||||
interface TextContent {
|
||||
type: "text";
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface ImageContent {
|
||||
type: "image";
|
||||
data: string; // base64 encoded
|
||||
mimeType: string; // e.g., "image/jpeg", "image/png"
|
||||
}
|
||||
|
||||
interface ThinkingContent {
|
||||
type: "thinking";
|
||||
thinking: string;
|
||||
}
|
||||
|
||||
interface ToolCall {
|
||||
type: "toolCall";
|
||||
id: string;
|
||||
name: string;
|
||||
arguments: Record<string, any>;
|
||||
}
|
||||
```
|
||||
|
||||
### Base Message Types (from pi-ai)
|
||||
|
||||
```typescript
|
||||
interface UserMessage {
|
||||
role: "user";
|
||||
content: string | (TextContent | ImageContent)[];
|
||||
timestamp: number; // Unix ms
|
||||
}
|
||||
|
||||
interface AssistantMessage {
|
||||
role: "assistant";
|
||||
content: (TextContent | ThinkingContent | ToolCall)[];
|
||||
api: string;
|
||||
provider: string;
|
||||
model: string;
|
||||
usage: Usage;
|
||||
stopReason: "stop" | "length" | "toolUse" | "error" | "aborted";
|
||||
errorMessage?: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface ToolResultMessage {
|
||||
role: "toolResult";
|
||||
toolCallId: string;
|
||||
toolName: string;
|
||||
content: (TextContent | ImageContent)[];
|
||||
details?: any; // Tool-specific metadata
|
||||
usage?: Usage; // Nested LLM work performed by the tool
|
||||
isError: boolean;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface Usage {
|
||||
input: number;
|
||||
output: number;
|
||||
cacheRead: number;
|
||||
cacheWrite: number;
|
||||
totalTokens: number;
|
||||
cost: {
|
||||
input: number;
|
||||
output: number;
|
||||
cacheRead: number;
|
||||
cacheWrite: number;
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The exported pi-ai `StopReason` type also includes `"pending"`, but that value is reserved for partial messages in streaming events. Terminal `done`/`error` messages replace it with a completion reason before pi persists the assistant message, so `"pending"` should never appear in session JSONL.
|
||||
|
||||
### Extended Message Types (from pi-coding-agent)
|
||||
|
||||
```typescript
|
||||
interface BashExecutionMessage {
|
||||
role: "bashExecution";
|
||||
command: string;
|
||||
output: string;
|
||||
exitCode: number | undefined;
|
||||
cancelled: boolean;
|
||||
truncated: boolean;
|
||||
fullOutputPath?: string;
|
||||
excludeFromContext?: boolean; // true for !! prefix commands
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface CustomMessage {
|
||||
role: "custom";
|
||||
customType: string; // Extension identifier
|
||||
content: string | (TextContent | ImageContent)[];
|
||||
display: boolean; // Show in TUI
|
||||
details?: any; // Extension-specific metadata
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface BranchSummaryMessage {
|
||||
role: "branchSummary";
|
||||
summary: string;
|
||||
fromId: string; // Entry we branched from
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface CompactionSummaryMessage {
|
||||
role: "compactionSummary";
|
||||
summary: string;
|
||||
tokensBefore: number;
|
||||
timestamp: number;
|
||||
}
|
||||
```
|
||||
|
||||
### AgentMessage Union
|
||||
|
||||
```typescript
|
||||
type AgentMessage =
|
||||
| UserMessage
|
||||
| AssistantMessage
|
||||
| ToolResultMessage
|
||||
| BashExecutionMessage
|
||||
| CustomMessage
|
||||
| BranchSummaryMessage
|
||||
| CompactionSummaryMessage;
|
||||
```
|
||||
Session entry timestamps are ISO 8601 strings. The nested message timestamp is a Unix timestamp in milliseconds.
|
||||
|
||||
## Entry Base
|
||||
|
||||
@@ -178,8 +53,8 @@ All entries (except `SessionHeader`) extend `SessionEntryBase`:
|
||||
```typescript
|
||||
interface SessionEntryBase {
|
||||
type: string;
|
||||
id: string; // 8-char hex ID
|
||||
parentId: string | null; // Parent entry ID (null for first entry)
|
||||
id: string; // Usually an 8-char hex ID; may fall back to a full UUID
|
||||
parentId: string | null; // Parent entry ID (null for a root entry)
|
||||
timestamp: string; // ISO timestamp
|
||||
}
|
||||
```
|
||||
@@ -202,17 +77,26 @@ For sessions with a parent (created via `/fork`, `/clone`, or `newSession({ pare
|
||||
|
||||
### SessionMessageEntry
|
||||
|
||||
A message in the conversation. The `message` field contains an `AgentMessage`.
|
||||
A message in the conversation. The `message` field contains an `AgentMessage`. System messages carry the prompt and tool loadout: the first request of a session persists one with every prompt section and tool declaration, and later changes persist as system messages that patch `sections` by name (`null` removes one) and list `toolsAdded`/`toolsRemoved`. Replaying them in order yields the current prompt and tools; there is no separate prompt state entry.
|
||||
|
||||
```json
|
||||
{"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello"}}
|
||||
{"type":"message","id":"b2c3d4e5","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:00:02.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}],"provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop"}}
|
||||
{"type":"message","id":"c3d4e5f6","parentId":"b2c3d4e5","timestamp":"2024-12-03T14:00:03.000Z","message":{"role":"toolResult","toolCallId":"call_123","toolName":"bash","content":[{"type":"text","text":"output"}],"isError":false}}
|
||||
{"type":"message","id":"a0b1c2d3","parentId":null,"timestamp":"2024-12-03T14:00:00.000Z","message":{"role":"system","content":"","sections":{"preamble":"You are an expert coding assistant...","tools":"<tools>\n- read: ...\n</tools>","cwd":"/project"},"toolsAdded":[{"name":"read","description":"...","parameters":{}}],"timestamp":1733234400000}}
|
||||
{"type":"message","id":"d4e5f6g7","parentId":"c3d4e5f6","timestamp":"2024-12-03T14:04:00.000Z","message":{"role":"system","content":"","sections":{"skills":"<skills>...</skills>"},"toolsRemoved":[{"name":"write"}],"timestamp":1733234640000}}
|
||||
```
|
||||
|
||||
Sessions created before system messages existed have no leading system message; the first request declares the current prompt as a later system message, which replays the same way.
|
||||
|
||||
```json
|
||||
{"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello","timestamp":1733234401000}}
|
||||
{"type":"message","id":"b2c3d4e5","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:00:02.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}],"api":"anthropic-messages","provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop","timestamp":1733234402000}}
|
||||
{"type":"message","id":"c3d4e5f6","parentId":"b2c3d4e5","timestamp":"2024-12-03T14:00:03.000Z","message":{"role":"toolResult","toolCallId":"call_123","toolName":"bash","content":[{"type":"text","text":"output"}],"isError":false,"timestamp":1733234403000}}
|
||||
```
|
||||
|
||||
Assistant messages name the model that produced them. Newer messages also record `thinkingLevel`, the Pi thinking level requested for that response.
|
||||
|
||||
### ModelChangeEntry
|
||||
|
||||
Emitted when the user switches models mid-session.
|
||||
Emitted when the user switches models mid-session. The latest entry is the selected model, which may be a [virtual model](virtual-models.md); assistant messages then name the physical model that answered.
|
||||
|
||||
```json
|
||||
{"type":"model_change","id":"d4e5f6g7","parentId":"c3d4e5f6","timestamp":"2024-12-03T14:05:00.000Z","provider":"openai","modelId":"gpt-4o"}
|
||||
@@ -226,26 +110,41 @@ Emitted when the user changes the thinking/reasoning level.
|
||||
{"type":"thinking_level_change","id":"e5f6g7h8","parentId":"d4e5f6g7","timestamp":"2024-12-03T14:06:00.000Z","thinkingLevel":"high"}
|
||||
```
|
||||
|
||||
### UsageEntry
|
||||
|
||||
Records model-attributed usage that is not an assistant message and does not participate in LLM context. `kind` is an arbitrary string identifying the operation; for example, cache warming uses `"cache_warm"`.
|
||||
|
||||
```json
|
||||
{"type":"usage","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:08:00.000Z","kind":"cache_warm","provider":"anthropic","model":"claude-sonnet-4-5","usage":{"input":0,"output":0,"cacheRead":50000,"cacheWrite":0,"totalTokens":50000,"cost":{"input":0,"output":0,"cacheRead":0.015,"cacheWrite":0,"total":0.015}}}
|
||||
```
|
||||
|
||||
Usage entries contribute to session token and cost totals. Pi hides them from the conversation tree. Consumers should treat unknown `kind` values as normal usage rather than rejecting them.
|
||||
|
||||
### CompactionEntry
|
||||
|
||||
Created when context is compacted. Stores a summary of earlier messages.
|
||||
Created when context is compacted. Stores a summary of earlier messages and a complete system prompt/tool checkpoint.
|
||||
|
||||
```json
|
||||
{"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","firstKeptEntryId":"c3d4e5f6","tokensBefore":50000}
|
||||
{"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","firstKeptEntryId":"c3d4e5f6","tokensBefore":50000,"systemMessage":{"role":"system","content":"You are a coding assistant.","toolsAdded":[],"timestamp":1733235000000}}
|
||||
```
|
||||
|
||||
Newer harness-generated compactions embed the retained post-compaction context directly on the entry, instead of `firstKeptEntryId`:
|
||||
|
||||
```json
|
||||
{"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","tokensBefore":50000,"retainedTail":[{"role":"user","content":"latest request"},{"role":"assistant","content":[{"type":"text","text":"latest reply"}],"provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop"}]}
|
||||
```
|
||||
`firstKeptEntryId` is required. It identifies the first entry retained from before the compaction entry. When rebuilding context, Pi replaces older summarized entries with the compaction summary and keeps the range beginning at this entry. A retain-none compaction stores its own ID in this field, so no preceding entries are retained.
|
||||
|
||||
Optional fields:
|
||||
- `systemMessage`: The replayed prompt sections and tool declarations at the compaction boundary; it becomes the leading system message of the compacted context, and system messages among the kept entries are dropped in its favor. It is absent on older session entries.
|
||||
- `usage`: LLM usage from generating the summary; included in session token and cost totals
|
||||
- `retainedTail`: Materialized `AgentMessage[]` kept after compaction. This is optional only for backward compatibility with older sessions. Newer harness-generated compactions include it so we can rebuild context from this checkpoint without walking older entries before the compaction entry.
|
||||
- `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
|
||||
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
|
||||
- `firstKeptEntryId`: for compatibility with old entry format.
|
||||
|
||||
### ContextEditEntry
|
||||
|
||||
Append-only edit of one earlier context-producing entry. It changes only future model context; the target entry and its metadata remain unchanged in raw history, UI, exports, and session accounting.
|
||||
|
||||
```json
|
||||
{"type":"context_edit","id":"g6h7i8j9","parentId":"f6g7h8i9","timestamp":"2024-12-03T14:11:00.000Z","targetId":"c3d4e5f6","replacement":null}
|
||||
```
|
||||
|
||||
Targets may be user, assistant, tool-result, or custom-message entries. `replacement: null` omits the target from model context. A non-null `replacement` replaces only the target message content. String replacements for assistant and tool-result entries are normalized to one text block because those roles require content arrays. If several edits target the same entry, the latest edit on the active branch wins. Edits are branch-relative: navigating to a point before the edit reveals the target's original contribution again.
|
||||
|
||||
### BranchSummaryEntry
|
||||
|
||||
@@ -255,6 +154,8 @@ Created when switching branches via `/tree` with an LLM generated summary of the
|
||||
{"type":"branch_summary","id":"g7h8i9j0","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:15:00.000Z","fromId":"f6g7h8i9","summary":"Branch explored approach A..."}
|
||||
```
|
||||
|
||||
`parentId` is the entry from which the new branch continues. `fromId` is the previous leaf whose abandoned path was summarized.
|
||||
|
||||
Optional fields:
|
||||
- `usage`: LLM usage from generating the summary; included in session token and cost totals
|
||||
- `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
|
||||
@@ -270,6 +171,8 @@ Extension state persistence. Does NOT participate in LLM context.
|
||||
|
||||
Use `customType` to identify your extension's entries on reload. Interactive mode can render custom entries via `pi.registerEntryRenderer(customType, renderer)`, but they still do not participate in LLM context.
|
||||
|
||||
Pi stores [virtual model](virtual-models.md) router state as custom entries with `customType` `pi.virtual-model-state` and `data` `{ provider, modelId, state }`.
|
||||
|
||||
### CustomMessageEntry
|
||||
|
||||
Extension-injected messages that DO participate in LLM context.
|
||||
@@ -305,11 +208,12 @@ The session name is displayed in the session selector (`/resume`) instead of the
|
||||
|
||||
## Tree Structure
|
||||
|
||||
Entries form a tree:
|
||||
- First entry has `parentId: null`
|
||||
- Each subsequent entry points to its parent via `parentId`
|
||||
Entries normally form one tree, but navigation APIs can create multiple roots:
|
||||
- A root entry has `parentId: null`; the first entry is initially the root
|
||||
- Each non-root entry points to its parent via `parentId`
|
||||
- Branching creates new children from an earlier entry
|
||||
- The "leaf" is the current position in the tree
|
||||
- Calling `resetLeaf()` or `branchWithSummary(null, ...)` allows a later entry to become another root
|
||||
|
||||
```
|
||||
[user msg] ─── [assistant] ─── [user msg] ─── [assistant] ─┬─ [user msg] ← current leaf
|
||||
@@ -322,24 +226,26 @@ Entries form a tree:
|
||||
`buildContextEntries()` walks from the current leaf to the root, producing the active entry list while honoring compaction:
|
||||
|
||||
1. Collects all entries on the path
|
||||
2. If a `CompactionEntry` is on the path:
|
||||
2. If one or more `CompactionEntry` values are on the path, uses the latest one:
|
||||
- Includes the compaction entry first
|
||||
- If `retainedTail` is present, it acts as a self-contained checkpoint and entries after the compaction are included
|
||||
- Otherwise entries from `firstKeptEntryId` to the compaction are included
|
||||
- Then entries after compaction are included
|
||||
- Includes non-system entries from `firstKeptEntryId` up to, but not including, the compaction entry
|
||||
- Includes entries after the compaction entry
|
||||
3. Preserves non-message entries in the selected range so interactive mode can render them
|
||||
|
||||
`buildSessionContext()` builds on that entry list to produce the message list for the LLM:
|
||||
`buildSessionProjection()` then applies the latest `context_edit` for each selected target. It returns the model-visible messages together with their source entries. Omitted targets produce no message; replacements retain the source entry's role and metadata while changing only content. The raw selected entries are not modified.
|
||||
|
||||
`buildSessionContext()` builds on that projection to produce the message list for the LLM:
|
||||
|
||||
1. Extracts current model and thinking level settings from the full path
|
||||
2. Converts selected entries to messages:
|
||||
- `message` -> stored `AgentMessage`
|
||||
- `compaction` -> `compactionSummary` plus `retainedTail` when present
|
||||
- `compaction` -> complete system checkpoint followed by `compactionSummary`
|
||||
- `branch_summary` -> `branchSummary`
|
||||
- `custom_message` -> `CustomMessage`
|
||||
- `custom` -> no context message
|
||||
- `context_edit` -> no context message of its own
|
||||
- `usage` and `custom` -> no context message
|
||||
|
||||
This makes newer compactions act like self-contained checkpoints. `retainedTail` is optional only so older sessions that only store `firstKeptEntryId` continue to load correctly.
|
||||
The compaction summary replaces entries before `firstKeptEntryId`. Pre-compaction system messages are folded into the complete checkpoint rather than replayed from the retained range. Retained non-system entries and all entries after the compaction remain available to the LLM.
|
||||
|
||||
## Parsing Example
|
||||
|
||||
@@ -364,6 +270,9 @@ for (const line of lines) {
|
||||
case "branch_summary":
|
||||
console.log(`[${entry.id}] Branch from ${entry.fromId}`);
|
||||
break;
|
||||
case "usage":
|
||||
console.log(`[${entry.id}] Usage (${entry.kind}): ${entry.usage.totalTokens} tokens`);
|
||||
break;
|
||||
case "custom":
|
||||
console.log(`[${entry.id}] Custom (${entry.customType}): ${JSON.stringify(entry.data)}`);
|
||||
break;
|
||||
@@ -382,57 +291,3 @@ for (const line of lines) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SessionManager API
|
||||
|
||||
Key methods for working with sessions programmatically.
|
||||
|
||||
### Static Creation Methods
|
||||
- `SessionManager.create(cwd, sessionDir?)` - New session
|
||||
- `SessionManager.open(path, sessionDir?)` - Open existing session file
|
||||
- `SessionManager.continueRecent(cwd, sessionDir?)` - Continue most recent or create new
|
||||
- `SessionManager.inMemory(cwd?)` - No file persistence
|
||||
- `SessionManager.forkFrom(sourcePath, targetCwd, sessionDir?)` - Fork session from another project
|
||||
|
||||
### Static Listing Methods
|
||||
- `SessionManager.list(cwd, sessionDir?, onProgress?)` - List sessions for a directory
|
||||
- `SessionManager.listAll(onProgress?)` - List all sessions across all projects
|
||||
|
||||
### Instance Methods - Session Management
|
||||
- `newSession(options?)` - Start a new session (options: `{ parentSession?: string }`)
|
||||
- `setSessionFile(path)` - Switch to a different session file
|
||||
- `createBranchedSession(leafId)` - Extract branch to new session file
|
||||
|
||||
### Instance Methods - Appending (all return entry ID)
|
||||
- `appendMessage(message)` - Add message
|
||||
- `appendThinkingLevelChange(level)` - Record thinking change
|
||||
- `appendModelChange(provider, modelId)` - Record model change
|
||||
- `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?, fromHook?)` - Add compaction
|
||||
- `appendCustomEntry(customType, data?)` - Extension state (not in context)
|
||||
- `appendSessionInfo(name)` - Set session display name
|
||||
- `appendCustomMessageEntry(customType, content, display, details?)` - Extension message (in context)
|
||||
- `appendLabelChange(targetId, label)` - Set/clear label
|
||||
|
||||
### Instance Methods - Tree Navigation
|
||||
- `getLeafId()` - Current position
|
||||
- `getLeafEntry()` - Get current leaf entry
|
||||
- `getEntry(id)` - Get entry by ID
|
||||
- `getBranch(fromId?)` - Walk from entry to root
|
||||
- `getTree()` - Get full tree structure
|
||||
- `getChildren(parentId)` - Get direct children
|
||||
- `getLabel(id)` - Get label for entry
|
||||
- `branch(entryId)` - Move leaf to earlier entry
|
||||
- `resetLeaf()` - Reset leaf to null (before any entries)
|
||||
- `branchWithSummary(entryId, summary, details?, fromHook?)` - Branch with context summary
|
||||
|
||||
### Instance Methods - Context & Info
|
||||
- `buildContextEntries()` - Get active branch entries with compaction applied
|
||||
- `buildSessionContext()` - Get messages, thinkingLevel, and model for LLM
|
||||
- `getEntries()` - All entries (excluding header)
|
||||
- `getHeader()` - Session header metadata
|
||||
- `getSessionName()` - Get display name from latest session_info entry
|
||||
- `getCwd()` - Working directory
|
||||
- `getSessionDir()` - Session storage directory
|
||||
- `getSessionId()` - Session UUID
|
||||
- `getSessionFile()` - Session file path (undefined for in-memory)
|
||||
- `isPersisted()` - Whether session is saved to disk
|
||||
|
||||
Reference in New Issue
Block a user