@symerian/symi 2.4.4 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/{agents-D0WIqYlR.js → agents-BEPfMqrg.js} +4 -4
  2. package/dist/{agents.config-DijsN6pE.js → agents.config-D60gMagv.js} +1 -1
  3. package/dist/{agents.config-BJhlUUzn.js → agents.config-DPv-AmZD.js} +1 -1
  4. package/dist/{audio-preflight-C40mKAp7.js → audio-preflight-CPBOQV4I.js} +4 -4
  5. package/dist/{audio-preflight-O3ASWbaG.js → audio-preflight-D02HwB-I.js} +4 -4
  6. package/dist/{auth-choice-CBrZeM8N.js → auth-choice-BeHaRQfM.js} +1 -1
  7. package/dist/{auth-choice-CzrXJoq0.js → auth-choice-CTeG2A5P.js} +1 -1
  8. package/dist/{banner-DBCyc2l3.js → banner-DihS8WHF.js} +1 -1
  9. package/dist/build-info.json +3 -3
  10. package/dist/bundled/boot-md/handler.js +6 -6
  11. package/dist/bundled/session-memory/handler.js +6 -6
  12. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  13. package/dist/{channel-options-CcNcqLfp.js → channel-options-BJphNYiq.js} +1 -1
  14. package/dist/{channel-options-D4b4yiR3.js → channel-options-D2Zf6a2L.js} +1 -1
  15. package/dist/{channel-web-BxgOSVS3.js → channel-web-BnZ6c0_u.js} +1 -1
  16. package/dist/{channels-cli-CH8FgCHM.js → channels-cli-CF9LDCSC.js} +4 -4
  17. package/dist/{channels-cli-DahG1tUQ.js → channels-cli-COMko9mZ.js} +4 -4
  18. package/dist/{chrome-CDJYxX5a.js → chrome-D2SKJnR7.js} +7 -7
  19. package/dist/{chrome-BFekevcE.js → chrome-EyvdASWt.js} +7 -7
  20. package/dist/{cli-xjbQGnY4.js → cli-DXpAHJS4.js} +1 -1
  21. package/dist/{cli-BG5jr57F.js → cli-DYNTJxmZ.js} +1 -1
  22. package/dist/{command-registry-jAjzb3Ub.js → command-registry-X_FmrHib.js} +9 -9
  23. package/dist/{completion-cli-C5YhoKGC.js → completion-cli-D1aObtjM.js} +1 -1
  24. package/dist/{completion-cli-zIGxgk1g.js → completion-cli-Dhj0jCR_.js} +2 -2
  25. package/dist/{config-cli-3hyKITmM.js → config-cli-BDpBT1b-.js} +1 -1
  26. package/dist/{config-cli-CPhmjH-O.js → config-cli-BrmaXVj4.js} +1 -1
  27. package/dist/{configure-C39-I7AH.js → configure-CkCFJCKp.js} +3 -3
  28. package/dist/{configure-S9KIFkj-.js → configure-oMqP6jIk.js} +3 -3
  29. package/dist/{deliver-BH0l3UKW.js → deliver-C-37cZUe.js} +1 -1
  30. package/dist/{deliver-CvCK5Mm9.js → deliver-D1ZN6-fl.js} +1 -1
  31. package/dist/{doctor-completion-DMcB-j3Q.js → doctor-completion-vhqAoURB.js} +1 -1
  32. package/dist/{doctor-completion-DjNFcAWO.js → doctor-completion-wGoyzRH8.js} +1 -1
  33. package/dist/entry.js +1 -1
  34. package/dist/extensionAPI.js +6 -6
  35. package/dist/{gateway-cli-CptbhYJ1.js → gateway-cli-BBPEwiAc.js} +9 -9
  36. package/dist/{gateway-cli-Bwd_To8f.js → gateway-cli-uDuGdJsH.js} +9 -9
  37. package/dist/{glass-ui-ws-B4jT1ok5.js → glass-ui-ws-DiqQflvy.js} +7 -7
  38. package/dist/{glass-ui-ws-B8ap5D2v.js → glass-ui-ws-TCkne4L4.js} +7 -7
  39. package/dist/{health-DhqSQMPI.js → health-1KsVR3eN.js} +1 -1
  40. package/dist/{health-DCb7BG-3.js → health-CPYlV7Zg.js} +1 -1
  41. package/dist/{hooks-cli-D5W9ERxc.js → hooks-cli-CL266d2E.js} +2 -2
  42. package/dist/{hooks-cli-DK2j2rIy.js → hooks-cli-PKy2h3eb.js} +2 -2
  43. package/dist/{image-B0wGflxA.js → image-Cp3JDEBB.js} +1 -1
  44. package/dist/{image-CHzdaNJ4.js → image-DcpMiprB.js} +1 -1
  45. package/dist/index.js +6 -6
  46. package/dist/llm-slug-generator.js +6 -6
  47. package/dist/{models-Bh86hVEJ.js → models-BsS_l1gY.js} +2 -2
  48. package/dist/{models-cli-DNLCTKv1.js → models-cli-CmR7k-2e.js} +2 -2
  49. package/dist/{models-cli-DLEKxIbC.js → models-cli-CvxkLybz.js} +3 -3
  50. package/dist/{onboard-CYMyc_UX.js → onboard-Bgo_BcMo.js} +2 -2
  51. package/dist/{onboard-ey37IWby.js → onboard-D2GpwLzg.js} +2 -2
  52. package/dist/{onboard-channels-Dj_lMj0q.js → onboard-channels-3WFDi7Ts.js} +1 -1
  53. package/dist/{onboard-channels-BmoLkeU6.js → onboard-channels-BNTeFCna.js} +1 -1
  54. package/dist/{onboarding-Dm9fej7n.js → onboarding-BUumoJYB.js} +3 -3
  55. package/dist/{onboarding-DLyAGYc6.js → onboarding-CbkyewZp.js} +3 -3
  56. package/dist/{onboarding.finalize-CEBQJBqF.js → onboarding.finalize-B2_mgA4K.js} +6 -6
  57. package/dist/{onboarding.finalize-csPp9wn_.js → onboarding.finalize-sESCY9Iq.js} +5 -5
  58. package/dist/{pi-embedded-Lrmi4POJ.js → pi-embedded-BIIdwXKr.js} +316 -85
  59. package/dist/{pi-embedded-BUYWm5p1.js → pi-embedded-BOF7XlCO.js} +316 -85
  60. package/dist/{pi-embedded-helpers-lgx_U5KS.js → pi-embedded-helpers-B8kqLWns.js} +4 -4
  61. package/dist/{pi-embedded-helpers-DLFjnVBb.js → pi-embedded-helpers-ag2bosuj.js} +4 -4
  62. package/dist/{plugin-registry-D1vzxXON.js → plugin-registry-BDfC2z-e.js} +1 -1
  63. package/dist/{plugin-registry-ChH5CJIw.js → plugin-registry-IXa-nyg0.js} +1 -1
  64. package/dist/plugin-sdk/agents/output-normalizer.d.ts +69 -0
  65. package/dist/plugin-sdk/{channel-web-DOZ-G9xX.js → channel-web-HznAZS1r.js} +1 -1
  66. package/dist/plugin-sdk/index.js +2 -2
  67. package/dist/plugin-sdk/{reply-BIMkrLWh.js → reply-DpnW-aMb.js} +302 -71
  68. package/dist/plugin-sdk/{web-BsZ7_Dy0.js → web-CGNEXRkp.js} +2 -2
  69. package/dist/{plugins-cli-CCMRc0SH.js → plugins-cli-DAxj0T7n.js} +2 -2
  70. package/dist/{plugins-cli-0PARfFDh.js → plugins-cli-DsYvb9az.js} +2 -2
  71. package/dist/{program-CTvCt90X.js → program-C_UFd0ph.js} +7 -7
  72. package/dist/{program-context-LQmFqAP2.js → program-context-C-1s9IMf.js} +17 -17
  73. package/dist/{prompt-select-styled-M1mZT6zR.js → prompt-select-styled-CYRG7OzR.js} +4 -4
  74. package/dist/{prompt-select-styled-Dk4KU3bk.js → prompt-select-styled-uEjL8GAK.js} +4 -4
  75. package/dist/{provider-auth-helpers-DM1hfi20.js → provider-auth-helpers-CJUiVhCt.js} +1 -1
  76. package/dist/{provider-auth-helpers-CXq_C8eC.js → provider-auth-helpers-CpOR6tLS.js} +1 -1
  77. package/dist/{push-apns-7t_aUx_g.js → push-apns-21LKYvkS.js} +1 -1
  78. package/dist/{push-apns-D-D1fcAb.js → push-apns-Ciljlk7J.js} +1 -1
  79. package/dist/{pw-ai-De-KR9_s.js → pw-ai-1htA-NnS.js} +1 -1
  80. package/dist/{pw-ai-BnAKvSuw.js → pw-ai-Ch7liUOW.js} +1 -1
  81. package/dist/{register.agent-nABNjBav.js → register.agent-BSv7WO-U.js} +6 -6
  82. package/dist/{register.agent-CWwXTRwB.js → register.agent-stsk6Gip.js} +5 -5
  83. package/dist/{register.configure-FljQTqAv.js → register.configure-C8oDtnaI.js} +6 -6
  84. package/dist/{register.configure-CV6utD3b.js → register.configure-DNQTd6SJ.js} +6 -6
  85. package/dist/{register.maintenance-BxRP1viU.js → register.maintenance-B3f3jkUo.js} +7 -7
  86. package/dist/{register.maintenance-CAACXueD.js → register.maintenance-dTI3y4Eh.js} +8 -8
  87. package/dist/{register.message-uz5SnsUO.js → register.message-Cbb4nH_0.js} +2 -2
  88. package/dist/{register.message-D_Cc5Hcu.js → register.message-K9BDeFyy.js} +2 -2
  89. package/dist/{register.onboard-BGsi8HVc.js → register.onboard-BBfmwa3j.js} +4 -4
  90. package/dist/{register.onboard-C8C1xEuj.js → register.onboard-Djz7Di9K.js} +4 -4
  91. package/dist/{register.setup-CbPytgHL.js → register.setup-B6hkCLH0.js} +4 -4
  92. package/dist/{register.setup-CyxXsD-4.js → register.setup-Dmu1jt3n.js} +4 -4
  93. package/dist/{register.status-health-sessions-DW422lcn.js → register.status-health-sessions-CvwhBkbb.js} +3 -3
  94. package/dist/{register.status-health-sessions-B_BYvadL.js → register.status-health-sessions-DaSrMm3l.js} +3 -3
  95. package/dist/{register.subclis-DAEtHKAL.js → register.subclis-Dv1WM9Kj.js} +9 -9
  96. package/dist/{reply-BWno_mxL.js → reply-BvVsPU7v.js} +303 -72
  97. package/dist/{run-main-GCA3ZWtS.js → run-main-55CDVAv6.js} +14 -14
  98. package/dist/{runner-DUBExAb5.js → runner-BcQ0sF9T.js} +1 -1
  99. package/dist/{runner-odEv83vv.js → runner-D0QUGA_X.js} +1 -1
  100. package/dist/{server-methods-C0qS1GBg.js → server-methods-Bf8SpXoW.js} +7 -7
  101. package/dist/{server-methods-BgZzcT_t.js → server-methods-CDDLS3ke.js} +7 -7
  102. package/dist/{server-node-events-BqTGMdx6.js → server-node-events-B9iZK3qE.js} +2 -2
  103. package/dist/{server-node-events-CCfQHLwH.js → server-node-events-Dx0L419d.js} +2 -2
  104. package/dist/{status-uaQ9lnOb.js → status-5XgxbiNb.js} +1 -1
  105. package/dist/{status-C0ghzWRG.js → status-C-kU0UFm.js} +1 -1
  106. package/dist/{status-BzeN5Od7.js → status-C-vthqzQ.js} +2 -2
  107. package/dist/{status-C_eTc_yp.js → status-DEymUALi.js} +2 -2
  108. package/dist/{subagent-registry-CtKDHowr.js → subagent-registry-CZah-77E.js} +303 -72
  109. package/dist/{update-cli-B2AkRDy-.js → update-cli-B21iNb0v.js} +7 -7
  110. package/dist/{update-cli-CYjjpmcv.js → update-cli-BSk-OFnI.js} +8 -8
  111. package/dist/{update-runner-C71_pwI8.js → update-runner-B5bKK21U.js} +1 -1
  112. package/dist/{update-runner-Co1TMSnd.js → update-runner-DPwXk0QQ.js} +1 -1
  113. package/dist/{web-DyULVUaV.js → web-CB23XCVF.js} +2 -2
  114. package/dist/{web-YnBBOOGf.js → web-DSgWG_2m.js} +6 -6
  115. package/dist/{web-DOlZ2V8e.js → web-DVvZ_mDC.js} +6 -6
  116. package/dist/{web-x4zdMRTu.js → web-mkZpWfVs.js} +1 -1
  117. package/package.json +1 -1
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
2
  import { M as getActivePluginRegistry, o as createSubsystemLogger } from "./entry.js";
