Arsitektur Integrasi Pi
Dokumen ini menjelaskan bagaimana Mayros berintegrasi dengan pi-coding-agent dan paket saudaranya (pi-ai, pi-agent-core, pi-tui) untuk mendukung kemampuan agen AI-nya.
Ringkasan
Mayros menggunakan SDK pi untuk menyematkan agen coding AI ke dalam arsitektur gateway pesan. Alih-alih menelurkan pi sebagai subprocess atau menggunakan mode RPC, Mayros langsung mengimpor dan membuat instance AgentSession pi melalui createAgentSession(). Pendekatan embedded ini menyediakan:
- Kontrol penuh atas siklus hidup sesi dan penanganan event
- Injeksi tool kustom (pesan, sandbox, aksi spesifik channel)
- Kustomisasi system prompt per channel/konteks
- Persistensi sesi dengan dukungan branching/compaction
- Rotasi profil auth multi-akun dengan failover
- Peralihan model yang agnostik provider
Dependensi Paket
json{ "@mariozechner/pi-agent-core": "0.49.3", "@mariozechner/pi-ai": "0.49.3", "@mariozechner/pi-coding-agent": "0.49.3", "@mariozechner/pi-tui": "0.49.3" }
| Paket | Tujuan |
|---|---|
pi-ai | Abstraksi LLM inti: Model, streamSimple, tipe pesan, API provider |
pi-agent-core | Loop agen, eksekusi tool, tipe AgentMessage |
pi-coding-agent | SDK tingkat tinggi: createAgentSession, SessionManager, AuthStorage, ModelRegistry, tool bawaan |
pi-tui | Komponen UI terminal (digunakan dalam mode TUI lokal Mayros) |
Alur Integrasi Inti
1. Menjalankan Embedded Agent
Entry point utama adalah runEmbeddedPiAgent() di pi-embedded-runner/run.ts:
typescriptimport { runEmbeddedPiAgent } from "./agents/pi-embedded-runner.js"; const result = await runEmbeddedPiAgent({ sessionId: "user-123", sessionKey: "main:whatsapp:+1234567890", sessionFile: "/path/to/session.jsonl", workspaceDir: "/path/to/workspace", config: mayrosConfig, prompt: "Hello, how are you?", provider: "anthropic", model: "claude-sonnet-4-20250514", timeoutMs: 120_000, runId: "run-abc", onBlockReply: async (payload) => { await sendToChannel(payload.text, payload.mediaUrls); }, });
2. Pembuatan Sesi
Di dalam runEmbeddedAttempt() (dipanggil oleh runEmbeddedPiAgent()), SDK pi digunakan:
typescriptimport { createAgentSession, DefaultResourceLoader, SessionManager, SettingsManager, } from "@mariozechner/pi-coding-agent"; const resourceLoader = new DefaultResourceLoader({ cwd: resolvedWorkspace, agentDir, settingsManager, additionalExtensionPaths, }); await resourceLoader.reload(); const { session } = await createAgentSession({ cwd: resolvedWorkspace, agentDir, authStorage: params.authStorage, modelRegistry: params.modelRegistry, model: params.model, thinkingLevel: mapThinkingLevel(params.thinkLevel), tools: builtInTools, customTools: allCustomTools, sessionManager, settingsManager, resourceLoader, }); applySystemPromptOverrideToSession(session, systemPromptOverride);
3. Subscription Event
subscribeEmbeddedPiSession() berlangganan event AgentSession pi:
typescriptconst subscription = subscribeEmbeddedPiSession({ session: activeSession, runId: params.runId, verboseLevel: params.verboseLevel, reasoningMode: params.reasoningLevel, toolResultFormat: params.toolResultFormat, onToolResult: params.onToolResult, onReasoningStream: params.onReasoningStream, onBlockReply: params.onBlockReply, onPartialReply: params.onPartialReply, onAgentEvent: params.onAgentEvent, });
Event yang ditangani meliputi:
message_start/message_end/message_update(streaming teks/thinking)tool_execution_start/tool_execution_update/tool_execution_endturn_start/turn_endagent_start/agent_endauto_compaction_start/auto_compaction_end
4. Prompting
Setelah pengaturan, sesi diprompt:
typescriptawait session.prompt(effectivePrompt, { images: imageResult.images });
SDK menangani loop agen lengkap: mengirim ke LLM, mengeksekusi tool call, streaming respons.
Arsitektur Tool
Pipeline Tool
- Base Tools:
codingToolspi (read, bash, edit, write) - Custom Replacement: Mayros mengganti bash dengan
exec/process, menyesuaikan read/edit/write untuk sandbox - Mayros Tools: messaging, browser, canvas, sessions, cron, gateway, dll.
- Channel Tools: Tool aksi spesifik Discord/Telegram/Slack/WhatsApp
- Policy Filtering: Tool difilter berdasarkan profil, provider, agen, grup, kebijakan sandbox
- Schema Normalization: Skema dibersihkan untuk quirk Gemini/OpenAI
- AbortSignal Wrapping: Tool dibungkus untuk menghormati abort signal
Tool Definition Adapter
AgentTool pi-agent-core memiliki signature execute yang berbeda dari ToolDefinition pi-coding-agent. Adapter di pi-tool-definition-adapter.ts menjembatani ini:
typescriptexport function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] { return tools.map((tool) => ({ name: tool.name, label: tool.label ?? name, description: tool.description ?? "", parameters: tool.parameters, execute: async (toolCallId, params, onUpdate, _ctx, signal) => { // pi-coding-agent signature differs from pi-agent-core return await tool.execute(toolCallId, params, signal, onUpdate); }, })); }
Strategi Tool Split
splitSdkTools() melewatkan semua tool melalui customTools:
typescriptexport function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled: boolean }) { return { builtInTools: [], // Empty. We override everything customTools: toToolDefinitions(options.tools), }; }
Ini memastikan filtering kebijakan Mayros, integrasi sandbox, dan toolset yang diperluas tetap konsisten di seluruh provider.
Konstruksi System Prompt
System prompt dibangun di buildAgentSystemPrompt() (system-prompt.ts). Ini merakit prompt lengkap dengan bagian termasuk Tooling, Tool Call Style, Safety guardrail, referensi CLI Mayros, Skills, Docs, Workspace, Sandbox, Messaging, Reply Tags, Voice, Silent Replies, Heartbeats, metadata Runtime, plus Memory dan Reactions ketika diaktifkan, dan file konteks opsional serta konten system prompt ekstra. Bagian dipangkas untuk mode prompt minimal yang digunakan oleh subagen.
Prompt diterapkan setelah pembuatan sesi melalui applySystemPromptOverrideToSession():
typescriptconst systemPromptOverride = createSystemPromptOverride(appendPrompt); applySystemPromptOverrideToSession(session, systemPromptOverride);
Manajemen Sesi
File Sesi
Sesi adalah file JSONL dengan struktur pohon (penautan id/parentId). SessionManager Pi menangani persistensi:
typescriptconst sessionManager = SessionManager.open(params.sessionFile);
Mayros membungkus ini dengan guardSessionManager() untuk keamanan hasil tool.
Caching Sesi
session-manager-cache.ts menyimpan instance SessionManager untuk menghindari parsing file berulang:
typescriptawait prewarmSessionFile(params.sessionFile); sessionManager = SessionManager.open(params.sessionFile); trackSessionManagerAccess(params.sessionFile);
Autentikasi & Resolusi Model
Profil Auth
Mayros memelihara penyimpanan profil auth dengan beberapa API key per provider:
typescriptconst authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false }); const profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });
Profil berputar pada kegagalan dengan pelacakan cooldown:
typescriptawait markAuthProfileFailure({ store, profileId, reason, cfg, agentDir }); const rotated = await advanceAuthProfile();
Resolusi Model
typescriptimport { resolveModel } from "./pi-embedded-runner/model.js"; const { model, error, authStorage, modelRegistry } = resolveModel( provider, modelId, agentDir, config, ); // Uses pi's ModelRegistry and AuthStorage authStorage.setRuntimeApiKey(model.provider, apiKeyInfo.apiKey);
Ekstensi Pi
Mayros memuat ekstensi pi kustom untuk perilaku khusus:
Compaction Safeguard
pi-extensions/compaction-safeguard.ts menambahkan guardrail ke compaction, termasuk penganggaran token adaptif plus ringkasan kegagalan tool dan operasi file:
typescriptif (resolveCompactionMode(params.cfg) === "safeguard") { setCompactionSafeguardRuntime(params.sessionManager, { maxHistoryShare }); paths.push(resolvePiExtensionPath("compaction-safeguard")); }
Context Pruning
pi-extensions/context-pruning.ts mengimplementasikan pemangkasan konteks berbasis cache-TTL:
typescriptif (cfg?.agents?.defaults?.contextPruning?.mode === "cache-ttl") { setContextPruningRuntime(params.sessionManager, { settings, contextWindowTokens, isToolPrunable, lastCacheTouchAt, }); paths.push(resolvePiExtensionPath("context-pruning")); }
Perbedaan Utama dari Pi CLI
| Aspek | Pi CLI | Mayros Embedded |
|---|---|---|
| Invokasi | Perintah pi / RPC | SDK melalui createAgentSession() |
| Tool | Tool coding default | Suite tool Mayros kustom |
| System prompt | AGENTS.md + prompt | Dinamis per-channel/konteks |
| Penyimpanan sesi | ~/.pi/agent/sessions/ | ~/.mayros/agents/<agentId>/sessions/ (atau $MAYROS_STATE_DIR/agents/<agentId>/sessions/) |
| Auth | Kredensial tunggal | Multi-profil dengan rotasi |
| Ekstensi | Dimuat dari disk | Programmatic + path disk |
| Penanganan event | Rendering TUI | Berbasis callback (onBlockReply, dll.) |
Pertimbangan Masa Depan
Area untuk potensi pengerjaan ulang:
- Penyelarasan signature tool: Saat ini beradaptasi antara signature pi-agent-core dan pi-coding-agent
- Pembungkusan session manager:
guardSessionManagermenambahkan keamanan tetapi meningkatkan kompleksitas - Pemuatan ekstensi: Dapat menggunakan
ResourceLoaderpi lebih langsung - Kompleksitas handler streaming:
subscribeEmbeddedPiSessiontelah tumbuh besar - Quirk provider: Banyak codepath spesifik provider yang berpotensi ditangani pi