How the Kimi Code Session Management System Works: A Three-Layer Architecture

The Kimi Code session management system implements a robust three-layer architecture separating filesystem persistence, RPC service logic, and protocol definitions to enable atomic session operations, real-time status tracking, and consistent cross-platform behavior across the MoonshotAI/kimi-code repository.

The session management system in MoonshotAI/kimi-code coordinates complex AI agent interactions through a sophisticated design that spans on-disk storage, real-time event streaming, and workspace isolation. This architecture ensures that sessions remain consistent across multiple front-ends including the CLI, web UI, and VS Code extension, while providing atomic operations for creation, forking, and archival.

Three-Layer Architecture Overview

The system organizes functionality into three tightly coupled layers:

Layer Responsibility Core Files
Persistence Stores sessions on disk, maintains a global index, and handles creation, forking, renaming, archiving, and deletion. packages/agent-core/src/session/store/session-store.ts
Service Exposes a high-level RPC-style API used by the engine, translates RPC calls into persistence actions, and publishes status events. packages/agent-core/src/services/session/sessionService.ts
Protocol Defines the wire-format types (Session, SessionSummary, SessionUpdate, etc.) that client SDKs and servers exchange. packages/protocol/src/session.ts

Session Persistence Layer (SessionStore)

The persistence layer implements durable storage through the SessionStore class in packages/agent-core/src/session/store/session-store.ts.

Directory Layout and Workspace Buckets

All sessions live under the path <home>/sessions/<bucket>/<session-id>/. The workspace bucket derives from a hash of the normalized workDir computed by encodeWorkDirKey, unless a workspace registry resolves the physical root to a predefined workspace ID. This design prevents duplicate buckets on case-variant Windows paths by canonicalizing directory strings before hashing.

The Append-Only Index

Session lookup relies on an append-only index stored at sessions/index.jsonl, which contains SessionIndexEntry records mapping session IDs to their directories and work-directories. The index enables fast lookups without filesystem scanning and can be rebuilt via SessionStore.reindex() if corrupted, which scans the filesystem, recovers work-dirs from each state.json, and repairs missing entries without overwriting valid data.

Atomic Operations and Error Handling

Core operations—including create, fork, rename, archive, delete, and list—manipulate both the index and on-disk files atomically. Each session directory contains a state.json for metadata and wire.jsonl for recorded agent events. Failures such as "session already exists" or "invalid title" raise strongly-typed KimiError instances with appropriate ErrorCodes.

Forking Sessions

The SessionStore.fork() method implements session branching by copying the source directory, optionally truncating history at a specific turn, dropping unneeded files like upcoming-goals.json, and updating state.json with fork metadata including forkedFrom and timestamps. Forking also appends a "forked" record to each agent's wire.jsonl to maintain audit trails.

Session Service Layer (SessionService)

The service layer acts as the bridge between RPC surface and persistence, implemented in packages/agent-core/src/services/session/sessionService.ts.

Event-Driven Status Management

SessionService maintains per-session work facts (busy, main_turn_active, pending_interaction, last_turn_reason) by listening to bus events such as turn.started, turn.ended, prompt.submitted, and event.approval.requested. These facts are recomputed via _computeWorkFacts and published as event.session.work_changed events through the IEventService defined in packages/agent-core/src/services/event/event.ts.

CRUD Operations and RPC Integration

Public methods including create, list, get, update, fork, createChild, and archive forward to the core RPC service (this.core.rpc.*). After each mutation, _patchSessionStatus augments the protocol session with live facts before emitting creation events. The service throws strongly-typed errors like SessionNotFoundError and SessionUndoUnavailableError to client SDKs.

Undo and Compaction Support

The undo method validates user input history via canUndoHistory before issuing undoHistory on the core RPC. The compact operation triggers beginCompaction after resuming the session in memory, allowing the system to condense event logs while preserving semantic state.

Protocol Layer and Type Definitions

The protocol layer defined in packages/protocol/src/session.ts establishes the contract between clients and server.

Core Session Types

Key types include:

  • Session – The full session object exposed to UIs, containing id, title, busy, main_turn_active, and metadata.
  • SessionSummary – Lightweight records for listing sessions, containing timestamps, archived flags, and optional lastPrompt.
  • SessionCreate, SessionUpdate, SessionFork – Input shapes accepted by the service layer for mutations.

