squidclaw 3.0.2 → 3.0.3

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 (388) hide show
  1. package/dist/{accounts-LA308FHj.js → accounts-CK_sHUyT.js} +2 -2
  2. package/dist/{accounts-CL_NXliB.js → accounts-CkF7YwoF.js} +17 -17
  3. package/dist/{accounts-F7tGwezI.js → accounts-DbloMfwT.js} +2 -2
  4. package/dist/{active-listener-DJv1FZqf.js → active-listener-AepfNSUY.js} +2 -2
  5. package/dist/{agents-DdixSPs3.js → agents-JnnOlm2G.js} +5 -5
  6. package/dist/{agents.config-Cn_vTN1v.js → agents.config-BeGeS2jv.js} +1 -1
  7. package/dist/{agents.config-C6KTwnde.js → agents.config-DHJBQ7uA.js} +1 -1
  8. package/dist/{plugin-sdk/api-key-rotation-DE4gr5YM.js → api-key-rotation-BHFJiYbw.js} +2 -2
  9. package/dist/{audio-preflight-AEM744TY.js → audio-preflight-BTYxAJjy.js} +32 -32
  10. package/dist/{audio-preflight-DpCWFB4z.js → audio-preflight-Dkl6Z32z.js} +4 -4
  11. package/dist/{audio-transcription-runner-CItniQDZ.js → audio-transcription-runner-DBkDgluo.js} +12 -12
  12. package/dist/{audio-transcription-runner-B2BdTEps.js → audio-transcription-runner-Gi_h5HEE.js} +1 -1
  13. package/dist/{audit-membership-runtime-w23FnNAN.js → audit-membership-runtime-DyLj-uhz.js} +4 -4
  14. package/dist/{auth-choice-7WVhiM9J.js → auth-choice-DQbCl-4F.js} +2 -2
  15. package/dist/{auth-choice-17U1cGPH.js → auth-choice-xwYK6txn.js} +2 -2
  16. package/dist/{banner-CJTrU-HC.js → banner-BxibaqUz.js} +1 -1
  17. package/dist/build-info.json +3 -3
  18. package/dist/bundled/boot-md/handler.js +51 -51
  19. package/dist/bundled/bootstrap-extra-files/handler.js +6 -6
  20. package/dist/bundled/command-logger/handler.js +2 -2
  21. package/dist/bundled/session-memory/handler.js +51 -51
  22. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  23. package/dist/{channel-activity-DPrXawu4.js → channel-activity-C5kTj83_.js} +3 -3
  24. package/dist/{channel-options-x47KAgAV.js → channel-options-BKsCYdHu.js} +1 -1
  25. package/dist/{channel-options-BM7IEY5X.js → channel-options-FdCN4cFo.js} +1 -1
  26. package/dist/{channel-web-B48pVgke.js → channel-web-BFUPrpIe.js} +1 -1
  27. package/dist/{channel-web-HM1q5FP_.js → channel-web-BkYtM8H5.js} +1 -1
  28. package/dist/{channels-cli-iPiD6449.js → channels-cli-BxhfVD-R.js} +7 -7
  29. package/dist/{channels-cli-y66ZCzYf.js → channels-cli-CZzGaGvG.js} +7 -7
  30. package/dist/{chrome-BQDCalPp.js → chrome-CAd6FQEn.js} +8 -8
  31. package/dist/{chrome-BFfAGQtd.js → chrome-pBkBuWci.js} +26 -26
  32. package/dist/cli/daemon-cli.js +1 -1
  33. package/dist/{cli-C-neGkM4.js → cli-GSev2Q95.js} +2 -2
  34. package/dist/{cli-BzpBs_KI.js → cli-bXiYaLre.js} +2 -2
  35. package/dist/{command-registry-BL80-JCV.js → command-registry-CvgCFxfY.js} +9 -9
  36. package/dist/{commands-registry-C2t2bcZ6.js → commands-registry-D6ZOTo1C.js} +4 -4
  37. package/dist/{completion-cli-CJ_L_gYr.js → completion-cli-BGM1V6EN.js} +2 -2
  38. package/dist/{completion-cli-Bi2s1mq8.js → completion-cli-OrgUDc2S.js} +1 -1
  39. package/dist/{config-cli-FhKX7MOY.js → config-cli-DbBvjvpS.js} +1 -1
  40. package/dist/{config-cli-BVpzzhoY.js → config-cli-uIP4r17f.js} +1 -1
  41. package/dist/{configure-ChiLGQo6.js → configure-BGvoAfbs.js} +6 -6
  42. package/dist/{configure-t9fm4x9H.js → configure-BOsTXjBw.js} +6 -6
  43. package/dist/{daemon-cli-DK8fQgAw.js → daemon-cli-CNi-QjEX.js} +1 -1
  44. package/dist/{daemon-cli-CO09shIt.js → daemon-cli-DN2TnjHQ.js} +1 -1
  45. package/dist/{deliver-aL8yOYS1.js → deliver-BJuiq0GS.js} +1 -1
  46. package/dist/{deliver-neVJ7AU9.js → deliver-DBXe-ZmL.js} +21 -21
  47. package/dist/{deliver-runtime-ChVR6sR3.js → deliver-runtime-DHKcNQzq.js} +3 -3
  48. package/dist/deliver-runtime-GlnBJNCj.js +36 -0
  49. package/dist/deps-send-discord.runtime-BRE0s2nz.js +26 -0
  50. package/dist/deps-send-imessage.runtime-DbIRBnmD.js +25 -0
  51. package/dist/deps-send-signal.runtime-B4h6X3o4.js +24 -0
  52. package/dist/deps-send-slack.runtime-BWXOnOxS.js +22 -0
  53. package/dist/deps-send-telegram.runtime-YvauJtgv.js +27 -0
  54. package/dist/{deps-send-whatsapp.runtime-WND2o1Mr.js → deps-send-whatsapp.runtime-BcxCalPD.js} +4 -4
  55. package/dist/deps-send-whatsapp.runtime-CslTuV47.js +60 -0
  56. package/dist/{deps-send-whatsapp.runtime-CZj97m5A.js → deps-send-whatsapp.runtime-DdxKewuy.js} +7 -7
  57. package/dist/{deps-send-whatsapp.runtime-DSbrPzxG.js → deps-send-whatsapp.runtime-Dl4ro-Df.js} +4 -4
  58. package/dist/{diagnostic-DoguEiWW.js → diagnostic-ySwZga6c.js} +2 -2
  59. package/dist/{doctor-completion-CKaQEebJ.js → doctor-completion-42wcUATu.js} +1 -1
  60. package/dist/{doctor-completion-Ctqsu6Y2.js → doctor-completion-D6RGDBD5.js} +1 -1
  61. package/dist/entry.js +2 -2
  62. package/dist/{plugin-sdk/errors-9oVz7reJ.js → errors-kkRuS2Cs.js} +1 -1
  63. package/dist/extensionAPI.js +6 -6
  64. package/dist/{fetch-DdiB5_OX.js → fetch-BLS7EMnx.js} +5 -5
  65. package/dist/{fetch-guard-CEV5qBHc.js → fetch-guard-D0fXNJls.js} +2 -2
  66. package/dist/{frontmatter-CjKtFduT.js → frontmatter-Cq1TcIQ2.js} +3 -3
  67. package/dist/{fs-safe-CwHbZdFH.js → fs-safe-BoB4X3GD.js} +4 -4
  68. package/dist/{gateway-cli-CSIyrhFg.js → gateway-cli-BbPfLLT6.js} +10 -10
  69. package/dist/{gateway-cli-xX1CTw9n.js → gateway-cli-CG3mshpO.js} +10 -10
  70. package/dist/{github-copilot-token-Cw3tAXM9.js → github-copilot-token-B5cPlwaz.js} +7 -7
  71. package/dist/{health-D9Pie2kF.js → health-CJgEuWuG.js} +1 -1
  72. package/dist/{health-D7mPTab_.js → health-dZqyhpdR.js} +1 -1
  73. package/dist/{hooks-cli-C6aI9HU7.js → hooks-cli-BD4Ww1dF.js} +3 -3
  74. package/dist/{hooks-cli-_1zdKcZA.js → hooks-cli-C0wWJOBW.js} +3 -3
  75. package/dist/{image-ecaECpjT.js → image-j_UomzVG.js} +6 -6
  76. package/dist/{image-ops-bdrMTILs.js → image-ops-CdgypS_g.js} +2 -2
  77. package/dist/image-runtime-BNh3IfMj.js +29 -0
  78. package/dist/{image-runtime-poRypm-b.js → image-runtime-SUtf9jqh.js} +3 -3
  79. package/dist/{image-DKZCmkET.js → image-sRW3RpTY.js} +1 -1
  80. package/dist/index.js +7 -7
  81. package/dist/{ir-D_GD01cg.js → ir-BvisJWXv.js} +8 -8
  82. package/dist/{legacy-names-B0wgIP0Q.js → legacy-names-aGJJuzM_.js} +1 -1
  83. package/dist/llm-slug-generator.js +51 -51
  84. package/dist/{logger-oGKcCLZ5.js → logger-CnTSBL7T.js} +7 -7
  85. package/dist/{login-gJWPqN66.js → login-BMeLPUiO.js} +5 -5
  86. package/dist/{login-qr-CgmlF7zK.js → login-qr-B2B67qqQ.js} +10 -10
  87. package/dist/{manager-CD69uguS.js → manager-DdxMYEDd.js} +13 -13
  88. package/dist/manager-runtime-BMygJEz3.js +18 -0
  89. package/dist/{model-selection-DMjtmGZP.js → model-selection-ag9BmVct.js} +43 -43
  90. package/dist/{models-BviRe-_7.js → models-BXT0s4KJ.js} +3 -3
  91. package/dist/{models-cli-BM5yo_mo.js → models-cli-BtLc9uPC.js} +3 -3
  92. package/dist/{models-cli-pvYVl1i-.js → models-cli-BwPFxWK2.js} +4 -4
  93. package/dist/{npm-resolution-DMM9Hopy.js → npm-resolution-DWpNPsBF.js} +1 -1
  94. package/dist/{npm-resolution-BTFMooVS.js → npm-resolution-Djbuzx6o.js} +1 -1
  95. package/dist/{onboard-DVuhj8ub.js → onboard-1KfKwvMR.js} +3 -3
  96. package/dist/{onboard-DTsgFKIa.js → onboard-ChxvwUze.js} +3 -3
  97. package/dist/{onboard-channels-W9UHiBQg.js → onboard-channels-CHrtFmhi.js} +2 -2
  98. package/dist/{onboard-channels-B1D9LqV_.js → onboard-channels-CXjnFvP1.js} +2 -2
  99. package/dist/{onboard-helpers-DVaF21TE.js → onboard-helpers-Bvpkyuwm.js} +6 -6
  100. package/dist/{onboard-helpers-PRhg7ZY5.js → onboard-helpers-ByttGRIZ.js} +6 -6
  101. package/dist/{onboard-remote-h-aHSDJ1.js → onboard-remote-Cfx2v9OI.js} +1 -1
  102. package/dist/{onboard-remote-DkIrV4Hx.js → onboard-remote-DxBaaS6o.js} +1 -1
  103. package/dist/{onboard-skills-fFSuiv21.js → onboard-skills-B7pHg1lN.js} +1 -1
  104. package/dist/{onboard-skills-fgrVmjJP.js → onboard-skills-PCnCZ6Od.js} +1 -1
  105. package/dist/{onboarding-D1nCnc_t.js → onboarding-D6kMb3yv.js} +7 -7
  106. package/dist/{onboarding-CYWs766P.js → onboarding-DuUMPrqA.js} +7 -7
  107. package/dist/{onboarding.finalize-Bcan6_vA.js → onboarding.finalize-KTOhO1-l.js} +7 -7
  108. package/dist/{onboarding.finalize-bAiXf9D6.js → onboarding.finalize-bphDUwZy.js} +6 -6
  109. package/dist/{onboarding.gateway-config-61E9xXYF.js → onboarding.gateway-config-DDdX0W74.js} +1 -1
  110. package/dist/{onboarding.gateway-config-Dyaqc_M7.js → onboarding.gateway-config-DNUJ0seU.js} +1 -1
  111. package/dist/{outbound-Cboz5UyH.js → outbound-DHDBvGLA.js} +6 -6
  112. package/dist/{outbound-attachment-PwEbEhAL.js → outbound-attachment-CqXiWbKN.js} +2 -2
  113. package/dist/{path-alias-guards-Cpsiv2KL.js → path-alias-guards-DORgbZ1w.js} +1 -1
  114. package/dist/{paths-CSdAWKDO.js → paths-DA5srn0U.js} +5 -5
  115. package/dist/{paths-CXClY8zC.js → paths-DSd911Oe.js} +4 -4
  116. package/dist/{pi-embedded-MktS4l8v.js → pi-embedded-BGz_qdCc.js} +24 -24
  117. package/dist/{pi-embedded-CkTlmTq8.js → pi-embedded-BP2UlUm_.js} +171 -171
  118. package/dist/{pi-embedded-helpers-DYWYzEOC.js → pi-embedded-helpers-BruaFB5l.js} +3 -3
  119. package/dist/{pi-embedded-helpers-Bfm_CvEb.js → pi-embedded-helpers-CmLnmKlb.js} +52 -52
  120. package/dist/{pi-model-discovery-DEps5Exd.js → pi-model-discovery-DAzuqPoG.js} +7 -7
  121. package/dist/pi-model-discovery-runtime-Dpu7Jm2L.js +11 -0
  122. package/dist/{pi-tools.before-tool-call.runtime-4wPdP7Br.js → pi-tools.before-tool-call.runtime-2Sp1jmlg.js} +9 -9
  123. package/dist/{plugin-registry-CvMvSI8O.js → plugin-registry-CLEhrKYA.js} +1 -1
  124. package/dist/{plugin-registry-DL2ClHLQ.js → plugin-registry-DtuxmgWx.js} +1 -1
  125. package/dist/plugin-sdk/{accounts-kr-Gz1hk.js → accounts-DghIDNk2.js} +2 -2
  126. package/dist/plugin-sdk/{accounts-CxUSDHsT.js → accounts-YTdQYQFr.js} +3 -3
  127. package/dist/plugin-sdk/{accounts-PSzw-z3S.js → accounts-h__dTrLK.js} +2 -2
  128. package/dist/plugin-sdk/{active-listener-BQNrTcR3.js → active-listener-_PRYjtJv.js} +2 -2
  129. package/dist/plugin-sdk/{api-key-rotation-Bhck7wki.js → api-key-rotation-mVDSAkKQ.js} +2 -2
  130. package/dist/plugin-sdk/{audio-preflight-_xgGaeho.js → audio-preflight-BZlQM-qX.js} +26 -26
  131. package/dist/plugin-sdk/{audio-transcription-runner-Dwc0Eh-B.js → audio-transcription-runner-CrYTX8py.js} +11 -11
  132. package/dist/plugin-sdk/{audit-membership-runtime-DHQDvH4u.js → audit-membership-runtime-Xl20kCBe.js} +2 -2
  133. package/dist/plugin-sdk/{channel-activity-XajEg_DL.js → channel-activity-gwxRn4wF.js} +3 -3
  134. package/dist/plugin-sdk/{channel-web-KtqCp4mz.js → channel-web-1WF-Nabe.js} +18 -18
  135. package/dist/plugin-sdk/{chrome-diV5m81I.js → chrome-BXbYwXRH.js} +6 -6
  136. package/dist/plugin-sdk/{commands-registry-DwZAJuut.js → commands-registry-0w-aZenK.js} +4 -4
  137. package/dist/plugin-sdk/{common-CqnO92P8.js → common-DBOCt6Yv.js} +2 -2
  138. package/dist/plugin-sdk/{config-DYbtdrsT.js → config-pRtEoVyZ.js} +7 -7
  139. package/dist/plugin-sdk/{deliver-DG_7Uagn.js → deliver-FjlJrtZk.js} +10 -10
  140. package/dist/plugin-sdk/deliver-runtime-DEzvpBW1.js +32 -0
  141. package/dist/plugin-sdk/deps-send-discord.runtime-Bhusa_Hi.js +23 -0
  142. package/dist/plugin-sdk/deps-send-imessage.runtime-bmakPm5f.js +22 -0
  143. package/dist/plugin-sdk/deps-send-signal.runtime-n00sfFto.js +21 -0
  144. package/dist/plugin-sdk/deps-send-slack.runtime-BvM3Z-Mr.js +19 -0
  145. package/dist/plugin-sdk/deps-send-telegram.runtime-CPuMkcmo.js +24 -0
  146. package/dist/plugin-sdk/deps-send-whatsapp.runtime-BzO6S-KX.js +57 -0
  147. package/dist/plugin-sdk/{diagnostic-CT7v_kM2.js → diagnostic-Dt2i3afe.js} +2 -2
  148. package/dist/plugin-sdk/{errors-B8oJXuCF.js → errors-CgRPdp3o.js} +1 -1
  149. package/dist/plugin-sdk/{fetch-guard-Or5BCq0E.js → fetch-guard-DyPZh8r2.js} +2 -2
  150. package/dist/plugin-sdk/{fs-safe-DFbwq9CS.js → fs-safe-DqCO1D4C.js} +3 -3
  151. package/dist/plugin-sdk/{image-rycGCqJO.js → image-CQ9TZ9vq.js} +6 -6
  152. package/dist/plugin-sdk/{image-ops-CMsocOob.js → image-ops-sw0uZ0GN.js} +2 -2
  153. package/dist/plugin-sdk/image-runtime-17_mTqsy.js +25 -0
  154. package/dist/plugin-sdk/index.js +50 -50
  155. package/dist/plugin-sdk/{ir-DihI2SIz.js → ir-BVZ5kUMb.js} +7 -7
  156. package/dist/plugin-sdk/{local-roots-1xVosTZ4.js → local-roots-fO3ZgW3G.js} +4 -4
  157. package/dist/plugin-sdk/{logger-Bg4vIUJn.js → logger-DIb2cGHp.js} +2 -2
  158. package/dist/plugin-sdk/{login-YhFrVUWo.js → login-Dg5cxB_3.js} +4 -4
  159. package/dist/plugin-sdk/{login-qr-SpUTuwYv.js → login-qr-C3Vn30cq.js} +5 -5
  160. package/dist/plugin-sdk/{manager-DrzOPeMD.js → manager-BR-TwWTH.js} +8 -8
  161. package/dist/plugin-sdk/manager-runtime-CvI9wF8N.js +15 -0
  162. package/dist/plugin-sdk/{outbound-Cc4cUn9K.js → outbound-1a3Z_QJ2.js} +5 -5
  163. package/dist/plugin-sdk/{outbound-attachment-Dtp3hQgc.js → outbound-attachment-BTQjD4YE.js} +2 -2
  164. package/dist/plugin-sdk/{path-alias-guards-DA0MhfkG.js → path-alias-guards-TnxupPQC.js} +1 -1
  165. package/dist/plugin-sdk/{paths-CP67O8eN.js → paths-B7_75Pdr.js} +1 -1
  166. package/dist/plugin-sdk/{pi-embedded-helpers-BDJ_4Plh.js → pi-embedded-helpers-DZRNadD8.js} +16 -16
  167. package/dist/plugin-sdk/{pi-model-discovery-Mk0GTDJl.js → pi-model-discovery-DGh6xekX.js} +1 -1
  168. package/dist/plugin-sdk/pi-model-discovery-runtime-DjjBdPYt.js +8 -0
  169. package/dist/plugin-sdk/{pi-tools.before-tool-call.runtime-DV72wTDb.js → pi-tools.before-tool-call.runtime-BZ9XgG_x.js} +4 -4
  170. package/dist/plugin-sdk/{plugins-DSs2-fnK.js → plugins-B8pWVYug.js} +4 -4
  171. package/dist/plugin-sdk/{proxy-env-Ib4-LUh-.js → proxy-env-BOlkiW1-.js} +1 -1
  172. package/dist/plugin-sdk/{proxy-fetch-ZPEvp58f.js → proxy-fetch-Dt5BedH8.js} +1 -1
  173. package/dist/plugin-sdk/{pw-ai-DIx2wpkY.js → pw-ai-C17A1o4w.js} +9 -9
  174. package/dist/plugin-sdk/{qmd-manager-Ov9ElEfG.js → qmd-manager-Bei6TaFq.js} +7 -7
  175. package/dist/plugin-sdk/{query-expansion-CzjwW461.js → query-expansion-POz2za8a.js} +4 -4
  176. package/dist/plugin-sdk/{redact-BoNEjbpF.js → redact-9WsNyb7S.js} +1 -1
  177. package/dist/plugin-sdk/{reply-CWWUd_JS.js → reply-BFbijn6_.js} +73 -73
  178. package/dist/plugin-sdk/{resolve-outbound-target-BOkvxZtM.js → resolve-outbound-target-B9iFEh0y.js} +2 -2
  179. package/dist/plugin-sdk/{run-with-concurrency-kVooFCVo.js → run-with-concurrency-DmTrN5JG.js} +1 -1
  180. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-DzhkSmLi.js +10 -0
  181. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-DyILWezU.js +19 -0
  182. package/dist/plugin-sdk/{send-BP1fSEBR.js → send-BGZo6HW1.js} +5 -5
  183. package/dist/plugin-sdk/{send-D9CSOGul.js → send-BisREGBZ.js} +6 -6
  184. package/dist/plugin-sdk/{send-BeLBlAsQ.js → send-BqkUDZed.js} +13 -13
  185. package/dist/plugin-sdk/{send-DLKxJJYV.js → send-D6_nNvi0.js} +8 -8
  186. package/dist/plugin-sdk/{send-XZ6IXCtL.js → send-Dj7XEcZN.js} +7 -7
  187. package/dist/plugin-sdk/{session-DtLUYWvY.js → session-D4KDs7Hq.js} +3 -3
  188. package/dist/plugin-sdk/{skill-commands-Bv7EZypt.js → skill-commands-D_xeseiI.js} +4 -4
  189. package/dist/plugin-sdk/{skills-BzXN4uev.js → skills-Bs2b3JfV.js} +6 -6
  190. package/dist/plugin-sdk/slash-commands.runtime-CUb5sqqf.js +13 -0
  191. package/dist/plugin-sdk/slash-dispatch.runtime-DCB6bGjB.js +52 -0
  192. package/dist/plugin-sdk/slash-skill-commands.runtime-BqEweE4K.js +16 -0
  193. package/dist/plugin-sdk/{store-DnJhFFW5.js → store-B7ESm9_L.js} +2 -2
  194. package/dist/plugin-sdk/subagent-registry-runtime-CCUW4SbM.js +52 -0
  195. package/dist/plugin-sdk/{tables-CpmqssLF.js → tables-1vhBJPK_.js} +1 -1
  196. package/dist/plugin-sdk/{thinking-1UCPuD9d.js → thinking-DjaClmzi.js} +7 -7
  197. package/dist/plugin-sdk/{tokens-DAL_5WHL.js → tokens-CLE20fRI.js} +1 -1
  198. package/dist/plugin-sdk/{tool-images-RX4QTMnt.js → tool-images-B95xcwiR.js} +2 -2
  199. package/dist/plugin-sdk/web-DeRmHQ4_.js +56 -0
  200. package/dist/plugin-sdk/{whatsapp-actions-BF6ih4Gi.js → whatsapp-actions-BYpcWkTN.js} +17 -17
  201. package/dist/plugin-sdk/whatsapp.js +50 -50
  202. package/dist/{plugins-CmdmAU0K.js → plugins-DXkm70nK.js} +11 -11
  203. package/dist/{plugins-cli-DBtLtIsQ.js → plugins-cli-Cs3UUJew.js} +3 -3
  204. package/dist/{plugins-cli-BMPvpwSo.js → plugins-cli-KPz6APX0.js} +3 -3
  205. package/dist/{program-context-KSeqVkRM.js → program-context-J_FyEsaS.js} +18 -18
  206. package/dist/{program-C6sTShRB.js → program-xNEHPhT8.js} +8 -8
  207. package/dist/{prompt-select-styled-Ba5fC0g1.js → prompt-select-styled-B1LjjgQ0.js} +5 -5
  208. package/dist/{prompt-select-styled-DFhJPiqx.js → prompt-select-styled-BRiogP_P.js} +5 -5
  209. package/dist/{provider-auth-helpers-S2rdI85T.js → provider-auth-helpers-CxUWqt95.js} +1 -1
  210. package/dist/{provider-auth-helpers-BPvZ8xkJ.js → provider-auth-helpers-hhFVhZdv.js} +1 -1
  211. package/dist/{proxy-env-QUJz9VEJ.js → proxy-env-D75CWSOo.js} +1 -1
  212. package/dist/{proxy-fetch-C2v-Utgg.js → proxy-fetch-lH6RsRTE.js} +1 -1
  213. package/dist/{push-apns-BQEPMPtG.js → push-apns-BBkpZyNR.js} +1 -1
  214. package/dist/{push-apns-CGibQhps.js → push-apns-BQjV_93G.js} +1 -1
  215. package/dist/{pw-ai-SYjuzbV6.js → pw-ai-7kHgUGj0.js} +14 -14
  216. package/dist/{pw-ai-zFPBSxaL.js → pw-ai-BmGrTicP.js} +1 -1
  217. package/dist/{qmd-manager-CO-shcLU.js → qmd-manager-BN0siR2Z.js} +10 -10
  218. package/dist/{query-expansion-DlQOkf-g.js → query-expansion-Dzxt6kXo.js} +6 -6
  219. package/dist/{redact-NmPEVjIo.js → redact-DvzicBMu.js} +1 -1
  220. package/dist/{register.agent-DP_2xCaO.js → register.agent-DYq06QHS.js} +8 -8
  221. package/dist/{register.agent-BwhWwpRX.js → register.agent-reU63wQ5.js} +7 -7
  222. package/dist/{register.configure-D8TE-yQn.js → register.configure-C4p9ad2q.js} +10 -10
  223. package/dist/{register.configure-C5i661J4.js → register.configure-DezZ4Q1p.js} +10 -10
  224. package/dist/{register.maintenance-BS2i3S5V.js → register.maintenance-CTvFmkAm.js} +9 -9
  225. package/dist/{register.maintenance-BA4UOg2_.js → register.maintenance-CzMKTC2a.js} +8 -8
  226. package/dist/{register.message-oFI2Mzrd.js → register.message-BmsovYS6.js} +3 -3
  227. package/dist/{register.message-D9hVI5b6.js → register.message-Bp4SDXWk.js} +3 -3
  228. package/dist/{register.onboard-D6wqijOl.js → register.onboard-C39xhpv1.js} +3 -3
  229. package/dist/{register.onboard-OaKr3SnU.js → register.onboard-DZt2kSAg.js} +3 -3
  230. package/dist/{register.setup-DsK_7zih.js → register.setup-04L_8wfA.js} +3 -3
  231. package/dist/{register.setup-Dygx-glo.js → register.setup-DWctFmOd.js} +3 -3
  232. package/dist/{register.status-health-sessions-C6VfEhho.js → register.status-health-sessions-CBPZoj51.js} +4 -4
  233. package/dist/{register.status-health-sessions-BmWcbWPR.js → register.status-health-sessions-N6SFc-UY.js} +4 -4
  234. package/dist/{register.subclis-CLf32krW.js → register.subclis-C3TphbCF.js} +10 -10
  235. package/dist/{reply-ZWkzBiSb.js → reply-CB1p166g.js} +5 -5
  236. package/dist/{run-main-asKkGUqy.js → run-main-7tknx04F.js} +15 -15
  237. package/dist/{run-with-concurrency-FczpX8ng.js → run-with-concurrency-BFR3ReeF.js} +4 -4
  238. package/dist/runtime-whatsapp-login.runtime-DSR-m0FW.js +13 -0
  239. package/dist/runtime-whatsapp-outbound.runtime-Blywd_bv.js +22 -0
  240. package/dist/{send-oS3t6gE6.js → send-C98RfcAb.js} +5 -5
  241. package/dist/{send-DX_O1OHH.js → send-Co5Bqwuo.js} +6 -6
  242. package/dist/{send-BNsV-D2Y.js → send-DjL7KlMV.js} +8 -8
  243. package/dist/{send-C-jb8X9I.js → send-Do7hKDL9.js} +7 -7
  244. package/dist/{send-D-Rnbdzz.js → send-bW7jDv8D.js} +26 -26
  245. package/dist/{server-node-events-DV2yeAp-.js → server-node-events-Ctjzvlem.js} +3 -3
  246. package/dist/{server-node-events-BHv7a_ll.js → server-node-events-DrCKK0J4.js} +3 -3
  247. package/dist/{session-DRyURckG.js → session-QSn69XeJ.js} +8 -8
  248. package/dist/{skill-commands-BrlAf_CG.js → skill-commands-Bi_jchJn.js} +9 -9
  249. package/dist/{skills-DWrRJwa-.js → skills-CTV78w4q.js} +22 -22
  250. package/dist/slash-commands.runtime-63MUmCBt.js +16 -0
  251. package/dist/{slash-dispatch.runtime-DkcAYuyK.js → slash-dispatch.runtime-BL3qA1O3.js} +6 -6
  252. package/dist/{slash-dispatch.runtime-BJOuQOeN.js → slash-dispatch.runtime-DRGqAgwa.js} +2 -2
  253. package/dist/slash-dispatch.runtime-Dh2L_3Tg.js +56 -0
  254. package/dist/{slash-dispatch.runtime-CEAbkOCI.js → slash-dispatch.runtime-uqWhoI6q.js} +2 -2
  255. package/dist/slash-skill-commands.runtime-B3MSSAQ-.js +20 -0
  256. package/dist/{status-Ck8-aQIF.js → status-BkfSGlOi.js} +3 -3
  257. package/dist/{status-CMhW6nGs.js → status-DdW571-j.js} +3 -3
  258. package/dist/{store-BFNH5fXG.js → store-B89Hj8Ub.js} +2 -2
  259. package/dist/{subagent-registry-DQpeidFk.js → subagent-registry-DGrfQVN3.js} +5 -5
  260. package/dist/subagent-registry-runtime-BRNDawlJ.js +56 -0
  261. package/dist/{subagent-registry-runtime-C-jjppV6.js → subagent-registry-runtime-DatTO2LD.js} +2 -2
  262. package/dist/{subagent-registry-runtime-tRRyFZL8.js → subagent-registry-runtime-Dsrz3yIh.js} +2 -2
  263. package/dist/{subagent-registry-runtime-BlRAnw80.js → subagent-registry-runtime-MtjBCcgn.js} +6 -6
  264. package/dist/{subsystem-BaLYRf7D.js → subsystem-6v7sWnAD.js} +14 -14
  265. package/dist/{tables-CnlmCLb3.js → tables-DGHzaXQz.js} +1 -1
  266. package/dist/{target-errors-Df1wB-I7.js → target-errors-CweAa7L9.js} +2 -2
  267. package/dist/{thinking-CTpcVnlx.js → thinking-SdNGqtJE.js} +7 -7
  268. package/dist/{tokens-D2XhLqIz.js → tokens-DfbMVF9y.js} +1 -1
  269. package/dist/{tool-images-CElPu2en.js → tool-images-8BKrL7Bn.js} +2 -2
  270. package/dist/{update-cli-5KzuA6pa.js → update-cli-0UiUaT3q.js} +10 -10
  271. package/dist/{update-cli-CEghYBNP.js → update-cli-C-uyQcFS.js} +9 -9
  272. package/dist/{update-runner-C5XgCwj2.js → update-runner-CT9YRLtn.js} +1 -1
  273. package/dist/{update-runner-C0q8aGFd.js → update-runner-CqVLeGYA.js} +1 -1
  274. package/dist/{web-DBm_uXOl.js → web-B2qXyOb9.js} +3 -3
  275. package/dist/{web-DdrUn13G.js → web-B7kbCskR.js} +55 -55
  276. package/dist/{web-DddJa7ZT.js → web-D1ZoRVB0.js} +6 -6
  277. package/dist/{web-O2WkG3cH.js → web-FqoNMI-k.js} +3 -3
  278. package/dist/{whatsapp-actions-DPszRJ8b.js → whatsapp-actions-BDkbnZVH.js} +21 -21
  279. package/dist/{workspace-TqfVSQuO.js → workspace-kVMIaBrV.js} +20 -20
  280. package/package.json +1 -1
  281. package/dist/api-key-rotation-Dzvqp3Dc.js +0 -181
  282. package/dist/deliver-runtime-BdUlqV9E.js +0 -36
  283. package/dist/deps-send-discord.runtime-R8jUd_2I.js +0 -26
  284. package/dist/deps-send-imessage.runtime-Die0aWtU.js +0 -25
  285. package/dist/deps-send-signal.runtime-Biux_4v4.js +0 -24
  286. package/dist/deps-send-slack.runtime-CkUST2Ky.js +0 -22
  287. package/dist/deps-send-telegram.runtime-CIN5ILBe.js +0 -27
  288. package/dist/deps-send-whatsapp.runtime-DUff9bWS.js +0 -60
  289. package/dist/errors-DfgAh2Ml.js +0 -54
  290. package/dist/image-runtime-irHu11-U.js +0 -29
  291. package/dist/manager-runtime-BISxj7HK.js +0 -18
  292. package/dist/pi-model-discovery-runtime-bzJViQLK.js +0 -11
  293. package/dist/plugin-sdk/accounts-BNuRM3rG.js +0 -288
  294. package/dist/plugin-sdk/accounts-CGTYP7Rh.js +0 -46
  295. package/dist/plugin-sdk/accounts-CcS9IAhD.js +0 -35
  296. package/dist/plugin-sdk/active-listener-CTsLn1AX.js +0 -50
  297. package/dist/plugin-sdk/audio-preflight-CRGLqp-g.js +0 -69
  298. package/dist/plugin-sdk/audio-transcription-runner-RXsskMMk.js +0 -2176
  299. package/dist/plugin-sdk/audit-membership-runtime-B9b-zRwg.js +0 -58
  300. package/dist/plugin-sdk/channel-activity-gPvD1D7S.js +0 -94
  301. package/dist/plugin-sdk/channel-web-LGl1zPJt.js +0 -2256
  302. package/dist/plugin-sdk/chrome-9Y_LcUg1.js +0 -2415
  303. package/dist/plugin-sdk/commands-registry-CcdEPxVg.js +0 -1125
  304. package/dist/plugin-sdk/config-CrQ5bCrw.js +0 -17912
  305. package/dist/plugin-sdk/deliver-D3xr5AkB.js +0 -1694
  306. package/dist/plugin-sdk/deliver-runtime-B79ZQu69.js +0 -32
  307. package/dist/plugin-sdk/deliver-runtime-BdTC7uKE.js +0 -32
  308. package/dist/plugin-sdk/deps-send-discord.runtime-BOQZIqC8.js +0 -23
  309. package/dist/plugin-sdk/deps-send-discord.runtime-CObCNMt3.js +0 -23
  310. package/dist/plugin-sdk/deps-send-imessage.runtime-CuHOc9Ka.js +0 -22
  311. package/dist/plugin-sdk/deps-send-imessage.runtime-DlWgi2DH.js +0 -22
  312. package/dist/plugin-sdk/deps-send-signal.runtime-Cz7FT8J8.js +0 -21
  313. package/dist/plugin-sdk/deps-send-signal.runtime-iPynghkE.js +0 -21
  314. package/dist/plugin-sdk/deps-send-slack.runtime-D4vDoRsg.js +0 -19
  315. package/dist/plugin-sdk/deps-send-slack.runtime-DNTbE5jS.js +0 -19
  316. package/dist/plugin-sdk/deps-send-telegram.runtime-7CR-xtCF.js +0 -24
  317. package/dist/plugin-sdk/deps-send-telegram.runtime-DjTVED_m.js +0 -24
  318. package/dist/plugin-sdk/deps-send-whatsapp.runtime-CRWOIKRC.js +0 -57
  319. package/dist/plugin-sdk/deps-send-whatsapp.runtime-bUi8kghi.js +0 -57
  320. package/dist/plugin-sdk/diagnostic-BXkLYs_9.js +0 -319
  321. package/dist/plugin-sdk/fetch-guard-C55uvn27.js +0 -156
  322. package/dist/plugin-sdk/fs-safe-Dqmpk-Fr.js +0 -352
  323. package/dist/plugin-sdk/image-3xW7IJdq.js +0 -2310
  324. package/dist/plugin-sdk/image-ops-BjK2qZZn.js +0 -584
  325. package/dist/plugin-sdk/image-runtime-CZZJJqcW.js +0 -25
  326. package/dist/plugin-sdk/image-runtime-Cjz368oj.js +0 -25
  327. package/dist/plugin-sdk/ir-CS7uuQhN.js +0 -1296
  328. package/dist/plugin-sdk/local-roots-DmOKwiNW.js +0 -186
  329. package/dist/plugin-sdk/logger-DDdrdbDu.js +0 -1163
  330. package/dist/plugin-sdk/login-BSEeU27Y.js +0 -57
  331. package/dist/plugin-sdk/login-qr-BwWJsDSj.js +0 -320
  332. package/dist/plugin-sdk/manager-DiXPCubI.js +0 -3917
  333. package/dist/plugin-sdk/manager-runtime-CF55pBNe.js +0 -15
  334. package/dist/plugin-sdk/manager-runtime-Ct0m9UJC.js +0 -15
  335. package/dist/plugin-sdk/outbound-attachment-BoFx05zw.js +0 -19
  336. package/dist/plugin-sdk/outbound-cpqK1GFe.js +0 -212
  337. package/dist/plugin-sdk/path-alias-guards-gBhrAn14.js +0 -43
  338. package/dist/plugin-sdk/paths-C6W4VHoa.js +0 -166
  339. package/dist/plugin-sdk/pi-embedded-helpers-C-B9B6Sp.js +0 -9627
  340. package/dist/plugin-sdk/pi-model-discovery-BGEeoPzN.js +0 -134
  341. package/dist/plugin-sdk/pi-model-discovery-runtime-BHZ_Htob.js +0 -8
  342. package/dist/plugin-sdk/pi-model-discovery-runtime-BrwtJHPU.js +0 -8
  343. package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-ByN_xThw.js +0 -354
  344. package/dist/plugin-sdk/plugins-D5cdn70e.js +0 -864
  345. package/dist/plugin-sdk/proxy-fetch-Cf3IUSDw.js +0 -38
  346. package/dist/plugin-sdk/pw-ai-C_QOIuin.js +0 -1938
  347. package/dist/plugin-sdk/qmd-manager-6bozlfFg.js +0 -1448
  348. package/dist/plugin-sdk/query-expansion-eeVz_aEm.js +0 -1011
  349. package/dist/plugin-sdk/redact-DfACyt0X.js +0 -319
  350. package/dist/plugin-sdk/reply-CQUX_haM.js +0 -98828
  351. package/dist/plugin-sdk/resolve-outbound-target-Dbz0O8cR.js +0 -40
  352. package/dist/plugin-sdk/run-with-concurrency-5DMu9szx.js +0 -1994
  353. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-DitS0I1z.js +0 -10
  354. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-OthrtsLL.js +0 -10
  355. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-CYCr6A3v.js +0 -19
  356. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-Q2HL0zL3.js +0 -19
  357. package/dist/plugin-sdk/send-BACEu1Un.js +0 -414
  358. package/dist/plugin-sdk/send-BU4OoR7u.js +0 -2587
  359. package/dist/plugin-sdk/send-DbxOJ_BC.js +0 -3135
  360. package/dist/plugin-sdk/send-n932vjT5.js +0 -540
  361. package/dist/plugin-sdk/send-uCPS53j8.js +0 -503
  362. package/dist/plugin-sdk/session-DenDKR_-.js +0 -169
  363. package/dist/plugin-sdk/skill-commands-BK1KDKmS.js +0 -342
  364. package/dist/plugin-sdk/skills-D4am-zkO.js +0 -1428
  365. package/dist/plugin-sdk/slash-commands.runtime-Bx1K1iqP.js +0 -13
  366. package/dist/plugin-sdk/slash-commands.runtime-DWfFqMZw.js +0 -13
  367. package/dist/plugin-sdk/slash-dispatch.runtime-DVn338JI.js +0 -52
  368. package/dist/plugin-sdk/slash-dispatch.runtime-pnWH5AjM.js +0 -52
  369. package/dist/plugin-sdk/slash-skill-commands.runtime-Dbi_YzPO.js +0 -16
  370. package/dist/plugin-sdk/slash-skill-commands.runtime-DxvNWv_E.js +0 -16
  371. package/dist/plugin-sdk/ssrf-2WBi1Tzx.js +0 -202
  372. package/dist/plugin-sdk/store-BKDMuvyn.js +0 -81
  373. package/dist/plugin-sdk/subagent-registry-runtime-FhP0l-Rw.js +0 -52
  374. package/dist/plugin-sdk/subagent-registry-runtime-hH9ADku1.js +0 -52
  375. package/dist/plugin-sdk/tables-CrDYcv_b.js +0 -55
  376. package/dist/plugin-sdk/target-errors-aOwE-MIU.js +0 -195
  377. package/dist/plugin-sdk/thinking-D41FMh9T.js +0 -1206
  378. package/dist/plugin-sdk/tokens-CTIYTLWu.js +0 -52
  379. package/dist/plugin-sdk/tool-images-CWc54lpI.js +0 -274
  380. package/dist/plugin-sdk/web-AtEy-48y.js +0 -56
  381. package/dist/plugin-sdk/web-DjKONHqF.js +0 -56
  382. package/dist/plugin-sdk/whatsapp-actions-DEZcm_CZ.js +0 -80
  383. package/dist/runtime-whatsapp-login.runtime-BqOsE5As.js +0 -13
  384. package/dist/runtime-whatsapp-outbound.runtime-D5S6mxFT.js +0 -22
  385. package/dist/slash-commands.runtime-JqCsKeu2.js +0 -16
  386. package/dist/slash-dispatch.runtime-h9I6EDYB.js +0 -56
  387. package/dist/slash-skill-commands.runtime-C0QZlkpu.js +0 -20
  388. package/dist/subagent-registry-runtime-BxvwRp_3.js +0 -56
