SDK
pi có thể giúp bạn sử dụng SDK. Yêu cầu nó xây dựng một tích hợp cho trường hợp sử dụng của bạn.
SDK cung cấp quyền truy cập theo chương trình vào các khả năng của tác nhân pi. Sử dụng nó để nhúng pi vào các ứng dụng khác, xây dựng giao diện tùy chỉnh hoặc tích hợp với quy trình làm việc tự động.
Các trường hợp sử dụng ví dụ:
- Xây dựng giao diện người dùng tùy chỉnh (web, máy tính để bàn, thiết bị di động)
- Tích hợp khả năng của đại lý vào các ứng dụng hiện có
- Tạo quy trình tự động với lý luận của tác nhân
- Xây dựng các công cụ tùy chỉnh sinh ra các đại lý phụ
- Kiểm tra hành vi của tác nhân theo chương trình
Xem examples/sdk/ để biết các ví dụ hoạt động từ kiểm soát tối thiểu đến kiểm soát hoàn toàn.
Bắt đầu nhanh
import { createAgentSession, ModelRuntime, SessionManager } from "@earendil-works/pi-coding-agent";
const modelRuntime = await ModelRuntime.create();
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
modelRuntime,
});
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?");Cài đặt
npm install @earendil-works/pi-coding-agentSDK được bao gồm trong gói chính. Không cần cài đặt riêng biệt.
Khái niệm cốt lõi
createAgentSession()
Chức năng chính của nhà máy cho một AgentSession.
createAgentSession() sử dụng ResourceLoader để cung cấp các tiện ích mở rộng, kỹ năng, prompt templates, chủ đề và context files. Nếu bạn không cung cấp, nó sẽ sử dụng DefaultResourceLoader với tính năng khám phá tiêu chuẩn.
import { createAgentSession, SessionManager } from "@earendil-works/pi-coding-agent";
// Minimal: defaults with DefaultResourceLoader
const { session } = await createAgentSession();
// Custom: override specific options
const { session } = await createAgentSession({
model: myModel,
tools: ["read", "bash"],
sessionManager: SessionManager.inMemory(),
});Phiên đại lý
Phiên này quản lý vòng đời của tác nhân, lịch sử tin nhắn, trạng thái mô hình, quá trình nén và truyền phát sự kiện.
interface AgentSession {
// Send a prompt and wait for completion
prompt(text: string, options?: PromptOptions): Promise<void>;
// Queue messages during streaming
steer(text: string): Promise<void>;
followUp(text: string): Promise<void>;
// Subscribe to events (returns unsubscribe function)
subscribe(listener: (event: AgentSessionEvent) => void): () => void;
// Session info
sessionFile: string | undefined;
sessionId: string;
// Model control
setModel(model: Model): Promise<void>;
setThinkingLevel(level: ThinkingLevel): void;
cycleModel(): Promise<ModelCycleResult | undefined>;
cycleThinkingLevel(): ThinkingLevel | undefined;
// State access
agent: Agent;
model: Model | undefined;
thinkingLevel: ThinkingLevel;
messages: AgentMessage[];
isStreaming: boolean;
// In-place tree navigation within the current session file
navigateTree(targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }): Promise<{ editorText?: string; cancelled: boolean }>;
// Compaction
compact(customInstructions?: string): Promise<CompactionResult>;
abortCompaction(): void;
// Abort current operation
abort(): Promise<void>;
// Cleanup
dispose(): void;
}Thay thế phiên API chẳng hạn như phiên mới, tiếp tục, phân nhánh và nhập trực tiếp trên AgentSessionRuntime chứ không phải trên AgentSession.
createAgentSessionRuntime() và AgentSessionRuntime
Sử dụng thời gian chạy API khi bạn cần thay thế phiên hoạt động và xây dựng lại trạng thái thời gian chạy giới hạn cwd. Đây là cùng một lớp được sử dụng bởi các chế độ tương tác, in và RPC tích hợp sẵn.
createAgentSessionRuntime() lấy một nhà máy thời gian chạy cộng với mục tiêu cwd/phiên ban đầu. Nhà máy đóng các đầu vào cố định toàn quy trình, tạo lại các dịch vụ liên kết với cwd cho cwd hiệu quả, giải quyết các tùy chọn phiên đối với các dịch vụ đó và trả về kết quả thời gian chạy đầy đủ.
import {
type CreateAgentSessionRuntimeFactory,
createAgentSessionFromServices,
createAgentSessionRuntime,
createAgentSessionServices,
getAgentDir,
SessionManager,
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
return {
...(await createAgentSessionFromServices({
services,
sessionManager,
sessionStartEvent,
})),
services,
diagnostics: services.diagnostics,
};
};
const runtime = await createAgentSessionRuntime(createRuntime, {
cwd: process.cwd(),
agentDir: getAgentDir(),
sessionManager: SessionManager.create(process.cwd()),
});AgentSessionRuntime sở hữu sự thay thế thời gian chạy hoạt động trên:
newSession()switchSession()fork()- bản sao chảy qua
fork(entryId, { position: "at" }) importFromJsonl()
Hành vi quan trọng:
runtime.sessionthay đổi sau những thao tác đó- đăng ký sự kiện được đính kèm với một
AgentSessioncụ thể, vì vậy hãy đăng ký lại sau khi thay thế - nếu bạn sử dụng tiện ích mở rộng, hãy gọi lại
runtime.session.bindExtensions(...)cho phiên mới - quá trình tạo trả về chẩn đoán trên
runtime.diagnostics - nếu việc tạo hoặc thay thế thời gian chạy không thành công, phương thức sẽ được đưa ra và người gọi sẽ quyết định cách xử lý nó
let session = runtime.session;
let unsubscribe = session.subscribe(() => {});
await runtime.newSession();
unsubscribe();
session = runtime.session;
unsubscribe = session.subscribe(() => {});Nhắc nhở và xếp hàng tin nhắn
PromptOptions kiểm soát việc mở rộng lời nhắc, hành vi xếp hàng trong khi phát trực tuyến và nhắc nhở thông báo trước ánh sáng:
interface PromptOptions {
expandPromptTemplates?: boolean;
images?: ImageContent[];
streamingBehavior?: "steer" | "followUp";
source?: InputSource;
preflightResult?: (success: boolean) => void;
}preflightResult được gọi một lần cho mỗi lần gọi prompt():
truekhi lời nhắc được chấp nhận, xếp hàng hoặc xử lý ngay lập tứcfalsekhi lời nhắc preflight bị từ chối trước khi được chấp nhận
Nó kích hoạt trước khi prompt() được giải quyết. prompt() vẫn chỉ giải quyết sau khi quá trình chạy được chấp nhận hoàn toàn kết thúc, bao gồm cả lần thử lại. Các lỗi sau khi chấp nhận được báo cáo thông qua luồng sự kiện và tin nhắn thông thường, không phải thông qua preflightResult(false).
Phương thức prompt() xử lý prompt templates, các lệnh mở rộng và gửi tin nhắn:
// Basic prompt (when not streaming)
await session.prompt("What files are here?");
// With images
await session.prompt("What's in this image?", {
images: [{ type: "image", source: { type: "base64", mediaType: "image/png", data: "..." } }]
});
// During streaming: must specify how to queue the message
await session.prompt("Stop and do this instead", { streamingBehavior: "steer" });
await session.prompt("After you're done, also check X", { streamingBehavior: "followUp" });Hành vi:
- Lệnh mở rộng (ví dụ:
/mycommand): Thực thi ngay lập tức, ngay cả trong khi phát trực tuyến. Họ quản lý tương tác LLM của riêng mình thông quapi.sendMessage(). - Dựa trên tệp prompt templates (từ tệp
.md): Đã mở rộng sang nội dung của chúng trước khi gửi hoặc xếp hàng. - Trong khi phát trực tuyến mà không có
streamingBehavior: Xảy ra lỗi. Sử dụng trực tiếpsteer()hoặcfollowUp()hoặc chỉ định tùy chọn. preflightResult(true): Có nghĩa là lời nhắc đã được chấp nhận, xếp hàng hoặc xử lý ngay lập tức.preflightResult(false): Có nghĩa là chuyến bay trước bị từ chối trước khi được chấp nhận.
Để xếp hàng rõ ràng trong khi phát trực tuyến:
// Queue a steering message for delivery after the current assistant turn finishes its tool calls
await session.steer("New instruction");
// Wait for agent to finish (delivered only when agent stops)
await session.followUp("After you're done, also do this");Cả steer() và followUp() đều mở rộng prompt templates dựa trên tệp nhưng có lỗi trên các lệnh mở rộng (không thể xếp hàng các lệnh mở rộng).
Đại lý và Trạng thái đại lý
Lớp Agent (từ @earendil-works/pi-agent-core) xử lý tương tác LLM cốt lõi. Truy cập nó qua 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: AgentTool[] - available tools
// state.streamingMessage?: AgentMessage - current partial assistant message
// state.errorMessage?: string - latest assistant error
// Replace messages (useful for branching or restoration)
session.agent.state.messages = messages; // copies the top-level array
// Replace tools
session.agent.state.tools = tools; // copies the top-level array
// Wait for agent to finish processing
await session.agent.waitForIdle();Sự kiện
Đăng ký các sự kiện để nhận thông báo đầu ra và vòng đời phát trực tuyến.
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 (queue, compaction, retry)
case "queue_update":
console.log(event.steering, event.followUp);
break;
case "compaction_start":
case "compaction_end":
case "auto_retry_start":
case "auto_retry_end":
case "summarization_retry_scheduled":
case "summarization_retry_attempt_start":
case "summarization_retry_finished":
break;
}
});Tùy chọn tham khảo
Thư mục
const { session } = await createAgentSession({
// Working directory for DefaultResourceLoader discovery
cwd: process.cwd(), // default
// Global config directory
agentDir: "~/.pi/agent", // default (expands ~)
});cwd được sử dụng bởi DefaultResourceLoader cho:
- Mở rộng dự án (
.pi/extensions/) - Kỹ năng dự án:
.pi/skills/.agents/skills/trongcwdvà các thư mục tổ tiên (tối đa git repo root hoặc root hệ thống tập tin khi không có trong repo)
- Lời nhắc dự án (
.pi/prompts/) - Tệp ngữ cảnh (
AGENTS.mdđi lên từ cwd) - Đặt tên thư mục phiên
agentDir được sử dụng bởi DefaultResourceLoader cho:
- Tiện ích mở rộng toàn cầu (
extensions/) - Kỹ năng toàn cầu:
skills/dướiagentDir(ví dụ~/.pi/agent/skills/)~/.agents/skills/
- Lời nhắc chung (
prompts/) - Tệp ngữ cảnh chung (
AGENTS.md) - Cài đặt (
settings.json) - Mô hình tùy chỉnh (
models.json) - Thông tin xác thực (
auth.json) - Phiên (
sessions/)
Khi bạn chuyển một tùy chỉnh ResourceLoader, cwd và agentDir không còn kiểm soát việc khám phá tài nguyên nữa. Chúng vẫn ảnh hưởng đến việc đặt tên phiên và độ phân giải đường chạy dao.
Người mẫu
import { getModel } from "@earendil-works/pi-ai";
import { ModelRuntime } from "@earendil-works/pi-coding-agent";
const modelRuntime = await ModelRuntime.create();
// 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.json
// (doesn't check if API key exists)
const customModel = modelRuntime.getModel("my-provider", "my-model");
// Get only models that have valid authentication configured
const available = await modelRuntime.getAvailable();
const { session } = await createAgentSession({
model: opus,
thinkingLevel: "medium", // off, minimal, low, medium, high, xhigh, max
// Models for cycling (Ctrl+P in interactive mode)
scopedModels: [
{ model: opus, thinkingLevel: "high" },
{ model: haiku, thinkingLevel: "off" },
],
modelRuntime,
});Nếu không có mô hình nào được cung cấp:
- Cố gắng khôi phục từ phiên (nếu tiếp tục)
- Sử dụng mặc định từ cài đặt
- Quay trở lại mô hình có sẵn đầu tiên
Để khớp với phân tích cú pháp mô hình CLI, hãy sử dụng trình trợ giúp trình phân giải đã xuất:
import {
resolveCliModel,
resolveModelScopeWithDiagnostics,
} from "@earendil-works/pi-coding-agent";
const cliModel = resolveCliModel({
cliModel: "anthropic/claude-opus-4-5:high",
modelRuntime,
});
if (cliModel.error) throw new Error(cliModel.error);
if (cliModel.warning) console.warn(cliModel.warning);
const { scopedModels, diagnostics } = await resolveModelScopeWithDiagnostics(
["anthropic/*:high", "gpt-5"],
modelRuntime,
);
for (const diagnostic of diagnostics) {
console.warn(diagnostic.message);
}resolveCliModel() sử dụng tất cả các mô hình đã đăng ký nên thiết lập lần đầu tiên theo kiểu --api-key có thể giải quyết một mô hình trước khi tồn tại xác thực được lưu trữ. resolveModelScopeWithDiagnostics() khớp với ngữ nghĩa của --models và enabledModels trong khi trả lại cảnh báo thay vì in chúng.
API Chìa khóa và OAuth
Mức độ ưu tiên của độ phân giải xác thực (được xử lý bởi ModelRuntime):
- Ghi đè thời gian chạy (thông qua
setRuntimeApiKey, không được duy trì) - Thông tin xác thực được lưu trữ trong
auth.json(API keys hoặc OAuth mã thông báo) - Biến môi trường (
ANTHROPIC_API_KEY,OPENAI_API_KEY, v.v.) - Trình phân giải dự phòng (đối với khóa nhà cung cấp tùy chỉnh từ
models.json)
import { InMemoryCredentialStore } from "@earendil-works/pi-ai";
import { createAgentSession, ModelRuntime } from "@earendil-works/pi-coding-agent";
// Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
const modelRuntime = await ModelRuntime.create();
// Provider-owned auth methods and current status
for (const provider of modelRuntime.getProviders()) {
const status = await modelRuntime.checkAuth(provider.id);
console.log(provider.name, provider.auth, status);
}
// Runtime API key override (not persisted to disk)
await modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
// Custom credential and model locations
const customRuntime = await ModelRuntime.create({
authPath: "/my/app/auth.json",
modelsPath: "/my/app/models.json",
});
// Or inject any pi-ai CredentialStore
const credentials = new InMemoryCredentialStore();
const inMemoryRuntime = await ModelRuntime.create({ credentials });
const { session } = await createAgentSession({
modelRuntime: customRuntime,
});login(), logout(), setRuntimeApiKey() và removeRuntimeApiKey() giải quyết sau khi danh mục, thành phần và ảnh chụp nhanh tình trạng sẵn có được lưu vào bộ nhớ đệm/tích hợp của nhà cung cấp bị ảnh hưởng nhất quán cục bộ. Họ không chờ đợi sự cập nhật danh mục từ xa. Nếu thông tin xác thực đã được cam kết nhưng đồng bộ hóa cục bộ không thành công thì chúng sẽ từ chối bằng CredentialSynchronizationError đã xuất; kiểm tra các trường providerId, operation, credential và cause của nó thay vì thử lại đột biến thông tin xác thực một cách mù quáng.
Hoạt động mô hình/xác thực công khai và ModelRuntime.create({ signal }) chấp nhận tín hiệu hủy bỏ tùy chọn và không bị giới hạn khi bị bỏ qua. SDK chính sách về thời hạn của ứng dụng đối với việc làm mới danh mục từ xa:
const signal = AbortSignal.timeout(15_000);
const result = await modelRuntime.refresh({
providers: ["anthropic"],
signal,
});
if (result.aborted) console.warn("Catalog refresh timed out; using cached models");
for (const [providerId, error] of result.errors) {
console.warn(`Could not refresh ${providerId}:`, error);
}Việc làm mới mạng không thành công hoặc hết thời gian chờ sẽ không hoàn tác thao tác xác thực thành công. refresh() bắt đầu một thế hệ nhà cung cấp mới, do đó, nó không chờ đợi sau một lần làm mới cũ bị đình trệ và các thế hệ cũ không thể xuất bản sau đó.
Lời nhắc hệ thống
Sử dụng ResourceLoader để ghi đè lời nhắc hệ thống:
import { createAgentSession, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
systemPromptOverride: () => "You are a helpful assistant.",
});
await loader.reload();
const { session } = await createAgentSession({ resourceLoader: loader });Công cụ
Chỉ định những công cụ tích hợp nào sẽ bật:
- Tên công cụ tích hợp:
read,bash,edit,write,grep,find,ls - Các phần dựng sẵn mặc định:
read,bash,edit,write noTools: "all"vô hiệu hóa tất cả các công cụnoTools: "builtin"vô hiệu hóa các phần tích hợp mặc định trong khi vẫn bật tiện ích mở rộng và công cụ tùy chỉnhexcludeToolsvô hiệu hóa các tên công cụ tùy chỉnh, tiện ích mở rộng hoặc tích hợp cụ thể sau khi áp dụng bất kỳ danh sách cho phéptoolsnào
Công cụ edit trả về details.diff cho màn hình TUI của Pi và details.patch dưới dạng bản vá thống nhất tiêu chuẩn cho người tiêu dùng SDK.
import { createAgentSession } from "@earendil-works/pi-coding-agent";
// Read-only mode
const { session } = await createAgentSession({
tools: ["read", "grep", "find", "ls"],
});
// Pick specific tools
const { session } = await createAgentSession({
tools: ["read", "bash", "grep"],
});
// Disable one tool while keeping the rest available
const { session } = await createAgentSession({
excludeTools: ["ask_question"],
});Công cụ với cwd tùy chỉnh
Khi bạn chuyển một cwd tùy chỉnh, createAgentSession() sẽ xây dựng các công cụ tích hợp đã chọn cho cwd đó.
import { createAgentSession, SessionManager } from "@earendil-works/pi-coding-agent";
const cwd = "/path/to/project";
// Use default tools for custom cwd
const { session } = await createAgentSession({
cwd,
sessionManager: SessionManager.inMemory(cwd),
});
// Or pick specific tools for custom cwd
const { session } = await createAgentSession({
cwd,
tools: ["read", "bash", "grep"],
sessionManager: SessionManager.inMemory(cwd),
});Công cụ tùy chỉnh
import { Type } from "typebox";
import { createAgentSession, defineTool } from "@earendil-works/pi-coding-agent";
// Inline custom tool
const myTool = defineTool({
name: "my_tool",
label: "My Tool",
description: "Does something useful",
parameters: Type.Object({
input: Type.String({ description: "Input value" }),
}),
execute: async (_toolCallId, params) => ({
content: [{ type: "text", text: `Result: ${params.input}` }],
details: {},
}),
});
// Pass custom tools directly
const { session } = await createAgentSession({
customTools: [myTool],
});Sử dụng defineTool() cho các định nghĩa và mảng độc lập như customTools: [myTool]. Nội tuyến pi.registerTool({... }) đã suy ra chính xác các loại tham số.
Các công cụ tùy chỉnh được chuyển qua customTools được kết hợp với các công cụ đã đăng ký tiện ích mở rộng. Extensions được tải bởi ResourceLoader cũng có thể đăng ký các công cụ thông qua pi.registerTool().
Nếu bạn vượt qua tools, hãy bao gồm từng tên công cụ tùy chỉnh hoặc tiện ích mở rộng mà bạn muốn bật, ví dụ: tools: ["read", "bash", "my_tool"].
Extensions
Extensions được tải bởi ResourceLoader. DefaultResourceLoader khám phá các tiện ích mở rộng từ các nguồn tiện ích mở rộng ~/.pi/agent/extensions/, .pi/extensions/ và settings.json.
import { createAgentSession, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
additionalExtensionPaths: ["/path/to/my-extension.ts"],
extensionFactories: [
(pi) => {
pi.on("agent_start", () => {
console.log("[Inline Extension] Agent starting");
});
},
],
});
await loader.reload();
const { session } = await createAgentSession({ resourceLoader: loader });Extensions có thể đăng ký công cụ, đăng ký sự kiện, thêm lệnh, v.v. Xem extensions.md để biết đầy đủ API.
Tiện ích mở rộng nội tuyến được đặt tên: Theo mặc định, các nhà máy nội tuyến hiển thị dưới dạng <inline:1>, <inline:2>, v.v. trong danh sách khởi động Extensions. Thay vào đó, để hiển thị tên mô tả, hãy bọc nhà máy:
import type { InlineExtension } from "@earendil-works/pi-coding-agent";
const myProvider: InlineExtension = {
name: "my-provider",
factory: (pi) => {
pi.on("agent_start", () => {
console.log("[my-provider] Agent starting");
});
},
};
const loader = new DefaultResourceLoader({
extensionFactories: [myProvider],
});Điều này hiển thị dưới dạng <inline:my-provider> thay vì <inline:1>. Các chức năng của nhà máy trần vẫn được chấp nhận để tương thích ngược.
Xe buýt sự kiện: Extensions có thể giao tiếp qua pi.events. Chuyển eventBus được chia sẻ đến DefaultResourceLoader nếu bạn cần phát hoặc nghe từ bên ngoài:
import { createEventBus, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const eventBus = createEventBus();
const loader = new DefaultResourceLoader({
eventBus,
});
await loader.reload();
eventBus.on("my-extension:status", (data) => console.log(data));Skills
import {
createAgentSession,
DefaultResourceLoader,
type Skill,
} from "@earendil-works/pi-coding-agent";
const customSkill: Skill = {
name: "my-skill",
description: "Custom instructions",
filePath: "/path/to/SKILL.md",
baseDir: "/path/to",
source: "custom",
};
const loader = new DefaultResourceLoader({
skillsOverride: (current) => ({
skills: [...current.skills, customSkill],
diagnostics: current.diagnostics,
}),
});
await loader.reload();
const { session } = await createAgentSession({ resourceLoader: loader });Tệp ngữ cảnh
import { createAgentSession, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
agentsFilesOverride: (current) => ({
agentsFiles: [
...current.agentsFiles,
{ path: "/virtual/AGENTS.md", content: "# Guidelines\n\n- Be concise" },
],
}),
});
await loader.reload();
const { session } = await createAgentSession({ resourceLoader: loader });Lệnh gạch chéo
import {
createAgentSession,
DefaultResourceLoader,
type PromptTemplate,
} from "@earendil-works/pi-coding-agent";
const customCommand: PromptTemplate = {
name: "deploy",
description: "Deploy the application",
source: "(custom)",
content: "# Deploy\n\n1. Build\n2. Test\n3. Deploy",
};
const loader = new DefaultResourceLoader({
promptsOverride: (current) => ({
prompts: [...current.prompts, customCommand],
diagnostics: current.diagnostics,
}),
});
await loader.reload();
const { session } = await createAgentSession({ resourceLoader: loader });Quản lý phiên
Phiên sử dụng cấu trúc cây với liên kết id/parentId, cho phép phân nhánh tại chỗ.
import {
type CreateAgentSessionRuntimeFactory,
createAgentSession,
createAgentSessionFromServices,
createAgentSessionRuntime,
createAgentSessionServices,
getAgentDir,
SessionManager,
} from "@earendil-works/pi-coding-agent";
// In-memory (no persistence)
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
});
// New persistent session
const { session: persisted } = await createAgentSession({
sessionManager: SessionManager.create(process.cwd()),
});
// Continue most recent
const { session: continued, modelFallbackMessage } = await createAgentSession({
sessionManager: SessionManager.continueRecent(process.cwd()),
});
if (modelFallbackMessage) {
console.log("Note:", modelFallbackMessage);
}
// Open specific file
const { session: opened } = await createAgentSession({
sessionManager: SessionManager.open("/path/to/session.jsonl"),
});
// List sessions
const currentProjectSessions = await SessionManager.list(process.cwd());
const allSessions = await SessionManager.listAll(process.cwd());
// Session replacement API for /new, /resume, /fork, /clone, and import flows.
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
return {
...(await createAgentSessionFromServices({
services,
sessionManager,
sessionStartEvent,
})),
services,
diagnostics: services.diagnostics,
};
};
const runtime = await createAgentSessionRuntime(createRuntime, {
cwd: process.cwd(),
agentDir: getAgentDir(),
sessionManager: SessionManager.create(process.cwd()),
});
// Replace the active session with a fresh one
await runtime.newSession();
// Replace the active session with another saved session
await runtime.switchSession("/path/to/session.jsonl");
// Replace the active session with a fork from a specific user entry
await runtime.fork("entry-id");
// Clone the active path through a specific entry
await runtime.fork("entry-id", { position: "at" });Cây quản lý phiên API:
const sm = SessionManager.open("/path/to/session.jsonl");
// Session listing
const currentProjectSessions = await SessionManager.list(process.cwd());
const allSessions = await SessionManager.listAll(process.cwd());
// Tree traversal
const entries = sm.getEntries(); // All entries (excludes header)
const tree = sm.getTree(); // Full tree structure
const path = sm.getPath(); // 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 fileQuản lý cài đặt
import { createAgentSession, SettingsManager, SessionManager } from "@earendil-works/pi-coding-agent";
// Default: loads from files (global + project merged)
const { session } = await createAgentSession({
settingsManager: SettingsManager.create(),
});
// With overrides
const settingsManager = SettingsManager.create();
settingsManager.applyOverrides({
compaction: { enabled: false },
retry: { enabled: true, maxRetries: 5 },
});
const { session } = await createAgentSession({ settingsManager });
// In-memory (no file I/O, for testing)
const { session } = await createAgentSession({
settingsManager: SettingsManager.inMemory({ compaction: { enabled: false } }),
sessionManager: SessionManager.inMemory(),
});
// Custom directories
const { session } = await createAgentSession({
settingsManager: SettingsManager.create("/custom/cwd", "/custom/agent"),
});Nhà máy tĩnh:
SettingsManager.create(cwd?, agentDir?)- Tải từ tập tinSettingsManager.inMemory(settings?)- Không có tệp vào/ra
Cài đặt dành riêng cho dự án:
Tải cài đặt từ hai vị trí và hợp nhất:
- Toàn cầu:
~/.pi/agent/settings.json - Dự án:
<cwd>/.pi/settings.json
Dự án ghi đè toàn cầu. Các đối tượng lồng nhau hợp nhất các khóa. Setters sửa đổi cài đặt chung theo mặc định.
Ngữ nghĩa xử lý kiên trì và lỗi:
- Getters/setters cài đặt đồng bộ cho trạng thái trong bộ nhớ.
- Tính kiên trì của Setters enqueue ghi không đồng bộ.
- Gọi
await settingsManager.flush()khi bạn cần ranh giới độ bền (ví dụ: trước khi thoát quá trình hoặc trước khi xác nhận nội dung tệp trong các bài kiểm tra). SettingsManagerkhông in các lỗi I/O cài đặt. Sử dụngsettingsManager.drainErrors()và báo cáo chúng trong lớp ứng dụng của bạn.
Trình tải tài nguyên
Sử dụng DefaultResourceLoader để khám phá các tiện ích mở rộng, kỹ năng, lời nhắc, chủ đề và context files.
import {
DefaultResourceLoader,
getAgentDir,
} from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
cwd,
agentDir: getAgentDir(),
});
await loader.reload();
const extensions = loader.getExtensions();
const skills = loader.getSkills();
const prompts = loader.getPrompts();
const themes = loader.getThemes();
const contextFiles = loader.getAgentsFiles().agentsFiles;Giá trị trả về
createAgentSession() trả về:
interface CreateAgentSessionResult {
// The session
session: AgentSession;
// Extensions result (for runner setup)
extensionsResult: LoadExtensionsResult;
// Warning if session model couldn't be restored
modelFallbackMessage?: string;
}
interface LoadExtensionsResult {
extensions: Extension[];
errors: Array<{ path: string; error: string }>;
runtime: ExtensionRuntime;
}Ví dụ hoàn chỉnh
import { getModel } from "@earendil-works/pi-ai";
import { Type } from "typebox";
import {
createAgentSession,
DefaultResourceLoader,
defineTool,
ModelRuntime,
SessionManager,
SettingsManager,
} from "@earendil-works/pi-coding-agent";
const modelRuntime = await ModelRuntime.create({
authPath: "/custom/agent/auth.json",
modelsPath: "/custom/agent/models.json",
});
if (process.env.MY_KEY) {
await modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY);
}
// Inline tool
const statusTool = defineTool({
name: "status",
label: "Status",
description: "Get system status",
parameters: Type.Object({}),
execute: async () => ({
content: [{ type: "text", text: `Uptime: ${process.uptime()}s` }],
details: {},
}),
});
const model = getModel("anthropic", "claude-opus-4-5");
if (!model) throw new Error("Model not found");
// In-memory settings with overrides
const settingsManager = SettingsManager.inMemory({
compaction: { enabled: false },
retry: { enabled: true, maxRetries: 2 },
});
const loader = new DefaultResourceLoader({
cwd: process.cwd(),
agentDir: "/custom/agent",
settingsManager,
systemPromptOverride: () => "You are a minimal assistant. Be concise.",
});
await loader.reload();
const { session } = await createAgentSession({
cwd: process.cwd(),
agentDir: "/custom/agent",
model,
thinkingLevel: "off",
modelRuntime,
tools: ["read", "bash", "status"],
customTools: [statusTool],
resourceLoader: loader,
sessionManager: SessionManager.inMemory(),
settingsManager,
});
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.");Chế độ chạy
SDK xuất các tiện ích chế độ chạy để xây dựng giao diện tùy chỉnh trên createAgentSession():
Chế độ tương tác
Chế độ tương tác đầy đủ TUI với trình chỉnh sửa, lịch sử trò chuyện và tất cả các lệnh tích hợp:
import {
type CreateAgentSessionRuntimeFactory,
createAgentSessionFromServices,
createAgentSessionRuntime,
createAgentSessionServices,
getAgentDir,
InteractiveMode,
SessionManager,
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
return {
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
services,
diagnostics: services.diagnostics,
};
};
const runtime = await createAgentSessionRuntime(createRuntime, {
cwd: process.cwd(),
agentDir: getAgentDir(),
sessionManager: SessionManager.create(process.cwd()),
});
const mode = new InteractiveMode(runtime, {
migratedProviders: [],
modelFallbackMessage: undefined,
initialMessage: "Hello",
initialImages: [],
initialMessages: [],
});
await mode.run();runPrintMode
Chế độ chụp một lần: gửi lời nhắc, kết quả đầu ra, thoát:
import {
type CreateAgentSessionRuntimeFactory,
createAgentSessionFromServices,
createAgentSessionRuntime,
createAgentSessionServices,
getAgentDir,
runPrintMode,
SessionManager,
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
return {
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
services,
diagnostics: services.diagnostics,
};
};
const runtime = await createAgentSessionRuntime(createRuntime, {
cwd: process.cwd(),
agentDir: getAgentDir(),
sessionManager: SessionManager.create(process.cwd()),
});
await runPrintMode(runtime, {
mode: "text",
initialMessage: "Hello",
initialImages: [],
messages: ["Follow up"],
});runRpcMode
Chế độ JSON-RPC để tích hợp quy trình con:
import {
type CreateAgentSessionRuntimeFactory,
createAgentSessionFromServices,
createAgentSessionRuntime,
createAgentSessionServices,
getAgentDir,
runRpcMode,
SessionManager,
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
return {
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
services,
diagnostics: services.diagnostics,
};
};
const runtime = await createAgentSessionRuntime(createRuntime, {
cwd: process.cwd(),
agentDir: getAgentDir(),
sessionManager: SessionManager.create(process.cwd()),
});
await runRpcMode(runtime);Xem RPC documentation để biết giao thức JSON.
RPC Chế độ thay thế
Để tích hợp dựa trên quy trình con mà không cần xây dựng bằng SDK, hãy sử dụng trực tiếp CLI:
pi --mode rpc --no-sessionXem RPC documentation để biết giao thức JSON.
SDK được ưu tiên khi:
- Bạn muốn loại an toàn
- Bạn đang trong quá trình Node.js tương tự
- Bạn cần truy cập trực tiếp vào trạng thái đại lý
- Bạn muốn tùy chỉnh các công cụ/tiện ích mở rộng theo chương trình
Chế độ RPC được ưu tiên khi:
- Bạn đang tích hợp từ một ngôn ngữ khác
- Bạn muốn cách ly quá trình
- Bạn đang xây dựng một ứng dụng khách không phân biệt ngôn ngữ
Xuất khẩu
Các điểm xuất khẩu chính:
// Factory
createAgentSession
createAgentSessionRuntime
AgentSessionRuntime
// Auth and Models
ModelRuntime // implements pi-ai Models and owns credential storage
ModelRegistry // synchronous extension compatibility facade
CredentialSynchronizationError
resolveCliModel
resolveModelScopeWithDiagnostics
// Resource loading
DefaultResourceLoader
type ResourceLoader
createEventBus
// Constants and helpers
CONFIG_DIR_NAME
defineTool
getAgentDir
getPackageDir
getReadmePath
getDocsPath
getExamplesPath
// Session management
SessionManager
SettingsManager
// Tool factories
createCodingTools
createReadOnlyTools
createReadTool, createBashTool, createEditTool, createWriteTool
createGrepTool, createFindTool, createLsTool
// Types
type CreateAgentSessionOptions
type CreateAgentSessionResult
type ExtensionFactory
type InlineExtension
type ExtensionAPI
type ToolDefinition
type Skill
type PromptTemplate
type ToolĐối với các loại tiện ích mở rộng, hãy xem extensions.md để biết đầy đủ API.