@symerian/symi 3.5.4 → 3.5.6

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 (413) hide show
  1. package/dist/{agent-Bl0Wfrd4.js → agent-BCszhl_7.js} +11 -11
  2. package/dist/{agent-BsRlH9Ez.js → agent-Cmx-1Tfs.js} +9 -9
  3. package/dist/{agents-Ch38fapn.js → agents-BkTzJJ83.js} +11 -11
  4. package/dist/{audit-CcxTZUi-.js → audit-Bk6kay2Z.js} +9 -9
  5. package/dist/{audit-CojL8qpM.js → audit-CtrXFZb5.js} +9 -9
  6. package/dist/{auth-choice-CQnJ5pRD.js → auth-choice-CucG4Wor.js} +8 -8
  7. package/dist/{auth-choice-O55PGflm.js → auth-choice-D-iIJjJY.js} +8 -8
  8. package/dist/{auth-choice-options-DfT-D0Cb.js → auth-choice-options-DmXqtnP9.js} +1 -1
  9. package/dist/{auth-choice-options-osb2GMd4.js → auth-choice-options-od_KpHe8.js} +1 -1
  10. package/dist/{auth-choice-prompt-6_u7zS1M.js → auth-choice-prompt-BnvC700A.js} +1 -1
  11. package/dist/{auth-choice-prompt-SCWccuw0.js → auth-choice-prompt-kt2FcieM.js} +1 -1
  12. package/dist/{auth-token-Dvw-1mFR.js → auth-token-DyhvQgv4.js} +1 -1
  13. package/dist/{auth-token-t_CY5BPB.js → auth-token-lPWiklDD.js} +1 -1
  14. package/dist/{banner-TDzek44y.js → banner-CApT91CY.js} +1 -1
  15. package/dist/{bonjour-discovery-BjSUj2V6.js → bonjour-discovery-CyLfNUkJ.js} +1 -1
  16. package/dist/{bonjour-discovery-FJyieAXp.js → bonjour-discovery-DuObXMh2.js} +1 -1
  17. package/dist/breakdown-B_Dhhm3K.js +753 -0
  18. package/dist/breakdown-Cszrv-Lf.js +753 -0
  19. package/dist/{browser-cli-BXH0KbhG.js → browser-cli-DGjYBquX.js} +9 -9
  20. package/dist/{browser-cli-UZqxfaV_.js → browser-cli-rZb2WjFF.js} +9 -9
  21. package/dist/build-info.json +3 -3
  22. package/dist/bundled/boot-md/handler.js +10 -10
  23. package/dist/bundled/session-memory/handler.js +9 -9
  24. package/dist/{call-CKm3T_ar.js → call-DKQC0JT1.js} +1 -1
  25. package/dist/{call-DrkOiHjS.js → call-ogggp9QZ.js} +1 -1
  26. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  27. package/dist/{channel-options-zAbgRuGY.js → channel-options-CdIEyHya.js} +2 -2
  28. package/dist/{channel-options-BEM8ruys.js → channel-options-DYh8mLMN.js} +2 -2
  29. package/dist/{channels-cli-cRWPvOQD.js → channels-cli-Bb18aE2b.js} +54 -53
  30. package/dist/{channels-cli-DdKnAzW9.js → channels-cli-sG9Wf2LH.js} +54 -53
  31. package/dist/{chrome-C_I81hbq.js → chrome-3jl2ulOE.js} +4 -4
  32. package/dist/{chrome-zElD4rpN.js → chrome-D1eO2jfe.js} +1 -1
  33. package/dist/{chrome-rzK8edU7.js → chrome-DJChpTwP.js} +1 -1
  34. package/dist/{chrome-BKUACyeO.js → chrome-OTJg3QKn.js} +4 -4
  35. package/dist/{clack-prompter-CuIw5vQW.js → clack-prompter-_kEnSVz4.js} +4 -4
  36. package/dist/{clack-prompter-Bc38EIYW.js → clack-prompter-v9MYo-5u.js} +4 -4
  37. package/dist/{cli-BJDlZfYi.js → cli-DEGt0Tp0.js} +36 -35
  38. package/dist/{cli--UhNWFtQ.js → cli-DtdTf-ZQ.js} +36 -35
  39. package/dist/{command-registry-COpZWfkh.js → command-registry-O155hUhR.js} +11 -11
  40. package/dist/{commands-registry-DPZevjMh.js → commands-registry-BuOUfpmg.js} +31 -0
  41. package/dist/{commands-registry-VfAQOVZO.js → commands-registry-C2Hvwjym.js} +31 -0
  42. package/dist/{commands-registry-BisT2Fcd.js → commands-registry-CJPBJPlh.js} +31 -0
  43. package/dist/{commands-registry-DFYDtKr_.js → commands-registry-DG2kGyg5.js} +31 -0
  44. package/dist/{completion-cli-EltMSZer.js → completion-cli-BaOjuoPX.js} +3 -3
  45. package/dist/{completion-cli-DVF5x7Kp.js → completion-cli-DLUKoSIx.js} +1 -1
  46. package/dist/{config-D7SS4vdk.js → config-B4jkreCN.js} +13 -2
  47. package/dist/{config-_DaupjQd.js → config-D7TcU4qN.js} +13 -2
  48. package/dist/{config-cli-DaPePEIB.js → config-cli-BuZ-L1Iw.js} +3 -3
  49. package/dist/{config-cli-kN07V9j6.js → config-cli-BxWavRxN.js} +3 -3
  50. package/dist/{config-guard-SNMCV6sc.js → config-guard-CLfXzB_z.js} +2 -2
  51. package/dist/{config-guard-CN1qhDyB.js → config-guard-D58THqAB.js} +8 -8
  52. package/dist/{config-validation-DS5Jr_iO.js → config-validation-DQ-lm2Qx.js} +1 -1
  53. package/dist/{config-validation-DGWvkKov.js → config-validation-DhsYEtLL.js} +1 -1
  54. package/dist/{configure-C9Z4clKW.js → configure-BSKWgEhS.js} +22 -22
  55. package/dist/{configure-id9imsuH.js → configure-gxAEhC9E.js} +22 -22
  56. package/dist/{control-service-CJWzOFkK.js → control-service-DOGU9T2P.js} +4 -4
  57. package/dist/{control-service-DvK2HPC2.js → control-service-DPzhv357.js} +4 -4
  58. package/dist/cost-cli-C9LvOtGz.js +138 -0
  59. package/dist/cost-cli-CmfkZsmZ.js +133 -0
  60. package/dist/{cron-cli-BIIzbF-W.js → cron-cli-DtDqHIZn.js} +7 -7
  61. package/dist/{cron-cli-BNx0V18_.js → cron-cli-L4iwVTNV.js} +7 -7
  62. package/dist/{daemon-cli-CGfWQN7c.js → daemon-cli-39fFIU2G.js} +15 -15
  63. package/dist/{daemon-cli-DCbqVfyu.js → daemon-cli-B5TdtWCQ.js} +15 -15
  64. package/dist/daemon-cli.js +13 -2
  65. package/dist/{daemon-runtime-BD_EkuZP.js → daemon-runtime-7YBz5otm.js} +3 -3
  66. package/dist/{daemon-runtime-CAdn50ea.js → daemon-runtime-DaJ4Tf2a.js} +3 -3
  67. package/dist/{deliver-6fYMGY7T.js → deliver-0nDhDdKd.js} +2 -2
  68. package/dist/{deliver-DyO3QD8O.js → deliver-BiWlR84Y.js} +5 -5
  69. package/dist/{deliver-DB4v0Tyl.js → deliver-C81eqdrP.js} +2 -2
  70. package/dist/{deliver-Cjyb6h4g.js → deliver-f3cIWxXT.js} +5 -5
  71. package/dist/{deps-Bt6gnwqB.js → deps-D5me2CAW.js} +1 -1
  72. package/dist/{devices-cli-CK5iNr60.js → devices-cli-DuVhACtW.js} +4 -4
  73. package/dist/{devices-cli-Dg4sVTTI.js → devices-cli-Ec6d58OB.js} +4 -4
  74. package/dist/{diagnostics-Ee2qfR9V.js → diagnostics-BZH08r5U.js} +1 -1
  75. package/dist/{diagnostics-4PsqURzT.js → diagnostics-CdawaB0U.js} +1 -1
  76. package/dist/{directory-cli-CIX9qXWA.js → directory-cli-BQrGwwjf.js} +6 -6
  77. package/dist/{directory-cli-CR-4DW4i.js → directory-cli-FR_KoYon.js} +6 -6
  78. package/dist/{dns-cli-Cd3EpJKL.js → dns-cli-CH2QMf70.js} +4 -4
  79. package/dist/{dns-cli-DzE58v7c.js → dns-cli-Cua_RGWw.js} +4 -4
  80. package/dist/{docs-cli-DD59E5fQ.js → docs-cli-9yu6OeWj.js} +2 -2
  81. package/dist/{docs-cli-BcqjkjOA.js → docs-cli-DwrSCuWF.js} +2 -2
  82. package/dist/{doctor-completion-Dw70YhMd.js → doctor-completion-BzfgfpBH.js} +2 -2
  83. package/dist/{doctor-completion-Dv6aw9I2.js → doctor-completion-wlBp8bv7.js} +2 -2
  84. package/dist/{doctor-config-flow-BOfsrB_o.js → doctor-config-flow-CKJlpwtv.js} +5 -5
  85. package/dist/{doctor-config-flow-dUAjyD2W.js → doctor-config-flow-CcwEh3WQ.js} +5 -5
  86. package/dist/{enable-avpl_Lwo.js → enable-BI6rQ1Fb.js} +1 -1
  87. package/dist/{enable-B5wvwTYB.js → enable-xfczksnk.js} +1 -1
  88. package/dist/entry.js +1 -1
  89. package/dist/{exec-approvals-cli-Cv9lE0Ov.js → exec-approvals-cli-1K1PMf0f.js} +10 -10
  90. package/dist/{exec-approvals-cli-CLD1HXqE.js → exec-approvals-cli-N45JsIvc.js} +10 -10
  91. package/dist/extensionAPI.js +8 -8
  92. package/dist/{gateway-cli-C1yf0Kx4.js → gateway-cli-Bz5fqsnE.js} +84 -83
  93. package/dist/{gateway-cli-DF-S-bKo.js → gateway-cli-_xNZ2L_e.js} +86 -85
  94. package/dist/{gateway-rpc-CBb3_pT9.js → gateway-rpc-c2_A2rwu.js} +2 -2
  95. package/dist/{gateway-rpc-DrcgCoEA.js → gateway-rpc-gDrdC_J6.js} +2 -2
  96. package/dist/{glass-ui-ws-CgTry9OG.js → glass-ui-ws-CbKVlQRh.js} +62 -61
  97. package/dist/{glass-ui-ws-BZJKBK5D.js → glass-ui-ws-DO8WKPIK.js} +63 -62
  98. package/dist/{health-B__mwl7J.js → health-B5BrlZ8G.js} +6 -6
  99. package/dist/{health-BJl_ZtRW.js → health-B7yvi1O9.js} +6 -6
  100. package/dist/{hooks-cli-CpDJa8fo.js → hooks-cli-CrgD2ZqP.js} +42 -41
  101. package/dist/{hooks-cli-B_d8Cv16.js → hooks-cli-mwiHuRfO.js} +42 -41
  102. package/dist/{hooks-status-CRdYwf7p.js → hooks-status-B5vDwm19.js} +1 -1
  103. package/dist/{hooks-status-i4MgV8tU.js → hooks-status-CQ33gaVT.js} +2 -2
  104. package/dist/index.js +47 -46
  105. package/dist/{inspect-BZEGJ1Wu.js → inspect-C3_zr-N9.js} +2 -2
  106. package/dist/{inspect-ChCXJY8c.js → inspect-D_lN8pwg.js} +2 -2
  107. package/dist/{install-safe-path-PVqsVjI9.js → install-safe-path-79R0iPyC.js} +2 -2
  108. package/dist/{install-safe-path-INk2Z_kc.js → install-safe-path-BBe6qFNr.js} +2 -2
  109. package/dist/{installs-lGgvyXAJ.js → installs-BVJQl3Tj.js} +3 -3
  110. package/dist/{installs-b6XWplET.js → installs-Bb1phV9x.js} +3 -3
  111. package/dist/{lifecycle-core-iiq9e4fE.js → lifecycle-core-DdbL6ELJ.js} +7 -7
  112. package/dist/{lifecycle-core-SWNKAc8k.js → lifecycle-core-O50xtu5c.js} +7 -7
  113. package/dist/llm-slug-generator.js +9 -9
  114. package/dist/{logs-cli-BGjeoamB.js → logs-cli-DvbMaSKU.js} +6 -6
  115. package/dist/{logs-cli-BEWpB_ac.js → logs-cli-T5v8efuM.js} +6 -6
  116. package/dist/{manager-xeIkDkmx.js → manager-BVPXSK-I.js} +1 -1
  117. package/dist/{manager-rvtFoeFT.js → manager-CnBU0aOR.js} +1 -1
  118. package/dist/{manager-PTSjHNVq.js → manager-CpBJ1BE6.js} +1 -1
  119. package/dist/{manager-DcZUW1bz.js → manager-CvqH_tah.js} +1 -1
  120. package/dist/{memory-D8JRYEYq.js → memory-BsGfHO_F.js} +4 -4
  121. package/dist/{memory-CeB8eMPH.js → memory-CbwmxmxW.js} +4 -4
  122. package/dist/{memory-cli-DZtv3G9o.js → memory-cli-B1dFPZw-.js} +7 -7
  123. package/dist/{memory-cli-rORHUdUV.js → memory-cli-BwQsPEFk.js} +7 -7
  124. package/dist/{model-catalog-MHTLXFwi.js → model-catalog-CzKsiNZA.js} +2 -2
  125. package/dist/{model-catalog-DQTmHZK7.js → model-catalog-IWi6-nY9.js} +2 -2
  126. package/dist/{model-picker-BVNI6Imm.js → model-picker-CS_h9RHv.js} +2 -2
  127. package/dist/{model-picker-DHLA0BEe.js → model-picker-DN-co6Oy.js} +2 -2
  128. package/dist/{models-D3haEpaG.js → models-Dm6dSSSx.js} +17 -17
  129. package/dist/{models-cli-DiyNuQ5w.js → models-cli-BA6ufqLd.js} +49 -48
  130. package/dist/{models-cli-DidUOdbx.js → models-cli-BPSrz6tf.js} +46 -45
  131. package/dist/{models-config-CRnTzdFs.js → models-config-B5Xxy-c-.js} +1 -1
  132. package/dist/{models-config-Br7EjqgG.js → models-config-CiR_RUxw.js} +1 -1
  133. package/dist/{node-cli-Yqf38Nio.js → node-cli-2HDdeLgi.js} +20 -20
  134. package/dist/{node-cli-DnwByBU2.js → node-cli-CH1yLZuO.js} +20 -20
  135. package/dist/{node-service-CRSkbk2b.js → node-service-CfHbECCi.js} +2 -2
  136. package/dist/{node-service-E8k7BOQV.js → node-service-D44noKnR.js} +2 -2
  137. package/dist/{nodes-cli-BY6HrZlh.js → nodes-cli-ARs9ZPma.js} +9 -9
  138. package/dist/{nodes-cli-OTk4gEj-.js → nodes-cli-DIm6cMS_.js} +9 -9
  139. package/dist/{note-Bn5K9itM.js → note-Cltpxj6i.js} +1 -1
  140. package/dist/{note-DtkOgLxt.js → note-ytwb4wwn.js} +1 -1
  141. package/dist/{npm-registry-spec-CZCkONwR.js → npm-registry-spec-CONWlhd6.js} +1 -1
  142. package/dist/{npm-registry-spec-L8BUQ0nu.js → npm-registry-spec-DPqOMFd9.js} +1 -1
  143. package/dist/{onboard-oIJ6OEGu.js → onboard-CjnPughY.js} +18 -18
  144. package/dist/{onboard-C1PSYsJY.js → onboard-Cmz6Rtm-.js} +18 -18
  145. package/dist/{onboard-channels-BSt89ffO.js → onboard-channels-Cozz3CQv.js} +7 -7
  146. package/dist/{onboard-channels-DvNWHvx3.js → onboard-channels-D00NAtQt.js} +7 -7
  147. package/dist/{onboard-custom-y7PsUrmE.js → onboard-custom-BCcuL4Uq.js} +2 -2
  148. package/dist/{onboard-custom-TvRg0dYq.js → onboard-custom-C-wfNtOM.js} +2 -2
  149. package/dist/{onboard-helpers-CtpOchu0.js → onboard-helpers-BKfeJ1xj.js} +4 -4
  150. package/dist/{onboard-helpers-HjgAKoSl.js → onboard-helpers-CCI7SimM.js} +4 -4
  151. package/dist/{onboard-hooks-BU0EsBMH.js → onboard-hooks-CXRw9BJY.js} +2 -2
  152. package/dist/{onboard-hooks-Cmy0Qz0F.js → onboard-hooks-DfDF9AU4.js} +2 -2
  153. package/dist/{onboard-remote-B7bM-1-l.js → onboard-remote-D4R-Yq2Q.js} +3 -3
  154. package/dist/{onboard-remote-B5kHPh_e.js → onboard-remote-DKXBH_lQ.js} +3 -3
  155. package/dist/{onboard-skills-BsPcuuer.js → onboard-skills-BPmu8XLA.js} +2 -2
  156. package/dist/{onboard-skills-V7pX2pkl.js → onboard-skills-jVyIFojF.js} +3 -3
  157. package/dist/{onboarding-D4SGY_zG.js → onboarding-BPZb40BJ.js} +16 -16
  158. package/dist/{onboarding-Ce0PyZFq.js → onboarding-BrTMOcPF.js} +16 -16
  159. package/dist/{onboarding.finalize-BDPrr9CT.js → onboarding.finalize-Bd2rGMjo.js} +26 -26
  160. package/dist/{onboarding.finalize-TkbmJzg5.js → onboarding.finalize-BiL_LXrR.js} +28 -28
  161. package/dist/{onboarding.gateway-config-9dgVRLeb.js → onboarding.gateway-config-B301LxTx.js} +6 -6
  162. package/dist/{onboarding.gateway-config-DXQhxsQS.js → onboarding.gateway-config-ChCxv8dy.js} +6 -6
  163. package/dist/{openai-model-default-D_rz8Pew.js → openai-model-default-CKfNKTZD.js} +1 -1
  164. package/dist/{openai-model-default-BkGyzajy.js → openai-model-default-ChdgeMqX.js} +1 -1
  165. package/dist/{outbound-send-deps-PNzbuoSX.js → outbound-send-deps-JQjmNLPx.js} +1 -1
  166. package/dist/{pairing-cli-WQ1MKO2B.js → pairing-cli-D7_UlTsI.js} +3 -3
  167. package/dist/{pairing-cli-D2zvrKTM.js → pairing-cli-UgiAsygW.js} +3 -3
  168. package/dist/{path-env-BHRjFlqO.js → path-env-BAyW1s3c.js} +1 -1
  169. package/dist/{path-env-i-ZjtVbs.js → path-env-C1hgM8gP.js} +1 -1
  170. package/dist/{pi-embedded-BPuUM-gD.js → pi-embedded-C9wLrFjj.js} +1439 -494
  171. package/dist/{pi-embedded-helpers-nFK_hP2q.js → pi-embedded-helpers-BBiyNXkS.js} +1 -1
  172. package/dist/{pi-embedded-helpers-DVolpQ34.js → pi-embedded-helpers-CDzBxa-P.js} +1 -1
  173. package/dist/{pi-tools.policy-uHgu_nx0.js → pi-tools.policy-CU8U7--z.js} +2 -2
  174. package/dist/{pi-tools.policy-CTzYYKRt.js → pi-tools.policy-WaLKhqJQ.js} +2 -2
  175. package/dist/{plugin-auto-enable-C4b23B35.js → plugin-auto-enable-Bt2sVz8w.js} +2 -2
  176. package/dist/{plugin-auto-enable-BkhVwtbW.js → plugin-auto-enable-PBDcVF_-.js} +2 -2
  177. package/dist/{plugin-registry-V5jShvbP.js → plugin-registry-BLoSesyj.js} +2 -2
  178. package/dist/{plugin-registry-CxUYRmLh.js → plugin-registry-CZDG8fjK.js} +2 -2
  179. package/dist/plugin-sdk/auto-reply/reply/commands-info.d.ts +1 -0
  180. package/dist/plugin-sdk/auto-reply/reply/middleware-context-warning.d.ts +22 -0
  181. package/dist/plugin-sdk/auto-reply/session-boundary-messages.d.ts +16 -3
  182. package/dist/plugin-sdk/auto-reply/status.d.ts +13 -0
  183. package/dist/plugin-sdk/config/types.models.d.ts +5 -0
  184. package/dist/plugin-sdk/config/zod-schema.core.d.ts +11 -0
  185. package/dist/plugin-sdk/config/zod-schema.d.ts +5 -0
  186. package/dist/plugin-sdk/cost/benchmark.d.ts +36 -0
  187. package/dist/plugin-sdk/cost/breakdown.d.ts +63 -0
  188. package/dist/plugin-sdk/cost/gpu-inference.d.ts +52 -0
  189. package/dist/plugin-sdk/cost/rates.d.ts +32 -0
  190. package/dist/plugin-sdk/cost/serving-discovery.d.ts +54 -0
  191. package/dist/plugin-sdk/cost/summary.d.ts +40 -0
  192. package/dist/plugin-sdk/index.js +13 -2
  193. package/dist/{plugins-cli-CMAwepRk.js → plugins-cli-2yraoR6V.js} +43 -42
  194. package/dist/{plugins-cli-BthQwo7n.js → plugins-cli-CGs9-UtO.js} +43 -42
  195. package/dist/{program-iw_XyVhs.js → program-BnKEJpZF.js} +46 -45
  196. package/dist/{program-context-BVEz8AgF.js → program-context-BvP9L_1W.js} +48 -40
  197. package/dist/{prompt-select-styled-CF4qV0_M.js → prompt-select-styled-BTF5vvv8.js} +32 -32
  198. package/dist/{prompt-select-styled-D3RAY7pg.js → prompt-select-styled-Brx330O3.js} +31 -31
  199. package/dist/{provider-auth-helpers-Dxo0v0UO.js → provider-auth-helpers-CppzYZM9.js} +6 -6
  200. package/dist/{provider-auth-helpers-BTBjOyhO.js → provider-auth-helpers-hjy3e-oS.js} +6 -6
  201. package/dist/{push-apns-B8Wg3Hqw.js → push-apns-BD2iO09c.js} +1 -1
  202. package/dist/{push-apns-DIIbGT1M.js → push-apns-DJ55TFPT.js} +1 -1
  203. package/dist/{pw-ai-kkF0QaDF.js → pw-ai-DBAtSFTB.js} +2 -2
  204. package/dist/{pw-ai-BFS9ezWe.js → pw-ai-DOAsQ5NX.js} +2 -2
  205. package/dist/{pw-ai-_prsAw5O.js → pw-ai-DQZa9DUQ.js} +2 -2
  206. package/dist/{pw-ai-Cx-Ko_FL.js → pw-ai-DY_6l11g.js} +2 -2
  207. package/dist/{qr-cli-CcAzgz_N.js → qr-cli-D2A-IU0Y.js} +1 -1
  208. package/dist/{qr-cli-KmGkQDBF.js → qr-cli-DHpiebkG.js} +1 -1
  209. package/dist/{redact-identifier-CXvHJXk9.js → redact-identifier-BOxAUdff.js} +1 -1
  210. package/dist/{register.agent-8XsVRuWC.js → register.agent-DTGvQGla.js} +61 -60
  211. package/dist/{register.agent-D-OIszeY.js → register.agent-Dz_P7PxO.js} +63 -62
  212. package/dist/register.configure-CrgU3FzU.js +131 -0
  213. package/dist/register.configure-D9w7Tm9e.js +135 -0
  214. package/dist/{register.maintenance-CjM8sJqH.js → register.maintenance-CqvrXPF7.js} +64 -63
  215. package/dist/{register.maintenance-CBYqsXkf.js → register.maintenance-d5xHdDgu.js} +63 -62
  216. package/dist/{register.message-DnljWvZP.js → register.message-C0tqgEor.js} +40 -39
  217. package/dist/{register.message-kSIASKVK.js → register.message-DNMCxaAD.js} +41 -40
  218. package/dist/{register.onboard-Vj1-Ike1.js → register.onboard--eJVfJGa.js} +28 -28
  219. package/dist/{register.onboard-eDNn1pdd.js → register.onboard-dkAvGraV.js} +28 -28
  220. package/dist/{register.setup-DMaoMWRD.js → register.setup-CgufX-6c.js} +28 -28
  221. package/dist/{register.setup-CmhspsS8.js → register.setup-Dwh0ylCS.js} +28 -28
  222. package/dist/{register.status-health-sessions-r3F9H8b0.js → register.status-health-sessions-BeAm7HAq.js} +36 -36
  223. package/dist/{register.status-health-sessions-CJqCoqAi.js → register.status-health-sessions-D6BRCFg_.js} +35 -35
  224. package/dist/{register.subclis-RqX1a2aL.js → register.subclis-Hb2xSHBy.js} +37 -29
  225. package/dist/{replies-BYF1gbJf.js → replies-0nzkXt6o.js} +1 -1
  226. package/dist/{replies-B91-OngF.js → replies-C5CBlnFS.js} +1 -1
  227. package/dist/{replies-DAYTg6Mb.js → replies-D0FYSIJg.js} +1 -1
  228. package/dist/{replies-UP2sglaR.js → replies-_DV8VSSj.js} +1 -1
  229. package/dist/{resolve-route-Zww0Y-HJ.js → resolve-route-CnTdHVgw.js} +1 -1
  230. package/dist/{resolve-route-CmZ7XjmB.js → resolve-route-D0NrCHnr.js} +1 -1
  231. package/dist/{routes-BfeVDhod.js → routes-CPMVuvoz.js} +3 -3
  232. package/dist/{routes-y2Ww0pum.js → routes-DIyAmLYR.js} +3 -3
  233. package/dist/{rpc-DZCrGGH5.js → rpc-B2BLRS45.js} +2 -2
  234. package/dist/{rpc-RIkh5F9v.js → rpc-gUsL9Mqf.js} +2 -2
  235. package/dist/{run-main-6pE2fYXT.js → run-main-B_NTFmz1.js} +61 -60
  236. package/dist/{sandbox-DQdjlC-w.js → sandbox-61-kshSF.js} +5 -5
  237. package/dist/{sandbox-BjQ6n3zl.js → sandbox-J92UBQK8.js} +5 -5
  238. package/dist/{sandbox-cli-CTYAHFyM.js → sandbox-cli-D9v0jhBb.js} +8 -8
  239. package/dist/{sandbox-cli-C0IVf8AS.js → sandbox-cli-DJgF-r8G.js} +8 -8
  240. package/dist/{security-cli-B8VyQJcl.js → security-cli-CZix5cXq.js} +13 -13
  241. package/dist/{security-cli-D0oErb9f.js → security-cli-J9J0qvDy.js} +13 -13
  242. package/dist/{send-Cxu1tl56.js → send-B0jHSNMF.js} +1 -1
  243. package/dist/{send-Cuk_Rjss.js → send-C75uSv6p.js} +1 -1
  244. package/dist/{send-BBfSp-8Q.js → send-Dq252-bi.js} +1 -1
  245. package/dist/{server-context-BFCh7pUb.js → server-context-D-82OTsT.js} +5 -5
  246. package/dist/{server-context-YlgRz1wC.js → server-context-SbbjNkPL.js} +5 -5
  247. package/dist/{server-methods-BxsThjMp.js → server-methods-CFWjtx32.js} +31 -31
  248. package/dist/{server-methods-BWCAXrQJ.js → server-methods-Cz_-FX5B.js} +31 -31
  249. package/dist/{server-node-events-AZFI44cm.js → server-node-events-BiMD-Sik.js} +40 -39
  250. package/dist/{server-node-events-C10Bhdag.js → server-node-events-UJ4Hwcsf.js} +39 -38
  251. package/dist/{service-vsb7_8MA.js → service-BF50XyKr.js} +2 -2
  252. package/dist/{service-BBw78ATM.js → service-Ccv3Zi5_.js} +2 -2
  253. package/dist/{session-cost-usage-CqLUlh7S.js → session-cost-usage-CJWHHY-C.js} +1 -1
  254. package/dist/{session-cost-usage-D6Ocwmq1.js → session-cost-usage-D3mgssM_.js} +1 -1
  255. package/dist/{session-utils-BZnPW904.js → session-utils-Cs1jlD-q.js} +3 -3
  256. package/dist/{session-utils-BGw_xwXK.js → session-utils-Zpe3t68b.js} +3 -3
  257. package/dist/{sessions-uS7rV-lI.js → sessions-BSmT7vGX.js} +3 -3
  258. package/dist/{sessions-DHPf5TzB.js → sessions-Dn6VXn4p.js} +1 -1
  259. package/dist/{sessions-optZRB57.js → sessions-Dxf5Kjig.js} +1 -1
  260. package/dist/{shared-CfBMF1VB.js → shared-BJRsBGGr.js} +2 -2
  261. package/dist/{shared-CVXZtpIq.js → shared-BmjlTHYU.js} +2 -2
  262. package/dist/{shared-BucaCyaw.js → shared-Ck6cf10x.js} +1 -1
  263. package/dist/{shared-k1QjV3ys.js → shared-Crfo8y70.js} +1 -1
  264. package/dist/{skill-commands-CKm7eCw6.js → skill-commands-D0xAWG0l.js} +1 -1
  265. package/dist/{skill-commands-DAtpPeXi.js → skill-commands-DKkiQJxU.js} +1 -1
  266. package/dist/{skill-commands-BoMrW3WV.js → skill-commands-JIccKWkf.js} +1 -1
  267. package/dist/{skill-commands-yPirQFOb.js → skill-commands-KnANH5Qm.js} +1 -1
  268. package/dist/{skills-cli-CcWFIcOR.js → skills-cli-BZF5mcG5.js} +7 -7
  269. package/dist/{skills-cli-DcJBgk5R.js → skills-cli-C9F-zLWe.js} +3 -3
  270. package/dist/{skills-install-CcW780Kq.js → skills-install-QOHQrX6P.js} +4 -4
  271. package/dist/{skills-install-CbRsCzAG.js → skills-install-X12kifP1.js} +4 -4
  272. package/dist/{skills-status-CLzaY4r2.js → skills-status-6LVKpabC.js} +1 -1
  273. package/dist/{ssrf-q6hBiAOi.js → ssrf-BCSnhba8.js} +13 -2
  274. package/dist/{ssrf-oI58TMOb.js → ssrf-DNhyFMRW.js} +13 -2
  275. package/dist/{status-BxD8CjLr.js → status-BGUaaSHe.js} +2 -2
  276. package/dist/{status-B5sjPQS6.js → status-Bp48-ySL.js} +20 -20
  277. package/dist/{status-CZc22Lqb.js → status-CObdh7-H.js} +2 -2
  278. package/dist/{status-Cv8N2kIe.js → status-FX0BMcCb.js} +20 -20
  279. package/dist/{status.update-B52bM2Tg.js → status.update-CdTtmVpp.js} +2 -2
  280. package/dist/{status.update-Bl_ewksT.js → status.update-_3qHPt0O.js} +2 -2
  281. package/dist/{subagent-registry-BnHgIGX-.js → subagent-registry-ChDWDl_p.js} +304 -106
  282. package/dist/{synthesis-fD8J2vag.js → synthesis-CmQvOHg6.js} +9 -9
  283. package/dist/{synthesis-7UL3pCpj.js → synthesis-DIkOQnhF.js} +8 -8
  284. package/dist/{synthesis-DvfrgkQU.js → synthesis-DdP6tbyk.js} +36 -35
  285. package/dist/{synthesis-o7Zdrwxz.js → synthesis-m6WCyI41.js} +36 -35
  286. package/dist/{system-cli-BAn07VkE.js → system-cli-DB9etQxq.js} +5 -5
  287. package/dist/{system-cli-BTZ8T0-Z.js → system-cli-szRqg1_v.js} +5 -5
  288. package/dist/{systemd-DCzA-V_E.js → systemd-Dic80Qni.js} +1 -1
  289. package/dist/{systemd-Cmn7zMqD.js → systemd-Dtydk5-z.js} +1 -1
  290. package/dist/{systemd-hints-CvIqgg9d.js → systemd-hints-DmDUq9JT.js} +4 -4
  291. package/dist/{systemd-hints-BlGehfA3.js → systemd-hints-bP8dBJ78.js} +4 -4
  292. package/dist/{systemd-linger-BUWYteOW.js → systemd-linger-BBxRNFXz.js} +2 -2
  293. package/dist/{systemd-linger-Bj4nK9ZB.js → systemd-linger-DjoQVcOq.js} +2 -2
  294. package/dist/{tui-XLWiN8Hm.js → tui-CEhOf9fk.js} +6 -6
  295. package/dist/{tui-B6mIUNPO.js → tui-Dp58oYvX.js} +6 -6
  296. package/dist/{tui-cli-byFYgg3c.js → tui-cli-DFaOwBwg.js} +12 -12
  297. package/dist/{tui-cli-CTK5_3rU.js → tui-cli-wxh3YpaV.js} +12 -12
  298. package/dist/{unified-runner-BIiKFnNF.js → unified-runner-Cu3lGa3A.js} +1440 -495
  299. package/dist/{unified-runner-DnikxMFg.js → unified-runner-DL-sfvGT.js} +305 -107
  300. package/dist/{update-DxY1UB0k.js → update-BDo7wxMf.js} +1 -1
  301. package/dist/{update-EhDcBqN1.js → update-CcacbR32.js} +1 -1
  302. package/dist/{update-check-pFwV6W-z.js → update-check-A86nJKtZ.js} +1 -1
  303. package/dist/{update-check-H0DwvuqN.js → update-check-oEbS0voJ.js} +1 -1
  304. package/dist/{update-cli-BAdPKO1o.js → update-cli-DAKoU0Wn.js} +73 -72
  305. package/dist/{update-cli-C8IVRiDZ.js → update-cli-gEBRNrm2.js} +74 -73
  306. package/dist/{update-runner-CERd2XdT.js → update-runner-CQMv-ibM.js} +3 -3
  307. package/dist/{update-runner-7oHPAIND.js → update-runner-DHi359Tb.js} +3 -3
  308. package/dist/{usage-format-_37Bn-Jb.js → usage-format-DQJz-0qd.js} +0 -1
  309. package/dist/{usage-format-rxT5cEAf.js → usage-format-DeczTGI-.js} +0 -1
  310. package/dist/{webhooks-cli-3UJupWMP.js → webhooks-cli-C3g4MxCE.js} +3 -3
  311. package/dist/{webhooks-cli-BFpGMNrf.js → webhooks-cli-C3uyehJS.js} +3 -3
  312. package/dist/{with-timeout-Bn-ltLg1.js → with-timeout-B0ZJa7f2.js} +1 -1
  313. package/dist/{with-timeout-EXM-FP4_.js → with-timeout-GbJ1Yzsh.js} +1 -1
  314. package/package.json +1 -1
  315. package/dist/register.configure-Bcdw9qlF.js +0 -130
  316. package/dist/register.configure-KE6Kvt4O.js +0 -134
  317. /package/dist/{agents.config-BG9fpad0.js → agents.config-Cyc_RegL.js} +0 -0
  318. /package/dist/{agents.config-CxrFhtC1.js → agents.config-DK6nN-Qh.js} +0 -0
  319. /package/dist/{argv-oa_KBmv1.js → argv-Bl0th4dq.js} +0 -0
  320. /package/dist/{auth-choice-legacy-DwMt7oDR.js → auth-choice-legacy-BZWIpO92.js} +0 -0
  321. /package/dist/{auth-choice-legacy-ZsU_kwPI.js → auth-choice-legacy-iEyARXI2.js} +0 -0
  322. /package/dist/{bindings-CLS_owm_.js → bindings-BAOPW5eK.js} +0 -0
  323. /package/dist/{bindings-BpMZcmYL.js → bindings-c7qLJdIA.js} +0 -0
  324. /package/dist/{brew-B3VMQVQk.js → brew-B4FH-mEH.js} +0 -0
  325. /package/dist/{brew-BsE_w2tW.js → brew-CI00FKf8.js} +0 -0
  326. /package/dist/{catalog-CriSxQMH.js → catalog-BaM8d1-T.js} +0 -0
  327. /package/dist/{catalog-BXxi5-YC.js → catalog-BnLcGVie.js} +0 -0
  328. /package/dist/{channel-selection-BiYW5XI-.js → channel-selection-BrFl0vVK.js} +0 -0
  329. /package/dist/{channel-selection-DF4bza2Q.js → channel-selection-DjrS6oiz.js} +0 -0
  330. /package/dist/{channels-status-issues-DuRF3XF3.js → channels-status-issues-BwbA2OBt.js} +0 -0
  331. /package/dist/{channels-status-issues-C2AVfv0-.js → channels-status-issues-iWQDGUQe.js} +0 -0
  332. /package/dist/{cli-utils-tNdOjVQI.js → cli-utils-CbnnSB38.js} +0 -0
  333. /package/dist/{clipboard-B1jgJ11s.js → clipboard-BSTxQ2tO.js} +0 -0
  334. /package/dist/{clipboard-Sks8Qw-6.js → clipboard-CHn5r7Kj.js} +0 -0
  335. /package/dist/{command-options-C2yg82U0.js → command-options-DgcCGXMQ.js} +0 -0
  336. /package/dist/{command-options-D_KEIae-.js → command-options-Vxb4M7Aj.js} +0 -0
  337. /package/dist/{consolidate-DPAffHCg.js → consolidate-BSUbtSDt.js} +0 -0
  338. /package/dist/{consolidate-CF6vEjPe.js → consolidate-DhoiF4n7.js} +0 -0
  339. /package/dist/{constants-B4wXIPMk.js → constants-BLIhifCJ.js} +0 -0
  340. /package/dist/{constants-ChnKXZKi.js → constants-BP_JoSwO.js} +0 -0
  341. /package/dist/{control-ui-assets-CkPR0Fz2.js → control-ui-assets-CnX0W3vy.js} +0 -0
  342. /package/dist/{control-ui-assets-BVCcPRi3.js → control-ui-assets-DfBRXG5y.js} +0 -0
  343. /package/dist/{delivery-queue-DqDe6994.js → delivery-queue-CIwn40ej.js} +0 -0
  344. /package/dist/{delivery-queue-RUd4NhRw.js → delivery-queue-duM0RT18.js} +0 -0
  345. /package/dist/{dm-policy-shared-DmpXsl2K.js → dm-policy-shared-BUwZ6Ajx.js} +0 -0
  346. /package/dist/{dm-policy-shared-ZfPtrTeh.js → dm-policy-shared-EuuPwRNE.js} +0 -0
  347. /package/dist/{entry-status-BqhxPFzK.js → entry-status-D0BSpWt_.js} +0 -0
  348. /package/dist/{format-BskCnX0I.js → format-BcXs5iuf.js} +0 -0
  349. /package/dist/{gmail-setup-utils-BlGvgPlF.js → gmail-setup-utils-DJgxyDTX.js} +0 -0
  350. /package/dist/{gmail-setup-utils-DsRU2ywQ.js → gmail-setup-utils-_TEJA4pL.js} +0 -0
  351. /package/dist/{health-format-CzrMGubG.js → health-format-Dp4xmTKn.js} +0 -0
  352. /package/dist/{health-format-C0DWlpEn.js → health-format-Li703vy6.js} +0 -0
  353. /package/dist/{help-format-DhRyo3Pj.js → help-format-8IYCRvx1.js} +0 -0
  354. /package/dist/{help-format-BjEVi4c_.js → help-format-BTNd5kFC.js} +0 -0
  355. /package/dist/{helpers-CcArejFh.js → helpers-BnXDQL2q.js} +0 -0
  356. /package/dist/{helpers-Dm_utoC3.js → helpers-CoScWBmD.js} +0 -0
  357. /package/dist/{helpers-DJRLZbrj.js → helpers-DGBa5iKd.js} +0 -0
  358. /package/dist/{helpers-DUclfUl-.js → helpers-lLtg0Hgi.js} +0 -0
  359. /package/dist/{ipv4--8f4a_51.js → ipv4-CCdAVmwu.js} +0 -0
  360. /package/dist/{ipv4-Cy7l-phR.js → ipv4-DFUXU3PT.js} +0 -0
  361. /package/dist/{links-D6ASL_as.js → links-B9CbwY46.js} +0 -0
  362. /package/dist/{links-BkFDs4sT.js → links-CQZxjjCO.js} +0 -0
  363. /package/dist/{logging-4WqMHwAZ.js → logging-BRejMykf.js} +0 -0
  364. /package/dist/{logging-iIX8duxv.js → logging-BmJ5ky59.js} +0 -0
  365. /package/dist/{logging-Czh4x_NQ.js → logging-CLWZ3KQI.js} +0 -0
  366. /package/dist/{model-D50Lt_sm.js → model-BMFj7NXy.js} +0 -0
  367. /package/dist/{model-param-b-CfiuLqZG.js → model-param-b-C6mMtCJr.js} +0 -0
  368. /package/dist/{onboard-config-BKb2QQqE.js → onboard-config-B9Iy9-4f.js} +0 -0
  369. /package/dist/{onboard-config-DZIbmz6s.js → onboard-config-DwsP5yz1.js} +0 -0
  370. /package/dist/{outbound-send-deps-BR6jeE9h.js → outbound-send-deps-DpyxnI3f.js} +0 -0
  371. /package/dist/{parse-log-line-CeJ1RDHv.js → parse-log-line-BQPvB6cZ.js} +0 -0
  372. /package/dist/{parse-log-line-DxFrnzNo.js → parse-log-line-Cg7e_EO6.js} +0 -0
  373. /package/dist/{parse-port-DdAxyRwV.js → parse-port-CLBKavYE.js} +0 -0
  374. /package/dist/{parse-port-W56FnCN_.js → parse-port-dzRz6QnZ.js} +0 -0
  375. /package/dist/{parse-timeout-DKY8YAUj.js → parse-timeout-CuYdP9TL.js} +0 -0
  376. /package/dist/{path-safety-LPRW6mO-.js → path-safety-ZDtSDPro.js} +0 -0
  377. /package/dist/{path-safety-grmMl9nR.js → path-safety-cWA8NpOb.js} +0 -0
  378. /package/dist/{plugins-allowlist-BuJjTWyS.js → plugins-allowlist-C5r7biDp.js} +0 -0
  379. /package/dist/{plugins-allowlist-BvQZxkGy.js → plugins-allowlist-CD4oIJNk.js} +0 -0
  380. /package/dist/{ports-CqKpyZSl.js → ports-BE4iY9ho.js} +0 -0
  381. /package/dist/{ports-BDzMH5Eu.js → ports-C2swmreL.js} +0 -0
  382. /package/dist/{program-context-C5Y6Svzj.js → program-context-CGKRxOBU.js} +0 -0
  383. /package/dist/{progress-deSwGz9x.js → progress-BOQ0hkeM.js} +0 -0
  384. /package/dist/{progress-B3K1UFtC.js → progress-DQTvTiEg.js} +0 -0
  385. /package/dist/{prompt-style-DeaIm7_1.js → prompt-style-CzRuIYtp.js} +0 -0
  386. /package/dist/{prompt-style-DS51QPPi.js → prompt-style-pphr4yLK.js} +0 -0
  387. /package/dist/{prompts-LvxbwPs6.js → prompts-B98rp78m.js} +0 -0
  388. /package/dist/{prompts-l_pUOv42.js → prompts-CqJkfsHC.js} +0 -0
  389. /package/dist/{qmd-manager-BbWeOOTD.js → qmd-manager-C6wRtPm_.js} +0 -0
  390. /package/dist/{qmd-manager-CYKlEJ2U.js → qmd-manager-CYEAMLE7.js} +0 -0
  391. /package/dist/{runtime-guard-GWXNB3ke.js → runtime-guard-Bgv3O9s4.js} +0 -0
  392. /package/dist/{runtime-guard-DWXoHW1Q.js → runtime-guard-ofQGcCUc.js} +0 -0
  393. /package/dist/{runtime-status-BqrK6ivx.js → runtime-status-B-PXkhrX.js} +0 -0
  394. /package/dist/{runtime-status-D4pjzLyv.js → runtime-status-Zb9OQ0VK.js} +0 -0
  395. /package/dist/{session-dirs-CXErIzZq.js → session-dirs-BsQ-g02q.js} +0 -0
  396. /package/dist/{session-dirs-DJ4qiP3r.js → session-dirs-DpiMgw4q.js} +0 -0
  397. /package/dist/{skill-scanner-zh2dJM3x.js → skill-scanner-D5p8L-xO.js} +0 -0
  398. /package/dist/{skill-scanner-Ur9nMoo4.js → skill-scanner-EhsZUzzk.js} +0 -0
  399. /package/dist/{stagger-DkaCfsKB.js → stagger-DQs772BN.js} +0 -0
  400. /package/dist/{status-Bz_-dDs6.js → status-DtyqId3v.js} +0 -0
  401. /package/dist/{status-CExNNC5N.js → status-dOhj12u0.js} +0 -0
  402. /package/dist/{system-run-command-CeR1OLFk.js → system-run-command-2oJPKfVr.js} +0 -0
  403. /package/dist/{system-run-command-Craglj8T.js → system-run-command-D_OmCQOL.js} +0 -0
  404. /package/dist/{table-xKEHbVsK.js → table-Dm8jYqmW.js} +0 -0
  405. /package/dist/{table-jBELNhV1.js → table-Ds5CZCyv.js} +0 -0
  406. /package/dist/{tool-loop-detection-D3y39HsT.js → tool-loop-detection-2Mxxm8YE.js} +0 -0
  407. /package/dist/{tool-loop-detection-DljhV89j.js → tool-loop-detection-Bk07vuCX.js} +0 -0
  408. /package/dist/{widearea-dns-C8Rsixsi.js → widearea-dns-BwIBBqZo.js} +0 -0
  409. /package/dist/{widearea-dns-BSrnDwJD.js → widearea-dns-DA_m7oeT.js} +0 -0
  410. /package/dist/{workspace-DKEYzTNc.js → workspace-DD9pYbiv.js} +0 -0
  411. /package/dist/{workspace-BkWAKK8O.js → workspace-Wkr6wXcS.js} +0 -0
  412. /package/dist/{wsl-cy5jpbkx.js → wsl-Ci3VOaSK.js} +0 -0
  413. /package/dist/{wsl-hSA0zCrh.js → wsl-S50RbgL8.js} +0 -0
