Архітектура інтеграції Pi
Цей документ описує, як Mayros інтегрується з pi-coding-agent та його сусідніми пакетами (pi-ai, pi-agent-core, pi-tui) для забезпечення можливостей AI-агента.
Огляд
Mayros використовує SDK pi для вбудовування AI-агента кодування в свою архітектуру шлюзу обміну повідомленнями. Замість створення pi як підпроцесу або використання режиму RPC, Mayros безпосередньо імпортує та створює екземпляр AgentSession pi через createAgentSession(). Цей вбудований підхід забезпечує:
- Повний контроль над життєвим циклом сесії та обробкою подій
- Власне впровадження інструментів (обмін повідомленнями, пісочниця, дії, специфічні для каналу)
- Налаштування системної підказки для кожного каналу/контексту
- Збереження сесії з підтримкою розгалуження/ущільнення
- Ротація профілю автентифікації з кількома обліковими записами з аварійним переключенням
- Перемикання моделі незалежно від провайдера
Залежності пакетів
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" }
| Пакет | Призначення |
|---|---|
pi-ai | Основні абстракції LLM: Model, streamSimple, типи повідомлень, API провайдерів |
pi-agent-core | Цикл агента, виконання інструментів, типи AgentMessage |
pi-coding-agent | Високорівневий SDK: createAgentSession, SessionManager, AuthStorage, ModelRegistry, вбудовані інструменти |
pi-tui | Компоненти термінального UI (використовуються в локальному режимі TUI Mayros) |
Структура файлів
src/agents/
├── pi-embedded-runner.ts # Реекспорт з pi-embedded-runner/
├── pi-embedded-runner/
│ ├── run.ts # Основний вхід: runEmbeddedPiAgent()
│ ├── run/
│ │ ├── attempt.ts # Логіка одної спроби з налаштуванням сесії
│ │ ├── params.ts # Тип RunEmbeddedPiAgentParams
│ │ ├── payloads.ts # Створення корисних навантажень відповідей з результатів запуску
│ │ ├── images.ts # Впровадження зображень моделі зору
│ │ └── types.ts # EmbeddedRunAttemptResult
│ ├── abort.ts # Виявлення помилки переривання
│ ├── cache-ttl.ts # Відстеження TTL кешу для обрізання контексту
│ ├── compact.ts # Логіка ручного/автоматичного ущільнення
│ ├── extensions.ts # Завантаження розширень pi для вбудованих запусків
│ ├── extra-params.ts # Параметри потоку, специфічні для провайдера
│ ├── google.ts # Виправлення порядку ходів Google/Gemini
│ ├── history.ts # Обмеження історії (DM проти групи)
│ ├── lanes.ts # Командні доріжки сесії/глобальні
│ ├── logger.ts # Логер підсистеми
│ ├── model.ts # Розв'язання моделі через ModelRegistry
│ ├── runs.ts # Відстеження активних запусків, переривання, черга
│ ├── sandbox-info.ts # Інформація про пісочницю для системної підказки
│ ├── session-manager-cache.ts # Кешування екземпляра SessionManager
│ ├── session-manager-init.ts # Ініціалізація файлу сесії
│ ├── system-prompt.ts # Побудовник системної підказки
│ ├── tool-split.ts # Розділення інструментів на builtIn vs custom
│ ├── types.ts # EmbeddedPiAgentMeta, EmbeddedPiRunResult
│ └── utils.ts # Відображення ThinkLevel, опис помилки
├── pi-embedded-subscribe.ts # Підписка/відправка подій сесії
├── pi-embedded-subscribe.types.ts # SubscribeEmbeddedPiSessionParams
├── pi-embedded-subscribe.handlers.ts # Фабрика обробників подій
├── pi-embedded-subscribe.handlers.lifecycle.ts
├── pi-embedded-subscribe.handlers.types.ts
├── pi-embedded-block-chunker.ts # Розбиття потокових блокових відповідей на частини
├── pi-embedded-messaging.ts # Відстеження надісланих інструментів обміну повідомленнями
├── pi-embedded-helpers.ts # Класифікація помилок, перевірка ходів
├── pi-embedded-helpers/ # Модулі помічників
├── pi-embedded-utils.ts # Утиліти форматування
├── pi-tools.ts # createMayrosCodingTools()
├── pi-tools.abort.ts # Обгортання AbortSignal для інструментів
├── pi-tools.policy.ts # Політика списку дозволів/заборон інструментів
├── pi-tools.read.ts # Налаштування інструменту читання
├── pi-tools.schema.ts # Нормалізація схеми інструментів
├── pi-tools.types.ts # Псевдонім типу AnyAgentTool
├── pi-tool-definition-adapter.ts # Адаптер AgentTool -> ToolDefinition
├── pi-settings.ts # Заміни налаштувань
├── pi-extensions/ # Власні розширення pi
│ ├── compaction-safeguard.ts # Розширення захисту
│ ├── compaction-safeguard-runtime.ts
│ ├── context-pruning.ts # Розширення обрізання контексту Cache-TTL
│ └── context-pruning/
├── model-auth.ts # Розв'язання профілю автентифікації
├── auth-profiles.ts # Сховище профілів, час очікування, аварійне переключення
├── model-selection.ts # Розв'язання моделі за замовчуванням
├── models-config.ts # Генерація models.json
├── model-catalog.ts # Кеш каталогу моделей
├── context-window-guard.ts # Перевірка вікна контексту
├── failover-error.ts # Клас FailoverError
├── defaults.ts # DEFAULT_PROVIDER, DEFAULT_MODEL
├── system-prompt.ts # buildAgentSystemPrompt()
├── system-prompt-params.ts # Розв'язання параметрів системної підказки
├── system-prompt-report.ts # Генерація звіту налагодження
├── tool-summaries.ts # Підсумки опису інструментів
├── tool-policy.ts # Розв'язання політики інструментів
├── transcript-policy.ts # Політика перевірки транскрипту
├── skills.ts # Створення знімка/підказки навички
├── skills/ # Підсистема навичок
├── sandbox.ts # Розв'язання контексту пісочниці
├── sandbox/ # Підсистема пісочниці
├── channel-tools.ts # Впровадження інструментів, специфічних для каналу
├── mayros-tools.ts # Інструменти, специфічні для Mayros
├── bash-tools.ts # Інструменти exec/process
├── apply-patch.ts # Інструмент apply_patch (OpenAI)
├── tools/ # Окремі реалізації інструментів
│ ├── 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
└── ...
Основний потік інтеграції
1. Запуск вбудованого агента
Основна точка входу — це runEmbeddedPiAgent() в 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: "Привіт, як справи?", provider: "anthropic", model: "claude-sonnet-4-20250514", timeoutMs: 120_000, runId: "run-abc", onBlockReply: async (payload) => { await sendToChannel(payload.text, payload.mediaUrls); }, });
2. Створення сесії
Всередині runEmbeddedAttempt() (викликаного runEmbeddedPiAgent()), використовується 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. Підписка на події
subscribeEmbeddedPiSession() підписується на події 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, });
Оброблені події включають:
message_start/message_end/message_update(потокове передавання тексту/мислення)tool_execution_start/tool_execution_update/tool_execution_endturn_start/turn_endagent_start/agent_endauto_compaction_start/auto_compaction_end
4. Підказка
Після налаштування сесії підказується:
typescriptawait session.prompt(effectivePrompt, { images: imageResult.images });
SDK обробляє повний цикл агента: відправку до LLM, виконання викликів інструментів, потокове передавання відповідей.
Архітектура інструментів
Конвеєр інструментів
- Базові інструменти:
codingToolspi (read, bash, edit, write) - Власні заміни: Mayros замінює bash на
exec/process, налаштовує read/edit/write для пісочниці - Інструменти Mayros: обмін повідомленнями, браузер, canvas, сесії, cron, шлюз тощо.
- Інструменти каналів: інструменти дій, специфічні для Discord/Telegram/Slack/WhatsApp
- Фільтрація політики: інструменти фільтруються за профілем, провайдером, агентом, групою, політиками пісочниці
- Нормалізація схеми: схеми очищені для особливостей Gemini/OpenAI
- Обгортання AbortSignal: інструменти обгорнуті для дотримання сигналів переривання
Адаптер визначення інструменту
AgentTool pi-agent-core має іншу сигнатуру execute, ніж ToolDefinition pi-coding-agent. Адаптер у pi-tool-definition-adapter.ts з'єднує це:
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 відрізняється від pi-agent-core return await tool.execute(toolCallId, params, signal, onUpdate); }, })); }
Стратегія розділення інструментів
splitSdkTools() передає всі інструменти через customTools:
typescriptexport function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled: boolean }) { return { builtInTools: [], // Порожньо. Ми замінюємо все customTools: toToolDefinitions(options.tools), }; }
Це забезпечує, що фільтрація політики Mayros, інтеграція пісочниці та розширений набір інструментів залишаються узгодженими між провайдерами.
Побудова системної підказки
Системна підказка будується в buildAgentSystemPrompt() (system-prompt.ts). Вона збирає повну підказку з розділами, включаючи Інструментарій, Стиль виклику інструментів, Захисні бар'єри безпеки, Довідник Mayros CLI, Навички, Документацію, Робочий простір, Пісочницю, Обмін повідомленнями, Теги відповіді, Голос, Тихі відповіді, Серцебиття, Метадані виконання, плюс Пам'ять та Реакції, коли ввімкнено, та необов'язкові файли контексту та додатковий вміст системної підказки. Розділи обрізаються для мінімального режиму підказки, що використовується підагентами.
Підказка застосовується після створення сесії через applySystemPromptOverrideToSession():
typescriptconst systemPromptOverride = createSystemPromptOverride(appendPrompt); applySystemPromptOverrideToSession(session, systemPromptOverride);
Управління сесіями
Файли сесій
Сесії — це файли JSONL з деревоподібною структурою (зв'язування id/parentId). SessionManager pi обробляє збереження:
typescriptconst sessionManager = SessionManager.open(params.sessionFile);
Mayros обгортає це за допомогою guardSessionManager() для безпеки результатів інструментів.
Кешування сесій
session-manager-cache.ts кешує екземпляри SessionManager, щоб уникнути повторного розбору файлів:
typescriptawait prewarmSessionFile(params.sessionFile); sessionManager = SessionManager.open(params.sessionFile); trackSessionManagerAccess(params.sessionFile);
Обмеження історії
limitHistoryTurns() обрізає історію розмов на основі типу каналу (DM проти групи).
Ущільнення
Автоматичне ущільнення спрацьовує при переповненні контексту. compactEmbeddedPiSessionDirect() обробляє ручне ущільнення:
typescriptconst compactResult = await compactEmbeddedPiSessionDirect({ sessionId, sessionFile, provider, model, ... });
Автентифікація та розв'язання моделі
Профілі автентифікації
Mayros підтримує сховище профілів автентифікації з кількома API-ключами на провайдера:
typescriptconst authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false }); const profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });
Профілі обертаються при збоях з відстеженням часу очікування:
typescriptawait markAuthProfileFailure({ store, profileId, reason, cfg, agentDir }); const rotated = await advanceAuthProfile();
Розв'язання моделі
typescriptimport { resolveModel } from "./pi-embedded-runner/model.js"; const { model, error, authStorage, modelRegistry } = resolveModel( provider, modelId, agentDir, config, ); // Використовує ModelRegistry та AuthStorage pi authStorage.setRuntimeApiKey(model.provider, apiKeyInfo.apiKey);
Аварійне переключення
FailoverError запускає відступ моделі при налаштуванні:
typescriptif (fallbackConfigured && isFailoverErrorMessage(errorText)) { throw new FailoverError(errorText, { reason: promptFailoverReason ?? "unknown", provider, model: modelId, profileId, status: resolveFailoverStatus(promptFailoverReason), }); }
Розширення Pi
Mayros завантажує власні розширення pi для спеціалізованої поведінки:
Захист ущільнення
pi-extensions/compaction-safeguard.ts додає захисні бар'єри до ущільнення, включаючи адаптивне бюджетування токенів плюс збої інструментів та підсумки операцій з файлами:
typescriptif (resolveCompactionMode(params.cfg) === "safeguard") { setCompactionSafeguardRuntime(params.sessionManager, { maxHistoryShare }); paths.push(resolvePiExtensionPath("compaction-safeguard")); }
Обрізання контексту
pi-extensions/context-pruning.ts реалізує обрізання контексту на основі cache-TTL:
typescriptif (cfg?.agents?.defaults?.contextPruning?.mode === "cache-ttl") { setContextPruningRuntime(params.sessionManager, { settings, contextWindowTokens, isToolPrunable, lastCacheTouchAt, }); paths.push(resolvePiExtensionPath("context-pruning")); }
Потокове передавання та блокові відповіді
Розбиття блоків
EmbeddedBlockChunker керує потоковим передаванням тексту в дискретні блоки відповідей:
typescriptconst blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;
Видалення тегів мислення/фінальних
Потоковий вивід обробляється для видалення блоків <think>/<thinking> та витягування вмісту <final>:
typescriptconst stripBlockTags = (text: string, state: { thinking: boolean; final: boolean }) => { // Видалити вміст <think>...</think> // Якщо enforceFinalTag, повернути лише вміст <final>...</final> };
Директиви відповіді
Директиви відповіді, такі як [[media:url]], [[voice]], [[reply:id]], розбираються та витягуються:
typescriptconst { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);
Обробка помилок
Класифікація помилок
pi-embedded-helpers.ts класифікує помилки для відповідної обробки:
typescriptisContextOverflowError(errorText) // Контекст занадто великий isCompactionFailureError(errorText) // Ущільнення не вдалося isAuthAssistantError(lastAssistant) // Збій автентифікації isRateLimitAssistantError(...) // Обмеження швидкості isFailoverAssistantError(...) // Має бути аварійне переключення classifyFailoverReason(errorText) // "auth" | "rate_limit" | "quota" | "timeout" | ...
Резервний рівень мислення
Якщо рівень мислення не підтримується, він повертається:
typescriptconst fallbackThinking = pickFallbackThinkingLevel({ message: errorText, attempted: attemptedThinking, }); if (fallbackThinking) { thinkLevel = fallbackThinking; continue; }
Інтеграція пісочниці
Коли ввімкнено режим пісочниці, інструменти та шляхи обмежені:
typescriptconst sandbox = await resolveSandboxContext({ config: params.config, sessionKey: sandboxSessionKey, workspaceDir: resolvedWorkspace, }); if (sandboxRoot) { // Використовувати інструменти read/edit/write у пісочниці // Exec виконується в контейнері // Браузер використовує URL мосту }
Обробка, специфічна для провайдера
Anthropic
- Очищення магічного рядка відмови
- Перевірка ходів для послідовних ролей
- Сумісність параметрів Claude Code
Google/Gemini
- Виправлення порядку ходів (
applyGoogleTurnOrderingFix) - Санітизація схеми інструментів (
sanitizeToolsForGoogle) - Санітизація історії сесій (
sanitizeSessionHistory)
OpenAI
- Інструмент
apply_patchдля моделей Codex - Обробка зниження рівня мислення
Інтеграція TUI
Mayros також має локальний режим TUI, який безпосередньо використовує компоненти pi-tui:
typescript// src/tui/tui.ts import { ... } from "@mariozechner/pi-tui";
Це забезпечує інтерактивний термінальний досвід, подібний до нативного режиму pi.
Ключові відмінності від Pi CLI
| Аспект | Pi CLI | Mayros Embedded |
|---|---|---|
| Виклик | Команда pi / RPC | SDK через createAgentSession() |
| Інструменти | Типові інструменти кодування | Власний набір інструментів Mayros |
| Системна підказка | AGENTS.md + підказки | Динамічна для кожного каналу/контексту |
| Зберігання сесій | ~/.pi/agent/sessions/ | ~/.mayros/agents/<agentId>/sessions/ (або $MAYROS_STATE_DIR/agents/<agentId>/sessions/) |
| Автентифікація | Одне посвідчення | Кілька профілів з ротацією |
| Розширення | Завантажені з диска | Програмні + шляхи диска |
| Обробка подій | Рендеринг TUI | На основі зворотних викликів (onBlockReply тощо) |
Майбутні міркування
Області для потенційного переробки:
- Узгодження сигнатур інструментів: наразі адаптація між сигнатурами pi-agent-core та pi-coding-agent
- Обгортання менеджера сесій:
guardSessionManagerдодає безпеку, але збільшує складність - Завантаження розширень: можна більш безпосередньо використовувати
ResourceLoaderpi - Складність обробника потокового передавання:
subscribeEmbeddedPiSessionвиріс великим - Особливості провайдера: багато кодових шляхів, специфічних для провайдера, які pi потенційно міг би обробити
Тести
Всі існуючі тести, які охоплюють інтеграцію pi та її розширення:
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