Architettura Integrazione Pi
Questo documento descrive come Mayros si integra con pi-coding-agent e i suoi pacchetti sibling (pi-ai, pi-agent-core, pi-tui) per alimentare le sue capacità di agente AI.
Panoramica
Mayros utilizza l'SDK pi per incorporare un agente AI di programmazione nella sua architettura gateway di messaggistica. Invece di generare pi come sottoprocesso o utilizzare la modalità RPC, Mayros importa direttamente e istanzia l'AgentSession di pi tramite createAgentSession(). Questo approccio incorporato fornisce:
- Controllo completo del ciclo di vita della sessione e gestione degli eventi
- Iniezione di strumenti personalizzati (messaggistica, sandbox, azioni specifiche del canale)
- Personalizzazione del prompt di sistema per canale/contesto
- Persistenza sessione con supporto branching/compaction
- Rotazione profilo auth multi-account con failover
- Cambio modello agnostico dal provider
Dipendenze Pacchetto
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" }
| Pacchetto | Scopo |
|---|---|
pi-ai | Astrazioni LLM core: Model, streamSimple, tipi messaggio, API provider |
pi-agent-core | Loop agente, esecuzione strumenti, tipi AgentMessage |
pi-coding-agent | SDK alto livello: createAgentSession, SessionManager, AuthStorage, ModelRegistry, strumenti integrati |
pi-tui | Componenti UI terminale (usati nella modalità TUI locale di Mayros) |
Struttura File
src/agents/
├── pi-embedded-runner.ts # Re-export da pi-embedded-runner/
├── pi-embedded-runner/
│ ├── run.ts # Entry principale: runEmbeddedPiAgent()
│ ├── run/
│ │ ├── attempt.ts # Logica singolo tentativo con setup sessione
│ │ ├── params.ts # Tipo RunEmbeddedPiAgentParams
│ │ ├── payloads.ts # Costruisce payload risposta dai risultati run
│ │ ├── images.ts # Iniezione immagine modello vision
│ │ └── types.ts # EmbeddedRunAttemptResult
│ ├── abort.ts # Rilevamento errore abort
│ ├── cache-ttl.ts # Tracciamento TTL cache per pruning contesto
│ ├── compact.ts # Logica compaction manuale/auto
│ ├── extensions.ts # Carica estensioni pi per run incorporati
│ ├── extra-params.ts # Parametri stream specifici provider
│ ├── google.ts # Correzioni ordinamento turni Google/Gemini
│ ├── history.ts # Limitazione storico (DM vs gruppo)
│ ├── lanes.ts # Corsie comando sessione/globale
│ ├── logger.ts # Logger sottosistema
│ ├── model.ts # Risoluzione modello tramite ModelRegistry
│ ├── runs.ts # Tracciamento run attivi, abort, coda
│ ├── sandbox-info.ts # Info sandbox per prompt sistema
│ ├── session-manager-cache.ts # Cache istanze SessionManager
│ ├── session-manager-init.ts # Inizializzazione file sessione
│ ├── system-prompt.ts # Costruttore prompt sistema
│ ├── tool-split.ts # Divide strumenti in builtIn vs custom
│ ├── types.ts # EmbeddedPiAgentMeta, EmbeddedPiRunResult
│ └── utils.ts # Mappatura ThinkLevel, descrizione errore
├── pi-embedded-subscribe.ts # Sottoscrizione/dispatch eventi sessione
├── pi-embedded-subscribe.types.ts # SubscribeEmbeddedPiSessionParams
├── pi-embedded-subscribe.handlers.ts # Factory gestore eventi
├── pi-embedded-subscribe.handlers.lifecycle.ts
├── pi-embedded-subscribe.handlers.types.ts
├── pi-embedded-block-chunker.ts # Chunking risposta blocco streaming
├── pi-embedded-messaging.ts # Tracciamento invio strumento messaggistica
├── pi-embedded-helpers.ts # Classificazione errori, validazione turni
├── pi-embedded-helpers/ # Moduli helper
├── pi-embedded-utils.ts # Utilità formattazione
├── pi-tools.ts # createMayrosCodingTools()
├── pi-tools.abort.ts # Wrapping AbortSignal per strumenti
├── pi-tools.policy.ts # Policy allowlist/denylist strumenti
├── pi-tools.read.ts # Personalizzazioni strumento Read
├── pi-tools.schema.ts # Normalizzazione schema strumenti
├── pi-tools.types.ts # Alias tipo AnyAgentTool
├── pi-tool-definition-adapter.ts # Adattatore AgentTool -> ToolDefinition
├── pi-settings.ts # Override impostazioni
├── pi-extensions/ # Estensioni pi personalizzate
│ ├── compaction-safeguard.ts # Estensione salvaguardia
│ ├── compaction-safeguard-runtime.ts
│ ├── context-pruning.ts # Estensione pruning contesto cache-TTL
│ └── context-pruning/
├── model-auth.ts # Risoluzione profilo auth
├── auth-profiles.ts # Store profili, cooldown, failover
├── model-selection.ts # Risoluzione modello predefinito
├── models-config.ts # Generazione models.json
├── model-catalog.ts # Cache catalogo modelli
├── context-window-guard.ts # Validazione finestra contesto
├── failover-error.ts # Classe FailoverError
├── defaults.ts # DEFAULT_PROVIDER, DEFAULT_MODEL
├── system-prompt.ts # buildAgentSystemPrompt()
├── system-prompt-params.ts # Risoluzione parametri prompt sistema
├── system-prompt-report.ts # Generazione report debug
├── tool-summaries.ts # Riepiloghi descrizione strumenti
├── tool-policy.ts # Risoluzione policy strumenti
├── transcript-policy.ts # Policy validazione trascrizione
├── skills.ts # Costruzione snapshot/prompt skill
├── skills/ # Sottosistema skill
├── sandbox.ts # Risoluzione contesto sandbox
├── sandbox/ # Sottosistema sandbox
├── channel-tools.ts # Iniezione strumenti specifici canale
├── mayros-tools.ts # Strumenti specifici Mayros
├── bash-tools.ts # Strumenti exec/process
├── apply-patch.ts # Strumento apply_patch (OpenAI)
├── tools/ # Implementazioni strumenti individuali
│ ├── 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
└── ...
Flusso Integrazione Core
1. Esecuzione Agente Incorporato
Il punto di ingresso principale è runEmbeddedPiAgent() in 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: "/percorso/a/session.jsonl", workspaceDir: "/percorso/a/workspace", config: mayrosConfig, prompt: "Ciao, come stai?", provider: "anthropic", model: "claude-sonnet-4-20250514", timeoutMs: 120_000, runId: "run-abc", onBlockReply: async (payload) => { await sendToChannel(payload.text, payload.mediaUrls); }, });
2. Creazione Sessione
All'interno di runEmbeddedAttempt() (chiamato da runEmbeddedPiAgent()), viene utilizzato l'SDK pi:
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. Sottoscrizione Eventi
subscribeEmbeddedPiSession() si sottoscrive agli eventi AgentSession di 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, });
Gli eventi gestiti includono:
message_start/message_end/message_update(streaming testo/thinking)tool_execution_start/tool_execution_update/tool_execution_endturn_start/turn_endagent_start/agent_endauto_compaction_start/auto_compaction_end
4. Prompting
Dopo il setup, la sessione riceve il prompt:
typescriptawait session.prompt(effectivePrompt, { images: imageResult.images });
L'SDK gestisce l'intero loop dell'agente: invio a LLM, esecuzione chiamate strumenti, streaming risposte.
Architettura Strumenti
Pipeline Strumenti
- Strumenti Base:
codingToolsdi pi (read, bash, edit, write) - Sostituzioni Personalizzate: Mayros sostituisce bash con
exec/process, personalizza read/edit/write per sandbox - Strumenti Mayros: messaggistica, browser, canvas, sessioni, cron, gateway, ecc.
- Strumenti Canale: strumenti azione specifici Discord/Telegram/Slack/WhatsApp
- Filtraggio Policy: strumenti filtrati per profilo, provider, agente, gruppo, policy sandbox
- Normalizzazione Schema: schemi puliti per quirk Gemini/OpenAI
- Wrapping AbortSignal: strumenti avvolti per rispettare segnali abort
Adattatore Definizione Strumento
L'AgentTool di pi-agent-core ha una firma execute diversa dalla ToolDefinition di pi-coding-agent. L'adattatore in pi-tool-definition-adapter.ts fa da ponte:
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) => { // la firma pi-coding-agent differisce da pi-agent-core return await tool.execute(toolCallId, params, signal, onUpdate); }, })); }
Strategia Divisione Strumenti
splitSdkTools() passa tutti gli strumenti tramite customTools:
typescriptexport function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled: boolean }) { return { builtInTools: [], // Vuoto. Sovrascriviamo tutto customTools: toToolDefinitions(options.tools), }; }
Questo assicura che il filtraggio policy di Mayros, l'integrazione sandbox e il toolset esteso rimangano coerenti tra i provider.
Costruzione Prompt Sistema
Il prompt sistema viene costruito in buildAgentSystemPrompt() (system-prompt.ts). Assembla un prompt completo con sezioni tra cui Tooling, Stile Chiamata Strumento, Guardrail Sicurezza, riferimento CLI Mayros, Skills, Docs, Workspace, Sandbox, Messaging, Tag Risposta, Voice, Risposte Silenziose, Heartbeat, metadati Runtime, più Memoria e Reazioni quando abilitati, e contenuto prompt sistema extra e file contesto opzionali. Le sezioni vengono rifinite per la modalità prompt minimo usata dai subagent.
Il prompt viene applicato dopo la creazione della sessione tramite applySystemPromptOverrideToSession():
typescriptconst systemPromptOverride = createSystemPromptOverride(appendPrompt); applySystemPromptOverrideToSession(session, systemPromptOverride);
Gestione Sessione
File Sessione
Le sessioni sono file JSONL con struttura ad albero (collegamento id/parentId). Il SessionManager di pi gestisce la persistenza:
typescriptconst sessionManager = SessionManager.open(params.sessionFile);
Mayros lo avvolge con guardSessionManager() per la sicurezza dei risultati degli strumenti.
Caching Sessione
session-manager-cache.ts mette in cache le istanze SessionManager per evitare parsing ripetuto del file:
typescriptawait prewarmSessionFile(params.sessionFile); sessionManager = SessionManager.open(params.sessionFile); trackSessionManagerAccess(params.sessionFile);
Limitazione Storico
limitHistoryTurns() taglia lo storico conversazione basato sul tipo di canale (DM vs gruppo).
Compaction
La compaction automatica si attiva su overflow contesto. compactEmbeddedPiSessionDirect() gestisce la compaction manuale:
typescriptconst compactResult = await compactEmbeddedPiSessionDirect({ sessionId, sessionFile, provider, model, ... });
Autenticazione & Risoluzione Modello
Profili Auth
Mayros mantiene uno store profili auth con più chiavi API per provider:
typescriptconst authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false }); const profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });
I profili ruotano su fallimenti con tracciamento cooldown:
typescriptawait markAuthProfileFailure({ store, profileId, reason, cfg, agentDir }); const rotated = await advanceAuthProfile();
Risoluzione Modello
typescriptimport { resolveModel } from "./pi-embedded-runner/model.js"; const { model, error, authStorage, modelRegistry } = resolveModel( provider, modelId, agentDir, config, ); // Usa ModelRegistry e AuthStorage di pi authStorage.setRuntimeApiKey(model.provider, apiKeyInfo.apiKey);
Failover
FailoverError attiva fallback modello quando configurato:
typescriptif (fallbackConfigured && isFailoverErrorMessage(errorText)) { throw new FailoverError(errorText, { reason: promptFailoverReason ?? "unknown", provider, model: modelId, profileId, status: resolveFailoverStatus(promptFailoverReason), }); }
Estensioni Pi
Mayros carica estensioni pi personalizzate per comportamento specializzato:
Salvaguardia Compaction
pi-extensions/compaction-safeguard.ts aggiunge guardrail alla compaction, incluso budgeting token adattivo più riepiloghi fallimento strumenti e operazioni file:
typescriptif (resolveCompactionMode(params.cfg) === "safeguard") { setCompactionSafeguardRuntime(params.sessionManager, { maxHistoryShare }); paths.push(resolvePiExtensionPath("compaction-safeguard")); }
Pruning Contesto
pi-extensions/context-pruning.ts implementa pruning contesto basato su cache-TTL:
typescriptif (cfg?.agents?.defaults?.contextPruning?.mode === "cache-ttl") { setContextPruningRuntime(params.sessionManager, { settings, contextWindowTokens, isToolPrunable, lastCacheTouchAt, }); paths.push(resolvePiExtensionPath("context-pruning")); }
Streaming & Risposte Blocco
Chunking Blocco
EmbeddedBlockChunker gestisce lo streaming del testo in blocchi risposta discreti:
typescriptconst blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;
Rimozione Tag Thinking/Final
L'output streaming viene elaborato per rimuovere blocchi <think>/<thinking> ed estrarre contenuto <final>:
typescriptconst stripBlockTags = (text: string, state: { thinking: boolean; final: boolean }) => { // Rimuove contenuto <think>...</think> // Se enforceFinalTag, restituisce solo contenuto <final>...</final> };
Direttive Risposta
Direttive risposta come [[media:url]], [[voice]], [[reply:id]] vengono parsate ed estratte:
typescriptconst { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);
Gestione Errori
Classificazione Errori
pi-embedded-helpers.ts classifica gli errori per gestione appropriata:
typescriptisContextOverflowError(errorText) // Contesto troppo grande isCompactionFailureError(errorText) // Compaction fallita isAuthAssistantError(lastAssistant) // Fallimento auth isRateLimitAssistantError(...) // Rate limited isFailoverAssistantError(...) // Dovrebbe failover classifyFailoverReason(errorText) // "auth" | "rate_limit" | "quota" | "timeout" | ...
Fallback Livello Thinking
Se un livello thinking non è supportato, fa fallback:
typescriptconst fallbackThinking = pickFallbackThinkingLevel({ message: errorText, attempted: attemptedThinking, }); if (fallbackThinking) { thinkLevel = fallbackThinking; continue; }
Integrazione Sandbox
Quando la modalità sandbox è abilitata, strumenti e percorsi sono vincolati:
typescriptconst sandbox = await resolveSandboxContext({ config: params.config, sessionKey: sandboxSessionKey, workspaceDir: resolvedWorkspace, }); if (sandboxRoot) { // Usa strumenti read/edit/write sandboxed // Exec viene eseguito in container // Browser usa URL bridge }
Gestione Specifica Provider
Anthropic
- Scrubbing stringa magica rifiuto
- Validazione turni per ruoli consecutivi
- Compatibilità parametro Claude Code
Google/Gemini
- Correzioni ordinamento turni (
applyGoogleTurnOrderingFix) - Sanitizzazione schema strumenti (
sanitizeToolsForGoogle) - Sanitizzazione storico sessione (
sanitizeSessionHistory)
OpenAI
- Strumento
apply_patchper modelli Codex - Gestione downgrade livello thinking
Integrazione TUI
Mayros ha anche una modalità TUI locale che usa componenti pi-tui direttamente:
typescript// src/tui/tui.ts import { ... } from "@mariozechner/pi-tui";
Questo fornisce l'esperienza terminale interattiva simile alla modalità nativa di pi.
Differenze Chiave da Pi CLI
| Aspetto | Pi CLI | Mayros Incorporato |
|---|---|---|
| Invocazione | Comando pi / RPC | SDK tramite createAgentSession() |
| Strumenti | Strumenti coding default | Suite strumenti Mayros personalizzata |
| Prompt sistema | AGENTS.md + prompts | Dinamico per canale/contesto |
| Storage sessione | ~/.pi/agent/sessions/ | ~/.mayros/agents/<agentId>/sessions/ (o $MAYROS_STATE_DIR/agents/<agentId>/sessions/) |
| Auth | Singola credenziale | Multi-profilo con rotazione |
| Estensioni | Caricate da disco | Programmatico + percorsi disco |
| Gestione eventi | Rendering TUI | Basato su callback (onBlockReply, ecc.) |
Considerazioni Future
Aree per potenziale rework:
- Allineamento firma strumenti: Attualmente si adatta tra firme pi-agent-core e pi-coding-agent
- Wrapping session manager:
guardSessionManageraggiunge sicurezza ma aumenta complessità - Caricamento estensioni: Potrebbe usare il
ResourceLoaderdi pi più direttamente - Complessità handler streaming:
subscribeEmbeddedPiSessionè cresciuto molto - Quirk provider: Molti codepath specifici provider che pi potrebbe potenzialmente gestire
Test
Tutti i test esistenti che coprono l'integrazione pi e le sue estensioni:
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