Install

bun add @oh-my-pi/pi-coding-agent

Node 20+ or any Bun version. The package is a TypeScript ES module; consumers compile against the published .d.ts.

Open a session

createAgentSession follows the same discovery rules as the CLI: it reads ~/.omp/agent/config.yml, finds credentials, loads extensions, MCP servers, skills, prompt templates. Pass any option to override one piece.

import {
  ModelRegistry,
  SessionManager,
  createAgentSession,
  discoverAuthStorage,
} from "@oh-my-pi/pi-coding-agent"
 
const authStorage = await discoverAuthStorage()
const modelRegistry = new ModelRegistry(authStorage)
await modelRegistry.refresh()
 
const { session, modelFallbackMessage } = await createAgentSession({
  sessionManager: SessionManager.inMemory(),
  authStorage,
  modelRegistry,
  model: modelRegistry.getAvailable()[0],
  thinkingLevel: "medium",
})
 
if (modelFallbackMessage) {
  process.stderr.write(modelFallbackMessage + "\n")
}
 
const unsubscribe = session.subscribe((event) => {
  if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
    process.stdout.write(event.assistantMessageEvent.delta)
  }
})
 
await session.prompt("Summarize this repository in three bullets.")
unsubscribe()
await session.dispose()

SessionManager.inMemory() keeps everything ephemeral. Swap in SessionManager.create(cwd) for the on-disk JSONL store the CLI uses, or implement your own. See Sessions for how persisted sessions resume, fork, and branch across embeds.

Streaming a turn

session.subscribe(handler) returns an unsubscribe function. Every event carries a type; the ones you usually care about:

EventWhat it carries
message_updateAssistant output. Inspect assistantMessageEvent.type for text_delta, thinking_delta, tool_call_start, tool_call_delta, or tool_result.
tool_execution_start / _update / _endTool-call lifecycle outside the assistant message. toolCallId, toolName, intent label.
agent_start / agent_endTurn boundaries. agent_end carries a stop reason and is the terminator that a single session.prompt resolves on.
auto_compaction_start / _endCompaction firing mid-stream.

What you can override

  • model and thinkingLevel — or let discovery pick.

  • systemPrompt — an array (replaces the default) or (defaults) => final.

  • toolNames — narrows the active built-in set. requireYieldTool opts in the hidden yield tool.

  • customTools — host-side tools the agent can call (see below).

  • extensions, additionalExtensionPaths, disableExtensionDiscovery.

  • skills, rules, promptTemplates, slashCommands, contextFiles — arrays override discovery.

  • authStorage — defaults to discoverAuthStorage() against ~/.omp/agent/agent.db.

  • sessionManagerinMemory(), file-backed (create(cwd)), or your own.

  • enableMCP. enableLsp, or hand in your own mcpManager.

Custom tools

A CustomTool is a plain object the agent can call back into. Parameters use a Zod schema (a TypeBox-style JSON schema also works); execute returns an AgentToolResult.

import { z } from "zod"
import { createAgentSession, type CustomTool } from "@oh-my-pi/pi-coding-agent"
 
const echoHost: CustomTool = {
  name: "echo_host",
  label: "Echo Host",
  description: "Echo a value back through the embedding host.",
  parameters: z.object({ message: z.string() }),
  async execute(_id, { message }) {
    return { content: [{ type: "text", text: `host: ${message}` }] }
  },
}
 
const { session } = await createAgentSession({
  customTools: [echoHost],
})

Forward the signal argument into long-running subprocesses so an abort (Esc in the TUI, an abort on the RPC pipe, session.abort() in the SDK) actually cancels the work.

Lifecycle

MethodEffect
session.prompt(text, opts?)Runs one turn. Resolves on agent_end.
session.steer(text)Inject a steering message into the running turn.
session.abort()Stop the current turn; emits agent_end with an aborted stop reason.
session.compact()Force a compaction pass.
session.dispose()Releases the model, MCP servers, and any LSP processes the session opened.

Need a non-Node language, or a process boundary between agent and host? Use the RPC mode instead. Spawning omp through the SDK is one of several entry shapes covered in the CLI reference.\n

Ask Docs

AI assistant to help answer questions about the documentation. Answers are read-only and cite docs/source.

Hi! How can I help you with the documentation today? Answers are read-only and cite docs/source.

Ctrl+Enter to send