@@ -8,17 +8,17 @@ import { _ as DEFAULT_PROVIDER, a as modelKey, d as resolveModelRefFromString, f
8
8
  import { i as resolveAckReaction, o as resolveEffectiveMessagesConfig, r as resolveResponsePrefixTemplate, s as resolveHumanDelayConfig, t as createReplyPrefixOptions } from "./reply-prefix-i-FPYcoQ.js";
9
9
  import { t as normalizeChatType } from "./chat-type-Acj2OK2p.js";
10
10
  import { i as resolveSlackAccount, n as listChannelPlugins, o as resolveSlackAppToken, r as normalizeChannelId$1, s as resolveSlackBotToken, t as getChannelPlugin } from "./plugins-CZ_mYwXq.js";
11
- import { S as resolveSlackChannelId, _ as resolveSlackWebClientOptions, a as sendMessageSlack, b as buildSlackBlocksFallbackText, c as getDefaultLocalRoots, d as fetchRemoteMedia, f as readResponseWithLimit, g as createSlackWebClient, h as fetchWithTimeout, i as resolveSlackThreadTs, l as loadWebMedia, m as bindAbortRelay, n as deliverReplies, o as renderMarkdownWithMarkers, p as fetchWithSsrFGuard, s as markdownToIRWithMeta, t as createSlackReplyDeliveryPlan, u as MediaFetchError, v as parseSlackBlocksInput, x as parseSlackTarget, y as validateSlackBlocksArray } from "./replies-BYF1gbJf.js";
12
- import { $ as loadSessionStore, $t as resolveToolProfilePolicy, A as formatRawAssistantErrorForUi, At as resolveMainSessionKey, B as isRateLimitAssistantError, Bt as saveMediaBuffer, C as downgradeOpenAIReasoningBlocks, Ct as resolveChannelResetConfig, D as classifyFailoverReason, Dt as DEFAULT_RESET_TRIGGERS, E as BILLING_ERROR_USER_MESSAGE, Et as resolveThreadFlag, F as isCompactionFailureError, Ft as createBrowserRouteContext, G as parseImageSizeError, Gt as resolveBrowserControlAuth, H as isTimeoutErrorMessage, Ht as resolveExistingPathsWithinRoot, I as isContextOverflowError, It as registerBrowserRoutes, J as resolveSandboxContext, Jt as collectExplicitAllowlist, K as sanitizeUserFacingText, Kt as applyOwnerOnlyToolPolicy, L as isFailoverAssistantError, Lt as resolveBrowserConfig, M as isAuthAssistantError, Mt as resolveGroupSessionKey, N as isBillingAssistantError, Nt as acquireSessionWriteLock, O as formatAssistantErrorText, Ot as resolveFreshSessionTotalTokens, P as isCloudCodeAssistFormatError, Pt as resolveSessionLockMaxHoldFromTimeout, Q as resolveAndPersistSessionFile, Qt as normalizeToolName$1, R as isFailoverErrorMessage, Rt as resolveProfile, S as extractToolResultId, St as evaluateSessionFreshness, T as isGoogleModelApi, Tt as resolveSessionResetType, U as isTransientHttpError, Ut as getBridgeAuthForPort, V as isRawApiErrorPayload, Vt as DEFAULT_UPLOAD_DIR, W as parseImageDimensionError, Wt as ensureBrowserControlAuth, X as extractDeliveryInfo, Xt as expandToolGroups, Y as resolveSandboxRuntimeStatus, Yt as expandPolicyWithPluginGroups, Z as appendAssistantMessageToSessionTranscript, Zt as mergeAlsoAllowPolicy, _ as sanitizeSessionMessagesImages, _t as INPUT_PROVENANCE_KIND_VALUES, a as normalizeChannelTargetInput, an as resolveBootstrapMaxChars, at as updateSessionStoreEntry, b as resolveImageSanitizationLimits, bt as normalizeInputProvenance, c as parseReplyDirectives, cn as getGlobalHookRunner, ct as deliveryContextFromSession, d as parseInlineDirectives$1, dt as normalizeDeliveryContext, en as stripPluginOnlyAllowlist, et as readSessionUpdatedAt, f as validateAnthropicTurns, ft as normalizeSessionDeliveryFields, g as normalizeTextForComparison, gt as extractToolCallNames, h as isMessagingToolDuplicateNormalized, ht as countToolResults, i as buildTargetResolverSignature, in as ensureSessionHeader, it as updateSessionStore, j as getApiErrorPayloadFingerprint, jt as deriveSessionMetaPatch, k as formatBillingErrorMessage, kt as canonicalizeMainSessionAlias, l as MEDIA_TOKEN_RE, ln as initializeGlobalHookRunner, lt as deliveryContextKey, m as pickFallbackThinkingLevel, mt as capArrayByJsonBytes, nn as matchesAnyGlobPattern, o as normalizeTargetForProvider, on as resolveBootstrapTotalMaxChars, ot as isCacheEnabled, p as validateGeminiTurns, pt as archiveSessionTranscripts, q as ensureSandboxWorkspaceForSession, qt as buildPluginToolGroups, r as normalizeReplyPayloadsForDelivery, rn as buildBootstrapContextFiles, rt as updateLastRoute, s as throwIfAborted, sn as sanitizeGoogleTurnOrdering, st as resolveCacheTtlMs$1, t as deliverOutboundPayloads, tn as compileGlobPatterns, tt as recordSessionMetaFromInbound, u as splitMediaFromOutput, ut as mergeDeliveryContext, v as sanitizeImageBlocks, vt as applyInputProvenanceToUserMessage, w as isAntigravityClaude, wt as resolveSessionResetPolicy, x as extractToolCallsFromAssistant, xt as resolveSessionKey, y as sanitizeToolResultImages, yt as hasInterSessionUserProvenance, z as isLikelyContextOverflowError, zt as getMediaDir } from "./deliver-Cjyb6h4g.js";
11
+ import { S as resolveSlackChannelId, _ as resolveSlackWebClientOptions, a as sendMessageSlack, b as buildSlackBlocksFallbackText, c as getDefaultLocalRoots, d as fetchRemoteMedia, f as readResponseWithLimit, g as createSlackWebClient, h as fetchWithTimeout, i as resolveSlackThreadTs, l as loadWebMedia, m as bindAbortRelay, n as deliverReplies, o as renderMarkdownWithMarkers, p as fetchWithSsrFGuard, s as markdownToIRWithMeta, t as createSlackReplyDeliveryPlan, u as MediaFetchError, v as parseSlackBlocksInput, x as parseSlackTarget, y as validateSlackBlocksArray } from "./replies-0nzkXt6o.js";
12
+ import { $ as loadSessionStore, $t as resolveToolProfilePolicy, A as formatRawAssistantErrorForUi, At as resolveMainSessionKey, B as isRateLimitAssistantError, Bt as saveMediaBuffer, C as downgradeOpenAIReasoningBlocks, Ct as resolveChannelResetConfig, D as classifyFailoverReason, Dt as DEFAULT_RESET_TRIGGERS, E as BILLING_ERROR_USER_MESSAGE, Et as resolveThreadFlag, F as isCompactionFailureError, Ft as createBrowserRouteContext, G as parseImageSizeError, Gt as resolveBrowserControlAuth, H as isTimeoutErrorMessage, Ht as resolveExistingPathsWithinRoot, I as isContextOverflowError, It as registerBrowserRoutes, J as resolveSandboxContext, Jt as collectExplicitAllowlist, K as sanitizeUserFacingText, Kt as applyOwnerOnlyToolPolicy, L as isFailoverAssistantError, Lt as resolveBrowserConfig, M as isAuthAssistantError, Mt as resolveGroupSessionKey, N as isBillingAssistantError, Nt as acquireSessionWriteLock, O as formatAssistantErrorText, Ot as resolveFreshSessionTotalTokens, P as isCloudCodeAssistFormatError, Pt as resolveSessionLockMaxHoldFromTimeout, Q as resolveAndPersistSessionFile, Qt as normalizeToolName$1, R as isFailoverErrorMessage, Rt as resolveProfile, S as extractToolResultId, St as evaluateSessionFreshness, T as isGoogleModelApi, Tt as resolveSessionResetType, U as isTransientHttpError, Ut as getBridgeAuthForPort, V as isRawApiErrorPayload, Vt as DEFAULT_UPLOAD_DIR, W as parseImageDimensionError, Wt as ensureBrowserControlAuth, X as extractDeliveryInfo, Xt as expandToolGroups, Y as resolveSandboxRuntimeStatus, Yt as expandPolicyWithPluginGroups, Z as appendAssistantMessageToSessionTranscript, Zt as mergeAlsoAllowPolicy, _ as sanitizeSessionMessagesImages, _t as INPUT_PROVENANCE_KIND_VALUES, a as normalizeChannelTargetInput, an as resolveBootstrapMaxChars, at as updateSessionStoreEntry, b as resolveImageSanitizationLimits, bt as normalizeInputProvenance, c as parseReplyDirectives, cn as getGlobalHookRunner, ct as deliveryContextFromSession, d as parseInlineDirectives$1, dt as normalizeDeliveryContext, en as stripPluginOnlyAllowlist, et as readSessionUpdatedAt, f as validateAnthropicTurns, ft as normalizeSessionDeliveryFields, g as normalizeTextForComparison, gt as extractToolCallNames, h as isMessagingToolDuplicateNormalized, ht as countToolResults, i as buildTargetResolverSignature, in as ensureSessionHeader, it as updateSessionStore, j as getApiErrorPayloadFingerprint, jt as deriveSessionMetaPatch, k as formatBillingErrorMessage, kt as canonicalizeMainSessionAlias, l as MEDIA_TOKEN_RE, ln as initializeGlobalHookRunner, lt as deliveryContextKey, m as pickFallbackThinkingLevel, mt as capArrayByJsonBytes, nn as matchesAnyGlobPattern, o as normalizeTargetForProvider, on as resolveBootstrapTotalMaxChars, ot as isCacheEnabled, p as validateGeminiTurns, pt as archiveSessionTranscripts, q as ensureSandboxWorkspaceForSession, qt as buildPluginToolGroups, r as normalizeReplyPayloadsForDelivery, rn as buildBootstrapContextFiles, rt as updateLastRoute, s as throwIfAborted, sn as sanitizeGoogleTurnOrdering, st as resolveCacheTtlMs$1, t as deliverOutboundPayloads, tn as compileGlobPatterns, tt as recordSessionMetaFromInbound, u as splitMediaFromOutput, ut as mergeDeliveryContext, v as sanitizeImageBlocks, vt as applyInputProvenanceToUserMessage, w as isAntigravityClaude, wt as resolveSessionResetPolicy, x as extractToolCallsFromAssistant, xt as resolveSessionKey, y as sanitizeToolResultImages, yt as hasInterSessionUserProvenance, z as isLikelyContextOverflowError, zt as getMediaDir } from "./deliver-f3cIWxXT.js";
13
13
  import { a as logMessageProcessed, i as logLaneEnqueue, o as logMessageQueued, r as logLaneDequeue, s as logSessionStateChange, t as diag } from "./diagnostic-BdRnGknC.js";
14
14
  import { n as getDiagnosticSessionState } from "./diagnostic-session-state-DpxCUzoM.js";
15
15
  import { S as GATEWAY_CLIENT_NAMES, _ as listDeliverableMessageChannels, a as chunkText, b as GATEWAY_CLIENT_IDS, c as resolveChunkMode, d as isSafeFenceBreak, f as parseFenceSpans, g as isMarkdownCapableMessageChannel, h as isInternalMessageChannel, i as chunkMarkdownTextWithMode, l as resolveTextChunkLimit, m as isDeliverableMessageChannel, o as chunkTextWithMode, p as INTERNAL_MESSAGE_CHANNEL, r as chunkMarkdownText, t as chunkByNewline, u as findFenceSpanAt, v as normalizeMessageChannel, x as GATEWAY_CLIENT_MODES, y as resolveGatewayMessageChannel } from "./chunk-CAZujdOi.js";
16
16
  import { _ as resolveSymiAgentDir, a as markAuthProfileFailure, c as dedupeProfileIds, d as ensureAuthProfileStore, f as resolveAuthStorePathForDisplay, g as normalizeSecretInput, i as isProfileInCooldown, l as listProfilesForProvider, m as resolveAuthProfileDisplayLabel, n as resolveAuthProfileOrder, o as markAuthProfileUsed, p as withFileLock$1, r as getSoonestCooldownExpiry, s as resolveApiKeyForProfile, u as markAuthProfileGood } from "./auth-profiles-Bt3PyWkt.js";
17
- import { C as unsetConfigValueAtPath, S as setConfigValueAtPath, T as VERSION, _ as resetConfigOverrides, b as getConfigValueAtPath, c as loadConfig, d as writeConfigFile, f as validateConfigObjectWithPlugins, g as getConfigOverrides, h as validateJsonSchemaValue, i as isBlockedHostnameOrIp, l as readConfigFileSnapshot, o as normalizeHostname, p as parseDurationMs, t as SsrFBlockedError, u as resolveConfigSnapshotHash, v as setConfigOverride, w as DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH, x as parseConfigPath, y as unsetConfigOverride } from "./ssrf-q6hBiAOi.js";
17
+ import { C as unsetConfigValueAtPath, S as setConfigValueAtPath, T as VERSION, _ as resetConfigOverrides, b as getConfigValueAtPath, c as loadConfig, d as writeConfigFile, f as validateConfigObjectWithPlugins, g as getConfigOverrides, h as validateJsonSchemaValue, i as isBlockedHostnameOrIp, l as readConfigFileSnapshot, o as normalizeHostname, p as parseDurationMs, t as SsrFBlockedError, u as resolveConfigSnapshotHash, v as setConfigOverride, w as DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH, x as parseConfigPath, y as unsetConfigOverride } from "./ssrf-BCSnhba8.js";
18
18
  import { t as parseBooleanValue } from "./boolean-BW6OTjPi.js";
19
19
  import { i as resolveShellEnvFallbackTimeoutMs, n as getShellPathFromLoginShell, s as isTruthyEnvValue } from "./shell-env-DgjeObDZ.js";
20
20
  import { c as normalizePluginsConfig, f as isPathInsideWithRealpath, i as safeStatSync, l as resolveEnableState, n as discoverSymiPlugins, p as isDangerousHostEnvVarName, r as isPathInside, s as applyTestPluginDefaults, t as loadPluginManifestRegistry, u as resolveMemorySlotDecision } from "./manifest-registry-CAWGTwb5.js";
21
- import { C as rawDataToString, O as DEFAULT_AI_SNAPSHOT_MAX_CHARS, T as isSecureWebSocketUrl, x as ensureChromeExtensionRelayServer } from "./chrome-BKUACyeO.js";
21
+ import { C as rawDataToString, O as DEFAULT_AI_SNAPSHOT_MAX_CHARS, T as isSecureWebSocketUrl, x as ensureChromeExtensionRelayServer } from "./chrome-3jl2ulOE.js";
22
22
  import { n as resolveCliName, t as formatCliCommand } from "./command-format-DPd9RN2g.js";
23
23
  import { c as assertSandboxPath, d as resolveSandboxedMediaSource, f as applySkillEnvOverrides, h as parseFrontmatterBlock, i as resolveSkillsPromptForRun, l as resolveSandboxInputPath, n as buildWorkspaceSkillSnapshot, p as applySkillEnvOverridesFromSnapshot, r as loadWorkspaceSkillEntries, s as assertMediaNotDataUrl } from "./skills-DO7WNsVJ.js";
24
24
  import { n as redactToolDetail } from "./redact-DSOAcWMe.js";
@@ -29,12 +29,12 @@ import { n as resolveConversationLabel } from "./conversation-label-DTTqF8gH.js"
29
29
  import { i as resolveSessionTranscriptPath, n as resolveSessionFilePath, o as resolveSessionTranscriptsDirForAgent, r as resolveSessionFilePathOptions, s as resolveStorePath, t as resolveDefaultSessionStorePath } from "./paths-BsT3BvfH.js";
30
30
  import { t as emitSessionTranscriptUpdate } from "./transcript-events-ChU6IQwp.js";
31
31
  import { n as saveJsonFile, t as loadJsonFile } from "./json-file-B7D44OOV.js";
32
- import { a as parseGeminiAuth, c as resolveMemorySearchConfig, d as requireApiKey, f as resolveApiKeyForProvider, h as resolveModelAuthMode, i as resolveOllamaBaseUrl, l as getApiKeyForModel, m as resolveEnvApiKey, n as retryAsync, o as collectProviderApiKeysForExecution, p as resolveAwsSdkEnvVarName, r as probeOllamaEmbeddingModels, s as executeWithApiKeyRotation, u as getCustomProviderApiKey } from "./manager-rvtFoeFT.js";
32
+ import { a as parseGeminiAuth, c as resolveMemorySearchConfig, d as requireApiKey, f as resolveApiKeyForProvider, h as resolveModelAuthMode, i as resolveOllamaBaseUrl, l as getApiKeyForModel, m as resolveEnvApiKey, n as retryAsync, o as collectProviderApiKeysForExecution, p as resolveAwsSdkEnvVarName, r as probeOllamaEmbeddingModels, s as executeWithApiKeyRotation, u as getCustomProviderApiKey } from "./manager-CnBU0aOR.js";
33
33
  import { r as resolveCopilotApiToken, t as DEFAULT_COPILOT_API_BASE_URL } from "./github-copilot-token-dYUr1mDQ.js";
34
34
  import { c as normalizeExtraMemoryPaths, f as runTasksWithConcurrency, s as listMemoryFiles } from "./internal-Ce-sg7EN.js";
35
35
  import { n as resolveMarkdownTableMode } from "./markdown-tables-jQzXAsf3.js";
36
- import { a as shouldHandleTextCommands, c as resolveNativeCommandsEnabled, i as normalizeCommandBody, l as resolveNativeSkillsEnabled, n as listChatCommands, o as isCommandFlagEnabled, r as listChatCommandsForConfig, s as isRestartEnabled } from "./commands-registry-DFYDtKr_.js";
37
- import { c as getSkillsSnapshotVersion, d as createAsyncLock, f as readJsonFile$1, i as resolveSkillCommandInvocation, l as pruneExpiredPending, n as listSkillCommandsForAgents, o as getRemoteSkillEligibility, p as writeJsonAtomic, r as listSkillCommandsForWorkspace, s as ensureSkillsWatcher, t as listReservedChatSlashCommandNames, u as resolvePairingPaths } from "./skill-commands-CKm7eCw6.js";
36
+ import { a as shouldHandleTextCommands, c as resolveNativeCommandsEnabled, i as normalizeCommandBody, l as resolveNativeSkillsEnabled, n as listChatCommands, o as isCommandFlagEnabled, r as listChatCommandsForConfig, s as isRestartEnabled } from "./commands-registry-DG2kGyg5.js";
37
+ import { c as getSkillsSnapshotVersion, d as createAsyncLock, f as readJsonFile$1, i as resolveSkillCommandInvocation, l as pruneExpiredPending, n as listSkillCommandsForAgents, o as getRemoteSkillEligibility, p as writeJsonAtomic, r as listSkillCommandsForWorkspace, s as ensureSkillsWatcher, t as listReservedChatSlashCommandNames, u as resolvePairingPaths } from "./skill-commands-D0xAWG0l.js";
38
38
  import { r as normalizeInboundTextNewlines, t as finalizeInboundContext } from "./inbound-context-M0vxsAoa.js";
39
39
  import { n as discoverModels, t as discoverAuthStorage } from "./pi-model-discovery-CuZX_Q4t.js";
40
40
  import { n as resolveAgentRoute, t as buildAgentSessionKey } from "./resolve-route-0kL4oMLp.js";
@@ -53,7 +53,7 @@ import { fileURLToPath } from "node:url";
53
53
  import { CURRENT_SESSION_VERSION, DefaultResourceLoader, SessionManager, SettingsManager, codingTools, createAgentSession, createEditTool, createReadTool, createWriteTool, estimateTokens, generateSummary, readTool } from "@mariozechner/pi-coding-agent";
54
54
  import crypto, { X509Certificate, createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
55
55
  import AjvPkg from "ajv";
56
- import { WebSocket } from "ws";
56
+ import { WebSocket as WebSocket$1 } from "ws";
57
57
  import { Buffer as Buffer$1 } from "node:buffer";
58
58
  import { complete, createAssistantMessageEventStream, streamSimple } from "@mariozechner/pi-ai";
59
59
  import { BedrockClient, ListFoundationModelsCommand } from "@aws-sdk/client-bedrock";
@@ -3390,7 +3390,7 @@ async function getMemorySearchManager(params) {
3390
3390
  const wrapper = new FallbackMemoryManager({
3391
3391
  primary,
3392
3392
  fallbackFactory: async () => {
3393
- const { MemoryIndexManager } = await import("./manager-rvtFoeFT.js").then((n) => n.t);
3393
+ const { MemoryIndexManager } = await import("./manager-CnBU0aOR.js").then((n) => n.t);
3394
3394
  return await MemoryIndexManager.get(params);
3395
3395
  }
3396
3396
  }, () => QMD_MANAGER_CACHE.delete(cacheKey));
@@ -3403,7 +3403,7 @@ async function getMemorySearchManager(params) {
3403
3403
  }
3404
3404
  }
3405
3405
  try {
3406
- const { MemoryIndexManager } = await import("./manager-rvtFoeFT.js").then((n) => n.t);
3406
+ const { MemoryIndexManager } = await import("./manager-CnBU0aOR.js").then((n) => n.t);
3407
3407
  return { manager: await MemoryIndexManager.get(params) };
3408
3408
  } catch (err) {
3409
3409
  return {
@@ -5920,7 +5920,7 @@ var GatewayClient = class {
5920
5920
  if (fingerprint !== expected) return /* @__PURE__ */ new Error("gateway tls fingerprint mismatch");
5921
5921
  });
5922
5922
  }
5923
- this.ws = new WebSocket(url, wsOptions);
5923
+ this.ws = new WebSocket$1(url, wsOptions);
5924
5924
  this.ws.on("open", () => {
5925
5925
  if (url.startsWith("wss://") && this.opts.tlsFingerprint) {
5926
5926
  const tlsError = this.validateTlsFingerprint();
@@ -6139,7 +6139,7 @@ var GatewayClient = class {
6139
6139
  return null;
6140
6140
  }
6141
6141
  async request(method, params, opts) {
6142
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) throw new Error("gateway not connected");
6142
+ if (!this.ws || this.ws.readyState !== WebSocket$1.OPEN) throw new Error("gateway not connected");
6143
6143
  const id = randomUUID();
6144
6144
  const frame = {
6145
6145
  type: "req",
@@ -7087,7 +7087,7 @@ async function routeReply(params) {
7087
7087
  const resolvedReplyToId = replyToId ?? (channelId === "slack" && threadId != null && threadId !== "" ? String(threadId) : void 0);
7088
7088
  const resolvedThreadId = channelId === "slack" ? null : threadId ?? null;
7089
7089
  try {
7090
- const { deliverOutboundPayloads } = await import("./deliver-Cjyb6h4g.js").then((n) => n.n);
7090
+ const { deliverOutboundPayloads } = await import("./deliver-f3cIWxXT.js").then((n) => n.n);
7091
7091
  return {
7092
7092
  ok: true,
7093
7093
  messageId: (await deliverOutboundPayloads({
@@ -16084,13 +16084,21 @@ async function applyMediaUnderstanding(params) {
16084
16084
  * Soft warning appended when context usage crosses the threshold.
16085
16085
  * Fires once per session (tracked via `SessionEntry.contextWarningSent`).
16086
16086
  */
16087
- const SESSION_CONTEXT_WARNING_MESSAGE = "📋 Heads up — this session is approaching the context limit. Start a new session for best results. Past sessions stay in history and can be revisited there.";
16087
+ const SESSION_CONTEXT_WARNING_MESSAGE = "📋 Heads up — this session is approaching the context limit. Symi will compact older context automatically when usage reaches 90%.";
16088
16088
  /**
16089
- * Hard limit message returned when the model API rejects the turn for
16090
- * context-too-long or role-ordering reasons, and on every subsequent
16091
- * turn until the user starts a new session.
16089
+ * Inline status emitted by Symi before running compaction proactively
16090
+ * at the 90% threshold. Followed by the agent's actual response in the
16091
+ * same turn.
16092
16092
  */
16093
- const SESSION_OVERFLOW_MESSAGE = "📋 This session has reached the context limit. Please start a new session — your full conversation is saved in history and can be revisited there.";
16093
+ const SESSION_COMPACTING_MESSAGE = "📋 Context limit reached for this session. Compacting older context and continuing…";
16094
+ /**
16095
+ * Returned when compaction can't recover enough budget to continue —
16096
+ * either because the proactive compaction at 90% failed, or because a
16097
+ * single user message overshot the window in one turn and the reactive
16098
+ * fallback compaction also failed. Same message also short-circuits
16099
+ * subsequent turns until /reset or /new.
16100
+ */
16101
+ const SESSION_COMPACTION_FAILED_MESSAGE = "📋 Couldn't compact this session further. Please /reset or /new to continue — your full conversation is saved in history.";
16094
16102
 
16095
16103
  //#endregion
16096
16104
  //#region src/sessions/level-overrides.ts
@@ -24404,7 +24412,6 @@ function formatTokenCount$1(value) {
24404
24412
  function formatUsd(value) {
24405
24413
  if (value === void 0 || !Number.isFinite(value)) return;
24406
24414
  if (value >= 1) return `$${value.toFixed(2)}`;
24407
- if (value >= .01) return `$${value.toFixed(2)}`;
24408
24415
  return `$${value.toFixed(4)}`;
24409
24416
  }
24410
24417
  function resolveModelCostConfig(params) {
@@ -24479,13 +24486,13 @@ function resolveRuntimeLabel(args) {
24479
24486
  return sessionKey !== resolveMainSessionKey({ session: { scope: args.sessionScope ?? "per-sender" } }).trim();
24480
24487
  })() ? "docker" : sessionKey ? "direct" : "unknown"}/${sandboxMode}`;
24481
24488
  }
24482
- const formatTokens = (total, contextTokens) => {
24489
+ const formatTokens$1 = (total, contextTokens) => {
24483
24490
  const ctx = contextTokens ?? null;
24484
24491
  if (total == null) return `?/${ctx ? formatTokenCount(ctx) : "?"}`;
24485
24492
  const pct = ctx ? Math.min(999, Math.round(total / ctx * 100)) : null;
24486
24493
  return `${formatTokenCount(total)}/${ctx ? formatTokenCount(ctx) : "?"}${pct !== null ? ` (${pct}%)` : ""}`;
24487
24494
  };
24488
- const formatContextUsageShort = (total, contextTokens) => `Context ${formatTokens(total, contextTokens ?? null)}`;
24495
+ const formatContextUsageShort = (total, contextTokens) => `Context ${formatTokens$1(total, contextTokens ?? null)}`;
24489
24496
  const formatQueueDetails = (queue) => {
24490
24497
  if (!queue) return "";
24491
24498
  const depth = typeof queue.depth === "number" ? `depth ${queue.depth}` : null;
@@ -24637,7 +24644,7 @@ function buildStatusMessage(args) {
24637
24644
  const updatedAt = entry?.updatedAt;
24638
24645
  const sessionLine = [`Session: ${args.sessionKey ?? "unknown"}`, typeof updatedAt === "number" ? `updated ${formatTimeAgo(now - updatedAt)}` : "no activity"].filter(Boolean).join(" • ");
24639
24646
  const groupActivationValue = entry?.chatType === "group" || entry?.chatType === "channel" || Boolean(args.sessionKey?.includes(":group:")) || Boolean(args.sessionKey?.includes(":channel:")) ? args.groupActivation ?? entry?.groupActivation ?? "mention" : void 0;
24640
- const contextLine = [`Context: ${formatTokens(totalTokens, contextTokens ?? null)}`, `🧹 Compactions: ${entry?.compactionCount ?? 0}`].filter(Boolean).join(" · ");
24647
+ const contextLine = [`Context: ${formatTokens$1(totalTokens, contextTokens ?? null)}`, `🧹 Compactions: ${entry?.compactionCount ?? 0}`].filter(Boolean).join(" · ");
24641
24648
  const queueMode = args.queue?.mode ?? "unknown";
24642
24649
  const queueDetails = formatQueueDetails(args.queue);
24643
24650
  const verboseLabel = verboseLevel === "full" ? "verbose:full" : verboseLevel === "on" ? "verbose" : null;
@@ -24669,14 +24676,19 @@ function buildStatusMessage(args) {
24669
24676
  config: args.config
24670
24677
  }) : void 0;
24671
24678
  const hasUsage = typeof inputTokens === "number" || typeof outputTokens === "number";
24672
- const cost = showCost && hasUsage ? estimateUsageCost({
24679
+ const rawCost = showCost && hasUsage ? estimateUsageCost({
24673
24680
  usage: {
24674
24681
  input: inputTokens ?? void 0,
24675
24682
  output: outputTokens ?? void 0
24676
24683
  },
24677
24684
  cost: costConfig
24678
24685
  }) : void 0;
24679
- const costLabel = showCost && hasUsage ? formatUsd(cost) : void 0;
24686
+ const useOverride = showCost && hasUsage && typeof args.costOverrideUsd === "number" && (rawCost === void 0 || rawCost === 0);
24687
+ const cost = useOverride ? args.costOverrideUsd : rawCost;
24688
+ const baseLabel = showCost && hasUsage ? formatUsd(cost) : void 0;
24689
+ const tag = useOverride ? " (self-hosted)" : "";
24690
+ const suffix = args.costLineSuffix ? ` · ${args.costLineSuffix}` : "";
24691
+ const costLabel = baseLabel ? `${baseLabel}${tag}${suffix}` : void 0;
24680
24692
  const selectedAuthLabel = selectedAuthLabelValue ? ` · 🔑 ${selectedAuthLabelValue}` : "";
24681
24693
  const channelModelNote = (() => {
24682
24694
  if (!args.config || !entry) return;
@@ -24721,6 +24733,8 @@ function buildStatusMessage(args) {
24721
24733
  fallbackLine,
24722
24734
  usageCostLine,
24723
24735
  cacheLine,
24736
+ args.engineLine,
24737
+ args.hardwareLine,
24724
24738
  `📚 ${contextLine}`,
24725
24739
  mediaLine,
24726
24740
  args.usageLine,
@@ -25297,6 +25311,606 @@ const handleDebugCommand = async (params, allowTextCommands) => {
25297
25311
  return null;
25298
25312
  };
25299
25313
 
25314
+ //#endregion
25315
+ //#region src/infra/session-cost-usage.ts
25316
+ const emptyTotals = () => ({
25317
+ input: 0,
25318
+ output: 0,
25319
+ cacheRead: 0,
25320
+ cacheWrite: 0,
25321
+ totalTokens: 0,
25322
+ totalCost: 0,
25323
+ inputCost: 0,
25324
+ outputCost: 0,
25325
+ cacheReadCost: 0,
25326
+ cacheWriteCost: 0,
25327
+ missingCostEntries: 0
25328
+ });
25329
+ const toFiniteNumber = (value) => {
25330
+ if (typeof value !== "number") return;
25331
+ if (!Number.isFinite(value)) return;
25332
+ return value;
25333
+ };
25334
+ const extractCostBreakdown = (usageRaw) => {
25335
+ if (!usageRaw || typeof usageRaw !== "object") return;
25336
+ const cost = usageRaw.cost;
25337
+ if (!cost) return;
25338
+ const total = toFiniteNumber(cost.total);
25339
+ if (total === void 0 || total < 0) return;
25340
+ return {
25341
+ total,
25342
+ input: toFiniteNumber(cost.input),
25343
+ output: toFiniteNumber(cost.output),
25344
+ cacheRead: toFiniteNumber(cost.cacheRead),
25345
+ cacheWrite: toFiniteNumber(cost.cacheWrite)
25346
+ };
25347
+ };
25348
+ const parseTimestamp = (entry) => {
25349
+ const raw = entry.timestamp;
25350
+ if (typeof raw === "string") {
25351
+ const parsed = new Date(raw);
25352
+ if (!Number.isNaN(parsed.valueOf())) return parsed;
25353
+ }
25354
+ const message = entry.message;
25355
+ const messageTimestamp = toFiniteNumber(message?.timestamp);
25356
+ if (messageTimestamp !== void 0) {
25357
+ const parsed = new Date(messageTimestamp);
25358
+ if (!Number.isNaN(parsed.valueOf())) return parsed;
25359
+ }
25360
+ };
25361
+ const parseTranscriptEntry = (entry) => {
25362
+ const message = entry.message;
25363
+ if (!message || typeof message !== "object") return null;
25364
+ const roleRaw = message.role;
25365
+ const role = roleRaw === "user" || roleRaw === "assistant" ? roleRaw : void 0;
25366
+ if (!role) return null;
25367
+ const usageRaw = message.usage ?? entry.usage;
25368
+ const usage = usageRaw ? normalizeUsage(usageRaw) ?? void 0 : void 0;
25369
+ const provider = (typeof message.provider === "string" ? message.provider : void 0) ?? (typeof entry.provider === "string" ? entry.provider : void 0);
25370
+ const model = (typeof message.model === "string" ? message.model : void 0) ?? (typeof entry.model === "string" ? entry.model : void 0);
25371
+ const costBreakdown = extractCostBreakdown(usageRaw);
25372
+ const stopReason = typeof message.stopReason === "string" ? message.stopReason : void 0;
25373
+ const durationMs = toFiniteNumber(message.durationMs ?? entry.durationMs);
25374
+ return {
25375
+ message,
25376
+ role,
25377
+ timestamp: parseTimestamp(entry),
25378
+ durationMs,
25379
+ usage,
25380
+ costTotal: costBreakdown?.total,
25381
+ costBreakdown,
25382
+ provider,
25383
+ model,
25384
+ stopReason,
25385
+ toolNames: extractToolCallNames(message),
25386
+ toolResultCounts: countToolResults(message)
25387
+ };
25388
+ };
25389
+ const formatDayKey = (date) => date.toLocaleDateString("en-CA", { timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone });
25390
+ const computeLatencyStats = (values) => {
25391
+ if (!values.length) return;
25392
+ const sorted = values.toSorted((a, b) => a - b);
25393
+ const total = sorted.reduce((sum, v) => sum + v, 0);
25394
+ const count = sorted.length;
25395
+ const p95Index = Math.max(0, Math.ceil(count * .95) - 1);
25396
+ return {
25397
+ count,
25398
+ avgMs: total / count,
25399
+ p95Ms: sorted[p95Index] ?? sorted[count - 1],
25400
+ minMs: sorted[0],
25401
+ maxMs: sorted[count - 1]
25402
+ };
25403
+ };
25404
+ const applyUsageTotals = (totals, usage) => {
25405
+ totals.input += usage.input ?? 0;
25406
+ totals.output += usage.output ?? 0;
25407
+ totals.cacheRead += usage.cacheRead ?? 0;
25408
+ totals.cacheWrite += usage.cacheWrite ?? 0;
25409
+ const totalTokens = usage.total ?? (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
25410
+ totals.totalTokens += totalTokens;
25411
+ };
25412
+ const applyCostBreakdown = (totals, costBreakdown) => {
25413
+ if (costBreakdown === void 0 || costBreakdown.total === void 0) return;
25414
+ totals.totalCost += costBreakdown.total;
25415
+ totals.inputCost += costBreakdown.input ?? 0;
25416
+ totals.outputCost += costBreakdown.output ?? 0;
25417
+ totals.cacheReadCost += costBreakdown.cacheRead ?? 0;
25418
+ totals.cacheWriteCost += costBreakdown.cacheWrite ?? 0;
25419
+ };
25420
+ const applyCostTotal = (totals, costTotal) => {
25421
+ if (costTotal === void 0) {
25422
+ totals.missingCostEntries += 1;
25423
+ return;
25424
+ }
25425
+ totals.totalCost += costTotal;
25426
+ };
25427
+ async function* readJsonlRecords(filePath) {
25428
+ const fileStream = fs.createReadStream(filePath, { encoding: "utf-8" });
25429
+ const rl = readline.createInterface({
25430
+ input: fileStream,
25431
+ crlfDelay: Infinity
25432
+ });
25433
+ try {
25434
+ for await (const line of rl) {
25435
+ const trimmed = line.trim();
25436
+ if (!trimmed) continue;
25437
+ try {
25438
+ const parsed = JSON.parse(trimmed);
25439
+ if (!parsed || typeof parsed !== "object") continue;
25440
+ yield parsed;
25441
+ } catch {}
25442
+ }
25443
+ } finally {
25444
+ rl.close();
25445
+ fileStream.destroy();
25446
+ }
25447
+ }
25448
+ async function scanTranscriptFile(params) {
25449
+ for await (const parsed of readJsonlRecords(params.filePath)) {
25450
+ const entry = parseTranscriptEntry(parsed);
25451
+ if (!entry) continue;
25452
+ if (entry.usage && entry.costTotal === void 0) {
25453
+ const cost = resolveModelCostConfig({
25454
+ provider: entry.provider,
25455
+ model: entry.model,
25456
+ config: params.config
25457
+ });
25458
+ entry.costTotal = estimateUsageCost({
25459
+ usage: entry.usage,
25460
+ cost
25461
+ });
25462
+ }
25463
+ params.onEntry(entry);
25464
+ }
25465
+ }
25466
+ async function scanUsageFile(params) {
25467
+ await scanTranscriptFile({
25468
+ filePath: params.filePath,
25469
+ config: params.config,
25470
+ onEntry: (entry) => {
25471
+ if (!entry.usage) return;
25472
+ params.onEntry({
25473
+ usage: entry.usage,
25474
+ costTotal: entry.costTotal,
25475
+ costBreakdown: entry.costBreakdown,
25476
+ provider: entry.provider,
25477
+ model: entry.model,
25478
+ timestamp: entry.timestamp
25479
+ });
25480
+ }
25481
+ });
25482
+ }
25483
+ async function loadCostUsageSummary(params) {
25484
+ const now = /* @__PURE__ */ new Date();
25485
+ let sinceTime;
25486
+ let untilTime;
25487
+ if (params?.startMs !== void 0 && params?.endMs !== void 0) {
25488
+ sinceTime = params.startMs;
25489
+ untilTime = params.endMs;
25490
+ } else {
25491
+ const days = Math.max(1, Math.floor(params?.days ?? 30));
25492
+ const since = new Date(now);
25493
+ since.setDate(since.getDate() - (days - 1));
25494
+ sinceTime = since.getTime();
25495
+ untilTime = now.getTime();
25496
+ }
25497
+ const dailyMap = /* @__PURE__ */ new Map();
25498
+ const totals = emptyTotals();
25499
+ const sessionsDir = resolveSessionTranscriptsDirForAgent(params?.agentId);
25500
+ const entries = await fs.promises.readdir(sessionsDir, { withFileTypes: true }).catch(() => []);
25501
+ const files = (await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map(async (entry) => {
25502
+ const filePath = path.join(sessionsDir, entry.name);
25503
+ const stats = await fs.promises.stat(filePath).catch(() => null);
25504
+ if (!stats) return null;
25505
+ if (stats.mtimeMs < sinceTime) return null;
25506
+ return filePath;
25507
+ }))).filter((filePath) => Boolean(filePath));
25508
+ for (const filePath of files) await scanUsageFile({
25509
+ filePath,
25510
+ config: params?.config,
25511
+ onEntry: (entry) => {
25512
+ const ts = entry.timestamp?.getTime();
25513
+ if (!ts || ts < sinceTime || ts > untilTime) return;
25514
+ const dayKey = formatDayKey(entry.timestamp ?? now);
25515
+ const bucket = dailyMap.get(dayKey) ?? emptyTotals();
25516
+ applyUsageTotals(bucket, entry.usage);
25517
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(bucket, entry.costBreakdown);
25518
+ else applyCostTotal(bucket, entry.costTotal);
25519
+ dailyMap.set(dayKey, bucket);
25520
+ applyUsageTotals(totals, entry.usage);
25521
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
25522
+ else applyCostTotal(totals, entry.costTotal);
25523
+ }
25524
+ });
25525
+ const daily = Array.from(dailyMap.entries()).map(([date, bucket]) => Object.assign({ date }, bucket)).toSorted((a, b) => a.date.localeCompare(b.date));
25526
+ const days = Math.ceil((untilTime - sinceTime) / (1440 * 60 * 1e3)) + 1;
25527
+ return {
25528
+ updatedAt: Date.now(),
25529
+ days,
25530
+ daily,
25531
+ totals
25532
+ };
25533
+ }
25534
+ async function loadSessionCostSummary(params) {
25535
+ const sessionFile = params.sessionFile ?? (params.sessionId ? resolveSessionFilePath(params.sessionId, params.sessionEntry, { agentId: params.agentId }) : void 0);
25536
+ if (!sessionFile || !fs.existsSync(sessionFile)) return null;
25537
+ const totals = emptyTotals();
25538
+ let firstActivity;
25539
+ let lastActivity;
25540
+ const activityDatesSet = /* @__PURE__ */ new Set();
25541
+ const dailyMap = /* @__PURE__ */ new Map();
25542
+ const dailyMessageMap = /* @__PURE__ */ new Map();
25543
+ const dailyLatencyMap = /* @__PURE__ */ new Map();
25544
+ const dailyModelUsageMap = /* @__PURE__ */ new Map();
25545
+ const messageCounts = {
25546
+ total: 0,
25547
+ user: 0,
25548
+ assistant: 0,
25549
+ toolCalls: 0,
25550
+ toolResults: 0,
25551
+ errors: 0
25552
+ };
25553
+ const toolUsageMap = /* @__PURE__ */ new Map();
25554
+ const modelUsageMap = /* @__PURE__ */ new Map();
25555
+ const errorStopReasons = new Set([
25556
+ "error",
25557
+ "aborted",
25558
+ "timeout"
25559
+ ]);
25560
+ const latencyValues = [];
25561
+ let lastUserTimestamp;
25562
+ const MAX_LATENCY_MS = 720 * 60 * 1e3;
25563
+ await scanTranscriptFile({
25564
+ filePath: sessionFile,
25565
+ config: params.config,
25566
+ onEntry: (entry) => {
25567
+ const ts = entry.timestamp?.getTime();
25568
+ if (params.startMs !== void 0 && ts !== void 0 && ts < params.startMs) return;
25569
+ if (params.endMs !== void 0 && ts !== void 0 && ts > params.endMs) return;
25570
+ if (ts !== void 0) {
25571
+ if (!firstActivity || ts < firstActivity) firstActivity = ts;
25572
+ if (!lastActivity || ts > lastActivity) lastActivity = ts;
25573
+ }
25574
+ if (entry.role === "user") {
25575
+ messageCounts.user += 1;
25576
+ messageCounts.total += 1;
25577
+ if (entry.timestamp) lastUserTimestamp = entry.timestamp.getTime();
25578
+ }
25579
+ if (entry.role === "assistant") {
25580
+ messageCounts.assistant += 1;
25581
+ messageCounts.total += 1;
25582
+ const ts = entry.timestamp?.getTime();
25583
+ if (ts !== void 0) {
25584
+ const latencyMs = entry.durationMs ?? (lastUserTimestamp !== void 0 ? Math.max(0, ts - lastUserTimestamp) : void 0);
25585
+ if (latencyMs !== void 0 && Number.isFinite(latencyMs) && latencyMs <= MAX_LATENCY_MS) {
25586
+ latencyValues.push(latencyMs);
25587
+ const dayKey = formatDayKey(entry.timestamp ?? new Date(ts));
25588
+ const dailyLatencies = dailyLatencyMap.get(dayKey) ?? [];
25589
+ dailyLatencies.push(latencyMs);
25590
+ dailyLatencyMap.set(dayKey, dailyLatencies);
25591
+ }
25592
+ }
25593
+ }
25594
+ if (entry.toolNames.length > 0) {
25595
+ messageCounts.toolCalls += entry.toolNames.length;
25596
+ for (const name of entry.toolNames) toolUsageMap.set(name, (toolUsageMap.get(name) ?? 0) + 1);
25597
+ }
25598
+ if (entry.toolResultCounts.total > 0) {
25599
+ messageCounts.toolResults += entry.toolResultCounts.total;
25600
+ messageCounts.errors += entry.toolResultCounts.errors;
25601
+ }
25602
+ if (entry.stopReason && errorStopReasons.has(entry.stopReason)) messageCounts.errors += 1;
25603
+ if (entry.timestamp) {
25604
+ const dayKey = formatDayKey(entry.timestamp);
25605
+ activityDatesSet.add(dayKey);
25606
+ const daily = dailyMessageMap.get(dayKey) ?? {
25607
+ date: dayKey,
25608
+ total: 0,
25609
+ user: 0,
25610
+ assistant: 0,
25611
+ toolCalls: 0,
25612
+ toolResults: 0,
25613
+ errors: 0
25614
+ };
25615
+ daily.total += entry.role === "user" || entry.role === "assistant" ? 1 : 0;
25616
+ if (entry.role === "user") daily.user += 1;
25617
+ else if (entry.role === "assistant") daily.assistant += 1;
25618
+ daily.toolCalls += entry.toolNames.length;
25619
+ daily.toolResults += entry.toolResultCounts.total;
25620
+ daily.errors += entry.toolResultCounts.errors;
25621
+ if (entry.stopReason && errorStopReasons.has(entry.stopReason)) daily.errors += 1;
25622
+ dailyMessageMap.set(dayKey, daily);
25623
+ }
25624
+ if (!entry.usage) return;
25625
+ applyUsageTotals(totals, entry.usage);
25626
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
25627
+ else applyCostTotal(totals, entry.costTotal);
25628
+ if (entry.timestamp) {
25629
+ const dayKey = formatDayKey(entry.timestamp);
25630
+ const entryTokens = (entry.usage.input ?? 0) + (entry.usage.output ?? 0) + (entry.usage.cacheRead ?? 0) + (entry.usage.cacheWrite ?? 0);
25631
+ const entryCost = entry.costBreakdown?.total ?? (entry.costBreakdown ? (entry.costBreakdown.input ?? 0) + (entry.costBreakdown.output ?? 0) + (entry.costBreakdown.cacheRead ?? 0) + (entry.costBreakdown.cacheWrite ?? 0) : entry.costTotal ?? 0);
25632
+ const existing = dailyMap.get(dayKey) ?? {
25633
+ tokens: 0,
25634
+ cost: 0
25635
+ };
25636
+ dailyMap.set(dayKey, {
25637
+ tokens: existing.tokens + entryTokens,
25638
+ cost: existing.cost + entryCost
25639
+ });
25640
+ if (entry.provider || entry.model) {
25641
+ const modelKey = `${dayKey}::${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
25642
+ const dailyModel = dailyModelUsageMap.get(modelKey) ?? {
25643
+ date: dayKey,
25644
+ provider: entry.provider,
25645
+ model: entry.model,
25646
+ tokens: 0,
25647
+ cost: 0,
25648
+ count: 0
25649
+ };
25650
+ dailyModel.tokens += entryTokens;
25651
+ dailyModel.cost += entryCost;
25652
+ dailyModel.count += 1;
25653
+ dailyModelUsageMap.set(modelKey, dailyModel);
25654
+ }
25655
+ }
25656
+ if (entry.provider || entry.model) {
25657
+ const key = `${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
25658
+ const existing = modelUsageMap.get(key) ?? {
25659
+ provider: entry.provider,
25660
+ model: entry.model,
25661
+ count: 0,
25662
+ totals: emptyTotals()
25663
+ };
25664
+ existing.count += 1;
25665
+ applyUsageTotals(existing.totals, entry.usage);
25666
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(existing.totals, entry.costBreakdown);
25667
+ else applyCostTotal(existing.totals, entry.costTotal);
25668
+ modelUsageMap.set(key, existing);
25669
+ }
25670
+ }
25671
+ });
25672
+ const dailyBreakdown = Array.from(dailyMap.entries()).map(([date, data]) => ({
25673
+ date,
25674
+ tokens: data.tokens,
25675
+ cost: data.cost
25676
+ })).toSorted((a, b) => a.date.localeCompare(b.date));
25677
+ const dailyMessageCounts = Array.from(dailyMessageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date));
25678
+ const dailyLatency = Array.from(dailyLatencyMap.entries()).map(([date, values]) => {
25679
+ const stats = computeLatencyStats(values);
25680
+ if (!stats) return null;
25681
+ return {
25682
+ date,
25683
+ ...stats
25684
+ };
25685
+ }).filter((entry) => Boolean(entry)).toSorted((a, b) => a.date.localeCompare(b.date));
25686
+ const dailyModelUsage = Array.from(dailyModelUsageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date) || b.cost - a.cost);
25687
+ const toolUsage = toolUsageMap.size ? {
25688
+ totalCalls: Array.from(toolUsageMap.values()).reduce((sum, count) => sum + count, 0),
25689
+ uniqueTools: toolUsageMap.size,
25690
+ tools: Array.from(toolUsageMap.entries()).map(([name, count]) => ({
25691
+ name,
25692
+ count
25693
+ })).toSorted((a, b) => b.count - a.count)
25694
+ } : void 0;
25695
+ const modelUsage = modelUsageMap.size ? Array.from(modelUsageMap.values()).toSorted((a, b) => {
25696
+ const costDiff = b.totals.totalCost - a.totals.totalCost;
25697
+ if (costDiff !== 0) return costDiff;
25698
+ return b.totals.totalTokens - a.totals.totalTokens;
25699
+ }) : void 0;
25700
+ return {
25701
+ sessionId: params.sessionId,
25702
+ sessionFile,
25703
+ firstActivity,
25704
+ lastActivity,
25705
+ durationMs: firstActivity !== void 0 && lastActivity !== void 0 ? Math.max(0, lastActivity - firstActivity) : void 0,
25706
+ activityDates: Array.from(activityDatesSet).toSorted(),
25707
+ dailyBreakdown,
25708
+ dailyMessageCounts,
25709
+ dailyLatency: dailyLatency.length ? dailyLatency : void 0,
25710
+ dailyModelUsage: dailyModelUsage.length ? dailyModelUsage : void 0,
25711
+ messageCounts,
25712
+ toolUsage,
25713
+ modelUsage,
25714
+ latency: computeLatencyStats(latencyValues),
25715
+ ...totals
25716
+ };
25717
+ }
25718
+
25719
+ //#endregion
25720
+ //#region src/cost/benchmark.ts
25721
+ /**
25722
+ * Claude reference rates and benchmark comparison.
25723
+ *
25724
+ * Hardcoded per-token USD rates for Claude Opus 4.7, Sonnet 4.6, and
25725
+ * Haiku 4.5 (per million tokens, Anthropic public list as of 2026-Q1).
25726
+ * Override via `models.gpuRates` is for GPU rates only — Claude rates can
25727
+ * be overridden via the per-model `cost: { input, output }` configuration
25728
+ * on the user's `anthropic` provider entry, which already exists.
25729
+ *
25730
+ * Display: pick a target tier via `agents.defaults.cost.benchmark`, default
25731
+ * `sonnet`. Setting `"all"` shows comparisons against all three tiers.
25732
+ */
25733
+ /** Per-million-token USD rates, applied via `estimateUsageCost`. */
25734
+ const CLAUDE_RATES = {
25735
+ opus: {
25736
+ input: 15,
25737
+ output: 75,
25738
+ cacheRead: 1.5,
25739
+ cacheWrite: 18.75
25740
+ },
25741
+ sonnet: {
25742
+ input: 3,
25743
+ output: 15,
25744
+ cacheRead: .3,
25745
+ cacheWrite: 3.75
25746
+ },
25747
+ haiku: {
25748
+ input: .8,
25749
+ output: 4,
25750
+ cacheRead: .08,
25751
+ cacheWrite: 1
25752
+ }
25753
+ };
25754
+ const CLAUDE_LABEL = {
25755
+ opus: "Claude Opus 4.7",
25756
+ sonnet: "Claude Sonnet 4.6",
25757
+ haiku: "Claude Haiku 4.5"
25758
+ };
25759
+ function benchmarkUsage(args) {
25760
+ if (!args.usage) return [];
25761
+ const tiers = args.target === "all" ? [
25762
+ "opus",
25763
+ "sonnet",
25764
+ "haiku"
25765
+ ] : [args.target];
25766
+ const results = [];
25767
+ for (const tier of tiers) {
25768
+ const cost = estimateUsageCost({
25769
+ usage: args.usage,
25770
+ cost: CLAUDE_RATES[tier]
25771
+ });
25772
+ if (cost === void 0) continue;
25773
+ results.push({
25774
+ tier,
25775
+ costUsd: cost
25776
+ });
25777
+ }
25778
+ return results;
25779
+ }
25780
+ function formatBenchmarkSuffix(args) {
25781
+ if (args.benchmarks.length === 0) return;
25782
+ if (args.benchmarks.length === 1) {
25783
+ const b = args.benchmarks[0];
25784
+ return formatPair(args.ourCostUsd, b);
25785
+ }
25786
+ const parts = [];
25787
+ for (const b of args.benchmarks) parts.push(`${shortLabel(b.tier)} $${formatCostShort(b.costUsd)}`);
25788
+ const cheapest = args.benchmarks.reduce((min, b) => b.costUsd < min.costUsd ? b : min);
25789
+ if (cheapest.costUsd > args.ourCostUsd && cheapest.costUsd > 0) {
25790
+ const savedPct = (cheapest.costUsd - args.ourCostUsd) / cheapest.costUsd * 100;
25791
+ if (savedPct >= 1) parts.push(`save ${savedPct.toFixed(0)}% vs ${shortLabel(cheapest.tier)}`);
25792
+ }
25793
+ return `vs ${parts.join(" / ")}`;
25794
+ }
25795
+ function formatPair(ourCost, b) {
25796
+ const benchPart = `${CLAUDE_LABEL[b.tier]} would be $${formatCostShort(b.costUsd)}`;
25797
+ if (b.costUsd > 0 && b.costUsd > ourCost) {
25798
+ const saved = (b.costUsd - ourCost) / b.costUsd * 100;
25799
+ if (saved >= 1) return `${benchPart} (save ${saved.toFixed(0)}%)`;
25800
+ } else if (b.costUsd > 0 && ourCost > b.costUsd) {
25801
+ const overspend = (ourCost - b.costUsd) / b.costUsd * 100;
25802
+ if (overspend >= 1) return `${benchPart} (+${overspend.toFixed(0)}%)`;
25803
+ }
25804
+ return benchPart;
25805
+ }
25806
+ function shortLabel(tier) {
25807
+ if (tier === "opus") return "Opus";
25808
+ if (tier === "sonnet") return "Sonnet";
25809
+ return "Haiku";
25810
+ }
25811
+ function formatCostShort(value) {
25812
+ if (value >= 1) return value.toFixed(2);
25813
+ return value.toFixed(4);
25814
+ }
25815
+ function isClaudeTier(value) {
25816
+ return value === "opus" || value === "sonnet" || value === "haiku";
25817
+ }
25818
+ function isBenchmarkTarget(value) {
25819
+ return isClaudeTier(value) || value === "all";
25820
+ }
25821
+ function resolveBenchmarkTarget(value) {
25822
+ if (typeof value === "string" && isBenchmarkTarget(value)) return value;
25823
+ return "sonnet";
25824
+ }
25825
+
25826
+ //#endregion
25827
+ //#region src/cost/summary.ts
25828
+ async function loadCostBenchmarkSummary(params) {
25829
+ const summary = await loadCostUsageSummary(params);
25830
+ const daily = summary.daily.map((day) => ({
25831
+ ...day,
25832
+ benchmarkUsd: computeBenchmarkPerTier(day)
25833
+ }));
25834
+ const benchmarkTotals = computeBenchmarkPerTier(summary.totals);
25835
+ const savingsTotals = {
25836
+ opus: benchmarkTotals.opus - summary.totals.totalCost,
25837
+ sonnet: benchmarkTotals.sonnet - summary.totals.totalCost,
25838
+ haiku: benchmarkTotals.haiku - summary.totals.totalCost
25839
+ };
25840
+ return {
25841
+ ...summary,
25842
+ daily,
25843
+ benchmarkTotals,
25844
+ savingsTotals
25845
+ };
25846
+ }
25847
+ function computeBenchmarkPerTier(totals) {
25848
+ const all = benchmarkUsage({
25849
+ usage: {
25850
+ input: totals.input,
25851
+ output: totals.output,
25852
+ cacheRead: totals.cacheRead,
25853
+ cacheWrite: totals.cacheWrite
25854
+ },
25855
+ target: "all"
25856
+ });
25857
+ const map = new Map(all.map((b) => [b.tier, b.costUsd]));
25858
+ return {
25859
+ opus: map.get("opus") ?? 0,
25860
+ sonnet: map.get("sonnet") ?? 0,
25861
+ haiku: map.get("haiku") ?? 0
25862
+ };
25863
+ }
25864
+ function resolveWindow(window, now = Date.now()) {
25865
+ const end = now;
25866
+ switch (window) {
25867
+ case "today": {
25868
+ const d = new Date(end);
25869
+ d.setHours(0, 0, 0, 0);
25870
+ return {
25871
+ startMs: d.getTime(),
25872
+ endMs: end
25873
+ };
25874
+ }
25875
+ case "week": return {
25876
+ startMs: end - 10080 * 6e4,
25877
+ endMs: end
25878
+ };
25879
+ case "month": return {
25880
+ startMs: end - 720 * 60 * 6e4,
25881
+ endMs: end
25882
+ };
25883
+ case "all": return {
25884
+ startMs: 0,
25885
+ endMs: end
25886
+ };
25887
+ }
25888
+ }
25889
+ function formatSummaryReport(summary, label) {
25890
+ const t = summary.totals;
25891
+ const b = summary.benchmarkTotals;
25892
+ const lines = [];
25893
+ if (label) lines.push(`# ${label}`);
25894
+ lines.push(`Tokens: ${formatTokens(t.totalTokens)} (${formatTokens(t.input)} in / ${formatTokens(t.output)} out)`);
25895
+ lines.push(`Spend: $${t.totalCost.toFixed(4)}`);
25896
+ lines.push(`Claude equivalents:`);
25897
+ lines.push(` Opus: $${b.opus.toFixed(4)} (saved $${(b.opus - t.totalCost).toFixed(4)})`);
25898
+ lines.push(` Sonnet: $${b.sonnet.toFixed(4)} (saved $${(b.sonnet - t.totalCost).toFixed(4)})`);
25899
+ lines.push(` Haiku: $${b.haiku.toFixed(4)} (saved $${(b.haiku - t.totalCost).toFixed(4)})`);
25900
+ if (summary.daily.length > 0) {
25901
+ lines.push("");
25902
+ lines.push("Daily:");
25903
+ for (const d of summary.daily.slice(-7)) lines.push(` ${d.date}: ${formatTokens(d.totalTokens).padStart(8)} tokens · $${d.totalCost.toFixed(4).padStart(8)} · vs Sonnet $${d.benchmarkUsd.sonnet.toFixed(4)}`);
25904
+ }
25905
+ return lines.join("\n");
25906
+ }
25907
+ function formatTokens(n) {
25908
+ if (!Number.isFinite(n) || n <= 0) return "0";
25909
+ if (n >= 1e6) return `${(n / 1e6).toFixed(1)}m`;
25910
+ if (n >= 1e3) return `${(n / 1e3).toFixed(n >= 1e4 ? 0 : 1)}k`;
25911
+ return String(Math.round(n));
25912
+ }
25913
+
25300
25914
  //#endregion
25301
25915
  //#region src/agents/system-prompt-report.ts
25302
25916
  function extractBetween(input, startMarker, endMarker) {
@@ -26417,6 +27031,560 @@ async function buildExportSessionReply(params) {
26417
27031
  ].join("\n") };
26418
27032
  }
26419
27033
 
27034
+ //#endregion
27035
+ //#region src/cost/rates.ts
27036
+ const GPU_VRAM_GB = {
27037
+ "a100-40gb": 40,
27038
+ "a100-80gb": 80,
27039
+ "h100-pcie": 80,
27040
+ "h100-sxm": 80,
27041
+ h200: 141,
27042
+ l40: 48,
27043
+ l40s: 48,
27044
+ a40: 48,
27045
+ a6000: 48,
27046
+ a5000: 24,
27047
+ v100: 32,
27048
+ mi300x: 192,
27049
+ "rtx-4090": 24
27050
+ };
27051
+ const GPU_LABEL = {
27052
+ "a100-40gb": "A100-40GB",
27053
+ "a100-80gb": "A100-80GB",
27054
+ "h100-pcie": "H100-PCIe",
27055
+ "h100-sxm": "H100-SXM",
27056
+ h200: "H200",
27057
+ l40: "L40",
27058
+ l40s: "L40S",
27059
+ a40: "A40",
27060
+ a6000: "RTX-A6000",
27061
+ a5000: "RTX-A5000",
27062
+ v100: "V100",
27063
+ mi300x: "MI300X",
27064
+ "rtx-4090": "RTX-4090"
27065
+ };
27066
+ const DEFAULT_HOURLY_RATES_USD = {
27067
+ "a100-40gb": 2.06,
27068
+ "a100-80gb": 2.21,
27069
+ "h100-pcie": 4.25,
27070
+ "h100-sxm": 4.76,
27071
+ h200: 6.5,
27072
+ l40: 1.27,
27073
+ l40s: 1.35,
27074
+ a40: .95,
27075
+ a6000: .96,
27076
+ a5000: .61,
27077
+ v100: .8,
27078
+ mi300x: 4.89,
27079
+ "rtx-4090": .74
27080
+ };
27081
+ /**
27082
+ * Rough decode (output) throughput defaults in tokens/sec for a 27-30B FP8
27083
+ * model on a single GPU of each type. Scales roughly inversely with model
27084
+ * parameter count and bytes-per-param. Used as a fallback when no live
27085
+ * `vllm:generation_tokens_total` delta has been observed yet.
27086
+ *
27087
+ * These are conservative published-benchmark medians; treat as ballpark.
27088
+ * Override via `models.gpuRates` is rate-only; throughput overrides are
27089
+ * Phase 4+ (not yet wired to config).
27090
+ */
27091
+ const DEFAULT_DECODE_TPS = {
27092
+ "a100-40gb": 60,
27093
+ "a100-80gb": 80,
27094
+ "h100-pcie": 120,
27095
+ "h100-sxm": 130,
27096
+ h200: 160,
27097
+ l40: 45,
27098
+ l40s: 50,
27099
+ a40: 40,
27100
+ a6000: 35,
27101
+ a5000: 25,
27102
+ v100: 25,
27103
+ mi300x: 110,
27104
+ "rtx-4090": 55
27105
+ };
27106
+ /**
27107
+ * Prefill throughput is typically 30-60× higher than decode for a given
27108
+ * setup. Use 40× as a balanced midpoint.
27109
+ */
27110
+ const PREFILL_DECODE_RATIO = 40;
27111
+ function resolveDefaultDecodeTps(gpuType, paramsB, bytesPerParam) {
27112
+ const baseline = DEFAULT_DECODE_TPS[gpuType];
27113
+ if (!paramsB) return baseline;
27114
+ const refBytes = 27;
27115
+ const modelBytes = paramsB * (bytesPerParam ?? 2);
27116
+ if (modelBytes <= 0) return baseline;
27117
+ const scaled = baseline * (refBytes / modelBytes);
27118
+ return Math.max(5, scaled);
27119
+ }
27120
+ function resolveHourlyRate(gpuType, overrides) {
27121
+ if (overrides && typeof overrides[gpuType] === "number" && overrides[gpuType] >= 0) return overrides[gpuType];
27122
+ return DEFAULT_HOURLY_RATES_USD[gpuType];
27123
+ }
27124
+
27125
+ //#endregion
27126
+ //#region src/cost/gpu-inference.ts
27127
+ /**
27128
+ * Heuristic GPU type + count inference for self-hosted serving endpoints.
27129
+ *
27130
+ * Two signals: the baseUrl hostname (often encodes "a100", "h100", etc.) and
27131
+ * the model id (encodes parameter count + quantization, e.g. "qwen36-27b-fp8").
27132
+ * Output is a confidence-tagged guess so downstream code (and the user) can
27133
+ * decide whether to trust the inference or override it.
27134
+ *
27135
+ * Bytes-per-parameter table:
27136
+ * fp32 → 4
27137
+ * fp16/bf16 → 2 (default when unspecified)
27138
+ * fp8/int8/q8 → 1
27139
+ * int4/q4/fp4 → 0.5
27140
+ *
27141
+ * GPU count formula:
27142
+ * model_bytes = params × bytes_per_param
27143
+ * target_util = 0.6 (40% headroom for KV cache, activations, scheduler)
27144
+ * count = max(1, ceil(model_bytes / (vram × target_util)))
27145
+ */
27146
+ const URL_GPU_PATTERNS = [
27147
+ {
27148
+ re: /h200/i,
27149
+ type: "h200",
27150
+ confidence: "high"
27151
+ },
27152
+ {
27153
+ re: /h100[-_]?pcie/i,
27154
+ type: "h100-pcie",
27155
+ confidence: "high"
27156
+ },
27157
+ {
27158
+ re: /h100[-_]?sxm/i,
27159
+ type: "h100-sxm",
27160
+ confidence: "high"
27161
+ },
27162
+ {
27163
+ re: /h100/i,
27164
+ type: "h100-sxm",
27165
+ confidence: "medium"
27166
+ },
27167
+ {
27168
+ re: /a100[-_]?80/i,
27169
+ type: "a100-80gb",
27170
+ confidence: "high"
27171
+ },
27172
+ {
27173
+ re: /a100[-_]?40/i,
27174
+ type: "a100-40gb",
27175
+ confidence: "high"
27176
+ },
27177
+ {
27178
+ re: /a100/i,
27179
+ type: "a100-80gb",
27180
+ confidence: "medium"
27181
+ },
27182
+ {
27183
+ re: /l40s/i,
27184
+ type: "l40s",
27185
+ confidence: "high"
27186
+ },
27187
+ {
27188
+ re: /l40/i,
27189
+ type: "l40",
27190
+ confidence: "high"
27191
+ },
27192
+ {
27193
+ re: /mi300x/i,
27194
+ type: "mi300x",
27195
+ confidence: "high"
27196
+ },
27197
+ {
27198
+ re: /a6000/i,
27199
+ type: "a6000",
27200
+ confidence: "high"
27201
+ },
27202
+ {
27203
+ re: /a5000/i,
27204
+ type: "a5000",
27205
+ confidence: "high"
27206
+ },
27207
+ {
27208
+ re: /a40/i,
27209
+ type: "a40",
27210
+ confidence: "high"
27211
+ },
27212
+ {
27213
+ re: /v100/i,
27214
+ type: "v100",
27215
+ confidence: "high"
27216
+ },
27217
+ {
27218
+ re: /rtx[-_]?4090|gpu[-_]?4090/i,
27219
+ type: "rtx-4090",
27220
+ confidence: "high"
27221
+ }
27222
+ ];
27223
+ function inferGpuFromUrl(baseUrl) {
27224
+ const url = baseUrl.toLowerCase();
27225
+ for (const pattern of URL_GPU_PATTERNS) {
27226
+ const match = url.match(pattern.re);
27227
+ if (match) return {
27228
+ gpuType: pattern.type,
27229
+ confidence: pattern.confidence,
27230
+ match: match[0]
27231
+ };
27232
+ }
27233
+ return { confidence: "low" };
27234
+ }
27235
+ function parseModelSize(modelId) {
27236
+ const id = modelId.toLowerCase();
27237
+ const sizeMatch = id.match(/(\d+(?:\.\d+)?)b(?:[-_./]|$)/);
27238
+ const paramsB = sizeMatch ? Number.parseFloat(sizeMatch[1]) : void 0;
27239
+ let bytesPerParam;
27240
+ if (/\b(fp4|q4|int4)\b/.test(id) || /[-_]q4[-_]/.test(id)) bytesPerParam = .5;
27241
+ else if (/\b(fp8|int8|q8|w8a8|w8a16)\b/.test(id) || /[-_]fp8[-_]?/.test(id)) bytesPerParam = 1;
27242
+ else if (/\b(fp16|bf16|float16|half)\b/.test(id)) bytesPerParam = 2;
27243
+ else if (/\b(fp32|float32)\b/.test(id)) bytesPerParam = 4;
27244
+ return {
27245
+ paramsB,
27246
+ bytesPerParam
27247
+ };
27248
+ }
27249
+ function inferGpuCount(args) {
27250
+ const util = args.targetUtilization ?? .6;
27251
+ if (!args.paramsB || !args.bytesPerParam) return 1;
27252
+ const modelBytes = args.paramsB * 1e9 * args.bytesPerParam;
27253
+ const usableVram = args.vramGb * 1e9 * util;
27254
+ return Math.max(1, Math.ceil(modelBytes / usableVram));
27255
+ }
27256
+ function inferGpu(args) {
27257
+ const reasoning = [];
27258
+ const overrideType = args.override?.gpuType;
27259
+ const overrideCount = args.override?.gpuCount;
27260
+ let gpuType;
27261
+ let confidence = "low";
27262
+ if (overrideType && overrideType in GPU_VRAM_GB) {
27263
+ gpuType = overrideType;
27264
+ confidence = "high";
27265
+ reasoning.push(`gpuType=${gpuType} from config override`);
27266
+ } else if (args.baseUrl) {
27267
+ const fromUrl = inferGpuFromUrl(args.baseUrl);
27268
+ if (fromUrl.gpuType) {
27269
+ gpuType = fromUrl.gpuType;
27270
+ confidence = fromUrl.confidence;
27271
+ reasoning.push(`gpuType=${gpuType} from URL pattern '${fromUrl.match}'`);
27272
+ } else reasoning.push("no GPU type pattern matched in URL");
27273
+ }
27274
+ const sized = args.modelId ? parseModelSize(args.modelId) : {};
27275
+ if (sized.paramsB) reasoning.push(`paramsB=${sized.paramsB} from model id '${args.modelId}'`);
27276
+ if (sized.bytesPerParam) reasoning.push(`bytesPerParam=${sized.bytesPerParam} from quantization marker`);
27277
+ else if (args.modelId) reasoning.push("no quantization marker — defaulting to bf16 (2 bytes)");
27278
+ let gpuCount = 1;
27279
+ if (typeof overrideCount === "number" && overrideCount > 0) {
27280
+ gpuCount = Math.floor(overrideCount);
27281
+ reasoning.push(`gpuCount=${gpuCount} from config override`);
27282
+ } else if (gpuType) {
27283
+ const bpp = sized.bytesPerParam ?? 2;
27284
+ gpuCount = inferGpuCount({
27285
+ paramsB: sized.paramsB,
27286
+ bytesPerParam: bpp,
27287
+ vramGb: GPU_VRAM_GB[gpuType]
27288
+ });
27289
+ if (sized.paramsB) reasoning.push(`gpuCount=${gpuCount} (model ${(sized.paramsB * bpp).toFixed(0)}GB / ${GPU_VRAM_GB[gpuType]}GB × 0.6 util)`);
27290
+ }
27291
+ return {
27292
+ gpuType,
27293
+ gpuCount,
27294
+ confidence,
27295
+ paramsB: sized.paramsB,
27296
+ bytesPerParam: sized.bytesPerParam,
27297
+ reasoning
27298
+ };
27299
+ }
27300
+
27301
+ //#endregion
27302
+ //#region src/cost/serving-discovery.ts
27303
+ const SUCCESS_TTL_MS = 6e4;
27304
+ const NULL_TTL_MS = 5 * 6e4;
27305
+ const DEFAULT_TIMEOUT_MS$1 = 4e3;
27306
+ const cache = /* @__PURE__ */ new Map();
27307
+ const previousSnapshots = /* @__PURE__ */ new Map();
27308
+ async function probeServingEndpoint(baseUrl, opts = {}) {
27309
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
27310
+ const nowFn = opts.now ?? (() => Date.now());
27311
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS$1;
27312
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
27313
+ if (!trimmed) return null;
27314
+ const cached = cache.get(trimmed);
27315
+ if (cached && !opts.forceRefresh && cached.expiresAt > nowFn()) return cached.info;
27316
+ const rootUrl = trimmed.replace(/\/v\d+$/, "");
27317
+ const probeAt = nowFn();
27318
+ const fetchOpts = () => ({
27319
+ signal: AbortSignal.timeout(timeoutMs),
27320
+ headers: { Accept: "application/json, text/plain, */*" }
27321
+ });
27322
+ const [versionRes, modelsRes, metricsRes] = await Promise.allSettled([
27323
+ fetchImpl(`${rootUrl}/version`, fetchOpts()),
27324
+ fetchImpl(`${rootUrl}/v1/models`, fetchOpts()),
27325
+ fetchImpl(`${rootUrl}/metrics`, fetchOpts())
27326
+ ]);
27327
+ const info = {
27328
+ engine: "unknown",
27329
+ probedAt: probeAt,
27330
+ baseUrl: trimmed,
27331
+ rootUrl
27332
+ };
27333
+ if (versionRes.status === "fulfilled" && versionRes.value.ok) try {
27334
+ const txt = await versionRes.value.text();
27335
+ try {
27336
+ const json = JSON.parse(txt);
27337
+ if (typeof json.version === "string") info.version = json.version;
27338
+ } catch {
27339
+ const stripped = txt.trim();
27340
+ if (stripped && stripped.length < 64 && /^[\w.\-+]+$/.test(stripped)) info.version = stripped;
27341
+ }
27342
+ } catch {}
27343
+ if (modelsRes.status === "fulfilled" && modelsRes.value.ok) try {
27344
+ const first = (await modelsRes.value.json()).data?.[0];
27345
+ if (first) {
27346
+ if (typeof first.id === "string") info.modelId = first.id;
27347
+ if (typeof first.max_model_len === "number") info.contextWindow = first.max_model_len;
27348
+ if (typeof first.owned_by === "string") {
27349
+ const owner = first.owned_by.toLowerCase();
27350
+ if (owner.includes("vllm")) info.engine = "vllm";
27351
+ else if (owner.includes("sglang")) info.engine = "sglang";
27352
+ else if (info.engine === "unknown") info.engine = "openai-compat";
27353
+ }
27354
+ }
27355
+ } catch {}
27356
+ let snapshot = { probedAt: probeAt };
27357
+ if (metricsRes.status === "fulfilled" && metricsRes.value.ok) try {
27358
+ const parsed = parsePrometheusMetrics(await metricsRes.value.text());
27359
+ info.kvCacheUsagePerc = parsed.kvCacheUsagePerc;
27360
+ info.queueDepth = parsed.queueDepth;
27361
+ info.numRequestsRunning = parsed.numRequestsRunning;
27362
+ info.cacheConfig = parsed.cacheConfig;
27363
+ snapshot = {
27364
+ probedAt: probeAt,
27365
+ promptTokensTotal: parsed.promptTokensTotal,
27366
+ generationTokensTotal: parsed.generationTokensTotal
27367
+ };
27368
+ if (info.engine === "unknown" && parsed.foundVllmPrefix) info.engine = "vllm";
27369
+ if (info.engine === "unknown" && parsed.foundSglangPrefix) info.engine = "sglang";
27370
+ } catch {}
27371
+ const prev = previousSnapshots.get(trimmed);
27372
+ if (prev && typeof prev.generationTokensTotal === "number" && typeof snapshot.generationTokensTotal === "number") {
27373
+ const dt = (snapshot.probedAt - prev.probedAt) / 1e3;
27374
+ const dToks = snapshot.generationTokensTotal - prev.generationTokensTotal;
27375
+ if (dt > 0 && dToks >= 0) info.observedTps = dToks / dt;
27376
+ }
27377
+ if (snapshot.generationTokensTotal !== void 0 || snapshot.promptTokensTotal !== void 0) previousSnapshots.set(trimmed, snapshot);
27378
+ if (!(info.version !== void 0 || info.modelId !== void 0 || info.cacheConfig !== void 0 || info.kvCacheUsagePerc !== void 0 || info.queueDepth !== void 0 || info.numRequestsRunning !== void 0)) {
27379
+ cache.set(trimmed, {
27380
+ info: null,
27381
+ expiresAt: nowFn() + NULL_TTL_MS
27382
+ });
27383
+ return null;
27384
+ }
27385
+ cache.set(trimmed, {
27386
+ info,
27387
+ expiresAt: nowFn() + SUCCESS_TTL_MS
27388
+ });
27389
+ return info;
27390
+ }
27391
+ function parsePrometheusMetrics(text) {
27392
+ const result = {
27393
+ foundVllmPrefix: false,
27394
+ foundSglangPrefix: false
27395
+ };
27396
+ const lines = text.split("\n");
27397
+ for (const raw of lines) {
27398
+ const line = raw.trim();
27399
+ if (!line || line.startsWith("#")) continue;
27400
+ if (line.startsWith("vllm:")) result.foundVllmPrefix = true;
27401
+ if (line.startsWith("sglang:")) result.foundSglangPrefix = true;
27402
+ const match = line.match(/^([^\s{]+)(\{[^}]*\})?\s+([0-9eE+\-.]+)$/);
27403
+ if (!match) continue;
27404
+ const metric = match[1];
27405
+ const labels = match[2];
27406
+ const value = Number(match[3]);
27407
+ if (!Number.isFinite(value)) continue;
27408
+ switch (metric) {
27409
+ case "vllm:prompt_tokens_total":
27410
+ result.promptTokensTotal = (result.promptTokensTotal ?? 0) + value;
27411
+ break;
27412
+ case "vllm:generation_tokens_total":
27413
+ result.generationTokensTotal = (result.generationTokensTotal ?? 0) + value;
27414
+ break;
27415
+ case "vllm:kv_cache_usage_perc":
27416
+ result.kvCacheUsagePerc = value;
27417
+ break;
27418
+ case "vllm:num_requests_waiting":
27419
+ if (!labels || !labels.includes("reason=")) result.queueDepth = value;
27420
+ break;
27421
+ case "vllm:num_requests_running":
27422
+ result.numRequestsRunning = value;
27423
+ break;
27424
+ case "vllm:cache_config_info": {
27425
+ if (!labels) break;
27426
+ const parsed = parseLabels(labels);
27427
+ const cfg = {};
27428
+ if (parsed.block_size !== void 0) cfg.blockSize = Number(parsed.block_size);
27429
+ if (parsed.num_gpu_blocks !== void 0) cfg.numGpuBlocks = Number(parsed.num_gpu_blocks);
27430
+ if (parsed.cache_dtype !== void 0) cfg.cacheDtype = parsed.cache_dtype;
27431
+ if (parsed.gpu_memory_utilization !== void 0) {
27432
+ const n = Number(parsed.gpu_memory_utilization);
27433
+ if (Number.isFinite(n)) cfg.gpuMemoryUtilization = n;
27434
+ }
27435
+ if (parsed.enable_prefix_caching !== void 0) cfg.enablePrefixCaching = parsed.enable_prefix_caching === "True";
27436
+ result.cacheConfig = cfg;
27437
+ break;
27438
+ }
27439
+ }
27440
+ }
27441
+ return result;
27442
+ }
27443
+ function parseLabels(rawLabels) {
27444
+ const inner = rawLabels.replace(/^\{/, "").replace(/\}$/, "");
27445
+ const out = {};
27446
+ const re = /(\w+)="([^"]*)"/g;
27447
+ let m;
27448
+ while ((m = re.exec(inner)) !== null) out[m[1]] = m[2];
27449
+ return out;
27450
+ }
27451
+ function formatEngineLine(info) {
27452
+ if (!info) return null;
27453
+ const parts = [];
27454
+ const engineLabel = (() => {
27455
+ if (info.engine === "vllm") return info.version ? `vLLM ${info.version}` : "vLLM";
27456
+ if (info.engine === "sglang") return info.version ? `SGLang ${info.version}` : "SGLang";
27457
+ if (info.engine === "openai-compat") return "OpenAI-compat";
27458
+ return info.version ? `engine ${info.version}` : null;
27459
+ })();
27460
+ if (engineLabel) parts.push(engineLabel);
27461
+ if (typeof info.observedTps === "number" && info.observedTps > .5) parts.push(`${Math.round(info.observedTps)} tps`);
27462
+ if (typeof info.kvCacheUsagePerc === "number") {
27463
+ const pct = Math.round(info.kvCacheUsagePerc * 100);
27464
+ if (pct > 0) parts.push(`KV ${pct}%`);
27465
+ }
27466
+ if (typeof info.queueDepth === "number" && info.queueDepth > 0) parts.push(`queue ${info.queueDepth}`);
27467
+ if (typeof info.numRequestsRunning === "number" && info.numRequestsRunning > 0) parts.push(`running ${info.numRequestsRunning}`);
27468
+ if (parts.length === 0) return null;
27469
+ return `🖥 ${parts.join(" · ")}`;
27470
+ }
27471
+
27472
+ //#endregion
27473
+ //#region src/cost/breakdown.ts
27474
+ async function buildCostBreakdown(args) {
27475
+ const benchmarkTarget = args.config?.models?.benchmark === "none" ? "none" : resolveBenchmarkTarget(args.config?.models?.benchmark);
27476
+ const breakdown = {
27477
+ serving: null,
27478
+ benchmarks: [],
27479
+ benchmarkTarget
27480
+ };
27481
+ if (args.baseUrl && args.baseUrl.trim()) try {
27482
+ breakdown.serving = await probeServingEndpoint(args.baseUrl, {
27483
+ timeoutMs: args.probeTimeoutMs ?? 3e3,
27484
+ forceRefresh: Boolean(args.forceProbeRefresh)
27485
+ });
27486
+ } catch {
27487
+ breakdown.serving = null;
27488
+ }
27489
+ breakdown.engineLine = formatEngineLine(breakdown.serving) ?? void 0;
27490
+ const modelCost = resolveModelCost(args.config, args.provider, args.modelId);
27491
+ const detectedModelId = breakdown.serving?.modelId ?? args.modelId;
27492
+ breakdown.gpu = inferGpu({
27493
+ baseUrl: args.baseUrl,
27494
+ modelId: detectedModelId,
27495
+ override: {
27496
+ gpuType: modelCost?.gpuType,
27497
+ gpuCount: modelCost?.gpuCount
27498
+ }
27499
+ });
27500
+ const overrides = args.config?.models?.gpuRates;
27501
+ let rate;
27502
+ let source;
27503
+ if (typeof modelCost?.hourlyRate === "number" && modelCost.hourlyRate >= 0) {
27504
+ rate = modelCost.hourlyRate;
27505
+ source = "model-override";
27506
+ } else if (breakdown.gpu.gpuType) {
27507
+ rate = resolveHourlyRate(breakdown.gpu.gpuType, overrides);
27508
+ if (rate !== void 0) source = overrides && breakdown.gpu.gpuType in overrides ? "config-override" : "default-table";
27509
+ }
27510
+ breakdown.hourlyRate = rate;
27511
+ breakdown.hourlyRateSource = source;
27512
+ if (breakdown.gpu?.gpuType) {
27513
+ const observed = breakdown.serving?.observedTps;
27514
+ if (typeof observed === "number" && observed > .5) {
27515
+ breakdown.decodeTps = observed;
27516
+ breakdown.prefillTps = observed * PREFILL_DECODE_RATIO;
27517
+ breakdown.throughputSource = "observed";
27518
+ } else {
27519
+ const decode = resolveDefaultDecodeTps(breakdown.gpu.gpuType, breakdown.gpu.paramsB, breakdown.gpu.bytesPerParam);
27520
+ breakdown.decodeTps = decode;
27521
+ breakdown.prefillTps = decode * PREFILL_DECODE_RATIO;
27522
+ breakdown.throughputSource = "default-table";
27523
+ }
27524
+ }
27525
+ if (args.usage && breakdown.hourlyRate !== void 0 && breakdown.gpu?.gpuType && breakdown.decodeTps !== void 0 && breakdown.prefillTps !== void 0) {
27526
+ const perSecond = breakdown.hourlyRate * breakdown.gpu.gpuCount / 3600;
27527
+ const inputTokens = args.usage.input ?? 0;
27528
+ const outputTokens = args.usage.output ?? 0;
27529
+ const totalCost = ((breakdown.prefillTps > 0 ? inputTokens / breakdown.prefillTps : 0) + (breakdown.decodeTps > 0 ? outputTokens / breakdown.decodeTps : 0)) * perSecond;
27530
+ breakdown.instanceCostUsd = totalCost;
27531
+ const totalTokens = inputTokens + outputTokens;
27532
+ if (totalTokens > 0) breakdown.perTokenAvgUsd = totalCost / totalTokens;
27533
+ }
27534
+ if (args.usage) {
27535
+ const costForEstimate = modelCost ? {
27536
+ input: modelCost.input ?? 0,
27537
+ output: modelCost.output ?? 0,
27538
+ cacheRead: modelCost.cacheRead ?? 0,
27539
+ cacheWrite: modelCost.cacheWrite ?? 0
27540
+ } : void 0;
27541
+ const rawCost = estimateUsageCost({
27542
+ usage: args.usage,
27543
+ cost: costForEstimate
27544
+ });
27545
+ if (typeof rawCost === "number" && rawCost > 0) breakdown.effectiveCostUsd = rawCost;
27546
+ else if (breakdown.instanceCostUsd !== void 0) breakdown.effectiveCostUsd = breakdown.instanceCostUsd;
27547
+ if (benchmarkTarget !== "none" && breakdown.effectiveCostUsd !== void 0) {
27548
+ breakdown.benchmarks = benchmarkUsage({
27549
+ usage: args.usage,
27550
+ target: benchmarkTarget
27551
+ });
27552
+ breakdown.costLineSuffix = formatBenchmarkSuffix({
27553
+ ourCostUsd: breakdown.effectiveCostUsd,
27554
+ benchmarks: breakdown.benchmarks
27555
+ });
27556
+ }
27557
+ }
27558
+ breakdown.hardwareLine = formatHardwareLine(breakdown);
27559
+ return breakdown;
27560
+ }
27561
+ function resolveModelCost(config, provider, modelId) {
27562
+ if (!config || !provider || !modelId) return;
27563
+ const providers = config.models?.providers;
27564
+ if (!providers) return;
27565
+ const providerCfg = providers[provider];
27566
+ if (!providerCfg?.models) return;
27567
+ return providerCfg.models.find((m) => m.id === modelId)?.cost;
27568
+ }
27569
+ function formatHardwareLine(breakdown) {
27570
+ const gpu = breakdown.gpu;
27571
+ if (!gpu?.gpuType) return;
27572
+ const label = GPU_LABEL[gpu.gpuType];
27573
+ const count = gpu.gpuCount;
27574
+ const parts = [];
27575
+ parts.push(`${count}× ${label}`);
27576
+ if (typeof breakdown.hourlyRate === "number") parts.push(`≈ $${(breakdown.hourlyRate * count).toFixed(2)}/hr`);
27577
+ const tag = (() => {
27578
+ if (breakdown.hourlyRateSource === "model-override") return "model override";
27579
+ if (breakdown.hourlyRateSource === "config-override") return "config override";
27580
+ if (gpu.confidence === "high") return "inferred";
27581
+ if (gpu.confidence === "medium") return "inferred · medium-conf";
27582
+ return "inferred · low-conf";
27583
+ })();
27584
+ parts.push(`(${tag})`);
27585
+ return `🧰 ${parts.join(" · ")}`;
27586
+ }
27587
+
26420
27588
  //#endregion
26421
27589
  //#region src/infra/provider-usage.shared.ts
26422
27590
  const DEFAULT_TIMEOUT_MS = 5e3;
@@ -27620,6 +28788,32 @@ async function buildStatusReply(params) {
27620
28788
  } catch {
27621
28789
  usageLine = null;
27622
28790
  }
28791
+ const baseUrl = cfg.models?.providers?.[provider]?.baseUrl;
28792
+ let engineLine;
28793
+ let hardwareLine;
28794
+ let costOverrideUsd;
28795
+ let costLineSuffix;
28796
+ try {
28797
+ const breakdown = await buildCostBreakdown({
28798
+ baseUrl,
28799
+ provider,
28800
+ modelId: model,
28801
+ config: cfg,
28802
+ usage: {
28803
+ input: sessionEntry?.inputTokens,
28804
+ output: sessionEntry?.outputTokens
28805
+ }
28806
+ });
28807
+ engineLine = breakdown.engineLine;
28808
+ hardwareLine = breakdown.hardwareLine;
28809
+ costOverrideUsd = breakdown.instanceCostUsd;
28810
+ costLineSuffix = breakdown.costLineSuffix;
28811
+ } catch {
28812
+ engineLine = void 0;
28813
+ hardwareLine = void 0;
28814
+ costOverrideUsd = void 0;
28815
+ costLineSuffix = void 0;
28816
+ }
27623
28817
  const queueSettings = resolveQueueSettings({
27624
28818
  cfg,
27625
28819
  channel: command.channel,
@@ -27702,6 +28896,10 @@ async function buildStatusReply(params) {
27702
28896
  showDetails: queueOverrides
27703
28897
  },
27704
28898
  subagentsLine,
28899
+ engineLine,
28900
+ hardwareLine,
28901
+ costOverrideUsd,
28902
+ costLineSuffix,
27705
28903
  mediaDecisions: params.mediaDecisions,
27706
28904
  includeTranscriptUsage: false
27707
28905
  }) };
@@ -27802,6 +29000,27 @@ const handleStatusCommand = async (params, allowTextCommands) => {
27802
29000
  })
27803
29001
  };
27804
29002
  };
29003
+ const handleCostCommand = async (params, allowTextCommands) => {
29004
+ if (!allowTextCommands) return null;
29005
+ const normalized = params.command.commandBodyNormalized;
29006
+ if (normalized !== "/cost" && !normalized.startsWith("/cost ")) return null;
29007
+ if (!params.command.isAuthorizedSender) {
29008
+ logVerbose(`Ignoring /cost from unauthorized sender: ${params.command.senderId || "<unknown>"}`);
29009
+ return { shouldContinue: false };
29010
+ }
29011
+ const arg = normalized.slice(5).trim();
29012
+ const window = arg === "today" || arg === "week" || arg === "month" || arg === "all" ? arg : "week";
29013
+ const { startMs, endMs } = resolveWindow(window);
29014
+ return {
29015
+ shouldContinue: false,
29016
+ reply: { text: formatSummaryReport(await loadCostBenchmarkSummary({
29017
+ startMs,
29018
+ endMs,
29019
+ config: params.cfg,
29020
+ agentId: params.agentId
29021
+ }), `${window.charAt(0).toUpperCase()}${window.slice(1)}`) }
29022
+ };
29023
+ };
27805
29024
  const handleContextCommand = async (params, allowTextCommands) => {
27806
29025
  if (!allowTextCommands) return null;
27807
29026
  const normalized = params.command.commandBodyNormalized;
@@ -28198,411 +29417,6 @@ function scheduleGatewaySigusr1Restart(opts) {
28198
29417
  };
28199
29418
  }
28200
29419
 
28201
- //#endregion
28202
- //#region src/infra/session-cost-usage.ts
28203
- const emptyTotals = () => ({
28204
- input: 0,
28205
- output: 0,
28206
- cacheRead: 0,
28207
- cacheWrite: 0,
28208
- totalTokens: 0,
28209
- totalCost: 0,
28210
- inputCost: 0,
28211
- outputCost: 0,
28212
- cacheReadCost: 0,
28213
- cacheWriteCost: 0,
28214
- missingCostEntries: 0
28215
- });
28216
- const toFiniteNumber = (value) => {
28217
- if (typeof value !== "number") return;
28218
- if (!Number.isFinite(value)) return;
28219
- return value;
28220
- };
28221
- const extractCostBreakdown = (usageRaw) => {
28222
- if (!usageRaw || typeof usageRaw !== "object") return;
28223
- const cost = usageRaw.cost;
28224
- if (!cost) return;
28225
- const total = toFiniteNumber(cost.total);
28226
- if (total === void 0 || total < 0) return;
28227
- return {
28228
- total,
28229
- input: toFiniteNumber(cost.input),
28230
- output: toFiniteNumber(cost.output),
28231
- cacheRead: toFiniteNumber(cost.cacheRead),
28232
- cacheWrite: toFiniteNumber(cost.cacheWrite)
28233
- };
28234
- };
28235
- const parseTimestamp = (entry) => {
28236
- const raw = entry.timestamp;
28237
- if (typeof raw === "string") {
28238
- const parsed = new Date(raw);
28239
- if (!Number.isNaN(parsed.valueOf())) return parsed;
28240
- }
28241
- const message = entry.message;
28242
- const messageTimestamp = toFiniteNumber(message?.timestamp);
28243
- if (messageTimestamp !== void 0) {
28244
- const parsed = new Date(messageTimestamp);
28245
- if (!Number.isNaN(parsed.valueOf())) return parsed;
28246
- }
28247
- };
28248
- const parseTranscriptEntry = (entry) => {
28249
- const message = entry.message;
28250
- if (!message || typeof message !== "object") return null;
28251
- const roleRaw = message.role;
28252
- const role = roleRaw === "user" || roleRaw === "assistant" ? roleRaw : void 0;
28253
- if (!role) return null;
28254
- const usageRaw = message.usage ?? entry.usage;
28255
- const usage = usageRaw ? normalizeUsage(usageRaw) ?? void 0 : void 0;
28256
- const provider = (typeof message.provider === "string" ? message.provider : void 0) ?? (typeof entry.provider === "string" ? entry.provider : void 0);
28257
- const model = (typeof message.model === "string" ? message.model : void 0) ?? (typeof entry.model === "string" ? entry.model : void 0);
28258
- const costBreakdown = extractCostBreakdown(usageRaw);
28259
- const stopReason = typeof message.stopReason === "string" ? message.stopReason : void 0;
28260
- const durationMs = toFiniteNumber(message.durationMs ?? entry.durationMs);
28261
- return {
28262
- message,
28263
- role,
28264
- timestamp: parseTimestamp(entry),
28265
- durationMs,
28266
- usage,
28267
- costTotal: costBreakdown?.total,
28268
- costBreakdown,
28269
- provider,
28270
- model,
28271
- stopReason,
28272
- toolNames: extractToolCallNames(message),
28273
- toolResultCounts: countToolResults(message)
28274
- };
28275
- };
28276
- const formatDayKey = (date) => date.toLocaleDateString("en-CA", { timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone });
28277
- const computeLatencyStats = (values) => {
28278
- if (!values.length) return;
28279
- const sorted = values.toSorted((a, b) => a - b);
28280
- const total = sorted.reduce((sum, v) => sum + v, 0);
28281
- const count = sorted.length;
28282
- const p95Index = Math.max(0, Math.ceil(count * .95) - 1);
28283
- return {
28284
- count,
28285
- avgMs: total / count,
28286
- p95Ms: sorted[p95Index] ?? sorted[count - 1],
28287
- minMs: sorted[0],
28288
- maxMs: sorted[count - 1]
28289
- };
28290
- };
28291
- const applyUsageTotals = (totals, usage) => {
28292
- totals.input += usage.input ?? 0;
28293
- totals.output += usage.output ?? 0;
28294
- totals.cacheRead += usage.cacheRead ?? 0;
28295
- totals.cacheWrite += usage.cacheWrite ?? 0;
28296
- const totalTokens = usage.total ?? (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
28297
- totals.totalTokens += totalTokens;
28298
- };
28299
- const applyCostBreakdown = (totals, costBreakdown) => {
28300
- if (costBreakdown === void 0 || costBreakdown.total === void 0) return;
28301
- totals.totalCost += costBreakdown.total;
28302
- totals.inputCost += costBreakdown.input ?? 0;
28303
- totals.outputCost += costBreakdown.output ?? 0;
28304
- totals.cacheReadCost += costBreakdown.cacheRead ?? 0;
28305
- totals.cacheWriteCost += costBreakdown.cacheWrite ?? 0;
28306
- };
28307
- const applyCostTotal = (totals, costTotal) => {
28308
- if (costTotal === void 0) {
28309
- totals.missingCostEntries += 1;
28310
- return;
28311
- }
28312
- totals.totalCost += costTotal;
28313
- };
28314
- async function* readJsonlRecords(filePath) {
28315
- const fileStream = fs.createReadStream(filePath, { encoding: "utf-8" });
28316
- const rl = readline.createInterface({
28317
- input: fileStream,
28318
- crlfDelay: Infinity
28319
- });
28320
- try {
28321
- for await (const line of rl) {
28322
- const trimmed = line.trim();
28323
- if (!trimmed) continue;
28324
- try {
28325
- const parsed = JSON.parse(trimmed);
28326
- if (!parsed || typeof parsed !== "object") continue;
28327
- yield parsed;
28328
- } catch {}
28329
- }
28330
- } finally {
28331
- rl.close();
28332
- fileStream.destroy();
28333
- }
28334
- }
28335
- async function scanTranscriptFile(params) {
28336
- for await (const parsed of readJsonlRecords(params.filePath)) {
28337
- const entry = parseTranscriptEntry(parsed);
28338
- if (!entry) continue;
28339
- if (entry.usage && entry.costTotal === void 0) {
28340
- const cost = resolveModelCostConfig({
28341
- provider: entry.provider,
28342
- model: entry.model,
28343
- config: params.config
28344
- });
28345
- entry.costTotal = estimateUsageCost({
28346
- usage: entry.usage,
28347
- cost
28348
- });
28349
- }
28350
- params.onEntry(entry);
28351
- }
28352
- }
28353
- async function scanUsageFile(params) {
28354
- await scanTranscriptFile({
28355
- filePath: params.filePath,
28356
- config: params.config,
28357
- onEntry: (entry) => {
28358
- if (!entry.usage) return;
28359
- params.onEntry({
28360
- usage: entry.usage,
28361
- costTotal: entry.costTotal,
28362
- costBreakdown: entry.costBreakdown,
28363
- provider: entry.provider,
28364
- model: entry.model,
28365
- timestamp: entry.timestamp
28366
- });
28367
- }
28368
- });
28369
- }
28370
- async function loadCostUsageSummary(params) {
28371
- const now = /* @__PURE__ */ new Date();
28372
- let sinceTime;
28373
- let untilTime;
28374
- if (params?.startMs !== void 0 && params?.endMs !== void 0) {
28375
- sinceTime = params.startMs;
28376
- untilTime = params.endMs;
28377
- } else {
28378
- const days = Math.max(1, Math.floor(params?.days ?? 30));
28379
- const since = new Date(now);
28380
- since.setDate(since.getDate() - (days - 1));
28381
- sinceTime = since.getTime();
28382
- untilTime = now.getTime();
28383
- }
28384
- const dailyMap = /* @__PURE__ */ new Map();
28385
- const totals = emptyTotals();
28386
- const sessionsDir = resolveSessionTranscriptsDirForAgent(params?.agentId);
28387
- const entries = await fs.promises.readdir(sessionsDir, { withFileTypes: true }).catch(() => []);
28388
- const files = (await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map(async (entry) => {
28389
- const filePath = path.join(sessionsDir, entry.name);
28390
- const stats = await fs.promises.stat(filePath).catch(() => null);
28391
- if (!stats) return null;
28392
- if (stats.mtimeMs < sinceTime) return null;
28393
- return filePath;
28394
- }))).filter((filePath) => Boolean(filePath));
28395
- for (const filePath of files) await scanUsageFile({
28396
- filePath,
28397
- config: params?.config,
28398
- onEntry: (entry) => {
28399
- const ts = entry.timestamp?.getTime();
28400
- if (!ts || ts < sinceTime || ts > untilTime) return;
28401
- const dayKey = formatDayKey(entry.timestamp ?? now);
28402
- const bucket = dailyMap.get(dayKey) ?? emptyTotals();
28403
- applyUsageTotals(bucket, entry.usage);
28404
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(bucket, entry.costBreakdown);
28405
- else applyCostTotal(bucket, entry.costTotal);
28406
- dailyMap.set(dayKey, bucket);
28407
- applyUsageTotals(totals, entry.usage);
28408
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
28409
- else applyCostTotal(totals, entry.costTotal);
28410
- }
28411
- });
28412
- const daily = Array.from(dailyMap.entries()).map(([date, bucket]) => Object.assign({ date }, bucket)).toSorted((a, b) => a.date.localeCompare(b.date));
28413
- const days = Math.ceil((untilTime - sinceTime) / (1440 * 60 * 1e3)) + 1;
28414
- return {
28415
- updatedAt: Date.now(),
28416
- days,
28417
- daily,
28418
- totals
28419
- };
28420
- }
28421
- async function loadSessionCostSummary(params) {
28422
- const sessionFile = params.sessionFile ?? (params.sessionId ? resolveSessionFilePath(params.sessionId, params.sessionEntry, { agentId: params.agentId }) : void 0);
28423
- if (!sessionFile || !fs.existsSync(sessionFile)) return null;
28424
- const totals = emptyTotals();
28425
- let firstActivity;
28426
- let lastActivity;
28427
- const activityDatesSet = /* @__PURE__ */ new Set();
28428
- const dailyMap = /* @__PURE__ */ new Map();
28429
- const dailyMessageMap = /* @__PURE__ */ new Map();
28430
- const dailyLatencyMap = /* @__PURE__ */ new Map();
28431
- const dailyModelUsageMap = /* @__PURE__ */ new Map();
28432
- const messageCounts = {
28433
- total: 0,
28434
- user: 0,
28435
- assistant: 0,
28436
- toolCalls: 0,
28437
- toolResults: 0,
28438
- errors: 0
28439
- };
28440
- const toolUsageMap = /* @__PURE__ */ new Map();
28441
- const modelUsageMap = /* @__PURE__ */ new Map();
28442
- const errorStopReasons = new Set([
28443
- "error",
28444
- "aborted",
28445
- "timeout"
28446
- ]);
28447
- const latencyValues = [];
28448
- let lastUserTimestamp;
28449
- const MAX_LATENCY_MS = 720 * 60 * 1e3;
28450
- await scanTranscriptFile({
28451
- filePath: sessionFile,
28452
- config: params.config,
28453
- onEntry: (entry) => {
28454
- const ts = entry.timestamp?.getTime();
28455
- if (params.startMs !== void 0 && ts !== void 0 && ts < params.startMs) return;
28456
- if (params.endMs !== void 0 && ts !== void 0 && ts > params.endMs) return;
28457
- if (ts !== void 0) {
28458
- if (!firstActivity || ts < firstActivity) firstActivity = ts;
28459
- if (!lastActivity || ts > lastActivity) lastActivity = ts;
28460
- }
28461
- if (entry.role === "user") {
28462
- messageCounts.user += 1;
28463
- messageCounts.total += 1;
28464
- if (entry.timestamp) lastUserTimestamp = entry.timestamp.getTime();
28465
- }
28466
- if (entry.role === "assistant") {
28467
- messageCounts.assistant += 1;
28468
- messageCounts.total += 1;
28469
- const ts = entry.timestamp?.getTime();
28470
- if (ts !== void 0) {
28471
- const latencyMs = entry.durationMs ?? (lastUserTimestamp !== void 0 ? Math.max(0, ts - lastUserTimestamp) : void 0);
28472
- if (latencyMs !== void 0 && Number.isFinite(latencyMs) && latencyMs <= MAX_LATENCY_MS) {
28473
- latencyValues.push(latencyMs);
28474
- const dayKey = formatDayKey(entry.timestamp ?? new Date(ts));
28475
- const dailyLatencies = dailyLatencyMap.get(dayKey) ?? [];
28476
- dailyLatencies.push(latencyMs);
28477
- dailyLatencyMap.set(dayKey, dailyLatencies);
28478
- }
28479
- }
28480
- }
28481
- if (entry.toolNames.length > 0) {
28482
- messageCounts.toolCalls += entry.toolNames.length;
28483
- for (const name of entry.toolNames) toolUsageMap.set(name, (toolUsageMap.get(name) ?? 0) + 1);
28484
- }
28485
- if (entry.toolResultCounts.total > 0) {
28486
- messageCounts.toolResults += entry.toolResultCounts.total;
28487
- messageCounts.errors += entry.toolResultCounts.errors;
28488
- }
28489
- if (entry.stopReason && errorStopReasons.has(entry.stopReason)) messageCounts.errors += 1;
28490
- if (entry.timestamp) {
28491
- const dayKey = formatDayKey(entry.timestamp);
28492
- activityDatesSet.add(dayKey);
28493
- const daily = dailyMessageMap.get(dayKey) ?? {
28494
- date: dayKey,
28495
- total: 0,
28496
- user: 0,
28497
- assistant: 0,
28498
- toolCalls: 0,
28499
- toolResults: 0,
28500
- errors: 0
28501
- };
28502
- daily.total += entry.role === "user" || entry.role === "assistant" ? 1 : 0;
28503
- if (entry.role === "user") daily.user += 1;
28504
- else if (entry.role === "assistant") daily.assistant += 1;
28505
- daily.toolCalls += entry.toolNames.length;
28506
- daily.toolResults += entry.toolResultCounts.total;
28507
- daily.errors += entry.toolResultCounts.errors;
28508
- if (entry.stopReason && errorStopReasons.has(entry.stopReason)) daily.errors += 1;
28509
- dailyMessageMap.set(dayKey, daily);
28510
- }
28511
- if (!entry.usage) return;
28512
- applyUsageTotals(totals, entry.usage);
28513
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
28514
- else applyCostTotal(totals, entry.costTotal);
28515
- if (entry.timestamp) {
28516
- const dayKey = formatDayKey(entry.timestamp);
28517
- const entryTokens = (entry.usage.input ?? 0) + (entry.usage.output ?? 0) + (entry.usage.cacheRead ?? 0) + (entry.usage.cacheWrite ?? 0);
28518
- const entryCost = entry.costBreakdown?.total ?? (entry.costBreakdown ? (entry.costBreakdown.input ?? 0) + (entry.costBreakdown.output ?? 0) + (entry.costBreakdown.cacheRead ?? 0) + (entry.costBreakdown.cacheWrite ?? 0) : entry.costTotal ?? 0);
28519
- const existing = dailyMap.get(dayKey) ?? {
28520
- tokens: 0,
28521
- cost: 0
28522
- };
28523
- dailyMap.set(dayKey, {
28524
- tokens: existing.tokens + entryTokens,
28525
- cost: existing.cost + entryCost
28526
- });
28527
- if (entry.provider || entry.model) {
28528
- const modelKey = `${dayKey}::${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
28529
- const dailyModel = dailyModelUsageMap.get(modelKey) ?? {
28530
- date: dayKey,
28531
- provider: entry.provider,
28532
- model: entry.model,
28533
- tokens: 0,
28534
- cost: 0,
28535
- count: 0
28536
- };
28537
- dailyModel.tokens += entryTokens;
28538
- dailyModel.cost += entryCost;
28539
- dailyModel.count += 1;
28540
- dailyModelUsageMap.set(modelKey, dailyModel);
28541
- }
28542
- }
28543
- if (entry.provider || entry.model) {
28544
- const key = `${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
28545
- const existing = modelUsageMap.get(key) ?? {
28546
- provider: entry.provider,
28547
- model: entry.model,
28548
- count: 0,
28549
- totals: emptyTotals()
28550
- };
28551
- existing.count += 1;
28552
- applyUsageTotals(existing.totals, entry.usage);
28553
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(existing.totals, entry.costBreakdown);
28554
- else applyCostTotal(existing.totals, entry.costTotal);
28555
- modelUsageMap.set(key, existing);
28556
- }
28557
- }
28558
- });
28559
- const dailyBreakdown = Array.from(dailyMap.entries()).map(([date, data]) => ({
28560
- date,
28561
- tokens: data.tokens,
28562
- cost: data.cost
28563
- })).toSorted((a, b) => a.date.localeCompare(b.date));
28564
- const dailyMessageCounts = Array.from(dailyMessageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date));
28565
- const dailyLatency = Array.from(dailyLatencyMap.entries()).map(([date, values]) => {
28566
- const stats = computeLatencyStats(values);
28567
- if (!stats) return null;
28568
- return {
28569
- date,
28570
- ...stats
28571
- };
28572
- }).filter((entry) => Boolean(entry)).toSorted((a, b) => a.date.localeCompare(b.date));
28573
- const dailyModelUsage = Array.from(dailyModelUsageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date) || b.cost - a.cost);
28574
- const toolUsage = toolUsageMap.size ? {
28575
- totalCalls: Array.from(toolUsageMap.values()).reduce((sum, count) => sum + count, 0),
28576
- uniqueTools: toolUsageMap.size,
28577
- tools: Array.from(toolUsageMap.entries()).map(([name, count]) => ({
28578
- name,
28579
- count
28580
- })).toSorted((a, b) => b.count - a.count)
28581
- } : void 0;
28582
- const modelUsage = modelUsageMap.size ? Array.from(modelUsageMap.values()).toSorted((a, b) => {
28583
- const costDiff = b.totals.totalCost - a.totals.totalCost;
28584
- if (costDiff !== 0) return costDiff;
28585
- return b.totals.totalTokens - a.totals.totalTokens;
28586
- }) : void 0;
28587
- return {
28588
- sessionId: params.sessionId,
28589
- sessionFile,
28590
- firstActivity,
28591
- lastActivity,
28592
- durationMs: firstActivity !== void 0 && lastActivity !== void 0 ? Math.max(0, lastActivity - firstActivity) : void 0,
28593
- activityDates: Array.from(activityDatesSet).toSorted(),
28594
- dailyBreakdown,
28595
- dailyMessageCounts,
28596
- dailyLatency: dailyLatency.length ? dailyLatency : void 0,
28597
- dailyModelUsage: dailyModelUsage.length ? dailyModelUsage : void 0,
28598
- messageCounts,
28599
- toolUsage,
28600
- modelUsage,
28601
- latency: computeLatencyStats(latencyValues),
28602
- ...totals
28603
- };
28604
- }
28605
-
28606
29420
  //#endregion
28607
29421
  //#region src/auto-reply/send-policy.ts
28608
29422
  function normalizeSendPolicyOverride(raw) {
@@ -29802,6 +30616,7 @@ async function handleCommands(params) {
29802
30616
  handleHelpCommand,
29803
30617
  handleCommandsListCommand,
29804
30618
  handleStatusCommand,
30619
+ handleCostCommand,
29805
30620
  handleAllowlistCommand,
29806
30621
  handleApproveCommand,
29807
30622
  handleContextCommand,
@@ -37429,6 +38244,32 @@ function createSessionStatusTool(opts) {
37429
38244
  }
37430
38245
  } catch {}
37431
38246
  const groupActivation = resolved.entry.chatType === "group" || resolved.entry.chatType === "channel" || resolved.key.includes(":group:") || resolved.key.includes(":channel:") ? normalizeGroupActivation(resolved.entry.groupActivation) ?? "mention" : void 0;
38247
+ const baseUrl = cfg.models?.providers?.[providerForCard]?.baseUrl;
38248
+ let engineLine;
38249
+ let hardwareLine;
38250
+ let costOverrideUsd;
38251
+ let costLineSuffix;
38252
+ try {
38253
+ const breakdown = await buildCostBreakdown({
38254
+ baseUrl,
38255
+ provider: providerForCard,
38256
+ modelId: configured.model,
38257
+ config: cfg,
38258
+ usage: {
38259
+ input: resolved.entry.inputTokens,
38260
+ output: resolved.entry.outputTokens
38261
+ }
38262
+ });
38263
+ engineLine = breakdown.engineLine;
38264
+ hardwareLine = breakdown.hardwareLine;
38265
+ costOverrideUsd = breakdown.instanceCostUsd;
38266
+ costLineSuffix = breakdown.costLineSuffix;
38267
+ } catch {
38268
+ engineLine = void 0;
38269
+ hardwareLine = void 0;
38270
+ costOverrideUsd = void 0;
38271
+ costLineSuffix = void 0;
38272
+ }
37432
38273
  const queueSettings = resolveQueueSettings({
37433
38274
  cfg,
37434
38275
  channel: resolved.entry.channel ?? resolved.entry.lastChannel ?? "unknown",
@@ -37474,6 +38315,10 @@ function createSessionStatusTool(opts) {
37474
38315
  dropPolicy: queueSettings.dropPolicy,
37475
38316
  showDetails: queueOverrides
37476
38317
  },
38318
+ engineLine,
38319
+ hardwareLine,
38320
+ costOverrideUsd,
38321
+ costLineSuffix,
37477
38322
  includeTranscriptUsage: false
37478
38323
  });
37479
38324
  return {
@@ -40982,6 +41827,86 @@ async function handleInlineActions(params) {
40982
41827
  };
40983
41828
  }
40984
41829
 
41830
+ //#endregion
41831
+ //#region src/auto-reply/reply/middleware-context-warning.ts
41832
+ /** Threshold (fraction of context window) that triggers the soft warning. */
41833
+ const CONTEXT_WARNING_THRESHOLD = .85;
41834
+ /**
41835
+ * Threshold that triggers proactive compaction in `prepareReplyTurn`.
41836
+ * Higher than the soft warning so the user sees the heads-up first;
41837
+ * compaction runs the next turn the threshold is observed.
41838
+ */
41839
+ const CONTEXT_PROACTIVE_COMPACT_THRESHOLD = .9;
41840
+ /**
41841
+ * Pure decision for "should `prepareReplyTurn` run proactive compaction
41842
+ * before the next turn?" — extracted so the trigger logic is unit-testable
41843
+ * without mocking the rest of the prep pipeline.
41844
+ *
41845
+ * Returns true ONLY when:
41846
+ * - we have a session id (otherwise compaction has no target),
41847
+ * - we have a positive context window,
41848
+ * - we have a positive cumulative usage from the previous turn,
41849
+ * - usage / window ≥ CONTEXT_PROACTIVE_COMPACT_THRESHOLD.
41850
+ */
41851
+ function shouldProactivelyCompact(args) {
41852
+ if (!args.sessionId) return false;
41853
+ if (!args.contextTokens || args.contextTokens <= 0) return false;
41854
+ const usage = args.totalTokens ?? 0;
41855
+ if (usage <= 0) return false;
41856
+ return usage / args.contextTokens >= CONTEXT_PROACTIVE_COMPACT_THRESHOLD;
41857
+ }
41858
+ /**
41859
+ * Read the model's context-window size, falling back to the global
41860
+ * default when the model isn't in the registry yet.
41861
+ */
41862
+ function resolveContextWindow(modelId) {
41863
+ const fromRegistry = lookupContextTokens(modelId);
41864
+ if (fromRegistry && fromRegistry > 0) return fromRegistry;
41865
+ return DEFAULT_CONTEXT_TOKENS;
41866
+ }
41867
+ /**
41868
+ * After-turn hook that surfaces a one-time soft warning when usage
41869
+ * crosses the context threshold. Mutates the result text to append
41870
+ * the warning when triggered, and persists `contextWarningSent: true`
41871
+ * on the session entry so the warning doesn't fire again.
41872
+ */
41873
+ function withContextUsageWarning() {
41874
+ return (next) => async (params) => {
41875
+ const result = await next(params);
41876
+ if (result.outbound.action === "drop") return result;
41877
+ if (!params.sessionKey) return result;
41878
+ const usage = result.rawResult.meta.agentMeta?.usage?.total ?? 0;
41879
+ if (usage <= 0) return result;
41880
+ if (usage / resolveContextWindow(params.modelId ?? result.modelId) < CONTEXT_WARNING_THRESHOLD) return result;
41881
+ const agentId = resolveAgentIdFromSessionKey(params.sessionKey);
41882
+ const storePath = resolveStorePath(params.config.session?.store, { agentId });
41883
+ let alreadyWarned = false;
41884
+ try {
41885
+ await updateSessionStoreEntry({
41886
+ storePath,
41887
+ sessionKey: params.sessionKey,
41888
+ update: async (entry) => {
41889
+ if (entry.contextWarningSent === true) {
41890
+ alreadyWarned = true;
41891
+ return null;
41892
+ }
41893
+ return { contextWarningSent: true };
41894
+ }
41895
+ });
41896
+ } catch (err) {
41897
+ logVerbose(`context-warning: failed to persist contextWarningSent flag for ${params.sessionKey}: ${String(err)}`);
41898
+ return result;
41899
+ }
41900
+ if (alreadyWarned) return result;
41901
+ const trimmedText = result.text.trimEnd();
41902
+ const separator = trimmedText ? "\n\n" : "";
41903
+ return {
41904
+ ...result,
41905
+ text: `${trimmedText}${separator}${SESSION_CONTEXT_WARNING_MESSAGE}`
41906
+ };
41907
+ };
41908
+ }
41909
+
40985
41910
  //#endregion
40986
41911
  //#region src/auto-reply/reply/session-reset-model.ts
40987
41912
  function splitBody(body) {
@@ -41151,7 +42076,7 @@ async function deliverSessionMaintenanceWarning(params) {
41151
42076
  return;
41152
42077
  }
41153
42078
  try {
41154
- const { deliverOutboundPayloads } = await import("./deliver-Cjyb6h4g.js").then((n) => n.n);
42079
+ const { deliverOutboundPayloads } = await import("./deliver-f3cIWxXT.js").then((n) => n.n);
41155
42080
  await deliverOutboundPayloads({
41156
42081
  cfg: params.cfg,
41157
42082
  channel,
@@ -41878,7 +42803,7 @@ async function prepareReplyTurn(ctx, opts, configOverride) {
41878
42803
  typing.cleanup();
41879
42804
  return {
41880
42805
  kind: "early-reply",
41881
- reply: { text: SESSION_OVERFLOW_MESSAGE }
42806
+ reply: { text: SESSION_COMPACTION_FAILED_MESSAGE }
41882
42807
  };
41883
42808
  }
41884
42809
  await applyResetModelOverride({
@@ -41991,6 +42916,82 @@ async function prepareReplyTurn(ctx, opts, configOverride) {
41991
42916
  };
41992
42917
  directives = inlineActionResult.directives;
41993
42918
  abortedLastRun = inlineActionResult.abortedLastRun ?? abortedLastRun;
42919
+ if (shouldProactivelyCompact({
42920
+ totalTokens: sessionEntry.totalTokens,
42921
+ contextTokens,
42922
+ sessionId: sessionEntry.sessionId
42923
+ })) {
42924
+ if (resolvedOpts?.onBlockReply) try {
42925
+ await resolvedOpts.onBlockReply({ text: SESSION_COMPACTING_MESSAGE });
42926
+ } catch (err) {
42927
+ logVerbose(`proactive-compact: inline status delivery failed: ${String(err)}`);
42928
+ }
42929
+ if (isEmbeddedPiRunActive(sessionEntry.sessionId)) {
42930
+ abortEmbeddedPiRun(sessionEntry.sessionId);
42931
+ await waitForEmbeddedPiRunEnd(sessionEntry.sessionId, 15e3);
42932
+ }
42933
+ let compactResult;
42934
+ try {
42935
+ compactResult = await compactEmbeddedPiSession({
42936
+ sessionId: sessionEntry.sessionId,
42937
+ sessionKey,
42938
+ messageChannel: command.channel,
42939
+ groupId: sessionEntry.groupId,
42940
+ groupChannel: sessionEntry.groupChannel,
42941
+ groupSpace: sessionEntry.space,
42942
+ spawnedBy: sessionEntry.spawnedBy,
42943
+ sessionFile: resolveSessionFilePath(sessionEntry.sessionId, sessionEntry, resolveSessionFilePathOptions({
42944
+ agentId,
42945
+ storePath
42946
+ })),
42947
+ workspaceDir,
42948
+ agentDir,
42949
+ config: cfg,
42950
+ skillsSnapshot: sessionEntry.skillsSnapshot,
42951
+ provider,
42952
+ model,
42953
+ thinkLevel: resolvedThinkLevel,
42954
+ reasoningLevel: resolvedReasoningLevel,
42955
+ trigger: "overflow",
42956
+ senderIsOwner: command.senderIsOwner,
42957
+ ownerNumbers: command.ownerList.length > 0 ? command.ownerList : void 0
42958
+ });
42959
+ } catch (err) {
42960
+ logVerbose(`proactive-compact: compactor threw for ${sessionKey}: ${String(err)}`);
42961
+ compactResult = {
42962
+ ok: false,
42963
+ compacted: false,
42964
+ reason: String(err)
42965
+ };
42966
+ }
42967
+ if (compactResult.ok && compactResult.compacted) await incrementCompactionCount({
42968
+ sessionEntry,
42969
+ sessionStore,
42970
+ sessionKey,
42971
+ storePath,
42972
+ tokensAfter: compactResult.result?.tokensAfter
42973
+ });
42974
+ else {
42975
+ logVerbose(`proactive-compact: failed for ${sessionKey} (${compactResult.reason ?? "unknown"})`);
42976
+ if (storePath) try {
42977
+ await updateSessionStoreEntry({
42978
+ storePath,
42979
+ sessionKey,
42980
+ update: async (entry) => {
42981
+ if (entry.endedReason === "context_overflow") return null;
42982
+ return { endedReason: "context_overflow" };
42983
+ }
42984
+ });
42985
+ } catch (err) {
42986
+ logVerbose(`proactive-compact: failed to mark session sealed: ${String(err)}`);
42987
+ }
42988
+ typing.cleanup();
42989
+ return {
42990
+ kind: "early-reply",
42991
+ reply: { text: SESSION_COMPACTION_FAILED_MESSAGE }
42992
+ };
42993
+ }
42994
+ }
41994
42995
  await stageSandboxMedia({
41995
42996
  ctx,
41996
42997
  sessionCtx,
@@ -51602,7 +52603,7 @@ async function runEmbeddedPiAgent(params) {
51602
52603
  error: err
51603
52604
  });
51604
52605
  }
51605
- const MAX_OVERFLOW_COMPACTION_ATTEMPTS = 3;
52606
+ const MAX_OVERFLOW_COMPACTION_ATTEMPTS = 1;
51606
52607
  const MAX_RUN_LOOP_ITERATIONS = resolveMaxRunRetryIterations(profileCandidates.length);
51607
52608
  let overflowCompactionAttempts = 0;
51608
52609
  let toolResultTruncationAttempted = false;
@@ -52625,8 +53626,8 @@ function extractErrorMessage(err) {
52625
53626
  function buildBoundaryResult(params) {
52626
53627
  const profile = resolveModelProfile(params.provider && params.modelId ? `${params.provider}/${params.modelId}` : "", params.config.models?.profiles);
52627
53628
  return {
52628
- text: SESSION_OVERFLOW_MESSAGE,
52629
- rawText: SESSION_OVERFLOW_MESSAGE,
53629
+ text: SESSION_COMPACTION_FAILED_MESSAGE,
53630
+ rawText: SESSION_COMPACTION_FAILED_MESSAGE,
52630
53631
  outbound: {
52631
53632
  action: "deliver",
52632
53633
  reason: "deliver"
@@ -52637,7 +53638,7 @@ function buildBoundaryResult(params) {
52637
53638
  profile,
52638
53639
  didSendViaMessagingTool: false,
52639
53640
  rawResult: {
52640
- payloads: [{ text: SESSION_OVERFLOW_MESSAGE }],
53641
+ payloads: [{ text: SESSION_COMPACTION_FAILED_MESSAGE }],
52641
53642
  meta: {
52642
53643
  durationMs: Date.now() - params.startTime,
52643
53644
  agentMeta: {
@@ -52696,62 +53697,6 @@ function withContextOverflowRecovery() {
52696
53697
  };
52697
53698
  }
52698
53699
 
52699
- //#endregion
52700
- //#region src/auto-reply/reply/middleware-context-warning.ts
52701
- /** Threshold (fraction of context window) that triggers the soft warning. */
52702
- const CONTEXT_WARNING_THRESHOLD = .85;
52703
- /**
52704
- * Read the model's context-window size, falling back to the global
52705
- * default when the model isn't in the registry yet.
52706
- */
52707
- function resolveContextWindow(modelId) {
52708
- const fromRegistry = lookupContextTokens(modelId);
52709
- if (fromRegistry && fromRegistry > 0) return fromRegistry;
52710
- return DEFAULT_CONTEXT_TOKENS;
52711
- }
52712
- /**
52713
- * After-turn hook that surfaces a one-time soft warning when usage
52714
- * crosses the context threshold. Mutates the result text to append
52715
- * the warning when triggered, and persists `contextWarningSent: true`
52716
- * on the session entry so the warning doesn't fire again.
52717
- */
52718
- function withContextUsageWarning() {
52719
- return (next) => async (params) => {
52720
- const result = await next(params);
52721
- if (result.outbound.action === "drop") return result;
52722
- if (!params.sessionKey) return result;
52723
- const usage = result.rawResult.meta.agentMeta?.usage?.total ?? 0;
52724
- if (usage <= 0) return result;
52725
- if (usage / resolveContextWindow(params.modelId ?? result.modelId) < CONTEXT_WARNING_THRESHOLD) return result;
52726
- const agentId = resolveAgentIdFromSessionKey(params.sessionKey);
52727
- const storePath = resolveStorePath(params.config.session?.store, { agentId });
52728
- let alreadyWarned = false;
52729
- try {
52730
- await updateSessionStoreEntry({
52731
- storePath,
52732
- sessionKey: params.sessionKey,
52733
- update: async (entry) => {
52734
- if (entry.contextWarningSent === true) {
52735
- alreadyWarned = true;
52736
- return null;
52737
- }
52738
- return { contextWarningSent: true };
52739
- }
52740
- });
52741
- } catch (err) {
52742
- logVerbose(`context-warning: failed to persist contextWarningSent flag for ${params.sessionKey}: ${String(err)}`);
52743
- return result;
52744
- }
52745
- if (alreadyWarned) return result;
52746
- const trimmedText = result.text.trimEnd();
52747
- const separator = trimmedText ? "\n\n" : "";
52748
- return {
52749
- ...result,
52750
- text: `${trimmedText}${separator}${SESSION_CONTEXT_WARNING_MESSAGE}`
52751
- };
52752
- };
52753
- }
52754
-
52755
53700
  //#endregion
52756
53701
  //#region src/auto-reply/reply/middleware-diagnostic-logging.ts
52757
53702
  function deriveChannel(ctx) {
@@ -57931,7 +58876,7 @@ function readSlackExternalArgMenuToken(raw) {
57931
58876
  }
57932
58877
  let commandsRegistry;
57933
58878
  async function getCommandsRegistry() {
57934
- if (!commandsRegistry) commandsRegistry = await import("./commands-registry-DFYDtKr_.js").then((n) => n.t);
58879
+ if (!commandsRegistry) commandsRegistry = await import("./commands-registry-DG2kGyg5.js").then((n) => n.t);
57935
58880
  return commandsRegistry;
57936
58881
  }
57937
58882
  function encodeSlackCommandArgValue(parts) {
@@ -58334,7 +59279,7 @@ async function registerSlackMonitorSlashCommands(params) {
58334
59279
  });
58335
59280
  const deliverSlashPayloads = async (replies) => {
58336
59281
  const [{ deliverSlackSlashReplies }, { resolveChunkMode }, { resolveMarkdownTableMode }] = await Promise.all([
58337
- import("./replies-BYF1gbJf.js").then((n) => n.r),
59282
+ import("./replies-0nzkXt6o.js").then((n) => n.r),
58338
59283
  import("./chunk-CAZujdOi.js").then((n) => n.s),
58339
59284
  import("./markdown-tables-jQzXAsf3.js").then((n) => n.t)
58340
59285
  ]);
@@ -58389,7 +59334,7 @@ async function registerSlackMonitorSlashCommands(params) {
58389
59334
  let nativeCommands = [];
58390
59335
  if (nativeEnabled) {
58391
59336
  reg = await getCommandsRegistry();
58392
- const skillCommands = nativeSkillsEnabled ? (await import("./skill-commands-CKm7eCw6.js").then((n) => n.a)).listSkillCommandsForAgents({ cfg }) : [];
59337
+ const skillCommands = nativeSkillsEnabled ? (await import("./skill-commands-D0xAWG0l.js").then((n) => n.a)).listSkillCommandsForAgents({ cfg }) : [];
58393
59338
  nativeCommands = reg.listNativeCommandSpecsForConfig(cfg, {
58394
59339
  skillCommands,
58395
59340
  provider: "slack"