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 interfacesrc/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 recoverysrc/agent-loop.ts— Main event loop that processes messages and state transitions
Session Worker Components
src/agent-session-runtime.ts— Generated at runtime; hosts a single rootAgentSessionsrc/scheduler.ts— Schedules autonomous execution turns for the agent
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 exportssrc/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 configurationssrc/stream.ts— Generic streaming interface consumed by all higher layerssrc/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:
src/session-resources.ts— Handles JSONL transcript persistence and "continual harness" state
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-agentis 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →