- Added `temperature` configuration setting to control LLM sampling temperature with values from 0 (deterministic) to 1 (creative) to -1 (provider default). - Added temperature option selector in settings UI with preset values: Default, 0, 0.2, 0.5, 0.7, 1. - Renamed `settingsInstance` parameter to `settings` in `CreateAgentSessionOptions` for consistency. - Updated all internal references from `settingsInstance` to `settings` throughout SDK and components. - Integrated temperature setting into agent configuration and selector controller.
28 KiB
omp can help you use the SDK. Ask it to build an integration for your use case.
SDK
The SDK provides programmatic access to omp's agent capabilities. Use it to embed omp 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
See examples/sdk/ for working examples from minimal to full control.
Quick Start
import { createAgentSession, discoverAuthStorage, discoverModels, SessionManager } from "@oh-my-pi/pi-coding-agent";
// Set up credential storage and model registry
const authStorage = await discoverAuthStorage();
const modelRegistry = discoverModels(authStorage);
const { session, modelFallbackMessage } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
authStorage,
modelRegistry,
});
if (modelFallbackMessage) {
process.stderr.write(`${modelFallbackMessage}\n`);
}
session.subscribe((event) => {
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
process.stdout.write(event.assistantMessageEvent.delta);
}
});
await session.prompt("What files are in the current directory?");
Installation
bun add @oh-my-pi/pi-coding-agent
The SDK is included in the main package. No separate installation needed.
Core Concepts
createAgentSession()
The main factory function. Creates an AgentSession with configurable options.
Philosophy: "Omit to discover, provide to override."
- Omit an option → omp discovers/loads from standard locations
- Provide an option → your value is used, discovery skipped for that option
import { createAgentSession } from "@oh-my-pi/pi-coding-agent";
import systemPrompt from "./SYSTEM.md" with { type: "text" };
// Minimal: all defaults (discovers from cwd + config dirs and ~/.omp/agent)
const { session } = await createAgentSession();
// Custom: override specific options
const { session } = await createAgentSession({
model: myModel,
systemPrompt,
toolNames: ["read", "bash", "edit"], // Filter to specific tools
sessionManager: SessionManager.inMemory(),
});
AgentSession
The session manages the agent lifecycle, message history, and event streaming.
interface AgentSession {
// Prompting
prompt(text: string, options?: PromptOptions): Promise<void>;
sendUserMessage(
content: string | (TextContent | ImageContent)[],
options?: { deliverAs?: "steer" | "followUp" }
): Promise<void>;
steer(text: string): void;
followUp(text: string): void;
// Subscribe to events (returns unsubscribe function)
subscribe(listener: (event: AgentSessionEvent) => void): () => void;
// Session info
sessionFile: string | undefined; // undefined for in-memory
sessionId: string;
sessionName: string | undefined;
// Model control
setModel(model: Model, role?: ModelRole): Promise<void>;
setModelTemporary(model: Model): Promise<void>;
setThinkingLevel(level: ThinkingLevel): void;
cycleModel(direction?: "forward" | "backward"): Promise<ModelCycleResult | undefined>;
cycleRoleModels(
direction?: "forward" | "backward"
): Promise<{ model: Model; thinkingLevel: ThinkingLevel; role: ModelRole } | undefined>;
cycleThinkingLevel(): ThinkingLevel | undefined;
// State access
agent: Agent;
sessionManager: SessionManager;
settings: Settings;
model: Model | undefined;
thinkingLevel: ThinkingLevel;
messages: AgentMessage[];
isStreaming: boolean;
isCompacting: boolean;
isRetrying: boolean;
// Session management
newSession(options?: NewSessionOptions): Promise<boolean>; // Returns false if cancelled by extension
fork(): Promise<boolean>; // Creates a new session file
// Branching
branch(entryId: string): Promise<{ selectedText: string; cancelled: boolean }>;
navigateTree(
targetId: string,
options?: { summarize?: boolean; customInstructions?: string }
): Promise<{ editorText?: string; cancelled: boolean; aborted?: boolean; summaryEntry?: BranchSummaryEntry }>;
// Custom message injection
sendCustomMessage<T>(
message: { customType: string; content: T; display?: boolean; details?: unknown },
options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn" }
): Promise<void>;
// Compaction
compact(
customInstructions?: string,
options?: { onComplete?: (result: CompactionResult) => void; onError?: (error: Error) => void }
): Promise<CompactionResult>;
abortCompaction(): void;
// Utilities
getSessionStats(): SessionStats;
formatSessionAsText(): string;
formatCompactContext(): string;
exportToHtml(outputPath?: string): Promise<string>;
handoff(customInstructions?: string): Promise<{ document: string } | undefined>;
// Abort current operation
abort(): Promise<void>;
// Cleanup
dispose(): Promise<void>;
}
Agent and AgentState
The Agent class (from @oh-my-pi/pi-agent-core) handles the core LLM interaction. Access it via session.agent.
// Access current state
const state = session.agent.state;
// state.messages: AgentMessage[] - conversation history
// state.model: Model - current model
// state.thinkingLevel: ThinkingLevel - current thinking level
// state.systemPrompt: string - system prompt
// state.tools: Tool[] - available tools
// Replace messages (useful for branching, restoration)
session.agent.replaceMessages(messages);
// Wait for agent to finish processing
await session.agent.waitForIdle();
Events
Subscribe to events to receive streaming output and lifecycle notifications.
session.subscribe((event) => {
switch (event.type) {
// Streaming text from assistant
case "message_update":
if (event.assistantMessageEvent.type === "text_delta") {
process.stdout.write(event.assistantMessageEvent.delta);
}
if (event.assistantMessageEvent.type === "thinking_delta") {
// Thinking output (if thinking enabled)
}
break;
// Tool execution
case "tool_execution_start":
console.log(`Tool: ${event.toolName}`);
break;
case "tool_execution_update":
// Streaming tool output
break;
case "tool_execution_end":
console.log(`Result: ${event.isError ? "error" : "success"}`);
break;
// Message lifecycle
case "message_start":
// New message starting
break;
case "message_end":
// Message complete
break;
// Agent lifecycle
case "agent_start":
// Agent started processing prompt
break;
case "agent_end":
// Agent finished (event.messages contains new messages)
break;
// Turn lifecycle (one LLM response + tool calls)
case "turn_start":
break;
case "turn_end":
// event.message: assistant response
// event.toolResults: tool results from this turn
break;
// Session events (auto-compaction, retry, TTSR, todo reminders)
case "auto_compaction_start":
case "auto_compaction_end":
case "auto_retry_start":
case "auto_retry_end":
case "ttsr_triggered":
// event.rules
break;
case "todo_reminder":
// event.todos
break;
}
});
Options Reference
Directories
const { session } = await createAgentSession({
// Working directory for project-local discovery
cwd: process.cwd(), // default
// Global config directory
agentDir: "~/.omp/agent", // default (expands ~)
});
cwd is used for:
- Project config discovery (
.omp/,.pi/,.claude/,.codex/,.gemini/) - Project extensions/tools/skills/commands (via config dirs)
- Context files (
AGENTS.mdwalking up from cwd) - Session directory naming (via
SessionManager.create(cwd))
agentDir is used for:
- Global settings (
config.yml+agent.db) - Primary auth/models locations (
agent.db,models.yml,models.json) - Prompt templates (
prompts/) - Custom TS commands (
commands/)
Model
import { getModel } from "@oh-my-pi/pi-ai";
import { discoverAuthStorage, discoverModels } from "@oh-my-pi/pi-coding-agent";
const authStorage = await discoverAuthStorage();
const modelRegistry = discoverModels(authStorage);
// Find specific built-in model (doesn't check if API key exists)
const opus = getModel("anthropic", "claude-opus-4-5");
if (!opus) throw new Error("Model not found");
// Find any model by provider/id, including custom models from models.yml
// (doesn't check if API key exists)
const customModel = modelRegistry.find("my-provider", "my-model");
// Get all models that have valid API keys configured
const available = modelRegistry.getAvailable();
const { session } = await createAgentSession({
model: opus,
thinkingLevel: "medium", // off, minimal, low, medium, high, xhigh
// Models for cycling (Ctrl+P in interactive mode)
scopedModels: [
{ model: opus, thinkingLevel: "high" },
{ model: haiku, thinkingLevel: "off" },
],
authStorage,
modelRegistry,
});
If no model is provided:
- Tries to restore from session (if continuing)
- Uses default from settings
- Falls back to first available model
API Keys and OAuth
API key resolution priority (handled by AuthStorage):
- Runtime overrides (via
setRuntimeApiKey, not persisted) - Stored credentials in
agent.db(API keys or OAuth tokens) - Environment variables (
ANTHROPIC_API_KEY,OPENAI_API_KEY, etc.) - Fallback resolver (for custom provider keys from
models.yml)
discoverAuthStorage opens the agent.db SQLite database in the agent directory.
import { AuthStorage, ModelRegistry, discoverAuthStorage, discoverModels } from "@oh-my-pi/pi-coding-agent";
// Default: uses agentDir/agent.db and agentDir/models.yml
const authStorage = await discoverAuthStorage();
const modelRegistry = discoverModels(authStorage);
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
authStorage,
modelRegistry,
});
// Runtime API key override (not persisted to disk)
authStorage.setRuntimeApiKey("anthropic", "sk-my-temp-key");
// Custom auth storage location (use create(), constructor is private)
const customAuth = await AuthStorage.create("/my/app/agent.db");
const customRegistry = new ModelRegistry(customAuth, "/my/app/models.yml");
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
authStorage: customAuth,
modelRegistry: customRegistry,
});
// No custom models.yml (built-in models only)
const simpleRegistry = new ModelRegistry(authStorage);
System Prompt
import systemPrompt from "./SYSTEM.md" with { type: "text" };
const { session } = await createAgentSession({
// Replace entirely with a static prompt
systemPrompt,
});
const { session: modified } = await createAgentSession({
// Or modify default (receives default, returns modified)
systemPrompt: (defaultPrompt) => {
return `${defaultPrompt}\n\n## Additional Rules\n- Be concise`;
},
});
Tools
By default, createAgentSession creates all built-in tools automatically. You can filter which tools are available using toolNames:
// Use all built-in tools (default)
const { session } = await createAgentSession();
// Filter to specific tools
const { session } = await createAgentSession({
toolNames: ["read", "grep", "find"], // Read-only tools
});
`toolNames` is an allowlist for built-ins; custom tools are always included even if not listed.
Available Built-in Tools
All tools are defined in BUILTIN_TOOLS:
ask- Interactive user prompts (requires UI)bash- Shell command executionpython- Python REPL executioncalc- Calculatorssh- Remote SSH executionedit- Surgical file editingfind- File search by glob patternsgrep- Content search with regexlsp- Language server protocol integrationnotebook- Jupyter notebook editingread- File reading (text and images)browser- Puppeteer-based web browsertask- Subagent spawningtodo_write- Todo file managementfetch- URL fetchingweb_search- Web searchwrite- File writing
Hidden tools (not in BUILTIN_TOOLS) are available but excluded unless requested:
submit_result- Required for subagent structured output (userequireSubmitResultToolor include intoolNames)report_finding- Security review reportingexit_plan_mode- Plan mode control
Creating Tools Manually
For advanced use cases, you can create tools directly using createTools:
import { createTools, Settings, type ToolSession } from "@oh-my-pi/pi-coding-agent";
const settings = await Settings.init({ cwd: "/path/to/project" });
const session: ToolSession = {
cwd: "/path/to/project",
hasUI: false,
getSessionFile: () => null,
getSessionSpawns: () => "*",
settings,
};
const tools = await createTools(session);
When you don't need factories:
- If you omit
toolNames, omp automatically creates them with the correctcwd - If you use
process.cwd()as yourcwd, the pre-built instances work fine
When you must use factories:
- When you specify both
cwd(different fromprocess.cwd()) AND custom tools
Custom Tools
import { Type } from "@sinclair/typebox";
import { createAgentSession, type CustomTool } from "@oh-my-pi/pi-coding-agent";
// Inline custom tool
const myTool: CustomTool = {
name: "my_tool",
label: "My Tool",
description: "Does something useful",
parameters: Type.Object({
input: Type.String({ description: "Input value" }),
}),
execute: async (toolCallId, params, onUpdate, ctx, signal) => ({
content: [{ type: "text", text: `Result: ${params.input}` }],
}),
// Optional session lifecycle handler
onSession: async (event, ctx) => {
if (event.reason === "shutdown") {
// cleanup
}
},
};
// Add custom tools (merged with built-in tools)
const { session } = await createAgentSession({
customTools: [myTool],
});
Extensions
Extensions intercept agent events and can register custom tools/commands. Hooks remain for legacy compatibility.
import { createAgentSession, discoverExtensions, type ExtensionFactory } from "@oh-my-pi/pi-coding-agent";
// Inline extension
const loggingExtension: ExtensionFactory = (api) => {
// Log tool calls
api.on("tool_call", async (event) => {
console.log(`Tool: ${event.toolName}`);
return undefined; // Don't block
});
// Block dangerous commands
api.on("tool_call", async (event) => {
if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
return { block: true, reason: "Dangerous command" };
}
return undefined;
});
// Register custom slash command
api.registerCommand("stats", {
description: "Show session stats",
handler: async (args, ctx) => {
const entries = ctx.sessionManager.getEntries();
ctx.ui.notify(`${entries.length} entries`, "info");
},
});
};
// Merge with discovery (default behavior)
const { session } = await createAgentSession({
extensions: [loggingExtension],
});
// Replace discovery
const { session } = await createAgentSession({
extensions: [loggingExtension],
disableExtensionDiscovery: true,
});
// Disable all extensions
const { session } = await createAgentSession({
extensions: [],
disableExtensionDiscovery: true,
});
// Use preloaded extensions (skip discovery I/O)
const discovered = await discoverExtensions();
const { session } = await createAgentSession({
preloadedExtensions: discovered,
extensions: [loggingExtension],
});
// Add paths without replacing discovery
const { session } = await createAgentSession({
additionalExtensionPaths: ["/extra/extensions"],
});
Extension API methods:
api.on(event, handler)- Subscribe to eventsapi.registerTool(definition)- Register a custom toolapi.registerCommand(name, options)- Register custom slash commandapi.registerMessageRenderer(customType, renderer)- Custom TUI renderingapi.exec(command, args, options?)- Execute shell commands
Skills
import { createAgentSession, discoverSkills, type Skill } from "@oh-my-pi/pi-coding-agent";
// Discover and filter
const { skills: allSkills, warnings } = await discoverSkills();
const filtered = allSkills.filter((s) => s.name.includes("search"));
// Custom skill
const mySkill: Skill = {
name: "my-skill",
description: "Custom instructions",
filePath: "/path/to/SKILL.md",
baseDir: "/path/to",
source: "custom",
};
const { session } = await createAgentSession({
skills: [...filtered, mySkill],
});
// Disable skills
const { session } = await createAgentSession({
skills: [],
});
Context Files
import { createAgentSession, discoverContextFiles } from "@oh-my-pi/pi-coding-agent";
// Discover AGENTS.md files
const discovered = await discoverContextFiles();
// Add custom context
const { session } = await createAgentSession({
contextFiles: [
...discovered,
{
path: "/virtual/AGENTS.md",
content: "# Guidelines\n\n- Be concise\n- Use TypeScript",
},
],
});
// Disable context files
const { session } = await createAgentSession({
contextFiles: [],
});
Slash Commands
import { createAgentSession, discoverSlashCommands, type FileSlashCommand } from "@oh-my-pi/pi-coding-agent";
const discovered = await discoverSlashCommands();
const customCommand: FileSlashCommand = {
name: "deploy",
description: "Deploy the application",
source: "(custom)",
content: "# Deploy\n\n1. Build\n2. Test\n3. Deploy",
};
const { session } = await createAgentSession({
slashCommands: [...discovered, customCommand],
});
Session Management
Sessions use a tree structure with id/parentId linking, enabling in-place branching.
import { createAgentSession, SessionManager } from "@oh-my-pi/pi-coding-agent";
// In-memory (no persistence)
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
});
// New persistent session
const { session } = await createAgentSession({
sessionManager: SessionManager.create(process.cwd()),
});
// Continue most recent (async)
const { session, modelFallbackMessage } = await createAgentSession({
sessionManager: await SessionManager.continueRecent(process.cwd()),
});
if (modelFallbackMessage) {
console.log("Note:", modelFallbackMessage);
}
// Open specific file (async)
const { session } = await createAgentSession({
sessionManager: await SessionManager.open("/path/to/session.jsonl"),
});
// List available sessions (async)
const sessions = await SessionManager.list(process.cwd());
for (const info of sessions) {
console.log(`${info.id}: ${info.firstMessage} (${info.messageCount} messages)`);
}
// Custom session directory (no cwd encoding)
const customDir = "/path/to/my-sessions";
const { session } = await createAgentSession({
sessionManager: SessionManager.create(process.cwd(), customDir),
});
SessionManager static factories:
SessionManager.create(cwd, sessionDir?)- New persistent session (sync)SessionManager.inMemory(cwd?)- In-memory session (sync)SessionManager.open(filePath, sessionDir?)- Open existing file (async)SessionManager.continueRecent(cwd, sessionDir?)- Most recent session (async)SessionManager.list(cwd, sessionDir?)- List sessions (async)SessionManager.listAll()- List all sessions across cwds (async)SessionManager.forkFrom(sourcePath, cwd, sessionDir?)- Fork from existing (async)
SessionManager tree API:
const sm = await SessionManager.open("/path/to/session.jsonl");
// Tree traversal
const entries = sm.getEntries(); // All entries (excludes header)
const tree = sm.getTree(); // Full tree structure
const branch = sm.getBranch(); // Path from root to current leaf
const leaf = sm.getLeafEntry(); // Current leaf entry
const entry = sm.getEntry(id); // Get entry by ID
const children = sm.getChildren(id); // Direct children of entry
// Labels
const label = sm.getLabel(id); // Get label for entry
sm.appendLabelChange(id, "checkpoint"); // Set label
// Branching
sm.branch(entryId); // Move leaf to earlier entry
sm.branchWithSummary(id, "Summary..."); // Branch with context summary
sm.createBranchedSession(leafId); // Extract path to new file
Settings Management
import { createAgentSession, Settings, SessionManager } from "@oh-my-pi/pi-coding-agent";
// Default: loads from files (global config.yml + project settings.json merged)
const settings = await Settings.init();
const { session } = await createAgentSession({
settings,
});
// Read/write settings
const enabled = settings.get("compaction.enabled");
settings.set("compaction.enabled", false);
// In-memory (no file I/O, for testing)
const isolated = Settings.isolated({
"compaction.enabled": false,
"retry.enabled": true,
});
const { session } = await createAgentSession({
settings: isolated,
sessionManager: SessionManager.inMemory(),
});
// Custom directories
const { session } = await createAgentSession({
cwd: "/custom/cwd",
agentDir: "/custom/agent",
});
Settings static factories:
Settings.init(options?)- Load from files (async)Settings.isolated(overrides?)- In-memory, no file I/O (sync)Settings.instance- Global singleton (throws if not initialized)
Settings file locations:
Settings load from two locations and merge:
- Global:
<agentDir>/config.yml(default~/.omp/agent/config.yml) - Project:
settings.jsonfrom the first matching config dir (.omp/,.pi/,.claude/,.codex/,.gemini/)
Project overrides global. Nested objects merge keys.
Discovery Functions
Discovery functions accept optional cwd and agentDir parameters where applicable.
import { getModel } from "@oh-my-pi/pi-ai";
import appendPrompt from "./APPEND_SYSTEM.md" with { type: "text" };
import {
AuthStorage,
ModelRegistry,
discoverAuthStorage,
discoverModels,
discoverSkills,
discoverExtensions,
discoverContextFiles,
discoverSlashCommands,
discoverPromptTemplates,
discoverCustomTSCommands,
discoverMCPServers,
buildSystemPrompt,
Settings,
} from "@oh-my-pi/pi-coding-agent";
// Auth and Models
const authStorage = await discoverAuthStorage(); // <agentDir>/agent.db
const modelRegistry = discoverModels(authStorage); // + <agentDir>/models.yml (or models.json)
const allModels = modelRegistry.getAll(); // All models (built-in + custom)
const available = modelRegistry.getAvailable(); // Only models with API keys
const model = modelRegistry.find("provider", "id"); // Find specific model
const builtIn = getModel("anthropic", "claude-opus-4-5"); // Built-in only
// Skills (async)
const { skills, warnings } = await discoverSkills(cwd, agentDir, skillsSettings);
// Extensions (async - loads TypeScript)
const extensionsResult = await discoverExtensions(cwd);
// Custom TS commands (async - loads TypeScript)
const customCommands = await discoverCustomTSCommands(cwd, agentDir);
// Context files (async)
const contextFiles = await discoverContextFiles(cwd, agentDir);
// Slash commands (async)
const commands = await discoverSlashCommands(cwd);
// Prompt templates (async)
const promptTemplates = await discoverPromptTemplates(cwd, agentDir);
// MCP servers (async)
const mcp = await discoverMCPServers(cwd);
// Settings (async - global + project merged)
const settings = await Settings.init({ cwd, agentDir });
// Build system prompt manually
const prompt = await buildSystemPrompt({
skills,
contextFiles,
appendPrompt,
cwd,
});
Return Value
createAgentSession() returns:
interface CreateAgentSessionResult {
// The session
session: AgentSession;
// Extensions result (loaded extensions + runtime)
extensionsResult: LoadExtensionsResult;
// Update tool UI context (interactive mode)
setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void;
// MCP manager for server lifecycle management (undefined if MCP disabled)
mcpManager?: MCPManager;
// Warning if session model couldn't be restored
modelFallbackMessage?: string;
// LSP servers that were warmed up at startup
lspServers?: Array<{ name: string; status: "ready" | "error"; fileTypes: string[]; error?: string }>;
}
Complete Example
import { getModel } from "@oh-my-pi/pi-ai";
import { Type } from "@sinclair/typebox";
import {
createAgentSession,
discoverAuthStorage,
discoverModels,
SessionManager,
Settings,
type ExtensionFactory,
type CustomTool,
} from "@oh-my-pi/pi-coding-agent";
import systemPrompt from "./SYSTEM.md" with { type: "text" };
// Set up auth storage
const authStorage = await discoverAuthStorage();
// Runtime API key override (not persisted)
if (Bun.env.MY_KEY) {
authStorage.setRuntimeApiKey("anthropic", Bun.env.MY_KEY);
}
// Model registry
const modelRegistry = discoverModels(authStorage);
// Inline extension
const auditExtension: ExtensionFactory = (api) => {
api.on("tool_call", async (event) => {
console.log(`[Audit] ${event.toolName}`);
return undefined;
});
};
// Inline tool
const statusTool: CustomTool = {
name: "status",
label: "Status",
description: "Get system status",
parameters: Type.Object({}),
execute: async (toolCallId, params, onUpdate, ctx, signal) => ({
content: [{ type: "text", text: `Uptime: ${process.uptime()}s` }],
}),
};
const model = getModel("anthropic", "claude-opus-4-5");
if (!model) throw new Error("Model not found");
// In-memory settings with overrides
const settings = Settings.isolated({
"compaction.enabled": false,
"retry.enabled": true,
});
const { session } = await createAgentSession({
cwd: process.cwd(),
agentDir: "/custom/agent",
model,
thinkingLevel: "off",
authStorage,
modelRegistry,
systemPrompt,
toolNames: ["read", "bash"],
customTools: [statusTool],
extensions: [auditExtension],
skills: [],
contextFiles: [],
slashCommands: [],
sessionManager: SessionManager.inMemory(),
settings,
});
session.subscribe((event) => {
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
process.stdout.write(event.assistantMessageEvent.delta);
}
});
await session.prompt("Get status and list files.");
RPC Mode Alternative
For subprocess-based integration, use RPC mode instead of the SDK:
omp --mode rpc --no-session
See RPC documentation for the JSON protocol.
The SDK is preferred when:
- 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
RPC mode is preferred when:
- You're integrating from another language
- You want process isolation
- You're building a language-agnostic client
Exports
The main entry point exports:
// Factory
createAgentSession
// Auth and Models
AuthStorage
ModelRegistry
discoverAuthStorage
discoverModels
// Discovery
discoverSkills
discoverExtensions
discoverCustomTSCommands
discoverContextFiles
discoverSlashCommands
discoverPromptTemplates
discoverMCPServers
// Helpers
buildSystemPrompt
Settings
// Session management
SessionManager
// Tool registry and factory
BUILTIN_TOOLS // Map of tool name to factory
createTools // Create all tools from ToolSession
type ToolSession // Session context for tool creation
// Individual tool classes
ReadTool, BashTool, EditTool, WriteTool
GrepTool, FindTool, PythonTool
loadSshTool
// Types
type CreateAgentSessionOptions
type CreateAgentSessionResult
type CustomTool
type ExtensionFactory
type Skill
type FileSlashCommand
type SkillsSettings
type Tool
For extension types, import from the main package:
import type {
ExtensionAPI,
ExtensionFactory,
ExtensionContext,
ExtensionCommandContext,
ToolDefinition,
} from "@oh-my-pi/pi-coding-agent";
For legacy hook types (deprecated, use extensions instead):
import type { HookAPI, HookFactory, HookContext, HookCommandContext } from "@oh-my-pi/pi-coding-agent/hooks";
For config utilities:
import { getAgentDir } from "@oh-my-pi/pi-coding-agent";