Documentation
¶
Overview ¶
Package pijsonl provides shared parsing primitives for Pi's session JSONL format. It is consumed both by the in-tree pi agent (cmd/trace/cli/agent/pi) and by the v2 compact-transcript dispatcher (cmd/trace/cli/transcript/compact). Keeping these in one place ensures active-branch resolution, line counting, and offset slicing stay byte- compatible across both call sites.
Index ¶
Constants ¶
const ( RoleUser = "user" RoleAssistant = "assistant" RoleToolResult = "toolResult" )
Role values present on Message.Role.
const ContentTypeText = "text"
ContentTypeText is the content-block `type` value for text blocks.
const EntryTypeMessage = "message"
EntryTypeMessage is the JSONL `type` value for conversational entries.
const MaxScannerLine = 10 * 1024 * 1024
MaxScannerLine is the maximum size of a single JSONL line we will parse. Pi tool calls can embed full file contents in arguments — 10 MB matches what other in-tree transcript scanners use (codex, copilot, droid).
Variables ¶
This section is empty.
Functions ¶
func CountLines ¶
CountLines returns the number of newline-terminated (or final unterminated) lines in data, including blank lines. Matches the offset semantics used by SkipLines and the compact-format StartLine.
func DecodeStringContent ¶
func DecodeStringContent(raw json.RawMessage) string
DecodeStringContent returns the raw string when content is a plain string, or "" when it's a JSON array (caller should decode as []ContentItem).
func NewScanner ¶
NewScanner returns a bufio.Scanner pre-configured with the Pi line-size limit.
func ResolveActiveBranch ¶
ResolveActiveBranch walks a Pi transcript tree and returns the set of entry IDs on the active conversation branch (root → most-recent message).
Pi sessions form a tree: every entry has id and parentId. When the user /forks or /clones mid-conversation, the JSONL file accumulates entries from BOTH branches. Without filtering, downstream analysis double-counts tokens, files, and prompts.
IMPORTANT: callers must pass FULL transcript bytes, not bytes already truncated by SkipLines. Resolving over a truncated buffer yields a disconnected tree where parentId pointers no longer reach the root, causing abandoned-branch entries to leak in.
Returns nil when the transcript has no tree structure (every entry has no parent or all entries are linear) — callers should treat nil as "all entries are on the active branch".
Types ¶
type ContentItem ¶
type ContentItem struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
Arguments json.RawMessage `json:"arguments,omitempty"`
}
ContentItem is one element of a Pi message's content array.
type Entry ¶
type Entry struct {
Type string `json:"type"`
ID string `json:"id"`
Timestamp string `json:"timestamp"`
Message Message `json:"message"`
}
Entry is the outer shell of one Pi JSONL line.
type Message ¶
type Message struct {
Role string `json:"role"`
Content json.RawMessage `json:"content"`
Usage *Usage `json:"usage,omitempty"`
StopReason string `json:"stopReason,omitempty"`
ToolCallID string `json:"toolCallId,omitempty"`
ToolName string `json:"toolName,omitempty"`
IsError bool `json:"isError,omitempty"`
}
Message is the inner Pi `message` object on entries with type=="message".