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) |
Struktur File
src/agents/
โโโ pi-embedded-runner.ts # Re-exports dari pi-embedded-runner/
โโโ pi-embedded-runner/
โ โโโ run.ts # Entry point utama: runEmbeddedPiAgent()
โ โโโ run/
โ โ โโโ attempt.ts # Logika percobaan tunggal dengan setup sesi
โ โ โโโ params.ts # Tipe RunEmbeddedPiAgentParams
โ โ โโโ payloads.ts # Bangun payload respons dari hasil run
โ โ โโโ images.ts # Injeksi gambar model Vision
โ โ โโโ types.ts # EmbeddedRunAttemptResult
โ โโโ abort.ts # Deteksi error pembatalan
โ โโโ cache-ttl.ts # Pelacakan Cache TTL untuk pemangkasan konteks
โ โโโ compact.ts # Logika compaction manual/otomatis
โ โโโ extensions.ts # Muat ekstensi pi untuk run embedded
โ โโโ extra-params.ts # Parameter stream spesifik provider
โ โโโ google.ts # Perbaikan urutan turn Google/Gemini
โ โโโ history.ts # Pembatasan histori (DM vs grup)
โ โโโ lanes.ts # Lane perintah sesi/global
โ โโโ logger.ts # Logger subsistem
โ โโโ model.ts # Resolusi model via ModelRegistry
โ โโโ runs.ts # Pelacakan run aktif, pembatalan, antrian
โ โโโ sandbox-info.ts # Info Sandbox untuk system prompt
โ โโโ session-manager-cache.ts # Caching instance SessionManager
โ โโโ session-manager-init.ts # Inisialisasi file sesi
โ โโโ system-prompt.ts # Pembangun system prompt
โ โโโ tool-split.ts # Pisahkan tool menjadi builtIn vs custom
โ โโโ types.ts # EmbeddedPiAgentMeta, EmbeddedPiRunResult
โ โโโ utils.ts # Pemetaan ThinkLevel, deskripsi error
โโโ pi-embedded-subscribe.ts # Subscription/dispatch event sesi
โโโ pi-embedded-subscribe.types.ts # SubscribeEmbeddedPiSessionParams
โโโ pi-embedded-subscribe.handlers.ts # Factory handler event
โโโ pi-embedded-subscribe.handlers.lifecycle.ts
โโโ pi-embedded-subscribe.handlers.types.ts
โโโ pi-embedded-block-chunker.ts # Chunking balasan streaming block
โโโ pi-embedded-messaging.ts # Pelacakan pengiriman tool pesan
โโโ pi-embedded-helpers.ts # Klasifikasi error, validasi turn
โโโ pi-embedded-helpers/ # Modul helper
โโโ pi-embedded-utils.ts # Utilitas format
โโโ pi-tools.ts # createMayrosCodingTools()
โโโ pi-tools.abort.ts # Pembungkusan AbortSignal untuk tool
โโโ pi-tools.policy.ts # Kebijakan allowlist/denylist tool
โโโ pi-tools.read.ts # Kustomisasi tool Read
โโโ pi-tools.schema.ts # Normalisasi skema tool
โโโ pi-tools.types.ts # Alias tipe AnyAgentTool
โโโ pi-tool-definition-adapter.ts # Adapter AgentTool -> ToolDefinition
โโโ pi-settings.ts # Override pengaturan
โโโ pi-extensions/ # Ekstensi pi kustom
โ โโโ compaction-safeguard.ts # Ekstensi Safeguard
โ โโโ compaction-safeguard-runtime.ts
โ โโโ context-pruning.ts # Ekstensi pemangkasan konteks Cache-TTL
โ โโโ context-pruning/
โโโ model-auth.ts # Resolusi profil Auth
โโโ auth-profiles.ts # Penyimpanan profil, cooldown, failover
โโโ model-selection.ts # Resolusi model default
โโโ models-config.ts # Pembuatan models.json
โโโ model-catalog.ts # Cache katalog model
โโโ context-window-guard.ts # Validasi jendela konteks
โโโ failover-error.ts # Kelas FailoverError
โโโ defaults.ts # DEFAULT_PROVIDER, DEFAULT_MODEL
โโโ system-prompt.ts # buildAgentSystemPrompt()
โโโ system-prompt-params.ts # Resolusi parameter system prompt
โโโ system-prompt-report.ts # Pembuatan laporan debug
โโโ tool-summaries.ts # Ringkasan deskripsi tool
โโโ tool-policy.ts # Resolusi kebijakan tool
โโโ transcript-policy.ts # Kebijakan validasi Transcript
โโโ skills.ts # Pembuatan Skill snapshot/prompt
โโโ skills/ # Subsistem Skill
โโโ sandbox.ts # Resolusi konteks Sandbox
โโโ sandbox/ # Subsistem Sandbox
โโโ channel-tools.ts # Injeksi tool spesifik channel
โโโ mayros-tools.ts # Tool spesifik Mayros
โโโ bash-tools.ts # Tool exec/process
โโโ apply-patch.ts # Tool apply_patch (OpenAI)
โโโ tools/ # Implementasi tool individual
โ โโโ browser-tool.ts
โ โโโ canvas-tool.ts
โ โโโ cron-tool.ts
โ โโโ discord-actions*.ts
โ โโโ gateway-tool.ts
โ โโโ image-tool.ts
โ โโโ message-tool.ts
โ โโโ nodes-tool.ts
โ โโโ session*.ts
โ โโโ slack-actions.ts
โ โโโ telegram-actions.ts
โ โโโ web-*.ts
โ โโโ whatsapp-actions.ts
โโโ ...
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);
Pembatasan Histori
limitHistoryTurns() memangkas histori percakapan berdasarkan tipe channel (DM vs grup).
Compaction
Auto-compaction terpicu pada context overflow. compactEmbeddedPiSessionDirect() menangani compaction manual:
typescriptconst compactResult = await compactEmbeddedPiSessionDirect({ sessionId, sessionFile, provider, model, ... });
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);
Failover
FailoverError memicu model fallback ketika dikonfigurasi:
typescriptif (fallbackConfigured && isFailoverErrorMessage(errorText)) { throw new FailoverError(errorText, { reason: promptFailoverReason ?? "unknown", provider, model: modelId, profileId, status: resolveFailoverStatus(promptFailoverReason), }); }
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")); }
Streaming & Balasan Block
Block Chunking
EmbeddedBlockChunker mengelola streaming teks menjadi block balasan diskrit:
typescriptconst blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;
Stripping Tag Thinking/Final
Output streaming diproses untuk menghapus block <think>/<thinking> dan mengekstrak konten <final>:
typescriptconst stripBlockTags = (text: string, state: { thinking: boolean; final: boolean }) => { // Strip <think>...</think> content // If enforceFinalTag, only return <final>...</final> content };
Reply Directives
Reply directives seperti [[media:url]], [[voice]], [[reply:id]] diparsing dan diekstrak:
typescriptconst { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);
Penanganan Error
Klasifikasi Error
pi-embedded-helpers.ts mengklasifikasikan error untuk penanganan yang tepat:
typescriptisContextOverflowError(errorText) // Konteks terlalu besar isCompactionFailureError(errorText) // Compaction gagal isAuthAssistantError(lastAssistant) // Kegagalan auth isRateLimitAssistantError(...) // Rate limited isFailoverAssistantError(...) // Harus failover classifyFailoverReason(errorText) // "auth" | "rate_limit" | "quota" | "timeout" | ...
Thinking Level Fallback
Jika thinking level tidak didukung, akan fallback:
typescriptconst fallbackThinking = pickFallbackThinkingLevel({ message: errorText, attempted: attemptedThinking, }); if (fallbackThinking) { thinkLevel = fallbackThinking; continue; }
Integrasi Sandbox
Ketika mode sandbox diaktifkan, tool dan path dibatasi:
typescriptconst sandbox = await resolveSandboxContext({ config: params.config, sessionKey: sandboxSessionKey, workspaceDir: resolvedWorkspace, }); if (sandboxRoot) { // Use sandboxed read/edit/write tools // Exec runs in container // Browser uses bridge URL }
Penanganan Spesifik Provider
Anthropic
- Pembersihan magic string penolakan
- Validasi turn untuk role berurutan
- Kompatibilitas parameter Claude Code
Google/Gemini
- Perbaikan urutan turn (
applyGoogleTurnOrderingFix) - Sanitasi skema tool (
sanitizeToolsForGoogle) - Sanitasi histori sesi (
sanitizeSessionHistory)
OpenAI
- Tool
apply_patchuntuk model Codex - Penanganan downgrade thinking level
Integrasi TUI
Mayros juga memiliki mode TUI lokal yang menggunakan komponen pi-tui langsung:
typescript// src/tui/tui.ts import { ... } from "@mariozechner/pi-tui";
Ini menyediakan pengalaman terminal interaktif serupa dengan mode native pi.
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
Test
Semua test yang ada yang mencakup integrasi pi dan ekstensinya:
src/agents/pi-embedded-block-chunker.test.tssrc/agents/pi-embedded-helpers.buildbootstrapcontextfiles.test.tssrc/agents/pi-embedded-helpers.classifyfailoverreason.test.tssrc/agents/pi-embedded-helpers.downgradeopenai-reasoning.test.tssrc/agents/pi-embedded-helpers.formatassistanterrortext.test.tssrc/agents/pi-embedded-helpers.formatrawassistanterrorforui.test.tssrc/agents/pi-embedded-helpers.image-dimension-error.test.tssrc/agents/pi-embedded-helpers.image-size-error.test.tssrc/agents/pi-embedded-helpers.isautherrormessage.test.tssrc/agents/pi-embedded-helpers.isbillingerrormessage.test.tssrc/agents/pi-embedded-helpers.iscloudcodeassistformaterror.test.tssrc/agents/pi-embedded-helpers.iscompactionfailureerror.test.tssrc/agents/pi-embedded-helpers.iscontextoverflowerror.test.tssrc/agents/pi-embedded-helpers.isfailovererrormessage.test.tssrc/agents/pi-embedded-helpers.islikelycontextoverflowerror.test.tssrc/agents/pi-embedded-helpers.ismessagingtoolduplicate.test.tssrc/agents/pi-embedded-helpers.messaging-duplicate.test.tssrc/agents/pi-embedded-helpers.normalizetextforcomparison.test.tssrc/agents/pi-embedded-helpers.resolvebootstrapmaxchars.test.tssrc/agents/pi-embedded-helpers.sanitize-session-messages-images.keeps-tool-call-tool-result-ids-unchanged.test.tssrc/agents/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.tssrc/agents/pi-embedded-helpers.sanitizegoogleturnordering.test.tssrc/agents/pi-embedded-helpers.sanitizesessionmessagesimages-thought-signature-stripping.test.tssrc/agents/pi-embedded-helpers.sanitizetoolcallid.test.tssrc/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.tssrc/agents/pi-embedded-helpers.stripthoughtsignatures.test.tssrc/agents/pi-embedded-helpers.validate-turns.test.tssrc/agents/pi-embedded-runner-extraparams.live.test.ts(live)src/agents/pi-embedded-runner-extraparams.test.tssrc/agents/pi-embedded-runner.applygoogleturnorderingfix.test.tssrc/agents/pi-embedded-runner.buildembeddedsandboxinfo.test.tssrc/agents/pi-embedded-runner.createsystempromptoverride.test.tssrc/agents/pi-embedded-runner.get-dm-history-limit-from-session-key.falls-back-provider-default-per-dm-not.test.tssrc/agents/pi-embedded-runner.get-dm-history-limit-from-session-key.returns-undefined-sessionkey-is-undefined.test.tssrc/agents/pi-embedded-runner.google-sanitize-thinking.test.tssrc/agents/pi-embedded-runner.guard.test.tssrc/agents/pi-embedded-runner.limithistoryturns.test.tssrc/agents/pi-embedded-runner.resolvesessionagentids.test.tssrc/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.test.tssrc/agents/pi-embedded-runner.sanitize-session-history.test.tssrc/agents/pi-embedded-runner.splitsdktools.test.tssrc/agents/pi-embedded-runner.test.tssrc/agents/pi-embedded-subscribe.code-span-awareness.test.tssrc/agents/pi-embedded-subscribe.reply-tags.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.calls-onblockreplyflush-before-tool-execution-start-preserve.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-append-text-end-content-is.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-call-onblockreplyflush-callback-is-not.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-duplicate-text-end-repeats-full.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-emit-duplicate-block-replies-text.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-block-replies-text-end-does-not.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-reasoning-as-separate-message-enabled.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.includes-canvas-action-metadata-tool-summaries.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.keeps-assistanttexts-final-answer-block-replies-are.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.keeps-indented-fenced-blocks-intact.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.reopens-fenced-blocks-splitting-inside-them.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.splits-long-single-line-fenced-blocks-reopen.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.streams-soft-chunks-paragraph-preference.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.subscribeembeddedpisession.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.suppresses-message-end-block-replies-message-tool.test.tssrc/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.waits-multiple-compaction-retries-before-resolving.test.tssrc/agents/pi-embedded-subscribe.tools.test.tssrc/agents/pi-embedded-utils.test.tssrc/agents/pi-extensions/compaction-safeguard.test.tssrc/agents/pi-extensions/context-pruning.test.tssrc/agents/pi-settings.test.tssrc/agents/pi-tool-definition-adapter.test.tssrc/agents/pi-tools-agent-config.test.tssrc/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping-b.test.tssrc/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.test.tssrc/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping-f.test.tssrc/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping.test.tssrc/agents/pi-tools.policy.test.tssrc/agents/pi-tools.safe-bins.test.tssrc/agents/pi-tools.workspace-paths.test.ts