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"
}
PacchettoScopo
pi-aiAstrazioni LLM core: Model, streamSimple, tipi messaggio, API provider
pi-agent-coreLoop agente, esecuzione strumenti, tipi AgentMessage
pi-coding-agentSDK alto livello: createAgentSession, SessionManager, AuthStorage, ModelRegistry, strumenti integrati
pi-tuiComponenti 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:

typescript
import { 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:

typescript
import {
  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:

typescript
const 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_end
  • turn_start / turn_end
  • agent_start / agent_end
  • auto_compaction_start / auto_compaction_end

4. Prompting

Dopo il setup, la sessione riceve il prompt:

typescript
await 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

  1. Strumenti Base: codingTools di pi (read, bash, edit, write)
  2. Sostituzioni Personalizzate: Mayros sostituisce bash con exec/process, personalizza read/edit/write per sandbox
  3. Strumenti Mayros: messaggistica, browser, canvas, sessioni, cron, gateway, ecc.
  4. Strumenti Canale: strumenti azione specifici Discord/Telegram/Slack/WhatsApp
  5. Filtraggio Policy: strumenti filtrati per profilo, provider, agente, gruppo, policy sandbox
  6. Normalizzazione Schema: schemi puliti per quirk Gemini/OpenAI
  7. 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:

typescript
export 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:

typescript
export 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():

typescript
const 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:

typescript
const 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:

typescript
await 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:

typescript
const compactResult = await compactEmbeddedPiSessionDirect({
  sessionId, sessionFile, provider, model, ...
});

Autenticazione & Risoluzione Modello

Profili Auth

Mayros mantiene uno store profili auth con più chiavi API per provider:

typescript
const authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
const profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });

I profili ruotano su fallimenti con tracciamento cooldown:

typescript
await markAuthProfileFailure({ store, profileId, reason, cfg, agentDir });
const rotated = await advanceAuthProfile();

Risoluzione Modello