3
3
  import { c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-D-jRCY0d.js";
4
4
  import { i as loadConfig } from "./config-DHBLS1Hl.js";
5
- import { h as loadSymiPlugins } from "./subagent-registry-CtKDHowr.js";
5
+ import { m as loadSymiPlugins } from "./subagent-registry-CZah-77E.js";
6
6
 
7
7
  //#region src/cli/plugin-registry.ts
8
8
  var plugin_registry_exports = /* @__PURE__ */ __exportAll({ ensurePluginRegistryLoaded: () => ensurePluginRegistryLoaded });
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
- import { pt as loadSymiPlugins } from "./reply-BWno_mxL.js";
2
+ import { ft as loadSymiPlugins } from "./reply-BvVsPU7v.js";
3
3
  import { d as getActivePluginRegistry } from "./registry-Cja8eT7G.js";
4
4
  import { t as createSubsystemLogger } from "./subsystem-D9vIQve0.js";
5
5
  import { c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-CgUHAtCo.js";
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Output Normalizer — single processing layer for all model output.
3
+ *
4
+ * All output from the model (text deltas, tool call arguments, final text)
5
+ * passes through ONE normalizer before reaching the agent loop, tool dispatch,
6
+ * event pipeline, or any client.
7
+ *
8
+ * Replaces the scattered filters across emitChatDelta, emitChatFinal, render.js,
9
+ * pi-tools.ts, and attempt.ts with one coherent processing point.
10
+ *
11
+ * Design: model output is untrusted input. The normalizer validates and cleans
12
+ * it the same way you'd sanitize user input at a system boundary.
13
+ *
14
+ * @module
15
+ */
16
+ import type { ModelProfile } from "../config/model-profiles.js";
17
+ export interface NormalizeTextResult {
18
+ /** Cleaned text delta. */
19
+ text: string;
20
+ /** If set, the stream should be aborted immediately. */
21
+ abort?: {
22
+ reason: string;
23
+ };
24
+ }
25
+ export interface OutputNormalizer {
26
+ /** Process a text delta from the model stream. Returns cleaned text
27
+ * and optional abort signal (combined — no separate shouldAbort check). */
28
+ normalizeTextDelta(delta: string): NormalizeTextResult;
29
+ /** Process tool call arguments. Returns cleaned args with all string
30
+ * values stripped of control tokens. */
31
+ normalizeToolArgs(args: Record<string, unknown>): Record<string, unknown>;
32
+ /** Process the final accumulated text. Strips tokens, detects and removes
33
+ * trailing monologue blocks. Called once when the model turn completes. */
34
+ normalizeFinalText(text: string): string;
35
+ /** Reset state for a new model turn. */
36
+ reset(): void;
37
+ }
38
+ /**
39
+ * Layer 2: Structural monologue detection.
40
+ * Detects a trailing block that:
41
+ * 1. Starts after a double newline
42
+ * 2. Opens with a self-referential phrase
43
+ * 3. Contains a numbered list with assessment keywords
44
+ * 4. Sits at the end of the text
45
+ */
46
+ declare function detectMonologueStructural(text: string): number | null;
47
+ /**
48
+ * Strip monologue from final text using the hierarchy:
49
+ * Layer 2 (structural) first, Layer 3 (regex) as fallback.
50
+ * Layer 1 (prompt tuning) happens before the model produces output.
51
+ */
52
+ declare function stripMonologue(text: string): string;
53
+ declare function detectRepetition(text: string, minBlock: number): boolean;
54
+ declare function sanitizeArgs(args: Record<string, unknown>, modelId: string): Record<string, unknown>;
55
+ /**
56
+ * Create an output normalizer configured for the given model profile.
57
+ *
58
+ * For Claude: passthrough (no stripping, no monologue, no aggressive cleaning).
59
+ * For Gemma/vLLM: full normalization pipeline.
60
+ * For unknown: conservative defaults.
61
+ */
62
+ export declare function createOutputNormalizer(profile: ModelProfile, modelId: string): OutputNormalizer;
63
+ export declare const __testing: {
64
+ detectMonologueStructural: typeof detectMonologueStructural;
65
+ stripMonologue: typeof stripMonologue;
66
+ detectRepetition: typeof detectRepetition;
67
+ sanitizeArgs: typeof sanitizeArgs;
68
+ };
69
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { a as buildGroupHistoryKey, n as DEFAULT_MAIN_KEY, r as buildAgentMainSessionKey, s as normalizeAgentId } from "./session-key-C_0eELjb.js";
2
2
  import { f as readWebSelfId, o as getWebAuthAgeMs, r as resolveWhatsAppAccount } from "./accounts-Ddm33hQm.js";
3
- import { E as enqueueSystemEvent, G as resolveMentionGating, W as shouldAckReactionForWhatsApp, X as buildHistoryContextFromEntries, Y as DEFAULT_GROUP_HISTORY_LIMIT, _ as resolveEnvelopeFormatOptions, c as computeBackoff, d as formatDurationPrecise, f as dispatchReplyWithBufferedBlockDispatcher, g as formatInboundEnvelope, h as resolveInboundDebounceMs, ht as createDedupeCache, l as sleepWithAbort, m as createInboundDebouncer, n as normalizeGroupActivation, nt as buildMentionRegexes, r as parseActivationCommand, rt as normalizeMentionText, t as getReplyFromConfig, tt as recordPendingHistoryEntryIfEnabled, u as buildPairingReply, v as hasControlCommand, y as shouldComputeCommandAuthorized } from "./reply-BIMkrLWh.js";
3
+ import { E as enqueueSystemEvent, G as resolveMentionGating, W as shouldAckReactionForWhatsApp, X as buildHistoryContextFromEntries, Y as DEFAULT_GROUP_HISTORY_LIMIT, _ as resolveEnvelopeFormatOptions, c as computeBackoff, d as formatDurationPrecise, f as dispatchReplyWithBufferedBlockDispatcher, g as formatInboundEnvelope, h as resolveInboundDebounceMs, ht as createDedupeCache, l as sleepWithAbort, m as createInboundDebouncer, n as normalizeGroupActivation, nt as buildMentionRegexes, r as parseActivationCommand, rt as normalizeMentionText, t as getReplyFromConfig, tt as recordPendingHistoryEntryIfEnabled, u as buildPairingReply, v as hasControlCommand, y as shouldComputeCommandAuthorized } from "./reply-DpnW-aMb.js";
4
4
  import { A as normalizeE164, B as toWhatsappJid, K as logVerbose, N as resolveJidToE164, O as isSelfChatMode, R as sleep, Y as shouldLogVerbose, k as jidToE164, s as normalizeChatChannelId, tt as getChildLogger, x as clamp } from "./registry-D0xTnUWt.js";
5
5
  import { n as loadConfig } from "./config-KlTNfkFF.js";
6
6
  import { i as defaultRuntime, t as createSubsystemLogger } from "./subsystem-B2uDN3TV.js";
@@ -1,6 +1,6 @@
1
1
  import { f as DEFAULT_ACCOUNT_ID, p as normalizeAccountId } from "./session-key-C_0eELjb.js";
2
2
  import { _ as createAccountListHelpers, i as resolveWhatsAppAuthDir, n as resolveDefaultWhatsAppAccountId, r as resolveWhatsAppAccount, t as listWhatsAppAccountIds } from "./accounts-Ddm33hQm.js";
3
- import { $ as clearHistoryEntriesIfEnabled, A as resolveDiscordUserAllowlist, B as logTypingFailure, C as stripMarkdown, Ct as unbindThreadBindingsBySessionKey, D as resolveSlackUserAllowlist, Dt as BLUEBUBBLES_ACTION_NAMES, Et as BLUEBUBBLES_ACTIONS, F as stringEnum, G as resolveMentionGating, H as removeAckReactionAfterReply, I as recordInboundSession, J as summarizeMapping, K as resolveMentionGatingWithBypass, L as resolveControlCommandGate, M as collectDiscordAuditChannelIds, N as formatDocsLink, O as resolveSlackChannelAllowlist, Ot as BLUEBUBBLES_GROUP_ACTIONS, P as optionalStringEnum, Q as clearHistoryEntries, R as logAckFailure, S as processLineMessage, St as listThreadBindingsBySessionKey, T as attachFooterText, Tt as resolveAllowlistMatchSimple, U as shouldAckReaction, V as createTypingCallbacks, W as shouldAckReactionForWhatsApp, Y as DEFAULT_GROUP_HISTORY_LIMIT, Z as buildPendingHistoryContextFromMap, _t as listDevicePairing, a as normalizeAccountId$1, at as isWSLEnv, bt as registerPluginHttpRoute, ct as DEFAULT_WEBHOOK_MAX_BODY_BYTES, dt as isRequestBodyLimitError, et as recordPendingHistoryEntry, ft as readJsonBodyWithLimit, gt as approveDevicePairing, ht as createDedupeCache, i as listLineAccountIds, it as isWSL2Sync, j as resolveDiscordChannelAllowlist, k as detectBinary, kt as CHANNEL_MESSAGE_ACTION_NAMES, lt as RequestBodyLimitError, mt as requestBodyErrorToText, o as resolveDefaultLineAccountId, ot as isWSLSync, pt as readRequestBodyWithLimit, q as mergeAllowlist, s as resolveLineAccount, st as DEFAULT_WEBHOOK_BODY_TIMEOUT_MS, tt as recordPendingHistoryEntryIfEnabled, ut as installRequestBodyLimitGuard, vt as rejectDevicePairing, w as createReceiptCard, wt as formatAllowlistMatchMeta, x as hasMarkdownToConvert, xt as autoBindSpawnedDiscordSubagent, yt as extractToolSend, z as logInboundDrop } from "./reply-BIMkrLWh.js";
3
+ import { $ as clearHistoryEntriesIfEnabled, A as resolveDiscordUserAllowlist, B as logTypingFailure, C as stripMarkdown, Ct as unbindThreadBindingsBySessionKey, D as resolveSlackUserAllowlist, Dt as BLUEBUBBLES_ACTION_NAMES, Et as BLUEBUBBLES_ACTIONS, F as stringEnum, G as resolveMentionGating, H as removeAckReactionAfterReply, I as recordInboundSession, J as summarizeMapping, K as resolveMentionGatingWithBypass, L as resolveControlCommandGate, M as collectDiscordAuditChannelIds, N as formatDocsLink, O as resolveSlackChannelAllowlist, Ot as BLUEBUBBLES_GROUP_ACTIONS, P as optionalStringEnum, Q as clearHistoryEntries, R as logAckFailure, S as processLineMessage, St as listThreadBindingsBySessionKey, T as attachFooterText, Tt as resolveAllowlistMatchSimple, U as shouldAckReaction, V as createTypingCallbacks, W as shouldAckReactionForWhatsApp, Y as DEFAULT_GROUP_HISTORY_LIMIT, Z as buildPendingHistoryContextFromMap, _t as listDevicePairing, a as normalizeAccountId$1, at as isWSLEnv, bt as registerPluginHttpRoute, ct as DEFAULT_WEBHOOK_MAX_BODY_BYTES, dt as isRequestBodyLimitError, et as recordPendingHistoryEntry, ft as readJsonBodyWithLimit, gt as approveDevicePairing, ht as createDedupeCache, i as listLineAccountIds, it as isWSL2Sync, j as resolveDiscordChannelAllowlist, k as detectBinary, kt as CHANNEL_MESSAGE_ACTION_NAMES, lt as RequestBodyLimitError, mt as requestBodyErrorToText, o as resolveDefaultLineAccountId, ot as isWSLSync, pt as readRequestBodyWithLimit, q as mergeAllowlist, s as resolveLineAccount, st as DEFAULT_WEBHOOK_BODY_TIMEOUT_MS, tt as recordPendingHistoryEntryIfEnabled, ut as installRequestBodyLimitGuard, vt as rejectDevicePairing, w as createReceiptCard, wt as formatAllowlistMatchMeta, x as hasMarkdownToConvert, xt as autoBindSpawnedDiscordSubagent, yt as extractToolSend, z as logInboundDrop } from "./reply-DpnW-aMb.js";
4
4
  import "./paths-DR2yt_mP.js";
5
5
  import "./github-copilot-token-D9X2phUj.js";
6
6
  import { D as resolveSlackAccount, E as resolveDefaultSlackAccountId, F as resolveDiscordAccount, M as listDiscordAccountIds, O as resolveSlackReplyToMode, P as resolveDefaultDiscordAccountId, S as resolveTelegramAccount, T as listSlackAccountIds, _ as normalizeWhatsAppTarget, a as listDiscordDirectoryPeersFromConfig, b as listTelegramAccountIds, c as listTelegramDirectoryGroupsFromConfig, d as listWhatsAppDirectoryPeersFromConfig, f as looksLikeSlackTargetId, g as isWhatsAppGroupJid, i as listDiscordDirectoryGroupsFromConfig, l as listTelegramDirectoryPeersFromConfig, o as listSlackDirectoryGroupsFromConfig, p as normalizeSlackMessagingTarget, s as listSlackDirectoryPeersFromConfig, u as listWhatsAppDirectoryGroupsFromConfig, w as listEnabledSlackAccounts, x as resolveDefaultTelegramAccountId } from "./plugins-BNByVCIH.js";
@@ -47,7 +47,7 @@ import "./paths-A0xdf3yk.js";
47
47
  import { h as onDiagnosticEvent, m as isDiagnosticsEnabled, p as emitDiagnosticEvent } from "./diagnostic-05pm5Rxi.js";
48
48
  import { n as extractOriginalFilename } from "./store-BdrNabcU.js";
49
49
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-BiyAyTWz.js";
50
- import { r as resolveWhatsAppHeartbeatRecipients } from "./channel-web-DOZ-G9xX.js";
50
+ import { r as resolveWhatsAppHeartbeatRecipients } from "./channel-web-HznAZS1r.js";
51
51
  import "./image-CLOPx7yW.js";
52
52
  import "./pi-model-discovery-LbcEa65a.js";
53
53
  import "./api-key-rotation-D_sMvI5W.js";
@@ -75,7 +75,7 @@ import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
75
75
  import * as fs$2 from "node:fs/promises";
76
76
  import fs$1 from "node:fs/promises";
77
77
  import { fileURLToPath } from "node:url";
78
- import { complete, completeSimple, streamSimple } from "@mariozechner/pi-ai";
78
+ import { complete, completeSimple, createAssistantMessageEventStream, streamSimple } from "@mariozechner/pi-ai";
79
79
  import AjvPkg from "ajv";
80
80
  import { ProxyAgent, fetch as fetch$1 } from "undici";
81
81
  import { Buffer as Buffer$1 } from "node:buffer";
@@ -27663,6 +27663,199 @@ function createCacheTrace(params) {
27663
27663
  };
27664
27664
  }
27665
27665
 
27666
+ //#endregion
27667
+ //#region src/agents/model-token-filter.ts
27668
+ /**
27669
+ * Strips model-specific control tokens from streamed text.
27670
+ *
27671
+ * Used both server-side (in the streaming pipeline) and by the Glass UI
27672
+ * (as a defense-in-depth fallback). The patterns here cover tokens known
27673
+ * to leak from Gemma 4 / vLLM; Claude output is left untouched.
27674
+ */
27675
+ const GEMMA_TOKEN_PATTERNS = [
27676
+ /<\|channel>\w*/g,
27677
+ /<channel\|>/g,
27678
+ /<start_of_turn>(?:model|user)?/g,
27679
+ /<end_of_turn>/g,
27680
+ /<\|(?:fim_prefix|fim_suffix|fim_middle)\|>/g,
27681
+ /^\s*<bos>\s*/gm,
27682
+ /<\|[^|>]{0,30}\|>/g,
27683
+ /<\|[^>]{0,30}>/g
27684
+ ];
27685
+ /**
27686
+ * Aggressively strip all fragments of model control token corruption from
27687
+ * tool arguments. This catches cases where the model produces raw garbage
27688
+ * like `<|<|"|<|<|\'` that doesn't match any known token template.
27689
+ */
27690
+ const AGGRESSIVE_TOKEN_FRAGMENTS = [/<\|/g, /\|>/g];
27691
+ const GEMMA_MODEL_HINTS$1 = ["gemma", "redsand/"];
27692
+ function isGemmaModel$1(modelId) {
27693
+ const lower = modelId.toLowerCase();
27694
+ return GEMMA_MODEL_HINTS$1.some((hint) => lower.includes(hint));
27695
+ }
27696
+ /**
27697
+ * Strip known control tokens from text. Only applies to Gemma-family models;
27698
+ * other models pass through unchanged.
27699
+ */
27700
+ /**
27701
+ * Strip known control tokens from text. Only applies to Gemma-family models;
27702
+ * other models pass through unchanged. Used for streamed text output.
27703
+ */
27704
+ function stripModelTokens(text, modelId) {
27705
+ if (!text || !isGemmaModel$1(modelId)) return text;
27706
+ let result = text;
27707
+ for (const re of GEMMA_TOKEN_PATTERNS) {
27708
+ re.lastIndex = 0;
27709
+ result = result.replace(re, "");
27710
+ }
27711
+ return result;
27712
+ }
27713
+ /**
27714
+ * Aggressively strip ALL token-like fragments from a string. Used for tool
27715
+ * call arguments where any `<|` corruption causes downstream failures.
27716
+ * More aggressive than `stripModelTokens` — removes bare `<|` and `|>` fragments
27717
+ * that don't match any known token template.
27718
+ */
27719
+ function stripModelTokensAggressive(text, modelId) {
27720
+ if (!text || !isGemmaModel$1(modelId)) return text;
27721
+ let result = stripModelTokens(text, modelId);
27722
+ for (const re of AGGRESSIVE_TOKEN_FRAGMENTS) {
27723
+ re.lastIndex = 0;
27724
+ result = result.replace(re, "");
27725
+ }
27726
+ return result;
27727
+ }
27728
+
27729
+ //#endregion
27730
+ //#region src/agents/output-normalizer.ts
27731
+ const MONOLOGUE_REGEX_PATTERNS = [
27732
+ /\n*I have addressed the request fully\.?\s*(?:\n[\s\S]*)?$/,
27733
+ /\n*I[''\u2019]ve reviewed my response[\s\S]*$/,
27734
+ /\n*\*?\*?Verification:?\*?\*?\s*\n[\s\S]*?(?:Everything is correct|All requirements met)\.?\s*\u2705?\s*$/,
27735
+ /\n*\d+\.\s*\*?\*?Requirements:?\*?\*?[\s\S]*?\d+\.\s*\*?\*?Verification:?\*?\*?[\s\S]*$/
27736
+ ];
27737
+ const SELF_REF_OPENERS = [
27738
+ "i have addressed",
27739
+ "i've reviewed",
27740
+ "i‘ve reviewed",
27741
+ "i’ve reviewed",
27742
+ "status check",
27743
+ "address requirements",
27744
+ "verification:",
27745
+ "requirements:"
27746
+ ];
27747
+ const ASSESSMENT_KEYWORDS = [
27748
+ "requirements",
27749
+ "verification",
27750
+ "correct",
27751
+ "addressed",
27752
+ "fulfilled",
27753
+ "confirmed",
27754
+ "passed"
27755
+ ];
27756
+ /**
27757
+ * Layer 2: Structural monologue detection.
27758
+ * Detects a trailing block that:
27759
+ * 1. Starts after a double newline
27760
+ * 2. Opens with a self-referential phrase
27761
+ * 3. Contains a numbered list with assessment keywords
27762
+ * 4. Sits at the end of the text
27763
+ */
27764
+ function detectMonologueStructural(text) {
27765
+ let searchFrom = Math.floor(text.length * .15);
27766
+ while (searchFrom < text.length) {
27767
+ const breakPos = text.indexOf("\n\n", searchFrom);
27768
+ if (breakPos < 0) return null;
27769
+ const trailingBlock = text.slice(breakPos).toLowerCase();
27770
+ if (!SELF_REF_OPENERS.some((opener) => trailingBlock.includes(opener))) {
27771
+ searchFrom = breakPos + 2;
27772
+ continue;
27773
+ }
27774
+ const hasNumberedList = /\d+\.\s/.test(trailingBlock);
27775
+ const hasBoldHeaders = /\*\*\w/.test(trailingBlock);
27776
+ if (!hasNumberedList && !hasBoldHeaders) {
27777
+ searchFrom = breakPos + 2;
27778
+ continue;
27779
+ }
27780
+ if (ASSESSMENT_KEYWORDS.filter((kw) => trailingBlock.includes(kw)).length < 2) {
27781
+ searchFrom = breakPos + 2;
27782
+ continue;
27783
+ }
27784
+ return breakPos;
27785
+ }
27786
+ return null;
27787
+ }
27788
+ /**
27789
+ * Strip monologue from final text using the hierarchy:
27790
+ * Layer 2 (structural) first, Layer 3 (regex) as fallback.
27791
+ * Layer 1 (prompt tuning) happens before the model produces output.
27792
+ */
27793
+ function stripMonologue(text) {
27794
+ const structuralCut = detectMonologueStructural(text);
27795
+ if (structuralCut !== null) {
27796
+ const cleaned = text.slice(0, structuralCut).trim();
27797
+ if (cleaned) return cleaned;
27798
+ }
27799
+ for (const pattern of MONOLOGUE_REGEX_PATTERNS) {
27800
+ const result = text.replace(pattern, "");
27801
+ if (result !== text && result.trim()) return result.trim();
27802
+ }
27803
+ return text;
27804
+ }
27805
+ const DEFAULT_REPETITION_MIN_BLOCK = 150;
27806
+ function detectRepetition(text, minBlock) {
27807
+ if (text.length < minBlock * 2.5) return false;
27808
+ const sampleStart = Math.floor(text.length * .25);
27809
+ const sample = text.slice(sampleStart, sampleStart + minBlock);
27810
+ const searchStart = sampleStart + minBlock;
27811
+ return text.indexOf(sample, searchStart) >= 0;
27812
+ }
27813
+ function sanitizeArgs(args, modelId) {
27814
+ const result = {};
27815
+ for (const [key, value] of Object.entries(args)) if (typeof value === "string") result[key] = stripModelTokensAggressive(value, modelId);
27816
+ else if (Array.isArray(value)) result[key] = value.map((item) => typeof item === "string" ? stripModelTokensAggressive(item, modelId) : item && typeof item === "object" ? sanitizeArgs(item, modelId) : item);
27817
+ else if (value && typeof value === "object") result[key] = sanitizeArgs(value, modelId);
27818
+ else result[key] = value;
27819
+ return result;
27820
+ }
27821
+ /**
27822
+ * Create an output normalizer configured for the given model profile.
27823
+ *
27824
+ * For Claude: passthrough (no stripping, no monologue, no aggressive cleaning).
27825
+ * For Gemma/vLLM: full normalization pipeline.
27826
+ * For unknown: conservative defaults.
27827
+ */
27828
+ function createOutputNormalizer(profile, modelId) {
27829
+ const isGemma = isGemmaModel$1(modelId);
27830
+ const shouldStrip = isGemma || profile.filters.stripPatterns.length > 0;
27831
+ const shouldSuppressMonologue = profile.filters.suppressMonologue;
27832
+ let accumulated = "";
27833
+ return {
27834
+ normalizeTextDelta(delta) {
27835
+ const text = shouldStrip ? stripModelTokens(delta, modelId) : delta;
27836
+ accumulated += text;
27837
+ if (detectRepetition(accumulated, DEFAULT_REPETITION_MIN_BLOCK)) return {
27838
+ text,
27839
+ abort: { reason: "repetition-detected" }
27840
+ };
27841
+ return { text };
27842
+ },
27843
+ normalizeToolArgs(args) {
27844
+ if (!isGemma) return args;
27845
+ return sanitizeArgs(args, modelId);
27846
+ },
27847
+ normalizeFinalText(text) {
27848
+ let result = text;
27849
+ if (shouldStrip) result = stripModelTokens(result, modelId);
27850
+ if (shouldSuppressMonologue) result = stripMonologue(result);
27851
+ return result.trim();
27852
+ },
27853
+ reset() {
27854
+ accumulated = "";
27855
+ }
27856
+ };
27857
+ }
27858
+
27666
27859
  //#endregion
27667
27860
  //#region src/agents/model-aware-stream.ts
27668
27861
  /**
@@ -27674,6 +27867,7 @@ function createCacheTrace(params) {
27674
27867
  */
27675
27868
  function createModelAwareStreamFn(opts) {
27676
27869
  const underlying = opts.baseStreamFn ?? streamSimple;
27870
+ const fullModelId = opts.provider ? `${opts.provider}/${opts.modelId}` : opts.modelId;
27677
27871
  const mergedParams = {
27678
27872
  ...opts.profile.params,
27679
27873
  ...opts.configExtraParams,
@@ -27710,9 +27904,11 @@ function createModelAwareStreamFn(opts) {
27710
27904
  }
27711
27905
  callerOnPayload?.(payload);
27712
27906
  };
27907
+ const normalizer = createOutputNormalizer(opts.profile, fullModelId);
27713
27908
  return (model, context, options) => {
27714
27909
  const callerOnPayload = options?.onPayload;
27715
- return underlying(model, context, {
27910
+ normalizer.reset();
27911
+ const streamOrPromise = underlying(model, context, {
27716
27912
  ...nativeOpts,
27717
27913
  ...options,
27718
27914
  onPayload: (payload) => onPayloadHook(payload, callerOnPayload),
@@ -27721,8 +27917,106 @@ function createModelAwareStreamFn(opts) {
27721
27917
  ...options?.headers
27722
27918
  } } : {}
27723
27919
  });
27920
+ if (streamOrPromise instanceof Promise) return streamOrPromise.then((s) => wrapStreamWithNormalizer(s, normalizer));
27921
+ return wrapStreamWithNormalizer(streamOrPromise, normalizer);
27724
27922
  };
27725
27923
  }
27924
+ /**
27925
+ * Wrap an AssistantMessageEventStream to intercept and normalize events:
27926
+ * - text_delta: strip tokens, detect repetition
27927
+ * - toolcall_end: sanitize tool call arguments
27928
+ * - done: normalize final message text
27929
+ */
27930
+ function wrapStreamWithNormalizer(rawStream, normalizer) {
27931
+ const normalized = createAssistantMessageEventStream();
27932
+ (async () => {
27933
+ try {
27934
+ for await (const event of rawStream) {
27935
+ const processed = normalizeEvent(event, normalizer);
27936
+ if (processed.abort) {
27937
+ normalized.push({
27938
+ type: "error",
27939
+ reason: "aborted",
27940
+ errorMessage: `output-normalizer: ${processed.abort.reason}`,
27941
+ usage: {
27942
+ input: 0,
27943
+ output: 0
27944
+ }
27945
+ });
27946
+ break;
27947
+ }
27948
+ normalized.push(processed.event);
27949
+ }
27950
+ } catch (err) {
27951
+ normalized.push({
27952
+ type: "error",
27953
+ reason: "error",
27954
+ errorMessage: err instanceof Error ? err.message : String(err),
27955
+ usage: {
27956
+ input: 0,
27957
+ output: 0
27958
+ }
27959
+ });
27960
+ }
27961
+ })();
27962
+ return normalized;
27963
+ }
27964
+ function normalizeEvent(event, normalizer) {
27965
+ if (event.type === "text_delta") {
27966
+ const result = normalizer.normalizeTextDelta(event.delta);
27967
+ if (result.abort) return {
27968
+ event,
27969
+ abort: result.abort
27970
+ };
27971
+ if (result.text !== event.delta) return { event: {
27972
+ ...event,
27973
+ delta: result.text
27974
+ } };
27975
+ return { event };
27976
+ }
27977
+ if (event.type === "toolcall_end" && event.toolCall) {
27978
+ const tc = event.toolCall;
27979
+ if (tc.arguments && typeof tc.arguments === "object") {
27980
+ const cleanedArgs = normalizer.normalizeToolArgs(tc.arguments);
27981
+ return { event: {
27982
+ ...event,
27983
+ toolCall: {
27984
+ ...tc,
27985
+ arguments: cleanedArgs
27986
+ }
27987
+ } };
27988
+ }
27989
+ return { event };
27990
+ }
27991
+ if (event.type === "done" && event.message) {
27992
+ const msg = event.message;
27993
+ if (Array.isArray(msg.content)) {
27994
+ let changed = false;
27995
+ const normalizedContent = msg.content.map((block) => {
27996
+ if (block.type === "text" && "text" in block) {
27997
+ const cleaned = normalizer.normalizeFinalText(block.text);
27998
+ if (cleaned !== block.text) {
27999
+ changed = true;
28000
+ return {
28001
+ ...block,
28002
+ text: cleaned
28003
+ };
28004
+ }
28005
+ }
28006
+ return block;
28007
+ });
28008
+ if (changed) return { event: {
28009
+ ...event,
28010
+ message: {
28011
+ ...msg,
28012
+ content: normalizedContent
28013
+ }
28014
+ } };
28015
+ }
28016
+ return { event };
28017
+ }
28018
+ return { event };
28019
+ }
27726
28020
  /** Detect vLLM/Gemma providers by model hints or baseUrl patterns. */
27727
28021
  function isVllmProvider(provider, modelId, config) {
27728
28022
  const lower = `${provider}/${modelId}`.toLowerCase();
@@ -30915,7 +31209,7 @@ function buildSystemPromptReport(params) {
30915
31209
 
30916
31210
  //#endregion
30917
31211
  //#region src/agents/transcript-policy.ts
30918
- const GEMMA_MODEL_HINTS$1 = ["gemma", "redsand/"];
31212
+ const GEMMA_MODEL_HINTS = ["gemma", "redsand/"];
30919
31213
  const MISTRAL_MODEL_HINTS = [
30920
31214
  "mistral",
30921
31215
  "mixtral",
@@ -30944,11 +31238,11 @@ function isAnthropicApi(modelApi, provider) {
30944
31238
  if (modelApi === "anthropic-messages") return true;
30945
31239
  return normalizeProviderId(provider ?? "") === "anthropic";
30946
31240
  }
30947
- function isGemmaModel$1(params) {
31241
+ function isGemmaModel(params) {
30948
31242
  if (normalizeProviderId(params.provider ?? "") === "redsand") return true;
30949
31243
  const modelId = (params.modelId ?? "").toLowerCase();
30950
31244
  if (!modelId) return false;
30951
- return GEMMA_MODEL_HINTS$1.some((hint) => modelId.includes(hint));
31245
+ return GEMMA_MODEL_HINTS.some((hint) => modelId.includes(hint));
30952
31246
  }
30953
31247
  function isMistralModel(params) {
30954
31248
  if (normalizeProviderId(params.provider ?? "") === "mistral") return true;
@@ -30966,7 +31260,7 @@ function resolveTranscriptPolicy(params) {
30966
31260
  provider,
30967
31261
  modelId
30968
31262
  });
30969
- const isGemma = isGemmaModel$1({
31263
+ const isGemma = isGemmaModel({
30970
31264
  provider,
30971
31265
  modelId
30972
31266
  });
@@ -35503,7 +35797,7 @@ async function runAgentTurn(params) {
35503
35797
  function createDefaultDeps() {
35504
35798
  return {
35505
35799
  sendMessageWhatsApp: async (...args) => {
35506
- const { sendMessageWhatsApp } = await import("./web-BsZ7_Dy0.js");
35800
+ const { sendMessageWhatsApp } = await import("./web-CGNEXRkp.js");
35507
35801
  return await sendMessageWhatsApp(...args);
35508
35802
  },
35509
35803
  sendMessageTelegram: async (...args) => {
@@ -52941,7 +53235,7 @@ function loadWebLoginQr() {
52941
53235
  return webLoginQrPromise;
52942
53236
  }
52943
53237
  function loadWebChannel() {
52944
- webChannelPromise ??= import("./web-BsZ7_Dy0.js");
53238
+ webChannelPromise ??= import("./web-CGNEXRkp.js");
52945
53239
  return webChannelPromise;
52946
53240
  }
52947
53241
  function loadWhatsAppActions() {
@@ -58172,69 +58466,6 @@ function createProcessTool(defaults) {
58172
58466
  }
58173
58467
  const processTool = createProcessTool();
58174
58468
 
58175
- //#endregion
58176
- //#region src/agents/model-token-filter.ts
58177
- /**
58178
- * Strips model-specific control tokens from streamed text.
58179
- *
58180
- * Used both server-side (in the streaming pipeline) and by the Glass UI
58181
- * (as a defense-in-depth fallback). The patterns here cover tokens known
58182
- * to leak from Gemma 4 / vLLM; Claude output is left untouched.
58183
- */
58184
- const GEMMA_TOKEN_PATTERNS = [
58185
- /<\|channel>\w*/g,
58186
- /<channel\|>/g,
58187
- /<start_of_turn>(?:model|user)?/g,
58188
- /<end_of_turn>/g,
58189
- /<\|(?:fim_prefix|fim_suffix|fim_middle)\|>/g,
58190
- /^\s*<bos>\s*/gm,
58191
- /<\|[^|>]{0,30}\|>/g,
58192
- /<\|[^>]{0,30}>/g
58193
- ];
58194
- /**
58195
- * Aggressively strip all fragments of model control token corruption from
58196
- * tool arguments. This catches cases where the model produces raw garbage
58197
- * like `<|<|"|<|<|\'` that doesn't match any known token template.
58198
- */
58199
- const AGGRESSIVE_TOKEN_FRAGMENTS = [/<\|/g, /\|>/g];
58200
- const GEMMA_MODEL_HINTS = ["gemma", "redsand/"];
58201
- function isGemmaModel(modelId) {
58202
- const lower = modelId.toLowerCase();
58203
- return GEMMA_MODEL_HINTS.some((hint) => lower.includes(hint));
58204
- }
58205
- /**
58206
- * Strip known control tokens from text. Only applies to Gemma-family models;
58207
- * other models pass through unchanged.
58208
- */
58209
- /**
58210
- * Strip known control tokens from text. Only applies to Gemma-family models;
58211
- * other models pass through unchanged. Used for streamed text output.
58212
- */
58213
- function stripModelTokens(text, modelId) {
58214
- if (!text || !isGemmaModel(modelId)) return text;
58215
- let result = text;
58216
- for (const re of GEMMA_TOKEN_PATTERNS) {
58217
- re.lastIndex = 0;
58218
- result = result.replace(re, "");
58219
- }
58220
- return result;
58221
- }
58222
- /**
58223
- * Aggressively strip ALL token-like fragments from a string. Used for tool
58224
- * call arguments where any `<|` corruption causes downstream failures.
58225
- * More aggressive than `stripModelTokens` — removes bare `<|` and `|>` fragments
58226
- * that don't match any known token template.
58227
- */
58228
- function stripModelTokensAggressive(text, modelId) {
58229
- if (!text || !isGemmaModel(modelId)) return text;
58230
- let result = stripModelTokens(text, modelId);
58231
- for (const re of AGGRESSIVE_TOKEN_FRAGMENTS) {
58232
- re.lastIndex = 0;
58233
- result = result.replace(re, "");
58234
- }
58235
- return result;
58236
- }
58237
-
58238
58469
  //#endregion
58239
58470
  //#region src/agents/pi-tools.abort.ts
58240
58471
  function throwAbortError() {
@@ -1,5 +1,5 @@
1
1
  import { a as WA_WEB_AUTH_DIR, g as webAuthExists, s as logWebSelfId, u as pickWebChannel } from "./accounts-Ddm33hQm.js";
2
- import "./reply-BIMkrLWh.js";
2
+ import "./reply-DpnW-aMb.js";
3
3
  import "./paths-DR2yt_mP.js";
4
4
  import "./github-copilot-token-D9X2phUj.js";
5
5
  import "./plugins-BNByVCIH.js";
@@ -45,7 +45,7 @@ import "./pi-embedded-helpers-CW630epe.js";
45
45
  import "./paths-A0xdf3yk.js";
46
46
  import "./diagnostic-05pm5Rxi.js";
47
47
  import "./store-BdrNabcU.js";
48
- import { n as monitorWebInbox, t as monitorWebChannel } from "./channel-web-DOZ-G9xX.js";
48
+ import { n as monitorWebInbox, t as monitorWebChannel } from "./channel-web-HznAZS1r.js";
49
49
  import "./image-CLOPx7yW.js";
50
50
  import "./pi-model-discovery-LbcEa65a.js";
51
51
  import "./api-key-rotation-D_sMvI5W.js";
@@ -13,7 +13,7 @@ import "./client-DMBZpU6X.js";
13
13
  import "./call-BcE47FtD.js";
14
14
  import "./message-channel-C9dERklz.js";
15
15
  import "./pairing-token-Byh6drgn.js";
16
- import "./subagent-registry-CtKDHowr.js";
16
+ import "./subagent-registry-CZah-77E.js";
17
17
  import "./sessions-CJXnZVjR.js";
18
18
  import "./tokens-Csntmwwn.js";
19
19
  import "./plugins-CwSlLxM8.js";
@@ -102,7 +102,7 @@ import "./npm-registry-spec-DkaZNHAW.js";
102
102
  import "./skill-scanner-BGWOBqLY.js";
103
103
  import { i as resolvePluginInstallDir, n as installPluginFromNpmSpec, r as installPluginFromPath, t as recordPluginInstall } from "./installs-CgQpVncj.js";
104
104
  import { t as renderTable } from "./table-D01d2GuY.js";
105
- import { t as buildPluginStatusReport } from "./status-C0ghzWRG.js";
105
+ import { t as buildPluginStatusReport } from "./status-C-kU0UFm.js";
106
106
  import { n as updateNpmInstalledPlugins } from "./update-DEMKx4eC.js";
107
107
  import os from "node:os";
108
108
  import path from "node:path";
@@ -1,7 +1,7 @@
1
1
  import { g as resolveStateDir } from "./paths-Cqn-zk3M.js";
2
2
  import { B as theme, S as shortenHomePath, g as resolveConfigDir, x as shortenHomeInString, y as resolveUserPath } from "./utils-B-0b9bGM.js";
3
3
  import "./thinking-EAliFiVK.js";
4
- import "./reply-BWno_mxL.js";
4
+ import "./reply-BvVsPU7v.js";
5
5
  import "./registry-Cja8eT7G.js";
6
6
  import { f as defaultRuntime } from "./subsystem-D9vIQve0.js";
7
7
  import "./exec-CWkblSrI.js";
@@ -106,7 +106,7 @@ import "./npm-registry-spec-C2JDdSZS.js";
106
106
  import "./skill-scanner-CLs8u6vQ.js";
107
107
  import { i as resolvePluginInstallDir, n as installPluginFromNpmSpec, r as installPluginFromPath, t as recordPluginInstall } from "./installs-C1Cebk97.js";
108
108
  import { t as renderTable } from "./table-BTgkRafz.js";
109
- import { t as buildPluginStatusReport } from "./status-uaQ9lnOb.js";
109
+ import { t as buildPluginStatusReport } from "./status-5XgxbiNb.js";
110
110
  import { n as updateNpmInstalledPlugins } from "./update-rw7wJwHd.js";
111
111
  import fs from "node:fs";
112
112
  import os from "node:os";
@@ -14,7 +14,7 @@ import "./client-DMBZpU6X.js";
14
14
  import "./call-BcE47FtD.js";
15
15
  import "./message-channel-C9dERklz.js";
16
16
  import "./pairing-token-Byh6drgn.js";
17
- import "./subagent-registry-CtKDHowr.js";
17
+ import "./subagent-registry-CZah-77E.js";
18
18
  import "./sessions-CJXnZVjR.js";
19
19
  import "./tokens-Csntmwwn.js";
20
20
  import "./plugins-CwSlLxM8.js";
@@ -99,13 +99,13 @@ import "./prompt-style-DwCXob2h.js";
99
99
  import "./pairing-labels-D1HDboV2.js";
100
100
  import "./pi-tools.policy-De00gPXt.js";
101
101
  import "./catalog-DLQFKucJ.js";
102
- import "./plugin-registry-D1vzxXON.js";
103
- import { n as resolveCliChannelOptions } from "./channel-options-CcNcqLfp.js";
104
- import { t as getSubCliCommandsWithSubcommands } from "./register.subclis-DAEtHKAL.js";
105
- import { a as registerProgramCommands, r as getCoreCliCommandsWithSubcommands } from "./command-registry-jAjzb3Ub.js";
102
+ import "./plugin-registry-BDfC2z-e.js";
103
+ import { n as resolveCliChannelOptions } from "./channel-options-BJphNYiq.js";
104
+ import { t as getSubCliCommandsWithSubcommands } from "./register.subclis-Dv1WM9Kj.js";
105
+ import { a as registerProgramCommands, r as getCoreCliCommandsWithSubcommands } from "./command-registry-X_FmrHib.js";
106
106
  import { r as setProgramContext } from "./program-context-CqzR_m-7.js";
107
107
  import { t as forceFreePort } from "./ports-Dn122MUd.js";
108
- import { n as formatCliBannerLine, r as hasEmittedCliBanner, t as emitCliBanner } from "./banner-DBCyc2l3.js";
108
+ import { n as formatCliBannerLine, r as hasEmittedCliBanner, t as emitCliBanner } from "./banner-DihS8WHF.js";
109
109
  import { Command } from "commander";
110
110
 
111
111
  //#region src/cli/program/context.ts
@@ -213,7 +213,7 @@ function registerPreActionHooks(program, programVersion) {
213
213
  commandPath
214
214
  });
215
215
  if (PLUGIN_REQUIRED_COMMANDS.has(commandPath[0])) {
216
- const { ensurePluginRegistryLoaded } = await import("./plugin-registry-D1vzxXON.js").then((n) => n.n);
216
+ const { ensurePluginRegistryLoaded } = await import("./plugin-registry-BDfC2z-e.js").then((n) => n.n);
217
217
  ensurePluginRegistryLoaded();
218
218
  }
219
219
  });