@symerian/symi 3.5.3 → 3.5.5

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-8EuVoCbs.js} +11 -11
  2. package/dist/{agent-BsRlH9Ez.js → agent-B87OYNFx.js} +9 -9
  3. package/dist/{agents-Ch38fapn.js → agents-CNbjbSD0.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-BL4lqaJL.js} +8 -8
  7. package/dist/{auth-choice-O55PGflm.js → auth-choice-CB0rQByJ.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-D-ssxnQN.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-BEM8ruys.js → channel-options-DLV6zIpW.js} +2 -2
  28. package/dist/{channel-options-zAbgRuGY.js → channel-options-_DJXj921.js} +2 -2
  29. package/dist/{channels-cli-cRWPvOQD.js → channels-cli-2OTAQPvZ.js} +54 -53
  30. package/dist/{channels-cli-DdKnAzW9.js → channels-cli-CUsX2v-1.js} +54 -53
  31. package/dist/{chrome-BKUACyeO.js → chrome-3jl2ulOE.js} +8 -8
  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-DPjznJQ-.js → chrome-OTJg3QKn.js} +1 -1
  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--UhNWFtQ.js → cli-D4cMWhob.js} +36 -35
  38. package/dist/{cli-BJDlZfYi.js → cli-Qq7pr2SX.js} +36 -35
  39. package/dist/{command-registry-COpZWfkh.js → command-registry-Br9vlIL_.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-CKLoZFMQ.js} +3 -3
  45. package/dist/{completion-cli-DVF5x7Kp.js → completion-cli-P5zBWNnc.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-kN07V9j6.js → config-cli-CcJOubCt.js} +3 -3
  49. package/dist/{config-cli-DaPePEIB.js → config-cli-NvqRZAqr.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-id9imsuH.js → configure-B1RJ6bi3.js} +22 -22
  55. package/dist/{configure-C9Z4clKW.js → configure-C7BfUqKR.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-DTRkeYm3.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-Be3Of_A2.js} +2 -2
  83. package/dist/{doctor-completion-Dv6aw9I2.js → doctor-completion-Dco2Lmvy.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-DF-S-bKo.js → gateway-cli-BQAh5DqM.js} +86 -85
  93. package/dist/{gateway-cli-C1yf0Kx4.js → gateway-cli-XV8T-ix8.js} +84 -83
  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-1FOCi0nn.js} +62 -61
  97. package/dist/{glass-ui-ws-BZJKBK5D.js → glass-ui-ws-CqGzDNV7.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-B_d8Cv16.js → hooks-cli-BPa-ssdB.js} +42 -41
  101. package/dist/{hooks-cli-CpDJa8fo.js → hooks-cli-D7iTDry_.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-rvtFoeFT.js → manager-Bt-1HGg9.js} +1 -1
  117. package/dist/{manager-DcZUW1bz.js → manager-CC13EPO9.js} +1 -1
  118. package/dist/{manager-CsxTf96V.js → manager-Ck1YSfr6.js} +1 -1
  119. package/dist/{manager-xeIkDkmx.js → manager-DghM7T-b.js} +1 -1
  120. package/dist/{memory-D8JRYEYq.js → memory-CgWOtF4K.js} +4 -4
  121. package/dist/{memory-cli-DZtv3G9o.js → memory-cli-DGheAg5i.js} +7 -7
  122. package/dist/{memory-cli-rORHUdUV.js → memory-cli-vN3fGs79.js} +7 -7
  123. package/dist/{memory-CeB8eMPH.js → memory-d0YI5Lr0.js} +4 -4
  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-CBw1pGIq.js} +17 -17
  129. package/dist/{models-cli-DidUOdbx.js → models-cli-BBReZHNq.js} +46 -45
  130. package/dist/{models-cli-DiyNuQ5w.js → models-cli-Bmh1S3iG.js} +49 -48
  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-Csj4sOF5.js} +18 -18
  144. package/dist/{onboard-C1PSYsJY.js → onboard-LVUmCZhX.js} +18 -18
  145. package/dist/{onboard-channels-DvNWHvx3.js → onboard-channels-mrSIlZDB.js} +7 -7
  146. package/dist/{onboard-channels-BSt89ffO.js → onboard-channels-vDtX0e0w.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-Ce0PyZFq.js → onboarding-D2VmoKU1.js} +16 -16
  158. package/dist/{onboarding-D4SGY_zG.js → onboarding-DojADc8N.js} +16 -16
  159. package/dist/{onboarding.finalize-TkbmJzg5.js → onboarding.finalize-Bi1wSEtw.js} +28 -28
  160. package/dist/{onboarding.finalize-BDPrr9CT.js → onboarding.finalize-C4BwVw6u.js} +26 -26
  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-helpers-nFK_hP2q.js → pi-embedded-helpers-BBiyNXkS.js} +1 -1
  171. package/dist/{pi-embedded-helpers-DVolpQ34.js → pi-embedded-helpers-CDzBxa-P.js} +1 -1
  172. package/dist/{pi-embedded-BPuUM-gD.js → pi-embedded-zSv7VKNQ.js} +1265 -428
  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-CxUYRmLh.js → plugin-registry-Dq6OJ45H.js} +2 -2
  178. package/dist/{plugin-registry-V5jShvbP.js → plugin-registry-L1h7mxjX.js} +2 -2
  179. package/dist/plugin-sdk/auto-reply/reply/commands-info.d.ts +1 -0
  180. package/dist/plugin-sdk/auto-reply/status.d.ts +13 -0
  181. package/dist/plugin-sdk/config/types.models.d.ts +5 -0
  182. package/dist/plugin-sdk/config/zod-schema.core.d.ts +11 -0
  183. package/dist/plugin-sdk/config/zod-schema.d.ts +5 -0
  184. package/dist/plugin-sdk/cost/benchmark.d.ts +36 -0
  185. package/dist/plugin-sdk/cost/breakdown.d.ts +63 -0
  186. package/dist/plugin-sdk/cost/gpu-inference.d.ts +52 -0
  187. package/dist/plugin-sdk/cost/rates.d.ts +32 -0
  188. package/dist/plugin-sdk/cost/serving-discovery.d.ts +54 -0
  189. package/dist/plugin-sdk/cost/summary.d.ts +40 -0
  190. package/dist/plugin-sdk/index.js +19 -8
  191. package/dist/{plugins-cli-BthQwo7n.js → plugins-cli-BEIKMoVH.js} +43 -42
  192. package/dist/{plugins-cli-CMAwepRk.js → plugins-cli-C9ehLXaT.js} +43 -42
  193. package/dist/{program-context-BVEz8AgF.js → program-context-Bh5wzWdC.js} +48 -40
  194. package/dist/{program-iw_XyVhs.js → program-iTd2Dei7.js} +46 -45
  195. package/dist/{prompt-select-styled-CF4qV0_M.js → prompt-select-styled-CNFytCD3.js} +32 -32
  196. package/dist/{prompt-select-styled-D3RAY7pg.js → prompt-select-styled-fXotfbCt.js} +31 -31
  197. package/dist/{provider-auth-helpers-BTBjOyhO.js → provider-auth-helpers-DBrH-cce.js} +6 -6
  198. package/dist/{provider-auth-helpers-Dxo0v0UO.js → provider-auth-helpers-Dho1n21x.js} +6 -6
  199. package/dist/{push-apns-DIIbGT1M.js → push-apns-DYYY9NOE.js} +1 -1
  200. package/dist/{push-apns-B8Wg3Hqw.js → push-apns-DpyCFRTu.js} +1 -1
  201. package/dist/{pw-ai-kkF0QaDF.js → pw-ai-DBAtSFTB.js} +2 -2
  202. package/dist/{pw-ai-BFS9ezWe.js → pw-ai-DOAsQ5NX.js} +2 -2
  203. package/dist/{pw-ai-_prsAw5O.js → pw-ai-DQZa9DUQ.js} +2 -2
  204. package/dist/{pw-ai-D2pEVS5n.js → pw-ai-DY_6l11g.js} +2 -2
  205. package/dist/{qr-cli-CcAzgz_N.js → qr-cli-D2A-IU0Y.js} +1 -1
  206. package/dist/{qr-cli-KmGkQDBF.js → qr-cli-DHpiebkG.js} +1 -1
  207. package/dist/{redact-identifier-CXvHJXk9.js → redact-identifier-BOxAUdff.js} +1 -1
  208. package/dist/{register.agent-8XsVRuWC.js → register.agent-BYpBNbHe.js} +61 -60
  209. package/dist/{register.agent-D-OIszeY.js → register.agent-DceNHGi_.js} +63 -62
  210. package/dist/register.configure-09lIIUvq.js +131 -0
  211. package/dist/register.configure-UUZqL0Ck.js +135 -0
  212. package/dist/{register.maintenance-CBYqsXkf.js → register.maintenance-CsoEyVyl.js} +63 -62
  213. package/dist/{register.maintenance-CjM8sJqH.js → register.maintenance-DdX8GZpv.js} +64 -63
  214. package/dist/{register.message-kSIASKVK.js → register.message-CAM62MaW.js} +41 -40
  215. package/dist/{register.message-DnljWvZP.js → register.message-RYn7LD6-.js} +40 -39
  216. package/dist/{register.onboard-Vj1-Ike1.js → register.onboard-CoRtNlNa.js} +28 -28
  217. package/dist/{register.onboard-eDNn1pdd.js → register.onboard-DhR5o8KO.js} +28 -28
  218. package/dist/{register.setup-CmhspsS8.js → register.setup-CEjhFwYz.js} +28 -28
  219. package/dist/{register.setup-DMaoMWRD.js → register.setup-CI_RT1Wa.js} +28 -28
  220. package/dist/{register.status-health-sessions-CJqCoqAi.js → register.status-health-sessions-8N1xEKl7.js} +35 -35
  221. package/dist/{register.status-health-sessions-r3F9H8b0.js → register.status-health-sessions-DNlsQ-xt.js} +36 -36
  222. package/dist/{register.subclis-RqX1a2aL.js → register.subclis-D1qkm3UK.js} +37 -29
  223. package/dist/{replies-BYF1gbJf.js → replies-0nzkXt6o.js} +1 -1
  224. package/dist/{replies-B91-OngF.js → replies-C5CBlnFS.js} +1 -1
  225. package/dist/{replies-DAYTg6Mb.js → replies-D0FYSIJg.js} +1 -1
  226. package/dist/{replies-UP2sglaR.js → replies-_DV8VSSj.js} +1 -1
  227. package/dist/{resolve-route-Zww0Y-HJ.js → resolve-route-CnTdHVgw.js} +1 -1
  228. package/dist/{resolve-route-CmZ7XjmB.js → resolve-route-D0NrCHnr.js} +1 -1
  229. package/dist/{routes-BfeVDhod.js → routes-CPMVuvoz.js} +3 -3
  230. package/dist/{routes-y2Ww0pum.js → routes-DIyAmLYR.js} +3 -3
  231. package/dist/{rpc-DZCrGGH5.js → rpc-B2BLRS45.js} +2 -2
  232. package/dist/{rpc-RIkh5F9v.js → rpc-gUsL9Mqf.js} +2 -2
  233. package/dist/{run-main-6pE2fYXT.js → run-main-hKg6FDt6.js} +61 -60
  234. package/dist/{sandbox-DQdjlC-w.js → sandbox-61-kshSF.js} +5 -5
  235. package/dist/{sandbox-BjQ6n3zl.js → sandbox-J92UBQK8.js} +5 -5
  236. package/dist/{sandbox-cli-CTYAHFyM.js → sandbox-cli-D9v0jhBb.js} +8 -8
  237. package/dist/{sandbox-cli-C0IVf8AS.js → sandbox-cli-DJgF-r8G.js} +8 -8
  238. package/dist/{security-cli-B8VyQJcl.js → security-cli-CZix5cXq.js} +13 -13
  239. package/dist/{security-cli-D0oErb9f.js → security-cli-J9J0qvDy.js} +13 -13
  240. package/dist/{send-Cxu1tl56.js → send-B0jHSNMF.js} +1 -1
  241. package/dist/{send-Cuk_Rjss.js → send-C75uSv6p.js} +1 -1
  242. package/dist/{send-BBfSp-8Q.js → send-Dq252-bi.js} +1 -1
  243. package/dist/{server-context-BFCh7pUb.js → server-context-D-82OTsT.js} +5 -5
  244. package/dist/{server-context-YlgRz1wC.js → server-context-SbbjNkPL.js} +5 -5
  245. package/dist/{server-methods-BWCAXrQJ.js → server-methods-CXoipzKe.js} +31 -31
  246. package/dist/{server-methods-BxsThjMp.js → server-methods-bIWvtXlT.js} +31 -31
  247. package/dist/{server-node-events-AZFI44cm.js → server-node-events-BD8wnswX.js} +40 -39
  248. package/dist/{server-node-events-C10Bhdag.js → server-node-events-nQkNuQOx.js} +39 -38
  249. package/dist/{service-vsb7_8MA.js → service-BF50XyKr.js} +2 -2
  250. package/dist/{service-BBw78ATM.js → service-Ccv3Zi5_.js} +2 -2
  251. package/dist/{session-cost-usage-CqLUlh7S.js → session-cost-usage-CJWHHY-C.js} +1 -1
  252. package/dist/{session-cost-usage-D6Ocwmq1.js → session-cost-usage-D3mgssM_.js} +1 -1
  253. package/dist/{session-utils-BZnPW904.js → session-utils-Cs1jlD-q.js} +3 -3
  254. package/dist/{session-utils-BGw_xwXK.js → session-utils-Zpe3t68b.js} +3 -3
  255. package/dist/{sessions-uS7rV-lI.js → sessions-BSmT7vGX.js} +3 -3
  256. package/dist/{sessions-DHPf5TzB.js → sessions-Dn6VXn4p.js} +1 -1
  257. package/dist/{sessions-optZRB57.js → sessions-Dxf5Kjig.js} +1 -1
  258. package/dist/{shared-CfBMF1VB.js → shared-BJRsBGGr.js} +2 -2
  259. package/dist/{shared-CVXZtpIq.js → shared-BmjlTHYU.js} +2 -2
  260. package/dist/{shared-BucaCyaw.js → shared-Ck6cf10x.js} +1 -1
  261. package/dist/{shared-k1QjV3ys.js → shared-Crfo8y70.js} +1 -1
  262. package/dist/{skill-commands-CKm7eCw6.js → skill-commands-D0xAWG0l.js} +1 -1
  263. package/dist/{skill-commands-DAtpPeXi.js → skill-commands-DKkiQJxU.js} +1 -1
  264. package/dist/{skill-commands-BoMrW3WV.js → skill-commands-JIccKWkf.js} +1 -1
  265. package/dist/{skill-commands-yPirQFOb.js → skill-commands-KnANH5Qm.js} +1 -1
  266. package/dist/{skills-cli-CcWFIcOR.js → skills-cli-BZF5mcG5.js} +7 -7
  267. package/dist/{skills-cli-DcJBgk5R.js → skills-cli-C9F-zLWe.js} +3 -3
  268. package/dist/{skills-install-CcW780Kq.js → skills-install-QOHQrX6P.js} +4 -4
  269. package/dist/{skills-install-CbRsCzAG.js → skills-install-X12kifP1.js} +4 -4
  270. package/dist/{skills-status-CLzaY4r2.js → skills-status-6LVKpabC.js} +1 -1
  271. package/dist/{ssrf-q6hBiAOi.js → ssrf-BCSnhba8.js} +13 -2
  272. package/dist/{ssrf-oI58TMOb.js → ssrf-DNhyFMRW.js} +13 -2
  273. package/dist/{status-BxD8CjLr.js → status-CIZltjd7.js} +2 -2
  274. package/dist/{status-Cv8N2kIe.js → status-CTDVhXdb.js} +20 -20
  275. package/dist/{status-CZc22Lqb.js → status-CWzbgPAZ.js} +2 -2
  276. package/dist/{status-B5sjPQS6.js → status-Dgg3SlRY.js} +20 -20
  277. package/dist/{status.update-B52bM2Tg.js → status.update-CdTtmVpp.js} +2 -2
  278. package/dist/{status.update-Bl_ewksT.js → status.update-_3qHPt0O.js} +2 -2
  279. package/dist/{subagent-registry-BnHgIGX-.js → subagent-registry-DQ_BPb-T.js} +130 -40
  280. package/dist/{synthesis-DvfrgkQU.js → synthesis-CDd1xqI3.js} +36 -35
  281. package/dist/{synthesis-CBIT6Vnk.js → synthesis-CSsmBmJc.js} +9 -9
  282. package/dist/{synthesis-o7Zdrwxz.js → synthesis-DIqhHKjV.js} +36 -35
  283. package/dist/{synthesis-7UL3pCpj.js → synthesis-XbEFEFK1.js} +8 -8
  284. package/dist/{system-cli-BAn07VkE.js → system-cli-DB9etQxq.js} +5 -5
  285. package/dist/{system-cli-BTZ8T0-Z.js → system-cli-szRqg1_v.js} +5 -5
  286. package/dist/{systemd-DCzA-V_E.js → systemd-Dic80Qni.js} +1 -1
  287. package/dist/{systemd-Cmn7zMqD.js → systemd-Dtydk5-z.js} +1 -1
  288. package/dist/{systemd-hints-CvIqgg9d.js → systemd-hints-DmDUq9JT.js} +4 -4
  289. package/dist/{systemd-hints-BlGehfA3.js → systemd-hints-bP8dBJ78.js} +4 -4
  290. package/dist/{systemd-linger-BUWYteOW.js → systemd-linger-BBxRNFXz.js} +2 -2
  291. package/dist/{systemd-linger-Bj4nK9ZB.js → systemd-linger-DjoQVcOq.js} +2 -2
  292. package/dist/{tui-XLWiN8Hm.js → tui-CEhOf9fk.js} +6 -6
  293. package/dist/{tui-B6mIUNPO.js → tui-Dp58oYvX.js} +6 -6
  294. package/dist/{tui-cli-byFYgg3c.js → tui-cli-DFaOwBwg.js} +12 -12
  295. package/dist/{tui-cli-CTK5_3rU.js → tui-cli-wxh3YpaV.js} +12 -12
  296. package/dist/{unified-runner-DnikxMFg.js → unified-runner-Bm3r8UOg.js} +130 -40
  297. package/dist/{unified-runner-BVvvnjXW.js → unified-runner-DN0asRIR.js} +1263 -426
  298. package/dist/{update-DxY1UB0k.js → update-BDo7wxMf.js} +1 -1
  299. package/dist/{update-EhDcBqN1.js → update-CcacbR32.js} +1 -1
  300. package/dist/{update-check-pFwV6W-z.js → update-check-A86nJKtZ.js} +1 -1
  301. package/dist/{update-check-H0DwvuqN.js → update-check-oEbS0voJ.js} +1 -1
  302. package/dist/{update-cli-C8IVRiDZ.js → update-cli-CK7nw0t0.js} +74 -73
  303. package/dist/{update-cli-BAdPKO1o.js → update-cli-kysdsvn3.js} +73 -72
  304. package/dist/{update-runner-CERd2XdT.js → update-runner-CQMv-ibM.js} +3 -3
  305. package/dist/{update-runner-7oHPAIND.js → update-runner-DHi359Tb.js} +3 -3
  306. package/dist/{usage-format-_37Bn-Jb.js → usage-format-DQJz-0qd.js} +0 -1
  307. package/dist/{usage-format-rxT5cEAf.js → usage-format-DeczTGI-.js} +0 -1
  308. package/dist/{webhooks-cli-3UJupWMP.js → webhooks-cli-C3g4MxCE.js} +3 -3
  309. package/dist/{webhooks-cli-BFpGMNrf.js → webhooks-cli-C3uyehJS.js} +3 -3
  310. package/dist/{with-timeout-Bn-ltLg1.js → with-timeout-B0ZJa7f2.js} +1 -1
  311. package/dist/{with-timeout-EXM-FP4_.js → with-timeout-GbJ1Yzsh.js} +1 -1
  312. package/extensions/outlook/src/graph-mail.test.ts +76 -0
  313. package/extensions/outlook/src/graph-mail.ts +7 -2
  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
