@symerian/symi 2.3.4 → 2.4.1

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 (170) hide show
  1. package/dist/{accounts-tNElYrCH.js → accounts-CI6zQTJj.js} +14 -14
  2. package/dist/{accounts-qtxJ-6em.js → accounts-CJR8j_Kq.js} +1 -1
  3. package/dist/{accounts-CWktKM8a.js → accounts-ChTFYj8Q.js} +1 -1
  4. package/dist/{active-listener-C9r8ZB9m.js → active-listener-D6sXIjAg.js} +1 -1
  5. package/dist/{agent-scope-BxoUQqgM.js → agent-scope-Bw1Ed8W9.js} +3 -3
  6. package/dist/{agents-E_Ere0qU.js → agents-BrpbYYTb.js} +4 -4
  7. package/dist/{agents.config-Cv_wsBXL.js → agents.config-Bf8u_0ts.js} +1 -1
  8. package/dist/{agents.config-DJTb7Jka.js → agents.config-j4SWyB6K.js} +1 -1
  9. package/dist/{audio-preflight-O3ASWbaG.js → audio-preflight-BkIfnmpi.js} +29 -29
  10. package/dist/{auth-choice-B3D_jLQw.js → auth-choice-BYB9fJiu.js} +1 -1
  11. package/dist/{auth-choice-D8ynWABO.js → auth-choice-DlrjQI-v.js} +1 -1
  12. package/dist/{banner-ChYzCy5p.js → banner-DRJJmkv1.js} +1 -1
  13. package/dist/{bindings-B7Ke6LJi.js → bindings-BU2hsBd9.js} +2 -2
  14. package/dist/build-info.json +3 -3
  15. package/dist/bundled/boot-md/handler.js +53 -53
  16. package/dist/bundled/bootstrap-extra-files/handler.js +5 -5
  17. package/dist/bundled/command-logger/handler.js +1 -1
  18. package/dist/bundled/session-memory/handler.js +53 -53
  19. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  20. package/dist/{channel-activity-CsM_hJ_s.js → channel-activity-C9-gaquj.js} +1 -1
  21. package/dist/{channel-options-BYUiEgev.js → channel-options-BQz0F4El.js} +1 -1
  22. package/dist/{channel-options-CMNzHg4p.js → channel-options-CxSIp3x-.js} +1 -1
  23. package/dist/{channel-web-C-HLPbLL.js → channel-web-BY4lhNxW.js} +1 -1
  24. package/dist/{channels-cli-CyhXPEWq.js → channels-cli--rkhLJvR.js} +4 -4
  25. package/dist/{channels-cli-CcCmH-Tp.js → channels-cli-B5Nj_nHr.js} +4 -4
  26. package/dist/{chrome-BFekevcE.js → chrome-CxSAp8x3.js} +20 -20
  27. package/dist/{chunk-BW5f05BR.js → chunk-ClbN9Pqy.js} +1 -1
  28. package/dist/{cli-Cp-NQ7yu.js → cli-CATf6JAq.js} +1 -1
  29. package/dist/{cli-Gcuf3NTF.js → cli-Ds6poYQ6.js} +1 -1
  30. package/dist/{command-format-BaxDnULz.js → command-format-UKHV-j0K.js} +1 -1
  31. package/dist/{command-registry-Cvr_dlLY.js → command-registry-DXt0PsFy.js} +9 -9
  32. package/dist/{commands-registry-D7CTCQPm.js → commands-registry-VSmULp-g.js} +4 -4
  33. package/dist/{completion-cli-DaOHSXM3.js → completion-cli-BsSDzZNA.js} +1 -1
  34. package/dist/{completion-cli-DDlYn0ya.js → completion-cli-CPMOXTf2.js} +2 -2
  35. package/dist/{config-cli-CmUPAVUz.js → config-cli-B_KCvdli.js} +1 -1
  36. package/dist/{config-cli-BcuAsDOu.js → config-cli-C_GarUko.js} +1 -1
  37. package/dist/{config-DRbjHIwD.js → config-eEaJddXj.js} +12 -12
  38. package/dist/{configure-Ctwt1377.js → configure-CM-z8YCS.js} +3 -3
  39. package/dist/{configure-OxYdT2hU.js → configure-vfmJApU8.js} +3 -3
  40. package/dist/{deliver-CvCK5Mm9.js → deliver-BA7ZN3iM.js} +20 -20
  41. package/dist/{diagnostic-CI0kRQkt.js → diagnostic-C3nsWaw3.js} +1 -1
  42. package/dist/{doctor-completion-D7ShsgUp.js → doctor-completion-8qbLmeX0.js} +1 -1
  43. package/dist/{doctor-completion-Dw78bQaQ.js → doctor-completion-Dnxn_-ov.js} +1 -1
  44. package/dist/entry.js +1 -1
  45. package/dist/extensionAPI.js +1 -1
  46. package/dist/{frontmatter-C_bv_0P8.js → frontmatter-DPlG6yha.js} +2 -2
  47. package/dist/{gateway-cli-D7nxPtEc.js → gateway-cli-DKDpOBp-.js} +9 -9
  48. package/dist/{gateway-cli-Bd7u0krH.js → gateway-cli-XIsXoJZ3.js} +9 -9
  49. package/dist/{gemini-auth-CdSPHuLl.js → gemini-auth-CF48hUR9.js} +1 -1
  50. package/dist/{github-copilot-token-C_qUP7p5.js → github-copilot-token-DJqsJ2-r.js} +7 -7
  51. package/dist/{glass-ui-ws-CzH0ikhI.js → glass-ui-ws-Be_AOhp7.js} +7 -7
  52. package/dist/{glass-ui-ws-DBivjzVA.js → glass-ui-ws-Z_wtGa_A.js} +7 -7
  53. package/dist/{health-rR61mwm3.js → health-BBGgp_dC.js} +1 -1
  54. package/dist/{health-BSOMI4B6.js → health-BmaWws9G.js} +1 -1
  55. package/dist/{hooks-cli-dS4fMEKE.js → hooks-cli-C5eV9sxP.js} +2 -2
  56. package/dist/{hooks-cli-BbiA-gGi.js → hooks-cli-W_aoP9nb.js} +2 -2
  57. package/dist/{image-B0wGflxA.js → image-BGmVDkkw.js} +4 -4
  58. package/dist/{image-ops-CvJzsyvE.js → image-ops-S8-8dAhx.js} +1 -1
  59. package/dist/index.js +6 -6
  60. package/dist/{ir-DccrnjsE.js → ir-CbFUkv_T.js} +4 -4
  61. package/dist/llm-slug-generator.js +53 -53
  62. package/dist/{local-roots-DMwIh5cS.js → local-roots-C7OCYACU.js} +5 -5
  63. package/dist/{login-CwCoxapk.js → login-B8uiUAnV.js} +7 -7
  64. package/dist/{login-qr-Batf3PT5.js → login-qr-CIZk8uKX.js} +12 -12
  65. package/dist/{manager-D_LwXbc6.js → manager-BoLr3xR_.js} +13 -13
  66. package/dist/{manifest-registry-D0IQ3WuX.js → manifest-registry-CneMHk0N.js} +19 -19
  67. package/dist/{markdown-tables-iMQQZu4Q.js → markdown-tables-DSHvnTLx.js} +1 -1
  68. package/dist/{message-channel-Dz5lr5b0.js → message-channel-DbsRltF2.js} +1 -1
  69. package/dist/{model-auth-DK43VicI.js → model-auth-CwOuTuXl.js} +9 -9
  70. package/dist/{models-DqE1s0YL.js → models-COaQWNz5.js} +2 -2
  71. package/dist/{models-cli-6v9jkDxp.js → models-cli-DH17yK8M.js} +3 -3
  72. package/dist/{models-cli-BWC7jYp4.js → models-cli-DeG1qheS.js} +2 -2
  73. package/dist/{onboard-Bxoibs4p.js → onboard-CXOUIg28.js} +2 -2
  74. package/dist/{onboard-BUEYf2m9.js → onboard-DBeHwdks.js} +2 -2
  75. package/dist/{onboard-channels-C3UYzZNC.js → onboard-channels-BCUkNB26.js} +1 -1
  76. package/dist/{onboard-channels-af6Cu6fT.js → onboard-channels-D93AAHMd.js} +1 -1
  77. package/dist/{onboarding-DW-7o6Ln.js → onboarding-C58wjONa.js} +3 -3
  78. package/dist/{onboarding-CDdMZbov.js → onboarding-Dfjn2-9q.js} +3 -3
  79. package/dist/{onboarding.finalize-29jsMLO2.js → onboarding.finalize-7r1HYXWd.js} +6 -6
  80. package/dist/{onboarding.finalize-BI70KOeI.js → onboarding.finalize-DGD56sXW.js} +5 -5
  81. package/dist/{outbound-attachment-DjNDa3zn.js → outbound-attachment-Co2diKdP.js} +2 -2
  82. package/dist/{outbound-D4fN_ZlE.js → outbound-opDNxv-l.js} +7 -7
  83. package/dist/{paths-DLyHUt31.js → paths-Cb87-LzP.js} +1 -1
  84. package/dist/{paths-Cce4PUkG.js → paths-CySxpNhH.js} +5 -5
  85. package/dist/{pi-auth-json-0SYBFZTt.js → pi-auth-json-DPWPoruO.js} +8 -8
  86. package/dist/{pi-embedded-PkSwAmVq.js → pi-embedded-B6uRrG1f.js} +355 -328
  87. package/dist/{pi-embedded-JXvD5-F-.js → pi-embedded-CAJ6egA1.js} +195 -168
  88. package/dist/{pi-embedded-helpers-DLFjnVBb.js → pi-embedded-helpers-DEEaCvEp.js} +52 -52
  89. package/dist/{plugin-registry-Reem6P3K.js → plugin-registry-C0iHnZ7j.js} +1 -1
  90. package/dist/{plugin-registry-B7AdPXfF.js → plugin-registry-D_BAH1V5.js} +1 -1
  91. package/dist/plugin-sdk/agents/model-aware-stream.d.ts +41 -0
  92. package/dist/plugin-sdk/agents/pi-embedded-runner/extra-params.d.ts +19 -0
  93. package/dist/plugin-sdk/agents/stream-monitor.d.ts +62 -0
  94. package/dist/plugin-sdk/{channel-web-CM7A3Y7G.js → channel-web-ilY3YUmF.js} +1 -1
  95. package/dist/plugin-sdk/index.js +2 -2
  96. package/dist/plugin-sdk/{reply-CDloTGFF.js → reply-CSgeVqcV.js} +195 -168
  97. package/dist/plugin-sdk/{web-CWNoMlnF.js → web-BVg5EjiY.js} +2 -2
  98. package/dist/{plugins-DQYI3Fr-.js → plugins-C4C9637U.js} +9 -9
  99. package/dist/{plugins-cli-V8mTTTnD.js → plugins-cli-BhOXY_Ay.js} +2 -2
  100. package/dist/{plugins-cli-B-6wVg3A.js → plugins-cli-LqQNHF1I.js} +2 -2
  101. package/dist/{program-DBtlRiFS.js → program-CutjuJj0.js} +7 -7
  102. package/dist/{program-context-BHPNVgg2.js → program-context-qVc_lsLV.js} +17 -17
  103. package/dist/{prompt-select-styled-Bh-zAqW1.js → prompt-select-styled-BCHe7Fks.js} +4 -4
  104. package/dist/{prompt-select-styled-Cup1c9RJ.js → prompt-select-styled-C0yn8YjW.js} +4 -4
  105. package/dist/{provider-auth-helpers-CiuLdUK3.js → provider-auth-helpers-BzczCfh8.js} +1 -1
  106. package/dist/{provider-auth-helpers-BNmU48Ez.js → provider-auth-helpers-Ds_HwlgY.js} +1 -1
  107. package/dist/{push-apns-9zUNNHgy.js → push-apns-CT8-VcK5.js} +1 -1
  108. package/dist/{push-apns-8VJkVSdh.js → push-apns-DvcqkHld.js} +1 -1
  109. package/dist/{pw-ai-BnAKvSuw.js → pw-ai-DhwRiS06.js} +11 -11
  110. package/dist/{qmd-manager-QHUP-_em.js → qmd-manager-DdZh9PHs.js} +7 -7
  111. package/dist/{register.agent-BtNmleKV.js → register.agent-DMvHFw16.js} +6 -6
  112. package/dist/{register.agent-DnglG42G.js → register.agent-yoXoJ_5O.js} +5 -5
  113. package/dist/{register.configure-CLW9tdE4.js → register.configure-B8UDTEcS.js} +6 -6
  114. package/dist/{register.configure-DfQOfV1W.js → register.configure-BqrNBkwZ.js} +6 -6
  115. package/dist/{register.maintenance-jFYcRLEN.js → register.maintenance-D1MuIUlv.js} +7 -7
  116. package/dist/{register.maintenance-BQfMsgo7.js → register.maintenance-DMLPFSKI.js} +8 -8
  117. package/dist/{register.message-DUsBvFSF.js → register.message-BnLBwUw9.js} +2 -2
  118. package/dist/{register.message-BhoZYcqM.js → register.message-CgtrjEFw.js} +2 -2
  119. package/dist/{register.onboard-BBwhoeoE.js → register.onboard-CXHhSH4B.js} +4 -4
  120. package/dist/{register.onboard-DQOkpYBY.js → register.onboard-D1X2dUGZ.js} +4 -4
  121. package/dist/{register.setup-Ca6khTSz.js → register.setup-DFDb5BDi.js} +4 -4
  122. package/dist/{register.setup-6jlL3L1h.js → register.setup-Q58lN0TV.js} +4 -4
  123. package/dist/{register.status-health-sessions-DQDXZYI3.js → register.status-health-sessions-CP7JWQHw.js} +3 -3
  124. package/dist/{register.status-health-sessions-DsYNMl06.js → register.status-health-sessions-DhTfQ530.js} +3 -3
  125. package/dist/{register.subclis-DJf3ihsW.js → register.subclis-CrTXa8cj.js} +9 -9
  126. package/dist/{registry-CK4e9hn8.js → registry-DP24za6g.js} +17 -17
  127. package/dist/{replies-BIX_isV7.js → replies-DpPvWiGF.js} +3 -3
  128. package/dist/{reply-DSjeqLEz.js → reply-DkwaBRX-.js} +195 -168
  129. package/dist/{reply-prefix-XlyuyChD.js → reply-prefix-CtL0omgM.js} +1 -1
  130. package/dist/{resolve-route-CZ-1eqw0.js → resolve-route-BVikmvWO.js} +4 -4
  131. package/dist/{retry-Cly39XZB.js → retry-dGG-MbxL.js} +1 -1
  132. package/dist/{run-main-B2coomPj.js → run-main-BLKPL_vM.js} +14 -14
  133. package/dist/{runner-odEv83vv.js → runner-B_KP4voe.js} +9 -9
  134. package/dist/{send-DeFniOjh.js → send-CHEOWVc8.js} +6 -6
  135. package/dist/{send-WyRqb4WD.js → send-DbcLJb0P.js} +7 -7
  136. package/dist/{send-B1u-LrcS.js → send-DeEosX8F.js} +18 -18
  137. package/dist/{send-CiTGOvEc.js → send-DwKJK3sM.js} +10 -10
  138. package/dist/{send-DW96zgDL.js → send-zSarozV2.js} +6 -6
  139. package/dist/{server-methods-QNBQbsvr.js → server-methods-CbeCo-6O.js} +7 -7
  140. package/dist/{server-methods-DHo5e8Gj.js → server-methods-EQ0JkHOg.js} +7 -7
  141. package/dist/{server-node-events-D_S0NRCQ.js → server-node-events-C1FDqJb9.js} +2 -2
  142. package/dist/{server-node-events-CJOo8WcL.js → server-node-events-CBHpc_25.js} +2 -2
  143. package/dist/{session-SM36BTsl.js → session-DV1MNlbV.js} +8 -8
  144. package/dist/{skill-commands-BJMb_psG.js → skill-commands-D610IKhm.js} +9 -9
  145. package/dist/{skills-BFekKL7i.js → skills-o5WVqM4V.js} +21 -21
  146. package/dist/{sqlite-DRbx2dhW.js → sqlite-6H6Zw1cs.js} +4 -4
  147. package/dist/{status-B8yaGk2o.js → status-B1r3Wp0-.js} +2 -2
  148. package/dist/{status-D_J6qcC1.js → status-Cksz7z4T.js} +1 -1
  149. package/dist/{status-4DaGE8j5.js → status-CnogoaI_.js} +2 -2
  150. package/dist/{status-kfEtYX22.js → status-jVJSC_Ga.js} +1 -1
  151. package/dist/{store-C0wvOkae.js → store-vVE6N2mH.js} +2 -2
  152. package/dist/{subagent-registry-CyW0EDWw.js → subagent-registry-Jwg44JMf.js} +195 -168
  153. package/dist/{subsystem-Bs9YvKLa.js → subsystem-DgpxyDQ_.js} +1 -1
  154. package/dist/{tables-DuZspiBu.js → tables-BIWsCKXJ.js} +1 -1
  155. package/dist/{target-errors-Be1SwYlW.js → target-errors-DyItGyW9.js} +2 -2
  156. package/dist/{thinking-CdlENGRW.js → thinking-Ni0HF-w6.js} +5 -5
  157. package/dist/{tokens-H1H1LiSQ.js → tokens-c_SLAkVb.js} +1 -1
  158. package/dist/{tool-images-DXB7tqWi.js → tool-images-DBCfXdli.js} +2 -2
  159. package/dist/{tool-loop-detection-Cs8_HCsx.js → tool-loop-detection-Bbc9OPFR.js} +3 -3
  160. package/dist/{update-cli-C-ZGqknl.js → update-cli-BkU6ori8.js} +8 -8
  161. package/dist/{update-cli-DJupxo-f.js → update-cli-D18nWvzY.js} +7 -7
  162. package/dist/{update-runner-AiIhp7fw.js → update-runner-BQg__DB5.js} +1 -1
  163. package/dist/{update-runner-BF5UULe-.js → update-runner-le1Hcqx4.js} +1 -1
  164. package/dist/{web-HeObJp6A.js → web-BSs2eYJa.js} +2 -2
  165. package/dist/{web-6vYYN17n.js → web-BsjZ2RTT.js} +57 -57
  166. package/dist/{web-6026eRzJ.js → web-DajtZMaX.js} +1 -1
  167. package/dist/{web-CryqKXT4.js → web-KYh3LgI0.js} +1 -1
  168. package/dist/{whatsapp-actions-D1RsnX7P.js → whatsapp-actions-oRQjcdQe.js} +23 -23
  169. package/dist/{workspace-wAaHI8-5.js → workspace-CbvamIU6.js} +6 -6
  170. package/package.json +1 -1
