docs(docs): moved documentation to root docs directory and updated all references
- Moved documentation files from packages/coding-agent/docs/ to root docs/ directory to flatten the documentation structure. - Updated all internal documentation links to account for the new file locations, adjusting relative paths to maintain correct references across the monorepo. - Updated README.md and issue template configuration to reference documentation at the new root docs/ location instead of packages/coding-agent/docs/.
This commit is contained in:
+336
@@ -0,0 +1,336 @@
|
||||
# SDK
|
||||
|
||||
The SDK is the in-process integration surface for `@oh-my-pi/pi-coding-agent`.
|
||||
Use it when you want direct access to agent state, event streaming, tool wiring, and session control from your own Bun/Node process.
|
||||
|
||||
If you need cross-language/process isolation, use RPC mode instead.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @oh-my-pi/pi-coding-agent
|
||||
```
|
||||
|
||||
## Entry points
|
||||
|
||||
`@oh-my-pi/pi-coding-agent` exports the SDK APIs from the package root (and also via `@oh-my-pi/pi-coding-agent/sdk`).
|
||||
|
||||
Core exports for embedders:
|
||||
|
||||
- `createAgentSession`
|
||||
- `SessionManager`
|
||||
- `Settings`
|
||||
- `AuthStorage`
|
||||
- `ModelRegistry`
|
||||
- `discoverAuthStorage`
|
||||
- Discovery helpers (`discoverExtensions`, `discoverSkills`, `discoverContextFiles`, `discoverPromptTemplates`, `discoverSlashCommands`, `discoverCustomTSCommands`, `discoverMCPServers`)
|
||||
- Tool factory surface (`createTools`, `BUILTIN_TOOLS`, tool classes)
|
||||
|
||||
## Quick start (auto-discovery defaults)
|
||||
|
||||
```ts
|
||||
import { createAgentSession } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const { session, modelFallbackMessage } = await createAgentSession();
|
||||
|
||||
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 3 bullets.");
|
||||
unsubscribe();
|
||||
await session.dispose();
|
||||
```
|
||||
|
||||
## What `createAgentSession()` discovers by default
|
||||
|
||||
`createAgentSession()` follows “provide to override, omit to discover”.
|
||||
|
||||
If omitted, it resolves:
|
||||
|
||||
- `cwd`: `getProjectDir()`
|
||||
- `agentDir`: `~/.omp/agent` (via `getAgentDir()`)
|
||||
- `authStorage`: `discoverAuthStorage(agentDir)`
|
||||
- `modelRegistry`: `new ModelRegistry(authStorage)` + `await refresh()`
|
||||
- `settings`: `await Settings.init({ cwd, agentDir })`
|
||||
- `sessionManager`: `SessionManager.create(cwd)` (file-backed)
|
||||
- skills/context files/prompt templates/slash commands/extensions/custom TS commands
|
||||
- built-in tools via `createTools(...)`
|
||||
- MCP tools (enabled by default)
|
||||
- LSP integration (enabled by default)
|
||||
|
||||
### Required vs optional inputs
|
||||
|
||||
Typically you must provide only what you want to control:
|
||||
|
||||
- **Must provide**: nothing for a minimal session
|
||||
- **Usually provide explicitly** in embedders:
|
||||
- `sessionManager` (if you need in-memory or custom location)
|
||||
- `authStorage` + `modelRegistry` (if you own credential/model lifecycle)
|
||||
- `model` or `modelPattern` (if deterministic model selection matters)
|
||||
- `settings` (if you need isolated/test config)
|
||||
|
||||
## Session manager behavior (persistent vs in-memory)
|
||||
|
||||
`AgentSession` always uses a `SessionManager`; behavior depends on which factory you use.
|
||||
|
||||
### File-backed (default)
|
||||
|
||||
```ts
|
||||
import { createAgentSession, SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
sessionManager: SessionManager.create(process.cwd()),
|
||||
});
|
||||
|
||||
console.log(session.sessionFile); // absolute .jsonl path
|
||||
```
|
||||
|
||||
- Persists conversation/messages/state deltas to session files.
|
||||
- Supports resume/open/list/fork workflows.
|
||||
- `session.sessionFile` is defined.
|
||||
|
||||
### In-memory
|
||||
|
||||
```ts
|
||||
import { createAgentSession, SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
console.log(session.sessionFile); // undefined
|
||||
```
|
||||
|
||||
- No filesystem persistence.
|
||||
- Useful for tests, ephemeral workers, request-scoped agents.
|
||||
- Session methods still work, but persistence-specific behaviors (file resume/fork paths) are naturally limited.
|
||||
|
||||
### Resume/open/list helpers
|
||||
|
||||
```ts
|
||||
import { SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const recent = await SessionManager.continueRecent(process.cwd());
|
||||
const listed = await SessionManager.list(process.cwd());
|
||||
const opened = listed[0] ? await SessionManager.open(listed[0].path) : null;
|
||||
```
|
||||
|
||||
## Model and auth wiring
|
||||
|
||||
`createAgentSession()` uses `ModelRegistry` + `AuthStorage` for model selection and API key resolution.
|
||||
|
||||
### Explicit wiring
|
||||
|
||||
```ts
|
||||
import {
|
||||
createAgentSession,
|
||||
discoverAuthStorage,
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const authStorage = await discoverAuthStorage();
|
||||
const modelRegistry = new ModelRegistry(authStorage);
|
||||
await modelRegistry.refresh();
|
||||
|
||||
const available = modelRegistry.getAvailable();
|
||||
if (available.length === 0) throw new Error("No authenticated models available");
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
model: available[0],
|
||||
thinkingLevel: "medium",
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
```
|
||||
|
||||
### Selection order when `model` is omitted
|
||||
|
||||
When no explicit `model`/`modelPattern` is provided:
|
||||
|
||||
1. restore model from existing session (if restorable + key available)
|
||||
2. settings default model role (`default`)
|
||||
3. first available model with valid auth
|
||||
|
||||
If restore fails, `modelFallbackMessage` explains fallback.
|
||||
|
||||
### Auth priority
|
||||
|
||||
`AuthStorage.getApiKey(...)` resolves in this order:
|
||||
|
||||
1. runtime override (`setRuntimeApiKey`)
|
||||
2. stored credentials in `agent.db`
|
||||
3. provider environment variables
|
||||
4. custom-provider resolver fallback (if configured)
|
||||
|
||||
## Event subscription model
|
||||
|
||||
Subscribe with `session.subscribe(listener)`; it returns an unsubscribe function.
|
||||
|
||||
```ts
|
||||
const unsubscribe = session.subscribe(event => {
|
||||
switch (event.type) {
|
||||
case "agent_start":
|
||||
case "turn_start":
|
||||
case "tool_execution_start":
|
||||
break;
|
||||
case "message_update":
|
||||
if (event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`AgentSessionEvent` includes core `AgentEvent` plus session-level events:
|
||||
|
||||
- `auto_compaction_start` / `auto_compaction_end`
|
||||
- `auto_retry_start` / `auto_retry_end`
|
||||
- `ttsr_triggered`
|
||||
- `todo_reminder`
|
||||
|
||||
## Prompt lifecycle
|
||||
|
||||
`session.prompt(text, options?)` is the primary entry point.
|
||||
|
||||
Behavior:
|
||||
|
||||
1. optional command/template expansion (`/` commands, custom commands, file slash commands, prompt templates)
|
||||
2. if currently streaming:
|
||||
- requires `streamingBehavior: "steer" | "followUp"`
|
||||
- queues instead of throwing work away
|
||||
3. if idle:
|
||||
- validates model + API key
|
||||
- appends user message
|
||||
- starts agent turn
|
||||
|
||||
Related APIs:
|
||||
|
||||
- `sendUserMessage(content, { deliverAs? })`
|
||||
- `steer(text, images?)`
|
||||
- `followUp(text, images?)`
|
||||
- `sendCustomMessage({ customType, content, ... }, { deliverAs?, triggerTurn? })`
|
||||
- `abort()`
|
||||
|
||||
## Tools and extension integration
|
||||
|
||||
### Built-ins and filtering
|
||||
|
||||
- Built-ins come from `createTools(...)` and `BUILTIN_TOOLS`.
|
||||
- `toolNames` acts as an allowlist for built-ins.
|
||||
- `customTools` and extension-registered tools are still included.
|
||||
- Hidden tools (for example `submit_result`) are opt-in unless required by options.
|
||||
|
||||
```ts
|
||||
const { session } = await createAgentSession({
|
||||
toolNames: ["read", "grep", "find", "write"],
|
||||
requireSubmitResultTool: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Extensions
|
||||
|
||||
- `extensions`: inline `ExtensionFactory[]`
|
||||
- `additionalExtensionPaths`: load extra extension files
|
||||
- `disableExtensionDiscovery`: disable automatic extension scanning
|
||||
- `preloadedExtensions`: reuse already loaded extension set
|
||||
|
||||
### Runtime tool set changes
|
||||
|
||||
`AgentSession` supports runtime activation updates:
|
||||
|
||||
- `getActiveToolNames()`
|
||||
- `getAllToolNames()`
|
||||
- `setActiveToolsByName(names)`
|
||||
- `refreshMCPTools(mcpTools)`
|
||||
|
||||
System prompt is rebuilt to reflect active tool changes.
|
||||
|
||||
## Discovery helpers
|
||||
|
||||
Use these when you want partial control without recreating internal discovery logic:
|
||||
|
||||
- `discoverAuthStorage(agentDir?)`
|
||||
- `discoverExtensions(cwd?)`
|
||||
- `discoverSkills(cwd?, _agentDir?, settings?)`
|
||||
- `discoverContextFiles(cwd?, _agentDir?)`
|
||||
- `discoverPromptTemplates(cwd?, agentDir?)`
|
||||
- `discoverSlashCommands(cwd?)`
|
||||
- `discoverCustomTSCommands(cwd?, agentDir?)`
|
||||
- `discoverMCPServers(cwd?)`
|
||||
- `buildSystemPrompt(options?)`
|
||||
|
||||
## Subagent-oriented options
|
||||
|
||||
For SDK consumers building orchestrators (similar to task executor flow):
|
||||
|
||||
- `outputSchema`: passes structured output expectation into tool context
|
||||
- `requireSubmitResultTool`: forces `submit_result` tool inclusion
|
||||
- `taskDepth`: recursion-depth context for nested task sessions
|
||||
- `parentTaskPrefix`: artifact naming prefix for nested task outputs
|
||||
|
||||
These are optional for normal single-agent embedding.
|
||||
|
||||
## `createAgentSession()` return value
|
||||
|
||||
```ts
|
||||
type CreateAgentSessionResult = {
|
||||
session: AgentSession;
|
||||
extensionsResult: LoadExtensionsResult;
|
||||
setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void;
|
||||
mcpManager?: MCPManager;
|
||||
modelFallbackMessage?: string;
|
||||
lspServers?: Array<{ name: string; status: "ready" | "error"; fileTypes: string[]; error?: string }>;
|
||||
};
|
||||
```
|
||||
|
||||
Use `setToolUIContext(...)` only if your embedder provides UI capabilities that tools/extensions should call into.
|
||||
|
||||
## Minimal controlled embed example
|
||||
|
||||
```ts
|
||||
import {
|
||||
createAgentSession,
|
||||
discoverAuthStorage,
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
Settings,
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const authStorage = await discoverAuthStorage();
|
||||
const modelRegistry = new ModelRegistry(authStorage);
|
||||
await modelRegistry.refresh();
|
||||
|
||||
const settings = Settings.isolated({
|
||||
"compaction.enabled": true,
|
||||
"retry.enabled": true,
|
||||
});
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
settings,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
toolNames: ["read", "grep", "find", "edit", "write"],
|
||||
enableMCP: false,
|
||||
enableLsp: true,
|
||||
});
|
||||
|
||||
session.subscribe(event => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
await session.prompt("Find all TODO comments in this repo and propose fixes.");
|
||||
await session.dispose();
|
||||
```
|
||||
Reference in New Issue
Block a user