@@ -9,12 +9,12 @@ import { _ as resolveAuthProfileDisplayLabel, a as markAuthProfileFailure, c as
9
9
  import { n as resolveCliName, t as formatCliCommand } from "./command-format-BrrHNE8r.js";
10
10
  import { _ as DEFAULT_MODEL, c as normalizeProviderId, d as resolveDefaultModelForAgent, f as resolveModelRefFromString, g as DEFAULT_CONTEXT_TOKENS, h as getProviderAdapter, i as findNormalizedProviderValue, m as resolveThinkingDefault, n as buildConfiguredAllowlistKeys, o as modelKey, p as resolveSubagentSpawnModelSelection, r as buildModelAliasIndex, s as normalizeModelRef$1, t as buildAllowedModelSet, u as resolveConfiguredModelRef, v as DEFAULT_PROVIDER } from "./model-selection-BqshlIZc.js";
11
11
  import { n as saveJsonFile, t as loadJsonFile } from "./json-file-CZ3ssFR9.js";
12
- import { $ as resolveSandboxContext, $t as resolveBrowserControlAuth, A as isGoogleModelApi, At as resolveSessionResetPolicy, B as isCompactionFailureError, Bt as resolveGroupSessionKey, C as sanitizeImageBlocks, Ct as INPUT_PROVENANCE_KIND_VALUES, D as extractToolResultId, Dt as resolveSessionKey, E as extractToolCallsFromAssistant, Et as normalizeInputProvenance, F as formatRawAssistantErrorForUi, Ft as canonicalizeMainSessionAlias, G as isRateLimitAssistantError, Gt as resolveBrowserConfig, H as isFailoverAssistantError, Ht as resolveSessionLockMaxHoldFromTimeout, I as getApiErrorPayloadFingerprint, J as isTransientHttpError, Jt as saveMediaBuffer, K as isRawApiErrorPayload, Kt as resolveProfile, L as isAuthAssistantError, M as classifyFailoverReason, Mt as resolveThreadFlag, N as formatAssistantErrorText, Nt as DEFAULT_RESET_TRIGGERS, O as downgradeOpenAIReasoningBlocks, Ot as evaluateSessionFreshness, P as formatBillingErrorMessage, Pt as resolveFreshSessionTotalTokens, Q as ensureSandboxWorkspaceForSession, Qt as ensureBrowserControlAuth, R as isBillingAssistantError, Rt as resolveMainSessionKey, S as sanitizeSessionMessagesImages, St as extractToolCallNames, T as resolveImageSanitizationLimits, Tt as hasInterSessionUserProvenance, U as isFailoverErrorMessage, Ut as createBrowserRouteContext, V as isContextOverflowError, Vt as acquireSessionWriteLock, W as isLikelyContextOverflowError, Wt as registerBrowserRoutes, X as parseImageSizeError, Xt as resolveExistingPathsWithinRoot, Y as parseImageDimensionError, Yt as DEFAULT_UPLOAD_DIR, Z as sanitizeUserFacingText, Zt as getBridgeAuthForPort, _ as validateAnthropicTurns, _t as normalizeSessionDeliveryFields, an as mergeAlsoAllowPolicy, at as loadSessionStore, b as isMessagingToolDuplicateNormalized, bt as capArrayByJsonBytes, c as normalizeChannelTargetInput, cn as stripPluginOnlyAllowlist, ct as updateLastRoute, d as parseReplyDirectives, dn as buildBootstrapContextFiles, dt as isCacheEnabled, en as applyOwnerOnlyToolPolicy, et as resolveSandboxRuntimeStatus, f as MEDIA_TOKEN_RE, fn as ensureSessionHeader, ft as resolveCacheTtlMs$1, g as initializeGlobalHookRunner, gt as normalizeDeliveryContext, h as getGlobalHookRunner, hn as sanitizeGoogleTurnOrdering, ht as mergeDeliveryContext, in as expandToolGroups, it as resolveAndPersistSessionFile, j as BILLING_ERROR_USER_MESSAGE, jt as resolveSessionResetType, k as isAntigravityClaude, kt as resolveChannelResetConfig, l as normalizeTargetForProvider, ln as compileGlobPatterns, lt as updateSessionStore, m as parseInlineDirectives$1, mn as resolveBootstrapTotalMaxChars, mt as deliveryContextKey, nn as collectExplicitAllowlist, o as normalizeReplyPayloadsForDelivery, on as normalizeToolName$1, ot as readSessionUpdatedAt, p as splitMediaFromOutput, pn as resolveBootstrapMaxChars, pt as deliveryContextFromSession, q as isTimeoutErrorMessage, qt as getMediaDir, rn as expandPolicyWithPluginGroups, rt as appendAssistantMessageToSessionTranscript, s as buildTargetResolverSignature, sn as resolveToolProfilePolicy, st as recordSessionMetaFromInbound, t as deliverOutboundPayloads, tn as buildPluginToolGroups, tt as extractDeliveryInfo, u as throwIfAborted, un as matchesAnyGlobPattern, ut as updateSessionStoreEntry, v as validateGeminiTurns, w as sanitizeToolResultImages, wt as applyInputProvenanceToUserMessage, x as normalizeTextForComparison, xt as countToolResults, y as pickFallbackThinkingLevel, yt as archiveSessionTranscripts, z as isCloudCodeAssistFormatError, zt as deriveSessionMetaPatch } from "./deliver-DTRkeYm3.js";
13
- 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-oI58TMOb.js";
12
+ import { $ as resolveSandboxContext, $t as resolveBrowserControlAuth, A as isGoogleModelApi, At as resolveSessionResetPolicy, B as isCompactionFailureError, Bt as resolveGroupSessionKey, C as sanitizeImageBlocks, Ct as INPUT_PROVENANCE_KIND_VALUES, D as extractToolResultId, Dt as resolveSessionKey, E as extractToolCallsFromAssistant, Et as normalizeInputProvenance, F as formatRawAssistantErrorForUi, Ft as canonicalizeMainSessionAlias, G as isRateLimitAssistantError, Gt as resolveBrowserConfig, H as isFailoverAssistantError, Ht as resolveSessionLockMaxHoldFromTimeout, I as getApiErrorPayloadFingerprint, J as isTransientHttpError, Jt as saveMediaBuffer, K as isRawApiErrorPayload, Kt as resolveProfile, L as isAuthAssistantError, M as classifyFailoverReason, Mt as resolveThreadFlag, N as formatAssistantErrorText, Nt as DEFAULT_RESET_TRIGGERS, O as downgradeOpenAIReasoningBlocks, Ot as evaluateSessionFreshness, P as formatBillingErrorMessage, Pt as resolveFreshSessionTotalTokens, Q as ensureSandboxWorkspaceForSession, Qt as ensureBrowserControlAuth, R as isBillingAssistantError, Rt as resolveMainSessionKey, S as sanitizeSessionMessagesImages, St as extractToolCallNames, T as resolveImageSanitizationLimits, Tt as hasInterSessionUserProvenance, U as isFailoverErrorMessage, Ut as createBrowserRouteContext, V as isContextOverflowError, Vt as acquireSessionWriteLock, W as isLikelyContextOverflowError, Wt as registerBrowserRoutes, X as parseImageSizeError, Xt as resolveExistingPathsWithinRoot, Y as parseImageDimensionError, Yt as DEFAULT_UPLOAD_DIR, Z as sanitizeUserFacingText, Zt as getBridgeAuthForPort, _ as validateAnthropicTurns, _t as normalizeSessionDeliveryFields, an as mergeAlsoAllowPolicy, at as loadSessionStore, b as isMessagingToolDuplicateNormalized, bt as capArrayByJsonBytes, c as normalizeChannelTargetInput, cn as stripPluginOnlyAllowlist, ct as updateLastRoute, d as parseReplyDirectives, dn as buildBootstrapContextFiles, dt as isCacheEnabled, en as applyOwnerOnlyToolPolicy, et as resolveSandboxRuntimeStatus, f as MEDIA_TOKEN_RE, fn as ensureSessionHeader, ft as resolveCacheTtlMs$1, g as initializeGlobalHookRunner, gt as normalizeDeliveryContext, h as getGlobalHookRunner, hn as sanitizeGoogleTurnOrdering, ht as mergeDeliveryContext, in as expandToolGroups, it as resolveAndPersistSessionFile, j as BILLING_ERROR_USER_MESSAGE, jt as resolveSessionResetType, k as isAntigravityClaude, kt as resolveChannelResetConfig, l as normalizeTargetForProvider, ln as compileGlobPatterns, lt as updateSessionStore, m as parseInlineDirectives$1, mn as resolveBootstrapTotalMaxChars, mt as deliveryContextKey, nn as collectExplicitAllowlist, o as normalizeReplyPayloadsForDelivery, on as normalizeToolName$1, ot as readSessionUpdatedAt, p as splitMediaFromOutput, pn as resolveBootstrapMaxChars, pt as deliveryContextFromSession, q as isTimeoutErrorMessage, qt as getMediaDir, rn as expandPolicyWithPluginGroups, rt as appendAssistantMessageToSessionTranscript, s as buildTargetResolverSignature, sn as resolveToolProfilePolicy, st as recordSessionMetaFromInbound, t as deliverOutboundPayloads, tn as buildPluginToolGroups, tt as extractDeliveryInfo, u as throwIfAborted, un as matchesAnyGlobPattern, ut as updateSessionStoreEntry, v as validateGeminiTurns, w as sanitizeToolResultImages, wt as applyInputProvenanceToUserMessage, x as normalizeTextForComparison, xt as countToolResults, y as pickFallbackThinkingLevel, yt as archiveSessionTranscripts, z as isCloudCodeAssistFormatError, zt as deriveSessionMetaPatch } from "./deliver-BiWlR84Y.js";
13
+ 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-DNhyFMRW.js";
14
14
  import { t as parseBooleanValue } from "./boolean-BsqeuxE6.js";
15
15
  import { i as resolveShellEnvFallbackTimeoutMs, n as getShellPathFromLoginShell, s as isTruthyEnvValue } from "./shell-env-B1lDWz4t.js";
16
16
  import { a as applyTestPluginDefaults, c as resolveMemorySlotDecision, d as isDangerousHostEnvVarName, i as safeStatSync, n as discoverSymiPlugins, o as normalizePluginsConfig, r as isPathInside, s as resolveEnableState, t as loadPluginManifestRegistry, u as isPathInsideWithRealpath } from "./manifest-registry-BGJu2aC-.js";
17
- import { C as rawDataToString, O as DEFAULT_AI_SNAPSHOT_MAX_CHARS, T as isSecureWebSocketUrl, x as ensureChromeExtensionRelayServer } from "./chrome-DPjznJQ-.js";
17
+ import { C as rawDataToString, O as DEFAULT_AI_SNAPSHOT_MAX_CHARS, T as isSecureWebSocketUrl, x as ensureChromeExtensionRelayServer } from "./chrome-OTJg3QKn.js";
18
18
  import { l as parseFrontmatterBlock } from "./frontmatter-CJEX1BrH.js";
19
19
  import { c as assertSandboxPath, d as resolveSandboxedMediaSource, f as applySkillEnvOverrides, i as resolveSkillsPromptForRun, l as resolveSandboxInputPath, n as buildWorkspaceSkillSnapshot, p as applySkillEnvOverridesFromSnapshot, r as loadWorkspaceSkillEntries, s as assertMediaNotDataUrl } from "./skills-Dm4gX4Tl.js";
20
20
  import { n as redactToolDetail } from "./redact-CSGZUFxa.js";
@@ -25,24 +25,24 @@ import { C as GATEWAY_CLIENT_MODES, S as GATEWAY_CLIENT_IDS, _ as isMarkdownCapa
25
25
  import { t as normalizeChatType } from "./chat-type-CE6cJOyt.js";
26
26
  import { n as resolveConversationLabel } from "./conversation-label-BVa8JTl2.js";
27
27
  import { i as resolveSlackAccount, n as listChannelPlugins, o as resolveSlackAppToken, r as normalizeChannelId$1, s as resolveSlackBotToken, t as getChannelPlugin } from "./plugins-B06cTFHC.js";
28
- import { _ as validateSlackBlocksArray, a as markdownToIRWithMeta, b as resolveSlackChannelId, c as MediaFetchError, d as fetchWithSsrFGuard, f as bindAbortRelay, g as parseSlackBlocksInput, h as resolveSlackWebClientOptions, i as renderMarkdownWithMarkers, l as fetchRemoteMedia, m as createSlackWebClient, o as getDefaultLocalRoots, p as fetchWithTimeout, s as loadWebMedia, t as sendMessageSlack, u as readResponseWithLimit, v as buildSlackBlocksFallbackText, y as parseSlackTarget } from "./send-Cuk_Rjss.js";
28
+ import { _ as validateSlackBlocksArray, a as markdownToIRWithMeta, b as resolveSlackChannelId, c as MediaFetchError, d as fetchWithSsrFGuard, f as bindAbortRelay, g as parseSlackBlocksInput, h as resolveSlackWebClientOptions, i as renderMarkdownWithMarkers, l as fetchRemoteMedia, m as createSlackWebClient, o as getDefaultLocalRoots, p as fetchWithTimeout, s as loadWebMedia, t as sendMessageSlack, u as readResponseWithLimit, v as buildSlackBlocksFallbackText, y as parseSlackTarget } from "./send-C75uSv6p.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 isSilentReplyText, t as SILENT_REPLY_TOKEN } from "./tokens-D_vCJSzF.js";
32
32
  import { a as logMessageProcessed, i as logLaneEnqueue, o as logMessageQueued, r as logLaneDequeue, s as logSessionStateChange, t as diag } from "./diagnostic-BALvP9wI.js";
33
33
  import { n as getDiagnosticSessionState } from "./diagnostic-session-state-BDfanaOY.js";
34
- 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-CsxTf96V.js";
34
+ 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-Ck1YSfr6.js";
35
35
  import { r as resolveCopilotApiToken, t as DEFAULT_COPILOT_API_BASE_URL } from "./github-copilot-token-uhEBNQfj.js";
36
36
  import { t as ensurePiAuthJsonFromAuthProfiles } from "./pi-auth-json-DCGR3yfh.js";
37
37
  import { a as resolveEffectiveMessagesConfig, i as resolveAckReaction, o as resolveHumanDelayConfig, r as resolveResponsePrefixTemplate, t as createReplyPrefixOptions } from "./reply-prefix-D0NzzC4I.js";
38
38
  import { c as normalizeExtraMemoryPaths, f as runTasksWithConcurrency, s as listMemoryFiles } from "./internal-BYHsj5p6.js";
39
39
  import { n as resolveMarkdownTableMode } from "./markdown-tables-CGqX2WvO.js";
40
- 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-DPZevjMh.js";
41
- 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-BoMrW3WV.js";
40
+ 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-BuOUfpmg.js";
41
+ 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-JIccKWkf.js";
42
42
  import { r as normalizeInboundTextNewlines, t as finalizeInboundContext } from "./inbound-context-DZqZj2qH.js";
43
43
  import { n as discoverModels, t as discoverAuthStorage } from "./pi-model-discovery-Rgm3jE5N.js";
44
44
  import { n as resolveAgentRoute, t as buildAgentSessionKey } from "./resolve-route-CDsQda0z.js";
45
- import { i as resolveSlackThreadTs, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-DAYTg6Mb.js";
45
+ import { i as resolveSlackThreadTs, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-D0FYSIJg.js";
46
46
  import { createRequire } from "node:module";
47
47
  import * as path$1 from "node:path";
48
48
  import path from "node:path";
@@ -4460,7 +4460,7 @@ async function getMemorySearchManager(params) {
4460
4460
  const wrapper = new FallbackMemoryManager({
4461
4461
  primary,
4462
4462
  fallbackFactory: async () => {
4463
- const { MemoryIndexManager } = await import("./manager-CsxTf96V.js").then((n) => n.t);
4463
+ const { MemoryIndexManager } = await import("./manager-Ck1YSfr6.js").then((n) => n.t);
4464
4464
  return await MemoryIndexManager.get(params);
4465
4465
  }
4466
4466
  }, () => QMD_MANAGER_CACHE.delete(cacheKey));
@@ -4473,7 +4473,7 @@ async function getMemorySearchManager(params) {
4473
4473
  }
4474
4474
  }
4475
4475
  try {
4476
- const { MemoryIndexManager } = await import("./manager-CsxTf96V.js").then((n) => n.t);
4476
+ const { MemoryIndexManager } = await import("./manager-Ck1YSfr6.js").then((n) => n.t);
4477
4477
  return { manager: await MemoryIndexManager.get(params) };
4478
4478
  } catch (err) {
4479
4479
  return {
@@ -10801,7 +10801,7 @@ async function routeReply(params) {
10801
10801
  const resolvedReplyToId = replyToId ?? (channelId === "slack" && threadId != null && threadId !== "" ? String(threadId) : void 0);
10802
10802
  const resolvedThreadId = channelId === "slack" ? null : threadId ?? null;
10803
10803
  try {
10804
- const { deliverOutboundPayloads } = await import("./deliver-DTRkeYm3.js").then((n) => n.n);
10804
+ const { deliverOutboundPayloads } = await import("./deliver-BiWlR84Y.js").then((n) => n.n);
10805
10805
  return {
10806
10806
  ok: true,
10807
10807
  messageId: (await deliverOutboundPayloads({
@@ -28056,7 +28056,6 @@ function formatTokenCount$1(value) {
28056
28056
  function formatUsd(value) {
28057
28057
  if (value === void 0 || !Number.isFinite(value)) return;
28058
28058
  if (value >= 1) return `$${value.toFixed(2)}`;
28059
- if (value >= .01) return `$${value.toFixed(2)}`;
28060
28059
  return `$${value.toFixed(4)}`;
28061
28060
  }
28062
28061
  function resolveModelCostConfig(params) {
@@ -28131,13 +28130,13 @@ function resolveRuntimeLabel(args) {
28131
28130
  return sessionKey !== resolveMainSessionKey({ session: { scope: args.sessionScope ?? "per-sender" } }).trim();
28132
28131
  })() ? "docker" : sessionKey ? "direct" : "unknown"}/${sandboxMode}`;
28133
28132
  }
28134
- const formatTokens = (total, contextTokens) => {
28133
+ const formatTokens$1 = (total, contextTokens) => {
28135
28134
  const ctx = contextTokens ?? null;
28136
28135
  if (total == null) return `?/${ctx ? formatTokenCount(ctx) : "?"}`;
28137
28136
  const pct = ctx ? Math.min(999, Math.round(total / ctx * 100)) : null;
28138
28137
  return `${formatTokenCount(total)}/${ctx ? formatTokenCount(ctx) : "?"}${pct !== null ? ` (${pct}%)` : ""}`;
28139
28138
  };
28140
- const formatContextUsageShort = (total, contextTokens) => `Context ${formatTokens(total, contextTokens ?? null)}`;
28139
+ const formatContextUsageShort = (total, contextTokens) => `Context ${formatTokens$1(total, contextTokens ?? null)}`;
28141
28140
  const formatQueueDetails = (queue) => {
28142
28141
  if (!queue) return "";
28143
28142
  const depth = typeof queue.depth === "number" ? `depth ${queue.depth}` : null;
@@ -28289,7 +28288,7 @@ function buildStatusMessage(args) {
28289
28288
  const updatedAt = entry?.updatedAt;
28290
28289
  const sessionLine = [`Session: ${args.sessionKey ?? "unknown"}`, typeof updatedAt === "number" ? `updated ${formatTimeAgo(now - updatedAt)}` : "no activity"].filter(Boolean).join(" • ");
28291
28290
  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;
28292
- const contextLine = [`Context: ${formatTokens(totalTokens, contextTokens ?? null)}`, `🧹 Compactions: ${entry?.compactionCount ?? 0}`].filter(Boolean).join(" · ");
28291
+ const contextLine = [`Context: ${formatTokens$1(totalTokens, contextTokens ?? null)}`, `🧹 Compactions: ${entry?.compactionCount ?? 0}`].filter(Boolean).join(" · ");
28293
28292
  const queueMode = args.queue?.mode ?? "unknown";
28294
28293
  const queueDetails = formatQueueDetails(args.queue);
28295
28294
  const verboseLabel = verboseLevel === "full" ? "verbose:full" : verboseLevel === "on" ? "verbose" : null;
@@ -28321,14 +28320,19 @@ function buildStatusMessage(args) {
28321
28320
  config: args.config
28322
28321
  }) : void 0;
28323
28322
  const hasUsage = typeof inputTokens === "number" || typeof outputTokens === "number";
28324
- const cost = showCost && hasUsage ? estimateUsageCost({
28323
+ const rawCost = showCost && hasUsage ? estimateUsageCost({
28325
28324
  usage: {
28326
28325
  input: inputTokens ?? void 0,
28327
28326
  output: outputTokens ?? void 0
28328
28327
  },
28329
28328
  cost: costConfig
28330
28329
  }) : void 0;
28331
- const costLabel = showCost && hasUsage ? formatUsd(cost) : void 0;
28330
+ const useOverride = showCost && hasUsage && typeof args.costOverrideUsd === "number" && (rawCost === void 0 || rawCost === 0);
28331
+ const cost = useOverride ? args.costOverrideUsd : rawCost;
28332
+ const baseLabel = showCost && hasUsage ? formatUsd(cost) : void 0;
28333
+ const tag = useOverride ? " (self-hosted)" : "";
28334
+ const suffix = args.costLineSuffix ? ` · ${args.costLineSuffix}` : "";
28335
+ const costLabel = baseLabel ? `${baseLabel}${tag}${suffix}` : void 0;
28332
28336
  const selectedAuthLabel = selectedAuthLabelValue ? ` · 🔑 ${selectedAuthLabelValue}` : "";
28333
28337
  const channelModelNote = (() => {
28334
28338
  if (!args.config || !entry) return;
@@ -28373,6 +28377,8 @@ function buildStatusMessage(args) {
28373
28377
  fallbackLine,
28374
28378
  usageCostLine,
28375
28379
  cacheLine,
28380
+ args.engineLine,
28381
+ args.hardwareLine,
28376
28382
  `📚 ${contextLine}`,
28377
28383
  mediaLine,
28378
28384
  args.usageLine,
@@ -28949,6 +28955,606 @@ const handleDebugCommand = async (params, allowTextCommands) => {
28949
28955
  return null;
28950
28956
  };
28951
28957
 
28958
+ //#endregion
28959
+ //#region src/infra/session-cost-usage.ts
28960
+ const emptyTotals = () => ({
28961
+ input: 0,
28962
+ output: 0,
28963
+ cacheRead: 0,
28964
+ cacheWrite: 0,
28965
+ totalTokens: 0,
28966
+ totalCost: 0,
28967
+ inputCost: 0,
28968
+ outputCost: 0,
28969
+ cacheReadCost: 0,
28970
+ cacheWriteCost: 0,
28971
+ missingCostEntries: 0
28972
+ });
28973
+ const toFiniteNumber = (value) => {
28974
+ if (typeof value !== "number") return;
28975
+ if (!Number.isFinite(value)) return;
28976
+ return value;
28977
+ };
28978
+ const extractCostBreakdown = (usageRaw) => {
28979
+ if (!usageRaw || typeof usageRaw !== "object") return;
28980
+ const cost = usageRaw.cost;
28981
+ if (!cost) return;
28982
+ const total = toFiniteNumber(cost.total);
28983
+ if (total === void 0 || total < 0) return;
28984
+ return {
28985
+ total,
28986
+ input: toFiniteNumber(cost.input),
28987
+ output: toFiniteNumber(cost.output),
28988
+ cacheRead: toFiniteNumber(cost.cacheRead),
28989
+ cacheWrite: toFiniteNumber(cost.cacheWrite)
28990
+ };
28991
+ };
28992
+ const parseTimestamp = (entry) => {
28993
+ const raw = entry.timestamp;
28994
+ if (typeof raw === "string") {
28995
+ const parsed = new Date(raw);
28996
+ if (!Number.isNaN(parsed.valueOf())) return parsed;
28997
+ }
28998
+ const message = entry.message;
28999
+ const messageTimestamp = toFiniteNumber(message?.timestamp);
29000
+ if (messageTimestamp !== void 0) {
29001
+ const parsed = new Date(messageTimestamp);
29002
+ if (!Number.isNaN(parsed.valueOf())) return parsed;
29003
+ }
29004
+ };
29005
+ const parseTranscriptEntry = (entry) => {
29006
+ const message = entry.message;
29007
+ if (!message || typeof message !== "object") return null;
29008
+ const roleRaw = message.role;
29009
+ const role = roleRaw === "user" || roleRaw === "assistant" ? roleRaw : void 0;
29010
+ if (!role) return null;
29011
+ const usageRaw = message.usage ?? entry.usage;
29012
+ const usage = usageRaw ? normalizeUsage(usageRaw) ?? void 0 : void 0;
29013
+ const provider = (typeof message.provider === "string" ? message.provider : void 0) ?? (typeof entry.provider === "string" ? entry.provider : void 0);
29014
+ const model = (typeof message.model === "string" ? message.model : void 0) ?? (typeof entry.model === "string" ? entry.model : void 0);
29015
+ const costBreakdown = extractCostBreakdown(usageRaw);
29016
+ const stopReason = typeof message.stopReason === "string" ? message.stopReason : void 0;
29017
+ const durationMs = toFiniteNumber(message.durationMs ?? entry.durationMs);
29018
+ return {
29019
+ message,
29020
+ role,
29021
+ timestamp: parseTimestamp(entry),
29022
+ durationMs,
29023
+ usage,
29024
+ costTotal: costBreakdown?.total,
29025
+ costBreakdown,
29026
+ provider,
29027
+ model,
29028
+ stopReason,
29029
+ toolNames: extractToolCallNames(message),
29030
+ toolResultCounts: countToolResults(message)
29031
+ };
29032
+ };
29033
+ const formatDayKey = (date) => date.toLocaleDateString("en-CA", { timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone });
29034
+ const computeLatencyStats = (values) => {
29035
+ if (!values.length) return;
29036
+ const sorted = values.toSorted((a, b) => a - b);
29037
+ const total = sorted.reduce((sum, v) => sum + v, 0);
29038
+ const count = sorted.length;
29039
+ const p95Index = Math.max(0, Math.ceil(count * .95) - 1);
29040
+ return {
29041
+ count,
29042
+ avgMs: total / count,
29043
+ p95Ms: sorted[p95Index] ?? sorted[count - 1],
29044
+ minMs: sorted[0],
29045
+ maxMs: sorted[count - 1]
29046
+ };
29047
+ };
29048
+ const applyUsageTotals = (totals, usage) => {
29049
+ totals.input += usage.input ?? 0;
29050
+ totals.output += usage.output ?? 0;
29051
+ totals.cacheRead += usage.cacheRead ?? 0;
29052
+ totals.cacheWrite += usage.cacheWrite ?? 0;
29053
+ const totalTokens = usage.total ?? (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
29054
+ totals.totalTokens += totalTokens;
29055
+ };
29056
+ const applyCostBreakdown = (totals, costBreakdown) => {
29057
+ if (costBreakdown === void 0 || costBreakdown.total === void 0) return;
29058
+ totals.totalCost += costBreakdown.total;
29059
+ totals.inputCost += costBreakdown.input ?? 0;
29060
+ totals.outputCost += costBreakdown.output ?? 0;
29061
+ totals.cacheReadCost += costBreakdown.cacheRead ?? 0;
29062
+ totals.cacheWriteCost += costBreakdown.cacheWrite ?? 0;
29063
+ };
29064
+ const applyCostTotal = (totals, costTotal) => {
29065
+ if (costTotal === void 0) {
29066
+ totals.missingCostEntries += 1;
29067
+ return;
29068
+ }
29069
+ totals.totalCost += costTotal;
29070
+ };
29071
+ async function* readJsonlRecords(filePath) {
29072
+ const fileStream = fs.createReadStream(filePath, { encoding: "utf-8" });
29073
+ const rl = readline.createInterface({
29074
+ input: fileStream,
29075
+ crlfDelay: Infinity
29076
+ });
29077
+ try {
29078
+ for await (const line of rl) {
29079
+ const trimmed = line.trim();
29080
+ if (!trimmed) continue;
29081
+ try {
29082
+ const parsed = JSON.parse(trimmed);
29083
+ if (!parsed || typeof parsed !== "object") continue;
29084
+ yield parsed;
29085
+ } catch {}
29086
+ }
29087
+ } finally {
29088
+ rl.close();
29089
+ fileStream.destroy();
29090
+ }
29091
+ }
29092
+ async function scanTranscriptFile(params) {
29093
+ for await (const parsed of readJsonlRecords(params.filePath)) {
29094
+ const entry = parseTranscriptEntry(parsed);
29095
+ if (!entry) continue;
29096
+ if (entry.usage && entry.costTotal === void 0) {
29097
+ const cost = resolveModelCostConfig({
29098
+ provider: entry.provider,
29099
+ model: entry.model,
29100
+ config: params.config
29101
+ });
29102
+ entry.costTotal = estimateUsageCost({
29103
+ usage: entry.usage,
29104
+ cost
29105
+ });
29106
+ }
29107
+ params.onEntry(entry);
29108
+ }
29109
+ }
29110
+ async function scanUsageFile(params) {
29111
+ await scanTranscriptFile({
29112
+ filePath: params.filePath,
29113
+ config: params.config,
29114
+ onEntry: (entry) => {
29115
+ if (!entry.usage) return;
29116
+ params.onEntry({
29117
+ usage: entry.usage,
29118
+ costTotal: entry.costTotal,
29119
+ costBreakdown: entry.costBreakdown,
29120
+ provider: entry.provider,
29121
+ model: entry.model,
29122
+ timestamp: entry.timestamp
29123
+ });
29124
+ }
29125
+ });
29126
+ }
29127
+ async function loadCostUsageSummary(params) {
29128
+ const now = /* @__PURE__ */ new Date();
29129
+ let sinceTime;
29130
+ let untilTime;
29131
+ if (params?.startMs !== void 0 && params?.endMs !== void 0) {
29132
+ sinceTime = params.startMs;
29133
+ untilTime = params.endMs;
29134
+ } else {
29135
+ const days = Math.max(1, Math.floor(params?.days ?? 30));
29136
+ const since = new Date(now);
29137
+ since.setDate(since.getDate() - (days - 1));
29138
+ sinceTime = since.getTime();
29139
+ untilTime = now.getTime();
29140
+ }
29141
+ const dailyMap = /* @__PURE__ */ new Map();
29142
+ const totals = emptyTotals();
29143
+ const sessionsDir = resolveSessionTranscriptsDirForAgent(params?.agentId);
29144
+ const entries = await fs.promises.readdir(sessionsDir, { withFileTypes: true }).catch(() => []);
29145
+ const files = (await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map(async (entry) => {
29146
+ const filePath = path.join(sessionsDir, entry.name);
29147
+ const stats = await fs.promises.stat(filePath).catch(() => null);
29148
+ if (!stats) return null;
29149
+ if (stats.mtimeMs < sinceTime) return null;
29150
+ return filePath;
29151
+ }))).filter((filePath) => Boolean(filePath));
29152
+ for (const filePath of files) await scanUsageFile({
29153
+ filePath,
29154
+ config: params?.config,
29155
+ onEntry: (entry) => {
29156
+ const ts = entry.timestamp?.getTime();
29157
+ if (!ts || ts < sinceTime || ts > untilTime) return;
29158
+ const dayKey = formatDayKey(entry.timestamp ?? now);
29159
+ const bucket = dailyMap.get(dayKey) ?? emptyTotals();
29160
+ applyUsageTotals(bucket, entry.usage);
29161
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(bucket, entry.costBreakdown);
29162
+ else applyCostTotal(bucket, entry.costTotal);
29163
+ dailyMap.set(dayKey, bucket);
29164
+ applyUsageTotals(totals, entry.usage);
29165
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
29166
+ else applyCostTotal(totals, entry.costTotal);
29167
+ }
29168
+ });
29169
+ const daily = Array.from(dailyMap.entries()).map(([date, bucket]) => Object.assign({ date }, bucket)).toSorted((a, b) => a.date.localeCompare(b.date));
29170
+ const days = Math.ceil((untilTime - sinceTime) / (1440 * 60 * 1e3)) + 1;
29171
+ return {
29172
+ updatedAt: Date.now(),
29173
+ days,
29174
+ daily,
29175
+ totals
29176
+ };
29177
+ }
29178
+ async function loadSessionCostSummary(params) {
29179
+ const sessionFile = params.sessionFile ?? (params.sessionId ? resolveSessionFilePath(params.sessionId, params.sessionEntry, { agentId: params.agentId }) : void 0);
29180
+ if (!sessionFile || !fs.existsSync(sessionFile)) return null;
29181
+ const totals = emptyTotals();
29182
+ let firstActivity;
29183
+ let lastActivity;
29184
+ const activityDatesSet = /* @__PURE__ */ new Set();
29185
+ const dailyMap = /* @__PURE__ */ new Map();
29186
+ const dailyMessageMap = /* @__PURE__ */ new Map();
29187
+ const dailyLatencyMap = /* @__PURE__ */ new Map();
29188
+ const dailyModelUsageMap = /* @__PURE__ */ new Map();
29189
+ const messageCounts = {
29190
+ total: 0,
29191
+ user: 0,
29192
+ assistant: 0,
29193
+ toolCalls: 0,
29194
+ toolResults: 0,
29195
+ errors: 0
29196
+ };
29197
+ const toolUsageMap = /* @__PURE__ */ new Map();
29198
+ const modelUsageMap = /* @__PURE__ */ new Map();
29199
+ const errorStopReasons = new Set([
29200
+ "error",
29201
+ "aborted",
29202
+ "timeout"
29203
+ ]);
29204
+ const latencyValues = [];
29205
+ let lastUserTimestamp;
29206
+ const MAX_LATENCY_MS = 720 * 60 * 1e3;
29207
+ await scanTranscriptFile({
29208
+ filePath: sessionFile,
29209
+ config: params.config,
29210
+ onEntry: (entry) => {
29211
+ const ts = entry.timestamp?.getTime();
29212
+ if (params.startMs !== void 0 && ts !== void 0 && ts < params.startMs) return;
29213
+ if (params.endMs !== void 0 && ts !== void 0 && ts > params.endMs) return;
29214
+ if (ts !== void 0) {
29215
+ if (!firstActivity || ts < firstActivity) firstActivity = ts;
29216
+ if (!lastActivity || ts > lastActivity) lastActivity = ts;
29217
+ }
29218
+ if (entry.role === "user") {
29219
+ messageCounts.user += 1;
29220
+ messageCounts.total += 1;
29221
+ if (entry.timestamp) lastUserTimestamp = entry.timestamp.getTime();
29222
+ }
29223
+ if (entry.role === "assistant") {
29224
+ messageCounts.assistant += 1;
29225
+ messageCounts.total += 1;
29226
+ const ts = entry.timestamp?.getTime();
29227
+ if (ts !== void 0) {
29228
+ const latencyMs = entry.durationMs ?? (lastUserTimestamp !== void 0 ? Math.max(0, ts - lastUserTimestamp) : void 0);
29229
+ if (latencyMs !== void 0 && Number.isFinite(latencyMs) && latencyMs <= MAX_LATENCY_MS) {
29230
+ latencyValues.push(latencyMs);
29231
+ const dayKey = formatDayKey(entry.timestamp ?? new Date(ts));
29232
+ const dailyLatencies = dailyLatencyMap.get(dayKey) ?? [];
29233
+ dailyLatencies.push(latencyMs);
29234
+ dailyLatencyMap.set(dayKey, dailyLatencies);
29235
+ }
29236
+ }
29237
+ }
29238
+ if (entry.toolNames.length > 0) {
29239
+ messageCounts.toolCalls += entry.toolNames.length;
29240
+ for (const name of entry.toolNames) toolUsageMap.set(name, (toolUsageMap.get(name) ?? 0) + 1);
29241
+ }
29242
+ if (entry.toolResultCounts.total > 0) {
29243
+ messageCounts.toolResults += entry.toolResultCounts.total;
29244
+ messageCounts.errors += entry.toolResultCounts.errors;
29245
+ }
29246
+ if (entry.stopReason && errorStopReasons.has(entry.stopReason)) messageCounts.errors += 1;
29247
+ if (entry.timestamp) {
29248
+ const dayKey = formatDayKey(entry.timestamp);
29249
+ activityDatesSet.add(dayKey);
29250
+ const daily = dailyMessageMap.get(dayKey) ?? {
29251
+ date: dayKey,
29252
+ total: 0,
29253
+ user: 0,
29254
+ assistant: 0,
29255
+ toolCalls: 0,
29256
+ toolResults: 0,
29257
+ errors: 0
29258
+ };
29259
+ daily.total += entry.role === "user" || entry.role === "assistant" ? 1 : 0;
29260
+ if (entry.role === "user") daily.user += 1;
29261
+ else if (entry.role === "assistant") daily.assistant += 1;
29262
+ daily.toolCalls += entry.toolNames.length;
29263
+ daily.toolResults += entry.toolResultCounts.total;
29264
+ daily.errors += entry.toolResultCounts.errors;
29265
+ if (entry.stopReason && errorStopReasons.has(entry.stopReason)) daily.errors += 1;
29266
+ dailyMessageMap.set(dayKey, daily);
29267
+ }
29268
+ if (!entry.usage) return;
29269
+ applyUsageTotals(totals, entry.usage);
29270
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
29271
+ else applyCostTotal(totals, entry.costTotal);
29272
+ if (entry.timestamp) {
29273
+ const dayKey = formatDayKey(entry.timestamp);
29274
+ const entryTokens = (entry.usage.input ?? 0) + (entry.usage.output ?? 0) + (entry.usage.cacheRead ?? 0) + (entry.usage.cacheWrite ?? 0);
29275
+ 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);
29276
+ const existing = dailyMap.get(dayKey) ?? {
29277
+ tokens: 0,
29278
+ cost: 0
29279
+ };
29280
+ dailyMap.set(dayKey, {
29281
+ tokens: existing.tokens + entryTokens,
29282
+ cost: existing.cost + entryCost
29283
+ });
29284
+ if (entry.provider || entry.model) {
29285
+ const modelKey = `${dayKey}::${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
29286
+ const dailyModel = dailyModelUsageMap.get(modelKey) ?? {
29287
+ date: dayKey,
29288
+ provider: entry.provider,
29289
+ model: entry.model,
29290
+ tokens: 0,
29291
+ cost: 0,
29292
+ count: 0
29293
+ };
29294
+ dailyModel.tokens += entryTokens;
29295
+ dailyModel.cost += entryCost;
29296
+ dailyModel.count += 1;
29297
+ dailyModelUsageMap.set(modelKey, dailyModel);
29298
+ }
29299
+ }
29300
+ if (entry.provider || entry.model) {
29301
+ const key = `${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
29302
+ const existing = modelUsageMap.get(key) ?? {
29303
+ provider: entry.provider,
29304
+ model: entry.model,
29305
+ count: 0,
29306
+ totals: emptyTotals()
29307
+ };
29308
+ existing.count += 1;
29309
+ applyUsageTotals(existing.totals, entry.usage);
29310
+ if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(existing.totals, entry.costBreakdown);
29311
+ else applyCostTotal(existing.totals, entry.costTotal);
29312
+ modelUsageMap.set(key, existing);
29313
+ }
29314
+ }
29315
+ });
29316
+ const dailyBreakdown = Array.from(dailyMap.entries()).map(([date, data]) => ({
29317
+ date,
29318
+ tokens: data.tokens,
29319
+ cost: data.cost
29320
+ })).toSorted((a, b) => a.date.localeCompare(b.date));
29321
+ const dailyMessageCounts = Array.from(dailyMessageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date));
29322
+ const dailyLatency = Array.from(dailyLatencyMap.entries()).map(([date, values]) => {
29323
+ const stats = computeLatencyStats(values);
29324
+ if (!stats) return null;
29325
+ return {
29326
+ date,
29327
+ ...stats
29328
+ };
29329
+ }).filter((entry) => Boolean(entry)).toSorted((a, b) => a.date.localeCompare(b.date));
29330
+ const dailyModelUsage = Array.from(dailyModelUsageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date) || b.cost - a.cost);
29331
+ const toolUsage = toolUsageMap.size ? {
29332
+ totalCalls: Array.from(toolUsageMap.values()).reduce((sum, count) => sum + count, 0),
29333
+ uniqueTools: toolUsageMap.size,
29334
+ tools: Array.from(toolUsageMap.entries()).map(([name, count]) => ({
29335
+ name,
29336
+ count
29337
+ })).toSorted((a, b) => b.count - a.count)
29338
+ } : void 0;
29339
+ const modelUsage = modelUsageMap.size ? Array.from(modelUsageMap.values()).toSorted((a, b) => {
29340
+ const costDiff = b.totals.totalCost - a.totals.totalCost;
29341
+ if (costDiff !== 0) return costDiff;
29342
+ return b.totals.totalTokens - a.totals.totalTokens;
29343
+ }) : void 0;
29344
+ return {
29345
+ sessionId: params.sessionId,
29346
+ sessionFile,
29347
+ firstActivity,
29348
+ lastActivity,
29349
+ durationMs: firstActivity !== void 0 && lastActivity !== void 0 ? Math.max(0, lastActivity - firstActivity) : void 0,
29350
+ activityDates: Array.from(activityDatesSet).toSorted(),
29351
+ dailyBreakdown,
29352
+ dailyMessageCounts,
29353
+ dailyLatency: dailyLatency.length ? dailyLatency : void 0,
29354
+ dailyModelUsage: dailyModelUsage.length ? dailyModelUsage : void 0,
29355
+ messageCounts,
29356
+ toolUsage,
29357
+ modelUsage,
29358
+ latency: computeLatencyStats(latencyValues),
29359
+ ...totals
29360
+ };
29361
+ }
29362
+
29363
+ //#endregion
29364
+ //#region src/cost/benchmark.ts
29365
+ /**
29366
+ * Claude reference rates and benchmark comparison.
29367
+ *
29368
+ * Hardcoded per-token USD rates for Claude Opus 4.7, Sonnet 4.6, and
29369
+ * Haiku 4.5 (per million tokens, Anthropic public list as of 2026-Q1).
29370
+ * Override via `models.gpuRates` is for GPU rates only — Claude rates can
29371
+ * be overridden via the per-model `cost: { input, output }` configuration
29372
+ * on the user's `anthropic` provider entry, which already exists.
29373
+ *
29374
+ * Display: pick a target tier via `agents.defaults.cost.benchmark`, default
29375
+ * `sonnet`. Setting `"all"` shows comparisons against all three tiers.
29376
+ */
29377
+ /** Per-million-token USD rates, applied via `estimateUsageCost`. */
29378
+ const CLAUDE_RATES = {
29379
+ opus: {
29380
+ input: 15,
29381
+ output: 75,
29382
+ cacheRead: 1.5,
29383
+ cacheWrite: 18.75
29384
+ },
29385
+ sonnet: {
29386
+ input: 3,
29387
+ output: 15,
29388
+ cacheRead: .3,
29389
+ cacheWrite: 3.75
29390
+ },
29391
+ haiku: {
29392
+ input: .8,
29393
+ output: 4,
29394
+ cacheRead: .08,
29395
+ cacheWrite: 1
29396
+ }
29397
+ };
29398
+ const CLAUDE_LABEL = {
29399
+ opus: "Claude Opus 4.7",
29400
+ sonnet: "Claude Sonnet 4.6",
29401
+ haiku: "Claude Haiku 4.5"
29402
+ };
29403
+ function benchmarkUsage(args) {
29404
+ if (!args.usage) return [];
29405
+ const tiers = args.target === "all" ? [
29406
+ "opus",
29407
+ "sonnet",
29408
+ "haiku"
29409
+ ] : [args.target];
29410
+ const results = [];
29411
+ for (const tier of tiers) {
29412
+ const cost = estimateUsageCost({
29413
+ usage: args.usage,
29414
+ cost: CLAUDE_RATES[tier]
29415
+ });
29416
+ if (cost === void 0) continue;
29417
+ results.push({
29418
+ tier,
29419
+ costUsd: cost
29420
+ });
29421
+ }
29422
+ return results;
29423
+ }
29424
+ function formatBenchmarkSuffix(args) {
29425
+ if (args.benchmarks.length === 0) return;
29426
+ if (args.benchmarks.length === 1) {
29427
+ const b = args.benchmarks[0];
29428
+ return formatPair(args.ourCostUsd, b);
29429
+ }
29430
+ const parts = [];
29431
+ for (const b of args.benchmarks) parts.push(`${shortLabel(b.tier)} $${formatCostShort(b.costUsd)}`);
29432
+ const cheapest = args.benchmarks.reduce((min, b) => b.costUsd < min.costUsd ? b : min);
29433
+ if (cheapest.costUsd > args.ourCostUsd && cheapest.costUsd > 0) {
29434
+ const savedPct = (cheapest.costUsd - args.ourCostUsd) / cheapest.costUsd * 100;
29435
+ if (savedPct >= 1) parts.push(`save ${savedPct.toFixed(0)}% vs ${shortLabel(cheapest.tier)}`);
29436
+ }
29437
+ return `vs ${parts.join(" / ")}`;
29438
+ }
29439
+ function formatPair(ourCost, b) {
29440
+ const benchPart = `${CLAUDE_LABEL[b.tier]} would be $${formatCostShort(b.costUsd)}`;
29441
+ if (b.costUsd > 0 && b.costUsd > ourCost) {
29442
+ const saved = (b.costUsd - ourCost) / b.costUsd * 100;
29443
+ if (saved >= 1) return `${benchPart} (save ${saved.toFixed(0)}%)`;
29444
+ } else if (b.costUsd > 0 && ourCost > b.costUsd) {
29445
+ const overspend = (ourCost - b.costUsd) / b.costUsd * 100;
29446
+ if (overspend >= 1) return `${benchPart} (+${overspend.toFixed(0)}%)`;
29447
+ }
29448
+ return benchPart;
29449
+ }
29450
+ function shortLabel(tier) {
29451
+ if (tier === "opus") return "Opus";
29452
+ if (tier === "sonnet") return "Sonnet";
29453
+ return "Haiku";
29454
+ }
29455
+ function formatCostShort(value) {
29456
+ if (value >= 1) return value.toFixed(2);
29457
+ return value.toFixed(4);
29458
+ }
29459
+ function isClaudeTier(value) {
29460
+ return value === "opus" || value === "sonnet" || value === "haiku";
29461
+ }
29462
+ function isBenchmarkTarget(value) {
29463
+ return isClaudeTier(value) || value === "all";
29464
+ }
29465
+ function resolveBenchmarkTarget(value) {
29466
+ if (typeof value === "string" && isBenchmarkTarget(value)) return value;
29467
+ return "sonnet";
29468
+ }
29469
+
29470
+ //#endregion
29471
+ //#region src/cost/summary.ts
29472
+ async function loadCostBenchmarkSummary(params) {
29473
+ const summary = await loadCostUsageSummary(params);
29474
+ const daily = summary.daily.map((day) => ({
29475
+ ...day,
29476
+ benchmarkUsd: computeBenchmarkPerTier(day)
29477
+ }));
29478
+ const benchmarkTotals = computeBenchmarkPerTier(summary.totals);
29479
+ const savingsTotals = {
29480
+ opus: benchmarkTotals.opus - summary.totals.totalCost,
29481
+ sonnet: benchmarkTotals.sonnet - summary.totals.totalCost,
29482
+ haiku: benchmarkTotals.haiku - summary.totals.totalCost
29483
+ };
29484
+ return {
29485
+ ...summary,
29486
+ daily,
29487
+ benchmarkTotals,
29488
+ savingsTotals
29489
+ };
29490
+ }
29491
+ function computeBenchmarkPerTier(totals) {
29492
+ const all = benchmarkUsage({
29493
+ usage: {
29494
+ input: totals.input,
29495
+ output: totals.output,
29496
+ cacheRead: totals.cacheRead,
29497
+ cacheWrite: totals.cacheWrite
29498
+ },
29499
+ target: "all"
29500
+ });
29501
+ const map = new Map(all.map((b) => [b.tier, b.costUsd]));
29502
+ return {
29503
+ opus: map.get("opus") ?? 0,
29504
+ sonnet: map.get("sonnet") ?? 0,
29505
+ haiku: map.get("haiku") ?? 0
29506
+ };
29507
+ }
29508
+ function resolveWindow(window, now = Date.now()) {
29509
+ const end = now;
29510
+ switch (window) {
29511
+ case "today": {
29512
+ const d = new Date(end);
29513
+ d.setHours(0, 0, 0, 0);
29514
+ return {
29515
+ startMs: d.getTime(),
29516
+ endMs: end
29517
+ };
29518
+ }
29519
+ case "week": return {
29520
+ startMs: end - 10080 * 6e4,
29521
+ endMs: end
29522
+ };
29523
+ case "month": return {
29524
+ startMs: end - 720 * 60 * 6e4,
29525
+ endMs: end
29526
+ };
29527
+ case "all": return {
29528
+ startMs: 0,
29529
+ endMs: end
29530
+ };
29531
+ }
29532
+ }
29533
+ function formatSummaryReport(summary, label) {
29534
+ const t = summary.totals;
29535
+ const b = summary.benchmarkTotals;
29536
+ const lines = [];
29537
+ if (label) lines.push(`# ${label}`);
29538
+ lines.push(`Tokens: ${formatTokens(t.totalTokens)} (${formatTokens(t.input)} in / ${formatTokens(t.output)} out)`);
29539
+ lines.push(`Spend: $${t.totalCost.toFixed(4)}`);
29540
+ lines.push(`Claude equivalents:`);
29541
+ lines.push(` Opus: $${b.opus.toFixed(4)} (saved $${(b.opus - t.totalCost).toFixed(4)})`);
29542
+ lines.push(` Sonnet: $${b.sonnet.toFixed(4)} (saved $${(b.sonnet - t.totalCost).toFixed(4)})`);
29543
+ lines.push(` Haiku: $${b.haiku.toFixed(4)} (saved $${(b.haiku - t.totalCost).toFixed(4)})`);
29544
+ if (summary.daily.length > 0) {
29545
+ lines.push("");
29546
+ lines.push("Daily:");
29547
+ 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)}`);
29548
+ }
29549
+ return lines.join("\n");
29550
+ }
29551
+ function formatTokens(n) {
29552
+ if (!Number.isFinite(n) || n <= 0) return "0";
29553
+ if (n >= 1e6) return `${(n / 1e6).toFixed(1)}m`;
29554
+ if (n >= 1e3) return `${(n / 1e3).toFixed(n >= 1e4 ? 0 : 1)}k`;
29555
+ return String(Math.round(n));
29556
+ }
29557
+
28952
29558
  //#endregion
28953
29559
  //#region src/agents/system-prompt-report.ts
28954
29560
  function extractBetween(input, startMarker, endMarker) {
@@ -29517,6 +30123,560 @@ async function buildExportSessionReply(params) {
29517
30123
  ].join("\n") };
29518
30124
  }
29519
30125
 
30126
+ //#endregion
30127
+ //#region src/cost/rates.ts
30128
+ const GPU_VRAM_GB = {
30129
+ "a100-40gb": 40,
30130
+ "a100-80gb": 80,
30131
+ "h100-pcie": 80,
30132
+ "h100-sxm": 80,
30133
+ h200: 141,
30134
+ l40: 48,
30135
+ l40s: 48,
30136
+ a40: 48,
30137
+ a6000: 48,
30138
+ a5000: 24,
30139
+ v100: 32,
30140
+ mi300x: 192,
30141
+ "rtx-4090": 24
30142
+ };
30143
+ const GPU_LABEL = {
30144
+ "a100-40gb": "A100-40GB",
30145
+ "a100-80gb": "A100-80GB",
30146
+ "h100-pcie": "H100-PCIe",
30147
+ "h100-sxm": "H100-SXM",
30148
+ h200: "H200",
30149
+ l40: "L40",
30150
+ l40s: "L40S",
30151
+ a40: "A40",
30152
+ a6000: "RTX-A6000",
30153
+ a5000: "RTX-A5000",
30154
+ v100: "V100",
30155
+ mi300x: "MI300X",
30156
+ "rtx-4090": "RTX-4090"
30157
+ };
30158
+ const DEFAULT_HOURLY_RATES_USD = {
30159
+ "a100-40gb": 2.06,
30160
+ "a100-80gb": 2.21,
30161
+ "h100-pcie": 4.25,
30162
+ "h100-sxm": 4.76,
30163
+ h200: 6.5,
30164
+ l40: 1.27,
30165
+ l40s: 1.35,
30166
+ a40: .95,
30167
+ a6000: .96,
30168
+ a5000: .61,
30169
+ v100: .8,
30170
+ mi300x: 4.89,
30171
+ "rtx-4090": .74
30172
+ };
30173
+ /**
30174
+ * Rough decode (output) throughput defaults in tokens/sec for a 27-30B FP8
30175
+ * model on a single GPU of each type. Scales roughly inversely with model
30176
+ * parameter count and bytes-per-param. Used as a fallback when no live
30177
+ * `vllm:generation_tokens_total` delta has been observed yet.
30178
+ *
30179
+ * These are conservative published-benchmark medians; treat as ballpark.
30180
+ * Override via `models.gpuRates` is rate-only; throughput overrides are
30181
+ * Phase 4+ (not yet wired to config).
30182
+ */
30183
+ const DEFAULT_DECODE_TPS = {
30184
+ "a100-40gb": 60,
30185
+ "a100-80gb": 80,
30186
+ "h100-pcie": 120,
30187
+ "h100-sxm": 130,
30188
+ h200: 160,
30189
+ l40: 45,
30190
+ l40s: 50,
30191
+ a40: 40,
30192
+ a6000: 35,
30193
+ a5000: 25,
30194
+ v100: 25,
30195
+ mi300x: 110,
30196
+ "rtx-4090": 55
30197
+ };
30198
+ /**
30199
+ * Prefill throughput is typically 30-60× higher than decode for a given
30200
+ * setup. Use 40× as a balanced midpoint.
30201
+ */
30202
+ const PREFILL_DECODE_RATIO = 40;
30203
+ function resolveDefaultDecodeTps(gpuType, paramsB, bytesPerParam) {
30204
+ const baseline = DEFAULT_DECODE_TPS[gpuType];
30205
+ if (!paramsB) return baseline;
30206
+ const refBytes = 27;
30207
+ const modelBytes = paramsB * (bytesPerParam ?? 2);
30208
+ if (modelBytes <= 0) return baseline;
30209
+ const scaled = baseline * (refBytes / modelBytes);
30210
+ return Math.max(5, scaled);
30211
+ }
30212
+ function resolveHourlyRate(gpuType, overrides) {
30213
+ if (overrides && typeof overrides[gpuType] === "number" && overrides[gpuType] >= 0) return overrides[gpuType];
30214
+ return DEFAULT_HOURLY_RATES_USD[gpuType];
30215
+ }
30216
+
30217
+ //#endregion
30218
+ //#region src/cost/gpu-inference.ts
30219
+ /**
30220
+ * Heuristic GPU type + count inference for self-hosted serving endpoints.
30221
+ *
30222
+ * Two signals: the baseUrl hostname (often encodes "a100", "h100", etc.) and
30223
+ * the model id (encodes parameter count + quantization, e.g. "qwen36-27b-fp8").
30224
+ * Output is a confidence-tagged guess so downstream code (and the user) can
30225
+ * decide whether to trust the inference or override it.
30226
+ *
30227
+ * Bytes-per-parameter table:
30228
+ * fp32 → 4
30229
+ * fp16/bf16 → 2 (default when unspecified)
30230
+ * fp8/int8/q8 → 1
30231
+ * int4/q4/fp4 → 0.5
30232
+ *
30233
+ * GPU count formula:
30234
+ * model_bytes = params × bytes_per_param
30235
+ * target_util = 0.6 (40% headroom for KV cache, activations, scheduler)
30236
+ * count = max(1, ceil(model_bytes / (vram × target_util)))
30237
+ */
30238
+ const URL_GPU_PATTERNS = [
30239
+ {
30240
+ re: /h200/i,
30241
+ type: "h200",
30242
+ confidence: "high"
30243
+ },
30244
+ {
30245
+ re: /h100[-_]?pcie/i,
30246
+ type: "h100-pcie",
30247
+ confidence: "high"
30248
+ },
30249
+ {
30250
+ re: /h100[-_]?sxm/i,
30251
+ type: "h100-sxm",
30252
+ confidence: "high"
30253
+ },
30254
+ {
30255
+ re: /h100/i,
30256
+ type: "h100-sxm",
30257
+ confidence: "medium"
30258
+ },
30259
+ {
30260
+ re: /a100[-_]?80/i,
30261
+ type: "a100-80gb",
30262
+ confidence: "high"
30263
+ },
30264
+ {
30265
+ re: /a100[-_]?40/i,
30266
+ type: "a100-40gb",
30267
+ confidence: "high"
30268
+ },
30269
+ {
30270
+ re: /a100/i,
30271
+ type: "a100-80gb",
30272
+ confidence: "medium"
30273
+ },
30274
+ {
30275
+ re: /l40s/i,
30276
+ type: "l40s",
30277
+ confidence: "high"
30278
+ },
30279
+ {
30280
+ re: /l40/i,
30281
+ type: "l40",
30282
+ confidence: "high"
30283
+ },
30284
+ {
30285
+ re: /mi300x/i,
30286
+ type: "mi300x",
30287
+ confidence: "high"
30288
+ },
30289
+ {
30290
+ re: /a6000/i,
30291
+ type: "a6000",
30292
+ confidence: "high"
30293
+ },
30294
+ {
30295
+ re: /a5000/i,
30296
+ type: "a5000",
30297
+ confidence: "high"
30298
+ },
30299
+ {
30300
+ re: /a40/i,
30301
+ type: "a40",
30302
+ confidence: "high"
30303
+ },
30304
+ {
30305
+ re: /v100/i,
30306
+ type: "v100",
30307
+ confidence: "high"
30308
+ },
30309
+ {
30310
+ re: /rtx[-_]?4090|gpu[-_]?4090/i,
30311
+ type: "rtx-4090",
30312
+ confidence: "high"
30313
+ }
30314
+ ];
30315
+ function inferGpuFromUrl(baseUrl) {
30316
+ const url = baseUrl.toLowerCase();
30317
+ for (const pattern of URL_GPU_PATTERNS) {
30318
+ const match = url.match(pattern.re);
30319
+ if (match) return {
30320
+ gpuType: pattern.type,
30321
+ confidence: pattern.confidence,
30322
+ match: match[0]
30323
+ };
30324
+ }
30325
+ return { confidence: "low" };
30326
+ }
30327
+ function parseModelSize(modelId) {
30328
+ const id = modelId.toLowerCase();
30329
+ const sizeMatch = id.match(/(\d+(?:\.\d+)?)b(?:[-_./]|$)/);
30330
+ const paramsB = sizeMatch ? Number.parseFloat(sizeMatch[1]) : void 0;
30331
+ let bytesPerParam;
30332
+ if (/\b(fp4|q4|int4)\b/.test(id) || /[-_]q4[-_]/.test(id)) bytesPerParam = .5;
30333
+ else if (/\b(fp8|int8|q8|w8a8|w8a16)\b/.test(id) || /[-_]fp8[-_]?/.test(id)) bytesPerParam = 1;
30334
+ else if (/\b(fp16|bf16|float16|half)\b/.test(id)) bytesPerParam = 2;
30335
+ else if (/\b(fp32|float32)\b/.test(id)) bytesPerParam = 4;
30336
+ return {
30337
+ paramsB,
30338
+ bytesPerParam
30339
+ };
30340
+ }
30341
+ function inferGpuCount(args) {
30342
+ const util = args.targetUtilization ?? .6;
30343
+ if (!args.paramsB || !args.bytesPerParam) return 1;
30344
+ const modelBytes = args.paramsB * 1e9 * args.bytesPerParam;
30345
+ const usableVram = args.vramGb * 1e9 * util;
30346
+ return Math.max(1, Math.ceil(modelBytes / usableVram));
30347
+ }
30348
+ function inferGpu(args) {
30349
+ const reasoning = [];
30350
+ const overrideType = args.override?.gpuType;
30351
+ const overrideCount = args.override?.gpuCount;
30352
+ let gpuType;
30353
+ let confidence = "low";
30354
+ if (overrideType && overrideType in GPU_VRAM_GB) {
30355
+ gpuType = overrideType;
30356
+ confidence = "high";
30357
+ reasoning.push(`gpuType=${gpuType} from config override`);
30358
+ } else if (args.baseUrl) {
30359
+ const fromUrl = inferGpuFromUrl(args.baseUrl);
30360
+ if (fromUrl.gpuType) {
30361
+ gpuType = fromUrl.gpuType;
30362
+ confidence = fromUrl.confidence;
30363
+ reasoning.push(`gpuType=${gpuType} from URL pattern '${fromUrl.match}'`);
30364
+ } else reasoning.push("no GPU type pattern matched in URL");
30365
+ }
30366
+ const sized = args.modelId ? parseModelSize(args.modelId) : {};
30367
+ if (sized.paramsB) reasoning.push(`paramsB=${sized.paramsB} from model id '${args.modelId}'`);
30368
+ if (sized.bytesPerParam) reasoning.push(`bytesPerParam=${sized.bytesPerParam} from quantization marker`);
30369
+ else if (args.modelId) reasoning.push("no quantization marker — defaulting to bf16 (2 bytes)");
30370
+ let gpuCount = 1;
30371
+ if (typeof overrideCount === "number" && overrideCount > 0) {
30372
+ gpuCount = Math.floor(overrideCount);
30373
+ reasoning.push(`gpuCount=${gpuCount} from config override`);
30374
+ } else if (gpuType) {
30375
+ const bpp = sized.bytesPerParam ?? 2;
30376
+ gpuCount = inferGpuCount({
30377
+ paramsB: sized.paramsB,
30378
+ bytesPerParam: bpp,
30379
+ vramGb: GPU_VRAM_GB[gpuType]
30380
+ });
30381
+ if (sized.paramsB) reasoning.push(`gpuCount=${gpuCount} (model ${(sized.paramsB * bpp).toFixed(0)}GB / ${GPU_VRAM_GB[gpuType]}GB × 0.6 util)`);
30382
+ }
30383
+ return {
30384
+ gpuType,
30385
+ gpuCount,
30386
+ confidence,
30387
+ paramsB: sized.paramsB,
30388
+ bytesPerParam: sized.bytesPerParam,
30389
+ reasoning
30390
+ };
30391
+ }
30392
+
30393
+ //#endregion
30394
+ //#region src/cost/serving-discovery.ts
30395
+ const SUCCESS_TTL_MS = 6e4;
30396
+ const NULL_TTL_MS = 5 * 6e4;
30397
+ const DEFAULT_TIMEOUT_MS$1 = 4e3;
30398
+ const cache = /* @__PURE__ */ new Map();
30399
+ const previousSnapshots = /* @__PURE__ */ new Map();
30400
+ async function probeServingEndpoint(baseUrl, opts = {}) {
30401
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
30402
+ const nowFn = opts.now ?? (() => Date.now());
30403
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS$1;
30404
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
30405
+ if (!trimmed) return null;
30406
+ const cached = cache.get(trimmed);
30407
+ if (cached && !opts.forceRefresh && cached.expiresAt > nowFn()) return cached.info;
30408
+ const rootUrl = trimmed.replace(/\/v\d+$/, "");
30409
+ const probeAt = nowFn();
30410
+ const fetchOpts = () => ({
30411
+ signal: AbortSignal.timeout(timeoutMs),
30412
+ headers: { Accept: "application/json, text/plain, */*" }
30413
+ });
30414
+ const [versionRes, modelsRes, metricsRes] = await Promise.allSettled([
30415
+ fetchImpl(`${rootUrl}/version`, fetchOpts()),
30416
+ fetchImpl(`${rootUrl}/v1/models`, fetchOpts()),
30417
+ fetchImpl(`${rootUrl}/metrics`, fetchOpts())
30418
+ ]);
30419
+ const info = {
30420
+ engine: "unknown",
30421
+ probedAt: probeAt,
30422
+ baseUrl: trimmed,
30423
+ rootUrl
30424
+ };
30425
+ if (versionRes.status === "fulfilled" && versionRes.value.ok) try {
30426
+ const txt = await versionRes.value.text();
30427
+ try {
30428
+ const json = JSON.parse(txt);
30429
+ if (typeof json.version === "string") info.version = json.version;
30430
+ } catch {
30431
+ const stripped = txt.trim();
30432
+ if (stripped && stripped.length < 64 && /^[\w.\-+]+$/.test(stripped)) info.version = stripped;
30433
+ }
30434
+ } catch {}
30435
+ if (modelsRes.status === "fulfilled" && modelsRes.value.ok) try {
30436
+ const first = (await modelsRes.value.json()).data?.[0];
30437
+ if (first) {
30438
+ if (typeof first.id === "string") info.modelId = first.id;
30439
+ if (typeof first.max_model_len === "number") info.contextWindow = first.max_model_len;
30440
+ if (typeof first.owned_by === "string") {
30441
+ const owner = first.owned_by.toLowerCase();
30442
+ if (owner.includes("vllm")) info.engine = "vllm";
30443
+ else if (owner.includes("sglang")) info.engine = "sglang";
30444
+ else if (info.engine === "unknown") info.engine = "openai-compat";
30445
+ }
30446
+ }
30447
+ } catch {}
30448
+ let snapshot = { probedAt: probeAt };
30449
+ if (metricsRes.status === "fulfilled" && metricsRes.value.ok) try {
30450
+ const parsed = parsePrometheusMetrics(await metricsRes.value.text());
30451
+ info.kvCacheUsagePerc = parsed.kvCacheUsagePerc;
30452
+ info.queueDepth = parsed.queueDepth;
30453
+ info.numRequestsRunning = parsed.numRequestsRunning;
30454
+ info.cacheConfig = parsed.cacheConfig;
30455
+ snapshot = {
30456
+ probedAt: probeAt,
30457
+ promptTokensTotal: parsed.promptTokensTotal,
30458
+ generationTokensTotal: parsed.generationTokensTotal
30459
+ };
30460
+ if (info.engine === "unknown" && parsed.foundVllmPrefix) info.engine = "vllm";
30461
+ if (info.engine === "unknown" && parsed.foundSglangPrefix) info.engine = "sglang";
30462
+ } catch {}
30463
+ const prev = previousSnapshots.get(trimmed);
30464
+ if (prev && typeof prev.generationTokensTotal === "number" && typeof snapshot.generationTokensTotal === "number") {
30465
+ const dt = (snapshot.probedAt - prev.probedAt) / 1e3;
30466
+ const dToks = snapshot.generationTokensTotal - prev.generationTokensTotal;
30467
+ if (dt > 0 && dToks >= 0) info.observedTps = dToks / dt;
30468
+ }
30469
+ if (snapshot.generationTokensTotal !== void 0 || snapshot.promptTokensTotal !== void 0) previousSnapshots.set(trimmed, snapshot);
30470
+ 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)) {
30471
+ cache.set(trimmed, {
30472
+ info: null,
30473
+ expiresAt: nowFn() + NULL_TTL_MS
30474
+ });
30475
+ return null;
30476
+ }
30477
+ cache.set(trimmed, {
30478
+ info,
30479
+ expiresAt: nowFn() + SUCCESS_TTL_MS
30480
+ });
30481
+ return info;
30482
+ }
30483
+ function parsePrometheusMetrics(text) {
30484
+ const result = {
30485
+ foundVllmPrefix: false,
30486
+ foundSglangPrefix: false
30487
+ };
30488
+ const lines = text.split("\n");
30489
+ for (const raw of lines) {
30490
+ const line = raw.trim();
30491
+ if (!line || line.startsWith("#")) continue;
30492
+ if (line.startsWith("vllm:")) result.foundVllmPrefix = true;
30493
+ if (line.startsWith("sglang:")) result.foundSglangPrefix = true;
30494
+ const match = line.match(/^([^\s{]+)(\{[^}]*\})?\s+([0-9eE+\-.]+)$/);
30495
+ if (!match) continue;
30496
+ const metric = match[1];
30497
+ const labels = match[2];
30498
+ const value = Number(match[3]);
30499
+ if (!Number.isFinite(value)) continue;
30500
+ switch (metric) {
30501
+ case "vllm:prompt_tokens_total":
30502
+ result.promptTokensTotal = (result.promptTokensTotal ?? 0) + value;
30503
+ break;
30504
+ case "vllm:generation_tokens_total":
30505
+ result.generationTokensTotal = (result.generationTokensTotal ?? 0) + value;
30506
+ break;
30507
+ case "vllm:kv_cache_usage_perc":
30508
+ result.kvCacheUsagePerc = value;
30509
+ break;
30510
+ case "vllm:num_requests_waiting":
30511
+ if (!labels || !labels.includes("reason=")) result.queueDepth = value;
30512
+ break;
30513
+ case "vllm:num_requests_running":
30514
+ result.numRequestsRunning = value;
30515
+ break;
30516
+ case "vllm:cache_config_info": {
30517
+ if (!labels) break;
30518
+ const parsed = parseLabels(labels);
30519
+ const cfg = {};
30520
+ if (parsed.block_size !== void 0) cfg.blockSize = Number(parsed.block_size);
30521
+ if (parsed.num_gpu_blocks !== void 0) cfg.numGpuBlocks = Number(parsed.num_gpu_blocks);
30522
+ if (parsed.cache_dtype !== void 0) cfg.cacheDtype = parsed.cache_dtype;
30523
+ if (parsed.gpu_memory_utilization !== void 0) {
30524
+ const n = Number(parsed.gpu_memory_utilization);
30525
+ if (Number.isFinite(n)) cfg.gpuMemoryUtilization = n;
30526
+ }
30527
+ if (parsed.enable_prefix_caching !== void 0) cfg.enablePrefixCaching = parsed.enable_prefix_caching === "True";
30528
+ result.cacheConfig = cfg;
30529
+ break;
30530
+ }
30531
+ }
30532
+ }
30533
+ return result;
30534
+ }
30535
+ function parseLabels(rawLabels) {
30536
+ const inner = rawLabels.replace(/^\{/, "").replace(/\}$/, "");
30537
+ const out = {};
30538
+ const re = /(\w+)="([^"]*)"/g;
30539
+ let m;
30540
+ while ((m = re.exec(inner)) !== null) out[m[1]] = m[2];
30541
+ return out;
30542
+ }
30543
+ function formatEngineLine(info) {
30544
+ if (!info) return null;
30545
+ const parts = [];
30546
+ const engineLabel = (() => {
30547
+ if (info.engine === "vllm") return info.version ? `vLLM ${info.version}` : "vLLM";
30548
+ if (info.engine === "sglang") return info.version ? `SGLang ${info.version}` : "SGLang";
30549
+ if (info.engine === "openai-compat") return "OpenAI-compat";
30550
+ return info.version ? `engine ${info.version}` : null;
30551
+ })();
30552
+ if (engineLabel) parts.push(engineLabel);
30553
+ if (typeof info.observedTps === "number" && info.observedTps > .5) parts.push(`${Math.round(info.observedTps)} tps`);
30554
+ if (typeof info.kvCacheUsagePerc === "number") {
30555
+ const pct = Math.round(info.kvCacheUsagePerc * 100);
30556
+ if (pct > 0) parts.push(`KV ${pct}%`);
30557
+ }
30558
+ if (typeof info.queueDepth === "number" && info.queueDepth > 0) parts.push(`queue ${info.queueDepth}`);
30559
+ if (typeof info.numRequestsRunning === "number" && info.numRequestsRunning > 0) parts.push(`running ${info.numRequestsRunning}`);
30560
+ if (parts.length === 0) return null;
30561
+ return `🖥 ${parts.join(" · ")}`;
30562
+ }
30563
+
30564
+ //#endregion
30565
+ //#region src/cost/breakdown.ts
30566
+ async function buildCostBreakdown(args) {
30567
+ const benchmarkTarget = args.config?.models?.benchmark === "none" ? "none" : resolveBenchmarkTarget(args.config?.models?.benchmark);
30568
+ const breakdown = {
30569
+ serving: null,
30570
+ benchmarks: [],
30571
+ benchmarkTarget
30572
+ };
30573
+ if (args.baseUrl && args.baseUrl.trim()) try {
30574
+ breakdown.serving = await probeServingEndpoint(args.baseUrl, {
30575
+ timeoutMs: args.probeTimeoutMs ?? 3e3,
30576
+ forceRefresh: Boolean(args.forceProbeRefresh)
30577
+ });
30578
+ } catch {
30579
+ breakdown.serving = null;
30580
+ }
30581
+ breakdown.engineLine = formatEngineLine(breakdown.serving) ?? void 0;
30582
+ const modelCost = resolveModelCost(args.config, args.provider, args.modelId);
30583
+ const detectedModelId = breakdown.serving?.modelId ?? args.modelId;
30584
+ breakdown.gpu = inferGpu({
30585
+ baseUrl: args.baseUrl,
30586
+ modelId: detectedModelId,
30587
+ override: {
30588
+ gpuType: modelCost?.gpuType,
30589
+ gpuCount: modelCost?.gpuCount
30590
+ }
30591
+ });
30592
+ const overrides = args.config?.models?.gpuRates;
30593
+ let rate;
30594
+ let source;
30595
+ if (typeof modelCost?.hourlyRate === "number" && modelCost.hourlyRate >= 0) {
30596
+ rate = modelCost.hourlyRate;
30597
+ source = "model-override";
30598
+ } else if (breakdown.gpu.gpuType) {
30599
+ rate = resolveHourlyRate(breakdown.gpu.gpuType, overrides);
30600
+ if (rate !== void 0) source = overrides && breakdown.gpu.gpuType in overrides ? "config-override" : "default-table";
30601
+ }
30602
+ breakdown.hourlyRate = rate;
30603
+ breakdown.hourlyRateSource = source;
30604
+ if (breakdown.gpu?.gpuType) {
30605
+ const observed = breakdown.serving?.observedTps;
30606
+ if (typeof observed === "number" && observed > .5) {
30607
+ breakdown.decodeTps = observed;
30608
+ breakdown.prefillTps = observed * PREFILL_DECODE_RATIO;
30609
+ breakdown.throughputSource = "observed";
30610
+ } else {
30611
+ const decode = resolveDefaultDecodeTps(breakdown.gpu.gpuType, breakdown.gpu.paramsB, breakdown.gpu.bytesPerParam);
30612
+ breakdown.decodeTps = decode;
30613
+ breakdown.prefillTps = decode * PREFILL_DECODE_RATIO;
30614
+ breakdown.throughputSource = "default-table";
30615
+ }
30616
+ }
30617
+ if (args.usage && breakdown.hourlyRate !== void 0 && breakdown.gpu?.gpuType && breakdown.decodeTps !== void 0 && breakdown.prefillTps !== void 0) {
30618
+ const perSecond = breakdown.hourlyRate * breakdown.gpu.gpuCount / 3600;
30619
+ const inputTokens = args.usage.input ?? 0;
30620
+ const outputTokens = args.usage.output ?? 0;
30621
+ const totalCost = ((breakdown.prefillTps > 0 ? inputTokens / breakdown.prefillTps : 0) + (breakdown.decodeTps > 0 ? outputTokens / breakdown.decodeTps : 0)) * perSecond;
30622
+ breakdown.instanceCostUsd = totalCost;
30623
+ const totalTokens = inputTokens + outputTokens;
30624
+ if (totalTokens > 0) breakdown.perTokenAvgUsd = totalCost / totalTokens;
30625
+ }
30626
+ if (args.usage) {
30627
+ const costForEstimate = modelCost ? {
30628
+ input: modelCost.input ?? 0,
30629
+ output: modelCost.output ?? 0,
30630
+ cacheRead: modelCost.cacheRead ?? 0,
30631
+ cacheWrite: modelCost.cacheWrite ?? 0
30632
+ } : void 0;
30633
+ const rawCost = estimateUsageCost({
30634
+ usage: args.usage,
30635
+ cost: costForEstimate
30636
+ });
30637
+ if (typeof rawCost === "number" && rawCost > 0) breakdown.effectiveCostUsd = rawCost;
30638
+ else if (breakdown.instanceCostUsd !== void 0) breakdown.effectiveCostUsd = breakdown.instanceCostUsd;
30639
+ if (benchmarkTarget !== "none" && breakdown.effectiveCostUsd !== void 0) {
30640
+ breakdown.benchmarks = benchmarkUsage({
30641
+ usage: args.usage,
30642
+ target: benchmarkTarget
30643
+ });
30644
+ breakdown.costLineSuffix = formatBenchmarkSuffix({
30645
+ ourCostUsd: breakdown.effectiveCostUsd,
30646
+ benchmarks: breakdown.benchmarks
30647
+ });
30648
+ }
30649
+ }
30650
+ breakdown.hardwareLine = formatHardwareLine(breakdown);
30651
+ return breakdown;
30652
+ }
30653
+ function resolveModelCost(config, provider, modelId) {
30654
+ if (!config || !provider || !modelId) return;
30655
+ const providers = config.models?.providers;
30656
+ if (!providers) return;
30657
+ const providerCfg = providers[provider];
30658
+ if (!providerCfg?.models) return;
30659
+ return providerCfg.models.find((m) => m.id === modelId)?.cost;
30660
+ }
30661
+ function formatHardwareLine(breakdown) {
30662
+ const gpu = breakdown.gpu;
30663
+ if (!gpu?.gpuType) return;
30664
+ const label = GPU_LABEL[gpu.gpuType];
30665
+ const count = gpu.gpuCount;
30666
+ const parts = [];
30667
+ parts.push(`${count}× ${label}`);
30668
+ if (typeof breakdown.hourlyRate === "number") parts.push(`≈ $${(breakdown.hourlyRate * count).toFixed(2)}/hr`);
30669
+ const tag = (() => {
30670
+ if (breakdown.hourlyRateSource === "model-override") return "model override";
30671
+ if (breakdown.hourlyRateSource === "config-override") return "config override";
30672
+ if (gpu.confidence === "high") return "inferred";
30673
+ if (gpu.confidence === "medium") return "inferred · medium-conf";
30674
+ return "inferred · low-conf";
30675
+ })();
30676
+ parts.push(`(${tag})`);
30677
+ return `🧰 ${parts.join(" · ")}`;
30678
+ }
30679
+
29520
30680
  //#endregion
29521
30681
  //#region src/infra/provider-usage.shared.ts
29522
30682
  const DEFAULT_TIMEOUT_MS = 5e3;
@@ -30720,6 +31880,32 @@ async function buildStatusReply(params) {
30720
31880
  } catch {
30721
31881
  usageLine = null;
30722
31882
  }
31883
+ const baseUrl = cfg.models?.providers?.[provider]?.baseUrl;
31884
+ let engineLine;
31885
+ let hardwareLine;
31886
+ let costOverrideUsd;
31887
+ let costLineSuffix;
31888
+ try {
31889
+ const breakdown = await buildCostBreakdown({
31890
+ baseUrl,
31891
+ provider,
31892
+ modelId: model,
31893
+ config: cfg,
31894
+ usage: {
31895
+ input: sessionEntry?.inputTokens,
31896
+ output: sessionEntry?.outputTokens
31897
+ }
31898
+ });
31899
+ engineLine = breakdown.engineLine;
31900
+ hardwareLine = breakdown.hardwareLine;
31901
+ costOverrideUsd = breakdown.instanceCostUsd;
31902
+ costLineSuffix = breakdown.costLineSuffix;
31903
+ } catch {
31904
+ engineLine = void 0;
31905
+ hardwareLine = void 0;
31906
+ costOverrideUsd = void 0;
31907
+ costLineSuffix = void 0;
31908
+ }
30723
31909
  const queueSettings = resolveQueueSettings({
30724
31910
  cfg,
30725
31911
  channel: command.channel,
@@ -30802,6 +31988,10 @@ async function buildStatusReply(params) {
30802
31988
  showDetails: queueOverrides
30803
31989
  },
30804
31990
  subagentsLine,
31991
+ engineLine,
31992
+ hardwareLine,
31993
+ costOverrideUsd,
31994
+ costLineSuffix,
30805
31995
  mediaDecisions: params.mediaDecisions,
30806
31996
  includeTranscriptUsage: false
30807
31997
  }) };
@@ -30902,6 +32092,27 @@ const handleStatusCommand = async (params, allowTextCommands) => {
30902
32092
  })
30903
32093
  };
30904
32094
  };
32095
+ const handleCostCommand = async (params, allowTextCommands) => {
32096
+ if (!allowTextCommands) return null;
32097
+ const normalized = params.command.commandBodyNormalized;
32098
+ if (normalized !== "/cost" && !normalized.startsWith("/cost ")) return null;
32099
+ if (!params.command.isAuthorizedSender) {
32100
+ logVerbose(`Ignoring /cost from unauthorized sender: ${params.command.senderId || "<unknown>"}`);
32101
+ return { shouldContinue: false };
32102
+ }
32103
+ const arg = normalized.slice(5).trim();
32104
+ const window = arg === "today" || arg === "week" || arg === "month" || arg === "all" ? arg : "week";
32105
+ const { startMs, endMs } = resolveWindow(window);
32106
+ return {
32107
+ shouldContinue: false,
32108
+ reply: { text: formatSummaryReport(await loadCostBenchmarkSummary({
32109
+ startMs,
32110
+ endMs,
32111
+ config: params.cfg,
32112
+ agentId: params.agentId
32113
+ }), `${window.charAt(0).toUpperCase()}${window.slice(1)}`) }
32114
+ };
32115
+ };
30905
32116
  const handleContextCommand = async (params, allowTextCommands) => {
30906
32117
  if (!allowTextCommands) return null;
30907
32118
  const normalized = params.command.commandBodyNormalized;
@@ -31298,411 +32509,6 @@ function scheduleGatewaySigusr1Restart(opts) {
31298
32509
  };
31299
32510
  }
31300
32511
 
31301
- //#endregion
31302
- //#region src/infra/session-cost-usage.ts
31303
- const emptyTotals = () => ({
31304
- input: 0,
31305
- output: 0,
31306
- cacheRead: 0,
31307
- cacheWrite: 0,
31308
- totalTokens: 0,
31309
- totalCost: 0,
31310
- inputCost: 0,
31311
- outputCost: 0,
31312
- cacheReadCost: 0,
31313
- cacheWriteCost: 0,
31314
- missingCostEntries: 0
31315
- });
31316
- const toFiniteNumber = (value) => {
31317
- if (typeof value !== "number") return;
31318
- if (!Number.isFinite(value)) return;
31319
- return value;
31320
- };
31321
- const extractCostBreakdown = (usageRaw) => {
31322
- if (!usageRaw || typeof usageRaw !== "object") return;
31323
- const cost = usageRaw.cost;
31324
- if (!cost) return;
31325
- const total = toFiniteNumber(cost.total);
31326
- if (total === void 0 || total < 0) return;
31327
- return {
31328
- total,
31329
- input: toFiniteNumber(cost.input),
31330
- output: toFiniteNumber(cost.output),
31331
- cacheRead: toFiniteNumber(cost.cacheRead),
31332
- cacheWrite: toFiniteNumber(cost.cacheWrite)
31333
- };
31334
- };
31335
- const parseTimestamp = (entry) => {
31336
- const raw = entry.timestamp;
31337
- if (typeof raw === "string") {
31338
- const parsed = new Date(raw);
31339
- if (!Number.isNaN(parsed.valueOf())) return parsed;
31340
- }
31341
- const message = entry.message;
31342
- const messageTimestamp = toFiniteNumber(message?.timestamp);
31343
- if (messageTimestamp !== void 0) {
31344
- const parsed = new Date(messageTimestamp);
31345
- if (!Number.isNaN(parsed.valueOf())) return parsed;
31346
- }
31347
- };
31348
- const parseTranscriptEntry = (entry) => {
31349
- const message = entry.message;
31350
- if (!message || typeof message !== "object") return null;
31351
- const roleRaw = message.role;
31352
- const role = roleRaw === "user" || roleRaw === "assistant" ? roleRaw : void 0;
31353
- if (!role) return null;
31354
- const usageRaw = message.usage ?? entry.usage;
31355
- const usage = usageRaw ? normalizeUsage(usageRaw) ?? void 0 : void 0;
31356
- const provider = (typeof message.provider === "string" ? message.provider : void 0) ?? (typeof entry.provider === "string" ? entry.provider : void 0);
31357
- const model = (typeof message.model === "string" ? message.model : void 0) ?? (typeof entry.model === "string" ? entry.model : void 0);
31358
- const costBreakdown = extractCostBreakdown(usageRaw);
31359
- const stopReason = typeof message.stopReason === "string" ? message.stopReason : void 0;
31360
- const durationMs = toFiniteNumber(message.durationMs ?? entry.durationMs);
31361
- return {
31362
- message,
31363
- role,
31364
- timestamp: parseTimestamp(entry),
31365
- durationMs,
31366
- usage,
31367
- costTotal: costBreakdown?.total,
31368
- costBreakdown,
31369
- provider,
31370
- model,
31371
- stopReason,
31372
- toolNames: extractToolCallNames(message),
31373
- toolResultCounts: countToolResults(message)
31374
- };
31375
- };
31376
- const formatDayKey = (date) => date.toLocaleDateString("en-CA", { timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone });
31377
- const computeLatencyStats = (values) => {
31378
- if (!values.length) return;
31379
- const sorted = values.toSorted((a, b) => a - b);
31380
- const total = sorted.reduce((sum, v) => sum + v, 0);
31381
- const count = sorted.length;
31382
- const p95Index = Math.max(0, Math.ceil(count * .95) - 1);
31383
- return {
31384
- count,
31385
- avgMs: total / count,
31386
- p95Ms: sorted[p95Index] ?? sorted[count - 1],
31387
- minMs: sorted[0],
31388
- maxMs: sorted[count - 1]
31389
- };
31390
- };
31391
- const applyUsageTotals = (totals, usage) => {
31392
- totals.input += usage.input ?? 0;
31393
- totals.output += usage.output ?? 0;
31394
- totals.cacheRead += usage.cacheRead ?? 0;
31395
- totals.cacheWrite += usage.cacheWrite ?? 0;
31396
- const totalTokens = usage.total ?? (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
31397
- totals.totalTokens += totalTokens;
31398
- };
31399
- const applyCostBreakdown = (totals, costBreakdown) => {
31400
- if (costBreakdown === void 0 || costBreakdown.total === void 0) return;
31401
- totals.totalCost += costBreakdown.total;
31402
- totals.inputCost += costBreakdown.input ?? 0;
31403
- totals.outputCost += costBreakdown.output ?? 0;
31404
- totals.cacheReadCost += costBreakdown.cacheRead ?? 0;
31405
- totals.cacheWriteCost += costBreakdown.cacheWrite ?? 0;
31406
- };
31407
- const applyCostTotal = (totals, costTotal) => {
31408
- if (costTotal === void 0) {
31409
- totals.missingCostEntries += 1;
31410
- return;
31411
- }
31412
- totals.totalCost += costTotal;
31413
- };
31414
- async function* readJsonlRecords(filePath) {
31415
- const fileStream = fs.createReadStream(filePath, { encoding: "utf-8" });
31416
- const rl = readline.createInterface({
31417
- input: fileStream,
31418
- crlfDelay: Infinity
31419
- });
31420
- try {
31421
- for await (const line of rl) {
31422
- const trimmed = line.trim();
31423
- if (!trimmed) continue;
31424
- try {
31425
- const parsed = JSON.parse(trimmed);
31426
- if (!parsed || typeof parsed !== "object") continue;
31427
- yield parsed;
31428
- } catch {}
31429
- }
31430
- } finally {
31431
- rl.close();
31432
- fileStream.destroy();
31433
- }
31434
- }
31435
- async function scanTranscriptFile(params) {
31436
- for await (const parsed of readJsonlRecords(params.filePath)) {
31437
- const entry = parseTranscriptEntry(parsed);
31438
- if (!entry) continue;
31439
- if (entry.usage && entry.costTotal === void 0) {
31440
- const cost = resolveModelCostConfig({
31441
- provider: entry.provider,
31442
- model: entry.model,
31443
- config: params.config
31444
- });
31445
- entry.costTotal = estimateUsageCost({
31446
- usage: entry.usage,
31447
- cost
31448
- });
31449
- }
31450
- params.onEntry(entry);
31451
- }
31452
- }
31453
- async function scanUsageFile(params) {
31454
- await scanTranscriptFile({
31455
- filePath: params.filePath,
31456
- config: params.config,
31457
- onEntry: (entry) => {
31458
- if (!entry.usage) return;
31459
- params.onEntry({
31460
- usage: entry.usage,
31461
- costTotal: entry.costTotal,
31462
- costBreakdown: entry.costBreakdown,
31463
- provider: entry.provider,
31464
- model: entry.model,
31465
- timestamp: entry.timestamp
31466
- });
31467
- }
31468
- });
31469
- }
31470
- async function loadCostUsageSummary(params) {
31471
- const now = /* @__PURE__ */ new Date();
31472
- let sinceTime;
31473
- let untilTime;
31474
- if (params?.startMs !== void 0 && params?.endMs !== void 0) {
31475
- sinceTime = params.startMs;
31476
- untilTime = params.endMs;
31477
- } else {
31478
- const days = Math.max(1, Math.floor(params?.days ?? 30));
31479
- const since = new Date(now);
31480
- since.setDate(since.getDate() - (days - 1));
31481
- sinceTime = since.getTime();
31482
- untilTime = now.getTime();
31483
- }
31484
- const dailyMap = /* @__PURE__ */ new Map();
31485
- const totals = emptyTotals();
31486
- const sessionsDir = resolveSessionTranscriptsDirForAgent(params?.agentId);
31487
- const entries = await fs.promises.readdir(sessionsDir, { withFileTypes: true }).catch(() => []);
31488
- const files = (await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map(async (entry) => {
31489
- const filePath = path.join(sessionsDir, entry.name);
31490
- const stats = await fs.promises.stat(filePath).catch(() => null);
31491
- if (!stats) return null;
31492
- if (stats.mtimeMs < sinceTime) return null;
31493
- return filePath;
31494
- }))).filter((filePath) => Boolean(filePath));
31495
- for (const filePath of files) await scanUsageFile({
31496
- filePath,
31497
- config: params?.config,
31498
- onEntry: (entry) => {
31499
- const ts = entry.timestamp?.getTime();
31500
- if (!ts || ts < sinceTime || ts > untilTime) return;
31501
- const dayKey = formatDayKey(entry.timestamp ?? now);
31502
- const bucket = dailyMap.get(dayKey) ?? emptyTotals();
31503
- applyUsageTotals(bucket, entry.usage);
31504
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(bucket, entry.costBreakdown);
31505
- else applyCostTotal(bucket, entry.costTotal);
31506
- dailyMap.set(dayKey, bucket);
31507
- applyUsageTotals(totals, entry.usage);
31508
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
31509
- else applyCostTotal(totals, entry.costTotal);
31510
- }
31511
- });
31512
- const daily = Array.from(dailyMap.entries()).map(([date, bucket]) => Object.assign({ date }, bucket)).toSorted((a, b) => a.date.localeCompare(b.date));
31513
- const days = Math.ceil((untilTime - sinceTime) / (1440 * 60 * 1e3)) + 1;
31514
- return {
31515
- updatedAt: Date.now(),
31516
- days,
31517
- daily,
31518
- totals
31519
- };
31520
- }
31521
- async function loadSessionCostSummary(params) {
31522
- const sessionFile = params.sessionFile ?? (params.sessionId ? resolveSessionFilePath(params.sessionId, params.sessionEntry, { agentId: params.agentId }) : void 0);
31523
- if (!sessionFile || !fs.existsSync(sessionFile)) return null;
31524
- const totals = emptyTotals();
31525
- let firstActivity;
31526
- let lastActivity;
31527
- const activityDatesSet = /* @__PURE__ */ new Set();
31528
- const dailyMap = /* @__PURE__ */ new Map();
31529
- const dailyMessageMap = /* @__PURE__ */ new Map();
31530
- const dailyLatencyMap = /* @__PURE__ */ new Map();
31531
- const dailyModelUsageMap = /* @__PURE__ */ new Map();
31532
- const messageCounts = {
31533
- total: 0,
31534
- user: 0,
31535
- assistant: 0,
31536
- toolCalls: 0,
31537
- toolResults: 0,
31538
- errors: 0
31539
- };
31540
- const toolUsageMap = /* @__PURE__ */ new Map();
31541
- const modelUsageMap = /* @__PURE__ */ new Map();
31542
- const errorStopReasons = new Set([
31543
- "error",
31544
- "aborted",
31545
- "timeout"
31546
- ]);
31547
- const latencyValues = [];
31548
- let lastUserTimestamp;
31549
- const MAX_LATENCY_MS = 720 * 60 * 1e3;
31550
- await scanTranscriptFile({
31551
- filePath: sessionFile,
31552
- config: params.config,
31553
- onEntry: (entry) => {
31554
- const ts = entry.timestamp?.getTime();
31555
- if (params.startMs !== void 0 && ts !== void 0 && ts < params.startMs) return;
31556
- if (params.endMs !== void 0 && ts !== void 0 && ts > params.endMs) return;
31557
- if (ts !== void 0) {
31558
- if (!firstActivity || ts < firstActivity) firstActivity = ts;
31559
- if (!lastActivity || ts > lastActivity) lastActivity = ts;
31560
- }
31561
- if (entry.role === "user") {
31562
- messageCounts.user += 1;
31563
- messageCounts.total += 1;
31564
- if (entry.timestamp) lastUserTimestamp = entry.timestamp.getTime();
31565
- }
31566
- if (entry.role === "assistant") {
31567
- messageCounts.assistant += 1;
31568
- messageCounts.total += 1;
31569
- const ts = entry.timestamp?.getTime();
31570
- if (ts !== void 0) {
31571
- const latencyMs = entry.durationMs ?? (lastUserTimestamp !== void 0 ? Math.max(0, ts - lastUserTimestamp) : void 0);
31572
- if (latencyMs !== void 0 && Number.isFinite(latencyMs) && latencyMs <= MAX_LATENCY_MS) {
31573
- latencyValues.push(latencyMs);
31574
- const dayKey = formatDayKey(entry.timestamp ?? new Date(ts));
31575
- const dailyLatencies = dailyLatencyMap.get(dayKey) ?? [];
31576
- dailyLatencies.push(latencyMs);
31577
- dailyLatencyMap.set(dayKey, dailyLatencies);
31578
- }
31579
- }
31580
- }
31581
- if (entry.toolNames.length > 0) {
31582
- messageCounts.toolCalls += entry.toolNames.length;
31583
- for (const name of entry.toolNames) toolUsageMap.set(name, (toolUsageMap.get(name) ?? 0) + 1);
31584
- }
31585
- if (entry.toolResultCounts.total > 0) {
31586
- messageCounts.toolResults += entry.toolResultCounts.total;
31587
- messageCounts.errors += entry.toolResultCounts.errors;
31588
- }
31589
- if (entry.stopReason && errorStopReasons.has(entry.stopReason)) messageCounts.errors += 1;
31590
- if (entry.timestamp) {
31591
- const dayKey = formatDayKey(entry.timestamp);
31592
- activityDatesSet.add(dayKey);
31593
- const daily = dailyMessageMap.get(dayKey) ?? {
31594
- date: dayKey,
31595
- total: 0,
31596
- user: 0,
31597
- assistant: 0,
31598
- toolCalls: 0,
31599
- toolResults: 0,
31600
- errors: 0
31601
- };
31602
- daily.total += entry.role === "user" || entry.role === "assistant" ? 1 : 0;
31603
- if (entry.role === "user") daily.user += 1;
31604
- else if (entry.role === "assistant") daily.assistant += 1;
31605
- daily.toolCalls += entry.toolNames.length;
31606
- daily.toolResults += entry.toolResultCounts.total;
31607
- daily.errors += entry.toolResultCounts.errors;
31608
- if (entry.stopReason && errorStopReasons.has(entry.stopReason)) daily.errors += 1;
31609
- dailyMessageMap.set(dayKey, daily);
31610
- }
31611
- if (!entry.usage) return;
31612
- applyUsageTotals(totals, entry.usage);
31613
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(totals, entry.costBreakdown);
31614
- else applyCostTotal(totals, entry.costTotal);
31615
- if (entry.timestamp) {
31616
- const dayKey = formatDayKey(entry.timestamp);
31617
- const entryTokens = (entry.usage.input ?? 0) + (entry.usage.output ?? 0) + (entry.usage.cacheRead ?? 0) + (entry.usage.cacheWrite ?? 0);
31618
- 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);
31619
- const existing = dailyMap.get(dayKey) ?? {
31620
- tokens: 0,
31621
- cost: 0
31622
- };
31623
- dailyMap.set(dayKey, {
31624
- tokens: existing.tokens + entryTokens,
31625
- cost: existing.cost + entryCost
31626
- });
31627
- if (entry.provider || entry.model) {
31628
- const modelKey = `${dayKey}::${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
31629
- const dailyModel = dailyModelUsageMap.get(modelKey) ?? {
31630
- date: dayKey,
31631
- provider: entry.provider,
31632
- model: entry.model,
31633
- tokens: 0,
31634
- cost: 0,
31635
- count: 0
31636
- };
31637
- dailyModel.tokens += entryTokens;
31638
- dailyModel.cost += entryCost;
31639
- dailyModel.count += 1;
31640
- dailyModelUsageMap.set(modelKey, dailyModel);
31641
- }
31642
- }
31643
- if (entry.provider || entry.model) {
31644
- const key = `${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
31645
- const existing = modelUsageMap.get(key) ?? {
31646
- provider: entry.provider,
31647
- model: entry.model,
31648
- count: 0,
31649
- totals: emptyTotals()
31650
- };
31651
- existing.count += 1;
31652
- applyUsageTotals(existing.totals, entry.usage);
31653
- if (entry.costBreakdown?.total !== void 0) applyCostBreakdown(existing.totals, entry.costBreakdown);
31654
- else applyCostTotal(existing.totals, entry.costTotal);
31655
- modelUsageMap.set(key, existing);
31656
- }
31657
- }
31658
- });
31659
- const dailyBreakdown = Array.from(dailyMap.entries()).map(([date, data]) => ({
31660
- date,
31661
- tokens: data.tokens,
31662
- cost: data.cost
31663
- })).toSorted((a, b) => a.date.localeCompare(b.date));
31664
- const dailyMessageCounts = Array.from(dailyMessageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date));
31665
- const dailyLatency = Array.from(dailyLatencyMap.entries()).map(([date, values]) => {
31666
- const stats = computeLatencyStats(values);
31667
- if (!stats) return null;
31668
- return {
31669
- date,
31670
- ...stats
31671
- };
31672
- }).filter((entry) => Boolean(entry)).toSorted((a, b) => a.date.localeCompare(b.date));
31673
- const dailyModelUsage = Array.from(dailyModelUsageMap.values()).toSorted((a, b) => a.date.localeCompare(b.date) || b.cost - a.cost);
31674
- const toolUsage = toolUsageMap.size ? {
31675
- totalCalls: Array.from(toolUsageMap.values()).reduce((sum, count) => sum + count, 0),
31676
- uniqueTools: toolUsageMap.size,
31677
- tools: Array.from(toolUsageMap.entries()).map(([name, count]) => ({
31678
- name,
31679
- count
31680
- })).toSorted((a, b) => b.count - a.count)
31681
- } : void 0;
31682
- const modelUsage = modelUsageMap.size ? Array.from(modelUsageMap.values()).toSorted((a, b) => {
31683
- const costDiff = b.totals.totalCost - a.totals.totalCost;
31684
- if (costDiff !== 0) return costDiff;
31685
- return b.totals.totalTokens - a.totals.totalTokens;
31686
- }) : void 0;
31687
- return {
31688
- sessionId: params.sessionId,
31689
- sessionFile,
31690
- firstActivity,
31691
- lastActivity,
31692
- durationMs: firstActivity !== void 0 && lastActivity !== void 0 ? Math.max(0, lastActivity - firstActivity) : void 0,
31693
- activityDates: Array.from(activityDatesSet).toSorted(),
31694
- dailyBreakdown,
31695
- dailyMessageCounts,
31696
- dailyLatency: dailyLatency.length ? dailyLatency : void 0,
31697
- dailyModelUsage: dailyModelUsage.length ? dailyModelUsage : void 0,
31698
- messageCounts,
31699
- toolUsage,
31700
- modelUsage,
31701
- latency: computeLatencyStats(latencyValues),
31702
- ...totals
31703
- };
31704
- }
31705
-
31706
32512
  //#endregion
31707
32513
  //#region src/auto-reply/send-policy.ts
31708
32514
  function normalizeSendPolicyOverride(raw) {
@@ -32902,6 +33708,7 @@ async function handleCommands(params) {
32902
33708
  handleHelpCommand,
32903
33709
  handleCommandsListCommand,
32904
33710
  handleStatusCommand,
33711
+ handleCostCommand,
32905
33712
  handleAllowlistCommand,
32906
33713
  handleApproveCommand,
32907
33714
  handleContextCommand,
@@ -40147,6 +40954,32 @@ function createSessionStatusTool(opts) {
40147
40954
  }
40148
40955
  } catch {}
40149
40956
  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;
40957
+ const baseUrl = cfg.models?.providers?.[providerForCard]?.baseUrl;
40958
+ let engineLine;
40959
+ let hardwareLine;
40960
+ let costOverrideUsd;
40961
+ let costLineSuffix;
40962
+ try {
40963
+ const breakdown = await buildCostBreakdown({
40964
+ baseUrl,
40965
+ provider: providerForCard,
40966
+ modelId: configured.model,
40967
+ config: cfg,
40968
+ usage: {
40969
+ input: resolved.entry.inputTokens,
40970
+ output: resolved.entry.outputTokens
40971
+ }
40972
+ });
40973
+ engineLine = breakdown.engineLine;
40974
+ hardwareLine = breakdown.hardwareLine;
40975
+ costOverrideUsd = breakdown.instanceCostUsd;
40976
+ costLineSuffix = breakdown.costLineSuffix;
40977
+ } catch {
40978
+ engineLine = void 0;
40979
+ hardwareLine = void 0;
40980
+ costOverrideUsd = void 0;
40981
+ costLineSuffix = void 0;
40982
+ }
40150
40983
  const queueSettings = resolveQueueSettings({
40151
40984
  cfg,
40152
40985
  channel: resolved.entry.channel ?? resolved.entry.lastChannel ?? "unknown",
@@ -40192,6 +41025,10 @@ function createSessionStatusTool(opts) {
40192
41025
  dropPolicy: queueSettings.dropPolicy,
40193
41026
  showDetails: queueOverrides
40194
41027
  },
41028
+ engineLine,
41029
+ hardwareLine,
41030
+ costOverrideUsd,
41031
+ costLineSuffix,
40195
41032
  includeTranscriptUsage: false
40196
41033
  });
40197
41034
  return {
@@ -43644,7 +44481,7 @@ async function deliverSessionMaintenanceWarning(params) {
43644
44481
  return;
43645
44482
  }
43646
44483
  try {
43647
- const { deliverOutboundPayloads } = await import("./deliver-DTRkeYm3.js").then((n) => n.n);
44484
+ const { deliverOutboundPayloads } = await import("./deliver-BiWlR84Y.js").then((n) => n.n);
43648
44485
  await deliverOutboundPayloads({
43649
44486
  cfg: params.cfg,
43650
44487
  channel,
@@ -50218,7 +51055,7 @@ function readSlackExternalArgMenuToken(raw) {
50218
51055
  }
50219
51056
  let commandsRegistry;
50220
51057
  async function getCommandsRegistry() {
50221
- if (!commandsRegistry) commandsRegistry = await import("./commands-registry-DPZevjMh.js").then((n) => n.t);
51058
+ if (!commandsRegistry) commandsRegistry = await import("./commands-registry-BuOUfpmg.js").then((n) => n.t);
50222
51059
  return commandsRegistry;
50223
51060
  }
50224
51061
  function encodeSlackCommandArgValue(parts) {
@@ -50621,7 +51458,7 @@ async function registerSlackMonitorSlashCommands(params) {
50621
51458
  });
50622
51459
  const deliverSlashPayloads = async (replies) => {
50623
51460
  const [{ deliverSlackSlashReplies }, { resolveChunkMode }, { resolveMarkdownTableMode }] = await Promise.all([
50624
- import("./replies-DAYTg6Mb.js").then((n) => n.r),
51461
+ import("./replies-D0FYSIJg.js").then((n) => n.r),
50625
51462
  import("./chunk-BkYIP_hB.js").then((n) => n.s),
50626
51463
  import("./markdown-tables-CGqX2WvO.js").then((n) => n.t)
50627
51464
  ]);
@@ -50676,7 +51513,7 @@ async function registerSlackMonitorSlashCommands(params) {
50676
51513
  let nativeCommands = [];
50677
51514
  if (nativeEnabled) {
50678
51515
  reg = await getCommandsRegistry();
50679
- const skillCommands = nativeSkillsEnabled ? (await import("./skill-commands-BoMrW3WV.js").then((n) => n.a)).listSkillCommandsForAgents({ cfg }) : [];
51516
+ const skillCommands = nativeSkillsEnabled ? (await import("./skill-commands-JIccKWkf.js").then((n) => n.a)).listSkillCommandsForAgents({ cfg }) : [];
50680
51517
  nativeCommands = reg.listNativeCommandSpecsForConfig(cfg, {
50681
51518
  skillCommands,
50682
51519
  provider: "slack"