PrimeAgent Codebase Architecture: How Functionality Is Organized Across Packages

PrimeAgent splits its functionality into loosely-coupled TypeScript packages that separate the terminal UI, daemon supervisor, session workers, IPython kernel, and LLM providers into distinct layers.

This modular organization enables PrimeIntellect-ai/prime-agent to maintain a lightweight presentation layer while keeping execution robust and extensible. The architecture follows a clear data flow: user input travels from the TUI through a daemon supervisor to session workers, which interact with an IPython kernel and model providers through a unified, type-safe API.

PrimeAgent Package Structure Overview

The codebase divides responsibilities across seven primary layers. Each layer lives in its own package under the packages/ directory, with clear boundaries between presentation, orchestration, execution, and infrastructure concerns.

Layer Package Core Responsibility
User Interface packages/tui Terminal rendering and keyboard input
Daemon / Supervisor packages/agent Process discovery, routing, and crash recovery
Session Worker packages/agent Root AgentSession execution and scheduling
Model-Facing Runtime (RLM) packages/coding-agent IPython kernel hosting and tool exposure
Model Provider Layer packages/ai LLM abstraction with unified event streaming
Persistence & Harness packages/ai Transcript storage and supplemental prompts
Extensions / Skills packages/coding-agent Dynamic plugin loading

The source analysis reveals this organization in packages/coding-agent/docs/architecture.md, which contains the canonical visual diagram of the system's data flow.

How the UI Layer Is Organized in PrimeAgent

The Terminal User Interface lives in packages/tui and remains strictly separated from execution logic.

  • src/tui.ts — Main TUI component that renders the interactive terminal interface
  • src/keybindings.ts — Default keyboard shortcut mappings

This package captures keystrokes and forwards them over a local daemon protocol to the supervisor. It never directly manipulates session state or executes code, maintaining the architectural boundary between presentation and execution.

PrimeAgent Daemon and Session Worker Organization

The packages/agent package implements both the supervisor and worker layers through distinct runtime modes.

Daemon Supervisor Components

  • src/agent.ts — Entry point for the daemon; handles process discovery, routing, attachments, and worker crash recovery
  • src/agent-loop.ts — Main event loop that processes messages and state transitions

Session Worker Components

The supervisor routes user requests to appropriate workers, while each worker maintains its own AgentSession, transcript, scheduler, and reference to an IPython kernel. This design allows multiple independent sessions to run concurrently under a single daemon.

IPython Kernel and Model Runtime Architecture

The packages/coding-agent package implements the RLM (Runtime Language Model) layer. This is the only tool exposed to the LLM—all file operations, shell commands, skill loads, and sub-agent delegation flow through this kernel.

Key source files:

  • src/index.ts — Public CLI and runtime entry point exports
  • src/cli.ts — Command-line parsing and startup orchestration

The kernel bootstraps an ipython tool that exposes functions like rlm(...) for spawning recursive sub-agents. When the model needs to execute Python, call system commands, or delegate to child agents, all requests pass through this single, well-typed bridge.

This centralization ensures the TypeScript host maintains complete observability and control over all model-originated actions.

PrimeAgent Model Provider Layer Organization

The packages/ai package abstracts all LLM providers behind a unified streaming interface.

Core abstraction files:

  • src/types.ts — Shared TypeScript definitions for streams, events, and provider configurations
  • src/stream.ts — Generic streaming interface consumed by all higher layers
  • src/bedrock-provider.ts — Example implementation showing how to add a custom provider

The provider layer streams unified event types: text, tool_call, thinking, and others. This normalization allows AgentSession to work with OpenAI, Anthropic, Google, Bedrock, or custom providers without code changes.

Adding a new provider requires implementing the StreamOptions interface and registering in packages/ai/src/providers/register-builtins.ts.

Persistence and Extension System Design

Session Resources and Transcripts

Also within packages/ai:

The harness stores supplemental prompts, memories, and skill descriptions separately from the immutable base system prompt. Users can refine this context with the /refine command without rebuilding core behavior.

Dynamic Extensions and Skills

The packages/coding-agent package supports runtime extension loading:

  • src/extensions.ts — Discovery, registration, and lifecycle management of extensions

Extensions are dynamically loadable npm packages that contribute:

  • Custom tools accessible through the IPython kernel
  • New slash commands
  • Additional UI panels
  • Theme modifications

Load an extension at startup:

prime-agent -e ./my-extension.ts

The extension exports a register function receiving the ExtensionRegistry, enabling additive functionality without modifying core source.

Practical Code Examples

Launching Sessions

prime-agent                     # New TUI session with fresh worker

prime-agent -c                  # Continue most recent session

prime-agent --resume 12345      # Resume specific saved session

Source: packages/coding-agent/src/cli.ts

Switching Models at Runtime

/model openai/gpt-4o

Parsed by the CLI and propagated to the current AgentSession's provider configuration in packages/agent/src/agent.ts.

Spawning Recursive Sub-Agents


# Inside IPython kernel prompt

review = await rlm(
    "Check the security of the current repository and report findings.",
    name="security-reviewer",
)

Creates a child AgentSession sharing the parent's provider and scheduler. Implementation spans packages/agent/src/agent.ts (child management) and packages/coding-agent/src/ipython-tool.ts (kernel bridge).

Implementing a Custom Provider

// ./my-provider.ts
import { stream, StreamOptions } from 'prime-agent/ai';

export async function* streamMyProvider(opts: StreamOptions) {
  // Translate opts to provider-specific HTTP request
  // Yield unified events: { type: 'text', text: '...' }
}

Register lazily in the built-in providers registry. Reference bedrock-provider.ts for complete implementation patterns.

Summary

PrimeAgent's functionality organization follows these architectural principles:

  • Strict separation of concerns — UI (tui), orchestration (agent), execution (coding-agent), and infrastructure (ai) remain independent packages
  • Single kernel bridge — The IPython kernel in coding-agent is the sole tool exposed to LLMs, centralizing security and observability
  • Unified provider abstraction — All LLM providers implement the same streaming interface in packages/ai
  • Runtime extensibility — Extensions load dynamically without recompilation via packages/coding-agent/src/extensions.ts
  • Immutable core, mutable harness — Session transcripts append-only in JSONL; supplemental context refines separately via session-resources.ts

This package structure enables PrimeAgent to add new model providers, UI components, or execution capabilities without modifying the core runtime loop.

Frequently Asked Questions

What is the main entry point for PrimeAgent?

The CLI entry point is packages/coding-agent/src/cli.ts, which parses arguments and delegates to either the TUI launcher or direct session resumption. The TUI itself lives in packages/tui/src/tui.ts and communicates with the daemon supervisor via local protocol.

How does PrimeAgent isolate the UI from code execution?

The TUI package (packages/tui) contains only presentation logic—terminal rendering and input handling. All execution happens in separate worker processes managed by the daemon in packages/agent. The TUI never directly accesses the IPython kernel or file system; all actions route through the supervisor's message protocol.

Can I add support for a new LLM provider without modifying core code?

You can implement a custom provider by creating a module that exports a streaming generator conforming to StreamOptions from packages/ai, then register it in packages/ai/src/providers/register-builtins.ts. For purely external extensions, the dynamic loading system in packages/coding-agent/src/extensions.ts may also support provider plugins in future versions.

What is the "continual harness" in PrimeAgent?

The continual harness is mutable context stored alongside the immutable session transcript. It contains refined prompts, accumulated memories, and skill descriptions that evolve during a session. Stored via packages/ai/src/session-resources.ts, it allows the /refine command to update agent behavior without altering the base system prompt.

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 →