@@ -51787,7 +51787,7 @@ function isVoiceChannelType(type) {
51787
51787
  function createDefaultDeps() {
51788
51788
  return {
51789
51789
  sendMessageWhatsApp: async (...args) => {
51790
- const { sendMessageWhatsApp } = await import("./web-CryqKXT4.js");
51790
+ const { sendMessageWhatsApp } = await import("./web-KYh3LgI0.js");
51791
51791
  return await sendMessageWhatsApp(...args);
51792
51792
  },
51793
51793
  sendMessageTelegram: async (...args) => {
@@ -67069,7 +67069,7 @@ function loadWebLoginQr() {
67069
67069
  return webLoginQrPromise;
67070
67070
  }
67071
67071
  function loadWebChannel() {
67072
- webChannelPromise ??= import("./web-CryqKXT4.js");
67072
+ webChannelPromise ??= import("./web-KYh3LgI0.js");
67073
67073
  return webChannelPromise;
67074
67074
  }
67075
67075
  function loadWhatsAppActions() {
@@ -72836,10 +72836,6 @@ function resolveModelProfile(modelId, userProfiles) {
72836
72836
 
72837
72837
  //#endregion
72838
72838
  //#region src/agents/pi-embedded-runner/extra-params.ts
72839
- const OPENROUTER_APP_HEADERS = {
72840
- "HTTP-Referer": "https://symi.ai",
72841
- "X-Title": "Symi"
72842
- };
72843
72839
  const ANTHROPIC_CONTEXT_1M_BETA = "context-1m-2025-08-07";
72844
72840
  const ANTHROPIC_1M_MODEL_PREFIXES = ["claude-opus-4", "claude-sonnet-4"];
72845
72841
  const OPENAI_RESPONSES_APIS = new Set(["openai-responses"]);
@@ -72857,70 +72853,6 @@ function resolveExtraParams(params) {
72857
72853
  const profile = resolveModelProfile(modelKey, params.cfg?.models?.profiles);
72858
72854
  if (profile.params && Object.keys(profile.params).length > 0) return { ...profile.params };
72859
72855
  }
72860
- /**
72861
- * Resolve cacheRetention from extraParams, supporting both new `cacheRetention`
72862
- * and legacy `cacheControlTtl` values for backwards compatibility.
72863
- *
72864
- * Mapping: "5m" → "short", "1h" → "long"
72865
- *
72866
- * Only applies to Anthropic provider (OpenRouter uses openai-completions API
72867
- * with hardcoded cache_control, not the cacheRetention stream option).
72868
- *
72869
- * Defaults to "short" for Anthropic provider when not explicitly configured.
72870
- */
72871
- function resolveCacheRetention(extraParams, provider) {
72872
- if (provider !== "anthropic") return;
72873
- const newVal = extraParams?.cacheRetention;
72874
- if (newVal === "none" || newVal === "short" || newVal === "long") return newVal;
72875
- const legacy = extraParams?.cacheControlTtl;
72876
- if (legacy === "5m") return "short";
72877
- if (legacy === "1h") return "long";
72878
- return "short";
72879
- }
72880
- function createStreamFnWithExtraParams(baseStreamFn, extraParams, provider) {
72881
- if (!extraParams || Object.keys(extraParams).length === 0) return;
72882
- const streamParams = {};
72883
- if (typeof extraParams.temperature === "number") streamParams.temperature = extraParams.temperature;
72884
- if (typeof extraParams.maxTokens === "number") streamParams.maxTokens = extraParams.maxTokens;
72885
- if (typeof extraParams.top_p === "number") streamParams.top_p = extraParams.top_p;
72886
- if (typeof extraParams.top_k === "number") streamParams.top_k = extraParams.top_k;
72887
- if (typeof extraParams.repeat_penalty === "number") streamParams.repeat_penalty = extraParams.repeat_penalty;
72888
- if (Array.isArray(extraParams.stop) && extraParams.stop.length > 0) streamParams.stop = extraParams.stop;
72889
- if (extraParams.chat_template_kwargs && typeof extraParams.chat_template_kwargs === "object") streamParams.chat_template_kwargs = extraParams.chat_template_kwargs;
72890
- const cacheRetention = resolveCacheRetention(extraParams, provider);
72891
- if (cacheRetention) streamParams.cacheRetention = cacheRetention;
72892
- if (Object.keys(streamParams).length === 0) return;
72893
- log$2.debug(`creating streamFn wrapper with params: ${JSON.stringify(streamParams)}`);
72894
- const sp = streamParams;
72895
- const payloadOverrides = {};
72896
- if (Array.isArray(sp.stop) && sp.stop.length > 0) payloadOverrides.stop = sp.stop;
72897
- if (typeof sp.top_p === "number") payloadOverrides.top_p = sp.top_p;
72898
- if (typeof sp.top_k === "number") payloadOverrides.top_k = sp.top_k;
72899
- if (typeof sp.repeat_penalty === "number") payloadOverrides.repeat_penalty = sp.repeat_penalty;
72900
- const hasPayloadOverrides = Object.keys(payloadOverrides).length > 0;
72901
- const underlying = baseStreamFn ?? streamSimple;
72902
- const wrappedStreamFn = (model, context, options) => {
72903
- if (hasPayloadOverrides) {
72904
- const originalOnPayload = options?.onPayload;
72905
- return underlying(model, context, {
72906
- ...streamParams,
72907
- ...options,
72908
- onPayload: (payload) => {
72909
- if (payload && typeof payload === "object") {
72910
- const p = payload;
72911
- for (const [key, value] of Object.entries(payloadOverrides)) if (p[key] === void 0) p[key] = value;
72912
- }
72913
- originalOnPayload?.(payload);
72914
- }
72915
- });
72916
- }
72917
- return underlying(model, context, {
72918
- ...streamParams,
72919
- ...options
72920
- });
72921
- };
72922
- return wrappedStreamFn;
72923
- }
72924
72856
  function isDirectOpenAIBaseUrl(baseUrl) {
72925
72857
  if (typeof baseUrl !== "string" || !baseUrl.trim()) return true;
72926
72858
  try {
@@ -73001,20 +72933,6 @@ function createAnthropicBetaHeadersWrapper(baseStreamFn, betas) {
73001
72933
  };
73002
72934
  }
73003
72935
  /**
73004
- * Create a streamFn wrapper that adds OpenRouter app attribution headers.
73005
- * These headers allow Symi to appear on OpenRouter's leaderboard.
73006
- */
73007
- function createOpenRouterHeadersWrapper(baseStreamFn) {
73008
- const underlying = baseStreamFn ?? streamSimple;
73009
- return (model, context, options) => underlying(model, context, {
73010
- ...options,
73011
- headers: {
73012
- ...OPENROUTER_APP_HEADERS,
73013
- ...options?.headers
73014
- }
73015
- });
73016
- }
73017
- /**
73018
72936
  * Create a streamFn wrapper that injects tool_stream=true for Z.AI providers.
73019
72937
  *
73020
72938
  * Z.AI's API supports the `tool_stream` parameter to enable real-time streaming
@@ -73037,82 +72955,6 @@ function createZaiToolStreamWrapper(baseStreamFn, enabled) {
73037
72955
  });
73038
72956
  };
73039
72957
  }
73040
- const GEMMA_STOP_SEQUENCES = ["<end_of_turn>", "<eos>"];
73041
- const VLLM_GEMMA_HINTS = ["gemma", "redsand"];
73042
- function isVllmOrGemmaProvider(provider, modelId, cfg) {
73043
- const lower = `${provider}/${modelId}`.toLowerCase();
73044
- if (VLLM_GEMMA_HINTS.some((h) => lower.includes(h))) return true;
73045
- const baseUrl = ((cfg?.models?.providers?.[provider])?.baseUrl ?? "").toLowerCase();
73046
- return baseUrl.includes("coreweave") || baseUrl.includes("vllm");
73047
- }
73048
- /**
73049
- * Wrap the stream function to fix vLLM/Gemma compat issues via onPayload:
73050
- * 1. Replace `max_completion_tokens` with `max_tokens` (vLLM ignores the former)
73051
- * 2. Inject Gemma stop sequences if none are set
73052
- * 3. Remove unsupported fields (store, stream_options.include_usage on older vLLM)
73053
- */
73054
- function createVllmCompatWrapper(baseStreamFn, extraParams) {
73055
- const underlying = baseStreamFn ?? streamSimple;
73056
- const configuredStop = Array.isArray(extraParams.stop) ? extraParams.stop : GEMMA_STOP_SEQUENCES;
73057
- return (model, context, options) => {
73058
- const originalOnPayload = options?.onPayload;
73059
- return underlying(model, context, {
73060
- ...options,
73061
- onPayload: (payload) => {
73062
- if (payload && typeof payload === "object") {
73063
- const p = payload;
73064
- if (p.max_completion_tokens && !p.max_tokens) {
73065
- p.max_tokens = p.max_completion_tokens;
73066
- delete p.max_completion_tokens;
73067
- }
73068
- if (!p.stop && configuredStop.length > 0) p.stop = configuredStop;
73069
- delete p.store;
73070
- }
73071
- originalOnPayload?.(payload);
73072
- }
73073
- });
73074
- };
73075
- }
73076
- /**
73077
- * Apply extra params (like temperature) to an agent's streamFn.
73078
- * Also adds OpenRouter app attribution headers when using the OpenRouter provider.
73079
- *
73080
- * @internal Exported for testing
73081
- */
73082
- function applyExtraParamsToAgent(agent, cfg, provider, modelId, extraParamsOverride) {
73083
- const extraParams = resolveExtraParams({
73084
- cfg,
73085
- provider,
73086
- modelId
73087
- });
73088
- const override = extraParamsOverride && Object.keys(extraParamsOverride).length > 0 ? Object.fromEntries(Object.entries(extraParamsOverride).filter(([, value]) => value !== void 0)) : void 0;
73089
- const merged = Object.assign({}, extraParams, override);
73090
- const wrappedStreamFn = createStreamFnWithExtraParams(agent.streamFn, merged, provider);
73091
- if (wrappedStreamFn) {
73092
- log$2.debug(`applying extraParams to agent streamFn for ${provider}/${modelId}`);
73093
- agent.streamFn = wrappedStreamFn;
73094
- }
73095
- const anthropicBetas = resolveAnthropicBetas(merged, provider, modelId);
73096
- if (anthropicBetas?.length) {
73097
- log$2.debug(`applying Anthropic beta header for ${provider}/${modelId}: ${anthropicBetas.join(",")}`);
73098
- agent.streamFn = createAnthropicBetaHeadersWrapper(agent.streamFn, anthropicBetas);
73099
- }
73100
- if (provider === "openrouter") {
73101
- log$2.debug(`applying OpenRouter app attribution headers for ${provider}/${modelId}`);
73102
- agent.streamFn = createOpenRouterHeadersWrapper(agent.streamFn);
73103
- }
73104
- if (provider === "zai" || provider === "z-ai") {
73105
- if (merged?.tool_stream !== false) {
73106
- log$2.debug(`enabling Z.AI tool_stream for ${provider}/${modelId}`);
73107
- agent.streamFn = createZaiToolStreamWrapper(agent.streamFn, true);
73108
- }
73109
- }
73110
- if (isVllmOrGemmaProvider(provider, modelId, cfg)) {
73111
- log$2.debug(`applying vLLM/Gemma compat wrapper for ${provider}/${modelId}`);
73112
- agent.streamFn = createVllmCompatWrapper(agent.streamFn, merged);
73113
- }
73114
- agent.streamFn = createOpenAIResponsesStoreWrapper(agent.streamFn);
73115
- }
73116
72958
 
73117
72959
  //#endregion
73118
72960
  //#region src/utils/safe-json.ts
@@ -73389,6 +73231,74 @@ function createCacheTrace(params) {
73389
73231
  };
73390
73232
  }
73391
73233
 
73234
+ //#endregion
73235
+ //#region src/agents/model-aware-stream.ts
73236
+ /**
73237
+ * Create a single stream function wrapper that handles all provider-specific
73238
+ * param injection via one onPayload hook.
73239
+ *
73240
+ * Replaces: createStreamFnWithExtraParams, createVllmCompatWrapper,
73241
+ * createOpenRouterHeadersWrapper.
73242
+ */
73243
+ function createModelAwareStreamFn(opts) {
73244
+ const underlying = opts.baseStreamFn ?? streamSimple;
73245
+ const mergedParams = {
73246
+ ...opts.profile.params,
73247
+ ...opts.configExtraParams,
73248
+ ...opts.streamParamsOverride
73249
+ };
73250
+ const nativeOpts = {};
73251
+ if (typeof mergedParams.temperature === "number") nativeOpts.temperature = mergedParams.temperature;
73252
+ if (typeof mergedParams.max_tokens === "number") nativeOpts.maxTokens = mergedParams.max_tokens;
73253
+ else if (typeof mergedParams.maxTokens === "number") nativeOpts.maxTokens = mergedParams.maxTokens;
73254
+ const injections = {};
73255
+ if (Array.isArray(mergedParams.stop) && mergedParams.stop.length > 0) injections.stop = mergedParams.stop;
73256
+ if (typeof mergedParams.top_p === "number") injections.top_p = mergedParams.top_p;
73257
+ if (typeof mergedParams.top_k === "number") injections.top_k = mergedParams.top_k;
73258
+ if (typeof mergedParams.repeat_penalty === "number") injections.repeat_penalty = mergedParams.repeat_penalty;
73259
+ const isVllm = isVllmProvider(opts.provider, opts.modelId, opts.config);
73260
+ const isOpenRouter = opts.provider === "openrouter";
73261
+ const extraHeaders = {};
73262
+ if (isOpenRouter) {
73263
+ extraHeaders["HTTP-Referer"] = "https://symi.ai";
73264
+ extraHeaders["X-Title"] = "Symi";
73265
+ }
73266
+ const hasExtraHeaders = Object.keys(extraHeaders).length > 0;
73267
+ const onPayloadHook = (payload, callerOnPayload) => {
73268
+ if (payload && typeof payload === "object") {
73269
+ const p = payload;
73270
+ for (const [key, val] of Object.entries(injections)) if (p[key] === void 0) p[key] = val;
73271
+ if (isVllm) {
73272
+ if (p.max_completion_tokens && !p.max_tokens) {
73273
+ p.max_tokens = p.max_completion_tokens;
73274
+ delete p.max_completion_tokens;
73275
+ }
73276
+ delete p.store;
73277
+ }
73278
+ }
73279
+ callerOnPayload?.(payload);
73280
+ };
73281
+ return (model, context, options) => {
73282
+ const callerOnPayload = options?.onPayload;
73283
+ return underlying(model, context, {
73284
+ ...nativeOpts,
73285
+ ...options,
73286
+ onPayload: (payload) => onPayloadHook(payload, callerOnPayload),
73287
+ ...hasExtraHeaders ? { headers: {
73288
+ ...extraHeaders,
73289
+ ...options?.headers
73290
+ } } : {}
73291
+ });
73292
+ };
73293
+ }
73294
+ /** Detect vLLM/Gemma providers by model hints or baseUrl patterns. */
73295
+ function isVllmProvider(provider, modelId, config) {
73296
+ const lower = `${provider}/${modelId}`.toLowerCase();
73297
+ if (["gemma", "redsand"].some((h) => lower.includes(h))) return true;
73298
+ const baseUrl = ((config?.models?.providers?.[provider])?.baseUrl ?? "").toLowerCase();
73299
+ return baseUrl.includes("coreweave") || baseUrl.includes("vllm");
73300
+ }
73301
+
73392
73302
  //#endregion
73393
73303
  //#region src/auto-reply/reply/streaming-directives.ts
73394
73304
  const splitTrailingDirective = (text) => {
@@ -75372,6 +75282,89 @@ Use the message tool with buttons:
75372
75282
  [{"label": "✅ Proceed", "data": "/plan-proceed"}, {"label": "✏️ Modify", "data": "/plan-modify"}, {"label": "❌ Cancel", "data": "/plan-cancel"}]
75373
75283
  </plan_mode>`;
75374
75284
 
75285
+ //#endregion
75286
+ //#region src/agents/stream-monitor.ts
75287
+ /**
75288
+ * Create a stream monitor configured for the given model profile.
75289
+ *
75290
+ * - Claude (hasStructuredThinking: true): repetition detection only
75291
+ * - Gemma/vLLM (hasStructuredThinking: false): tool JSON + repetition detection
75292
+ */
75293
+ function createStreamMonitor(profile, overrides) {
75294
+ const detectToolJson = overrides?.detectToolJson ?? !profile.filters.hasStructuredThinking;
75295
+ const detectRepetition = overrides?.detectRepetition ?? true;
75296
+ const minBlockSize = overrides?.repetitionMinBlockSize ?? 150;
75297
+ let accumulated = "";
75298
+ let stopSignaled = false;
75299
+ let stopReason;
75300
+ return {
75301
+ onChunk(delta) {
75302
+ if (stopSignaled) return;
75303
+ accumulated += delta;
75304
+ if (detectToolJson && hasCompleteToolJson(accumulated)) {
75305
+ stopSignaled = true;
75306
+ stopReason = "complete-tool-json";
75307
+ return;
75308
+ }
75309
+ if (detectRepetition && hasRepetition(accumulated, minBlockSize)) {
75310
+ stopSignaled = true;
75311
+ stopReason = "repetition-detected";
75312
+ return;
75313
+ }
75314
+ },
75315
+ shouldStop: () => stopSignaled,
75316
+ getAccumulated: () => accumulated,
75317
+ getStopReason: () => stopReason,
75318
+ reset() {
75319
+ accumulated = "";
75320
+ stopSignaled = false;
75321
+ stopReason = void 0;
75322
+ }
75323
+ };
75324
+ }
75325
+ /**
75326
+ * Detect if the accumulated text contains a syntactically complete JSON
75327
+ * object with tool_name and tool_args. Used for models that output tool
75328
+ * calls as plain text JSON (not native structured tool calls).
75329
+ */
75330
+ function hasCompleteToolJson(text) {
75331
+ const hasToolKey = text.includes("tool_name") || text.includes("\"tool\"");
75332
+ const hasArgsKey = text.includes("tool_args") || text.includes("\"args\"");
75333
+ if (!hasToolKey || !hasArgsKey) return false;
75334
+ const lastBrace = text.lastIndexOf("}");
75335
+ if (lastBrace < 0) return false;
75336
+ let depth = 0;
75337
+ let start = -1;
75338
+ for (let i = lastBrace; i >= 0; i--) {
75339
+ if (text[i] === "}") depth++;
75340
+ if (text[i] === "{") depth--;
75341
+ if (depth === 0) {
75342
+ start = i;
75343
+ break;
75344
+ }
75345
+ }
75346
+ if (start < 0) return false;
75347
+ const candidate = text.slice(start, lastBrace + 1);
75348
+ try {
75349
+ const parsed = JSON.parse(candidate);
75350
+ return typeof parsed === "object" && parsed !== null && (typeof parsed.tool_name === "string" || typeof parsed.tool === "string") && (typeof parsed.tool_args === "object" || typeof parsed.args === "object");
75351
+ } catch {
75352
+ return false;
75353
+ }
75354
+ }
75355
+ /**
75356
+ * Detect if the accumulated text contains a repeated block, indicating
75357
+ * a looping cascade. Returns true if a block of `minBlockSize` chars
75358
+ * from the first half appears again in the second half.
75359
+ */
75360
+ function hasRepetition(text, minBlockSize) {
75361
+ if (text.length < minBlockSize * 2.5) return false;
75362
+ const sampleStart = Math.floor(text.length * .25);
75363
+ const sample = text.slice(sampleStart, sampleStart + minBlockSize);
75364
+ const searchStart = sampleStart + minBlockSize;
75365
+ return text.indexOf(sample, searchStart) >= 0;
75366
+ }
75367
+
75375
75368
  //#endregion
75376
75369
  //#region src/agents/symipulse-timeout.ts
75377
75370
  /**
@@ -76436,14 +76429,39 @@ async function runEmbeddedAttempt(params) {
76436
76429
  modelApi: params.model.api,
76437
76430
  workspaceDir: params.workspaceDir
76438
76431
  });
76439
- if (params.model.api === "ollama") {
76440
- const providerConfig = params.config?.models?.providers?.[params.model.provider];
76441
- const modelBaseUrl = typeof params.model.baseUrl === "string" ? params.model.baseUrl.trim() : "";
76442
- const providerBaseUrl = typeof providerConfig?.baseUrl === "string" ? providerConfig.baseUrl.trim() : "";
76443
- const ollamaBaseUrl = modelBaseUrl || providerBaseUrl || OLLAMA_NATIVE_BASE_URL;
76444
- activeSession.agent.streamFn = createOllamaStreamFn(ollamaBaseUrl);
76445
- } else activeSession.agent.streamFn = streamSimple;
76446
- applyExtraParamsToAgent(activeSession.agent, params.config, params.provider, params.modelId, params.streamParams);
76432
+ {
76433
+ let baseStreamFn = streamSimple;
76434
+ if (params.model.api === "ollama") {
76435
+ const providerConfig = params.config?.models?.providers?.[params.model.provider];
76436
+ const modelBaseUrl = typeof params.model.baseUrl === "string" ? params.model.baseUrl.trim() : "";
76437
+ const providerBaseUrl = typeof providerConfig?.baseUrl === "string" ? providerConfig.baseUrl.trim() : "";
76438
+ baseStreamFn = createOllamaStreamFn(modelBaseUrl || providerBaseUrl || OLLAMA_NATIVE_BASE_URL);
76439
+ }
76440
+ const configExtraParams = resolveExtraParams({
76441
+ cfg: params.config,
76442
+ provider: params.provider,
76443
+ modelId: params.modelId
76444
+ });
76445
+ activeSession.agent.streamFn = createModelAwareStreamFn({
76446
+ baseStreamFn,
76447
+ profile: modelProfile,
76448
+ provider: params.provider,
76449
+ modelId: params.modelId,
76450
+ config: params.config,
76451
+ configExtraParams,
76452
+ streamParamsOverride: params.streamParams
76453
+ });
76454
+ const merged = {
76455
+ ...configExtraParams,
76456
+ ...params.streamParams
76457
+ };
76458
+ const anthropicBetas = resolveAnthropicBetas(merged, params.provider, params.modelId);
76459
+ if (anthropicBetas?.length) activeSession.agent.streamFn = createAnthropicBetaHeadersWrapper(activeSession.agent.streamFn, anthropicBetas);
76460
+ if (params.provider === "zai" || params.provider === "z-ai") {
76461
+ if (merged?.tool_stream !== false) activeSession.agent.streamFn = createZaiToolStreamWrapper(activeSession.agent.streamFn, true);
76462
+ }
76463
+ activeSession.agent.streamFn = createOpenAIResponsesStoreWrapper(activeSession.agent.streamFn);
76464
+ }
76447
76465
  if (cacheTrace) {
76448
76466
  cacheTrace.recordStage("session:loaded", {
76449
76467
  messages: activeSession.messages,
@@ -76561,6 +76579,7 @@ async function runEmbeddedAttempt(params) {
76561
76579
  return fn(...args);
76562
76580
  });
76563
76581
  };
76582
+ const streamMonitor = createStreamMonitor(modelProfile);
76564
76583
  const subscription = subscribeEmbeddedPiSession({
76565
76584
  session: activeSession,
76566
76585
  runId: params.runId,
@@ -76582,6 +76601,14 @@ async function runEmbeddedAttempt(params) {
76582
76601
  onAgentEvent: (evt) => {
76583
76602
  armSymipulseTimer();
76584
76603
  params.onAgentEvent?.(evt);
76604
+ if (evt.stream === "assistant" && typeof evt.data?.text === "string" && !aborted) {
76605
+ streamMonitor.onChunk(evt.data.text);
76606
+ if (streamMonitor.shouldStop()) {
76607
+ const reason = streamMonitor.getStopReason();
76608
+ log$2.warn(`stream monitor triggered abort: runId=${params.runId} reason=${reason}`);
76609
+ abortRun(false, /* @__PURE__ */ new Error(`stream-monitor:${reason}`));
76610
+ }
76611
+ }
76585
76612
  },
76586
76613
  enforceFinalTag: params.enforceFinalTag,
76587
76614
  config: params.config,