typescript
import { 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:

typescript
if (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:

typescript
if (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:

typescript
if (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:

typescript
const blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;

Rimozione Tag Thinking/Final

L'output streaming viene elaborato per rimuovere blocchi <think>/<thinking> ed estrarre contenuto <final>:

typescript
const 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:

typescript
const { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);

Gestione Errori

Classificazione Errori

pi-embedded-helpers.ts classifica gli errori per gestione appropriata:

typescript
isContextOverflowError(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:

typescript
const fallbackThinking = pickFallbackThinkingLevel({
  message: errorText,
  attempted: attemptedThinking,
});
if (fallbackThinking) {
  thinkLevel = fallbackThinking;
  continue;
}

Integrazione Sandbox

Quando la modalità sandbox è abilitata, strumenti e percorsi sono vincolati:

typescript
const 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_patch per 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

AspettoPi CLIMayros Incorporato
InvocazioneComando pi / RPCSDK tramite createAgentSession()
StrumentiStrumenti coding defaultSuite strumenti Mayros personalizzata
Prompt sistemaAGENTS.md + promptsDinamico per canale/contesto
Storage sessione~/.pi/agent/sessions/~/.mayros/agents/<agentId>/sessions/ (o $MAYROS_STATE_DIR/agents/<agentId>/sessions/)
AuthSingola credenzialeMulti-profilo con rotazione
EstensioniCaricate da discoProgrammatico + percorsi disco
Gestione eventiRendering TUIBasato su callback (onBlockReply, ecc.)

Considerazioni Future

Aree per potenziale rework:

  1. Allineamento firma strumenti: Attualmente si adatta tra firme pi-agent-core e pi-coding-agent
  2. Wrapping session manager: guardSessionManager aggiunge sicurezza ma aumenta complessità
  3. Caricamento estensioni: Potrebbe usare il ResourceLoader di pi più direttamente
  4. Complessità handler streaming: subscribeEmbeddedPiSession è cresciuto molto
  5. 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.ts
  • src/agents/pi-embedded-helpers.buildbootstrapcontextfiles.test.ts
  • src/agents/pi-embedded-helpers.classifyfailoverreason.test.ts
  • src/agents/pi-embedded-helpers.downgradeopenai-reasoning.test.ts
  • src/agents/pi-embedded-helpers.formatassistanterrortext.test.ts
  • src/agents/pi-embedded-helpers.formatrawassistanterrorforui.test.ts
  • src/agents/pi-embedded-helpers.image-dimension-error.test.ts
  • src/agents/pi-embedded-helpers.image-size-error.test.ts
  • src/agents/pi-embedded-helpers.isautherrormessage.test.ts
  • src/agents/pi-embedded-helpers.isbillingerrormessage.test.ts
  • src/agents/pi-embedded-helpers.iscloudcodeassistformaterror.test.ts
  • src/agents/pi-embedded-helpers.iscompactionfailureerror.test.ts
  • src/agents/pi-embedded-helpers.iscontextoverflowerror.test.ts
  • src/agents/pi-embedded-helpers.isfailovererrormessage.test.ts
  • src/agents/pi-embedded-helpers.islikelycontextoverflowerror.test.ts
  • src/agents/pi-embedded-helpers.ismessagingtoolduplicate.test.ts
  • src/agents/pi-embedded-helpers.messaging-duplicate.test.ts
  • src/agents/pi-embedded-helpers.normalizetextforcomparison.test.ts
  • src/agents/pi-embedded-helpers.resolvebootstrapmaxchars.test.ts
  • src/agents/pi-embedded-helpers.sanitize-session-messages-images.keeps-tool-call-tool-result-ids-unchanged.test.ts
  • src/agents/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.ts
  • src/agents/pi-embedded-helpers.sanitizegoogleturnordering.test.ts
  • src/agents/pi-embedded-helpers.sanitizesessionmessagesimages-thought-signature-stripping.test.ts
  • src/agents/pi-embedded-helpers.sanitizetoolcallid.test.ts
  • src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts
  • src/agents/pi-embedded-helpers.stripthoughtsignatures.test.ts
  • src/agents/pi-embedded-helpers.validate-turns.test.ts
  • src/agents/pi-embedded-runner-extraparams.live.test.ts (live)
  • src/agents/pi-embedded-runner-extraparams.test.ts
  • src/agents/pi-embedded-runner.applygoogleturnorderingfix.test.ts
  • src/agents/pi-embedded-runner.buildembeddedsandboxinfo.test.ts
  • src/agents/pi-embedded-runner.createsystempromptoverride.test.ts
  • src/agents/pi-embedded-runner.get-dm-history-limit-from-session-key.falls-back-provider-default-per-dm-not.test.ts
  • src/agents/pi-embedded-runner.get-dm-history-limit-from-session-key.returns-undefined-sessionkey-is-undefined.test.ts
  • src/agents/pi-embedded-runner.google-sanitize-thinking.test.ts
  • src/agents/pi-embedded-runner.guard.test.ts
  • src/agents/pi-embedded-runner.limithistoryturns.test.ts
  • src/agents/pi-embedded-runner.resolvesessionagentids.test.ts
  • src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.test.ts
  • src/agents/pi-embedded-runner.sanitize-session-history.test.ts
  • src/agents/pi-embedded-runner.splitsdktools.test.ts
  • src/agents/pi-embedded-runner.test.ts
  • src/agents/pi-embedded-subscribe.code-span-awareness.test.ts
  • src/agents/pi-embedded-subscribe.reply-tags.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.calls-onblockreplyflush-before-tool-execution-start-preserve.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-append-text-end-content-is.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-call-onblockreplyflush-callback-is-not.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-duplicate-text-end-repeats-full.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-emit-duplicate-block-replies-text.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-block-replies-text-end-does-not.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-reasoning-as-separate-message-enabled.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.includes-canvas-action-metadata-tool-summaries.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.keeps-assistanttexts-final-answer-block-replies-are.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.keeps-indented-fenced-blocks-intact.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.reopens-fenced-blocks-splitting-inside-them.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.splits-long-single-line-fenced-blocks-reopen.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.streams-soft-chunks-paragraph-preference.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.subscribeembeddedpisession.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.suppresses-message-end-block-replies-message-tool.test.ts
  • src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.waits-multiple-compaction-retries-before-resolving.test.ts
  • src/agents/pi-embedded-subscribe.tools.test.ts
  • src/agents/pi-embedded-utils.test.ts
  • src/agents/pi-extensions/compaction-safeguard.test.ts
  • src/agents/pi-extensions/context-pruning.test.ts
  • src/agents/pi-settings.test.ts
  • src/agents/pi-tool-definition-adapter.test.ts
  • src/agents/pi-tools-agent-config.test.ts
  • src/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping-b.test.ts
  • src/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.test.ts
  • src/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping-f.test.ts
  • src/agents/pi-tools.create-mayros-coding-tools.adds-claude-style-aliases-schemas-without-dropping.test.ts
  • src/agents/pi-tools.policy.test.ts
  • src/agents/pi-tools.safe-bins.test.ts
  • src/agents/pi-tools.workspace-paths.test.ts