# Prime Agent Session JSONL Format: Structure, Schema, and Parsing Guide

> Understand the Prime Agent session JSONL format. Learn its structure, schema, and how to parse it programmatically for your AI projects. Get started today.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: api-reference
- Published: 2026-08-10

---

**Prime Agent stores each chat session as a JSON Lines (JSONL) file where the first line contains a session header with metadata and all subsequent lines form a branching tree structure via `id` and `parentId` fields.**

The Prime Agent codebase (PrimeIntellect-ai/prime-agent) persists conversation history using a custom JSONL specification defined in [`packages/coding-agent/docs/session-format.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/docs/session-format.md) and implemented in [`src/core/session-manager.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/src/core/session-manager.ts). This format enables non-linear conversation branching without creating duplicate files, versioning support for schema migrations, and efficient append-only writes.

## Understanding the JSONL Structure

Each `.jsonl` session file consists of newline-delimited JSON objects. The structure separates static metadata from dynamic conversation entries that form a directed acyclic graph.

### Session Header (First Line)

The first line of every session file is a **SessionHeader** object containing file-level metadata. This header is not part of the entry tree and establishes the session context.

```json
{"type":"session","version":3,"id":"uuid","timestamp":"2024-12-03T14:00:00.000Z","cwd":"/path/to/project"}

```

Key fields include:
- **type**: Always `"session"` for the header
- **version**: Schema version (currently **v3**), enabling automatic migration of older files
- **id**: Unique session UUID
- **cwd**: Working directory at session creation
- **parentSession**: Optional UUID referencing a parent session for forked conversations

### Entry Types and Tree Structure

All subsequent lines are entries that form a **tree** via `id` and `parentId` fields. The leaf node (entry with no children) represents the current conversation position.

Common entry types defined in [`src/core/messages.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/src/core/messages.ts) include:

- **SessionMessageEntry**: Contains actual conversation content (`user`, `assistant`, `tool_result` messages)
- **ModelChangeEntry**: Records model/provider switches during the session
- **ThinkingLevelChangeEntry**: Tracks reasoning depth adjustments
- **CompactionEntry**, **BranchSummaryEntry**: Bookkeeping entries for context management
- **CustomEntry**, **LabelEntry**: User-defined metadata

Each entry shares these core fields:
- **id**: Unique entry identifier
- **parentId**: Reference to the previous entry's `id`, enabling branching
- **timestamp**: ISO 8601 timestamp
- **type**: Discriminator for the entry variant

## Parsing Sessions Programmatically

You can read Prime Agent session files using standard JSONL parsing techniques or the official TypeScript API.

### Manual Parsing with TypeScript

For external tooling or analysis scripts, parse the file using Node.js built-in modules. This approach mirrors the internal implementation in [`src/core/session-manager.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/src/core/session-manager.ts):

```typescript
import { readFileSync } from "fs";

const SESSION_PATH = "/home/you/.prime/agent/sessions/2024-12-03T14-00-00-uuid.jsonl";

const lines = readFileSync(SESSION_PATH, "utf8").trim().split("\n");

type SessionEntry =
  | { type: "session"; version: number; id: string; timestamp: string; cwd: string; parentSession?: string }
  | { type: "message"; id: string; parentId: string; timestamp: string; message: any }
  | { type: "model_change"; id: string; parentId: string; timestamp: string; provider: string; modelId: string }
  | { type: string; [key: string]: any };

for (const line of lines) {
  const entry: SessionEntry = JSON.parse(line);

  switch (entry.type) {
    case "session":
      console.log(`Session v${entry.version} – cwd: ${entry.cwd}`);
      break;
    case "message":
      console.log(`[${entry.id}] ${entry.message.role}: ${entry.message.content}`);
      break;
    case "model_change":
      console.log(`Model switched to ${entry.provider}/${entry.modelId}`);
      break;
    default:
      console.log(`${entry.type} entry (id=${entry.id})`);
  }
}

```

This implementation:
1. Reads the entire file as UTF-8
2. Splits on newlines to separate JSON objects
3. Parses each line independently
4. Dispatches handling based on the `type` field

### Using the SessionManager API

For plugins or extensions developed against the Prime Agent SDK, use the higher-level `SessionManager` class to handle versioning, tree reconstruction, and context building automatically:

```typescript
import { SessionManager } from "@earendil-works/pi-coding-agent";

async function analyzeSessions() {
  const sessions = await SessionManager.list(process.cwd());

  for (const sess of sessions) {
    const header = sess.getHeader();
    const leafId = sess.getLeafId();
    const context = await sess.buildSessionContext();

    console.log(`${header.id} – ${header.cwd}`);
    console.log(`Current leaf: ${leafId}`);
    console.log(`${context.messages.length} messages in LLM context`);
  }
}

```

The `SessionManager` API in [`src/core/session-manager.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/src/core/session-manager.ts) provides methods for:
- **Creating and opening** sessions with automatic version migration
- **Listing** sessions by working directory
- **Navigating** the entry tree and identifying leaf nodes
- **Building context** by traversing from root to current leaf for LLM prompts

## Summary

- **Prime Agent session JSONL format** stores each session as a line-delimited JSON file with a header followed by tree-structured entries
- **File locations**: Schema documentation resides in [`packages/coding-agent/docs/session-format.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/docs/session-format.md), while implementation logic is in [`src/core/session-manager.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/src/core/session-manager.ts) and type definitions in [`src/core/messages.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/src/core/messages.ts)
- **Tree structure** is implemented via `id` and `parentId` fields on every entry, supporting non-linear conversation branching
- **Current version** is v3, with automatic migration support for legacy files
- **Parsing options** include manual line-by-line JSON parsing for external tools or the official `SessionManager` API for integrated extensions

## Frequently Asked Questions

### How does Prime Agent handle conversation branching in the JSONL file?

Prime Agent implements branching through the `parentId` field on entries. When creating a branch, new entries reference an earlier entry's `id` as their `parentId`, forming a tree structure. The leaf node (the entry with no children) represents the current conversation state. This design allows multiple conversation branches to coexist in a single append-only file without duplication.

### What is the difference between a SessionHeader and SessionMessageEntry?

The **SessionHeader** appears only as the first line and stores static metadata like the session UUID, version, working directory, and optional parent session reference. It does not participate in the entry tree. A **SessionMessageEntry** contains actual conversation content (user messages, assistant responses, tool results) and includes both `id` and `parentId` fields to position itself within the conversation tree.

### Can I parse Prime Agent session files without installing the full SDK?

Yes, the JSONL format is plain text and requires no special libraries. You can parse sessions using standard JSON parsing in any programming language. Read the file, split by newlines, and parse each line as independent JSON. However, using the official `SessionManager` API (from `@earendil-works/pi-coding-agent`) handles schema versioning automatically and reconstructs the entry tree for you.

### What entry types should I handle when building custom tools?

At minimum, handle `"session"` (the header), `"message"` (conversation content), and `"model_change"` (model switches). Other entry types like `"thinking_level_change"`, `"compaction"`, `"branch_summary"`, and `"custom_message"` may be relevant depending on your use case. The format is extensible, so implement a default case for unknown types to ensure forward compatibility.