Pi için yapılandırma, özelleştirme, platform kurulumu ve API referansları.

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-agent

SDK 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.session bu 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:

  • true istemin kabul edildiği, kuyruğa alındığı veya hemen işlendiği zaman
  • false istem ö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şimlerini pi.sendMessage() aracılığıyla yönetirler.
  • Dosya tabanlı prompt templates (.md dosyalardan): Göndermeden veya kuyruğa almadan önce içeriklerine genişletilir.
  • streamingBehavior olmadan akış sırasında: Bir hata verir. Doğrudan steer() veya followUp() 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/
    • cwd ve 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.md cwd'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:

  1. Oturumdan geri yüklemeye çalışır (devam ediyorsa)
  2. Ayarlardaki varsayılanı kullanır
  3. 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.

Bkz. examples/sdk/02-custom-model.ts

API Tuşlar ve OAuth

Kimlik doğrulama çözümleme önceliği (ModelRuntime tarafından yönetilir):

  1. Çalışma zamanı geçersiz kılmaları (setRuntimeApiKey aracılığıyla, kalıcı değil)
  2. Kimlik bilgileri auth.json (API keys veya OAuth jetonları) içinde depolanır
  3. Ortam değişkenleri (ANTHROPIC_API_KEY, OPENAI_API_KEY, vb.)
  4. 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.

Bkz. examples/sdk/09-api-keys-and-oauth.ts

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 });

Bkz. examples/sdk/03-custom-prompt.ts

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ır
  • noTools: "builtin" uzantıları ve özel araçları etkin tutarken varsayılan yerleşikleri devre dışı bırakır
  • excludeTools herhangi bir tools izin 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),
});

Bkz. examples/sdk/05-tools.ts

Ö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"].

Bkz. examples/sdk/05-tools.ts

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));

Bkz. examples/sdk/06-extensions.ts ve docs/extensions.md

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 });

Bkz. examples/sdk/04-skills.ts

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 });

Bkz. examples/sdk/07-context-files.ts

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 });

Bkz. examples/sdk/08-prompt-templates.ts

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 file

Bkz. examples/sdk/11-sessions.ts ve Session Format

Ayarlar 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ükle
  • SettingsManager.inMemory(settings?) - Dosya G/Ç yok

Projeye özel ayarlar:

Ayarlar iki konumdan yüklenir ve birleştirilir:

  1. Küresel: ~/.pi/agent/settings.json
  2. 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.
  • SettingsManager ayarlar G/Ç hatalarını yazdırmaz. settingsManager.drainErrors() kullanın ve bunları uygulama katmanınızda raporlayın.

Bkz. examples/sdk/10-settings.ts

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-session

JSON 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 Tool

Uzantı türleri için, API'nin tamamı için extensions.md'ye bakın.