Wire Format Stability

These TypeScript definitions ensure a stable contract across the TUI, web UI, VS Code extension, and Node SDK, preventing breaking changes in serialized session data.

Event Flow and Real-Time Updates

Session changes propagate through a four-stage pipeline:

  1. Client requests arrive at REST/WebSocket endpoints (/api/v1/sessions) and route to SessionService methods.
  2. Service updates SessionStore or calls core RPC, triggering disk mutations and index updates.
  3. Service patches sessions with live facts via _computeWorkFacts and fires event.session.created or event.session.work_changed.
  4. UI components subscribe via IEventService and refresh session lists, status badges, or transcript views.

Integration with Subsystems

Session management interacts with several supporting services:

  • Workspace Registry – Located in packages/agent-core/src/session/store/workdir-key.ts, provides resolveWorkspaceId to map workDir to stable buckets and handle Windows path canonicalization.
  • Prompt Service – Supplies current prompt IDs to determine mainTurnActive status.
  • Approval and Question Services – Contribute to the busy flag by exposing pending user interactions.

Working with the Session API

The following examples demonstrate common operations using the Node SDK.

Creating a new session:

import { Klient } from '@moonshot-ai/klient';

async function newSession() {
  const client = new Klient({ baseUrl: 'http://localhost:58627' });
  const session = await client.global.sessions.create({
    metadata: { cwd: '/home/alice/project' },
    title: 'Exploring Kimi',
  });
  console.log('Created session:', session.id);
}

Forking a session at turn 2:

const forked = await client.global.sessions.fork('session-abc123', {
  title: 'Fork of Exploration',
  turnIndex: 2,                     // truncate after the 2nd user turn
});
console.log('Forked session ID:', forked.id);

Listing non-archived sessions:

const list = await client.global.sessions.list({
  workspaceId: 'workspace-my-repo',
  excludeEmpty: true,
});
list.items.forEach(s => console.log(`${s.title} (${s.id})`));

Subscribing to status changes via WebSocket:

const ws = new WebSocket('ws://localhost:58627/api/v1/ws');
ws.onmessage = ev => {
  const event = JSON.parse(ev.data);
  if (event.type === 'event.session.work_changed') {
    console.log(`Session ${event.sessionId} busy=${event.busy}`);
  }
};

Summary

  • Three-layer design separates filesystem persistence (SessionStore), RPC service logic (SessionService), and protocol types (@moonshot-ai/protocol).
  • Atomic storage uses workspace buckets, an append-only index at sessions/index.jsonl, and per-session state.json and wire.jsonl files.
  • Real-time status propagates via event-driven work facts and the event.session.work_changed event.
  • Robust forking copies directories, truncates history, and maintains audit trails in wire.jsonl.
  • Cross-platform safety relies on workspace registry canonicalization in workdir-key.ts to handle case-sensitivity issues.

Frequently Asked Questions

How does Kimi Code store session data on disk?

Sessions are stored under <home>/sessions/<bucket>/<session-id>/ as defined in packages/agent-core/src/session/store/session-store.ts. Each session contains a state.json file for metadata and a wire.jsonl file for recorded agent events, organized into workspace buckets derived from normalized directory paths.

What happens when I fork a session in Kimi Code?

The SessionStore.fork() method copies the source directory to a new location, optionally truncates the history at a specified turn index, removes temporary files like upcoming-goals.json, updates state.json with forkedFrom metadata, and appends a fork record to wire.jsonl to preserve the audit trail.

How does the session service track real-time activity status?

SessionService computes work facts (busy, main_turn_active, pending_interaction) by listening to internal bus events such as turn.started and prompt.submitted. It publishes these status changes via event.session.work_changed through the event bus defined in packages/agent-core/src/services/event/event.ts, allowing UI components to react instantly.

Can session data be recovered if the index becomes corrupted?

Yes. The SessionStore.reindex() method scans the filesystem, recovers work-directories from each session's state.json, and reconstructs the append-only index at sessions/index.jsonl without overwriting existing valid data, effectively repairing the catalog while preserving session integrity.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →