Understanding the Transcript Layers (L0-L4) Architecture in Kimi Code

Kimi Code models conversation history as a deterministic five-layer stack (L0-L4) that strictly separates wire contracts, immutable state storage, operational mutations, transport granularity, and UI rendering to guarantee perfect server-client synchronization.

Kimi Code, the AI coding assistant by MoonshotAI, manages conversation state through a sophisticated transcript layers (L0-L4) architecture that treats chat history as a convergent data structure. This design enables identical deterministic logic to execute on both server and client while maintaining strict separation between data contracts, state management, and presentation concerns.

Layer 0 (L0): Vendor Contracts and Wire Formats

L0 defines the foundational vendor contracts—pure wire-format data structures shared between LLM providers, tool APIs, and internal services. These files contain strictly no business logic, only TypeScript interfaces and type definitions that ensure interoperability.

According to the source code comments in packages/agent-core-v2/src/kosong/protocol/protocol.ts, the L0 contracts reside in the kosong package under packages/kosong/contract/. Key files include provider.ts, message.ts, and protocol.ts, which define provider-agnostic schemas for messages, tool calls, and usage statistics that never leak implementation details to upper layers.

Layer 1 (L1): The Convergent Store

At the heart of the architecture sits the convergent store, implemented by the AgentTranscript class in packages/transcript/src/store/agentTranscript.ts. This layer serves as the single source of truth for an agent's conversation history, maintaining immutable snapshots of turns, tasks, and interactions.

The store accepts incoming operations and applies them to produce new state, emitting TranscriptChangeEvent instances whenever mutations occur. Because the store holds immutable snapshots, every state change generates a new consistent view of the transcript without modifying previous references, enabling time-travel debugging and optimistic UI patterns.

Layer 2 (L2): Operation Vocabulary and Convergence Logic

L2 defines the operational vocabulary that describes how to mutate L1 state. Located in packages/transcript/src/ops/operation.ts, the TranscriptOperation type enumerates all possible mutations—including append, replace, and delete—as discriminated union types.

The convergence logic resides in packages/transcript/src/ops/apply.ts within the pure function applyOperation. This function takes an existing AgentState and a TranscriptOperation, returning a new state with the operation folded in. Because applyOperation is pure and deterministic, the same initial state and operation sequence always produce identical results, enabling perfect synchronization across distributed clients.

The layer also implements a gap detection mechanism. When the apply method in AgentTranscript encounters an operation that cannot be applied due to missing dependencies, it signals a gap, prompting the client to request a fresh snapshot rather than attempting to patch inconsistent state.

Layer 3 (L3): Transport and Subscription Granularity

L3 controls how operations traverse the network and at what granularity clients receive updates. Defined in packages/transcript/src/granularity/grade.ts, the Grade enum specifies subscription levels: off, block, or turn.

The transport layer uses these grades to filter operations via helpers like filterOps, ensuring that low-traffic UIs receive only turn-level batches while real-time components can subscribe to block-level updates. This design makes the system transport-agnostic—whether operations arrive via REST pagination or WebSocket streams, the L2 convergence logic remains identical.

Layer 4 (L4): View Registry and Rendering

The top layer, implemented in packages/transcript/src/view/registry.ts, provides a framework-agnostic ViewRegistry singleton. Rather than importing the store directly, UI components consume the registry, which maps raw AgentTranscriptSnapshot objects into virtualization-ready data structures.

This separation ensures that rendering logic remains decoupled from core state management. The registry handles item virtualization, task grouping, and interaction formatting, supplying React or other frontend frameworks with pre-computed view models derived from the immutable L1 snapshot.

How the Layers Interact: Server to Client Data Flow

The transcript layers (L0-L4) operate as a unified pipeline that guarantees deterministic state convergence:

  1. Server-side generation: Core events (new LLM turns, tool executions) are converted into L2 operations (TranscriptOperation objects) by the TranscriptService in packages/kap-server/src/services/transcript/transcriptService.ts.

  2. L2 application: The server calls applyOperation to fold these operations into the per-agent L1 store (AgentTranscript), producing a new immutable snapshot.

  3. L3 transport: After the store updates, it emits change events that the transport layer filters according to each client's Grade subscription level. Operations are forwarded via WebSocket or embedded in paged REST responses.

  4. Client convergence: Clients receive the ops and run the identical L2 → L1 convergence path, arriving at the same state as the server even after reconnections or missed batches.

  5. L4 rendering: The client's ViewRegistry reads the final snapshot and supplies UI components with ready-to-render structures.

Practical Implementation Guide

The following TypeScript example demonstrates the full L1-L4 integration path:

// Initialize the L1 convergent store
import { AgentTranscript } from '#/transcript/store/agentTranscript';
const transcript = new AgentTranscript('agent-123');

// Subscribe to changes (L3 granularity)
transcript.onChange(event => {
  console.log('Ops applied:', event.ops);
  
  // Extract immutable snapshot (L1)
  const snapshot = transcript.snapshot();
  
  // Render via L4 registry
  // viewRegistry.render(snapshot);
});

// Simulate receiving L2 ops from transport
const ops = [
  {
    type: 'append',
    target: 'turn',
    turnId: 'turn-5',
    content: { role: 'assistant', text: 'Hello world!' },
  },
] as const;

// Apply with gap detection
const result = transcript.apply(ops);
if (result.gap) {
  console.warn('Gap detected; request fresh snapshot from server');
}

// Windowed snapshot for virtualization
const tailSnapshot = transcript.snapshot({ tailTurns: 10 });

Summary

  • L0 provides vendor-agnostic wire contracts in packages/kosong/contract/, ensuring type-safe interoperability without business logic.
  • L1 implements the AgentTranscript store in packages/transcript/src/store/agentTranscript.ts, maintaining immutable snapshots as the single source of truth.
  • L2 defines TranscriptOperation types and the applyOperation pure function for deterministic, idempotent state mutations.
  • L3 manages transport granularity through the Grade enum, filtering operations for efficient network utilization.
  • L4 decouples rendering via the ViewRegistry, transforming snapshots into UI-ready structures without direct store dependencies.

Frequently Asked Questions

What makes the Kimi Code transcript layers deterministic?

The architecture achieves determinism through the L2 convergence layer. Because applyOperation in packages/transcript/src/ops/apply.ts is a pure function, applying the same sequence of TranscriptOperation objects to the same initial state always produces identical results on both server and client, regardless of transport method or network conditions.

How does Kimi Code handle missed updates or network reconnections?

The gap detection mechanism in the AgentTranscript.apply method detects when an operation references missing dependencies. When a gap is detected, the client knows it has missed operations and requests a fresh L1 snapshot rather than applying partial updates, ensuring state consistency without complex merge algorithms.

What is the difference between Grade levels in L3?

The Grade enum in packages/transcript/src/granularity/grade.ts defines subscription granularity: off receives no updates, block receives batched operations suitable for low-frequency polling, and turn delivers individual turn-level updates for real-time UIs. This allows clients to optimize bandwidth based on their rendering requirements.

Why are L0 contracts kept separate from operational logic?

Separating wire-format contracts (L0) from operational logic (L2) ensures that provider-specific schemas (OpenAI, Anthropic, etc.) never leak into the convergence layer. This separation, enforced by the kosong package structure in packages/kosong/contract/, allows the system to add new LLM providers without modifying the transcript synchronization logic.

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 →