Atomic can help you use the SDK. Ask it to build an integration for your use case.
SDK
The SDK provides programmatic access to atomic’s agent capabilities. Use it to embed atomic in other applications, build custom interfaces, or integrate with automated workflows. Example use cases:- Build a custom UI (web, desktop, mobile)
- Integrate agent capabilities into existing applications
- Create automated pipelines with agent reasoning
- Build custom tools that spawn sub-agents
- Test agent behavior programmatically
Quick Start
Installation
Install the SDK package with Bun:--ignore-scripts to the install command.
The SDK is included in the main package. No separate installation needed.
Core Concepts
createAgentSession()
The main factory function for a singleAgentSession.
createAgentSession() uses a ResourceLoader to supply extensions, skills, prompt templates, themes, and context files. If you do not provide one, it uses DefaultResourceLoader with standard discovery.
AgentSession
The session manages agent lifecycle, message history, model state, compaction, and event streaming.AgentSessionRuntime, not on AgentSession.
createAgentSessionRuntime() and AgentSessionRuntime
Use the runtime API when you need to replace the active session and rebuild cwd-bound runtime state. This is the same layer used by the built-in interactive, print, and RPC modes.createAgentSessionRuntime() takes a runtime factory plus the initial cwd/session target. The factory closes over process-global fixed inputs, recreates cwd-bound services for the effective cwd, resolves session options against those services, and returns a full runtime result.
AgentSessionRuntime owns replacement of the active runtime across:
newSession()switchSession()fork()- clone flows via
fork(entryId, { position: "at" }) importFromJsonl()
runtime.sessionchanges after those operations- event subscriptions are attached to a specific
AgentSession, so re-subscribe after replacement - if you use extensions, call
runtime.session.bindExtensions(...)again for the new session - creation returns diagnostics on
runtime.diagnostics - if runtime creation or replacement fails, the method throws and the caller decides how to handle it
Prompting and Message Queueing
PromptOptions controls prompt expansion, queueing behavior while streaming, and prompt preflight notifications:
preflightResult is called once per prompt() invocation:
truewhen the prompt was accepted, queued, or handled immediatelyfalsewhen prompt preflight rejected before acceptance
prompt() resolves. prompt() still resolves only after the full accepted run finishes, including retries. Failures after acceptance are reported through the normal event and message stream, not through preflightResult(false).
The prompt() method handles prompt templates, extension commands, and message sending:
- Extension commands (e.g.,
/mycommand): Execute immediately, even during streaming. They manage their own LLM interaction viapi.sendMessage(). - File-based prompt templates (from
.mdfiles): Expanded to their content before sending or queueing. - During streaming without
streamingBehavior: Throws an error. Usesteer()orfollowUp()directly, or specify the option. preflightResult(true): Means the prompt was accepted, queued, or handled immediately.preflightResult(false): Means preflight rejected before acceptance.
steer() and followUp() expand file-based prompt templates but error on extension commands (extension commands cannot be queued).
Agent and AgentState
TheAgent class (from @earendil-works/pi-agent-core) handles the core LLM interaction. Access it via session.agent.
Events
Subscribe to events to receive streaming output and lifecycle notifications.Options Reference
Directories
.atomic locations first and legacy .pi locations for compatibility when multiple config directories are supported. Passing an explicit agentDir makes that directory the user override.
cwd is used by DefaultResourceLoader for:
- Project extensions (
.atomic/extensions/, then legacy.pi/extensions/) - Project skills:
.atomic/skills/, then legacy.pi/skills/.agents/skills/incwdand ancestor directories (up to git repo root, or filesystem root when not in a repo)
- Project prompts (
.atomic/prompts/, then legacy.pi/prompts/) - Context files (
AGENTS.mdwalking up from cwd) - Session directory naming
agentDir is used by DefaultResourceLoader for:
- Global extensions (
extensions/) - Global skills:
skills/underagentDir(for example~/.atomic/agent/skills/; legacy~/.pi/agent/skills/is also considered by default)~/.agents/skills/
- Global prompts (
prompts/) - Global context file (
AGENTS.md) - Settings (
settings.json) - Custom models (
models.json) - Credentials (
auth.json) - Sessions (
sessions/)
ResourceLoader, cwd and agentDir no longer control resource discovery. They still influence session naming and tool path resolution.
Model
- Tries to restore from session (if continuing)
- Uses default from settings
- Falls back to first available model
See examples/sdk/02-custom-model.ts
API Keys and OAuth
API key resolution priority (handled by AuthStorage):- Runtime overrides (via
setRuntimeApiKey, not persisted) - Stored credentials in
auth.json(API keys or OAuth tokens) - Environment variables (
ANTHROPIC_API_KEY,OPENAI_API_KEY, etc.) - Fallback resolver (for custom provider keys from
models.json)
See examples/sdk/09-api-keys-and-oauth.ts
System Prompt
Use aResourceLoader to override the system prompt:
See examples/sdk/03-custom-prompt.ts
Tools
Specify which tools to expose by name:- Built-in tool names:
read,bash,edit,write,grep,find,ls,ask_user_question,todo - The default active built-ins include
ask_user_questionandtodoin addition to file and shell tools. toolsis an allowlist: when provided, only the listed built-in, extension, and custom tool names are exposed.excludedToolsis a blocklist: matching built-in, extension, and custom tool names are omitted from the final registry and active tool set. If both are provided,toolsis applied first andexcludedToolssubtracts from it.noTools: "all"disables all toolsnoTools: "builtin"disables default built-ins while keeping extension and custom tools enabled, except names listed inexcludedTools
Tools with Custom cwd
When you pass a customcwd, createAgentSession() builds selected built-in tools for that cwd.
See examples/sdk/05-tools.ts
Custom Tools
defineTool() for standalone definitions and arrays like customTools: [myTool]. Inline pi.registerTool({ ... }) already infers parameter types correctly.
Custom tools passed via customTools are combined with extension-registered tools. Extensions loaded by the ResourceLoader can also register tools via pi.registerTool().
If you pass tools, include each custom or extension tool name you want enabled, for example tools: ["read", "bash", "my_tool"]. Use excludedTools to remove a custom or extension tool by name from the final exposed set.
See examples/sdk/05-tools.ts
Extensions
Extensions are loaded by theResourceLoader. DefaultResourceLoader discovers extensions from ~/.atomic/agent/extensions/ and .atomic/extensions/ first, then legacy ~/.pi/agent/extensions/ and .pi/extensions/, plus settings.json extension sources.
pi.events. Pass a shared eventBus to DefaultResourceLoader if you need to emit or listen from outside:
See examples/sdk/06-extensions.ts and Extensions
Skills
See examples/sdk/04-skills.ts
Context Files
See examples/sdk/07-context-files.ts
Slash Commands
See examples/sdk/08-prompt-templates.ts
Session Management
Sessions use a tree structure withid/parentId linking, enabling in-place branching.
See examples/sdk/11-sessions.ts and Session Format
Settings Management
SettingsManager.create(cwd?, agentDir?)- Load from filesSettingsManager.inMemory(settings?)- No file I/O
- Global:
~/.atomic/agent/settings.json, then legacy~/.pi/agent/settings.json - Project:
<cwd>/.atomic/settings.json, then legacy<cwd>/.pi/settings.json
- Settings getters/setters are synchronous for in-memory state.
- Setters enqueue persistence writes asynchronously.
- Call
await settingsManager.flush()when you need a durability boundary (for example, before process exit or before asserting file contents in tests). SettingsManagerdoes not print settings I/O errors. UsesettingsManager.drainErrors()and report them in your app layer.
See examples/sdk/10-settings.ts
ResourceLoader
UseDefaultResourceLoader to discover extensions, skills, prompts, themes, and context files.
Return Value
createAgentSession() returns:
Complete Example
Run Modes
The SDK exports run mode utilities for building custom interfaces on top ofcreateAgentSession():
InteractiveMode
Full TUI interactive mode with editor, chat history, and all built-in commands:runPrintMode
Single-shot mode: send prompts, output result, exit:runRpcMode
JSON-RPC mode for subprocess integration:RPC Mode Alternative
For subprocess-based integration without building with the SDK, use the CLI directly:- You want type safety
- You’re in the same Node.js process
- You need direct access to agent state
- You want to customize tools/extensions programmatically
- You’re integrating from another language
- You want process isolation
- You’re building a language-agnostic client