PrimeAgent API Reference: Complete Guide to Session Management, Streaming, and LLM Integration
PrimeAgent exposes a dual-layered TypeScript API consisting of a host-side session manager (createAgentSession) for running persistent agent workflows and a provider-agnostic streaming layer (stream, complete) for direct LLM integration.
The PrimeAgent API is the programmatic interface for PrimeIntellect-ai/prime-agent, a TypeScript-based coding agent framework that orchestrates LLM interactions with persistent IPython kernels and tool execution. Whether you are embedding agent capabilities into a Node.js application or building custom extensions, understanding the two-layer architecture—host session management and model-facing streaming—is essential for effective integration.
Core Architecture: Host Layer vs. Model Layer
PrimeAgent organizes its API into distinct layers with clear separation of concerns:
- Host Layer (
@earendil-works/pi-agent-core): Manages persistent sessions, tool registration, and conversation state - Model Layer (
@earendil-works/pi-ai): Handles provider-specific LLM communication with unified streaming semantics
This separation allows you to use the streaming primitives directly for simple completions or leverage the full session machinery for multi-turn interactive workflows.
Host-Side API: Creating and Managing Agent Sessions
The primary entry point for PrimeAgent integration is createAgentSession() in packages/coding-agent/src/core/sdk.ts.
Session Creation and Initialization
export async function createAgentSession(
options?: CreateAgentSessionOptions,
): Promise<CreateAgentSessionResult>;
When invoked, createAgentSession instantiates several core components:
- SessionManager – Persists conversation history to JSONL files and handles session lifecycle
- SettingsManager – Loads authentication credentials and user preferences
- ModelRegistry – Enumerates available models based on configured API keys
- Agent – The core state machine that processes messages and schedules tool calls
The findInitialModel() function in packages/coding-agent/src/core/model-resolver.ts automatically selects a default model or restores a previously used model from session storage.
Configuration Options
The CreateAgentSessionOptions interface supports extensive customization:
| Option | Purpose |
|---|---|
model |
Explicit Model selection, bypassing auto-resolution |
tools |
Allow-list of built-in tools to enable (ipython, bash, edit) |
noTools |
Disable all tool execution |
customTools |
Array of ToolDefinition objects for domain-specific capabilities |
thinkingLevel |
Reasoning depth: "low", "medium", "high" |
onPayload |
Callback to intercept/modify provider requests |
onResponse |
Callback to inspect raw provider responses |
Working with AgentSession
The returned AgentSession exposes methods for interactive control:
const { session } = await createAgentSession();
// Inject a user message into conversation state
await session.sendMessage({
role: "user",
content: "Analyze the runtime complexity of this function",
timestamp: Date.now()
});
// Execute one agent turn (may involve multiple tool calls)
await session.runTurn();
// Attach to an existing session for debugging or monitoring
await session.attach(sessionId);
Model-Facing API: Streaming and Completion Functions
For direct LLM interaction without session overhead, use the streaming primitives in packages/ai/src/stream.ts.
Core Streaming Function
export function stream<TApi extends Api>(
model: Model<TApi>,
context: Context,
options?: ProviderStreamOptions,
): AssistantMessageEventStream;
The stream function returns an AssistantMessageEventStream that emits incremental events defined in AssistantMessageEvent (packages/ai/src/types.ts):
start– Stream initializationtext_delta– Incremental text generationthinking_delta– Reasoning chain updates (for supported models)toolcall_delta– Partial tool call formationdone– Completion signal with finalAssistantMessageerror– Structured error information
Convenience Wrappers
PrimeAgent provides three simplified variants:
complete<TApi>()– Consumes the full stream and returns a singleAssistantMessagestreamSimple<TApi>()– AcceptsSimpleStreamOptionswith explicitreasoninglevel and customthinkingBudgetscompleteSimple<TApi>()– Combines simple options with full consumption
All variants resolve the correct provider implementation via getApiProvider() in packages/ai/src/api-registry.ts, with built-in providers registered through packages/ai/src/register-builtins.ts.
Provider Registration Architecture
New LLM providers are added by:
- Implementing the
Providerinterface inpackages/ai/src/providers/<provider>.ts - Registering the provider in
packages/ai/src/register-builtins.ts
Supported providers include OpenAI, Anthropic, and Amazon Bedrock, with automatic credential resolution from environment variables or settings files.
Message and Event Types
The unified type system in packages/ai/src/types.ts ensures consistency across layers.
Core Message Types
| Type | Description |
|---|---|
UserMessage |
Input from the user with timestamp |
AssistantMessage |
Complete LLM response with content blocks |
ToolResultMessage |
Structured output from tool execution |
Content Block Variants
TextContent– Plain text segmentsThinkingContent– Model reasoning tracesImageContent– Base64-encoded images with mime typesToolCall– Pending or completed tool invocations
Streaming Event Protocol
The AssistantMessageEvent type defines the contract between provider implementations and consumers, enabling type-safe handling of partial responses across all supported LLM APIs.
Practical Integration Examples
One-Shot Completion with Custom Reasoning
import { getModel, streamSimple } from "@earendil-works/pi-ai";
import { createAgentSession } from "@earendil-works/pi-agent-core";
async function run() {
// Initialize agent session for credential and model management
const { session } = await createAgentSession();
// Resolve specific model with cost and capability metadata
const model = getModel("anthropic", "claude-opus-4-5");
// Construct minimal conversation context
const context = {
messages: [{
role: "user",
content: "Explain recursion in 2 sentences.",
timestamp: Date.now()
}],
};
// Stream with high reasoning depth
const stream = await streamSimple(model, context, { reasoning: "high" });
stream.on("text_delta", ({ delta }) => process.stdout.write(delta));
await stream.result(); // Await completion
}
run().catch(console.error);
Source: streamSimple implementation in [packages/ai/src/stream.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/stream.ts)
Interactive Session with Tool Constraints
import { createAgentSession } from "@earendil-works/pi-agent-core";
async function startInteractive() {
const { session } = await createAgentSession({
tools: ["ipython"], // IPython only, no bash/edit
thinkingLevel: "medium",
model: getModel("openai", "gpt-4o"), // Explicit model selection
});
await session.sendMessage({
role: "user",
content: "List all .ts files in src/",
timestamp: Date.now()
});
await session.runTurn(); // Executes until LLM yields final response
}
startInteractive();
Source: createAgentSession in [packages/coding-agent/src/core/sdk.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/sdk.ts)
Custom Tool Registration
import { createAgentSession, ToolDefinition } from "@earendil-works/pi-agent-core";
const echoTool: ToolDefinition = {
name: "echo",
description: "Echoes back the supplied text.",
schema: {
type: "object",
properties: { text: { type: "string" } },
required: ["text"]
},
invoke: async ({ text }) => ({
role: "toolResult",
toolCallId: "1",
toolName: "echo",
content: [{ type: "text", text }],
isError: false,
timestamp: Date.now()
}),
};
async function demo() {
const { session } = await createAgentSession({
customTools: [echoTool],
tools: ["echo"], // Explicit enable required
});
await session.sendMessage({
role: "user",
content: "Use the echo tool to say hello.",
timestamp: Date.now()
});
await session.runTurn();
}
demo();
Source: Tool registration API in [packages/coding-agent/src/tools/index.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/tools/index.ts)
CLI Interface as API Consumer
The prime-agent binary is a thin wrapper over the host API defined in packages/coding-agent/src/cli/args.ts:
| Command | API Mapping |
|---|---|
| Interactive TUI | createAgentSession() with default options → packages/tui/src/index.ts |
--mode json |
Direct streamSimple/completeSimple invocation |
list-models |
ModelRegistry enumeration |
agents, attach, resume |
SessionManager persistence operations |
All CLI flags map directly to CreateAgentSessionOptions fields, ensuring behavioral parity between programmatic and command-line usage.
Extension Points and Customization
Provider Extensions
Implement the Provider interface to add new LLM backends:
- Handle transport-specific authentication
- Translate native streaming formats to
AssistantMessageEventprotocol - Register via
register-builtins.ts
Tool Extensions
Custom tools follow the ToolDefinition contract:
- JSON Schema for parameter validation
- Async
invokefunction returningToolResultMessage - Injection via
customToolsoption or package registry
Lifecycle Hooks
Extensions loaded by DefaultResourceLoader can intercept:
before_provider_request– Modify payloads before transmissionafter_provider_response– Inspect or transform raw responsescontextevents – Access conversation state for analytics or logging
Summary
- Two-layer architecture: Host layer (
createAgentSession) for session management, model layer (stream/complete) for direct LLM access - Entry point:
createAgentSession()inpackages/coding-agent/src/core/sdk.tsreturns a configuredAgentSessionwith tool and model resolution - Streaming primitives:
stream,streamSimple,complete,completeSimpleinpackages/ai/src/stream.tsprovide unified provider abstraction - Type safety: Shared
MessageandAssistantMessageEventtypes inpackages/ai/src/types.tsensure cross-layer consistency - Extensibility: Provider interface,
ToolDefinitiontype, and lifecycle hooks enable customization without core modification - CLI parity: All command-line functionality maps directly to programmatic API options
Frequently Asked Questions
What is the difference between stream and streamSimple in the PrimeAgent API?
stream accepts raw ProviderStreamOptions for maximum control over provider-specific parameters, while streamSimple exposes a streamlined SimpleStreamOptionsinterface with explicit reasoning levels and thinkingBudgets. Both return the same AssistantMessageEventStream, but streamSimple is recommended for most use cases as it handles common configuration patterns automatically.
How do I persist conversation history across process restarts?
PrimeAgent's SessionManager automatically persists conversations to JSONL files. When calling createAgentSession(), omit the sessionId option to create a fresh session, or provide a previously saved ID to resume. The session.attach(sessionId) method on AgentSession also allows dynamic reconnection to running sessions for debugging or multi-process coordination.
Can I use PrimeAgent with custom LLM providers not in the builtin registry?
Yes. Implement the Provider interface with methods for request streaming and response parsing, then register your implementation in packages/ai/src/register-builtins.ts. Your provider will integrate seamlessly with stream(), complete(), and all higher-level APIs. The getApiProvider() resolver in packages/ai/src/api-registry.ts handles runtime selection based on Model metadata.
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 →