@@ -1,2310 +0,0 @@
1
- import { U as resolveAgentModelFallbackValues, W as resolveAgentModelPrimaryValue } from "./run-with-concurrency-5DMu9szx.js";
2
- import { $n as requireApiKey, Bn as resolveImplicitBedrockProvider, Hn as resolveImplicitProviders, Or as resolveSquidClawAgentDir, Rr as normalizeSecretInput, Vn as resolveImplicitCopilotProvider, Zn as getApiKeyForModel, n as loadConfig, xn as applyConfigEnvVars, zn as normalizeProviders } from "./config-CrQ5bCrw.js";
3
- import { O as shortenHomeInString, y as isRecord } from "./logger-DDdrdbDu.js";
4
- import { N as sanitizeUserFacingText } from "./pi-embedded-helpers-C-B9B6Sp.js";
5
- import { n as redactToolDetail } from "./redact-BoNEjbpF.js";
6
- import path from "node:path";
7
- import fs from "node:fs/promises";
8
- import { complete } from "@mariozechner/pi-ai";
9
-
10
- //#region src/agents/minimax-vlm.ts
11
- function coerceApiHost(params) {
12
- const env = params.env ?? process.env;
13
- const raw = params.apiHost?.trim() || env.MINIMAX_API_HOST?.trim() || params.modelBaseUrl?.trim() || "https://api.minimax.io";
14
- try {
15
- return new URL(raw).origin;
16
- } catch {}
17
- try {
18
- return new URL(`https://${raw}`).origin;
19
- } catch {
20
- return "https://api.minimax.io";
21
- }
22
- }
23
- function pickString(rec, key) {
24
- const v = rec[key];
25
- return typeof v === "string" ? v : "";
26
- }
27
- async function minimaxUnderstandImage(params) {
28
- const apiKey = normalizeSecretInput(params.apiKey);
29
- if (!apiKey) throw new Error("MiniMax VLM: apiKey required");
30
- const prompt = params.prompt.trim();
31
- if (!prompt) throw new Error("MiniMax VLM: prompt required");
32
- const imageDataUrl = params.imageDataUrl.trim();
33
- if (!imageDataUrl) throw new Error("MiniMax VLM: imageDataUrl required");
34
- if (!/^data:image\/(png|jpeg|webp);base64,/i.test(imageDataUrl)) throw new Error("MiniMax VLM: imageDataUrl must be a base64 data:image/(png|jpeg|webp) URL");
35
- const host = coerceApiHost({
36
- apiHost: params.apiHost,
37
- modelBaseUrl: params.modelBaseUrl
38
- });
39
- const url = new URL("/v1/coding_plan/vlm", host).toString();
40
- const res = await fetch(url, {
41
- method: "POST",
42
- headers: {
43
- Authorization: `Bearer ${apiKey}`,
44
- "Content-Type": "application/json",
45
- "MM-API-Source": "SquidClaw"
46
- },
47
- body: JSON.stringify({
48
- prompt,
49
- image_url: imageDataUrl
50
- })
51
- });
52
- const traceId = res.headers.get("Trace-Id") ?? "";
53
- if (!res.ok) {
54
- const body = await res.text().catch(() => "");
55
- const trace = traceId ? ` Trace-Id: ${traceId}` : "";
56
- throw new Error(`MiniMax VLM request failed (${res.status} ${res.statusText}).${trace}${body ? ` Body: ${body.slice(0, 400)}` : ""}`);
57
- }
58
- const json = await res.json().catch(() => null);
59
- if (!isRecord(json)) {
60
- const trace = traceId ? ` Trace-Id: ${traceId}` : "";
61
- throw new Error(`MiniMax VLM response was not JSON.${trace}`);
62
- }
63
- const baseResp = isRecord(json.base_resp) ? json.base_resp : {};
64
- const code = typeof baseResp.status_code === "number" ? baseResp.status_code : -1;
65
- if (code !== 0) {
66
- const msg = (baseResp.status_msg ?? "").trim();
67
- const trace = traceId ? ` Trace-Id: ${traceId}` : "";
68
- throw new Error(`MiniMax VLM API error (${code})${msg ? `: ${msg}` : ""}.${trace}`);
69
- }
70
- const content = pickString(json, "content").trim();
71
- if (!content) {
72
- const trace = traceId ? ` Trace-Id: ${traceId}` : "";
73
- throw new Error(`MiniMax VLM returned no content.${trace}`);
74
- }
75
- return content;
76
- }
77
-
78
- //#endregion
79
- //#region src/agents/models-config.ts
80
- const DEFAULT_MODE = "merge";
81
- function resolvePreferredTokenLimit(explicitValue, implicitValue) {
82
- return explicitValue > implicitValue ? explicitValue : implicitValue;
83
- }
84
- function mergeProviderModels(implicit, explicit) {
85
- const implicitModels = Array.isArray(implicit.models) ? implicit.models : [];
86
- const explicitModels = Array.isArray(explicit.models) ? explicit.models : [];
87
- if (implicitModels.length === 0) return {
88
- ...implicit,
89
- ...explicit
90
- };
91
- const getId = (model) => {
92
- if (!model || typeof model !== "object") return "";
93
- const id = model.id;
94
- return typeof id === "string" ? id.trim() : "";
95
- };
96
- const implicitById = new Map(implicitModels.map((model) => [getId(model), model]).filter(([id]) => Boolean(id)));
97
- const seen = /* @__PURE__ */ new Set();
98
- const mergedModels = explicitModels.map((explicitModel) => {
99
- const id = getId(explicitModel);
100
- if (!id) return explicitModel;
101
- seen.add(id);
102
- const implicitModel = implicitById.get(id);
103
- if (!implicitModel) return explicitModel;
104
- return {
105
- ...explicitModel,
106
- input: implicitModel.input,
107
- reasoning: "reasoning" in explicitModel ? explicitModel.reasoning : implicitModel.reasoning,
108
- contextWindow: resolvePreferredTokenLimit(explicitModel.contextWindow, implicitModel.contextWindow),
109
- maxTokens: resolvePreferredTokenLimit(explicitModel.maxTokens, implicitModel.maxTokens)
110
- };
111
- });
112
- for (const implicitModel of implicitModels) {
113
- const id = getId(implicitModel);
114
- if (!id || seen.has(id)) continue;
115
- seen.add(id);
116
- mergedModels.push(implicitModel);
117
- }
118
- return {
119
- ...implicit,
120
- ...explicit,
121
- models: mergedModels
122
- };
123
- }
124
- function mergeProviders(params) {
125
- const out = params.implicit ? { ...params.implicit } : {};
126
- for (const [key, explicit] of Object.entries(params.explicit ?? {})) {
127
- const providerKey = key.trim();
128
- if (!providerKey) continue;
129
- const implicit = out[providerKey];
130
- out[providerKey] = implicit ? mergeProviderModels(implicit, explicit) : explicit;
131
- }
132
- return out;
133
- }
134
- async function readJson(pathname) {
135
- try {
136
- const raw = await fs.readFile(pathname, "utf8");
137
- return JSON.parse(raw);
138
- } catch {
139
- return null;
140
- }
141
- }
142
- async function resolveProvidersForModelsJson(params) {
143
- const { cfg, agentDir } = params;
144
- const explicitProviders = cfg.models?.providers ?? {};
145
- const providers = mergeProviders({
146
- implicit: await resolveImplicitProviders({
147
- agentDir,
148
- explicitProviders
149
- }),
150
- explicit: explicitProviders
151
- });
152
- const implicitBedrock = await resolveImplicitBedrockProvider({
153
- agentDir,
154
- config: cfg
155
- });
156
- if (implicitBedrock) {
157
- const existing = providers["amazon-bedrock"];
158
- providers["amazon-bedrock"] = existing ? mergeProviderModels(implicitBedrock, existing) : implicitBedrock;
159
- }
160
- const implicitCopilot = await resolveImplicitCopilotProvider({ agentDir });
161
- if (implicitCopilot && !providers["github-copilot"]) providers["github-copilot"] = implicitCopilot;
162
- return providers;
163
- }
164
- function mergeWithExistingProviderSecrets(params) {
165
- const { nextProviders, existingProviders } = params;
166
- const mergedProviders = {};
167
- for (const [key, entry] of Object.entries(existingProviders)) mergedProviders[key] = entry;
168
- for (const [key, newEntry] of Object.entries(nextProviders)) {
169
- const existing = existingProviders[key];
170
- if (!existing) {
171
- mergedProviders[key] = newEntry;
172
- continue;
173
- }
174
- const preserved = {};
175
- if (typeof existing.apiKey === "string" && existing.apiKey) preserved.apiKey = existing.apiKey;
176
- if (typeof existing.baseUrl === "string" && existing.baseUrl) preserved.baseUrl = existing.baseUrl;
177
- mergedProviders[key] = {
178
- ...newEntry,
179
- ...preserved
180
- };
181
- }
182
- return mergedProviders;
183
- }
184
- async function resolveProvidersForMode(params) {
185
- if (params.mode !== "merge") return params.providers;
186
- const existing = await readJson(params.targetPath);
187
- if (!isRecord(existing) || !isRecord(existing.providers)) return params.providers;
188
- const existingProviders = existing.providers;
189
- return mergeWithExistingProviderSecrets({
190
- nextProviders: params.providers,
191
- existingProviders
192
- });
193
- }
194
- async function readRawFile(pathname) {
195
- try {
196
- return await fs.readFile(pathname, "utf8");
197
- } catch {
198
- return "";
199
- }
200
- }
201
- async function ensureSquidClawModelsJson(config, agentDirOverride) {
202
- const cfg = config ?? loadConfig();
203
- const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveSquidClawAgentDir();
204
- applyConfigEnvVars(cfg);
205
- const providers = await resolveProvidersForModelsJson({
206
- cfg,
207
- agentDir
208
- });
209
- if (Object.keys(providers).length === 0) return {
210
- agentDir,
211
- wrote: false
212
- };
213
- const mode = cfg.models?.mode ?? DEFAULT_MODE;
214
- const targetPath = path.join(agentDir, "models.json");
215
- const normalizedProviders = normalizeProviders({
216
- providers: await resolveProvidersForMode({
217
- mode,
218
- targetPath,
219
- providers
220
- }),
221
- agentDir
222
- });
223
- const next = `${JSON.stringify({ providers: normalizedProviders }, null, 2)}\n`;
224
- if (await readRawFile(targetPath) === next) return {
225
- agentDir,
226
- wrote: false
227
- };
228
- await fs.mkdir(agentDir, {
229
- recursive: true,
230
- mode: 448
231
- });
232
- await fs.writeFile(targetPath, next, { mode: 384 });
233
- return {
234
- agentDir,
235
- wrote: true
236
- };
237
- }
238
-
239
- //#endregion
240
- //#region src/shared/chat-content.ts
241
- function extractTextFromChatContent(content, opts) {
242
- const normalize = opts?.normalizeText ?? ((text) => text.replace(/\s+/g, " ").trim());
243
- const joinWith = opts?.joinWith ?? " ";
244
- if (typeof content === "string") {
245
- const normalized = normalize(opts?.sanitizeText ? opts.sanitizeText(content) : content);
246
- return normalized ? normalized : null;
247
- }
248
- if (!Array.isArray(content)) return null;
249
- const chunks = [];
250
- for (const block of content) {
251
- if (!block || typeof block !== "object") continue;
252
- if (block.type !== "text") continue;
253
- const text = block.text;
254
- if (typeof text !== "string") continue;
255
- const value = opts?.sanitizeText ? opts.sanitizeText(text) : text;
256
- if (value.trim()) chunks.push(value);
257
- }
258
- const joined = normalize(chunks.join(joinWith));
259
- return joined ? joined : null;
260
- }
261
-
262
- //#endregion
263
- //#region src/shared/text/code-regions.ts
264
- function findCodeRegions(text) {
265
- const regions = [];
266
- for (const match of text.matchAll(/(^|\n)(```|~~~)[^\n]*\n[\s\S]*?(?:\n\2(?:\n|$)|$)/g)) {
267
- const start = (match.index ?? 0) + match[1].length;
268
- regions.push({
269
- start,
270
- end: start + match[0].length - match[1].length
271
- });
272
- }
273
- for (const match of text.matchAll(/`+[^`]+`+/g)) {
274
- const start = match.index ?? 0;
275
- const end = start + match[0].length;
276
- if (!regions.some((r) => start >= r.start && end <= r.end)) regions.push({
277
- start,
278
- end
279
- });
280
- }
281
- regions.sort((a, b) => a.start - b.start);
282
- return regions;
283
- }
284
- function isInsideCode(pos, regions) {
285
- return regions.some((r) => pos >= r.start && pos < r.end);
286
- }
287
-
288
- //#endregion
289
- //#region src/shared/text/reasoning-tags.ts
290
- const QUICK_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking|final)\b/i;
291
- const FINAL_TAG_RE = /<\s*\/?\s*final\b[^<>]*>/gi;
292
- const THINKING_TAG_RE = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\b[^<>]*>/gi;
293
- function applyTrim(value, mode) {
294
- if (mode === "none") return value;
295
- if (mode === "start") return value.trimStart();
296
- return value.trim();
297
- }
298
- function stripReasoningTagsFromText(text, options) {
299
- if (!text) return text;
300
- if (!QUICK_TAG_RE.test(text)) return text;
301
- const mode = options?.mode ?? "strict";
302
- const trimMode = options?.trim ?? "both";
303
- let cleaned = text;
304
- if (FINAL_TAG_RE.test(cleaned)) {
305
- FINAL_TAG_RE.lastIndex = 0;
306
- const finalMatches = [];
307
- const preCodeRegions = findCodeRegions(cleaned);
308
- for (const match of cleaned.matchAll(FINAL_TAG_RE)) {
309
- const start = match.index ?? 0;
310
- finalMatches.push({
311
- start,
312
- length: match[0].length,
313
- inCode: isInsideCode(start, preCodeRegions)
314
- });
315
- }
316
- for (let i = finalMatches.length - 1; i >= 0; i--) {
317
- const m = finalMatches[i];
318
- if (!m.inCode) cleaned = cleaned.slice(0, m.start) + cleaned.slice(m.start + m.length);
319
- }
320
- } else FINAL_TAG_RE.lastIndex = 0;
321
- const codeRegions = findCodeRegions(cleaned);
322
- THINKING_TAG_RE.lastIndex = 0;
323
- let result = "";
324
- let lastIndex = 0;
325
- let inThinking = false;
326
- for (const match of cleaned.matchAll(THINKING_TAG_RE)) {
327
- const idx = match.index ?? 0;
328
- const isClose = match[1] === "/";
329
- if (isInsideCode(idx, codeRegions)) continue;
330
- if (!inThinking) {
331
- result += cleaned.slice(lastIndex, idx);
332
- if (!isClose) inThinking = true;
333
- } else if (isClose) inThinking = false;
334
- lastIndex = idx + match[0].length;
335
- }
336
- if (!inThinking || mode === "preserve") result += cleaned.slice(lastIndex);
337
- return applyTrim(result, trimMode);
338
- }
339
-
340
- //#endregion
341
- //#region apps/shared/SquidClawKit/Sources/SquidClawKit/Resources/tool-display.json
342
- var tool_display_default = {
343
- version: 1,
344
- fallback: {
345
- "emoji": "🧩",
346
- "detailKeys": [
347
- "command",
348
- "path",
349
- "url",
350
- "targetUrl",
351
- "targetId",
352
- "ref",
353
- "element",
354
- "node",
355
- "nodeId",
356
- "id",
357
- "requestId",
358
- "to",
359
- "channelId",
360
- "guildId",
361
- "userId",
362
- "name",
363
- "query",
364
- "pattern",
365
- "messageId"
366
- ]
367
- },
368
- tools: {
369
- "bash": {
370
- "emoji": "🛠️",
371
- "title": "Bash",
372
- "detailKeys": ["command"]
373
- },
374
- "process": {
375
- "emoji": "🧰",
376
- "title": "Process",
377
- "detailKeys": ["sessionId"]
378
- },
379
- "read": {
380
- "emoji": "📖",
381
- "title": "Read",
382
- "detailKeys": ["path"]
383
- },
384
- "write": {
385
- "emoji": "✍️",
386
- "title": "Write",
387
- "detailKeys": ["path"]
388
- },
389
- "edit": {
390
- "emoji": "📝",
391
- "title": "Edit",
392
- "detailKeys": ["path"]
393
- },
394
- "attach": {
395
- "emoji": "📎",
396
- "title": "Attach",
397
- "detailKeys": [
398
- "path",
399
- "url",
400
- "fileName"
401
- ]
402
- },
403
- "browser": {
404
- "emoji": "🌐",
405
- "title": "Browser",
406
- "actions": {
407
- "status": { "label": "status" },
408
- "start": { "label": "start" },
409
- "stop": { "label": "stop" },
410
- "tabs": { "label": "tabs" },
411
- "open": {
412
- "label": "open",
413
- "detailKeys": ["targetUrl"]
414
- },
415
- "focus": {
416
- "label": "focus",
417
- "detailKeys": ["targetId"]
418
- },
419
- "close": {
420
- "label": "close",
421
- "detailKeys": ["targetId"]
422
- },
423
- "snapshot": {
424
- "label": "snapshot",
425
- "detailKeys": [
426
- "targetUrl",
427
- "targetId",
428
- "ref",
429
- "element",
430
- "format"
431
- ]
432
- },
433
- "screenshot": {
434
- "label": "screenshot",
435
- "detailKeys": [
436
- "targetUrl",
437
- "targetId",
438
- "ref",
439
- "element"
440
- ]
441
- },
442
- "navigate": {
443
- "label": "navigate",
444
- "detailKeys": ["targetUrl", "targetId"]
445
- },
446
- "console": {
447
- "label": "console",
448
- "detailKeys": ["level", "targetId"]
449
- },
450
- "pdf": {
451
- "label": "pdf",
452
- "detailKeys": ["targetId"]
453
- },
454
- "upload": {
455
- "label": "upload",
456
- "detailKeys": [
457
- "paths",
458
- "ref",
459
- "inputRef",
460
- "element",
461
- "targetId"
462
- ]
463
- },
464
- "dialog": {
465
- "label": "dialog",
466
- "detailKeys": [
467
- "accept",
468
- "promptText",
469
- "targetId"
470
- ]
471
- },
472
- "act": {
473
- "label": "act",
474
- "detailKeys": [
475
- "request.kind",
476
- "request.ref",
477
- "request.selector",
478
- "request.text",
479
- "request.value"
480
- ]
481
- }
482
- }
483
- },
484
- "canvas": {
485
- "emoji": "🖼️",
486
- "title": "Canvas",
487
- "actions": {
488
- "present": {
489
- "label": "present",
490
- "detailKeys": [
491
- "target",
492
- "node",
493
- "nodeId"
494
- ]
495
- },
496
- "hide": {
497
- "label": "hide",
498
- "detailKeys": ["node", "nodeId"]
499
- },
500
- "navigate": {
501
- "label": "navigate",
502
- "detailKeys": [
503
- "url",
504
- "node",
505
- "nodeId"
506
- ]
507
- },
508
- "eval": {
509
- "label": "eval",
510
- "detailKeys": [
511
- "javaScript",
512
- "node",
513
- "nodeId"
514
- ]
515
- },
516
- "snapshot": {
517
- "label": "snapshot",
518
- "detailKeys": [
519
- "format",
520
- "node",
521
- "nodeId"
522
- ]
523
- },
524
- "a2ui_push": {
525
- "label": "A2UI push",
526
- "detailKeys": [
527
- "jsonlPath",
528
- "node",
529
- "nodeId"
530
- ]
531
- },
532
- "a2ui_reset": {
533
- "label": "A2UI reset",
534
- "detailKeys": ["node", "nodeId"]
535
- }
536
- }
537
- },
538
- "nodes": {
539
- "emoji": "📱",
540
- "title": "Nodes",
541
- "actions": {
542
- "status": { "label": "status" },
543
- "describe": {
544
- "label": "describe",
545
- "detailKeys": ["node", "nodeId"]
546
- },
547
- "pending": { "label": "pending" },
548
- "approve": {
549
- "label": "approve",
550
- "detailKeys": ["requestId"]
551
- },
552
- "reject": {
553
- "label": "reject",
554
- "detailKeys": ["requestId"]
555
- },
556
- "notify": {
557
- "label": "notify",
558
- "detailKeys": [
559
- "node",
560
- "nodeId",
561
- "title",
562
- "body"
563
- ]
564
- },
565
- "camera_snap": {
566
- "label": "camera snap",
567
- "detailKeys": [
568
- "node",
569
- "nodeId",
570
- "facing",
571
- "deviceId"
572
- ]
573
- },
574
- "camera_list": {
575
- "label": "camera list",
576
- "detailKeys": ["node", "nodeId"]
577
- },
578
- "camera_clip": {
579
- "label": "camera clip",
580
- "detailKeys": [
581
- "node",
582
- "nodeId",
583
- "facing",
584
- "duration",
585
- "durationMs"
586
- ]
587
- },
588
- "screen_record": {
589
- "label": "screen record",
590
- "detailKeys": [
591
- "node",
592
- "nodeId",
593
- "duration",
594
- "durationMs",
595
- "fps",
596
- "screenIndex"
597
- ]
598
- }
599
- }
600
- },
601
- "cron": {
602
- "emoji": "⏰",
603
- "title": "Cron",
604
- "actions": {
605
- "status": { "label": "status" },
606
- "list": { "label": "list" },
607
- "add": {
608
- "label": "add",
609
- "detailKeys": [
610
- "job.name",
611
- "job.id",
612
- "job.schedule",
613
- "job.cron"
614
- ]
615
- },
616
- "update": {
617
- "label": "update",
618
- "detailKeys": ["id"]
619
- },
620
- "remove": {
621
- "label": "remove",
622
- "detailKeys": ["id"]
623
- },
624
- "run": {
625
- "label": "run",
626
- "detailKeys": ["id"]
627
- },
628
- "runs": {
629
- "label": "runs",
630
- "detailKeys": ["id"]
631
- },
632
- "wake": {
633
- "label": "wake",
634
- "detailKeys": ["text", "mode"]
635
- }
636
- }
637
- },
638
- "gateway": {
639
- "emoji": "🔌",
640
- "title": "Gateway",
641
- "actions": { "restart": {
642
- "label": "restart",
643
- "detailKeys": ["reason", "delayMs"]
644
- } }
645
- },
646
- "whatsapp_login": {
647
- "emoji": "🟢",
648
- "title": "WhatsApp Login",
649
- "actions": {
650
- "start": { "label": "start" },
651
- "wait": { "label": "wait" }
652
- }
653
- },
654
- "discord": {
655
- "emoji": "💬",
656
- "title": "Discord",
657
- "actions": {
658
- "react": {
659
- "label": "react",
660
- "detailKeys": [
661
- "channelId",
662
- "messageId",
663
- "emoji"
664
- ]
665
- },
666
- "reactions": {
667
- "label": "reactions",
668
- "detailKeys": ["channelId", "messageId"]
669
- },
670
- "sticker": {
671
- "label": "sticker",
672
- "detailKeys": ["to", "stickerIds"]
673
- },
674
- "poll": {
675
- "label": "poll",
676
- "detailKeys": ["question", "to"]
677
- },
678
- "permissions": {
679
- "label": "permissions",
680
- "detailKeys": ["channelId"]
681
- },
682
- "readMessages": {
683
- "label": "read messages",
684
- "detailKeys": ["channelId", "limit"]
685
- },
686
- "sendMessage": {
687
- "label": "send",
688
- "detailKeys": ["to", "content"]
689
- },
690
- "editMessage": {
691
- "label": "edit",
692
- "detailKeys": ["channelId", "messageId"]
693
- },
694
- "deleteMessage": {
695
- "label": "delete",
696
- "detailKeys": ["channelId", "messageId"]
697
- },
698
- "threadCreate": {
699
- "label": "thread create",
700
- "detailKeys": ["channelId", "name"]
701
- },
702
- "threadList": {
703
- "label": "thread list",
704
- "detailKeys": ["guildId", "channelId"]
705
- },
706
- "threadReply": {
707
- "label": "thread reply",
708
- "detailKeys": ["channelId", "content"]
709
- },
710
- "pinMessage": {
711
- "label": "pin",
712
- "detailKeys": ["channelId", "messageId"]
713
- },
714
- "unpinMessage": {
715
- "label": "unpin",
716
- "detailKeys": ["channelId", "messageId"]
717
- },
718
- "listPins": {
719
- "label": "list pins",
720
- "detailKeys": ["channelId"]
721
- },
722
- "searchMessages": {
723
- "label": "search",
724
- "detailKeys": ["guildId", "content"]
725
- },
726
- "memberInfo": {
727
- "label": "member",
728
- "detailKeys": ["guildId", "userId"]
729
- },
730
- "roleInfo": {
731
- "label": "roles",
732
- "detailKeys": ["guildId"]
733
- },
734
- "emojiList": {
735
- "label": "emoji list",
736
- "detailKeys": ["guildId"]
737
- },
738
- "roleAdd": {
739
- "label": "role add",
740
- "detailKeys": [
741
- "guildId",
742
- "userId",
743
- "roleId"
744
- ]
745
- },
746
- "roleRemove": {
747
- "label": "role remove",
748
- "detailKeys": [
749
- "guildId",
750
- "userId",
751
- "roleId"
752
- ]
753
- },
754
- "channelInfo": {
755
- "label": "channel",
756
- "detailKeys": ["channelId"]
757
- },
758
- "channelList": {
759
- "label": "channels",
760
- "detailKeys": ["guildId"]
761
- },
762
- "voiceStatus": {
763
- "label": "voice",
764
- "detailKeys": ["guildId", "userId"]
765
- },
766
- "eventList": {
767
- "label": "events",
768
- "detailKeys": ["guildId"]
769
- },
770
- "eventCreate": {
771
- "label": "event create",
772
- "detailKeys": ["guildId", "name"]
773
- },
774
- "timeout": {
775
- "label": "timeout",
776
- "detailKeys": ["guildId", "userId"]
777
- },
778
- "kick": {
779
- "label": "kick",
780
- "detailKeys": ["guildId", "userId"]
781
- },
782
- "ban": {
783
- "label": "ban",
784
- "detailKeys": ["guildId", "userId"]
785
- }
786
- }
787
- }
788
- }
789
- };
790
-
791
- //#endregion
792
- //#region src/agents/tool-display-common.ts
793
- function asRecord(args) {
794
- return args && typeof args === "object" ? args : void 0;
795
- }
796
- function normalizeToolName(name) {
797
- return (name ?? "tool").trim();
798
- }
799
- function defaultTitle(name) {
800
- const cleaned = name.replace(/_/g, " ").trim();
801
- if (!cleaned) return "Tool";
802
- return cleaned.split(/\s+/).map((part) => part.length <= 2 && part.toUpperCase() === part ? part : `${part.at(0)?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
803
- }
804
- function normalizeVerb(value) {
805
- const trimmed = value?.trim();
806
- if (!trimmed) return;
807
- return trimmed.replace(/_/g, " ");
808
- }
809
- function resolveActionArg(args) {
810
- if (!args || typeof args !== "object") return;
811
- const actionRaw = args.action;
812
- if (typeof actionRaw !== "string") return;
813
- return actionRaw.trim() || void 0;
814
- }
815
- function resolveToolVerbAndDetailForArgs(params) {
816
- return resolveToolVerbAndDetail({
817
- toolKey: params.toolKey,
818
- args: params.args,
819
- meta: params.meta,
820
- action: resolveActionArg(params.args),
821
- spec: params.spec,
822
- fallbackDetailKeys: params.fallbackDetailKeys,
823
- detailMode: params.detailMode,
824
- detailCoerce: params.detailCoerce,
825
- detailMaxEntries: params.detailMaxEntries,
826
- detailFormatKey: params.detailFormatKey
827
- });
828
- }
829
- function coerceDisplayValue(value, opts = {}) {
830
- const maxStringChars = opts.maxStringChars ?? 160;
831
- const maxArrayEntries = opts.maxArrayEntries ?? 3;
832
- if (value === null || value === void 0) return;
833
- if (typeof value === "string") {
834
- const trimmed = value.trim();
835
- if (!trimmed) return;
836
- const firstLine = trimmed.split(/\r?\n/)[0]?.trim() ?? "";
837
- if (!firstLine) return;
838
- if (firstLine.length > maxStringChars) return `${firstLine.slice(0, Math.max(0, maxStringChars - 3))}…`;
839
- return firstLine;
840
- }
841
- if (typeof value === "boolean") {
842
- if (!value && !opts.includeFalse) return;
843
- return value ? "true" : "false";
844
- }
845
- if (typeof value === "number") {
846
- if (!Number.isFinite(value)) return opts.includeNonFinite ? String(value) : void 0;
847
- if (value === 0 && !opts.includeZero) return;
848
- return String(value);
849
- }
850
- if (Array.isArray(value)) {
851
- const values = value.map((item) => coerceDisplayValue(item, opts)).filter((item) => Boolean(item));
852
- if (values.length === 0) return;
853
- const preview = values.slice(0, maxArrayEntries).join(", ");
854
- return values.length > maxArrayEntries ? `${preview}…` : preview;
855
- }
856
- }
857
- function lookupValueByPath(args, path) {
858
- if (!args || typeof args !== "object") return;
859
- let current = args;
860
- for (const segment of path.split(".")) {
861
- if (!segment) return;
862
- if (!current || typeof current !== "object") return;
863
- current = current[segment];
864
- }
865
- return current;
866
- }
867
- function formatDetailKey(raw, overrides = {}) {
868
- const last = raw.split(".").filter(Boolean).at(-1) ?? raw;
869
- const override = overrides[last];
870
- if (override) return override;
871
- return last.replace(/_/g, " ").replace(/-/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim().toLowerCase() || last.toLowerCase();
872
- }
873
- function resolvePathArg(args) {
874
- const record = asRecord(args);
875
- if (!record) return;
876
- for (const candidate of [
877
- record.path,
878
- record.file_path,
879
- record.filePath
880
- ]) {
881
- if (typeof candidate !== "string") continue;
882
- const trimmed = candidate.trim();
883
- if (trimmed) return trimmed;
884
- }
885
- }
886
- function resolveReadDetail(args) {
887
- const record = asRecord(args);
888
- if (!record) return;
889
- const path = resolvePathArg(record);
890
- if (!path) return;
891
- const offsetRaw = typeof record.offset === "number" && Number.isFinite(record.offset) ? Math.floor(record.offset) : void 0;
892
- const limitRaw = typeof record.limit === "number" && Number.isFinite(record.limit) ? Math.floor(record.limit) : void 0;
893
- const offset = offsetRaw !== void 0 ? Math.max(1, offsetRaw) : void 0;
894
- const limit = limitRaw !== void 0 ? Math.max(1, limitRaw) : void 0;
895
- if (offset !== void 0 && limit !== void 0) return `${limit === 1 ? "line" : "lines"} ${offset}-${offset + limit - 1} from ${path}`;
896
- if (offset !== void 0) return `from line ${offset} in ${path}`;
897
- if (limit !== void 0) return `first ${limit} ${limit === 1 ? "line" : "lines"} of ${path}`;
898
- return `from ${path}`;
899
- }
900
- function resolveWriteDetail(toolKey, args) {
901
- const record = asRecord(args);
902
- if (!record) return;
903
- const path = resolvePathArg(record) ?? (typeof record.url === "string" ? record.url.trim() : void 0);
904
- if (!path) return;
905
- if (toolKey === "attach") return `from ${path}`;
906
- const destinationPrefix = toolKey === "edit" ? "in" : "to";
907
- const content = typeof record.content === "string" ? record.content : typeof record.newText === "string" ? record.newText : typeof record.new_string === "string" ? record.new_string : void 0;
908
- if (content && content.length > 0) return `${destinationPrefix} ${path} (${content.length} chars)`;
909
- return `${destinationPrefix} ${path}`;
910
- }
911
- function resolveWebSearchDetail(args) {
912
- const record = asRecord(args);
913
- if (!record) return;
914
- const query = typeof record.query === "string" ? record.query.trim() : void 0;
915
- const count = typeof record.count === "number" && Number.isFinite(record.count) && record.count > 0 ? Math.floor(record.count) : void 0;
916
- if (!query) return;
917
- return count !== void 0 ? `for "${query}" (top ${count})` : `for "${query}"`;
918
- }
919
- function resolveWebFetchDetail(args) {
920
- const record = asRecord(args);
921
- if (!record) return;
922
- const url = typeof record.url === "string" ? record.url.trim() : void 0;
923
- if (!url) return;
924
- const mode = typeof record.extractMode === "string" ? record.extractMode.trim() : void 0;
925
- const maxChars = typeof record.maxChars === "number" && Number.isFinite(record.maxChars) && record.maxChars > 0 ? Math.floor(record.maxChars) : void 0;
926
- const suffix = [mode ? `mode ${mode}` : void 0, maxChars !== void 0 ? `max ${maxChars} chars` : void 0].filter((value) => Boolean(value)).join(", ");
927
- return suffix ? `from ${url} (${suffix})` : `from ${url}`;
928
- }
929
- function stripOuterQuotes(value) {
930
- if (!value) return value;
931
- const trimmed = value.trim();
932
- if (trimmed.length >= 2 && (trimmed.startsWith("\"") && trimmed.endsWith("\"") || trimmed.startsWith("'") && trimmed.endsWith("'"))) return trimmed.slice(1, -1).trim();
933
- return trimmed;
934
- }
935
- function splitShellWords(input, maxWords = 48) {
936
- if (!input) return [];
937
- const words = [];
938
- let current = "";
939
- let quote;
940
- let escaped = false;
941
- for (let i = 0; i < input.length; i += 1) {
942
- const char = input[i];
943
- if (escaped) {
944
- current += char;
945
- escaped = false;
946
- continue;
947
- }
948
- if (char === "\\") {
949
- escaped = true;
950
- continue;
951
- }
952
- if (quote) {
953
- if (char === quote) quote = void 0;
954
- else current += char;
955
- continue;
956
- }
957
- if (char === "\"" || char === "'") {
958
- quote = char;
959
- continue;
960
- }
961
- if (/\s/.test(char)) {
962
- if (!current) continue;
963
- words.push(current);
964
- if (words.length >= maxWords) return words;
965
- current = "";
966
- continue;
967
- }
968
- current += char;
969
- }
970
- if (current) words.push(current);
971
- return words;
972
- }
973
- function binaryName(token) {
974
- if (!token) return;
975
- const cleaned = stripOuterQuotes(token) ?? token;
976
- return (cleaned.split(/[/]/).at(-1) ?? cleaned).trim().toLowerCase();
977
- }
978
- function optionValue(words, names) {
979
- const lookup = new Set(names);
980
- for (let i = 0; i < words.length; i += 1) {
981
- const token = words[i];
982
- if (!token) continue;
983
- if (lookup.has(token)) {
984
- const value = words[i + 1];
985
- if (value && !value.startsWith("-")) return value;
986
- continue;
987
- }
988
- for (const name of names) if (name.startsWith("--") && token.startsWith(`${name}=`)) return token.slice(name.length + 1);
989
- }
990
- }
991
- function positionalArgs(words, from = 1, optionsWithValue = []) {
992
- const args = [];
993
- const takesValue = new Set(optionsWithValue);
994
- for (let i = from; i < words.length; i += 1) {
995
- const token = words[i];
996
- if (!token) continue;
997
- if (token === "--") {
998
- for (let j = i + 1; j < words.length; j += 1) {
999
- const candidate = words[j];
1000
- if (candidate) args.push(candidate);
1001
- }
1002
- break;
1003
- }
1004
- if (token.startsWith("--")) {
1005
- if (token.includes("=")) continue;
1006
- if (takesValue.has(token)) i += 1;
1007
- continue;
1008
- }
1009
- if (token.startsWith("-")) {
1010
- if (takesValue.has(token)) i += 1;
1011
- continue;
1012
- }
1013
- args.push(token);
1014
- }
1015
- return args;
1016
- }
1017
- function firstPositional(words, from = 1, optionsWithValue = []) {
1018
- return positionalArgs(words, from, optionsWithValue)[0];
1019
- }
1020
- function trimLeadingEnv(words) {
1021
- if (words.length === 0) return words;
1022
- let index = 0;
1023
- if (binaryName(words[0]) === "env") {
1024
- index = 1;
1025
- while (index < words.length) {
1026
- const token = words[index];
1027
- if (!token) break;
1028
- if (token.startsWith("-")) {
1029
- index += 1;
1030
- continue;
1031
- }
1032
- if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(token)) {
1033
- index += 1;
1034
- continue;
1035
- }
1036
- break;
1037
- }
1038
- return words.slice(index);
1039
- }
1040
- while (index < words.length && /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[index])) index += 1;
1041
- return words.slice(index);
1042
- }
1043
- function unwrapShellWrapper(command) {
1044
- const words = splitShellWords(command, 10);
1045
- if (words.length < 3) return command;
1046
- const bin = binaryName(words[0]);
1047
- if (!(bin === "bash" || bin === "sh" || bin === "zsh" || bin === "fish")) return command;
1048
- const flagIndex = words.findIndex((token, index) => index > 0 && (token === "-c" || token === "-lc" || token === "-ic"));
1049
- if (flagIndex === -1) return command;
1050
- const inner = words.slice(flagIndex + 1).join(" ").trim();
1051
- return inner ? stripOuterQuotes(inner) ?? command : command;
1052
- }
1053
- function scanTopLevelChars(command, visit) {
1054
- let quote;
1055
- let escaped = false;
1056
- for (let i = 0; i < command.length; i += 1) {
1057
- const char = command[i];
1058
- if (escaped) {
1059
- escaped = false;
1060
- continue;
1061
- }
1062
- if (char === "\\") {
1063
- escaped = true;
1064
- continue;
1065
- }
1066
- if (quote) {
1067
- if (char === quote) quote = void 0;
1068
- continue;
1069
- }
1070
- if (char === "\"" || char === "'") {
1071
- quote = char;
1072
- continue;
1073
- }
1074
- if (visit(char, i) === false) return;
1075
- }
1076
- }
1077
- function splitTopLevelStages(command) {
1078
- const parts = [];
1079
- let start = 0;
1080
- scanTopLevelChars(command, (char, index) => {
1081
- if (char === ";") {
1082
- parts.push(command.slice(start, index));
1083
- start = index + 1;
1084
- return true;
1085
- }
1086
- if ((char === "&" || char === "|") && command[index + 1] === char) {
1087
- parts.push(command.slice(start, index));
1088
- start = index + 2;
1089
- return true;
1090
- }
1091
- return true;
1092
- });
1093
- parts.push(command.slice(start));
1094
- return parts.map((part) => part.trim()).filter((part) => part.length > 0);
1095
- }
1096
- function splitTopLevelPipes(command) {
1097
- const parts = [];
1098
- let start = 0;
1099
- scanTopLevelChars(command, (char, index) => {
1100
- if (char === "|" && command[index - 1] !== "|" && command[index + 1] !== "|") {
1101
- parts.push(command.slice(start, index));
1102
- start = index + 1;
1103
- }
1104
- return true;
1105
- });
1106
- parts.push(command.slice(start));
1107
- return parts.map((part) => part.trim()).filter((part) => part.length > 0);
1108
- }
1109
- function parseChdirTarget(head) {
1110
- const words = splitShellWords(head, 3);
1111
- const bin = binaryName(words[0]);
1112
- if (bin === "cd" || bin === "pushd") return words[1] || void 0;
1113
- }
1114
- function isChdirCommand(head) {
1115
- const bin = binaryName(splitShellWords(head, 2)[0]);
1116
- return bin === "cd" || bin === "pushd" || bin === "popd";
1117
- }
1118
- function isPopdCommand(head) {
1119
- return binaryName(splitShellWords(head, 2)[0]) === "popd";
1120
- }
1121
- function stripShellPreamble(command) {
1122
- let rest = command.trim();
1123
- let chdirPath;
1124
- for (let i = 0; i < 4; i += 1) {
1125
- let first;
1126
- scanTopLevelChars(rest, (char, idx) => {
1127
- if (char === "&" && rest[idx + 1] === "&") {
1128
- first = {
1129
- index: idx,
1130
- length: 2
1131
- };
1132
- return false;
1133
- }
1134
- if (char === "|" && rest[idx + 1] === "|") {
1135
- first = {
1136
- index: idx,
1137
- length: 2,
1138
- isOr: true
1139
- };
1140
- return false;
1141
- }
1142
- if (char === ";" || char === "\n") {
1143
- first = {
1144
- index: idx,
1145
- length: 1
1146
- };
1147
- return false;
1148
- }
1149
- });
1150
- const head = (first ? rest.slice(0, first.index) : rest).trim();
1151
- const isChdir = (first ? !first.isOr : i > 0) && isChdirCommand(head);
1152
- if (!(head.startsWith("set ") || head.startsWith("export ") || head.startsWith("unset ") || isChdir)) break;
1153
- if (isChdir) if (isPopdCommand(head)) chdirPath = void 0;
1154
- else chdirPath = parseChdirTarget(head) ?? chdirPath;
1155
- rest = first ? rest.slice(first.index + first.length).trimStart() : "";
1156
- if (!rest) break;
1157
- }
1158
- return {
1159
- command: rest.trim(),
1160
- chdirPath
1161
- };
1162
- }
1163
- function summarizeKnownExec(words) {
1164
- if (words.length === 0) return "run command";
1165
- const bin = binaryName(words[0]) ?? "command";
1166
- if (bin === "git") {
1167
- const globalWithValue = new Set([
1168
- "-C",
1169
- "-c",
1170
- "--git-dir",
1171
- "--work-tree",
1172
- "--namespace",
1173
- "--config-env"
1174
- ]);
1175
- const gitCwd = optionValue(words, ["-C"]);
1176
- let sub;
1177
- for (let i = 1; i < words.length; i += 1) {
1178
- const token = words[i];
1179
- if (!token) continue;
1180
- if (token === "--") {
1181
- sub = firstPositional(words, i + 1);
1182
- break;
1183
- }
1184
- if (token.startsWith("--")) {
1185
- if (token.includes("=")) continue;
1186
- if (globalWithValue.has(token)) i += 1;
1187
- continue;
1188
- }
1189
- if (token.startsWith("-")) {
1190
- if (globalWithValue.has(token)) i += 1;
1191
- continue;
1192
- }
1193
- sub = token;
1194
- break;
1195
- }
1196
- const map = {
1197
- status: "check git status",
1198
- diff: "check git diff",
1199
- log: "view git history",
1200
- show: "show git object",
1201
- branch: "list git branches",
1202
- checkout: "switch git branch",
1203
- switch: "switch git branch",
1204
- commit: "create git commit",
1205
- pull: "pull git changes",
1206
- push: "push git changes",
1207
- fetch: "fetch git changes",
1208
- merge: "merge git changes",
1209
- rebase: "rebase git branch",
1210
- add: "stage git changes",
1211
- restore: "restore git files",
1212
- reset: "reset git state",
1213
- stash: "stash git changes"
1214
- };
1215
- if (sub && map[sub]) return map[sub];
1216
- if (!sub || sub.startsWith("/") || sub.startsWith("~") || sub.includes("/")) return gitCwd ? `run git command in ${gitCwd}` : "run git command";
1217
- return `run git ${sub}`;
1218
- }
1219
- if (bin === "grep" || bin === "rg" || bin === "ripgrep") {
1220
- const positional = positionalArgs(words, 1, [
1221
- "-e",
1222
- "--regexp",
1223
- "-f",
1224
- "--file",
1225
- "-m",
1226
- "--max-count",
1227
- "-A",
1228
- "--after-context",
1229
- "-B",
1230
- "--before-context",
1231
- "-C",
1232
- "--context"
1233
- ]);
1234
- const pattern = optionValue(words, ["-e", "--regexp"]) ?? positional[0];
1235
- const target = positional.length > 1 ? positional.at(-1) : void 0;
1236
- if (pattern) return target ? `search "${pattern}" in ${target}` : `search "${pattern}"`;
1237
- return "search text";
1238
- }
1239
- if (bin === "find") {
1240
- const path = words[1] && !words[1].startsWith("-") ? words[1] : ".";
1241
- const name = optionValue(words, ["-name", "-iname"]);
1242
- return name ? `find files named "${name}" in ${path}` : `find files in ${path}`;
1243
- }
1244
- if (bin === "ls") {
1245
- const target = firstPositional(words, 1);
1246
- return target ? `list files in ${target}` : "list files";
1247
- }
1248
- if (bin === "head" || bin === "tail") {
1249
- const lines = optionValue(words, ["-n", "--lines"]) ?? words.slice(1).find((token) => /^-\d+$/.test(token))?.slice(1);
1250
- const positional = positionalArgs(words, 1, ["-n", "--lines"]);
1251
- let target = positional.at(-1);
1252
- if (target && /^\d+$/.test(target) && positional.length === 1) target = void 0;
1253
- const side = bin === "head" ? "first" : "last";
1254
- const unit = lines === "1" ? "line" : "lines";
1255
- if (lines && target) return `show ${side} ${lines} ${unit} of ${target}`;
1256
- if (lines) return `show ${side} ${lines} ${unit}`;
1257
- if (target) return `show ${target}`;
1258
- return `show ${bin} output`;
1259
- }
1260
- if (bin === "cat") {
1261
- const target = firstPositional(words, 1);
1262
- return target ? `show ${target}` : "show output";
1263
- }
1264
- if (bin === "sed") {
1265
- const expression = optionValue(words, ["-e", "--expression"]);
1266
- const positional = positionalArgs(words, 1, [
1267
- "-e",
1268
- "--expression",
1269
- "-f",
1270
- "--file"
1271
- ]);
1272
- const script = expression ?? positional[0];
1273
- const target = expression ? positional[0] : positional[1];
1274
- if (script) {
1275
- const compact = (stripOuterQuotes(script) ?? script).replace(/\s+/g, "");
1276
- const range = compact.match(/^([0-9]+),([0-9]+)p$/);
1277
- if (range) return target ? `print lines ${range[1]}-${range[2]} from ${target}` : `print lines ${range[1]}-${range[2]}`;
1278
- const single = compact.match(/^([0-9]+)p$/);
1279
- if (single) return target ? `print line ${single[1]} from ${target}` : `print line ${single[1]}`;
1280
- }
1281
- return target ? `run sed on ${target}` : "run sed transform";
1282
- }
1283
- if (bin === "printf" || bin === "echo") return "print text";
1284
- if (bin === "cp" || bin === "mv") {
1285
- const positional = positionalArgs(words, 1, [
1286
- "-t",
1287
- "--target-directory",
1288
- "-S",
1289
- "--suffix"
1290
- ]);
1291
- const src = positional[0];
1292
- const dst = positional[1];
1293
- const action = bin === "cp" ? "copy" : "move";
1294
- if (src && dst) return `${action} ${src} to ${dst}`;
1295
- if (src) return `${action} ${src}`;
1296
- return `${action} files`;
1297
- }
1298
- if (bin === "rm") {
1299
- const target = firstPositional(words, 1);
1300
- return target ? `remove ${target}` : "remove files";
1301
- }
1302
- if (bin === "mkdir") {
1303
- const target = firstPositional(words, 1);
1304
- return target ? `create folder ${target}` : "create folder";
1305
- }
1306
- if (bin === "touch") {
1307
- const target = firstPositional(words, 1);
1308
- return target ? `create file ${target}` : "create file";
1309
- }
1310
- if (bin === "curl" || bin === "wget") {
1311
- const url = words.find((token) => /^https?:\/\//i.test(token));
1312
- return url ? `fetch ${url}` : "fetch url";
1313
- }
1314
- if (bin === "npm" || bin === "pnpm" || bin === "yarn" || bin === "bun") {
1315
- const positional = positionalArgs(words, 1, [
1316
- "--prefix",
1317
- "-C",
1318
- "--cwd",
1319
- "--config"
1320
- ]);
1321
- const sub = positional[0] ?? "command";
1322
- return {
1323
- install: "install dependencies",
1324
- test: "run tests",
1325
- build: "run build",
1326
- start: "start app",
1327
- lint: "run lint",
1328
- run: positional[1] ? `run ${positional[1]}` : "run script"
1329
- }[sub] ?? `run ${bin} ${sub}`;
1330
- }
1331
- if (bin === "node" || bin === "python" || bin === "python3" || bin === "ruby" || bin === "php") {
1332
- if (words.slice(1).find((token) => token.startsWith("<<"))) return `run ${bin} inline script (heredoc)`;
1333
- if ((bin === "node" ? optionValue(words, ["-e", "--eval"]) : bin === "python" || bin === "python3" ? optionValue(words, ["-c"]) : void 0) !== void 0) return `run ${bin} inline script`;
1334
- const script = firstPositional(words, 1, bin === "node" ? [
1335
- "-e",
1336
- "--eval",
1337
- "-m"
1338
- ] : [
1339
- "-c",
1340
- "-e",
1341
- "--eval",
1342
- "-m"
1343
- ]);
1344
- if (!script) return `run ${bin}`;
1345
- if (bin === "node") return `${words.includes("--check") || words.includes("-c") ? "check js syntax for" : "run node script"} ${script}`;
1346
- return `run ${bin} ${script}`;
1347
- }
1348
- if (bin === "squidclaw") {
1349
- const sub = firstPositional(words, 1);
1350
- return sub ? `run squidclaw ${sub}` : "run squidclaw";
1351
- }
1352
- const arg = firstPositional(words, 1);
1353
- if (!arg || arg.length > 48) return `run ${bin}`;
1354
- return /^[A-Za-z0-9._/-]+$/.test(arg) ? `run ${bin} ${arg}` : `run ${bin}`;
1355
- }
1356
- function summarizePipeline(stage) {
1357
- const pipeline = splitTopLevelPipes(stage);
1358
- if (pipeline.length > 1) return `${summarizeKnownExec(trimLeadingEnv(splitShellWords(pipeline[0])))} -> ${summarizeKnownExec(trimLeadingEnv(splitShellWords(pipeline[pipeline.length - 1])))}${pipeline.length > 2 ? ` (+${pipeline.length - 2} steps)` : ""}`;
1359
- return summarizeKnownExec(trimLeadingEnv(splitShellWords(stage)));
1360
- }
1361
- function summarizeExecCommand(command) {
1362
- const { command: cleaned, chdirPath } = stripShellPreamble(command);
1363
- if (!cleaned) return chdirPath ? {
1364
- text: "",
1365
- chdirPath
1366
- } : void 0;
1367
- const stages = splitTopLevelStages(cleaned);
1368
- if (stages.length === 0) return;
1369
- const summaries = stages.map((stage) => summarizePipeline(stage));
1370
- return {
1371
- text: summaries.length === 1 ? summaries[0] : summaries.join(" → "),
1372
- chdirPath,
1373
- allGeneric: summaries.every((s) => isGenericSummary(s))
1374
- };
1375
- }
1376
- /** Known summarizer prefixes that indicate a recognized command with useful context. */
1377
- const KNOWN_SUMMARY_PREFIXES = [
1378
- "check git",
1379
- "view git",
1380
- "show git",
1381
- "list git",
1382
- "switch git",
1383
- "create git",
1384
- "pull git",
1385
- "push git",
1386
- "fetch git",
1387
- "merge git",
1388
- "rebase git",
1389
- "stage git",
1390
- "restore git",
1391
- "reset git",
1392
- "stash git",
1393
- "search ",
1394
- "find files",
1395
- "list files",
1396
- "show first",
1397
- "show last",
1398
- "print line",
1399
- "print text",
1400
- "copy ",
1401
- "move ",
1402
- "remove ",
1403
- "create folder",
1404
- "create file",
1405
- "fetch http",
1406
- "install dependencies",
1407
- "run tests",
1408
- "run build",
1409
- "start app",
1410
- "run lint",
1411
- "run squidclaw",
1412
- "run node script",
1413
- "run node ",
1414
- "run python",
1415
- "run ruby",
1416
- "run php",
1417
- "run sed",
1418
- "run git ",
1419
- "run npm ",
1420
- "run pnpm ",
1421
- "run yarn ",
1422
- "run bun ",
1423
- "check js syntax"
1424
- ];
1425
- /** True when the summary is generic and the raw command would be more informative. */
1426
- function isGenericSummary(summary) {
1427
- if (summary === "run command") return true;
1428
- if (summary.startsWith("run ")) return !KNOWN_SUMMARY_PREFIXES.some((prefix) => summary.startsWith(prefix));
1429
- return false;
1430
- }
1431
- /** Compact the raw command for display: collapse whitespace, trim long strings. */
1432
- function compactRawCommand(raw, maxLength = 120) {
1433
- const oneLine = raw.replace(/\s*\n\s*/g, " ").replace(/\s{2,}/g, " ").trim();
1434
- if (oneLine.length <= maxLength) return oneLine;
1435
- return `${oneLine.slice(0, Math.max(0, maxLength - 1))}…`;
1436
- }
1437
- function resolveExecDetail(args) {
1438
- const record = asRecord(args);
1439
- if (!record) return;
1440
- const raw = typeof record.command === "string" ? record.command.trim() : void 0;
1441
- if (!raw) return;
1442
- const unwrapped = unwrapShellWrapper(raw);
1443
- const result = summarizeExecCommand(unwrapped) ?? summarizeExecCommand(raw);
1444
- const summary = result?.text || "run command";
1445
- const cwd = (typeof record.workdir === "string" ? record.workdir : typeof record.cwd === "string" ? record.cwd : void 0)?.trim() || result?.chdirPath || void 0;
1446
- const compact = compactRawCommand(unwrapped);
1447
- if (result?.allGeneric !== false && isGenericSummary(summary)) return cwd ? `${compact} (in ${cwd})` : compact;
1448
- const displaySummary = cwd ? `${summary} (in ${cwd})` : summary;
1449
- if (compact && compact !== displaySummary && compact !== summary) return `${displaySummary}\n\n\`${compact}\``;
1450
- return displaySummary;
1451
- }
1452
- function resolveActionSpec(spec, action) {
1453
- if (!spec || !action) return;
1454
- return spec.actions?.[action] ?? void 0;
1455
- }
1456
- function resolveDetailFromKeys(args, keys, opts) {
1457
- if (opts.mode === "first") {
1458
- for (const key of keys) {
1459
- const display = coerceDisplayValue(lookupValueByPath(args, key), opts.coerce);
1460
- if (display) return display;
1461
- }
1462
- return;
1463
- }
1464
- const entries = [];
1465
- for (const key of keys) {
1466
- const display = coerceDisplayValue(lookupValueByPath(args, key), opts.coerce);
1467
- if (!display) continue;
1468
- entries.push({
1469
- label: opts.formatKey ? opts.formatKey(key) : key,
1470
- value: display
1471
- });
1472
- }
1473
- if (entries.length === 0) return;
1474
- if (entries.length === 1) return entries[0].value;
1475
- const seen = /* @__PURE__ */ new Set();
1476
- const unique = [];
1477
- for (const entry of entries) {
1478
- const token = `${entry.label}:${entry.value}`;
1479
- if (seen.has(token)) continue;
1480
- seen.add(token);
1481
- unique.push(entry);
1482
- }
1483
- if (unique.length === 0) return;
1484
- return unique.slice(0, opts.maxEntries ?? 8).map((entry) => `${entry.label} ${entry.value}`).join(" · ");
1485
- }
1486
- function resolveToolVerbAndDetail(params) {
1487
- const actionSpec = resolveActionSpec(params.spec, params.action);
1488
- const fallbackVerb = params.toolKey === "web_search" ? "search" : params.toolKey === "web_fetch" ? "fetch" : params.toolKey.replace(/_/g, " ").replace(/\./g, " ");
1489
- const verb = normalizeVerb(actionSpec?.label ?? params.action ?? fallbackVerb);
1490
- let detail;
1491
- if (params.toolKey === "exec") detail = resolveExecDetail(params.args);
1492
- if (!detail && params.toolKey === "read") detail = resolveReadDetail(params.args);
1493
- if (!detail && (params.toolKey === "write" || params.toolKey === "edit" || params.toolKey === "attach")) detail = resolveWriteDetail(params.toolKey, params.args);
1494
- if (!detail && params.toolKey === "web_search") detail = resolveWebSearchDetail(params.args);
1495
- if (!detail && params.toolKey === "web_fetch") detail = resolveWebFetchDetail(params.args);
1496
- const detailKeys = actionSpec?.detailKeys ?? params.spec?.detailKeys ?? params.fallbackDetailKeys ?? [];
1497
- if (!detail && detailKeys.length > 0) detail = resolveDetailFromKeys(params.args, detailKeys, {
1498
- mode: params.detailMode,
1499
- coerce: params.detailCoerce,
1500
- maxEntries: params.detailMaxEntries,
1501
- formatKey: params.detailFormatKey
1502
- });
1503
- if (!detail && params.meta) detail = params.meta;
1504
- return {
1505
- verb,
1506
- detail
1507
- };
1508
- }
1509
- function formatToolDetailText(detail, opts = {}) {
1510
- if (!detail) return;
1511
- const normalized = detail.includes(" · ") ? detail.split(" · ").map((part) => part.trim()).filter((part) => part.length > 0).join(", ") : detail;
1512
- if (!normalized) return;
1513
- return opts.prefixWithWith ? `with ${normalized}` : normalized;
1514
- }
1515
-
1516
- //#endregion
1517
- //#region src/agents/tool-display-overrides.json
1518
- var tool_display_overrides_default = {
1519
- version: 1,
1520
- tools: {
1521
- "exec": {
1522
- "emoji": "🛠️",
1523
- "title": "Exec",
1524
- "detailKeys": ["command"]
1525
- },
1526
- "tool_call": {
1527
- "emoji": "🧰",
1528
- "title": "Tool Call",
1529
- "detailKeys": []
1530
- },
1531
- "tool_call_update": {
1532
- "emoji": "🧰",
1533
- "title": "Tool Call",
1534
- "detailKeys": []
1535
- },
1536
- "session_status": {
1537
- "emoji": "📊",
1538
- "title": "Session Status",
1539
- "detailKeys": ["sessionKey", "model"]
1540
- },
1541
- "sessions_list": {
1542
- "emoji": "🗂️",
1543
- "title": "Sessions",
1544
- "detailKeys": [
1545
- "kinds",
1546
- "limit",
1547
- "activeMinutes",
1548
- "messageLimit"
1549
- ]
1550
- },
1551
- "sessions_send": {
1552
- "emoji": "📨",
1553
- "title": "Session Send",
1554
- "detailKeys": [
1555
- "label",
1556
- "sessionKey",
1557
- "agentId",
1558
- "timeoutSeconds"
1559
- ]
1560
- },
1561
- "sessions_history": {
1562
- "emoji": "🧾",
1563
- "title": "Session History",
1564
- "detailKeys": [
1565
- "sessionKey",
1566
- "limit",
1567
- "includeTools"
1568
- ]
1569
- },
1570
- "sessions_spawn": {
1571
- "emoji": "🧑‍🔧",
1572
- "title": "Sub-agent",
1573
- "detailKeys": [
1574
- "label",
1575
- "task",
1576
- "agentId",
1577
- "model",
1578
- "thinking",
1579
- "runTimeoutSeconds",
1580
- "cleanup"
1581
- ]
1582
- },
1583
- "subagents": {
1584
- "emoji": "🤖",
1585
- "title": "Subagents",
1586
- "actions": {
1587
- "list": {
1588
- "label": "list",
1589
- "detailKeys": ["recentMinutes"]
1590
- },
1591
- "kill": {
1592
- "label": "kill",
1593
- "detailKeys": ["target"]
1594
- },
1595
- "steer": {
1596
- "label": "steer",
1597
- "detailKeys": ["target"]
1598
- }
1599
- }
1600
- },
1601
- "agents_list": {
1602
- "emoji": "🧭",
1603
- "title": "Agents",
1604
- "detailKeys": []
1605
- },
1606
- "memory_search": {
1607
- "emoji": "🧠",
1608
- "title": "Memory Search",
1609
- "detailKeys": ["query"]
1610
- },
1611
- "memory_get": {
1612
- "emoji": "📓",
1613
- "title": "Memory Get",
1614
- "detailKeys": [
1615
- "path",
1616
- "from",
1617
- "lines"
1618
- ]
1619
- },
1620
- "web_search": {
1621
- "emoji": "🔎",
1622
- "title": "Web Search",
1623
- "detailKeys": ["query", "count"]
1624
- },
1625
- "web_fetch": {
1626
- "emoji": "📄",
1627
- "title": "Web Fetch",
1628
- "detailKeys": [
1629
- "url",
1630
- "extractMode",
1631
- "maxChars"
1632
- ]
1633
- },
1634
- "message": {
1635
- "emoji": "✉️",
1636
- "title": "Message",
1637
- "actions": {
1638
- "send": {
1639
- "label": "send",
1640
- "detailKeys": [
1641
- "provider",
1642
- "to",
1643
- "media",
1644
- "replyTo",
1645
- "threadId"
1646
- ]
1647
- },
1648
- "poll": {
1649
- "label": "poll",
1650
- "detailKeys": [
1651
- "provider",
1652
- "to",
1653
- "pollQuestion"
1654
- ]
1655
- },
1656
- "react": {
1657
- "label": "react",
1658
- "detailKeys": [
1659
- "provider",
1660
- "to",
1661
- "messageId",
1662
- "emoji",
1663
- "remove"
1664
- ]
1665
- },
1666
- "reactions": {
1667
- "label": "reactions",
1668
- "detailKeys": [
1669
- "provider",
1670
- "to",
1671
- "messageId",
1672
- "limit"
1673
- ]
1674
- },
1675
- "read": {
1676
- "label": "read",
1677
- "detailKeys": [
1678
- "provider",
1679
- "to",
1680
- "limit"
1681
- ]
1682
- },
1683
- "edit": {
1684
- "label": "edit",
1685
- "detailKeys": [
1686
- "provider",
1687
- "to",
1688
- "messageId"
1689
- ]
1690
- },
1691
- "delete": {
1692
- "label": "delete",
1693
- "detailKeys": [
1694
- "provider",
1695
- "to",
1696
- "messageId"
1697
- ]
1698
- },
1699
- "pin": {
1700
- "label": "pin",
1701
- "detailKeys": [
1702
- "provider",
1703
- "to",
1704
- "messageId"
1705
- ]
1706
- },
1707
- "unpin": {
1708
- "label": "unpin",
1709
- "detailKeys": [
1710
- "provider",
1711
- "to",
1712
- "messageId"
1713
- ]
1714
- },
1715
- "list-pins": {
1716
- "label": "list pins",
1717
- "detailKeys": ["provider", "to"]
1718
- },
1719
- "permissions": {
1720
- "label": "permissions",
1721
- "detailKeys": [
1722
- "provider",
1723
- "channelId",
1724
- "to"
1725
- ]
1726
- },
1727
- "thread-create": {
1728
- "label": "thread create",
1729
- "detailKeys": [
1730
- "provider",
1731
- "channelId",
1732
- "threadName"
1733
- ]
1734
- },
1735
- "thread-list": {
1736
- "label": "thread list",
1737
- "detailKeys": [
1738
- "provider",
1739
- "guildId",
1740
- "channelId"
1741
- ]
1742
- },
1743
- "thread-reply": {
1744
- "label": "thread reply",
1745
- "detailKeys": [
1746
- "provider",
1747
- "channelId",
1748
- "messageId"
1749
- ]
1750
- },
1751
- "search": {
1752
- "label": "search",
1753
- "detailKeys": [
1754
- "provider",
1755
- "guildId",
1756
- "query"
1757
- ]
1758
- },
1759
- "sticker": {
1760
- "label": "sticker",
1761
- "detailKeys": [
1762
- "provider",
1763
- "to",
1764
- "stickerId"
1765
- ]
1766
- },
1767
- "member-info": {
1768
- "label": "member",
1769
- "detailKeys": [
1770
- "provider",
1771
- "guildId",
1772
- "userId"
1773
- ]
1774
- },
1775
- "role-info": {
1776
- "label": "roles",
1777
- "detailKeys": ["provider", "guildId"]
1778
- },
1779
- "emoji-list": {
1780
- "label": "emoji list",
1781
- "detailKeys": ["provider", "guildId"]
1782
- },
1783
- "emoji-upload": {
1784
- "label": "emoji upload",
1785
- "detailKeys": [
1786
- "provider",
1787
- "guildId",
1788
- "emojiName"
1789
- ]
1790
- },
1791
- "sticker-upload": {
1792
- "label": "sticker upload",
1793
- "detailKeys": [
1794
- "provider",
1795
- "guildId",
1796
- "stickerName"
1797
- ]
1798
- },
1799
- "role-add": {
1800
- "label": "role add",
1801
- "detailKeys": [
1802
- "provider",
1803
- "guildId",
1804
- "userId",
1805
- "roleId"
1806
- ]
1807
- },
1808
- "role-remove": {
1809
- "label": "role remove",
1810
- "detailKeys": [
1811
- "provider",
1812
- "guildId",
1813
- "userId",
1814
- "roleId"
1815
- ]
1816
- },
1817
- "channel-info": {
1818
- "label": "channel",
1819
- "detailKeys": ["provider", "channelId"]
1820
- },
1821
- "channel-list": {
1822
- "label": "channels",
1823
- "detailKeys": ["provider", "guildId"]
1824
- },
1825
- "voice-status": {
1826
- "label": "voice",
1827
- "detailKeys": [
1828
- "provider",
1829
- "guildId",
1830
- "userId"
1831
- ]
1832
- },
1833
- "event-list": {
1834
- "label": "events",
1835
- "detailKeys": ["provider", "guildId"]
1836
- },
1837
- "event-create": {
1838
- "label": "event create",
1839
- "detailKeys": [
1840
- "provider",
1841
- "guildId",
1842
- "eventName"
1843
- ]
1844
- },
1845
- "timeout": {
1846
- "label": "timeout",
1847
- "detailKeys": [
1848
- "provider",
1849
- "guildId",
1850
- "userId"
1851
- ]
1852
- },
1853
- "kick": {
1854
- "label": "kick",
1855
- "detailKeys": [
1856
- "provider",
1857
- "guildId",
1858
- "userId"
1859
- ]
1860
- },
1861
- "ban": {
1862
- "label": "ban",
1863
- "detailKeys": [
1864
- "provider",
1865
- "guildId",
1866
- "userId"
1867
- ]
1868
- }
1869
- }
1870
- },
1871
- "apply_patch": {
1872
- "emoji": "🩹",
1873
- "title": "Apply Patch",
1874
- "detailKeys": []
1875
- }
1876
- }
1877
- };
1878
-
1879
- //#endregion
1880
- //#region src/agents/tool-display.ts
1881
- const SHARED_TOOL_DISPLAY_CONFIG = tool_display_default;
1882
- const TOOL_DISPLAY_OVERRIDES = tool_display_overrides_default;
1883
- const FALLBACK = TOOL_DISPLAY_OVERRIDES.fallback ?? SHARED_TOOL_DISPLAY_CONFIG.fallback ?? { emoji: "🧩" };
1884
- const TOOL_MAP = Object.assign({}, SHARED_TOOL_DISPLAY_CONFIG.tools, TOOL_DISPLAY_OVERRIDES.tools);
1885
- const DETAIL_LABEL_OVERRIDES = {
1886
- agentId: "agent",
1887
- sessionKey: "session",
1888
- targetId: "target",
1889
- targetUrl: "url",
1890
- nodeId: "node",
1891
- requestId: "request",
1892
- messageId: "message",
1893
- threadId: "thread",
1894
- channelId: "channel",
1895
- guildId: "guild",
1896
- userId: "user",
1897
- runTimeoutSeconds: "timeout",
1898
- timeoutSeconds: "timeout",
1899
- includeTools: "tools",
1900
- pollQuestion: "poll",
1901
- maxChars: "max chars"
1902
- };
1903
- const MAX_DETAIL_ENTRIES = 8;
1904
- function resolveToolDisplay(params) {
1905
- const name = normalizeToolName(params.name);
1906
- const key = name.toLowerCase();
1907
- const spec = TOOL_MAP[key];
1908
- const emoji = spec?.emoji ?? FALLBACK.emoji ?? "🧩";
1909
- const title = spec?.title ?? defaultTitle(name);
1910
- const label = spec?.label ?? title;
1911
- let { verb, detail } = resolveToolVerbAndDetailForArgs({
1912
- toolKey: key,
1913
- args: params.args,
1914
- meta: params.meta,
1915
- spec,
1916
- fallbackDetailKeys: FALLBACK.detailKeys,
1917
- detailMode: "summary",
1918
- detailMaxEntries: MAX_DETAIL_ENTRIES,
1919
- detailFormatKey: (raw) => formatDetailKey(raw, DETAIL_LABEL_OVERRIDES)
1920
- });
1921
- if (detail) detail = shortenHomeInString(detail);
1922
- return {
1923
- name,
1924
- emoji,
1925
- title,
1926
- label,
1927
- verb,
1928
- detail
1929
- };
1930
- }
1931
- function formatToolDetail(display) {
1932
- return formatToolDetailText(display.detail ? redactToolDetail(display.detail) : void 0);
1933
- }
1934
- function formatToolSummary(display) {
1935
- const detail = formatToolDetail(display);
1936
- return detail ? `${display.emoji} ${display.label}: ${detail}` : `${display.emoji} ${display.label}`;
1937
- }
1938
-
1939
- //#endregion
1940
- //#region src/agents/pi-embedded-utils.ts
1941
- function isAssistantMessage(msg) {
1942
- return msg?.role === "assistant";
1943
- }
1944
- /**
1945
- * Strip malformed Minimax tool invocations that leak into text content.
1946
- * Minimax sometimes embeds tool calls as XML in text blocks instead of
1947
- * proper structured tool calls. This removes:
1948
- * - <invoke name="...">...</invoke> blocks
1949
- * - </minimax:tool_call> closing tags
1950
- */
1951
- function stripMinimaxToolCallXml(text) {
1952
- if (!text) return text;
1953
- if (!/minimax:tool_call/i.test(text)) return text;
1954
- let cleaned = text.replace(/<invoke\b[^>]*>[\s\S]*?<\/invoke>/gi, "");
1955
- cleaned = cleaned.replace(/<\/?minimax:tool_call>/gi, "");
1956
- return cleaned;
1957
- }
1958
- /**
1959
- * Strip downgraded tool call text representations that leak into text content.
1960
- * When replaying history to Gemini, tool calls without `thought_signature` are
1961
- * downgraded to text blocks like `[Tool Call: name (ID: ...)]`. These should
1962
- * not be shown to users.
1963
- */
1964
- function stripDowngradedToolCallText(text) {
1965
- if (!text) return text;
1966
- if (!/\[Tool (?:Call|Result)/i.test(text) && !/\[Historical context/i.test(text)) return text;
1967
- const consumeJsonish = (input, start, options) => {
1968
- const { allowLeadingNewlines = false } = options ?? {};
1969
- let index = start;
1970
- while (index < input.length) {
1971
- const ch = input[index];
1972
- if (ch === " " || ch === " ") {
1973
- index += 1;
1974
- continue;
1975
- }
1976
- if (allowLeadingNewlines && (ch === "\n" || ch === "\r")) {
1977
- index += 1;
1978
- continue;
1979
- }
1980
- break;
1981
- }
1982
- if (index >= input.length) return null;
1983
- const startChar = input[index];
1984
- if (startChar === "{" || startChar === "[") {
1985
- let depth = 0;
1986
- let inString = false;
1987
- let escape = false;
1988
- for (let i = index; i < input.length; i += 1) {
1989
- const ch = input[i];
1990
- if (inString) {
1991
- if (escape) escape = false;
1992
- else if (ch === "\\") escape = true;
1993
- else if (ch === "\"") inString = false;
1994
- continue;
1995
- }
1996
- if (ch === "\"") {
1997
- inString = true;
1998
- continue;
1999
- }
2000
- if (ch === "{" || ch === "[") {
2001
- depth += 1;
2002
- continue;
2003
- }
2004
- if (ch === "}" || ch === "]") {
2005
- depth -= 1;
2006
- if (depth === 0) return i + 1;
2007
- }
2008
- }
2009
- return null;
2010
- }
2011
- if (startChar === "\"") {
2012
- let escape = false;
2013
- for (let i = index + 1; i < input.length; i += 1) {
2014
- const ch = input[i];
2015
- if (escape) {
2016
- escape = false;
2017
- continue;
2018
- }
2019
- if (ch === "\\") {
2020
- escape = true;
2021
- continue;
2022
- }
2023
- if (ch === "\"") return i + 1;
2024
- }
2025
- return null;
2026
- }
2027
- let end = index;
2028
- while (end < input.length && input[end] !== "\n" && input[end] !== "\r") end += 1;
2029
- return end;
2030
- };
2031
- const stripToolCalls = (input) => {
2032
- const markerRe = /\[Tool Call:[^\]]*\]/gi;
2033
- let result = "";
2034
- let cursor = 0;
2035
- for (const match of input.matchAll(markerRe)) {
2036
- const start = match.index ?? 0;
2037
- if (start < cursor) continue;
2038
- result += input.slice(cursor, start);
2039
- let index = start + match[0].length;
2040
- while (index < input.length && (input[index] === " " || input[index] === " ")) index += 1;
2041
- if (input[index] === "\r") {
2042
- index += 1;
2043
- if (input[index] === "\n") index += 1;
2044
- } else if (input[index] === "\n") index += 1;
2045
- while (index < input.length && (input[index] === " " || input[index] === " ")) index += 1;
2046
- if (input.slice(index, index + 9).toLowerCase() === "arguments") {
2047
- index += 9;
2048
- if (input[index] === ":") index += 1;
2049
- if (input[index] === " ") index += 1;
2050
- const end = consumeJsonish(input, index, { allowLeadingNewlines: true });
2051
- if (end !== null) index = end;
2052
- }
2053
- if ((input[index] === "\n" || input[index] === "\r") && (result.endsWith("\n") || result.endsWith("\r") || result.length === 0)) {
2054
- if (input[index] === "\r") index += 1;
2055
- if (input[index] === "\n") index += 1;
2056
- }
2057
- cursor = index;
2058
- }
2059
- result += input.slice(cursor);
2060
- return result;
2061
- };
2062
- let cleaned = stripToolCalls(text);
2063
- cleaned = cleaned.replace(/\[Tool Result for ID[^\]]*\]\n?[\s\S]*?(?=\n*\[Tool |\n*$)/gi, "");
2064
- cleaned = cleaned.replace(/\[Historical context:[^\]]*\]\n?/gi, "");
2065
- return cleaned.trim();
2066
- }
2067
- /**
2068
- * Strip thinking tags and their content from text.
2069
- * This is a safety net for cases where the model outputs <think> tags
2070
- * that slip through other filtering mechanisms.
2071
- */
2072
- function stripThinkingTagsFromText(text) {
2073
- return stripReasoningTagsFromText(text, {
2074
- mode: "strict",
2075
- trim: "both"
2076
- });
2077
- }
2078
- function extractAssistantText(msg) {
2079
- return sanitizeUserFacingText(extractTextFromChatContent(msg.content, {
2080
- sanitizeText: (text) => stripThinkingTagsFromText(stripDowngradedToolCallText(stripMinimaxToolCallXml(text))).trim(),
2081
- joinWith: "\n",
2082
- normalizeText: (text) => text.trim()
2083
- }) ?? "", { errorContext: msg.stopReason === "error" || Boolean(msg.errorMessage?.trim()) });
2084
- }
2085
- function extractAssistantThinking(msg) {
2086
- if (!Array.isArray(msg.content)) return "";
2087
- return msg.content.map((block) => {
2088
- if (!block || typeof block !== "object") return "";
2089
- const record = block;
2090
- if (record.type === "thinking" && typeof record.thinking === "string") return record.thinking.trim();
2091
- return "";
2092
- }).filter(Boolean).join("\n").trim();
2093
- }
2094
- function formatReasoningMessage(text) {
2095
- const trimmed = text.trim();
2096
- if (!trimmed) return "";
2097
- return `Reasoning:\n${trimmed.split("\n").map((line) => line ? `_${line}_` : line).join("\n")}`;
2098
- }
2099
- function splitThinkingTaggedText(text) {
2100
- const trimmedStart = text.trimStart();
2101
- if (!trimmedStart.startsWith("<")) return null;
2102
- const openRe = /<\s*(?:think(?:ing)?|thought|antthinking)\s*>/i;
2103
- const closeRe = /<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/i;
2104
- if (!openRe.test(trimmedStart)) return null;
2105
- if (!closeRe.test(text)) return null;
2106
- const scanRe = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
2107
- let inThinking = false;
2108
- let cursor = 0;
2109
- let thinkingStart = 0;
2110
- const blocks = [];
2111
- const pushText = (value) => {
2112
- if (!value) return;
2113
- blocks.push({
2114
- type: "text",
2115
- text: value
2116
- });
2117
- };
2118
- const pushThinking = (value) => {
2119
- const cleaned = value.trim();
2120
- if (!cleaned) return;
2121
- blocks.push({
2122
- type: "thinking",
2123
- thinking: cleaned
2124
- });
2125
- };
2126
- for (const match of text.matchAll(scanRe)) {
2127
- const index = match.index ?? 0;
2128
- const isClose = Boolean(match[1]?.includes("/"));
2129
- if (!inThinking && !isClose) {
2130
- pushText(text.slice(cursor, index));
2131
- thinkingStart = index + match[0].length;
2132
- inThinking = true;
2133
- continue;
2134
- }
2135
- if (inThinking && isClose) {
2136
- pushThinking(text.slice(thinkingStart, index));
2137
- cursor = index + match[0].length;
2138
- inThinking = false;
2139
- }
2140
- }
2141
- if (inThinking) return null;
2142
- pushText(text.slice(cursor));
2143
- if (!blocks.some((b) => b.type === "thinking")) return null;
2144
- return blocks;
2145
- }
2146
- function promoteThinkingTagsToBlocks(message) {
2147
- if (!Array.isArray(message.content)) return;
2148
- if (message.content.some((block) => block.type === "thinking")) return;
2149
- const next = [];
2150
- let changed = false;
2151
- for (const block of message.content) {
2152
- if (block.type !== "text") {
2153
- next.push(block);
2154
- continue;
2155
- }
2156
- const split = splitThinkingTaggedText(block.text);
2157
- if (!split) {
2158
- next.push(block);
2159
- continue;
2160
- }
2161
- changed = true;
2162
- for (const part of split) if (part.type === "thinking") next.push({
2163
- type: "thinking",
2164
- thinking: part.thinking
2165
- });
2166
- else if (part.type === "text") {
2167
- const cleaned = part.text.trimStart();
2168
- if (cleaned) next.push({
2169
- type: "text",
2170
- text: cleaned
2171
- });
2172
- }
2173
- }
2174
- if (!changed) return;
2175
- message.content = next;
2176
- }
2177
- function extractThinkingFromTaggedText(text) {
2178
- if (!text) return "";
2179
- const scanRe = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
2180
- let result = "";
2181
- let lastIndex = 0;
2182
- let inThinking = false;
2183
- for (const match of text.matchAll(scanRe)) {
2184
- const idx = match.index ?? 0;
2185
- if (inThinking) result += text.slice(lastIndex, idx);
2186
- inThinking = !(match[1] === "/");
2187
- lastIndex = idx + match[0].length;
2188
- }
2189
- return result.trim();
2190
- }
2191
- function extractThinkingFromTaggedStream(text) {
2192
- if (!text) return "";
2193
- const closed = extractThinkingFromTaggedText(text);
2194
- if (closed) return closed;
2195
- const openRe = /<\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
2196
- const closeRe = /<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
2197
- const openMatches = [...text.matchAll(openRe)];
2198
- if (openMatches.length === 0) return "";
2199
- const closeMatches = [...text.matchAll(closeRe)];
2200
- const lastOpen = openMatches[openMatches.length - 1];
2201
- const lastClose = closeMatches[closeMatches.length - 1];
2202
- if (lastClose && (lastClose.index ?? -1) > (lastOpen.index ?? -1)) return closed;
2203
- const start = (lastOpen.index ?? 0) + lastOpen[0].length;
2204
- return text.slice(start).trim();
2205
- }
2206
- function inferToolMetaFromArgs(toolName, args) {
2207
- return formatToolDetail(resolveToolDisplay({
2208
- name: toolName,
2209
- args
2210
- }));
2211
- }
2212
-
2213
- //#endregion
2214
- //#region src/agents/tools/image-tool.helpers.ts
2215
- function decodeDataUrl(dataUrl) {
2216
- const trimmed = dataUrl.trim();
2217
- const match = /^data:([^;,]+);base64,([a-z0-9+/=\r\n]+)$/i.exec(trimmed);
2218
- if (!match) throw new Error("Invalid data URL (expected base64 data: URL).");
2219
- const mimeType = (match[1] ?? "").trim().toLowerCase();
2220
- if (!mimeType.startsWith("image/")) throw new Error(`Unsupported data URL type: ${mimeType || "unknown"}`);
2221
- const b64 = (match[2] ?? "").trim();
2222
- const buffer = Buffer.from(b64, "base64");
2223
- if (buffer.length === 0) throw new Error("Invalid data URL: empty payload.");
2224
- return {
2225
- buffer,
2226
- mimeType,
2227
- kind: "image"
2228
- };
2229
- }
2230
- function coerceImageAssistantText(params) {
2231
- const stop = params.message.stopReason;
2232
- const errorMessage = params.message.errorMessage?.trim();
2233
- if (stop === "error" || stop === "aborted") throw new Error(errorMessage ? `Image model failed (${params.provider}/${params.model}): ${errorMessage}` : `Image model failed (${params.provider}/${params.model})`);
2234
- if (errorMessage) throw new Error(`Image model failed (${params.provider}/${params.model}): ${errorMessage}`);
2235
- const text = extractAssistantText(params.message);
2236
- if (text.trim()) return text.trim();
2237
- throw new Error(`Image model returned no text (${params.provider}/${params.model}).`);
2238
- }
2239
- function coerceImageModelConfig(cfg) {
2240
- const primary = resolveAgentModelPrimaryValue(cfg?.agents?.defaults?.imageModel);
2241
- const fallbacks = resolveAgentModelFallbackValues(cfg?.agents?.defaults?.imageModel);
2242
- return {
2243
- ...primary?.trim() ? { primary: primary.trim() } : {},
2244
- ...fallbacks.length > 0 ? { fallbacks } : {}
2245
- };
2246
- }
2247
- function resolveProviderVisionModelFromConfig(params) {
2248
- const models = (params.cfg?.models?.providers?.[params.provider])?.models ?? [];
2249
- const id = (((params.provider === "minimax" ? models.find((m) => (m?.id ?? "").trim() === "MiniMax-VL-01" && Array.isArray(m?.input) && m.input.includes("image")) : null) ?? models.find((m) => Boolean((m?.id ?? "").trim()) && m.input?.includes("image")))?.id ?? "").trim();
2250
- return id ? `${params.provider}/${id}` : null;
2251
- }
2252
-
2253
- //#endregion
2254
- //#region src/media-understanding/providers/image.ts
2255
- let piModelDiscoveryRuntimePromise = null;
2256
- function loadPiModelDiscoveryRuntime() {
2257
- piModelDiscoveryRuntimePromise ??= import("./pi-model-discovery-runtime-BHZ_Htob.js");
2258
- return piModelDiscoveryRuntimePromise;
2259
- }
2260
- async function describeImageWithModel(params) {
2261
- await ensureSquidClawModelsJson(params.cfg, params.agentDir);
2262
- const { discoverAuthStorage, discoverModels } = await loadPiModelDiscoveryRuntime();
2263
- const authStorage = discoverAuthStorage(params.agentDir);
2264
- const model = discoverModels(authStorage, params.agentDir).find(params.provider, params.model);
2265
- if (!model) throw new Error(`Unknown model: ${params.provider}/${params.model}`);
2266
- if (!model.input?.includes("image")) throw new Error(`Model does not support images: ${params.provider}/${params.model}`);
2267
- const apiKey = requireApiKey(await getApiKeyForModel({
2268
- model,
2269
- cfg: params.cfg,
2270
- agentDir: params.agentDir,
2271
- profileId: params.profile,
2272
- preferredProfile: params.preferredProfile
2273
- }), model.provider);
2274
- authStorage.setRuntimeApiKey(model.provider, apiKey);
2275
- const base64 = params.buffer.toString("base64");
2276
- if (model.provider === "minimax") return {
2277
- text: await minimaxUnderstandImage({
2278
- apiKey,
2279
- prompt: params.prompt ?? "Describe the image.",
2280
- imageDataUrl: `data:${params.mime ?? "image/jpeg"};base64,${base64}`,
2281
- modelBaseUrl: model.baseUrl
2282
- }),
2283
- model: model.id
2284
- };
2285
- return {
2286
- text: coerceImageAssistantText({
2287
- message: await complete(model, { messages: [{
2288
- role: "user",
2289
- content: [{
2290
- type: "text",
2291
- text: params.prompt ?? "Describe the image."
2292
- }, {
2293
- type: "image",
2294
- data: base64,
2295
- mimeType: params.mime ?? "image/jpeg"
2296
- }],
2297
- timestamp: Date.now()
2298
- }] }, {
2299
- apiKey,
2300
- maxTokens: params.maxTokens ?? 512
2301
- }),
2302
- provider: model.provider,
2303
- model: model.id
2304
- }),
2305
- model: model.id
2306
- };
2307
- }
2308
-
2309
- //#endregion
2310
- export { ensureSquidClawModelsJson as C, extractTextFromChatContent as S, formatToolSummary as _, resolveProviderVisionModelFromConfig as a, findCodeRegions as b, extractThinkingFromTaggedStream as c, inferToolMetaFromArgs as d, isAssistantMessage as f, stripThinkingTagsFromText as g, stripMinimaxToolCallXml as h, decodeDataUrl as i, extractThinkingFromTaggedText as l, stripDowngradedToolCallText as m, coerceImageAssistantText as n, extractAssistantText as o, promoteThinkingTagsToBlocks as p, coerceImageModelConfig as r, extractAssistantThinking as s, describeImageWithModel as t, formatReasoningMessage as u, resolveToolDisplay as v, minimaxUnderstandImage as w, isInsideCode as x, stripReasoningTagsFromText as y };