SDK
pi, SDK'yi kullanmanıza yardımcı olabilir. Kullanım durumunuz için bir entegrasyon oluşturmasını isteyin.
SDK pi'nin aracı yeteneklerine programlı erişim sağlar. Pi'yi diğer uygulamalara eklemek, özel arayüzler oluşturmak veya otomatik iş akışlarıyla entegre etmek için kullanın.
Örnek kullanım durumları:
- Özel bir kullanıcı arayüzü oluşturun (web, masaüstü, mobil)
- Aracı yeteneklerini mevcut uygulamalara entegre edin
- Aracı mantığıyla otomatik işlem hatları oluşturun
- Alt aracıları ortaya çıkaran özel araçlar oluşturun
- Aracı davranışını programlı olarak test edin
Minimumdan tam kontrole kadar çalışma örnekleri için examples/sdk/'e bakın.
Hızlı Başlangıç
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?");Kurulum
npm install @earendil-works/pi-coding-agentSDK ana pakete dahildir. Ayrı bir kuruluma gerek yoktur.
Temel Kavramlar
createAgentSession()
Tek bir AgentSession için ana fabrika işlevi.
createAgentSession(), uzantıları, becerileri, prompt templates, temaları ve context files sağlamak için ResourceLoader'yi kullanır. Eğer bir tane sağlamazsanız standart keşifle DefaultResourceLoader kullanır.
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(),
});Temsilci Oturumu
Oturum, aracı yaşam döngüsünü, mesaj geçmişini, model durumunu, sıkıştırmayı ve olay akışını yönetir.
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;
}Yeni oturum, özgeçmiş, çatal ve içe aktarma gibi oturum değiştirme API'ler, AgentSession'de değil, AgentSessionRuntime'da yayındadır.
createAgentSessionRuntime() ve AgentSessionRuntime
Etkin oturumu değiştirmeniz ve cwd'ye bağlı çalışma zamanı durumunu yeniden oluşturmanız gerektiğinde API çalışma zamanını kullanın. Bu, yerleşik etkileşimli, yazdırma ve RPC modları tarafından kullanılan katmanın aynısıdır.
createAgentSessionRuntime() çalışma zamanı fabrikasını artı başlangıç cwd/oturum hedefini alır. Fabrika, süreç geneli sabit girdiler üzerinden kapanır, etkili cwd için cwd'ye bağlı hizmetleri yeniden oluşturur, bu hizmetlere göre oturum seçeneklerini çözümler ve tam çalışma zamanı sonucunu döndürür.
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 aşağıdakiler arasında etkin çalışma zamanının değiştirilmesine sahiptir:
newSession()switchSession()fork()- klon
fork(entryId, { position: "at" })üzerinden akar importFromJsonl()
Önemli davranış:
runtime.sessionbu işlemlerden sonraki değişiklikler- etkinlik abonelikleri belirli bir
AgentSession'ye bağlıdır, bu nedenle değiştirdikten sonra yeniden abone olun - Uzantı kullanıyorsanız yeni oturum için
runtime.session.bindExtensions(...)'ı tekrar arayın - oluşturma
runtime.diagnostics'de teşhis döndürür - çalışma zamanı oluşturma veya değiştirme başarısız olursa, yöntem çalışır ve arayan kişi bunun nasıl ele alınacağına karar verir
let session = runtime.session;
let unsubscribe = session.subscribe(() => {});
await runtime.newSession();
unsubscribe();
session = runtime.session;
unsubscribe = session.subscribe(() => {});İstemde Bulunma ve Mesaj Kuyruğa Alma
PromptOptions istem genişletmeyi, akış sırasında sıraya alma davranışını ve istem ön kontrol bildirimlerini kontrol eder:
interface PromptOptions {
expandPromptTemplates?: boolean;
images?: ImageContent[];
streamingBehavior?: "steer" | "followUp";
source?: InputSource;
preflightResult?: (success: boolean) => void;
}preflightResult, prompt() çağrı başına bir kez çağrılır:
trueistemin kabul edildiği, kuyruğa alındığı veya hemen işlendiği zamanfalseistem ön kontrolü kabul edilmeden önce reddedildiğinde
prompt() çözümlenmeden önce ateşlenir. prompt() yeniden denemeler de dahil olmak üzere yalnızca kabul edilen çalıştırmanın tamamı bittikten sonra çözümlenmeye devam ediyor. Kabulden sonraki arızalar preflightResult(false) aracılığıyla değil, normal olay ve mesaj akışı aracılığıyla raporlanır.
prompt() yöntemi prompt templates'yi, uzantı komutlarını ve mesaj göndermeyi yönetir:
// 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" });Davranış:
- Uzantı komutları (ör.
/mycommand): Yayın sırasında bile hemen yürütülür. Kendi LLM etkileşimlerinipi.sendMessage()aracılığıyla yönetirler. - Dosya tabanlı prompt templates (
.mddosyalardan): Göndermeden veya kuyruğa almadan önce içeriklerine genişletilir. streamingBehaviorolmadan akış sırasında: Bir hata verir. Doğrudansteer()veyafollowUp()kullanın veya seçeneği belirtin.preflightResult(true): İstemin hemen kabul edildiği, kuyruğa alındığı veya işlendiği anlamına gelir.preflightResult(false): Ön kontrolün kabul edilmeden önce reddedildiği anlamına gelir.
Akış sırasında açık sıraya alma için:
// 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");Hem steer() hem de followUp() dosya tabanlı prompt templates'yi genişletiyor ancak uzantı komutlarında hata var (uzantı komutları sıraya alınamıyor).
Acente ve Acente Durumu
Agent sınıfı (@earendil-works/pi-agent-core'den itibaren) temel LLM etkileşimini yönetir. session.agent aracılığıyla erişin.
// 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();Olaylar
Akış çıktısı ve yaşam döngüsü bildirimlerini almak için etkinliklere abone olun.
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;
}
});Seçenek Referansı
Dizinler
const { session } = await createAgentSession({
// Working directory for DefaultResourceLoader discovery
cwd: process.cwd(), // default
// Global config directory
agentDir: "~/.pi/agent", // default (expands ~)
});cwd, DefaultResourceLoader tarafından şu amaçlarla kullanılır:
- Proje uzantıları (
.pi/extensions/) - Proje becerileri:
.pi/skills/cwdve ata dizinlerinde.agents/skills/(git repo köküne veya repoda olmadığında dosya sistemi köküne kadar)
- Proje istemleri (
.pi/prompts/) - Bağlam dosyaları (
AGENTS.mdcwd'den yukarı doğru yürürken) - Oturum dizini adlandırma
agentDir, DefaultResourceLoader tarafından şu amaçlarla kullanılır:
- Küresel uzantılar (
extensions/) - Küresel beceriler:
skills/agentDir'nin altında (örneğin~/.pi/agent/skills/)~/.agents/skills/
- Genel istemler (
prompts/) - Genel içerik dosyası (
AGENTS.md) - Ayarlar (
settings.json) - Özel modeller (
models.json) - Kimlik Bilgileri (
auth.json) - Oturumlar (
sessions/)
Özel bir ResourceLoader, cwd ve agentDir'yi ilettiğinizde artık kaynak keşfi kontrol edilmez. Bunlar hâlâ oturum adlandırma ve araç yolu çözümlemesini etkilemektedir.
Modeli
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,
});Herhangi bir model sağlanmadıysa:
- Oturumdan geri yüklemeye çalışır (devam ediyorsa)
- Ayarlardaki varsayılanı kullanır
- Mevcut ilk modele geri döner
CLI model ayrıştırmayı eşleştirmek için dışa aktarılan çözümleyici yardımcılarını kullanın:
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() tüm kayıtlı modelleri kullanır, böylece --api-key tarzı ilk kurulum, kayıtlı kimlik doğrulama mevcut olmadan önce bir modeli çözebilir. resolveModelScopeWithDiagnostics(), uyarıları yazdırmak yerine geri döndürürken --models ve enabledModels anlambilimiyle eşleşir.
API Tuşlar ve OAuth
Kimlik doğrulama çözümleme önceliği (ModelRuntime tarafından yönetilir):
- Çalışma zamanı geçersiz kılmaları (
setRuntimeApiKeyaracılığıyla, kalıcı değil) - Kimlik bilgileri
auth.json(API keys veya OAuth jetonları) içinde depolanır - Ortam değişkenleri (
ANTHROPIC_API_KEY,OPENAI_API_KEY, vb.) - Geri dönüş çözümleyici (
models.json'den itibaren özel sağlayıcı anahtarları için)
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() ve removeRuntimeApiKey(), etkilenen sağlayıcının önbelleğe alınmış/yerleşik kataloğu, kompozisyonu ve kullanılabilirlik anlık görüntüsünün yerel olarak tutarlı olmasından sonra çözümlenir. Uzaktan katalog tazeliğini beklemiyorlar. Kimlik bilgileri kaydedildiyse ancak yerel senkronizasyon başarısız olursa, dışa aktarılan CredentialSynchronizationError ile reddedilir; Kimlik bilgisi mutasyonunu körü körüne yeniden denemek yerine providerId, operation, credential ve cause alanlarını inceleyin.
Genel model/kimlik doğrulama işlemleri ve ModelRuntime.create({ signal }) isteğe bağlı iptal sinyallerini kabul eder ve atlandığında sınırsızdır. SDK uygulamaların uzaktan kataloğun güncellenmesi için kendi son tarih politikası:
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);
}Başarısız olan veya zaman aşımına uğrayan bir ağ yenilemesi, başarılı bir kimlik bilgisi işlemini geri almaz. refresh() yeni bir sağlayıcı nesli başlatır, böylece eski durmuş yenilemenin arkasında beklemez ve eski nesiller daha sonra yayınlayamaz.
Sistem İstemi
Sistem istemini geçersiz kılmak için ResourceLoader kullanın:
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 });Aletler
Hangi yerleşik araçların etkinleştirileceğini belirtin:
- Yerleşik araç adları:
read,bash,edit,write,grep,find,ls - Varsayılan yerleşikler:
read,bash,edit,write noTools: "all"tüm araçları devre dışı bırakırnoTools: "builtin"uzantıları ve özel araçları etkin tutarken varsayılan yerleşikleri devre dışı bırakırexcludeToolsherhangi birtoolsizin verilenler listesi uygulandıktan sonra belirli yerleşik, uzantı veya özel araç adlarını devre dışı bırakır
edit aracı, Pi'nin TUI ekranı için details.diff'yi ve SDK tüketiciler için standart birleştirilmiş yama olarak details.patch'yi döndürür.
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"],
});Özel cwd'li araçlar
Özel bir cwd ilettiğinizde, createAgentSession() o cwd için seçilen yerleşik araçları oluşturur.
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),
});Özel Araçlar
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],
});Bağımsız tanımlar ve customTools: [myTool] gibi diziler için defineTool() kullanın. Satır içi pi.registerTool({... }) parametre türlerini zaten doğru bir şekilde çıkarıyor.
customTools aracılığıyla aktarılan özel araçlar, uzantıya kayıtlı araçlarla birleştirilir. ResourceLoader tarafından yüklenen Extensions aynı zamanda araçları pi.registerTool() aracılığıyla da kaydedebilir.
tools değerini geçerseniz, etkinleştirilmesini istediğiniz her özel veya uzantı aracı adını ekleyin, örneğin tools: ["read", "bash", "my_tool"].
Extensions
Extensions, ResourceLoader tarafından yüklenir. DefaultResourceLoader, ~/.pi/agent/extensions/, .pi/extensions/ ve settings.json uzantı kaynaklarından uzantıları keşfeder.
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 araçları kaydedebilir, etkinliklere abone olabilir, komutlar ekleyebilir ve daha fazlasını yapabilir. API'nin tamamı için extensions.md'ye bakın.
Adlandırılmış satır içi uzantılar: Varsayılan olarak, satır içi fabrikalar başlangıç Extensions listesinde <inline:1>, <inline:2> vb. olarak görüntülenir. Bunun yerine açıklayıcı bir ad göstermek için fabrikayı sarın:
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],
});Bu, <inline:1> yerine <inline:my-provider> olarak görüntülenir. Geriye dönük uyumluluk açısından çıplak fabrika işlevleri hâlâ kabul edilmektedir.
Olay Veriyolu: Extensions pi.events aracılığıyla iletişim kurabilir. Dışarıdan ses çıkarmanız veya dinlemeniz gerekiyorsa, paylaşılan eventBus'den DefaultResourceLoader'ye iletin:
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 });Bağlam Dosyaları
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 });Eğik Çizgi Komutları
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 });Oturum Yönetimi
Oturumlar, yerinde dallanmaya olanak tanıyan id/parentId bağlantılı bir ağaç yapısı kullanır.
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" });SessionManager ağacı 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 fileAyarlar Yönetimi
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"),
});Statik fabrikalar:
SettingsManager.create(cwd?, agentDir?)- Dosyalardan yükleSettingsManager.inMemory(settings?)- Dosya G/Ç yok
Projeye özel ayarlar:
Ayarlar iki konumdan yüklenir ve birleştirilir:
- Küresel:
~/.pi/agent/settings.json - Proje:
<cwd>/.pi/settings.json
Proje globali geçersiz kılar. İç içe geçmiş nesneler anahtarları birleştirir. Ayarlayıcılar varsayılan olarak genel ayarları değiştirir.
Kalıcılık ve hata işleme anlambilimi:
- Ayar alıcıları/ayarlayıcıları bellek içi durum için eşzamanlıdır.
- Ayarlayıcılar kalıcılık yazmalarını eşzamansız olarak kuyruğa alır.
- Dayanıklılık sınırına ihtiyaç duyduğunuzda (örneğin, işlemden çıkmadan önce veya testlerde dosya içeriklerini belirtmeden önce)
await settingsManager.flush()'ı çağırın. SettingsManagerayarlar G/Ç hatalarını yazdırmaz.settingsManager.drainErrors()kullanın ve bunları uygulama katmanınızda raporlayın.
Kaynak Yükleyici
Uzantıları, becerileri, istemleri, temaları ve context files'yi keşfetmek için DefaultResourceLoader'yi kullanın.
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;Dönüş Değeri
createAgentSession() şunu döndürür:
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;
}Tam Örnek
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.");Çalıştırma Modları
SDK, createAgentSession()'nin üzerine özel arayüzler oluşturmak için çalışma modu yardımcı programlarını dışa aktarır:
Etkileşimli Mod
Düzenleyici, sohbet geçmişi ve tüm yerleşik komutlarla tam TUI etkileşimli mod:
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'u çalıştır
Tek çekim modu: istem gönderme, sonuç çıktısı, çıkış:
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'u çalıştır
Alt süreç entegrasyonu için JSON-RPC modu:
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);JSON protokolü için RPC documentation'ye bakın.
RPC Mod Alternatifi
SDK ile derleme yapmadan alt süreç tabanlı entegrasyon için doğrudan CLI'yi kullanın:
pi --mode rpc --no-sessionJSON protokolü için RPC documentation'ye bakın.
SDK şu durumlarda tercih edilir:
- Tip güvenliği istiyorsunuz
- Siz de aynı Node.js sürecindesiniz
- Temsilci durumuna doğrudan erişmeniz gerekiyor
- Araçları/uzantıları programlı olarak özelleştirmek istiyorsunuz
RPC modu şu durumlarda tercih edilir:
- Başka bir dilden entegrasyon yapıyorsunuz
- Süreç izolasyonu istiyorsunuz
- Dilden bağımsız bir istemci oluşturuyorsunuz
İhracat
Ana giriş noktası ihracatları:
// 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 ToolUzantı türleri için, API'nin tamamı için extensions.md'ye bakın.