@qredence/fleet 0.6.1 → 0.6.2

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 (271) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/web/client/assets/agent-disclosure-CMrxF7L-.js +1 -0
  3. package/dist/web/client/assets/analytics-stub-C2vgmGm_.js +1 -0
  4. package/dist/web/client/assets/artifacts-panel-DmQghvw8.js +1 -0
  5. package/dist/web/client/assets/{bot-Bs7QWJ2q.js → bot-DbB9BKL0.js} +1 -1
  6. package/dist/web/client/assets/bundle-mjs-cJTHqqzI.js +1 -0
  7. package/dist/web/client/assets/button-Dl0ce3Y5.js +1 -0
  8. package/dist/web/client/assets/{card-DA3Vnqay.js → card-DCEnYd2G.js} +1 -1
  9. package/dist/web/client/assets/chat-C24kD2SP.js +52 -0
  10. package/dist/web/client/assets/chat-command-palette-BIwjhE6s.js +1 -0
  11. package/dist/web/client/assets/check-B3LlvM65.js +1 -0
  12. package/dist/web/client/assets/{chevron-down-BEVGmnSb.js → chevron-down-DUUprRP5.js} +1 -1
  13. package/dist/web/client/assets/chevron-right-NVqQIoiO.js +1 -0
  14. package/dist/web/client/assets/{chunk-YOKDWASO-BAf618wr.js → chunk-YOKDWASO-Bte3iwlH.js} +6 -6
  15. package/dist/web/client/assets/citations-BUvM92nt.js +1 -0
  16. package/dist/web/client/assets/collapsible-CUxOjhDJ.js +1 -0
  17. package/dist/web/client/assets/command-Dv96gATQ.js +1 -0
  18. package/dist/web/client/assets/createBaseUIEventDetails-B58Jldei.js +1 -0
  19. package/dist/web/client/assets/createLucideIcon-_dfI7Arx.js +1 -0
  20. package/dist/web/client/assets/dialog-BCb4rQh0.js +1 -0
  21. package/dist/web/client/assets/dist-52wg4XPY.js +1 -0
  22. package/dist/web/client/assets/dist-DbHxXSgQ.js +41 -0
  23. package/dist/web/client/assets/ease-CMumuPlX.js +1 -0
  24. package/dist/web/client/assets/{eye-B0DFz5hL.js → eye-CDHqtVoE.js} +1 -1
  25. package/dist/web/client/assets/file-text-TmalmYrb.js +1 -0
  26. package/dist/web/client/assets/{folder-BC5p7qK7.js → folder-vuNT4shY.js} +1 -1
  27. package/dist/web/client/assets/{fork-picker-dialog-B7NNpVmW.js → fork-picker-dialog-CpwEwsxA.js} +1 -1
  28. package/dist/web/client/assets/gauge-BsDqNM1A.js +1 -0
  29. package/dist/web/client/assets/globals-DCtBkCSD.css +2 -0
  30. package/dist/web/client/assets/{hard-drive-CHqgr7VQ.js → hard-drive-BT7UxHQu.js} +1 -1
  31. package/dist/web/client/assets/highlighted-body-KPVGNVTW-CgT7gqvs.js +1 -0
  32. package/dist/web/client/assets/horizontal-resize-VLjLByUV.js +1 -0
  33. package/dist/web/client/assets/index-BGnQeUYE.js +12 -0
  34. package/dist/web/client/assets/input-CxZp56Im.js +1 -0
  35. package/dist/web/client/assets/input-group-D7lAfKHR.js +1 -0
  36. package/dist/web/client/assets/ipython-tool-CkHaO3PW.js +3 -0
  37. package/dist/web/client/assets/is-ref-object-BcRWZ4l7.js +1 -0
  38. package/dist/web/client/assets/{loader-circle-DjfHXUPB.js → loader-circle-B5GIZGxd.js} +1 -1
  39. package/dist/web/client/assets/markdown-BHkByC9K.js +2 -0
  40. package/dist/web/client/assets/{markdown-code-xNyjdZ4g.js → markdown-code-CDTRq-HZ.js} +1 -1
  41. package/dist/web/client/assets/mermaid-HWGCJPDP-CY3N5ECk.js +1 -0
  42. package/dist/web/client/assets/message-queue-Dl8wbCOu.js +1 -0
  43. package/dist/web/client/assets/model-selector-list-CRZCXeBf.js +1 -0
  44. package/dist/web/client/assets/{notify-DxL0VD7Z.js → notify-DjVixft7.js} +1 -1
  45. package/dist/web/client/assets/{openui-renderer-TLNe5e_Q.js → openui-renderer-Bkkx5kmA.js} +37 -37
  46. package/dist/web/client/assets/{package-CdcJFPf2.js → package-BKBPgwMP.js} +1 -1
  47. package/dist/web/client/assets/{pencil-DcUwsKLn.js → pencil-CdO6qfv3.js} +1 -1
  48. package/dist/web/client/assets/{plug-Dt6VN0zF.js → plug-BRROUIw-.js} +1 -1
  49. package/dist/web/client/assets/prompt-input-WaGSKZCU.js +1 -0
  50. package/dist/web/client/assets/prompt-suggestions-BNyTcyWg.js +1 -0
  51. package/dist/web/client/assets/provider-catalog-C0XBIasJ.js +1 -0
  52. package/dist/web/client/assets/provider-label-Cka0ep0S.js +1 -0
  53. package/dist/web/client/assets/react-CwJFpaho.js +1 -0
  54. package/dist/web/client/assets/react-dom-DX3XddaT.js +1 -0
  55. package/dist/web/client/assets/{refresh-cw-IThTJ3j-.js → refresh-cw-l9WPHRkq.js} +1 -1
  56. package/dist/web/client/assets/repl-panel-L9dmPqio.js +1 -0
  57. package/dist/web/client/assets/{resource-helpers-Q2T0YCMO.js → resource-helpers-BuWybA8l.js} +1 -1
  58. package/dist/web/client/assets/resources-panel-mT-aMCvV.js +1 -0
  59. package/dist/web/client/assets/right-panel-context-CS8tJMzE.js +1 -0
  60. package/dist/web/client/assets/right-panel-registry-BCW7fQTG.js +2 -0
  61. package/dist/web/client/assets/{rotate-ccw-WNFNkKQD.js → rotate-ccw-CfGhzOv7.js} +1 -1
  62. package/dist/web/client/assets/routes-BWe5Iz-2.js +16 -0
  63. package/dist/web/client/assets/safe-external-url-BbAom7Bm.js +1 -0
  64. package/dist/web/client/assets/search-BjcXAUrI.js +1 -0
  65. package/dist/web/client/assets/session-insights-panel-B0rl37lo.js +1 -0
  66. package/dist/web/client/assets/session-reasoning-panel-8D2P7iaJ.js +1 -0
  67. package/dist/web/client/assets/session-tool-renderer-3E3cv8D0.js +1395 -0
  68. package/dist/web/client/assets/settings-dialog-B8lHq2tT.js +2 -0
  69. package/dist/web/client/assets/{skeleton-CkR2VmWc.js → skeleton-C3mo31Qu.js} +1 -1
  70. package/dist/web/client/assets/skeleton-loaders-BMa_G4yX.js +1 -0
  71. package/dist/web/client/assets/{shield-check-CkA2viVW.js → sparkles-D8XIY8pN.js} +1 -1
  72. package/dist/web/client/assets/square-DQaQu9bp.js +1 -0
  73. package/dist/web/client/assets/{square-terminal-BYTN_I86.js → square-terminal-BsopiuN7.js} +1 -1
  74. package/dist/web/client/assets/{subagent-chat-panel-oeLDPDAK.js → subagent-chat-panel-C5ukYiUx.js} +1 -1
  75. package/dist/web/client/assets/subagent-transcript-lqNcSVbH.js +1 -0
  76. package/dist/web/client/assets/subagents-panel-SJKhaVTr.js +1 -0
  77. package/dist/web/client/assets/{sun-BWiZFty0.js → sun-D0llhiMU.js} +1 -1
  78. package/dist/web/client/assets/surfaces-CpfsGAIA.js +1 -0
  79. package/dist/web/client/assets/switch-D3FhZU-S.js +1 -0
  80. package/dist/web/client/assets/terminal-BQAKkBY6.js +1 -0
  81. package/dist/web/client/assets/toast-lnCWGgSE.js +1 -0
  82. package/dist/web/client/assets/tokens-Ch5WqXC_.js +1 -0
  83. package/dist/web/client/assets/tool-result-B_yb2JoE.js +4 -0
  84. package/dist/web/client/assets/tool-timeline-VnMRQoLS.js +1 -0
  85. package/dist/web/client/assets/{triangle-alert-CU-gd7ui.js → triangle-alert-GAYh_5d3.js} +1 -1
  86. package/dist/web/client/assets/ui-preferences-aG2U2jjW.js +1 -0
  87. package/dist/web/client/assets/use-presence-7I2qv4qI.js +1 -0
  88. package/dist/web/client/assets/use-reduced-motion-BOcG709U.js +9 -0
  89. package/dist/web/client/assets/useBaseUiId-D9ZGPZ6f.js +1 -0
  90. package/dist/web/client/assets/useControlled-CgAAWIy9.js +1 -0
  91. package/dist/web/client/assets/utils-Brtgag-m.js +1 -0
  92. package/dist/web/client/assets/virtualized-turn-list-BgUgX6tM.js +6 -0
  93. package/dist/web/client/assets/workspace-panel-CKF5JQl2.js +1 -0
  94. package/dist/web/client/assets/workspace-path-nav-DqPbETfJ.js +2 -0
  95. package/dist/web/client/assets/{wrench-BJNNe07k.js → wrench-Myc12BTA.js} +1 -1
  96. package/dist/web/client/assets/x-BGsDD848.js +1 -0
  97. package/dist/web/client/bundle-budget.json +6 -6
  98. package/dist/web/server/_tanstack-start-manifest_v-BDPifIFN-DTSNCHBX.js +91 -0
  99. package/dist/web/server/{artifacts-panel-D3ySO--V-XSL53CXL.js → artifacts-panel-BN3DgqfV-N73J6N5Y.js} +39 -44
  100. package/dist/web/server/{chat-command-palette-kAbXhWVg-TJWXH2WW.js → chat-command-palette-G8awyZRw-2QE7FXGT.js} +18 -18
  101. package/dist/web/server/{chunk-SALXCFVO.js → chunk-33QA7BQJ.js} +19 -1
  102. package/dist/web/server/{chunk-5UCAJBAH.js → chunk-43S5N7SH.js} +80 -47
  103. package/dist/web/server/chunk-4EBSM4JR.js +74 -0
  104. package/dist/web/server/{chunk-ZIFSJ3HQ.js → chunk-4OTHKQMG.js} +185 -109
  105. package/dist/web/server/{chunk-NNKJTKOQ.js → chunk-6SOMNRAX.js} +309 -279
  106. package/dist/web/server/chunk-7E76R7MB.js +2138 -0
  107. package/dist/web/server/{chunk-EBG3XFGQ.js → chunk-7FK6YEMA.js} +49 -44
  108. package/dist/web/server/chunk-7HXCGBUP.js +56 -0
  109. package/dist/web/server/{chunk-P66QQWUM.js → chunk-7NZ3FJDA.js} +14 -1
  110. package/dist/web/server/{chunk-HF7DG7PC.js → chunk-7UTDOTOU.js} +80 -78
  111. package/dist/web/server/{chunk-OZO5ARFA.js → chunk-BQROC4PL.js} +11 -2
  112. package/dist/web/server/{chunk-JTCCQZLN.js → chunk-BUXJSBE3.js} +2 -2
  113. package/dist/web/server/{chunk-NIZBFVJF.js → chunk-CAPTFJOC.js} +9 -7
  114. package/dist/web/server/{chunk-YGYOBX7G.js → chunk-CCYLHNZJ.js} +1767 -52
  115. package/dist/web/server/{chunk-DJMHPJBP.js → chunk-CHEC7TWB.js} +3 -1
  116. package/dist/web/server/{chunk-NJ4QEZHK.js → chunk-CW6KZUKT.js} +7 -5
  117. package/dist/web/server/chunk-DLA5TLKX.js +164 -0
  118. package/dist/web/server/{chunk-MNBGB2SP.js → chunk-E5HALE4M.js} +4 -4
  119. package/dist/web/server/{chunk-D27LRYVT.js → chunk-EDAWH2MT.js} +10 -9
  120. package/dist/web/server/{chunk-NGCQJ33Y.js → chunk-ENGEUJIH.js} +1494 -1644
  121. package/dist/web/server/{chunk-RIP3PBWT.js → chunk-ESM7OCRL.js} +4 -4
  122. package/dist/web/server/{chunk-O3HDELZ2.js → chunk-FT74GAAH.js} +676 -670
  123. package/dist/web/server/{chunk-WNCAL4HN.js → chunk-HQ5TEXHT.js} +132 -152
  124. package/dist/web/server/{chunk-YOM42BKD.js → chunk-IPV4GLJL.js} +16 -16
  125. package/dist/web/server/{chunk-UL2725KQ.js → chunk-IXGLKAPN.js} +54 -46
  126. package/dist/web/server/{chunk-3TIMGWWI.js → chunk-JPDRUSUD.js} +2 -2
  127. package/dist/web/server/{chunk-4WBFCB4O.js → chunk-JVOW2NWC.js} +179 -177
  128. package/dist/web/server/chunk-K6PTNSCW.js +31 -0
  129. package/dist/web/server/{chunk-AR7O7JXD.js → chunk-KBWUBWVJ.js} +24 -1
  130. package/dist/web/server/{chunk-QIULBRTU.js → chunk-MJXXVQNA.js} +79 -84
  131. package/dist/web/server/{chunk-NWDI3OWB.js → chunk-NCK2FJAD.js} +30 -26
  132. package/dist/web/server/{chunk-QFRCJWQQ.js → chunk-NMBH57JT.js} +94 -33
  133. package/dist/web/server/{chunk-EAJTWMK5.js → chunk-NZ6KQT2X.js} +2 -2
  134. package/dist/web/server/{chunk-2DDWXTVG.js → chunk-O2UYZT3Z.js} +11 -11
  135. package/dist/web/server/{chunk-DLUZFOG3.js → chunk-OMEDERPG.js} +21 -25
  136. package/dist/web/server/{chunk-BLSX7WHW.js → chunk-OSMP55KI.js} +23 -2
  137. package/dist/web/server/{chunk-S3PQ6HKH.js → chunk-OVJYUWSQ.js} +2 -2
  138. package/dist/web/server/{chunk-UCUFC553.js → chunk-RXUMFFUV.js} +3 -3
  139. package/dist/web/server/{chunk-DO2O27B2.js → chunk-SDV3P3IW.js} +2 -2
  140. package/dist/web/server/chunk-TLNZNR7C.js +46 -0
  141. package/dist/web/server/{chunk-FYDQK6UX.js → chunk-UDD5W4CR.js} +32 -10
  142. package/dist/web/server/{chunk-MNPHMZU7.js → chunk-UE32PAV2.js} +47 -57
  143. package/dist/web/server/{chunk-KP2PNDGL.js → chunk-WB2LJC3R.js} +29 -32
  144. package/dist/web/server/{chunk-ETTDO4UO.js → chunk-WTYNN6EV.js} +1 -26
  145. package/dist/web/server/{chunk-EJEPDVK6.js → chunk-WU6X3GPJ.js} +48 -5
  146. package/dist/web/server/{chunk-XIB6XNUX.js → chunk-XJ6TGSUB.js} +425 -404
  147. package/dist/web/server/{chunk-PLYZ7P2Y.js → chunk-YMPJMHXZ.js} +41 -4
  148. package/dist/web/server/{chunk-GETSIVNU.js → chunk-YVGCPUAW.js} +7 -7
  149. package/dist/web/server/{chunk-4UBOIY2S.js → chunk-ZNFXBGLK.js} +1 -1
  150. package/dist/web/server/chunk-ZOVXMNJM.js +477 -0
  151. package/dist/web/server/{fork-picker-dialog-Ds6Tgtu3-DIBWN7MV.js → fork-picker-dialog-YKlapaxN-DR5L74ST.js} +9 -8
  152. package/dist/web/server/{markdown-DTnMbD87-FXGGAPJD.js → markdown-BzNejPoZ-6ITTDAV6.js} +2 -3
  153. package/dist/web/server/{markdown-code-BStjFfsy-SSLWUT4S.js → markdown-code-DAwXuW6m-HHVELO6I.js} +3 -4
  154. package/dist/web/server/{fleet-message-queue-D_w8lSeY-T3HB7HVQ.js → message-queue-Demph1x4-RBJUC3AT.js} +14 -10
  155. package/dist/web/server/{model-selector-list-DxeGZoD2-P6S6FSJH.js → model-selector-list-BmzLiCx9-TK6JGGKU.js} +20 -19
  156. package/dist/web/server/{openui-renderer-MKFv6LlH-MDRSVFEY.js → openui-renderer-moJGf0LA-QCU3PI6H.js} +17 -18
  157. package/dist/web/server/{prompt-suggestions-BOItmGnD-YQA7RHLG.js → prompt-suggestions-yPZqX__K-3VGJC4IF.js} +7 -6
  158. package/dist/web/server/{repl-panel-CuyF8wt5-CHDT2Q3N.js → repl-panel-CgUF1qUw-3DFD2V53.js} +10 -11
  159. package/dist/web/server/{resources-panel-CE5pD4vy-V5FXBTYC.js → resources-panel-ChUliWV--JITAGS6Q.js} +6 -7
  160. package/dist/web/server/{router-Dg72SESP-PCWKLFRG.js → router-CPdFlpbe-LAD4MNZB.js} +3111 -235
  161. package/dist/web/server/{routes-BGrVtPYF-SURPAJN6.js → routes-hkom6S6L-DUPPQHPY.js} +5045 -4285
  162. package/dist/web/server/server.js +2 -2
  163. package/dist/web/server/{session-insights-panel-CUhdgvRt-VB2HUCQP.js → session-insights-panel-xgrkX1Rp-FDNURBXZ.js} +9 -9
  164. package/dist/web/server/{fleet-reasoning-panel-DG_vuvv0-NCZWEEIT.js → session-reasoning-panel-m1RgcIph-NUXGXVKE.js} +21 -22
  165. package/dist/web/server/session-tool-renderer-CglQ2ky7-2JVYNZG2.js +45 -0
  166. package/dist/web/server/{settings-dialog-CK0FJlTg-HZRBAXDZ.js → settings-dialog-BCEfmgtP-T3WQEZHB.js} +175 -1373
  167. package/dist/web/server/{subagent-chat-panel-gzamnTgK-PQ2TLLJF.js → subagent-chat-panel-BTwI1kdB-LKBWA4GD.js} +32 -41
  168. package/dist/web/server/{subagents-panel-Berjd7HJ-EI5ZKC6V.js → subagents-panel-8Z9_csoV-HYMEEBHB.js} +37 -45
  169. package/dist/web/server/{fleet-tool-timeline-D6yM4ZMz-ZSFVRRRI.js → tool-timeline-QL9k5dzA-RLU26HXT.js} +6 -6
  170. package/dist/web/server/{workspace-panel-CBBa_3UO-B4PPFPMA.js → workspace-panel-BHEB9nRM-TS62SYBA.js} +24 -31
  171. package/package.json +1 -1
  172. package/dist/web/client/assets/action-swap-roll-COzQ86wm.js +0 -1
  173. package/dist/web/client/assets/agent-activity-svETLf_5.js +0 -1
  174. package/dist/web/client/assets/agent-disclosure-DAMuuGcM.js +0 -1
  175. package/dist/web/client/assets/analytics-stub-B6zGMuSV.js +0 -1
  176. package/dist/web/client/assets/artifacts-panel-HVjqBMyx.js +0 -1
  177. package/dist/web/client/assets/artifacts-utils-N_kUFbz2.js +0 -1
  178. package/dist/web/client/assets/bundle-mjs-DKHVkVWu.js +0 -1
  179. package/dist/web/client/assets/button-C5wFDY5_.js +0 -1
  180. package/dist/web/client/assets/chat-BhYseKd6.js +0 -52
  181. package/dist/web/client/assets/chat-command-palette-LILDO_vG.js +0 -1
  182. package/dist/web/client/assets/check-JjHKAZas.js +0 -1
  183. package/dist/web/client/assets/chevron-right-DrJxToLs.js +0 -1
  184. package/dist/web/client/assets/chevron-up-CnSvySGH.js +0 -1
  185. package/dist/web/client/assets/circle-alert-CONlFReH.js +0 -1
  186. package/dist/web/client/assets/circle-x-CkKCB__4.js +0 -1
  187. package/dist/web/client/assets/citations-BPv8HIpf.js +0 -2
  188. package/dist/web/client/assets/cn-C8c0S2mI.js +0 -1
  189. package/dist/web/client/assets/collapsible-BoXtZZWN.js +0 -1
  190. package/dist/web/client/assets/command-PhicLCoO.js +0 -1
  191. package/dist/web/client/assets/createBaseUIEventDetails-DV0dQrBX.js +0 -1
  192. package/dist/web/client/assets/createLucideIcon-DwxZHm0M.js +0 -1
  193. package/dist/web/client/assets/dialog-pBGUjAQ7.js +0 -1
  194. package/dist/web/client/assets/dist-BPaFisIZ.js +0 -41
  195. package/dist/web/client/assets/earth-DGZXAN5r.js +0 -1
  196. package/dist/web/client/assets/ease-u56MhKYS.js +0 -1
  197. package/dist/web/client/assets/file-text-T-NcAlZs.js +0 -1
  198. package/dist/web/client/assets/fleet-message-queue-fbYYwMj0.js +0 -1
  199. package/dist/web/client/assets/fleet-pi-tool-renderer-BRgNnmaJ.js +0 -1395
  200. package/dist/web/client/assets/fleet-reasoning-panel-CjA2dwUJ.js +0 -1
  201. package/dist/web/client/assets/fleet-subagent-list-iKUtLJKZ.js +0 -1
  202. package/dist/web/client/assets/fleet-tool-timeline-C8heL7ae.js +0 -1
  203. package/dist/web/client/assets/gauge-DNpstbBn.js +0 -1
  204. package/dist/web/client/assets/globals-CuIiqOTg.css +0 -2
  205. package/dist/web/client/assets/highlighted-body-KPVGNVTW-sUCZ1fHv.js +0 -1
  206. package/dist/web/client/assets/horizontal-resize-Cp3iHMH7.js +0 -1
  207. package/dist/web/client/assets/image-BbPmlw-n.js +0 -1
  208. package/dist/web/client/assets/index-CSGplyr_.js +0 -12
  209. package/dist/web/client/assets/input-PcdubeKn.js +0 -1
  210. package/dist/web/client/assets/input-group-C2HJEZvl.js +0 -1
  211. package/dist/web/client/assets/ipython-tool-CyuMOxz1.js +0 -3
  212. package/dist/web/client/assets/layout-gyLzPvVv.js +0 -1
  213. package/dist/web/client/assets/markdown-lvexwooo.js +0 -2
  214. package/dist/web/client/assets/mermaid-HWGCJPDP-Bm7CuruA.js +0 -1
  215. package/dist/web/client/assets/message-square-hbDao-A1.js +0 -1
  216. package/dist/web/client/assets/model-selector-list-CoXX358G.js +0 -1
  217. package/dist/web/client/assets/plus-DXN1Bg_z.js +0 -1
  218. package/dist/web/client/assets/prompt-input-fwP8TsgQ.js +0 -1
  219. package/dist/web/client/assets/prompt-suggestions-BlGXmWS7.js +0 -1
  220. package/dist/web/client/assets/provider-catalog-DYMFdbKc.js +0 -1
  221. package/dist/web/client/assets/provider-label-B4q5mI65.js +0 -1
  222. package/dist/web/client/assets/react-dom-Bwxum3ti.js +0 -1
  223. package/dist/web/client/assets/repl-panel-C5om8MGU.js +0 -1
  224. package/dist/web/client/assets/resources-panel-D867-goy.js +0 -1
  225. package/dist/web/client/assets/right-panel-context-DHlNWJsF.js +0 -1
  226. package/dist/web/client/assets/right-panel-registry-BBlxLxnx.js +0 -2
  227. package/dist/web/client/assets/routes-XGsAIqBJ.js +0 -16
  228. package/dist/web/client/assets/safe-external-url-D3PJJIcM.js +0 -1
  229. package/dist/web/client/assets/search-eWVnAJsb.js +0 -1
  230. package/dist/web/client/assets/session-insights-panel-YnaXvTpi.js +0 -1
  231. package/dist/web/client/assets/settings-dialog-BSBasR3o.js +0 -2
  232. package/dist/web/client/assets/skeleton-loaders-C9vHwAYV.js +0 -1
  233. package/dist/web/client/assets/sparkles-DuclzqlE.js +0 -1
  234. package/dist/web/client/assets/square-Bhn8gjr0.js +0 -1
  235. package/dist/web/client/assets/subagent-transcript-DaVHjNUH.js +0 -1
  236. package/dist/web/client/assets/subagent-utils-DDH5qm9Z.js +0 -1
  237. package/dist/web/client/assets/subagents-panel-D_aVgSCi.js +0 -1
  238. package/dist/web/client/assets/surfaces-BhAXz9So.js +0 -1
  239. package/dist/web/client/assets/switch-WhXeJNNY.js +0 -1
  240. package/dist/web/client/assets/terminal-DOS1s1gm.js +0 -1
  241. package/dist/web/client/assets/toast-D3c9XeGe.js +0 -1
  242. package/dist/web/client/assets/tool-result-Cki8WUNc.js +0 -4
  243. package/dist/web/client/assets/ui-preferences-CImQGZm_.js +0 -1
  244. package/dist/web/client/assets/use-reduced-motion-eORd7fqW.js +0 -9
  245. package/dist/web/client/assets/useBaseUiId-CHqXB2UQ.js +0 -1
  246. package/dist/web/client/assets/useControlled-CJJ9BOQB.js +0 -1
  247. package/dist/web/client/assets/utils-Eg7xtNmV.js +0 -1
  248. package/dist/web/client/assets/virtualized-turn-list-CdMa-ydT.js +0 -6
  249. package/dist/web/client/assets/workspace-panel-77bDbprs.js +0 -1
  250. package/dist/web/client/assets/workspace-path-nav-C0AQNZyy.js +0 -1
  251. package/dist/web/client/assets/x-CsRC_tCI.js +0 -1
  252. package/dist/web/server/_tanstack-start-manifest_v-0L7fqnH4-KMVGUFE4.js +0 -95
  253. package/dist/web/server/agent-activity-BuEE6iVw-CDZLK4D2.js +0 -514
  254. package/dist/web/server/chunk-2JHTYWD5.js +0 -1196
  255. package/dist/web/server/chunk-3JMESBAT.js +0 -35
  256. package/dist/web/server/chunk-42XU6WV7.js +0 -56
  257. package/dist/web/server/chunk-AQ66E5OW.js +0 -33
  258. package/dist/web/server/chunk-BYXBJQAS.js +0 -0
  259. package/dist/web/server/chunk-FAGDMGLK.js +0 -6589
  260. package/dist/web/server/chunk-FJV6EQDW.js +0 -36
  261. package/dist/web/server/chunk-GL6HWDJB.js +0 -19
  262. package/dist/web/server/chunk-L46H6IDX.js +0 -13
  263. package/dist/web/server/chunk-NIDBN7BQ.js +0 -86
  264. package/dist/web/server/chunk-ON33WDZX.js +0 -31
  265. package/dist/web/server/chunk-PVJCTQFK.js +0 -22
  266. package/dist/web/server/chunk-QPNUGF3V.js +0 -35
  267. package/dist/web/server/chunk-S5LFXXDY.js +0 -1265
  268. package/dist/web/server/chunk-VPKX7QRU.js +0 -42
  269. package/dist/web/server/chunk-ZCVWADNW.js +0 -37
  270. package/dist/web/server/fleet-pi-tool-renderer-qwc-qZFq-4U556N5Q.js +0 -51
  271. package/dist/web/server/fleet-subagent-list-BGb0PjhF-2X67FMUV.js +0 -18
@@ -1,39 +1,36 @@
1
+ import {
2
+ Eye
3
+ } from "./chunk-2ST2ULW7.js";
1
4
  import {
2
5
  Citations,
3
- LazyMarkdown,
4
6
  ListTodo,
5
7
  LogOut,
6
8
  MessageCircleQuestionMark,
7
- PI_TOOL_RENDERERS,
8
9
  useHoverCapable
9
- } from "./chunk-NWDI3OWB.js";
10
- import {
11
- pct,
12
- progressOf
13
- } from "./chunk-V3S6BVXO.js";
14
- import {
15
- mono
16
- } from "./chunk-UCUFC553.js";
17
- import {
18
- Eye
19
- } from "./chunk-2ST2ULW7.js";
10
+ } from "./chunk-NCK2FJAD.js";
20
11
  import {
21
12
  GitBranch,
22
13
  Globe,
23
- ShieldCheck
24
- } from "./chunk-BLSX7WHW.js";
25
- import {
14
+ ShieldCheck,
26
15
  Sparkles
27
- } from "./chunk-3JMESBAT.js";
16
+ } from "./chunk-OSMP55KI.js";
28
17
  import {
29
18
  Terminal
30
19
  } from "./chunk-XA42CHF2.js";
31
20
  import {
21
+ LazyMarkdown,
32
22
  stripSandboxPrefixes
33
- } from "./chunk-P66QQWUM.js";
23
+ } from "./chunk-7NZ3FJDA.js";
34
24
  import {
35
25
  Search
36
26
  } from "./chunk-JIULUYHT.js";
27
+ import {
28
+ pct,
29
+ progressOf
30
+ } from "./chunk-V3S6BVXO.js";
31
+ import {
32
+ mono
33
+ } from "./chunk-RXUMFFUV.js";
37
34
  import {
38
35
  bundledLanguages,
39
36
  createHighlighter,
@@ -47,36 +44,27 @@ import {
47
44
  FileDiff,
48
45
  ToolResult,
49
46
  ToolResultOutput
50
- } from "./chunk-DLUZFOG3.js";
47
+ } from "./chunk-OMEDERPG.js";
51
48
  import {
52
49
  ActionSwapRollText,
50
+ AgentDisclosure,
51
+ CircleX,
53
52
  FileCodeCorner
54
- } from "./chunk-EJEPDVK6.js";
55
- import {
56
- AgentDisclosure
57
- } from "./chunk-VPKX7QRU.js";
58
- import {
59
- Collapsible,
60
- CollapsibleContent,
61
- CollapsibleTrigger
62
- } from "./chunk-MNPHMZU7.js";
53
+ } from "./chunk-WU6X3GPJ.js";
63
54
  import {
64
55
  RotateCcw
65
56
  } from "./chunk-OOXWPL22.js";
66
- import {
67
- Wrench
68
- } from "./chunk-O2DUZJYK.js";
69
- import {
70
- CircleX
71
- } from "./chunk-ON33WDZX.js";
72
57
  import {
73
58
  CircleCheck,
74
59
  LoaderCircle
75
60
  } from "./chunk-TNL4YV63.js";
61
+ import {
62
+ Wrench
63
+ } from "./chunk-O2DUZJYK.js";
76
64
  import {
77
65
  AnimatePresence,
78
66
  useReducedMotion
79
- } from "./chunk-NIZBFVJF.js";
67
+ } from "./chunk-CAPTFJOC.js";
80
68
  import {
81
69
  ChevronRight
82
70
  } from "./chunk-3C4CFCIS.js";
@@ -87,16 +75,16 @@ import {
87
75
  SPRING_PRESS,
88
76
  SPRING_SWAP,
89
77
  m
90
- } from "./chunk-EBG3XFGQ.js";
78
+ } from "./chunk-7FK6YEMA.js";
91
79
  import {
92
- ChevronUp
93
- } from "./chunk-OZO5ARFA.js";
80
+ Collapsible,
81
+ CollapsibleContent,
82
+ CollapsibleTrigger
83
+ } from "./chunk-UE32PAV2.js";
94
84
  import {
85
+ ChevronUp,
95
86
  isSafeExternalUrl
96
- } from "./chunk-L46H6IDX.js";
97
- import {
98
- ChevronDown
99
- } from "./chunk-WWJF4RO2.js";
87
+ } from "./chunk-BQROC4PL.js";
100
88
  import {
101
89
  Check
102
90
  } from "./chunk-4QD4PCVP.js";
@@ -104,29 +92,30 @@ import {
104
92
  X
105
93
  } from "./chunk-JBLHIEVG.js";
106
94
  import {
107
- FileText
108
- } from "./chunk-AR7O7JXD.js";
95
+ ChevronDown
96
+ } from "./chunk-WWJF4RO2.js";
109
97
  import {
110
- CircleAlert
111
- } from "./chunk-ZCVWADNW.js";
98
+ CircleAlert,
99
+ FileText
100
+ } from "./chunk-KBWUBWVJ.js";
112
101
  import {
113
102
  IpythonTool,
114
103
  ToolApprovalFooter,
115
104
  ToolTextShimmer,
116
105
  adaptToolPart,
117
106
  useToolComplete
118
- } from "./chunk-QIULBRTU.js";
107
+ } from "./chunk-MJXXVQNA.js";
119
108
  import {
120
109
  createLucideIcon
121
110
  } from "./chunk-4ZIEVI5O.js";
122
111
  import {
123
112
  cn
124
- } from "./chunk-DJMHPJBP.js";
113
+ } from "./chunk-CHEC7TWB.js";
125
114
  import {
126
115
  __exportAll
127
116
  } from "./chunk-L547YHC4.js";
128
117
 
129
- // web/app/dist/server/assets/fleet-pi-tool-renderer-qwc-qZFq.js
118
+ // web/app/dist/server/assets/session-tool-renderer-CglQ2ky7.js
130
119
  import React, { createContext, memo, useCallback, useContext, useEffect, useId, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
131
120
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
132
121
  var ChevronsDown = createLucideIcon("chevrons-down", [["path", {
@@ -283,9 +272,9 @@ function QuestionPrompt({ questions, questionIndex = 1, totalQuestions, onPrevio
283
272
  className: "flex items-center justify-between gap-px",
284
273
  "data-total-questions": resolvedTotal,
285
274
  children: /* @__PURE__ */ jsxs("div", {
286
- className: "flex items-center gap-2 text-sm text-an-tool-color",
275
+ className: "flex items-center gap-2 text-sm text-foreground",
287
276
  children: [/* @__PURE__ */ jsx("span", {
288
- className: "inline-flex h-5 min-w-5 items-center justify-center rounded px-1 text-sm font-medium text-an-tool-color-muted",
277
+ className: "inline-flex h-5 min-w-5 items-center justify-center rounded px-1 text-sm font-medium text-muted-foreground",
289
278
  children: clampedIndex
290
279
  }), /* @__PURE__ */ jsx("span", { children: activeQuestion.title })]
291
280
  })
@@ -303,14 +292,14 @@ function QuestionPrompt({ questions, questionIndex = 1, totalQuestions, onPrevio
303
292
  if (customEnabled) setCustomText("");
304
293
  } else toggleMulti(optionId);
305
294
  },
306
- className: "-mx-2 flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left hover:bg-an-background-secondary",
295
+ className: "-mx-2 flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left hover:bg-secondary",
307
296
  children: [/* @__PURE__ */ jsx("span", {
308
- className: cn("inline-flex h-5 min-w-5 items-center justify-center rounded border px-1 text-sm font-medium", checked ? "border-an-primary-color bg-an-primary-color text-an-send-button-color" : "border-border bg-transparent text-an-tool-color-muted"),
297
+ className: cn("inline-flex h-5 min-w-5 items-center justify-center rounded border px-1 text-sm font-medium", checked ? "border-primary bg-primary text-primary-foreground" : "border-border bg-transparent text-muted-foreground"),
309
298
  children: optionBadge(idx)
310
299
  }), /* @__PURE__ */ jsxs("span", {
311
- className: "text-sm text-an-tool-color",
300
+ className: "text-sm text-foreground",
312
301
  children: [option.label, option.description && /* @__PURE__ */ jsxs("span", {
313
- className: "text-an-tool-color-muted",
302
+ className: "text-muted-foreground",
314
303
  children: [" ", option.description]
315
304
  })]
316
305
  })]
@@ -318,13 +307,13 @@ function QuestionPrompt({ questions, questionIndex = 1, totalQuestions, onPrevio
318
307
  }), customEnabled && /* @__PURE__ */ jsxs("div", {
319
308
  className: "flex items-center gap-2 pt-1",
320
309
  children: [/* @__PURE__ */ jsx("span", {
321
- className: cn("inline-flex h-5 min-w-5 items-center justify-center rounded border px-1 text-sm font-medium", selectedIds.includes(QUESTION_CUSTOM_ID) ? "border-an-primary-color bg-an-primary-color text-an-send-button-color" : "border-border bg-transparent text-an-tool-color-muted"),
310
+ className: cn("inline-flex h-5 min-w-5 items-center justify-center rounded border px-1 text-sm font-medium", selectedIds.includes(QUESTION_CUSTOM_ID) ? "border-primary bg-primary text-primary-foreground" : "border-border bg-transparent text-muted-foreground"),
322
311
  children: optionBadge(activeQuestion.options.length)
323
312
  }), /* @__PURE__ */ jsx("input", {
324
313
  value: customText,
325
314
  onChange: (event) => handleCustomTextChange(event.target.value),
326
315
  placeholder: activeQuestion.customPlaceholder ?? "Type your answer",
327
- className: "h-7 w-full rounded-md border border-border bg-background px-2 text-base text-an-tool-color md:text-sm"
316
+ className: "h-7 w-full rounded-md border border-border bg-background px-2 text-base text-foreground md:text-sm"
328
317
  })]
329
318
  })]
330
319
  }),
@@ -333,7 +322,7 @@ function QuestionPrompt({ questions, questionIndex = 1, totalQuestions, onPrevio
333
322
  onChange: (event) => setTextValue(event.target.value),
334
323
  placeholder: activeQuestion.placeholder ?? "Type your answer",
335
324
  rows: 3,
336
- className: "w-full resize-y rounded-md border border-border bg-background px-2 py-1.5 text-base text-an-tool-color md:text-sm"
325
+ className: "w-full resize-y rounded-md border border-border bg-background px-2 py-1.5 text-base text-foreground md:text-sm"
337
326
  }),
338
327
  /* @__PURE__ */ jsxs("div", {
339
328
  className: cn("flex items-center gap-1.5", showNav ? "justify-between" : "justify-end"),
@@ -343,13 +332,13 @@ function QuestionPrompt({ questions, questionIndex = 1, totalQuestions, onPrevio
343
332
  type: "button",
344
333
  onClick: onPreviousQuestion,
345
334
  disabled: !canGoPrev,
346
- className: "h-6 rounded px-2 text-sm text-muted-foreground hover:text-an-tool-color disabled:opacity-60",
335
+ className: "h-6 rounded px-2 text-sm text-muted-foreground hover:text-foreground disabled:opacity-60",
347
336
  children: "Previous"
348
337
  }), onNextQuestion && /* @__PURE__ */ jsx("button", {
349
338
  type: "button",
350
339
  onClick: onNextQuestion,
351
340
  disabled: !canGoNext,
352
- className: "h-6 rounded px-2 text-sm text-muted-foreground hover:text-an-tool-color disabled:opacity-60",
341
+ className: "h-6 rounded px-2 text-sm text-muted-foreground hover:text-foreground disabled:opacity-60",
353
342
  children: "Next"
354
343
  })]
355
344
  }), /* @__PURE__ */ jsxs("div", {
@@ -357,13 +346,13 @@ function QuestionPrompt({ questions, questionIndex = 1, totalQuestions, onPrevio
357
346
  children: [allowSkip && /* @__PURE__ */ jsx("button", {
358
347
  type: "button",
359
348
  onClick: handleSkip,
360
- className: "h-6 rounded px-2 text-sm text-muted-foreground transition-[background-color,color,transform] duration-150 hover:bg-muted/50 hover:text-an-tool-color active:scale-[0.98]",
349
+ className: "h-6 rounded px-2 text-sm text-muted-foreground transition-[background-color,color,transform] duration-150 hover:bg-muted/50 hover:text-foreground active:scale-[0.98]",
361
350
  children: skipLabel
362
351
  }), /* @__PURE__ */ jsx("button", {
363
352
  type: "button",
364
353
  onClick: handleSubmit,
365
354
  disabled: !canSubmit,
366
- className: "h-6 rounded bg-an-primary-color px-2.5 text-sm font-medium text-an-send-button-color transition-[background-color,transform] duration-150 hover:bg-an-primary-color/90 active:scale-[0.98] disabled:opacity-60 disabled:hover:bg-an-primary-color disabled:active:scale-100",
355
+ className: "h-6 rounded bg-primary px-2.5 text-sm font-medium text-primary-foreground transition-[background-color,transform] duration-150 hover:bg-primary/90 active:scale-[0.98] disabled:opacity-60 disabled:hover:bg-primary disabled:active:scale-100",
367
356
  children: primaryLabel
368
357
  })]
369
358
  })]
@@ -440,9 +429,9 @@ function QuestionTool({ part }) {
440
429
  if (!isControlled) setLocalIndex((prev) => Math.min(totalQuestions, prev + 1));
441
430
  };
442
431
  return /* @__PURE__ */ jsxs("div", {
443
- className: "overflow-hidden rounded-an-tool-border-radius border border-border bg-an-tool-background",
432
+ className: "overflow-hidden rounded-chat-tool border border-border bg-muted",
444
433
  children: [/* @__PURE__ */ jsxs("div", {
445
- className: "flex h-7 items-center justify-between border-b border-border px-3 text-xs text-an-tool-color-muted",
434
+ className: "flex h-7 items-center justify-between border-b border-border px-3 text-xs text-muted-foreground",
446
435
  children: [/* @__PURE__ */ jsxs("div", {
447
436
  className: "inline-flex items-center gap-1.5",
448
437
  children: [/* @__PURE__ */ jsx(MessageCircleQuestionMark, { className: "size-3.5" }), "Question"]
@@ -453,7 +442,7 @@ function QuestionTool({ part }) {
453
442
  type: "button",
454
443
  onClick: goPrev,
455
444
  disabled: !canGoPrev,
456
- className: "inline-flex size-5 items-center justify-center rounded-[4px] hover:bg-an-background-secondary disabled:opacity-40",
445
+ className: "inline-flex size-5 items-center justify-center rounded-[4px] hover:bg-secondary disabled:opacity-40",
457
446
  "aria-label": "Previous question",
458
447
  children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-3.5" })
459
448
  }),
@@ -466,14 +455,14 @@ function QuestionTool({ part }) {
466
455
  type: "button",
467
456
  onClick: goNext,
468
457
  disabled: !canGoNext,
469
- className: "inline-flex size-5 items-center justify-center rounded-[4px] hover:bg-an-background-secondary disabled:opacity-40",
458
+ className: "inline-flex size-5 items-center justify-center rounded-[4px] hover:bg-secondary disabled:opacity-40",
470
459
  "aria-label": "Next question",
471
460
  children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" })
472
461
  })
473
462
  ]
474
463
  })]
475
464
  }), isComplete ? /* @__PURE__ */ jsx("div", {
476
- className: "bg-background px-3 py-2 text-xs text-an-tool-color-muted",
465
+ className: "bg-background px-3 py-2 text-xs text-muted-foreground",
477
466
  children: summaryText
478
467
  }) : /* @__PURE__ */ jsx(QuestionPrompt, {
479
468
  questions,
@@ -495,64 +484,6 @@ function QuestionTool({ part }) {
495
484
  }, `${clampedIndex}-${question.title}`)]
496
485
  });
497
486
  }
498
- var toolStateCache = /* @__PURE__ */ new Map();
499
- function getToolStateSnapshot(part) {
500
- return {
501
- state: part.state,
502
- inputJson: JSON.stringify(part.input || {}),
503
- outputJson: JSON.stringify(part.output || {})
504
- };
505
- }
506
- function hasToolStateChanged(toolCallId, part) {
507
- const cached = toolStateCache.get(toolCallId);
508
- const current = getToolStateSnapshot(part);
509
- if (!cached) {
510
- toolStateCache.set(toolCallId, current);
511
- return true;
512
- }
513
- const changed = cached.state !== current.state || cached.inputJson !== current.inputJson || cached.outputJson !== current.outputJson;
514
- if (changed) toolStateCache.set(toolCallId, current);
515
- return changed;
516
- }
517
- function arePartsEqual(prev, next) {
518
- if (prev.toolCallId !== next.toolCallId) return false;
519
- if (prev.type !== next.type) return false;
520
- const toolCallId = next.toolCallId;
521
- if (!toolCallId) return prev.state === next.state;
522
- return !hasToolStateChanged(toolCallId, next);
523
- }
524
- function isToolCompleted(part) {
525
- if (part.output !== void 0 && part.output !== null) return true;
526
- if (part.state === "error") return true;
527
- if (part.state === "result") return true;
528
- return false;
529
- }
530
- function areToolPropsEqual(prevProps, nextProps) {
531
- if (!arePartsEqual(prevProps.part, nextProps.part)) return false;
532
- if (isToolCompleted(nextProps.part)) return true;
533
- if (prevProps.chatStatus !== nextProps.chatStatus) return false;
534
- return true;
535
- }
536
- function formatElapsedTime(ms) {
537
- if (ms < 1e3) return "";
538
- const seconds = Math.floor(ms / 1e3);
539
- if (seconds < 60) return `${seconds}s`;
540
- const minutes = Math.floor(seconds / 60);
541
- const remainingSeconds = seconds % 60;
542
- if (remainingSeconds === 0) return `${minutes}m`;
543
- return `${minutes}m ${remainingSeconds}s`;
544
- }
545
- function getToolStatus(part, chatStatus) {
546
- const basePending = part.state !== "output-available" && part.state !== "output-error";
547
- const isError = part.state === "output-error" || part.state === "output-available" && part.output?.success === false;
548
- const isSuccess = part.state === "output-available" && !isError;
549
- return {
550
- isPending: basePending && chatStatus === "streaming",
551
- isError,
552
- isSuccess,
553
- isInterrupted: basePending && chatStatus !== "streaming" && chatStatus !== void 0
554
- };
555
- }
556
487
  function extractCommandSummary(cmd) {
557
488
  return cmd.split("|").map((s) => s.trim().split(/\s+/)[0] ?? "").filter(Boolean).slice(0, 4).join(", ");
558
489
  }
@@ -562,7 +493,7 @@ function BashToolTerminalCard({ step, state, onComplete, approval }) {
562
493
  const command = step.bashCommand ?? step.toolDetail;
563
494
  const summary = extractCommandSummary(command);
564
495
  return /* @__PURE__ */ jsxs("div", {
565
- className: "overflow-hidden rounded-an-tool-border-radius border border-border bg-an-tool-background",
496
+ className: "overflow-hidden rounded-chat-tool border border-border bg-muted",
566
497
  children: [
567
498
  /* @__PURE__ */ jsxs("div", {
568
499
  className: "flex h-7 items-center justify-between pr-2 pl-2.5",
@@ -594,7 +525,7 @@ function BashToolTerminalCard({ step, state, onComplete, approval }) {
594
525
  })]
595
526
  }),
596
527
  /* @__PURE__ */ jsxs("div", {
597
- className: "overflow-hidden border-t border-border bg-background px-2.5 py-1.5 font-mono text-[0.75rem] leading-[16px]",
528
+ className: "overflow-hidden border-t border-border bg-background px-2.5 py-1.5 font-mono text-label leading-[16px]",
598
529
  children: [/* @__PURE__ */ jsxs("div", {
599
530
  className: "break-all",
600
531
  children: [/* @__PURE__ */ jsx("span", {
@@ -11507,10 +11438,10 @@ function EditToolDiffCard({ step, state, onComplete, input, output, isCollapsibl
11507
11438
  ` : void 0, [themeType]);
11508
11439
  const diffClassName = "an-edit-diff dark:bg-black dark:[--diffs-bg:#000] dark:[--diffs-bg-buffer-override:#000] dark:[--diffs-bg-context-override:#000] dark:[--diffs-bg-hover-override:#0a0a0a] dark:[--diffs-bg-separator-override:#0f0f0f]";
11509
11440
  return /* @__PURE__ */ jsxs("div", {
11510
- className: "an-edit-tool-card overflow-hidden rounded-an-tool-border-radius border border-an-tool-border-color bg-an-tool-background dark:bg-black",
11441
+ className: "an-edit-tool-card overflow-hidden rounded-chat-tool border border-border bg-muted dark:bg-black",
11511
11442
  children: [
11512
11443
  /* @__PURE__ */ jsxs("div", {
11513
- className: "flex h-7 items-center justify-between bg-an-tool-background px-2.5 py-0 " + (isPending && !diffFiles ? "" : "border-b border-an-tool-border-color"),
11444
+ className: "flex h-7 items-center justify-between bg-muted px-2.5 py-0 " + (isPending && !diffFiles ? "" : "border-b border-border"),
11514
11445
  children: [/* @__PURE__ */ jsxs("div", {
11515
11446
  className: "flex min-w-0 items-center gap-1.5",
11516
11447
  children: [hasFileName && /* @__PURE__ */ jsx(FileExtIcon, {
@@ -11531,28 +11462,28 @@ function EditToolDiffCard({ step, state, onComplete, input, output, isCollapsibl
11531
11462
  fileName
11532
11463
  ]
11533
11464
  }) : /* @__PURE__ */ jsxs("span", {
11534
- className: "truncate text-xs text-an-tool-color-muted",
11465
+ className: "truncate text-xs text-muted-foreground",
11535
11466
  children: [
11536
11467
  isWrite ? "Created" : "Edited",
11537
11468
  " ",
11538
11469
  step.filePath && onFilePathClick ? /* @__PURE__ */ jsx("button", {
11539
11470
  type: "button",
11540
11471
  onClick: () => onFilePathClick(step.filePath ?? ""),
11541
- className: "truncate underline-offset-2 hover:text-an-tool-color hover:underline",
11472
+ className: "truncate underline-offset-2 hover:text-foreground hover:underline",
11542
11473
  children: fileName
11543
11474
  }) : fileName
11544
11475
  ]
11545
11476
  })]
11546
11477
  }), step.diffStats && !isPending && /* @__PURE__ */ jsx("span", {
11547
- className: "inline-flex gap-2 font-mono text-[0.6875rem] text-an-tool-color-muted",
11478
+ className: "inline-flex gap-2 font-mono text-caption text-muted-foreground",
11548
11479
  children: step.diffStats.split(" ").map((token) => /* @__PURE__ */ jsx("span", {
11549
- className: token.startsWith("+") ? "text-an-diff-added-text" : token.startsWith("-") ? "text-an-diff-removed-text" : void 0,
11480
+ className: token.startsWith("+") ? "text-product-diff-added" : token.startsWith("-") ? "text-product-diff-removed" : void 0,
11550
11481
  children: token
11551
11482
  }, token))
11552
11483
  })]
11553
11484
  }),
11554
11485
  diffFiles ? /* @__PURE__ */ jsx("div", {
11555
- className: `${diffClassName} text-[0.75rem]`,
11486
+ className: `${diffClassName} text-label`,
11556
11487
  style: diffCssVars,
11557
11488
  children: /* @__PURE__ */ jsxs("div", {
11558
11489
  className: isCollapsible ? "group/edit-diff relative" : "relative",
@@ -11612,7 +11543,7 @@ function ToolRowBase({ icon, shimmerLabel, completeLabel, isAnimating, detail, o
11612
11543
  const isExpanded = expanded ?? false;
11613
11544
  const canToggle = expandable && (isComplete || isExpanded || isAnimating);
11614
11545
  const row = /* @__PURE__ */ jsxs("div", {
11615
- className: cn("flex max-w-full items-center gap-1 rounded-an-tool-border-radius select-none", canToggle ? "cursor-pointer" : "cursor-default"),
11546
+ className: cn("flex max-w-full items-center gap-1 rounded-chat-tool select-none", canToggle ? "cursor-pointer" : "cursor-default"),
11616
11547
  children: [/* @__PURE__ */ jsxs("div", {
11617
11548
  className: "flex min-w-0 items-center gap-2 text-sm text-muted-foreground",
11618
11549
  children: [
@@ -11632,10 +11563,10 @@ function ToolRowBase({ icon, shimmerLabel, completeLabel, isAnimating, detail, o
11632
11563
  detail && (onDetailClick ? /* @__PURE__ */ jsx("button", {
11633
11564
  type: "button",
11634
11565
  onClick: onDetailClick,
11635
- className: "min-w-0 flex-1 truncate text-left font-normal text-an-foreground-muted/60 underline-offset-2 hover:text-an-foreground-muted hover:underline",
11566
+ className: "min-w-0 flex-1 truncate text-left font-normal text-muted-foreground/60 underline-offset-2 hover:text-muted-foreground hover:underline",
11636
11567
  children: detail
11637
11568
  }) : /* @__PURE__ */ jsx("span", {
11638
- className: "min-w-0 flex-1 truncate font-normal text-an-foreground-muted/60",
11569
+ className: "min-w-0 flex-1 truncate font-normal text-muted-foreground/60",
11639
11570
  children: detail
11640
11571
  })),
11641
11572
  trailingContent
@@ -11674,6 +11605,64 @@ var GenericTool = memo(function GenericTool2({ icon, title, subtitle, isPending,
11674
11605
  onDetailClick: onSubtitleClick
11675
11606
  });
11676
11607
  });
11608
+ var toolStateCache = /* @__PURE__ */ new Map();
11609
+ function getToolStateSnapshot(part) {
11610
+ return {
11611
+ state: part.state,
11612
+ inputJson: JSON.stringify(part.input || {}),
11613
+ outputJson: JSON.stringify(part.output || {})
11614
+ };
11615
+ }
11616
+ function hasToolStateChanged(toolCallId, part) {
11617
+ const cached = toolStateCache.get(toolCallId);
11618
+ const current = getToolStateSnapshot(part);
11619
+ if (!cached) {
11620
+ toolStateCache.set(toolCallId, current);
11621
+ return true;
11622
+ }
11623
+ const changed = cached.state !== current.state || cached.inputJson !== current.inputJson || cached.outputJson !== current.outputJson;
11624
+ if (changed) toolStateCache.set(toolCallId, current);
11625
+ return changed;
11626
+ }
11627
+ function arePartsEqual(prev, next) {
11628
+ if (prev.toolCallId !== next.toolCallId) return false;
11629
+ if (prev.type !== next.type) return false;
11630
+ const toolCallId = next.toolCallId;
11631
+ if (!toolCallId) return prev.state === next.state;
11632
+ return !hasToolStateChanged(toolCallId, next);
11633
+ }
11634
+ function isToolCompleted(part) {
11635
+ if (part.output !== void 0 && part.output !== null) return true;
11636
+ if (part.state === "error") return true;
11637
+ if (part.state === "result") return true;
11638
+ return false;
11639
+ }
11640
+ function areToolPropsEqual(prevProps, nextProps) {
11641
+ if (!arePartsEqual(prevProps.part, nextProps.part)) return false;
11642
+ if (isToolCompleted(nextProps.part)) return true;
11643
+ if (prevProps.chatStatus !== nextProps.chatStatus) return false;
11644
+ return true;
11645
+ }
11646
+ function formatElapsedTime(ms) {
11647
+ if (ms < 1e3) return "";
11648
+ const seconds = Math.floor(ms / 1e3);
11649
+ if (seconds < 60) return `${seconds}s`;
11650
+ const minutes = Math.floor(seconds / 60);
11651
+ const remainingSeconds = seconds % 60;
11652
+ if (remainingSeconds === 0) return `${minutes}m`;
11653
+ return `${minutes}m ${remainingSeconds}s`;
11654
+ }
11655
+ function getToolStatus(part, chatStatus) {
11656
+ const basePending = part.state !== "output-available" && part.state !== "output-error";
11657
+ const isError = part.state === "output-error" || part.state === "output-available" && part.output?.success === false;
11658
+ const isSuccess = part.state === "output-available" && !isError;
11659
+ return {
11660
+ isPending: basePending && chatStatus === "streaming",
11661
+ isError,
11662
+ isSuccess,
11663
+ isInterrupted: basePending && chatStatus !== "streaming" && chatStatus !== void 0
11664
+ };
11665
+ }
11677
11666
  var PRIORITY_ARGS = [
11678
11667
  "query",
11679
11668
  "question",
@@ -11829,7 +11818,7 @@ ${displayOutput}
11829
11818
  }, [displayOutput]);
11830
11819
  const hasExpandableContent = !!codeBlock && !isPending;
11831
11820
  if (isInterrupted && !part.output) return /* @__PURE__ */ jsxs("span", {
11832
- className: "text-sm text-an-tool-color-muted",
11821
+ className: "text-sm text-muted-foreground",
11833
11822
  children: [mcpInfo.displayName, " interrupted"]
11834
11823
  });
11835
11824
  return /* @__PURE__ */ jsx("div", {
@@ -11843,7 +11832,7 @@ ${displayOutput}
11843
11832
  expandable: hasExpandableContent,
11844
11833
  defaultOpen,
11845
11834
  children: codeBlock && /* @__PURE__ */ jsx(LazyMarkdown, {
11846
- className: "text-[0.75rem]",
11835
+ className: "text-label",
11847
11836
  codeControls: false,
11848
11837
  content: codeBlock
11849
11838
  })
@@ -11876,42 +11865,6 @@ function IconSpinner({ className, ...rest }) {
11876
11865
  })]
11877
11866
  });
11878
11867
  }
11879
- function CheckIcon(props) {
11880
- return /* @__PURE__ */ jsx("svg", {
11881
- xmlns: "http://www.w3.org/2000/svg",
11882
- viewBox: "0 0 24 24",
11883
- fill: "none",
11884
- ...props,
11885
- children: /* @__PURE__ */ jsx("path", {
11886
- d: "M5 12.75L10 19L19 5",
11887
- stroke: "currentColor",
11888
- strokeWidth: "2",
11889
- strokeLinecap: "round",
11890
- strokeLinejoin: "round"
11891
- })
11892
- });
11893
- }
11894
- function IconArrowRight(props) {
11895
- return /* @__PURE__ */ jsxs("svg", {
11896
- viewBox: "0 0 24 24",
11897
- fill: "none",
11898
- width: "24",
11899
- height: "24",
11900
- ...props,
11901
- children: [/* @__PURE__ */ jsx("path", {
11902
- d: "M14 6L20 12L14 18",
11903
- stroke: "currentColor",
11904
- strokeWidth: "2",
11905
- strokeLinecap: "round",
11906
- strokeLinejoin: "round"
11907
- }), /* @__PURE__ */ jsx("path", {
11908
- d: "M19 12H4",
11909
- stroke: "currentColor",
11910
- strokeWidth: "2",
11911
- strokeLinecap: "round"
11912
- })]
11913
- });
11914
- }
11915
11868
  function getPlanFileName(plan) {
11916
11869
  const rawId = plan.id?.trim();
11917
11870
  if (!rawId) return "plan-working.md";
@@ -11951,20 +11904,20 @@ var PlanTool = memo(function PlanTool2({ part, chatStatus }) {
11951
11904
  };
11952
11905
  const actionLabel = total > 0 ? `${completed}/${total} complete` : pendingDecision ? "Awaiting review" : void 0;
11953
11906
  return /* @__PURE__ */ jsxs("div", {
11954
- className: "an-tool-plan overflow-hidden rounded-an-tool-border-radius border border-border bg-an-tool-background",
11907
+ className: "an-tool-plan overflow-hidden rounded-chat-tool border border-border bg-muted",
11955
11908
  children: [/* @__PURE__ */ jsxs("div", {
11956
11909
  className: "flex h-7 items-center justify-between pr-2.5 pl-3",
11957
11910
  children: [/* @__PURE__ */ jsxs("div", {
11958
11911
  className: "flex min-w-0 items-center gap-1",
11959
- children: [isPending ? /* @__PURE__ */ jsx(IconSpinner, { className: "h-3 w-3 shrink-0 animate-spin text-an-tool-color-muted" }) : /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5 shrink-0 text-an-tool-color-muted" }), /* @__PURE__ */ jsx("span", {
11960
- className: "truncate text-xs text-an-tool-color-muted",
11912
+ children: [isPending ? /* @__PURE__ */ jsx(IconSpinner, { className: "h-3 w-3 shrink-0 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), /* @__PURE__ */ jsx("span", {
11913
+ className: "truncate text-xs text-muted-foreground",
11961
11914
  children: fileName
11962
11915
  })]
11963
11916
  }), /* @__PURE__ */ jsx("button", {
11964
11917
  type: "button",
11965
11918
  onClick: () => setIsExpanded((prev) => !prev),
11966
11919
  "aria-label": isExpanded ? "Collapse plan" : "Expand plan",
11967
- className: "inline-flex size-5 items-center justify-center text-an-tool-color-muted",
11920
+ className: "inline-flex size-5 items-center justify-center text-muted-foreground",
11968
11921
  children: isExpanded ? /* @__PURE__ */ jsx(ChevronsUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronsDown, { className: "h-3.5 w-3.5" })
11969
11922
  })]
11970
11923
  }), /* @__PURE__ */ jsxs("div", {
@@ -11975,16 +11928,16 @@ var PlanTool = memo(function PlanTool2({ part, chatStatus }) {
11975
11928
  children: [/* @__PURE__ */ jsxs("div", {
11976
11929
  className: "flex items-center justify-between gap-2 px-3",
11977
11930
  children: [/* @__PURE__ */ jsx("div", {
11978
- className: "text-sm text-an-tool-color",
11931
+ className: "text-sm text-foreground",
11979
11932
  children: plan.title
11980
11933
  }), actionLabel ? /* @__PURE__ */ jsx("div", {
11981
- className: "rounded-full border border-border px-2 py-0.5 text-[0.6875rem] text-an-tool-color-muted",
11934
+ className: "rounded-full border border-border px-2 py-0.5 text-caption text-muted-foreground",
11982
11935
  children: actionLabel
11983
11936
  }) : null]
11984
11937
  }), hasSummary ? /* @__PURE__ */ jsxs("div", {
11985
11938
  className: "relative",
11986
11939
  children: [/* @__PURE__ */ jsx("div", {
11987
- className: cn("px-3", "text-sm text-an-tool-color-muted", !isExpanded && "max-h-[94px] overflow-hidden"),
11940
+ className: cn("px-3", "text-sm text-muted-foreground", !isExpanded && "max-h-[94px] overflow-hidden"),
11988
11941
  children: /* @__PURE__ */ jsx(LazyMarkdown, {
11989
11942
  content: summary,
11990
11943
  className: "text-sm"
@@ -11996,33 +11949,33 @@ var PlanTool = memo(function PlanTool2({ part, chatStatus }) {
11996
11949
  children: /* @__PURE__ */ jsx("button", {
11997
11950
  type: "button",
11998
11951
  onClick: () => setIsExpanded(true),
11999
- className: "-mx-2 h-5 rounded-[4px] px-1.5 text-xs text-muted-foreground hover:text-an-tool-color",
11952
+ className: "-mx-2 h-5 rounded-[4px] px-1.5 text-xs text-muted-foreground hover:text-foreground",
12000
11953
  children: "Read detailed plan"
12001
11954
  })
12002
11955
  })]
12003
11956
  })]
12004
11957
  }) : /* @__PURE__ */ jsx("div", {
12005
- className: "text-xs text-an-tool-color-muted",
11958
+ className: "text-xs text-muted-foreground",
12006
11959
  children: "No plan summary provided."
12007
11960
  })]
12008
11961
  }),
12009
11962
  (isExpanded || !hasSummary) && /* @__PURE__ */ jsxs("div", {
12010
- className: "mt-2 flex items-center justify-between border-t border-border bg-an-tool-background pt-1.5 pr-2 pb-2 pl-3.5",
11963
+ className: "mt-2 flex items-center justify-between border-t border-border bg-muted pt-1.5 pr-2 pb-2 pl-3.5",
12011
11964
  children: [/* @__PURE__ */ jsx("button", {
12012
11965
  type: "button",
12013
11966
  onClick: () => setIsExpanded((prev) => !prev),
12014
- className: "-mx-2 h-5 rounded-[4px] px-1.5 text-xs text-muted-foreground hover:text-an-tool-color",
11967
+ className: "-mx-2 h-5 rounded-[4px] px-1.5 text-xs text-muted-foreground hover:text-foreground",
12015
11968
  children: isExpanded ? "Hide detailed plan" : "Read detailed plan"
12016
11969
  }), canAct ? /* @__PURE__ */ jsx("div", {
12017
- className: "text-[0.6875rem] text-an-tool-color-muted",
11970
+ className: "text-caption text-muted-foreground",
12018
11971
  children: "Choose what to do with this plan."
12019
11972
  }) : isAlreadyApproved ? /* @__PURE__ */ jsx("div", {
12020
- className: "text-[0.6875rem] text-an-tool-color-muted",
11973
+ className: "text-caption text-muted-foreground",
12021
11974
  children: "Approved"
12022
11975
  }) : null]
12023
11976
  }),
12024
11977
  canAct ? /* @__PURE__ */ jsxs("div", {
12025
- className: "flex flex-col gap-2 border-t border-border bg-an-tool-background px-3 py-2.5",
11978
+ className: "flex flex-col gap-2 border-t border-border bg-muted px-3 py-2.5",
12026
11979
  children: [/* @__PURE__ */ jsxs("div", {
12027
11980
  className: "flex flex-wrap gap-2",
12028
11981
  children: [
@@ -12030,21 +11983,21 @@ var PlanTool = memo(function PlanTool2({ part, chatStatus }) {
12030
11983
  type: "button",
12031
11984
  onClick: () => runAction("execute", part.input?.onExecute),
12032
11985
  disabled: Boolean(isActing),
12033
- className: "h-7 rounded-[6px] bg-an-primary-color px-2.5 text-xs font-medium text-an-send-button-color disabled:opacity-60",
11986
+ className: "h-7 rounded-[6px] bg-primary px-2.5 text-xs font-medium text-primary-foreground disabled:opacity-60",
12034
11987
  children: isActing === "execute" ? "Executing..." : part.input?.executeLabel ?? "Execute"
12035
11988
  }),
12036
11989
  /* @__PURE__ */ jsx("button", {
12037
11990
  type: "button",
12038
11991
  onClick: () => runAction("stay", part.input?.onStay),
12039
11992
  disabled: Boolean(isActing),
12040
- className: "h-7 rounded-[6px] border border-border px-2.5 text-xs text-an-tool-color disabled:opacity-60",
11993
+ className: "h-7 rounded-[6px] border border-border px-2.5 text-xs text-foreground disabled:opacity-60",
12041
11994
  children: isActing === "stay" ? "Saving..." : part.input?.stayLabel ?? "Stay"
12042
11995
  }),
12043
11996
  /* @__PURE__ */ jsx("button", {
12044
11997
  type: "button",
12045
11998
  onClick: () => setIsRefining((prev) => !prev),
12046
11999
  disabled: Boolean(isActing),
12047
- className: "h-7 rounded-[6px] border border-border px-2.5 text-xs text-an-tool-color disabled:opacity-60",
12000
+ className: "h-7 rounded-[6px] border border-border px-2.5 text-xs text-foreground disabled:opacity-60",
12048
12001
  children: part.input?.refineLabel ?? "Refine"
12049
12002
  })
12050
12003
  ]
@@ -12055,7 +12008,7 @@ var PlanTool = memo(function PlanTool2({ part, chatStatus }) {
12055
12008
  onChange: (event) => setRefineText(event.target.value),
12056
12009
  rows: 3,
12057
12010
  placeholder: "Describe what should change in the plan",
12058
- className: "w-full resize-y rounded-[8px] border border-border bg-background px-3 py-2 text-base text-an-tool-color outline-none focus:border-an-primary-color md:text-sm"
12011
+ className: "w-full resize-y rounded-[8px] border border-border bg-background px-3 py-2 text-base text-foreground outline-none focus:border-primary md:text-sm"
12059
12012
  }), /* @__PURE__ */ jsxs("div", {
12060
12013
  className: "flex items-center justify-end gap-2",
12061
12014
  children: [/* @__PURE__ */ jsx("button", {
@@ -12065,13 +12018,13 @@ var PlanTool = memo(function PlanTool2({ part, chatStatus }) {
12065
12018
  setRefineText("");
12066
12019
  },
12067
12020
  disabled: Boolean(isActing),
12068
- className: "h-7 rounded-[6px] border border-border px-2.5 text-xs text-an-tool-color disabled:opacity-60",
12021
+ className: "h-7 rounded-[6px] border border-border px-2.5 text-xs text-foreground disabled:opacity-60",
12069
12022
  children: "Cancel"
12070
12023
  }), /* @__PURE__ */ jsx("button", {
12071
12024
  type: "button",
12072
12025
  onClick: () => runAction("refine", part.input?.onRefine, refineText),
12073
12026
  disabled: Boolean(isActing),
12074
- className: "h-7 rounded-[6px] bg-an-primary-color px-2.5 text-xs font-medium text-an-send-button-color disabled:opacity-60",
12027
+ className: "h-7 rounded-[6px] bg-primary px-2.5 text-xs font-medium text-primary-foreground disabled:opacity-60",
12075
12028
  children: isActing === "refine" ? "Submitting..." : "Submit refinement"
12076
12029
  })]
12077
12030
  })]
@@ -12097,9 +12050,9 @@ function SearchGroupRich({ toolSteps, stepStates, onStepComplete, results = [],
12097
12050
  expandable: hasExpandableContent,
12098
12051
  defaultOpen,
12099
12052
  children: /* @__PURE__ */ jsxs("div", {
12100
- className: "overflow-hidden rounded-an-tool-border-radius border border-border bg-an-tool-background",
12053
+ className: "overflow-hidden rounded-chat-tool border border-border bg-muted",
12101
12054
  children: [/* @__PURE__ */ jsxs("div", {
12102
- className: "flex h-7 items-center gap-1 border-b border-an-tool-border-color px-2.5 py-0 text-xs",
12055
+ className: "flex h-7 items-center gap-1 border-b border-border px-2.5 py-0 text-xs",
12103
12056
  children: [
12104
12057
  /* @__PURE__ */ jsx("span", {
12105
12058
  className: "font-medium text-foreground",
@@ -12120,7 +12073,7 @@ function SearchGroupRich({ toolSteps, stepStates, onStepComplete, results = [],
12120
12073
  children: /* @__PURE__ */ jsx("div", {
12121
12074
  className: "flex flex-col gap-1 p-1",
12122
12075
  children: results.map((result) => /* @__PURE__ */ jsxs("div", {
12123
- className: cn("flex cursor-default items-center gap-2 rounded-[calc(var(--an-tool-border-radius)-4px)] px-2 py-1", "hover:bg-muted/50"),
12076
+ className: cn("flex cursor-default items-center gap-2 rounded-[calc(var(--chat-tool-radius)-4px)] px-2 py-1", "hover:bg-muted/50"),
12124
12077
  children: [
12125
12078
  /* @__PURE__ */ jsx("div", {
12126
12079
  className: "flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground",
@@ -12171,1477 +12124,1364 @@ var SearchTool = memo(function SearchTool2({ part, results, defaultOpen }) {
12171
12124
  defaultOpen
12172
12125
  });
12173
12126
  });
12174
- function ThinkingCollapsed({ step, state, onComplete, defaultOpen, expanded, onToggleExpand }) {
12175
- useToolComplete(state === "animating", step.duration, onComplete);
12176
- return /* @__PURE__ */ jsx(ToolRowBase, {
12177
- shimmerLabel: "Thinking",
12178
- completeLabel: "Thought",
12179
- isAnimating: state === "animating",
12180
- expandable: !!step.thoughtContent,
12181
- defaultOpen,
12182
- expanded,
12183
- onToggleExpand,
12184
- children: /* @__PURE__ */ jsx("div", {
12185
- className: "max-h-[175px] overflow-y-auto",
12186
- children: /* @__PURE__ */ jsx("p", {
12187
- className: "text-sm whitespace-pre-wrap text-muted-foreground",
12188
- children: step.thoughtContent
12189
- })
12127
+ function statusLabel(status) {
12128
+ if (status === "in-progress") return "In progress";
12129
+ if (status === "completed") return "Completed";
12130
+ if (status === "cancelled") return "Cancelled";
12131
+ return "Pending";
12132
+ }
12133
+ function TodoHeaderIcon({ complete }) {
12134
+ const reduce = useReducedMotion() ?? false;
12135
+ return /* @__PURE__ */ jsx("span", {
12136
+ "aria-hidden": "true",
12137
+ className: "relative grid size-6 shrink-0 place-items-center",
12138
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
12139
+ initial: false,
12140
+ mode: "popLayout",
12141
+ children: complete ? /* @__PURE__ */ jsxs(m.svg, {
12142
+ viewBox: "0 0 24 24",
12143
+ initial: reduce ? { opacity: 1 } : {
12144
+ opacity: 0,
12145
+ scale: 0.72
12146
+ },
12147
+ animate: {
12148
+ opacity: 1,
12149
+ scale: 1
12150
+ },
12151
+ exit: { opacity: 0 },
12152
+ transition: reduce ? { duration: 0 } : SPRING_SWAP,
12153
+ className: "absolute size-5.5 overflow-visible text-emerald-500",
12154
+ children: [/* @__PURE__ */ jsx("circle", {
12155
+ cx: "12",
12156
+ cy: "12",
12157
+ r: "9",
12158
+ fill: "currentColor"
12159
+ }), /* @__PURE__ */ jsx(m.path, {
12160
+ d: "M7.5 12.25 10.5 15.25 16.75 8.75",
12161
+ fill: "none",
12162
+ stroke: "white",
12163
+ strokeWidth: "2.25",
12164
+ strokeLinecap: "round",
12165
+ strokeLinejoin: "round",
12166
+ initial: reduce ? { pathLength: 1 } : { pathLength: 0 },
12167
+ animate: { pathLength: 1 },
12168
+ transition: reduce ? { duration: 0 } : {
12169
+ duration: 0.24,
12170
+ ease: EASE_OUT
12171
+ }
12172
+ })]
12173
+ }, "complete") : /* @__PURE__ */ jsx(m.span, {
12174
+ initial: reduce ? { opacity: 1 } : {
12175
+ opacity: 0,
12176
+ scale: 0.8
12177
+ },
12178
+ animate: {
12179
+ opacity: 1,
12180
+ scale: 1
12181
+ },
12182
+ exit: reduce ? { opacity: 0 } : {
12183
+ opacity: 0,
12184
+ scale: 0.72
12185
+ },
12186
+ transition: reduce ? { duration: 0 } : SPRING_SWAP,
12187
+ className: "absolute grid place-items-center text-muted-foreground",
12188
+ children: /* @__PURE__ */ jsx(ListTodo, { className: "size-4" })
12189
+ }, "todo")
12190
12190
  })
12191
12191
  });
12192
12192
  }
12193
- var ThinkingTool = memo(function ThinkingTool2({ part, step: externalStep, state: externalState, onComplete: externalOnComplete, defaultOpen, expanded, onToggleExpand }) {
12194
- let step;
12195
- let stepState;
12196
- let onComplete;
12197
- if (externalStep && externalState && externalOnComplete) {
12198
- step = externalStep;
12199
- stepState = externalState;
12200
- onComplete = externalOnComplete;
12201
- } else if (part) {
12202
- const adapted = adaptToolPart(part, "Thinking");
12203
- step = adapted.step;
12204
- stepState = adapted.stepState;
12205
- onComplete = () => {
12206
- };
12207
- } else return null;
12208
- return /* @__PURE__ */ jsx(ThinkingCollapsed, {
12209
- step,
12210
- state: stepState,
12211
- onComplete,
12212
- defaultOpen,
12213
- expanded,
12214
- onToggleExpand
12215
- });
12216
- });
12217
- function detectChanges(oldTodos, newTodos) {
12218
- if (!oldTodos || oldTodos.length === 0) return {
12219
- type: "creation",
12220
- items: newTodos.map((todo, index) => ({
12221
- todo,
12222
- newStatus: todo.status,
12223
- index
12224
- }))
12225
- };
12226
- const changes = [];
12227
- newTodos.forEach((newTodo, index) => {
12228
- const oldTodo = oldTodos[index];
12229
- if (!oldTodo || oldTodo.status !== newTodo.status) changes.push({
12230
- todo: newTodo,
12231
- oldStatus: oldTodo?.status,
12232
- newStatus: newTodo.status,
12233
- index
12234
- });
12235
- });
12236
- if (changes.length === 1) return {
12237
- type: "single",
12238
- items: changes
12239
- };
12240
- return {
12241
- type: "multiple",
12242
- items: changes
12243
- };
12244
- }
12245
- var TodoStatusIcon$1 = ({ status, isPending }) => {
12246
- if (isPending && status === "in_progress") return /* @__PURE__ */ jsx("div", {
12247
- className: "flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full border border-an-foreground-muted/60",
12248
- children: /* @__PURE__ */ jsx(IconArrowRight, { className: "h-2 w-2 text-an-foreground-muted/70" })
12249
- });
12250
- switch (status) {
12251
- case "completed":
12252
- return /* @__PURE__ */ jsx("div", {
12253
- className: "flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full border border-an-foreground-muted/40",
12254
- children: /* @__PURE__ */ jsx(CheckIcon, { className: "h-2 w-2 text-an-foreground-muted/70" })
12255
- });
12256
- case "in_progress":
12257
- return /* @__PURE__ */ jsx("div", {
12258
- className: "flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full border border-an-foreground-muted/60",
12259
- children: /* @__PURE__ */ jsx(IconArrowRight, { className: "h-2 w-2 text-an-foreground-muted/70" })
12260
- });
12261
- default:
12262
- return /* @__PURE__ */ jsx("div", { className: "flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full border border-an-foreground-muted/60" });
12263
- }
12264
- };
12265
- var TodoListItem = memo(function TodoListItem2({ todo, isPending }) {
12266
- return /* @__PURE__ */ jsxs("div", {
12267
- className: cn("flex items-start gap-2"),
12268
- children: [/* @__PURE__ */ jsx("div", {
12269
- className: "mt-[2px]",
12270
- children: /* @__PURE__ */ jsx(TodoStatusIcon$1, {
12271
- status: todo.status,
12272
- isPending
12273
- })
12274
- }), /* @__PURE__ */ jsx("span", {
12275
- className: cn("text-sm", todo.status === "completed" && "line-through", isPending || todo.status === "completed" || todo.status === "pending" ? "text-an-foreground/60" : "text-an-foreground/80"),
12276
- children: todo.content
12277
- })]
12278
- });
12279
- });
12280
- var TodoTool = memo(function TodoTool2({ part, chatStatus }) {
12281
- const { isPending } = getToolStatus(part, chatStatus);
12282
- const isStreaming = part.state === "input-streaming";
12283
- const oldTodos = part.output?.oldTodos || [];
12284
- const newTodos = part.input?.todos || part.output?.newTodos || [];
12285
- const isCreation = oldTodos.length === 0;
12286
- const changes = useMemo(() => detectChanges(oldTodos, newTodos), [oldTodos, newTodos]);
12287
- if (isStreaming || newTodos.length === 0) return /* @__PURE__ */ jsx("div", {
12288
- className: "flex flex-col gap-2 text-sm leading-relaxed text-an-foreground/80",
12289
- children: /* @__PURE__ */ jsx("div", {
12290
- className: "text-an-foreground/60",
12291
- children: /* @__PURE__ */ jsx(ToolTextShimmer, {
12292
- as: "span",
12293
- duration: 1.2,
12294
- className: "m-0 inline-flex h-4 items-center text-sm leading-none",
12295
- children: isCreation ? "Creating to-do list..." : "Updating to-dos..."
12296
- })
12297
- })
12298
- });
12299
- if (changes.type === "single") return /* @__PURE__ */ jsx("div", {
12300
- className: "flex flex-col gap-2 text-sm leading-relaxed text-an-foreground/80",
12301
- children: newTodos.map((todo) => /* @__PURE__ */ jsx(TodoListItem, {
12302
- todo,
12303
- isPending
12304
- }, todo.content))
12305
- });
12306
- if (changes.type === "multiple") return /* @__PURE__ */ jsx("div", {
12307
- className: "flex flex-col gap-2 text-sm leading-relaxed text-an-foreground/80",
12308
- children: newTodos.map((todo) => /* @__PURE__ */ jsx(TodoListItem, {
12309
- todo,
12310
- isPending
12311
- }, todo.content))
12312
- });
12313
- return /* @__PURE__ */ jsx("div", {
12314
- className: "flex flex-col gap-2 text-sm leading-relaxed text-an-foreground/80",
12315
- children: newTodos.map((todo) => /* @__PURE__ */ jsx(TodoListItem, {
12316
- todo,
12317
- isPending
12318
- }, todo.content))
12319
- });
12320
- }, areToolPropsEqual);
12321
- function useElapsedTime(startedAt, isPending) {
12322
- const [elapsedMs, setElapsedMs] = useState(0);
12323
- useEffect(() => {
12324
- if (isPending && startedAt) {
12325
- setElapsedMs(Date.now() - startedAt);
12326
- const interval = setInterval(() => {
12327
- setElapsedMs(Date.now() - startedAt);
12328
- }, 1e3);
12329
- return () => clearInterval(interval);
12330
- }
12331
- }, [isPending, startedAt]);
12332
- return elapsedMs;
12333
- }
12334
- function getDisplayPath(filePath) {
12335
- if (!filePath) return "";
12336
- const stripped = stripSandboxPrefixes(filePath);
12337
- if (stripped !== filePath) return stripped;
12338
- if (filePath.startsWith("/")) {
12339
- const parts = filePath.split("/");
12340
- const rootIndicators = [
12341
- "apps",
12342
- "packages",
12343
- "src",
12344
- "lib",
12345
- "components"
12346
- ];
12347
- const rootIndex = parts.findIndex((p) => rootIndicators.includes(p));
12348
- if (rootIndex > 0) return parts.slice(rootIndex).join("/");
12349
- }
12350
- return filePath;
12351
- }
12352
- function calculateDiffStats(oldString, newString) {
12353
- const oldLines = oldString.split("\n");
12354
- const newLines = newString.split("\n");
12355
- const maxLines = Math.max(oldLines.length, newLines.length);
12356
- let addedLines = 0;
12357
- let removedLines = 0;
12358
- for (let i = 0; i < maxLines; i++) if (oldLines[i] !== void 0 && newLines[i] !== void 0) {
12359
- if (oldLines[i] !== newLines[i]) {
12360
- removedLines++;
12361
- addedLines++;
12362
- }
12363
- } else if (oldLines[i] !== void 0) removedLines++;
12364
- else if (newLines[i] !== void 0) addedLines++;
12365
- return {
12366
- addedLines,
12367
- removedLines
12368
- };
12369
- }
12370
- var toolRegistry = {
12371
- "tool-Task": {
12372
- icon: Sparkles,
12373
- title: (part) => {
12374
- const isPending = part.state !== "output-available" && part.state !== "output-error";
12375
- const subagentType = part.input?.subagent_type || "Agent";
12376
- return isPending ? `Running ${subagentType}` : `${subagentType} completed`;
12377
- },
12378
- subtitle: (part) => {
12379
- const desc = part.input?.description || "";
12380
- return desc.length > 50 ? `${desc.slice(0, 47)}...` : desc;
12381
- },
12382
- variant: "simple"
12383
- },
12384
- "tool-Agent": {
12385
- icon: Sparkles,
12386
- title: (part) => {
12387
- const isPending = part.state !== "output-available" && part.state !== "output-error";
12388
- const subagentType = part.input?.subagent_type || "Agent";
12389
- return isPending ? `Running ${subagentType}` : `${subagentType} completed`;
12390
- },
12391
- subtitle: (part) => {
12392
- const desc = part.input?.description || "";
12393
- return desc.length > 50 ? `${desc.slice(0, 47)}...` : desc;
12394
- },
12395
- variant: "simple"
12396
- },
12397
- "tool-Skill": {
12398
- icon: Sparkles,
12399
- title: () => "Skill",
12400
- subtitle: (part) => part.input?.skill || "",
12401
- variant: "simple"
12402
- },
12403
- "tool-Grep": {
12404
- icon: Search,
12405
- title: (part) => {
12406
- if (part.state !== "output-available" && part.state !== "output-error") return "Grepping";
12407
- const numFiles = part.output?.numFiles || 0;
12408
- return numFiles > 0 ? `Grepped ${numFiles} files` : "No matches";
12409
- },
12410
- subtitle: (part) => {
12411
- const pattern = part.input?.pattern || "";
12412
- const path = part.input?.path || "";
12413
- if (path) {
12414
- const combined = `${pattern} in ${getDisplayPath(path)}`;
12415
- return combined.length > 40 ? `${combined.slice(0, 37)}...` : combined;
12416
- }
12417
- return pattern.length > 40 ? `${pattern.slice(0, 37)}...` : pattern;
12418
- },
12419
- variant: "simple"
12420
- },
12421
- "tool-Glob": {
12422
- icon: FolderSearch,
12423
- title: (part) => {
12424
- if (part.state !== "output-available" && part.state !== "output-error") return "Exploring files";
12425
- const numFiles = part.output?.numFiles || 0;
12426
- return numFiles > 0 ? `Found ${numFiles} files` : "No files found";
12427
- },
12428
- subtitle: (part) => {
12429
- const pattern = part.input?.pattern || "";
12430
- return pattern.length > 40 ? `${pattern.slice(0, 37)}...` : pattern;
12431
- },
12432
- variant: "simple"
12433
- },
12434
- "tool-Read": {
12435
- icon: Eye,
12436
- title: (part) => {
12437
- return part.state !== "output-available" && part.state !== "output-error" ? "Reading" : "Read";
12438
- },
12439
- subtitle: (part) => {
12440
- const filePath = part.input?.file_path || "";
12441
- if (!filePath) return "";
12442
- return filePath.split("/").pop() || "";
12443
- },
12444
- variant: "simple"
12445
- },
12446
- "tool-Edit": {
12447
- icon: FileCodeCorner,
12448
- title: (part) => {
12449
- const filePath = part.input?.file_path || "";
12450
- if (!filePath) return "Edit";
12451
- return filePath.split("/").pop() || "Edit";
12452
- },
12453
- subtitle: (part) => {
12454
- if (part.state !== "output-available" && part.state !== "output-error") return "";
12455
- const oldString = part.input?.old_string || "";
12456
- const newString = part.input?.new_string || "";
12457
- if (!oldString && !newString) return "";
12458
- if (oldString !== newString) {
12459
- const { addedLines, removedLines } = calculateDiffStats(oldString, newString);
12460
- return `+${addedLines} -${removedLines}`;
12461
- }
12462
- return "";
12463
- },
12464
- variant: "simple"
12465
- },
12466
- "tool-Write": {
12467
- icon: FilePlus,
12468
- title: () => "Create",
12469
- subtitle: (part) => {
12470
- const filePath = part.input?.file_path || "";
12471
- if (!filePath) return "";
12472
- return filePath.split("/").pop() || "";
12473
- },
12474
- variant: "simple"
12475
- },
12476
- "tool-Bash": {
12477
- icon: Terminal,
12478
- title: (part) => {
12479
- return part.state !== "output-available" && part.state !== "output-error" ? "Running command" : "Ran command";
12480
- },
12481
- subtitle: (part) => {
12482
- const command = part.input?.command || "";
12483
- if (!command) return "";
12484
- let normalized = command.replace(/\\\s*\n\s*/g, " ").trim();
12485
- normalized = normalized.replace(/\/(?:Users|home|root)\/[^\s"']+/g, (match) => getDisplayPath(match));
12486
- return normalized.length > 50 ? `${normalized.slice(0, 47)}...` : normalized;
12487
- },
12488
- variant: "simple"
12489
- },
12490
- "tool-IPython": {
12491
- icon: FileCodeCorner,
12492
- title: (part) => {
12493
- return part.state !== "output-available" && part.state !== "output-error" ? "Running cell" : "Ran cell";
12494
- },
12495
- subtitle: (part) => {
12496
- const code = part.input?.code || "";
12497
- if (!code) return "";
12498
- const firstLine = code.split("\n", 1)[0].trim();
12499
- return firstLine.length > 50 ? `${firstLine.slice(0, 47)}...` : firstLine;
12500
- },
12501
- variant: "simple"
12502
- },
12503
- "tool-WebFetch": {
12504
- icon: Globe,
12505
- title: (part) => {
12506
- return part.state !== "output-available" && part.state !== "output-error" ? "Fetching" : "Fetched";
12507
- },
12508
- subtitle: (part) => {
12509
- const url = part.input?.url || "";
12510
- try {
12511
- return new URL(url).hostname.replace("www.", "");
12512
- } catch {
12513
- return url.slice(0, 30);
12514
- }
12515
- },
12516
- variant: "simple"
12517
- },
12518
- "tool-WebSearch": {
12519
- icon: Search,
12520
- title: (part) => {
12521
- return part.state !== "output-available" && part.state !== "output-error" ? "Searching web" : "Searched web";
12522
- },
12523
- subtitle: (part) => {
12524
- const query = part.input?.query || "";
12525
- return query.length > 40 ? `${query.slice(0, 37)}...` : query;
12526
- },
12527
- variant: "collapsible"
12528
- },
12529
- "tool-TodoWrite": {
12530
- icon: ListTodo,
12531
- title: (part) => {
12532
- const isPending = part.state !== "output-available" && part.state !== "output-error";
12533
- const action = part.input?.action || "update";
12534
- if (isPending) return action === "add" ? "Adding todo" : "Updating todos";
12535
- return action === "add" ? "Added todo" : "Updated todos";
12536
- },
12537
- subtitle: (part) => {
12538
- const todos = part.input?.todos || [];
12539
- if (todos.length === 0) return "";
12540
- return `${todos.length} ${todos.length === 1 ? "item" : "items"}`;
12541
- },
12542
- variant: "simple"
12543
- },
12544
- "tool-PlanWrite": {
12545
- icon: Sparkles,
12546
- title: (part) => {
12547
- const isPending = part.state !== "output-available" && part.state !== "output-error";
12548
- const action = part.input?.action || "create";
12549
- if (isPending) {
12550
- if (action === "create") return "Creating plan";
12551
- if (action === "approve") return "Approving plan";
12552
- return "Updating plan";
12553
- }
12554
- const status = part.input?.plan?.status;
12555
- if (status === "awaiting_approval") return "Plan ready for review";
12556
- if (status === "approved") return "Plan approved";
12557
- if (status === "completed") return "Plan completed";
12558
- return action === "create" ? "Created plan" : "Updated plan";
12559
- },
12560
- variant: "simple"
12561
- },
12562
- "tool-ExitPlanMode": {
12563
- icon: LogOut,
12564
- title: (part) => {
12565
- return part.state !== "output-available" && part.state !== "output-error" ? "Finishing plan" : "Plan complete";
12566
- },
12567
- variant: "simple"
12568
- },
12569
- "tool-NotebookEdit": {
12570
- icon: FileCodeCorner,
12571
- title: (part) => {
12572
- return part.state !== "output-available" && part.state !== "output-error" ? "Editing notebook" : "Edited notebook";
12573
- },
12574
- subtitle: (part) => {
12575
- const filePath = part.input?.file_path || "";
12576
- if (!filePath) return "";
12577
- return filePath.split("/").pop() || "";
12578
- },
12579
- variant: "simple"
12580
- },
12581
- "tool-BashOutput": {
12582
- icon: Terminal,
12583
- title: (part) => {
12584
- return part.state !== "output-available" && part.state !== "output-error" ? "Getting output" : "Command output";
12585
- },
12586
- subtitle: (part) => {
12587
- const output = part.output;
12588
- if (typeof output === "string" && output.trim()) return output.trim();
12589
- const command = part.input?.command || "";
12590
- if (!command) return "";
12591
- let normalized = command.replace(/\\\s*\n\s*/g, " ").trim();
12592
- normalized = normalized.replace(/\/(?:Users|home|root)\/[^\s"']+/g, (match) => getDisplayPath(match));
12593
- return normalized.length > 50 ? `${normalized.slice(0, 47)}...` : normalized;
12594
- },
12595
- variant: "simple"
12596
- },
12597
- "tool-KillShell": {
12598
- icon: CircleX,
12599
- title: (part) => {
12600
- return part.state !== "output-available" && part.state !== "output-error" ? "Stopping shell" : "Shell stopped";
12601
- },
12602
- subtitle: (part) => {
12603
- const pid = part.input?.pid;
12604
- return typeof pid === "number" ? `pid ${pid}` : "";
12605
- },
12606
- variant: "simple"
12607
- },
12608
- "tool-cloning": {
12609
- icon: GitBranch,
12610
- title: (part) => {
12611
- return part.state !== "output-available" && part.state !== "output-error" ? "Cloning repo" : "Repo cloned";
12612
- },
12613
- subtitle: (part) => part.input?.repo ?? "",
12614
- variant: "simple"
12615
- },
12616
- "tool-Thinking": {
12617
- icon: Sparkles,
12618
- title: (part) => {
12619
- return part.state !== "output-available" && part.state !== "output-error" ? "Thinking..." : "Thought";
12620
- },
12621
- variant: "collapsible"
12622
- }
12623
- };
12624
- var MCP_TOOL_PREFIX = "tool-mcp__";
12625
- var BUILTIN_MCP_TOOLS = {
12626
- "tool-ListMcpResources": {
12627
- serverName: "mcp",
12628
- toolName: "list_resources",
12629
- displayName: "List Resources",
12630
- category: "list"
12631
- },
12632
- "tool-ListMcpResourcesTool": {
12633
- serverName: "mcp",
12634
- toolName: "list_resources",
12635
- displayName: "List Resources",
12636
- category: "list"
12637
- },
12638
- "tool-ReadMcpResource": {
12639
- serverName: "mcp",
12640
- toolName: "read_resource",
12641
- displayName: "Read Resource",
12642
- category: "get"
12643
- },
12644
- "tool-ReadMcpResourceTool": {
12645
- serverName: "mcp",
12646
- toolName: "read_resource",
12647
- displayName: "Read Resource",
12648
- category: "get"
12649
- }
12650
- };
12651
- function parseMcpToolType(partType) {
12652
- const builtin = BUILTIN_MCP_TOOLS[partType];
12653
- if (builtin) return builtin;
12654
- if (!partType.startsWith(MCP_TOOL_PREFIX)) return null;
12655
- const withoutPrefix = partType.slice(10);
12656
- const separatorIndex = withoutPrefix.indexOf("__");
12657
- if (separatorIndex === -1) return null;
12658
- const serverName = withoutPrefix.slice(0, separatorIndex);
12659
- const toolName2 = withoutPrefix.slice(separatorIndex + 2);
12660
- return {
12661
- serverName,
12662
- toolName: toolName2,
12663
- displayName: toolName2.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim(),
12664
- category: "other"
12665
- };
12666
- }
12667
- function formatCount(value, label) {
12668
- return `${value} ${value === 1 ? label : `${label}s`}`;
12669
- }
12670
- function summarizeNestedTools(nestedTools) {
12671
- if (nestedTools.length === 0) return "";
12672
- const fileTypes = /* @__PURE__ */ new Set([
12673
- "tool-Read",
12674
- "tool-Edit",
12675
- "tool-Write"
12676
- ]);
12677
- const searchTypes = /* @__PURE__ */ new Set([
12678
- "tool-Search",
12679
- "tool-Grep",
12680
- "tool-Glob",
12681
- "tool-WebSearch"
12682
- ]);
12683
- const commandTypes = /* @__PURE__ */ new Set(["tool-Bash"]);
12684
- let fileCount = 0;
12685
- let searchCount = 0;
12686
- let commandCount = 0;
12687
- for (const tool of nestedTools) if (fileTypes.has(tool.type)) fileCount += 1;
12688
- else if (searchTypes.has(tool.type)) searchCount += 1;
12689
- else if (commandTypes.has(tool.type)) commandCount += 1;
12690
- const parts = [];
12691
- if (fileCount > 0) parts.push(formatCount(fileCount, "file"));
12692
- if (searchCount > 0) parts.push(`${searchCount} ${searchCount === 1 ? "search" : "searches"}`);
12693
- if (commandCount > 0) parts.push(formatCount(commandCount, "command"));
12694
- if (parts.length === 0) return "";
12695
- if (parts.length === 1) return parts[0];
12696
- if (parts.length === 2) return `${parts[0]} and ${parts[1]}`;
12697
- return `${parts.slice(0, -1).join(", ")}, and ${parts[parts.length - 1]}`;
12698
- }
12699
- function getNestedCounts(nestedTools) {
12700
- const fileTypes = /* @__PURE__ */ new Set([
12701
- "tool-Read",
12702
- "tool-Edit",
12703
- "tool-Write"
12704
- ]);
12705
- const searchTypes = /* @__PURE__ */ new Set([
12706
- "tool-Search",
12707
- "tool-Grep",
12708
- "tool-Glob",
12709
- "tool-WebSearch"
12710
- ]);
12711
- let fileCount = 0;
12712
- let searchCount = 0;
12713
- for (const tool of nestedTools) if (fileTypes.has(tool.type)) fileCount += 1;
12714
- else if (searchTypes.has(tool.type)) searchCount += 1;
12715
- return {
12716
- fileCount,
12717
- searchCount
12718
- };
12719
- }
12720
- function formatStreamCounts(fileCount, searchCount) {
12721
- const parts = [];
12722
- if (fileCount > 0) parts.push(formatCount(fileCount, "file"));
12723
- if (searchCount > 0) parts.push(`${searchCount} ${searchCount === 1 ? "search" : "searches"}`);
12724
- return parts.join(", ");
12725
- }
12726
- var ToolGroup = memo(function ToolGroup2({ part, nestedTools = [], chatStatus, completeLabel, shimmerLabel, interruptedLabel, maxVisibleTools = 5, defaultOpen, showElapsed = true }) {
12727
- const { isPending, isInterrupted } = getToolStatus(part, chatStatus);
12728
- const description = part.input?.description || "";
12729
- const [expanded, setExpanded] = useState(defaultOpen ?? false);
12730
- const [visibleCount, setVisibleCount] = useState(0);
12731
- const startedAt = part.callProviderMetadata?.custom?.startedAt ?? part.startedAt;
12732
- const hasNestedTools = nestedTools.length > 0;
12733
- const streamKey = part.toolCallId ?? part.id ?? "";
12734
- const outputDuration = part.output?.totalDurationMs || part.output?.duration || part.output?.duration_ms;
12735
- const maskThreshold = 4;
12736
- const streamHeight = Math.max(1, maxVisibleTools) * 28;
12737
- const visibleToolCount = isPending ? Math.max(visibleCount, 0) : nestedTools.length;
12738
- const wasPendingRef = useRef(isPending);
12739
- const userToggledRef = useRef(false);
12740
- const openTimerRef = useRef(null);
12741
- const { fileCount, searchCount } = useMemo(() => {
12742
- return getNestedCounts(isPending ? nestedTools.slice(0, Math.max(visibleCount, 0)) : nestedTools);
12743
- }, [
12744
- isPending,
12745
- nestedTools,
12746
- visibleCount
12747
- ]);
12748
- const streamCounts = formatStreamCounts(fileCount, searchCount);
12749
- const listRef = useRef(null);
12750
- const elapsedMs = useElapsedTime(startedAt, isPending);
12751
- useEffect(() => {
12752
- const wasPending = wasPendingRef.current;
12753
- if (openTimerRef.current) {
12754
- window.clearTimeout(openTimerRef.current);
12755
- openTimerRef.current = null;
12756
- }
12757
- if (isPending && !wasPending) {
12758
- if (!userToggledRef.current && defaultOpen !== false) {
12759
- setExpanded(false);
12760
- openTimerRef.current = window.setTimeout(() => {
12761
- setExpanded(true);
12762
- }, 60);
12763
- }
12764
- }
12765
- if (!isPending && wasPending) {
12766
- setExpanded(false);
12767
- userToggledRef.current = false;
12768
- }
12769
- wasPendingRef.current = isPending;
12770
- return () => {
12771
- if (openTimerRef.current) {
12772
- window.clearTimeout(openTimerRef.current);
12773
- openTimerRef.current = null;
12774
- }
12775
- };
12776
- }, [defaultOpen, isPending]);
12777
- useEffect(() => {
12778
- if (!isPending || nestedTools.length === 0) {
12779
- setVisibleCount(nestedTools.length);
12780
- return;
12781
- }
12782
- let index = 1;
12783
- setVisibleCount(Math.min(index, nestedTools.length));
12784
- const interval = setInterval(() => {
12785
- index += 1;
12786
- setVisibleCount(Math.min(index, nestedTools.length));
12787
- if (index >= nestedTools.length) clearInterval(interval);
12788
- }, 450);
12789
- return () => clearInterval(interval);
12790
- }, [
12791
- isPending,
12792
- nestedTools.length,
12793
- streamKey
12794
- ]);
12795
- useEffect(() => {
12796
- if (!isPending || !listRef.current) return;
12797
- listRef.current.scrollTop = listRef.current.scrollHeight;
12798
- }, [isPending, visibleCount]);
12799
- const subtitle = (() => {
12800
- if (isPending && hasNestedTools) return streamCounts;
12801
- if (!isPending && hasNestedTools) {
12802
- const summary = summarizeNestedTools(nestedTools);
12803
- if (summary) return summary;
12804
- }
12805
- if (!description) return "";
12806
- return description.length > 60 ? `${description.slice(0, 57)}...` : description;
12807
- })();
12808
- const elapsedTimeDisplay = formatElapsedTime(!isPending && outputDuration ? outputDuration : elapsedMs);
12809
- if (isInterrupted && !part.output) return /* @__PURE__ */ jsx(ToolRowBase, {
12810
- completeLabel: interruptedLabel,
12811
- isAnimating: false
12812
- });
12813
- return /* @__PURE__ */ jsx(ToolRowBase, {
12814
- completeLabel,
12815
- shimmerLabel,
12816
- isAnimating: isPending,
12817
- detail: subtitle,
12818
- expandable: hasNestedTools,
12819
- expanded,
12820
- onToggleExpand: () => {
12821
- userToggledRef.current = true;
12822
- setExpanded((prev) => !prev);
12823
- },
12824
- trailingContent: showElapsed && elapsedTimeDisplay ? /* @__PURE__ */ jsx("span", {
12825
- className: "shrink-0 font-normal text-an-foreground-muted/60 tabular-nums",
12826
- children: elapsedTimeDisplay
12827
- }) : void 0,
12828
- children: /* @__PURE__ */ jsxs("div", {
12829
- className: "relative",
12830
- children: [isPending && expanded && visibleToolCount > maskThreshold && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 z-10 h-10 bg-linear-to-b from-an-background to-transparent" }), /* @__PURE__ */ jsx("div", {
12831
- ref: listRef,
12832
- className: cn(nestedTools.length > 1 ? "flex flex-col gap-2" : void 0, isPending && expanded && visibleToolCount > maskThreshold && "overflow-y-auto"),
12833
- style: isPending && expanded && visibleToolCount > maskThreshold ? { height: `${streamHeight}px` } : void 0,
12834
- children: (isPending ? nestedTools.slice(0, Math.max(visibleCount, 0)) : nestedTools).map((nestedPart, idx) => {
12835
- const derivedPart = isPending ? {
12836
- ...nestedPart,
12837
- state: idx === visibleCount - 1 ? "input-streaming" : "output-available"
12838
- } : nestedPart;
12839
- const nestedMeta = toolRegistry[derivedPart.type];
12840
- if (!nestedMeta) return null;
12841
- const { isPending: nestedIsPending, isError: nestedIsError } = getToolStatus(derivedPart, chatStatus);
12842
- return /* @__PURE__ */ jsx(GenericTool, {
12843
- icon: nestedMeta.icon,
12844
- title: nestedMeta.title(derivedPart),
12845
- subtitle: nestedMeta.subtitle?.(derivedPart),
12846
- isPending: nestedIsPending,
12847
- isError: nestedIsError
12848
- }, derivedPart.toolCallId ?? derivedPart.id ?? `${derivedPart.type}-${nestedMeta.title(derivedPart)}`);
12849
- })
12850
- })]
12851
- })
12852
- });
12853
- });
12854
- function deriveToolStatus(part, chatStatus) {
12855
- if (part.state === "input-streaming") return "streaming";
12856
- if (part.state === "output-available") return "success";
12857
- if (part.state === "output-error") return "error";
12858
- const { isPending } = getToolStatus(part, chatStatus);
12859
- return isPending ? "pending" : "success";
12860
- }
12861
- var ToolRenderer = memo(function ToolRenderer2({ part, nestedTools, chatStatus, toolRenderers }) {
12862
- const partType = part.type;
12863
- switch (partType) {
12864
- case "tool-Bash":
12865
- return /* @__PURE__ */ jsx(BashTool, { part });
12866
- case "tool-IPython":
12867
- return /* @__PURE__ */ jsx(IpythonTool, { part });
12868
- case "tool-Edit":
12869
- case "tool-Write":
12870
- return /* @__PURE__ */ jsx(EditTool, { part });
12871
- case "tool-WebSearch":
12872
- case "tool-Grep":
12873
- case "tool-Glob":
12874
- return /* @__PURE__ */ jsx(SearchTool, { part });
12875
- case "tool-PlanWrite":
12876
- return /* @__PURE__ */ jsx(PlanTool, {
12877
- part,
12878
- chatStatus
12879
- });
12880
- case "tool-TodoWrite":
12881
- return /* @__PURE__ */ jsx(TodoTool, {
12882
- part,
12883
- chatStatus
12884
- });
12885
- case "tool-Question":
12886
- return /* @__PURE__ */ jsx(QuestionTool, {
12887
- part,
12888
- chatStatus
12889
- });
12890
- case "tool-Task":
12891
- case "tool-Agent": {
12892
- const labelBase = part.type === "tool-Agent" ? "Agent" : "Task";
12893
- return /* @__PURE__ */ jsx(ToolGroup, {
12894
- part,
12895
- nestedTools,
12896
- chatStatus,
12897
- completeLabel: `${labelBase} completed`,
12898
- shimmerLabel: `Running ${labelBase.toLowerCase()}`,
12899
- interruptedLabel: `${labelBase} interrupted`,
12900
- defaultOpen: false
12901
- });
12902
- }
12903
- case "tool-Thinking":
12904
- return /* @__PURE__ */ jsx(ThinkingTool, { part });
12905
- }
12906
- const mcpInfo = parseMcpToolType(partType);
12907
- if (mcpInfo) {
12908
- if (toolRenderers) {
12909
- const CustomRenderer = toolRenderers[mcpInfo.toolName];
12910
- if (CustomRenderer) return /* @__PURE__ */ jsx(CustomRenderer, {
12911
- name: mcpInfo.toolName,
12912
- input: part.input ?? {},
12913
- output: part.output ? unwrapMcpOutput(part.output) : void 0,
12914
- status: deriveToolStatus(part, chatStatus)
12915
- });
12916
- }
12917
- return /* @__PURE__ */ jsx(McpTool, {
12918
- part,
12919
- mcpInfo,
12920
- chatStatus
12921
- });
12922
- }
12923
- if (toolRenderers && partType.startsWith("tool-")) {
12924
- const toolName3 = partType.slice(5);
12925
- const CustomRenderer = toolRenderers[toolName3];
12926
- if (CustomRenderer) return /* @__PURE__ */ jsx(CustomRenderer, {
12927
- name: toolName3,
12928
- input: part.input ?? {},
12929
- output: part.output ?? part.result,
12930
- status: deriveToolStatus(part, chatStatus)
12931
- });
12932
- }
12933
- const meta = toolRegistry[partType];
12934
- if (meta) {
12935
- const { isPending: isPending2, isError: isError2 } = getToolStatus(part, chatStatus);
12936
- return /* @__PURE__ */ jsx(GenericTool, {
12937
- title: meta.title(part),
12938
- subtitle: meta.subtitle?.(part),
12939
- isPending: isPending2,
12940
- isError: isError2
12941
- });
12942
- }
12943
- const toolName2 = partType.startsWith("tool-") ? partType.slice(5) : partType;
12944
- const { isPending, isError } = getToolStatus(part, chatStatus);
12945
- return /* @__PURE__ */ jsx(GenericTool, {
12946
- title: isPending ? `Running ${toolName2}` : toolName2,
12947
- isPending,
12948
- isError
12949
- });
12950
- });
12951
- function AgentPlan({ steps, activeIndex, className, ...props }) {
12952
- const total = steps.length;
12953
- const completed = progressOf(activeIndex, total);
12954
- const allDone = completed >= total;
12955
- const progress = pct(completed, total);
12956
- return /* @__PURE__ */ jsxs("div", {
12957
- "data-slot": "agent-plan",
12958
- className: cn("flex w-full max-w-sm flex-col gap-3", className),
12959
- ...props,
12193
+ function TodoStatusIcon({ status, progress }) {
12194
+ const reduce = useReducedMotion() ?? false;
12195
+ const normalizedProgress = progress === void 0 ? 0.68 : Math.min(100, Math.max(0, progress)) / 100;
12196
+ return /* @__PURE__ */ jsxs(m.svg, {
12197
+ "aria-hidden": "true",
12198
+ viewBox: "0 0 24 24",
12199
+ initial: false,
12200
+ className: cn("mx-0.5 size-5 shrink-0 overflow-visible text-muted-foreground", status === "in-progress" && "text-foreground", status === "cancelled" && "text-rose-600 dark:text-rose-400"),
12960
12201
  children: [
12961
- /* @__PURE__ */ jsxs("div", {
12962
- className: "flex items-center justify-between",
12963
- children: [/* @__PURE__ */ jsx("span", {
12964
- className: "text-[0.84375rem] font-medium",
12965
- children: "Plan"
12966
- }), /* @__PURE__ */ jsxs("span", {
12967
- className: cn(mono, "text-foreground/35 tabular-nums"),
12968
- children: [
12969
- completed,
12970
- " of ",
12971
- total
12972
- ]
12973
- })]
12202
+ /* @__PURE__ */ jsx(m.circle, {
12203
+ cx: "12",
12204
+ cy: "12",
12205
+ r: "9",
12206
+ fill: "currentColor",
12207
+ stroke: "currentColor",
12208
+ strokeWidth: "1.5",
12209
+ strokeDasharray: status === "pending" ? "2 3" : void 0,
12210
+ strokeLinecap: "round",
12211
+ initial: false,
12212
+ animate: { fillOpacity: status === "completed" ? 0.06 : 0 },
12213
+ transition: reduce ? { duration: 0 } : {
12214
+ duration: 0.18,
12215
+ ease: EASE_OUT
12216
+ },
12217
+ className: cn(status === "in-progress" && "opacity-20")
12974
12218
  }),
12975
- /* @__PURE__ */ jsx("div", {
12976
- className: "bg-foreground/[0.06] h-[3px] w-full overflow-hidden rounded-full",
12977
- children: /* @__PURE__ */ jsx("span", {
12978
- className: "bg-foreground/80 block h-full rounded-full transition-[width] duration-500",
12979
- style: { width: `${progress}%` }
12980
- })
12219
+ /* @__PURE__ */ jsx(m.circle, {
12220
+ cx: "12",
12221
+ cy: "12",
12222
+ r: "9",
12223
+ pathLength: "1",
12224
+ fill: "none",
12225
+ stroke: "currentColor",
12226
+ strokeWidth: "2",
12227
+ strokeLinecap: "round",
12228
+ initial: false,
12229
+ animate: {
12230
+ pathLength: status === "in-progress" ? normalizedProgress : 0,
12231
+ opacity: status === "in-progress" ? 1 : 0,
12232
+ rotate: status === "in-progress" && progress === void 0 && !reduce ? 360 : -90
12233
+ },
12234
+ transition: status === "in-progress" && progress === void 0 && !reduce ? { rotate: {
12235
+ duration: 1.1,
12236
+ repeat: Infinity,
12237
+ ease: "linear"
12238
+ } } : reduce ? { duration: 0 } : SPRING_LAYOUT,
12239
+ style: { transformOrigin: "12px 12px" }
12240
+ }),
12241
+ /* @__PURE__ */ jsx(m.path, {
12242
+ d: "M7.5 12.25 10.5 15.25 16.75 8.75",
12243
+ fill: "none",
12244
+ stroke: "currentColor",
12245
+ strokeWidth: "2",
12246
+ strokeLinecap: "round",
12247
+ strokeLinejoin: "round",
12248
+ initial: false,
12249
+ animate: {
12250
+ pathLength: status === "completed" ? 1 : 0,
12251
+ opacity: status === "completed" ? 1 : 0
12252
+ },
12253
+ transition: reduce ? { duration: 0 } : {
12254
+ duration: 0.24,
12255
+ ease: EASE_OUT
12256
+ }
12981
12257
  }),
12982
- /* @__PURE__ */ jsx("ul", {
12983
- className: "flex flex-col gap-2.5",
12984
- children: steps.map((step, i) => {
12985
- const done = allDone || i < completed;
12986
- const active = !allDone && i === completed;
12987
- return /* @__PURE__ */ jsxs("li", {
12988
- className: "flex items-center gap-2.5 text-[0.84375rem]",
12989
- children: [/* @__PURE__ */ jsx("span", {
12990
- className: "flex size-4 shrink-0 items-center justify-center",
12991
- children: done ? /* @__PURE__ */ jsx(Check, { className: "text-foreground/35 size-3.5" }) : active ? /* @__PURE__ */ jsx(LoaderCircle, { className: "text-foreground/90 size-3.5 animate-spin motion-reduce:animate-none" }) : /* @__PURE__ */ jsx("span", {
12992
- "aria-hidden": true,
12993
- className: "bg-foreground/15 size-1.5 rounded-full"
12994
- })
12995
- }), /* @__PURE__ */ jsx("span", {
12996
- className: cn(done && "text-foreground/40", active && "text-foreground/90", !done && !active && "text-foreground/35"),
12997
- children: step
12998
- })]
12999
- }, step);
13000
- })
12258
+ /* @__PURE__ */ jsx(m.path, {
12259
+ d: "M8.5 8.5 15.5 15.5M15.5 8.5 8.5 15.5",
12260
+ fill: "none",
12261
+ stroke: "currentColor",
12262
+ strokeWidth: "2",
12263
+ strokeLinecap: "round",
12264
+ initial: false,
12265
+ animate: {
12266
+ pathLength: status === "cancelled" ? 1 : 0,
12267
+ opacity: status === "cancelled" ? 1 : 0
12268
+ },
12269
+ transition: reduce ? { duration: 0 } : {
12270
+ duration: 0.2,
12271
+ ease: EASE_OUT
12272
+ }
13001
12273
  })
13002
12274
  ]
13003
12275
  });
13004
12276
  }
13005
- function fleetAgentPlanPresentation(items) {
13006
- if (items.length === 0) return void 0;
13007
- const steps = items.flatMap((item) => {
13008
- const title = item.title.trim();
13009
- return title ? [title] : [];
12277
+ function TodoList({ items, title = "To-dos", open, defaultOpen = true, onOpenChange, collapseOnComplete = true, maxHeight = 248, className }) {
12278
+ const reduce = useReducedMotion() ?? false;
12279
+ const baseId = useId();
12280
+ const triggerId = `${baseId}-trigger`;
12281
+ const contentId = `${baseId}-content`;
12282
+ const viewportRef = useRef(null);
12283
+ const previousComplete = useRef(false);
12284
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
12285
+ const currentOpen = open ?? internalOpen;
12286
+ const completed = items.filter((item) => item.status === "completed").length;
12287
+ const allComplete = items.length > 0 && completed === items.length;
12288
+ const itemCount = items.length;
12289
+ const setOpen = useCallback((next) => {
12290
+ if (open === void 0) setInternalOpen(next);
12291
+ onOpenChange?.(next);
12292
+ }, [onOpenChange, open]);
12293
+ useEffect(() => {
12294
+ if (previousComplete.current && !allComplete) setOpen(true);
12295
+ if (!previousComplete.current && allComplete && collapseOnComplete) setOpen(false);
12296
+ previousComplete.current = allComplete;
12297
+ }, [
12298
+ allComplete,
12299
+ collapseOnComplete,
12300
+ setOpen
12301
+ ]);
12302
+ useLayoutEffect(() => {
12303
+ const viewport = viewportRef.current;
12304
+ if (!viewport || itemCount === 0) return;
12305
+ const frame = requestAnimationFrame(() => {
12306
+ if (viewport.scrollHeight <= viewport.clientHeight) return;
12307
+ if (typeof viewport.scrollTo === "function") viewport.scrollTo({
12308
+ top: viewport.scrollHeight,
12309
+ behavior: reduce ? "auto" : "smooth"
12310
+ });
12311
+ else viewport.scrollTop = viewport.scrollHeight;
12312
+ });
12313
+ return () => cancelAnimationFrame(frame);
12314
+ }, [itemCount, reduce]);
12315
+ return /* @__PURE__ */ jsxs("section", {
12316
+ "aria-label": "Agent task list",
12317
+ className: cn("w-full overflow-hidden rounded-2xl border border-border/70", className),
12318
+ children: [/* @__PURE__ */ jsxs("button", {
12319
+ id: triggerId,
12320
+ type: "button",
12321
+ "aria-expanded": currentOpen,
12322
+ "aria-controls": contentId,
12323
+ onClick: () => setOpen(!currentOpen),
12324
+ className: "group flex h-11 w-full items-center gap-2.5 rounded-2xl px-3.5 text-left outline-none focus-visible:ring-2 focus-visible:ring-ring",
12325
+ children: [
12326
+ /* @__PURE__ */ jsx(TodoHeaderIcon, { complete: allComplete }),
12327
+ /* @__PURE__ */ jsx("h3", {
12328
+ className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground/90",
12329
+ children: title
12330
+ }),
12331
+ /* @__PURE__ */ jsxs("span", {
12332
+ className: cn("shrink-0 text-xs font-medium tabular-nums text-muted-foreground", allComplete && "text-emerald-600 dark:text-emerald-400"),
12333
+ children: [/* @__PURE__ */ jsxs("span", {
12334
+ className: "sr-only",
12335
+ children: [
12336
+ completed,
12337
+ " of ",
12338
+ items.length,
12339
+ " tasks completed"
12340
+ ]
12341
+ }), /* @__PURE__ */ jsxs("span", {
12342
+ "aria-hidden": "true",
12343
+ className: "inline-flex",
12344
+ children: [
12345
+ /* @__PURE__ */ jsx(ActionSwapRollText, {
12346
+ value: String(completed),
12347
+ children: completed
12348
+ }),
12349
+ /* @__PURE__ */ jsx("span", { children: "/" }),
12350
+ /* @__PURE__ */ jsx("span", { children: items.length })
12351
+ ]
12352
+ })]
12353
+ }),
12354
+ /* @__PURE__ */ jsx(m.span, {
12355
+ "aria-hidden": "true",
12356
+ animate: { rotate: currentOpen ? 180 : 0 },
12357
+ transition: reduce ? { duration: 0 } : SPRING_SWAP,
12358
+ className: "text-muted-foreground/50 transition-colors group-hover:text-muted-foreground",
12359
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" })
12360
+ })
12361
+ ]
12362
+ }), /* @__PURE__ */ jsx(AgentDisclosure, {
12363
+ id: contentId,
12364
+ role: "region",
12365
+ "aria-labelledby": triggerId,
12366
+ open: currentOpen,
12367
+ children: /* @__PURE__ */ jsxs("div", {
12368
+ ref: viewportRef,
12369
+ className: "scrollbar-hide overflow-y-auto px-2 pb-2",
12370
+ style: { maxHeight },
12371
+ children: [/* @__PURE__ */ jsx("ol", {
12372
+ "aria-live": allComplete ? "polite" : "off",
12373
+ className: "space-y-0",
12374
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
12375
+ initial: false,
12376
+ mode: "popLayout",
12377
+ children: items.map((item) => {
12378
+ const status = item.status ?? "pending";
12379
+ return /* @__PURE__ */ jsxs(m.li, {
12380
+ layout: "position",
12381
+ initial: reduce ? { opacity: 1 } : {
12382
+ opacity: 0,
12383
+ y: 6
12384
+ },
12385
+ animate: {
12386
+ opacity: 1,
12387
+ y: 0
12388
+ },
12389
+ exit: reduce ? { opacity: 0 } : {
12390
+ opacity: 0,
12391
+ y: -3
12392
+ },
12393
+ transition: reduce ? { duration: 0 } : {
12394
+ opacity: {
12395
+ duration: 0.18,
12396
+ ease: EASE_OUT
12397
+ },
12398
+ y: SPRING_LAYOUT,
12399
+ layout: SPRING_LAYOUT
12400
+ },
12401
+ className: "flex min-h-9 items-center gap-2.5 rounded-xl px-1.5 py-1",
12402
+ children: [
12403
+ /* @__PURE__ */ jsx(TodoStatusIcon, {
12404
+ status,
12405
+ progress: item.progress
12406
+ }),
12407
+ /* @__PURE__ */ jsxs("span", {
12408
+ className: "sr-only",
12409
+ children: [statusLabel(status), ": "]
12410
+ }),
12411
+ /* @__PURE__ */ jsx("span", {
12412
+ className: cn("min-w-0 flex-1 truncate text-sm leading-5", status === "pending" && "text-muted-foreground/65", status === "in-progress" && "text-foreground", status === "completed" && "text-muted-foreground/60", status === "cancelled" && "text-muted-foreground/55"),
12413
+ children: /* @__PURE__ */ jsxs("span", {
12414
+ className: "relative inline-block max-w-full",
12415
+ children: [item.title, /* @__PURE__ */ jsx(m.span, {
12416
+ "aria-hidden": "true",
12417
+ initial: false,
12418
+ animate: {
12419
+ scaleX: status === "completed" ? 1 : 0,
12420
+ opacity: status === "completed" ? 1 : 0
12421
+ },
12422
+ transition: reduce ? { duration: 0 } : {
12423
+ duration: 0.28,
12424
+ ease: EASE_OUT,
12425
+ delay: 0.06
12426
+ },
12427
+ className: "absolute inset-x-0 top-1/2 h-px origin-left bg-current"
12428
+ })]
12429
+ })
12430
+ }),
12431
+ item.detail ? /* @__PURE__ */ jsx("span", {
12432
+ className: "shrink-0 text-sm text-muted-foreground/55",
12433
+ children: item.detail
12434
+ }) : null
12435
+ ]
12436
+ }, item.id);
12437
+ })
12438
+ })
12439
+ }), !items.length && /* @__PURE__ */ jsx("p", {
12440
+ className: "px-1.5 py-2 text-sm text-muted-foreground",
12441
+ children: "No tasks yet"
12442
+ })]
12443
+ })
12444
+ })]
13010
12445
  });
13011
- if (steps.length !== items.length) return void 0;
13012
- let activeIndex = 0;
13013
- while (activeIndex < items.length && items[activeIndex]?.status === "completed") activeIndex += 1;
13014
- if (items.slice(activeIndex + 1).some((item) => item.status === "completed")) return void 0;
12446
+ }
12447
+ function toTodoStatus(status) {
12448
+ if (status === "in_progress" || status === "in-progress") return "in-progress";
12449
+ if (status === "completed") return "completed";
12450
+ if (status === "cancelled") return "cancelled";
12451
+ return "pending";
12452
+ }
12453
+ function toTodoListItems(items) {
12454
+ return (items ?? []).flatMap((item, index) => {
12455
+ const title = item.title ?? item.content;
12456
+ if (!title) return [];
12457
+ return [{
12458
+ id: `${index}-${title}`,
12459
+ title,
12460
+ status: toTodoStatus(item.status)
12461
+ }];
12462
+ });
12463
+ }
12464
+ var TodoTool = memo(function TodoTool2({ part }) {
12465
+ const isStreaming = part.state === "input-streaming";
12466
+ const newTodos = useMemo(() => toTodoListItems(part.input?.todos ?? part.output?.newTodos), [part.input?.todos, part.output?.newTodos]);
12467
+ if (isStreaming || newTodos.length === 0) return /* @__PURE__ */ jsx(ToolTextShimmer, {
12468
+ as: "span",
12469
+ duration: 1.2,
12470
+ className: "m-0 inline-flex h-4 items-center text-label leading-none",
12471
+ children: "Updating to-dos..."
12472
+ });
12473
+ return /* @__PURE__ */ jsx(TodoList, {
12474
+ items: newTodos,
12475
+ title: "Todo list",
12476
+ defaultOpen: true,
12477
+ collapseOnComplete: false,
12478
+ maxHeight: 240
12479
+ });
12480
+ }, areToolPropsEqual);
12481
+ function useElapsedTime(startedAt, isPending) {
12482
+ const [elapsedMs, setElapsedMs] = useState(0);
12483
+ useEffect(() => {
12484
+ if (isPending && startedAt) {
12485
+ setElapsedMs(Date.now() - startedAt);
12486
+ const interval = setInterval(() => {
12487
+ setElapsedMs(Date.now() - startedAt);
12488
+ }, 1e3);
12489
+ return () => clearInterval(interval);
12490
+ }
12491
+ }, [isPending, startedAt]);
12492
+ return elapsedMs;
12493
+ }
12494
+ function getDisplayPath(filePath) {
12495
+ if (!filePath) return "";
12496
+ const stripped = stripSandboxPrefixes(filePath);
12497
+ if (stripped !== filePath) return stripped;
12498
+ if (filePath.startsWith("/")) {
12499
+ const parts = filePath.split("/");
12500
+ const rootIndicators = [
12501
+ "apps",
12502
+ "packages",
12503
+ "src",
12504
+ "lib",
12505
+ "components"
12506
+ ];
12507
+ const rootIndex = parts.findIndex((p) => rootIndicators.includes(p));
12508
+ if (rootIndex > 0) return parts.slice(rootIndex).join("/");
12509
+ }
12510
+ return filePath;
12511
+ }
12512
+ function calculateDiffStats(oldString, newString) {
12513
+ const oldLines = oldString.split("\n");
12514
+ const newLines = newString.split("\n");
12515
+ const maxLines = Math.max(oldLines.length, newLines.length);
12516
+ let addedLines = 0;
12517
+ let removedLines = 0;
12518
+ for (let i = 0; i < maxLines; i++) if (oldLines[i] !== void 0 && newLines[i] !== void 0) {
12519
+ if (oldLines[i] !== newLines[i]) {
12520
+ removedLines++;
12521
+ addedLines++;
12522
+ }
12523
+ } else if (oldLines[i] !== void 0) removedLines++;
12524
+ else if (newLines[i] !== void 0) addedLines++;
13015
12525
  return {
13016
- steps,
13017
- activeIndex
12526
+ addedLines,
12527
+ removedLines
13018
12528
  };
13019
12529
  }
13020
- function FleetAgentPlan({ presentation, className }) {
13021
- return /* @__PURE__ */ jsx(AgentPlan, {
13022
- steps: presentation.steps,
13023
- activeIndex: presentation.activeIndex,
13024
- "aria-label": `Plan progress: ${Math.min(presentation.activeIndex, presentation.steps.length)} of ${presentation.steps.length} steps completed`,
13025
- className
13026
- });
13027
- }
13028
- var STATUS_TEXT = {
13029
- queued: "Waiting to generate",
13030
- generating: "Generating image",
13031
- refining: "Refining details",
13032
- complete: "Image ready",
13033
- error: "Generation failed"
13034
- };
13035
- var MEDIA_STATE = {
13036
- queued: {
13037
- filter: "blur(4px) saturate(0.75)",
13038
- opacity: 0,
13039
- scale: 1.02
12530
+ var toolRegistry = {
12531
+ "tool-Task": {
12532
+ icon: Sparkles,
12533
+ title: (part) => {
12534
+ const isPending = part.state !== "output-available" && part.state !== "output-error";
12535
+ const subagentType = part.input?.subagent_type || "Agent";
12536
+ return isPending ? `Running ${subagentType}` : `${subagentType} completed`;
12537
+ },
12538
+ subtitle: (part) => {
12539
+ const desc = part.input?.description || "";
12540
+ return desc.length > 50 ? `${desc.slice(0, 47)}...` : desc;
12541
+ },
12542
+ variant: "simple"
13040
12543
  },
13041
- generating: {
13042
- filter: "blur(3px) saturate(0.85)",
13043
- opacity: 0,
13044
- scale: 1.015
12544
+ "tool-Agent": {
12545
+ icon: Sparkles,
12546
+ title: (part) => {
12547
+ const isPending = part.state !== "output-available" && part.state !== "output-error";
12548
+ const subagentType = part.input?.subagent_type || "Agent";
12549
+ return isPending ? `Running ${subagentType}` : `${subagentType} completed`;
12550
+ },
12551
+ subtitle: (part) => {
12552
+ const desc = part.input?.description || "";
12553
+ return desc.length > 50 ? `${desc.slice(0, 47)}...` : desc;
12554
+ },
12555
+ variant: "simple"
12556
+ },
12557
+ "tool-Skill": {
12558
+ icon: Sparkles,
12559
+ title: () => "Skill",
12560
+ subtitle: (part) => part.input?.skill || "",
12561
+ variant: "simple"
12562
+ },
12563
+ "tool-Grep": {
12564
+ icon: Search,
12565
+ title: (part) => {
12566
+ if (part.state !== "output-available" && part.state !== "output-error") return "Grepping";
12567
+ const numFiles = part.output?.numFiles || 0;
12568
+ return numFiles > 0 ? `Grepped ${numFiles} files` : "No matches";
12569
+ },
12570
+ subtitle: (part) => {
12571
+ const pattern = part.input?.pattern || "";
12572
+ const path = part.input?.path || "";
12573
+ if (path) {
12574
+ const combined = `${pattern} in ${getDisplayPath(path)}`;
12575
+ return combined.length > 40 ? `${combined.slice(0, 37)}...` : combined;
12576
+ }
12577
+ return pattern.length > 40 ? `${pattern.slice(0, 37)}...` : pattern;
12578
+ },
12579
+ variant: "simple"
12580
+ },
12581
+ "tool-Glob": {
12582
+ icon: FolderSearch,
12583
+ title: (part) => {
12584
+ if (part.state !== "output-available" && part.state !== "output-error") return "Exploring files";
12585
+ const numFiles = part.output?.numFiles || 0;
12586
+ return numFiles > 0 ? `Found ${numFiles} files` : "No files found";
12587
+ },
12588
+ subtitle: (part) => {
12589
+ const pattern = part.input?.pattern || "";
12590
+ return pattern.length > 40 ? `${pattern.slice(0, 37)}...` : pattern;
12591
+ },
12592
+ variant: "simple"
12593
+ },
12594
+ "tool-Read": {
12595
+ icon: Eye,
12596
+ title: (part) => {
12597
+ return part.state !== "output-available" && part.state !== "output-error" ? "Reading" : "Read";
12598
+ },
12599
+ subtitle: (part) => {
12600
+ const filePath = part.input?.file_path || "";
12601
+ if (!filePath) return "";
12602
+ return filePath.split("/").pop() || "";
12603
+ },
12604
+ variant: "simple"
12605
+ },
12606
+ "tool-Edit": {
12607
+ icon: FileCodeCorner,
12608
+ title: (part) => {
12609
+ const filePath = part.input?.file_path || "";
12610
+ if (!filePath) return "Edit";
12611
+ return filePath.split("/").pop() || "Edit";
12612
+ },
12613
+ subtitle: (part) => {
12614
+ if (part.state !== "output-available" && part.state !== "output-error") return "";
12615
+ const oldString = part.input?.old_string || "";
12616
+ const newString = part.input?.new_string || "";
12617
+ if (!oldString && !newString) return "";
12618
+ if (oldString !== newString) {
12619
+ const { addedLines, removedLines } = calculateDiffStats(oldString, newString);
12620
+ return `+${addedLines} -${removedLines}`;
12621
+ }
12622
+ return "";
12623
+ },
12624
+ variant: "simple"
12625
+ },
12626
+ "tool-Write": {
12627
+ icon: FilePlus,
12628
+ title: () => "Create",
12629
+ subtitle: (part) => {
12630
+ const filePath = part.input?.file_path || "";
12631
+ if (!filePath) return "";
12632
+ return filePath.split("/").pop() || "";
12633
+ },
12634
+ variant: "simple"
12635
+ },
12636
+ "tool-Bash": {
12637
+ icon: Terminal,
12638
+ title: (part) => {
12639
+ return part.state !== "output-available" && part.state !== "output-error" ? "Running command" : "Ran command";
12640
+ },
12641
+ subtitle: (part) => {
12642
+ const command = part.input?.command || "";
12643
+ if (!command) return "";
12644
+ let normalized = command.replace(/\\\s*\n\s*/g, " ").trim();
12645
+ normalized = normalized.replace(/\/(?:Users|home|root)\/[^\s"']+/g, (match) => getDisplayPath(match));
12646
+ return normalized.length > 50 ? `${normalized.slice(0, 47)}...` : normalized;
12647
+ },
12648
+ variant: "simple"
12649
+ },
12650
+ "tool-IPython": {
12651
+ icon: FileCodeCorner,
12652
+ title: (part) => {
12653
+ return part.state !== "output-available" && part.state !== "output-error" ? "Running cell" : "Ran cell";
12654
+ },
12655
+ subtitle: (part) => {
12656
+ const code = part.input?.code || "";
12657
+ if (!code) return "";
12658
+ const firstLine = code.split("\n", 1)[0].trim();
12659
+ return firstLine.length > 50 ? `${firstLine.slice(0, 47)}...` : firstLine;
12660
+ },
12661
+ variant: "simple"
12662
+ },
12663
+ "tool-WebFetch": {
12664
+ icon: Globe,
12665
+ title: (part) => {
12666
+ return part.state !== "output-available" && part.state !== "output-error" ? "Fetching" : "Fetched";
12667
+ },
12668
+ subtitle: (part) => {
12669
+ const url = part.input?.url || "";
12670
+ try {
12671
+ return new URL(url).hostname.replace("www.", "");
12672
+ } catch {
12673
+ return url.slice(0, 30);
12674
+ }
12675
+ },
12676
+ variant: "simple"
12677
+ },
12678
+ "tool-WebSearch": {
12679
+ icon: Search,
12680
+ title: (part) => {
12681
+ return part.state !== "output-available" && part.state !== "output-error" ? "Searching web" : "Searched web";
12682
+ },
12683
+ subtitle: (part) => {
12684
+ const query = part.input?.query || "";
12685
+ return query.length > 40 ? `${query.slice(0, 37)}...` : query;
12686
+ },
12687
+ variant: "collapsible"
12688
+ },
12689
+ "tool-TodoWrite": {
12690
+ icon: ListTodo,
12691
+ title: (part) => {
12692
+ const isPending = part.state !== "output-available" && part.state !== "output-error";
12693
+ const action = part.input?.action || "update";
12694
+ if (isPending) return action === "add" ? "Adding todo" : "Updating todos";
12695
+ return action === "add" ? "Added todo" : "Updated todos";
12696
+ },
12697
+ subtitle: (part) => {
12698
+ const todos = part.input?.todos || [];
12699
+ if (todos.length === 0) return "";
12700
+ return `${todos.length} ${todos.length === 1 ? "item" : "items"}`;
12701
+ },
12702
+ variant: "simple"
12703
+ },
12704
+ "tool-PlanWrite": {
12705
+ icon: Sparkles,
12706
+ title: (part) => {
12707
+ const isPending = part.state !== "output-available" && part.state !== "output-error";
12708
+ const action = part.input?.action || "create";
12709
+ if (isPending) {
12710
+ if (action === "create") return "Creating plan";
12711
+ if (action === "approve") return "Approving plan";
12712
+ return "Updating plan";
12713
+ }
12714
+ const status = part.input?.plan?.status;
12715
+ if (status === "awaiting_approval") return "Plan ready for review";
12716
+ if (status === "approved") return "Plan approved";
12717
+ if (status === "completed") return "Plan completed";
12718
+ return action === "create" ? "Created plan" : "Updated plan";
12719
+ },
12720
+ variant: "simple"
12721
+ },
12722
+ "tool-ExitPlanMode": {
12723
+ icon: LogOut,
12724
+ title: (part) => {
12725
+ return part.state !== "output-available" && part.state !== "output-error" ? "Finishing plan" : "Plan complete";
12726
+ },
12727
+ variant: "simple"
12728
+ },
12729
+ "tool-NotebookEdit": {
12730
+ icon: FileCodeCorner,
12731
+ title: (part) => {
12732
+ return part.state !== "output-available" && part.state !== "output-error" ? "Editing notebook" : "Edited notebook";
12733
+ },
12734
+ subtitle: (part) => {
12735
+ const filePath = part.input?.file_path || "";
12736
+ if (!filePath) return "";
12737
+ return filePath.split("/").pop() || "";
12738
+ },
12739
+ variant: "simple"
13045
12740
  },
13046
- refining: {
13047
- filter: "blur(1.5px) saturate(0.95)",
13048
- opacity: 0.62,
13049
- scale: 1.005
12741
+ "tool-BashOutput": {
12742
+ icon: Terminal,
12743
+ title: (part) => {
12744
+ return part.state !== "output-available" && part.state !== "output-error" ? "Getting output" : "Command output";
12745
+ },
12746
+ subtitle: (part) => {
12747
+ const output = part.output;
12748
+ if (typeof output === "string" && output.trim()) return output.trim();
12749
+ const command = part.input?.command || "";
12750
+ if (!command) return "";
12751
+ let normalized = command.replace(/\\\s*\n\s*/g, " ").trim();
12752
+ normalized = normalized.replace(/\/(?:Users|home|root)\/[^\s"']+/g, (match) => getDisplayPath(match));
12753
+ return normalized.length > 50 ? `${normalized.slice(0, 47)}...` : normalized;
12754
+ },
12755
+ variant: "simple"
13050
12756
  },
13051
- complete: {
13052
- filter: "blur(0px) saturate(1)",
13053
- opacity: 1,
13054
- scale: 1
12757
+ "tool-KillShell": {
12758
+ icon: CircleX,
12759
+ title: (part) => {
12760
+ return part.state !== "output-available" && part.state !== "output-error" ? "Stopping shell" : "Shell stopped";
12761
+ },
12762
+ subtitle: (part) => {
12763
+ const pid = part.input?.pid;
12764
+ return typeof pid === "number" ? `pid ${pid}` : "";
12765
+ },
12766
+ variant: "simple"
13055
12767
  },
13056
- error: {
13057
- filter: "blur(2px) saturate(0.5)",
13058
- opacity: 0.28,
13059
- scale: 1
12768
+ "tool-cloning": {
12769
+ icon: GitBranch,
12770
+ title: (part) => {
12771
+ return part.state !== "output-available" && part.state !== "output-error" ? "Cloning repo" : "Repo cloned";
12772
+ },
12773
+ subtitle: (part) => part.input?.repo ?? "",
12774
+ variant: "simple"
12775
+ },
12776
+ "tool-Thinking": {
12777
+ icon: Sparkles,
12778
+ title: (part) => {
12779
+ return part.state !== "output-available" && part.state !== "output-error" ? "Thinking..." : "Thought";
12780
+ },
12781
+ variant: "collapsible"
13060
12782
  }
13061
12783
  };
13062
- var OVERLAY_OPACITY = {
13063
- queued: 1,
13064
- generating: 1,
13065
- refining: 0.48,
13066
- complete: 0,
13067
- error: 0
12784
+ var MCP_TOOL_PREFIX = "tool-mcp__";
12785
+ var BUILTIN_MCP_TOOLS = {
12786
+ "tool-ListMcpResources": {
12787
+ serverName: "mcp",
12788
+ toolName: "list_resources",
12789
+ displayName: "List Resources",
12790
+ category: "list"
12791
+ },
12792
+ "tool-ListMcpResourcesTool": {
12793
+ serverName: "mcp",
12794
+ toolName: "list_resources",
12795
+ displayName: "List Resources",
12796
+ category: "list"
12797
+ },
12798
+ "tool-ReadMcpResource": {
12799
+ serverName: "mcp",
12800
+ toolName: "read_resource",
12801
+ displayName: "Read Resource",
12802
+ category: "get"
12803
+ },
12804
+ "tool-ReadMcpResourceTool": {
12805
+ serverName: "mcp",
12806
+ toolName: "read_resource",
12807
+ displayName: "Read Resource",
12808
+ category: "get"
12809
+ }
13068
12810
  };
13069
- var DOT_GAP = 10;
13070
- var TWO_PI = Math.PI * 2;
13071
- function DitherMark({ status, reduce }) {
13072
- if (status === "complete") return /* @__PURE__ */ jsx(Check, {
13073
- "aria-hidden": "true",
13074
- className: "size-3.5"
13075
- });
13076
- if (status === "error") return /* @__PURE__ */ jsx(CircleAlert, {
13077
- "aria-hidden": "true",
13078
- className: "size-3.5"
13079
- });
13080
- return /* @__PURE__ */ jsxs(m.span, {
13081
- "aria-hidden": "true",
13082
- animate: reduce ? void 0 : { rotate: 360 },
13083
- transition: {
13084
- duration: 2.4,
13085
- ease: EASE_IN_OUT,
13086
- repeat: Number.POSITIVE_INFINITY
13087
- },
13088
- className: "grid size-3.5 grid-cols-2 place-items-center gap-0.5",
13089
- children: [
13090
- /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current" }),
13091
- /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current opacity-55" }),
13092
- /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current opacity-55" }),
13093
- /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current" })
13094
- ]
13095
- });
12811
+ function parseMcpToolType(partType) {
12812
+ const builtin = BUILTIN_MCP_TOOLS[partType];
12813
+ if (builtin) return builtin;
12814
+ if (!partType.startsWith(MCP_TOOL_PREFIX)) return null;
12815
+ const withoutPrefix = partType.slice(10);
12816
+ const separatorIndex = withoutPrefix.indexOf("__");
12817
+ if (separatorIndex === -1) return null;
12818
+ const serverName = withoutPrefix.slice(0, separatorIndex);
12819
+ const toolName2 = withoutPrefix.slice(separatorIndex + 2);
12820
+ return {
12821
+ serverName,
12822
+ toolName: toolName2,
12823
+ displayName: toolName2.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim(),
12824
+ category: "other"
12825
+ };
13096
12826
  }
13097
- function DitherField({ interactive, reduce, status }) {
13098
- const canHover = useHoverCapable();
13099
- const canvasRef = useRef(null);
13100
- useEffect(() => {
13101
- const canvas = canvasRef.current;
13102
- const context = canvas?.getContext("2d");
13103
- if (!canvas || !context) return;
13104
- let frame = 0;
13105
- let width = 0;
13106
- let height = 0;
13107
- let dotColor = "currentColor";
13108
- const pointer = {
13109
- x: 0,
13110
- y: 0,
13111
- targetX: 0,
13112
- targetY: 0,
13113
- inside: false
13114
- };
13115
- const pointerEnabled = interactive && canHover && !reduce;
13116
- const resize = () => {
13117
- const rect = canvas.getBoundingClientRect();
13118
- width = rect.width || canvas.clientWidth || 208;
13119
- height = rect.height || canvas.clientHeight || 208;
13120
- const dpr = Math.min(window.devicePixelRatio || 1, 2);
13121
- canvas.width = Math.round(width * dpr);
13122
- canvas.height = Math.round(height * dpr);
13123
- context.setTransform(dpr, 0, 0, dpr, 0, 0);
13124
- dotColor = window.getComputedStyle(canvas).color;
13125
- pointer.x = width / 2;
13126
- pointer.y = height / 2;
13127
- pointer.targetX = pointer.x;
13128
- pointer.targetY = pointer.y;
13129
- };
13130
- const draw = (time) => {
13131
- context.clearRect(0, 0, width, height);
13132
- if (!pointer.inside) {
13133
- pointer.targetX = width / 2 + (reduce ? 0 : Math.sin(time / 1700) * width * 0.12);
13134
- pointer.targetY = height / 2 + (reduce ? 0 : Math.cos(time / 2100) * height * 0.1);
13135
- }
13136
- const follow = reduce ? 1 : pointer.inside ? 0.16 : 0.045;
13137
- pointer.x += (pointer.targetX - pointer.x) * follow;
13138
- pointer.y += (pointer.targetY - pointer.y) * follow;
13139
- const radius = Math.min(width, height) * 0.38;
13140
- const columns = Math.ceil(width / DOT_GAP) + 1;
13141
- const rows = Math.ceil(height / DOT_GAP) + 1;
13142
- const offsetX = (width - (columns - 1) * DOT_GAP) / 2;
13143
- const offsetY = (height - (rows - 1) * DOT_GAP) / 2;
13144
- context.fillStyle = dotColor;
13145
- for (let row = 0; row < rows; row += 1) for (let column = 0; column < columns; column += 1) {
13146
- const anchorX = offsetX + column * DOT_GAP;
13147
- const anchorY = offsetY + row * DOT_GAP;
13148
- const deltaX = anchorX - pointer.x;
13149
- const deltaY = anchorY - pointer.y;
13150
- const distance = Math.hypot(deltaX, deltaY);
13151
- const proximity = Math.max(0, 1 - distance / radius);
13152
- const influence = proximity * proximity * (3 - 2 * proximity);
13153
- const displacement = influence * influence * 9;
13154
- const directionX = distance > 0 ? deltaX / distance : 0;
13155
- const directionY = distance > 0 ? deltaY / distance : 0;
13156
- const x = anchorX + directionX * displacement;
13157
- const y = anchorY + directionY * displacement;
13158
- const dotRadius = 0.65 + influence * 0.85;
13159
- context.globalAlpha = 0.17 + influence * 0.72;
13160
- context.beginPath();
13161
- context.arc(x, y, dotRadius, 0, TWO_PI);
13162
- context.fill();
12827
+ function formatCount(value, label) {
12828
+ return `${value} ${value === 1 ? label : `${label}s`}`;
12829
+ }
12830
+ function summarizeNestedTools(nestedTools) {
12831
+ if (nestedTools.length === 0) return "";
12832
+ const fileTypes = /* @__PURE__ */ new Set([
12833
+ "tool-Read",
12834
+ "tool-Edit",
12835
+ "tool-Write"
12836
+ ]);
12837
+ const searchTypes = /* @__PURE__ */ new Set([
12838
+ "tool-Search",
12839
+ "tool-Grep",
12840
+ "tool-Glob",
12841
+ "tool-WebSearch"
12842
+ ]);
12843
+ const commandTypes = /* @__PURE__ */ new Set(["tool-Bash"]);
12844
+ let fileCount = 0;
12845
+ let searchCount = 0;
12846
+ let commandCount = 0;
12847
+ for (const tool of nestedTools) if (fileTypes.has(tool.type)) fileCount += 1;
12848
+ else if (searchTypes.has(tool.type)) searchCount += 1;
12849
+ else if (commandTypes.has(tool.type)) commandCount += 1;
12850
+ const parts = [];
12851
+ if (fileCount > 0) parts.push(formatCount(fileCount, "file"));
12852
+ if (searchCount > 0) parts.push(`${searchCount} ${searchCount === 1 ? "search" : "searches"}`);
12853
+ if (commandCount > 0) parts.push(formatCount(commandCount, "command"));
12854
+ if (parts.length === 0) return "";
12855
+ if (parts.length === 1) return parts[0];
12856
+ if (parts.length === 2) return `${parts[0]} and ${parts[1]}`;
12857
+ return `${parts.slice(0, -1).join(", ")}, and ${parts[parts.length - 1]}`;
12858
+ }
12859
+ function getNestedCounts(nestedTools) {
12860
+ const fileTypes = /* @__PURE__ */ new Set([
12861
+ "tool-Read",
12862
+ "tool-Edit",
12863
+ "tool-Write"
12864
+ ]);
12865
+ const searchTypes = /* @__PURE__ */ new Set([
12866
+ "tool-Search",
12867
+ "tool-Grep",
12868
+ "tool-Glob",
12869
+ "tool-WebSearch"
12870
+ ]);
12871
+ let fileCount = 0;
12872
+ let searchCount = 0;
12873
+ for (const tool of nestedTools) if (fileTypes.has(tool.type)) fileCount += 1;
12874
+ else if (searchTypes.has(tool.type)) searchCount += 1;
12875
+ return {
12876
+ fileCount,
12877
+ searchCount
12878
+ };
12879
+ }
12880
+ function formatStreamCounts(fileCount, searchCount) {
12881
+ const parts = [];
12882
+ if (fileCount > 0) parts.push(formatCount(fileCount, "file"));
12883
+ if (searchCount > 0) parts.push(`${searchCount} ${searchCount === 1 ? "search" : "searches"}`);
12884
+ return parts.join(", ");
12885
+ }
12886
+ var ToolGroup = memo(function ToolGroup2({ part, nestedTools = [], chatStatus, completeLabel, shimmerLabel, interruptedLabel, maxVisibleTools = 5, defaultOpen, showElapsed = true }) {
12887
+ const { isPending, isInterrupted } = getToolStatus(part, chatStatus);
12888
+ const description = part.input?.description || "";
12889
+ const [expanded, setExpanded] = useState(defaultOpen ?? false);
12890
+ const [visibleCount, setVisibleCount] = useState(0);
12891
+ const startedAt = part.callProviderMetadata?.custom?.startedAt ?? part.startedAt;
12892
+ const hasNestedTools = nestedTools.length > 0;
12893
+ const streamKey = part.toolCallId ?? part.id ?? "";
12894
+ const outputDuration = part.output?.totalDurationMs || part.output?.duration || part.output?.duration_ms;
12895
+ const maskThreshold = 4;
12896
+ const streamHeight = Math.max(1, maxVisibleTools) * 28;
12897
+ const visibleToolCount = isPending ? Math.max(visibleCount, 0) : nestedTools.length;
12898
+ const wasPendingRef = useRef(isPending);
12899
+ const userToggledRef = useRef(false);
12900
+ const openTimerRef = useRef(null);
12901
+ const { fileCount, searchCount } = useMemo(() => {
12902
+ return getNestedCounts(isPending ? nestedTools.slice(0, Math.max(visibleCount, 0)) : nestedTools);
12903
+ }, [
12904
+ isPending,
12905
+ nestedTools,
12906
+ visibleCount
12907
+ ]);
12908
+ const streamCounts = formatStreamCounts(fileCount, searchCount);
12909
+ const listRef = useRef(null);
12910
+ const elapsedMs = useElapsedTime(startedAt, isPending);
12911
+ useEffect(() => {
12912
+ const wasPending = wasPendingRef.current;
12913
+ if (openTimerRef.current) {
12914
+ window.clearTimeout(openTimerRef.current);
12915
+ openTimerRef.current = null;
12916
+ }
12917
+ if (isPending && !wasPending) {
12918
+ if (!userToggledRef.current && defaultOpen !== false) {
12919
+ setExpanded(false);
12920
+ openTimerRef.current = window.setTimeout(() => {
12921
+ setExpanded(true);
12922
+ }, 60);
13163
12923
  }
13164
- context.globalAlpha = 1;
13165
- if (!reduce) frame = window.requestAnimationFrame(draw);
13166
- };
13167
- const handlePointerMove = (event) => {
13168
- if (!pointerEnabled) return;
13169
- const rect = canvas.getBoundingClientRect();
13170
- pointer.inside = true;
13171
- pointer.targetX = event.clientX - rect.left;
13172
- pointer.targetY = event.clientY - rect.top;
13173
- };
13174
- const handlePointerLeave = () => {
13175
- pointer.inside = false;
13176
- };
13177
- const resizeObserver = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(resize);
13178
- resize();
13179
- resizeObserver?.observe(canvas);
13180
- canvas.addEventListener("pointermove", handlePointerMove, { passive: true });
13181
- canvas.addEventListener("pointerleave", handlePointerLeave);
13182
- draw(0);
12924
+ }
12925
+ if (!isPending && wasPending) {
12926
+ setExpanded(false);
12927
+ userToggledRef.current = false;
12928
+ }
12929
+ wasPendingRef.current = isPending;
13183
12930
  return () => {
13184
- if (frame) window.cancelAnimationFrame(frame);
13185
- resizeObserver?.disconnect();
13186
- canvas.removeEventListener("pointermove", handlePointerMove);
13187
- canvas.removeEventListener("pointerleave", handlePointerLeave);
12931
+ if (openTimerRef.current) {
12932
+ window.clearTimeout(openTimerRef.current);
12933
+ openTimerRef.current = null;
12934
+ }
13188
12935
  };
12936
+ }, [defaultOpen, isPending]);
12937
+ useEffect(() => {
12938
+ if (!isPending || nestedTools.length === 0) {
12939
+ setVisibleCount(nestedTools.length);
12940
+ return;
12941
+ }
12942
+ let index = 1;
12943
+ setVisibleCount(Math.min(index, nestedTools.length));
12944
+ const interval = setInterval(() => {
12945
+ index += 1;
12946
+ setVisibleCount(Math.min(index, nestedTools.length));
12947
+ if (index >= nestedTools.length) clearInterval(interval);
12948
+ }, 450);
12949
+ return () => clearInterval(interval);
13189
12950
  }, [
13190
- canHover,
13191
- interactive,
13192
- reduce
12951
+ isPending,
12952
+ nestedTools.length,
12953
+ streamKey
13193
12954
  ]);
13194
- return /* @__PURE__ */ jsx(m.div, {
13195
- "aria-hidden": "true",
13196
- initial: false,
13197
- animate: { opacity: OVERLAY_OPACITY[status] },
13198
- transition: {
13199
- duration: reduce ? 0 : 0.4,
13200
- ease: EASE_OUT
13201
- },
13202
- className: "absolute inset-0 overflow-hidden bg-muted",
13203
- children: /* @__PURE__ */ jsx("canvas", {
13204
- ref: canvasRef,
13205
- className: "absolute inset-0 size-full text-foreground"
13206
- })
12955
+ useEffect(() => {
12956
+ if (!isPending || !listRef.current) return;
12957
+ listRef.current.scrollTop = listRef.current.scrollHeight;
12958
+ }, [isPending, visibleCount]);
12959
+ const subtitle = (() => {
12960
+ if (isPending && hasNestedTools) return streamCounts;
12961
+ if (!isPending && hasNestedTools) {
12962
+ const summary = summarizeNestedTools(nestedTools);
12963
+ if (summary) return summary;
12964
+ }
12965
+ if (!description) return "";
12966
+ return description.length > 60 ? `${description.slice(0, 57)}...` : description;
12967
+ })();
12968
+ const elapsedTimeDisplay = formatElapsedTime(!isPending && outputDuration ? outputDuration : elapsedMs);
12969
+ if (isInterrupted && !part.output) return /* @__PURE__ */ jsx(ToolRowBase, {
12970
+ completeLabel: interruptedLabel,
12971
+ isAnimating: false
13207
12972
  });
13208
- }
13209
- function ImageGeneration({ children, status = "generating", label, prompt, resolution = "1024 \xD7 1024", aspectRatio = "1 / 1", size = "compact", interactive = true, statusText, showStatus = true, onRetry, className, mediaClassName, statusClassName }) {
13210
- const reduce = useReducedMotion() ?? false;
13211
- const active = status === "queued" || status === "generating" || status === "refining";
13212
- const mediaState = MEDIA_STATE[status];
13213
- const resolvedStatusText = statusText ?? STATUS_TEXT[status];
13214
- const resolvedLabel = label ?? (prompt ? `${resolvedStatusText}: ${prompt}` : resolvedStatusText);
13215
- return /* @__PURE__ */ jsx("div", {
13216
- "data-slot": "image-generation",
13217
- "data-state": status,
13218
- "aria-busy": active,
13219
- className: cn("w-full", className),
12973
+ return /* @__PURE__ */ jsx(ToolRowBase, {
12974
+ completeLabel,
12975
+ shimmerLabel,
12976
+ isAnimating: isPending,
12977
+ detail: subtitle,
12978
+ expandable: hasNestedTools,
12979
+ expanded,
12980
+ onToggleExpand: () => {
12981
+ userToggledRef.current = true;
12982
+ setExpanded((prev) => !prev);
12983
+ },
12984
+ trailingContent: showElapsed && elapsedTimeDisplay ? /* @__PURE__ */ jsx("span", {
12985
+ className: "shrink-0 font-normal text-muted-foreground/60 tabular-nums",
12986
+ children: elapsedTimeDisplay
12987
+ }) : void 0,
13220
12988
  children: /* @__PURE__ */ jsxs("div", {
13221
- className: cn("w-full", size === "compact" && "mx-auto max-w-52"),
13222
- children: [
13223
- /* @__PURE__ */ jsxs("div", {
13224
- role: "img",
13225
- "aria-label": resolvedLabel,
13226
- style: { aspectRatio },
13227
- className: "relative isolate w-full overflow-hidden rounded-xl bg-muted",
13228
- children: [
13229
- /* @__PURE__ */ jsx(m.div, {
13230
- "aria-hidden": children ? void 0 : true,
13231
- initial: false,
13232
- animate: reduce ? { opacity: mediaState.opacity } : {
13233
- filter: mediaState.filter,
13234
- opacity: mediaState.opacity,
13235
- scale: mediaState.scale
13236
- },
13237
- transition: reduce ? { duration: 0 } : {
13238
- duration: 0.4,
13239
- ease: EASE_OUT
13240
- },
13241
- className: cn("absolute inset-0 [&>*]:size-full [&>*]:object-cover [&_img]:size-full [&_img]:object-cover", mediaClassName),
13242
- children
13243
- }),
13244
- /* @__PURE__ */ jsx(AnimatePresence, {
13245
- initial: false,
13246
- children: active ? /* @__PURE__ */ jsx(m.div, {
13247
- initial: { opacity: 0 },
13248
- animate: { opacity: 1 },
13249
- exit: { opacity: 0 },
13250
- transition: {
13251
- duration: reduce ? 0 : 0.25,
13252
- ease: EASE_OUT
13253
- },
13254
- className: "absolute inset-0",
13255
- children: /* @__PURE__ */ jsx(DitherField, {
13256
- interactive,
13257
- reduce,
13258
- status
13259
- })
13260
- }, "dither-field") : null
13261
- }),
13262
- resolution ? /* @__PURE__ */ jsx("span", {
13263
- className: "absolute top-2 right-2 z-10 rounded-full bg-background/75 px-2 py-0.5 font-mono text-[0.625rem] tabular-nums text-muted-foreground",
13264
- children: resolution
13265
- }) : null
13266
- ]
13267
- }),
13268
- /* @__PURE__ */ jsx(AnimatePresence, {
13269
- initial: false,
13270
- children: showStatus || prompt ? /* @__PURE__ */ jsxs(m.div, {
13271
- initial: false,
13272
- className: "mt-3 text-left",
13273
- children: [/* @__PURE__ */ jsxs("div", {
13274
- "aria-live": "polite",
13275
- className: cn(showStatus ? "flex min-h-5 items-center gap-2" : "contents", "text-sm font-medium text-foreground", status === "error" && "text-destructive", statusClassName),
13276
- children: [showStatus ? /* @__PURE__ */ jsx(DitherMark, {
13277
- status,
13278
- reduce
13279
- }) : null, /* @__PURE__ */ jsx(AnimatePresence, {
13280
- mode: "popLayout",
13281
- initial: false,
13282
- children: showStatus ? /* @__PURE__ */ jsx(m.span, {
13283
- initial: reduce ? false : {
13284
- opacity: 0,
13285
- y: 4
13286
- },
13287
- animate: {
13288
- opacity: 1,
13289
- y: 0
13290
- },
13291
- exit: reduce ? void 0 : {
13292
- opacity: 0,
13293
- y: -4
13294
- },
13295
- transition: {
13296
- duration: reduce ? 0 : 0.15,
13297
- ease: EASE_OUT
13298
- },
13299
- children: resolvedStatusText
13300
- }, resolvedStatusText) : null
13301
- })]
13302
- }), prompt ? /* @__PURE__ */ jsxs("p", {
13303
- className: "mt-0.5 truncate text-xs text-muted-foreground",
13304
- children: [
13305
- "\u201C",
13306
- prompt,
13307
- "\u201D"
13308
- ]
13309
- }) : null]
13310
- }, "status-block") : null
13311
- }),
13312
- status === "error" && onRetry ? /* @__PURE__ */ jsxs(m.button, {
13313
- type: "button",
13314
- onClick: onRetry,
13315
- whileTap: reduce ? void 0 : { scale: 0.96 },
13316
- transition: SPRING_PRESS,
13317
- className: "mt-3 inline-flex min-h-10 items-center gap-2 rounded-full px-3 text-sm font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring",
13318
- children: [/* @__PURE__ */ jsx(RotateCcw, {
13319
- "aria-hidden": "true",
13320
- className: "size-4"
13321
- }), "Try again"]
13322
- }) : null
13323
- ]
12989
+ className: "relative",
12990
+ children: [isPending && expanded && visibleToolCount > maskThreshold && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 z-10 h-10 bg-linear-to-b from-background to-transparent" }), /* @__PURE__ */ jsx("div", {
12991
+ ref: listRef,
12992
+ className: cn(nestedTools.length > 1 ? "flex flex-col gap-2" : void 0, isPending && expanded && visibleToolCount > maskThreshold && "overflow-y-auto"),
12993
+ style: isPending && expanded && visibleToolCount > maskThreshold ? { height: `${streamHeight}px` } : void 0,
12994
+ children: (isPending ? nestedTools.slice(0, Math.max(visibleCount, 0)) : nestedTools).map((nestedPart, idx) => {
12995
+ const derivedPart = isPending ? {
12996
+ ...nestedPart,
12997
+ state: idx === visibleCount - 1 ? "input-streaming" : "output-available"
12998
+ } : nestedPart;
12999
+ const nestedMeta = toolRegistry[derivedPart.type];
13000
+ if (!nestedMeta) return null;
13001
+ const { isPending: nestedIsPending, isError: nestedIsError } = getToolStatus(derivedPart, chatStatus);
13002
+ return /* @__PURE__ */ jsx(GenericTool, {
13003
+ icon: nestedMeta.icon,
13004
+ title: nestedMeta.title(derivedPart),
13005
+ subtitle: nestedMeta.subtitle?.(derivedPart),
13006
+ isPending: nestedIsPending,
13007
+ isError: nestedIsError
13008
+ }, derivedPart.toolCallId ?? derivedPart.id ?? `${derivedPart.type}-${nestedMeta.title(derivedPart)}`);
13009
+ })
13010
+ })]
13324
13011
  })
13325
13012
  });
13013
+ });
13014
+ function deriveToolStatus(part, chatStatus) {
13015
+ if (part.state === "input-streaming") return "streaming";
13016
+ if (part.state === "output-available") return "success";
13017
+ if (part.state === "output-error") return "error";
13018
+ const { isPending } = getToolStatus(part, chatStatus);
13019
+ return isPending ? "pending" : "success";
13326
13020
  }
13327
- function statusLabel(status) {
13328
- if (status === "in-progress") return "In progress";
13329
- if (status === "completed") return "Completed";
13330
- if (status === "cancelled") return "Cancelled";
13331
- return "Pending";
13332
- }
13333
- function TodoHeaderIcon({ complete }) {
13334
- const reduce = useReducedMotion() ?? false;
13335
- return /* @__PURE__ */ jsx("span", {
13336
- "aria-hidden": "true",
13337
- className: "relative grid size-6 shrink-0 place-items-center",
13338
- children: /* @__PURE__ */ jsx(AnimatePresence, {
13339
- initial: false,
13340
- mode: "popLayout",
13341
- children: complete ? /* @__PURE__ */ jsxs(m.svg, {
13342
- viewBox: "0 0 24 24",
13343
- initial: reduce ? { opacity: 1 } : {
13344
- opacity: 0,
13345
- scale: 0.72
13346
- },
13347
- animate: {
13348
- opacity: 1,
13349
- scale: 1
13350
- },
13351
- exit: { opacity: 0 },
13352
- transition: reduce ? { duration: 0 } : SPRING_SWAP,
13353
- className: "absolute size-5.5 overflow-visible text-emerald-500",
13354
- children: [/* @__PURE__ */ jsx("circle", {
13355
- cx: "12",
13356
- cy: "12",
13357
- r: "9",
13358
- fill: "currentColor"
13359
- }), /* @__PURE__ */ jsx(m.path, {
13360
- d: "M7.5 12.25 10.5 15.25 16.75 8.75",
13361
- fill: "none",
13362
- stroke: "white",
13363
- strokeWidth: "2.25",
13364
- strokeLinecap: "round",
13365
- strokeLinejoin: "round",
13366
- initial: reduce ? { pathLength: 1 } : { pathLength: 0 },
13367
- animate: { pathLength: 1 },
13368
- transition: reduce ? { duration: 0 } : {
13369
- duration: 0.24,
13370
- ease: EASE_OUT
13371
- }
13372
- })]
13373
- }, "complete") : /* @__PURE__ */ jsx(m.span, {
13374
- initial: reduce ? { opacity: 1 } : {
13375
- opacity: 0,
13376
- scale: 0.8
13377
- },
13378
- animate: {
13379
- opacity: 1,
13380
- scale: 1
13381
- },
13382
- exit: reduce ? { opacity: 0 } : {
13383
- opacity: 0,
13384
- scale: 0.72
13385
- },
13386
- transition: reduce ? { duration: 0 } : SPRING_SWAP,
13387
- className: "absolute grid place-items-center text-muted-foreground",
13388
- children: /* @__PURE__ */ jsx(ListTodo, { className: "size-4" })
13389
- }, "todo")
13390
- })
13021
+ var ToolRenderer = memo(function ToolRenderer2({ part, nestedTools, chatStatus, toolRenderers }) {
13022
+ const partType = part.type;
13023
+ switch (partType) {
13024
+ case "tool-Bash":
13025
+ return /* @__PURE__ */ jsx(BashTool, { part });
13026
+ case "tool-IPython":
13027
+ return /* @__PURE__ */ jsx(IpythonTool, { part });
13028
+ case "tool-Edit":
13029
+ case "tool-Write":
13030
+ return /* @__PURE__ */ jsx(EditTool, { part });
13031
+ case "tool-WebSearch":
13032
+ case "tool-Grep":
13033
+ case "tool-Glob":
13034
+ return /* @__PURE__ */ jsx(SearchTool, { part });
13035
+ case "tool-PlanWrite":
13036
+ return /* @__PURE__ */ jsx(PlanTool, {
13037
+ part,
13038
+ chatStatus
13039
+ });
13040
+ case "tool-TodoWrite":
13041
+ return /* @__PURE__ */ jsx(TodoTool, {
13042
+ part,
13043
+ chatStatus
13044
+ });
13045
+ case "tool-Question":
13046
+ return /* @__PURE__ */ jsx(QuestionTool, {
13047
+ part,
13048
+ chatStatus
13049
+ });
13050
+ case "tool-Task":
13051
+ case "tool-Agent": {
13052
+ const labelBase = part.type === "tool-Agent" ? "Agent" : "Task";
13053
+ return /* @__PURE__ */ jsx(ToolGroup, {
13054
+ part,
13055
+ nestedTools,
13056
+ chatStatus,
13057
+ completeLabel: `${labelBase} completed`,
13058
+ shimmerLabel: `Running ${labelBase.toLowerCase()}`,
13059
+ interruptedLabel: `${labelBase} interrupted`,
13060
+ defaultOpen: false
13061
+ });
13062
+ }
13063
+ case "tool-Thinking":
13064
+ return null;
13065
+ }
13066
+ const mcpInfo = parseMcpToolType(partType);
13067
+ if (mcpInfo) {
13068
+ if (toolRenderers) {
13069
+ const CustomRenderer = toolRenderers[mcpInfo.toolName];
13070
+ if (CustomRenderer) return /* @__PURE__ */ jsx(CustomRenderer, {
13071
+ name: mcpInfo.toolName,
13072
+ input: part.input ?? {},
13073
+ output: part.output ? unwrapMcpOutput(part.output) : void 0,
13074
+ status: deriveToolStatus(part, chatStatus)
13075
+ });
13076
+ }
13077
+ return /* @__PURE__ */ jsx(McpTool, {
13078
+ part,
13079
+ mcpInfo,
13080
+ chatStatus
13081
+ });
13082
+ }
13083
+ if (toolRenderers && partType.startsWith("tool-")) {
13084
+ const toolName3 = partType.slice(5);
13085
+ const CustomRenderer = toolRenderers[toolName3];
13086
+ if (CustomRenderer) return /* @__PURE__ */ jsx(CustomRenderer, {
13087
+ name: toolName3,
13088
+ input: part.input ?? {},
13089
+ output: part.output ?? part.result,
13090
+ status: deriveToolStatus(part, chatStatus)
13091
+ });
13092
+ }
13093
+ const meta = toolRegistry[partType];
13094
+ if (meta) {
13095
+ const { isPending: isPending2, isError: isError2 } = getToolStatus(part, chatStatus);
13096
+ return /* @__PURE__ */ jsx(GenericTool, {
13097
+ title: meta.title(part),
13098
+ subtitle: meta.subtitle?.(part),
13099
+ isPending: isPending2,
13100
+ isError: isError2
13101
+ });
13102
+ }
13103
+ const toolName2 = partType.startsWith("tool-") ? partType.slice(5) : partType;
13104
+ const { isPending, isError } = getToolStatus(part, chatStatus);
13105
+ return /* @__PURE__ */ jsx(GenericTool, {
13106
+ title: isPending ? `Running ${toolName2}` : toolName2,
13107
+ isPending,
13108
+ isError
13391
13109
  });
13392
- }
13393
- function TodoStatusIcon({ status, progress }) {
13394
- const reduce = useReducedMotion() ?? false;
13395
- const normalizedProgress = progress === void 0 ? 0.68 : Math.min(100, Math.max(0, progress)) / 100;
13396
- return /* @__PURE__ */ jsxs(m.svg, {
13397
- "aria-hidden": "true",
13398
- viewBox: "0 0 24 24",
13399
- initial: false,
13400
- className: cn("mx-0.5 size-5 shrink-0 overflow-visible text-muted-foreground", status === "in-progress" && "text-foreground", status === "cancelled" && "text-rose-600 dark:text-rose-400"),
13401
- children: [
13402
- /* @__PURE__ */ jsx(m.circle, {
13403
- cx: "12",
13404
- cy: "12",
13405
- r: "9",
13406
- fill: "currentColor",
13407
- stroke: "currentColor",
13408
- strokeWidth: "1.5",
13409
- strokeDasharray: status === "pending" ? "2 3" : void 0,
13410
- strokeLinecap: "round",
13411
- initial: false,
13412
- animate: { fillOpacity: status === "completed" ? 0.06 : 0 },
13413
- transition: reduce ? { duration: 0 } : {
13414
- duration: 0.18,
13415
- ease: EASE_OUT
13416
- },
13417
- className: cn(status === "in-progress" && "opacity-20")
13418
- }),
13419
- /* @__PURE__ */ jsx(m.circle, {
13420
- cx: "12",
13421
- cy: "12",
13422
- r: "9",
13423
- pathLength: "1",
13424
- fill: "none",
13425
- stroke: "currentColor",
13426
- strokeWidth: "2",
13427
- strokeLinecap: "round",
13428
- initial: false,
13429
- animate: {
13430
- pathLength: status === "in-progress" ? normalizedProgress : 0,
13431
- opacity: status === "in-progress" ? 1 : 0,
13432
- rotate: status === "in-progress" && progress === void 0 && !reduce ? 360 : -90
13433
- },
13434
- transition: status === "in-progress" && progress === void 0 && !reduce ? { rotate: {
13435
- duration: 1.1,
13436
- repeat: Infinity,
13437
- ease: "linear"
13438
- } } : reduce ? { duration: 0 } : SPRING_LAYOUT,
13439
- style: { transformOrigin: "12px 12px" }
13440
- }),
13441
- /* @__PURE__ */ jsx(m.path, {
13442
- d: "M7.5 12.25 10.5 15.25 16.75 8.75",
13443
- fill: "none",
13444
- stroke: "currentColor",
13445
- strokeWidth: "2",
13446
- strokeLinecap: "round",
13447
- strokeLinejoin: "round",
13448
- initial: false,
13449
- animate: {
13450
- pathLength: status === "completed" ? 1 : 0,
13451
- opacity: status === "completed" ? 1 : 0
13452
- },
13453
- transition: reduce ? { duration: 0 } : {
13454
- duration: 0.24,
13455
- ease: EASE_OUT
13456
- }
13457
- }),
13458
- /* @__PURE__ */ jsx(m.path, {
13459
- d: "M8.5 8.5 15.5 15.5M15.5 8.5 8.5 15.5",
13460
- fill: "none",
13461
- stroke: "currentColor",
13462
- strokeWidth: "2",
13463
- strokeLinecap: "round",
13464
- initial: false,
13465
- animate: {
13466
- pathLength: status === "cancelled" ? 1 : 0,
13467
- opacity: status === "cancelled" ? 1 : 0
13468
- },
13469
- transition: reduce ? { duration: 0 } : {
13470
- duration: 0.2,
13471
- ease: EASE_OUT
13472
- }
13473
- })
13110
+ });
13111
+ var STATUS_TEXT = {
13112
+ queued: "Waiting to generate",
13113
+ generating: "Generating image",
13114
+ refining: "Refining details",
13115
+ complete: "Image ready",
13116
+ error: "Generation failed"
13117
+ };
13118
+ var MEDIA_STATE = {
13119
+ queued: {
13120
+ filter: "blur(4px) saturate(0.75)",
13121
+ opacity: 0,
13122
+ scale: 1.02
13123
+ },
13124
+ generating: {
13125
+ filter: "blur(3px) saturate(0.85)",
13126
+ opacity: 0,
13127
+ scale: 1.015
13128
+ },
13129
+ refining: {
13130
+ filter: "blur(1.5px) saturate(0.95)",
13131
+ opacity: 0.62,
13132
+ scale: 1.005
13133
+ },
13134
+ complete: {
13135
+ filter: "blur(0px) saturate(1)",
13136
+ opacity: 1,
13137
+ scale: 1
13138
+ },
13139
+ error: {
13140
+ filter: "blur(2px) saturate(0.5)",
13141
+ opacity: 0.28,
13142
+ scale: 1
13143
+ }
13144
+ };
13145
+ var OVERLAY_OPACITY = {
13146
+ queued: 1,
13147
+ generating: 1,
13148
+ refining: 0.48,
13149
+ complete: 0,
13150
+ error: 0
13151
+ };
13152
+ var DOT_GAP = 10;
13153
+ var TWO_PI = Math.PI * 2;
13154
+ function DitherMark({ status, reduce }) {
13155
+ if (status === "complete") return /* @__PURE__ */ jsx(Check, {
13156
+ "aria-hidden": "true",
13157
+ className: "size-3.5"
13158
+ });
13159
+ if (status === "error") return /* @__PURE__ */ jsx(CircleAlert, {
13160
+ "aria-hidden": "true",
13161
+ className: "size-3.5"
13162
+ });
13163
+ return /* @__PURE__ */ jsxs(m.span, {
13164
+ "aria-hidden": "true",
13165
+ animate: reduce ? void 0 : { rotate: 360 },
13166
+ transition: {
13167
+ duration: 2.4,
13168
+ ease: EASE_IN_OUT,
13169
+ repeat: Number.POSITIVE_INFINITY
13170
+ },
13171
+ className: "grid size-3.5 grid-cols-2 place-items-center gap-0.5",
13172
+ children: [
13173
+ /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current" }),
13174
+ /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current opacity-55" }),
13175
+ /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current opacity-55" }),
13176
+ /* @__PURE__ */ jsx("span", { className: "size-1 rounded-[1px] bg-current" })
13474
13177
  ]
13475
13178
  });
13476
13179
  }
13477
- function TodoList({ items, title = "To-dos", open, defaultOpen = true, onOpenChange, collapseOnComplete = true, maxHeight = 248, className }) {
13478
- const reduce = useReducedMotion() ?? false;
13479
- const baseId = useId();
13480
- const triggerId = `${baseId}-trigger`;
13481
- const contentId = `${baseId}-content`;
13482
- const viewportRef = useRef(null);
13483
- const previousComplete = useRef(false);
13484
- const [internalOpen, setInternalOpen] = useState(defaultOpen);
13485
- const currentOpen = open ?? internalOpen;
13486
- const completed = items.filter((item) => item.status === "completed").length;
13487
- const allComplete = items.length > 0 && completed === items.length;
13488
- const itemCount = items.length;
13489
- const setOpen = useCallback((next) => {
13490
- if (open === void 0) setInternalOpen(next);
13491
- onOpenChange?.(next);
13492
- }, [onOpenChange, open]);
13180
+ function DitherField({ interactive, reduce, status }) {
13181
+ const canHover = useHoverCapable();
13182
+ const canvasRef = useRef(null);
13493
13183
  useEffect(() => {
13494
- if (previousComplete.current && !allComplete) setOpen(true);
13495
- if (!previousComplete.current && allComplete && collapseOnComplete) setOpen(false);
13496
- previousComplete.current = allComplete;
13184
+ const canvas = canvasRef.current;
13185
+ const context = canvas?.getContext("2d");
13186
+ if (!canvas || !context) return;
13187
+ let frame = 0;
13188
+ let width = 0;
13189
+ let height = 0;
13190
+ let dotColor = "currentColor";
13191
+ const pointer = {
13192
+ x: 0,
13193
+ y: 0,
13194
+ targetX: 0,
13195
+ targetY: 0,
13196
+ inside: false
13197
+ };
13198
+ const pointerEnabled = interactive && canHover && !reduce;
13199
+ const resize = () => {
13200
+ const rect = canvas.getBoundingClientRect();
13201
+ width = rect.width || canvas.clientWidth || 208;
13202
+ height = rect.height || canvas.clientHeight || 208;
13203
+ const dpr = Math.min(window.devicePixelRatio || 1, 2);
13204
+ canvas.width = Math.round(width * dpr);
13205
+ canvas.height = Math.round(height * dpr);
13206
+ context.setTransform(dpr, 0, 0, dpr, 0, 0);
13207
+ dotColor = window.getComputedStyle(canvas).color;
13208
+ pointer.x = width / 2;
13209
+ pointer.y = height / 2;
13210
+ pointer.targetX = pointer.x;
13211
+ pointer.targetY = pointer.y;
13212
+ };
13213
+ const draw = (time) => {
13214
+ context.clearRect(0, 0, width, height);
13215
+ if (!pointer.inside) {
13216
+ pointer.targetX = width / 2 + (reduce ? 0 : Math.sin(time / 1700) * width * 0.12);
13217
+ pointer.targetY = height / 2 + (reduce ? 0 : Math.cos(time / 2100) * height * 0.1);
13218
+ }
13219
+ const follow = reduce ? 1 : pointer.inside ? 0.16 : 0.045;
13220
+ pointer.x += (pointer.targetX - pointer.x) * follow;
13221
+ pointer.y += (pointer.targetY - pointer.y) * follow;
13222
+ const radius = Math.min(width, height) * 0.38;
13223
+ const columns = Math.ceil(width / DOT_GAP) + 1;
13224
+ const rows = Math.ceil(height / DOT_GAP) + 1;
13225
+ const offsetX = (width - (columns - 1) * DOT_GAP) / 2;
13226
+ const offsetY = (height - (rows - 1) * DOT_GAP) / 2;
13227
+ context.fillStyle = dotColor;
13228
+ for (let row = 0; row < rows; row += 1) for (let column = 0; column < columns; column += 1) {
13229
+ const anchorX = offsetX + column * DOT_GAP;
13230
+ const anchorY = offsetY + row * DOT_GAP;
13231
+ const deltaX = anchorX - pointer.x;
13232
+ const deltaY = anchorY - pointer.y;
13233
+ const distance = Math.hypot(deltaX, deltaY);
13234
+ const proximity = Math.max(0, 1 - distance / radius);
13235
+ const influence = proximity * proximity * (3 - 2 * proximity);
13236
+ const displacement = influence * influence * 9;
13237
+ const directionX = distance > 0 ? deltaX / distance : 0;
13238
+ const directionY = distance > 0 ? deltaY / distance : 0;
13239
+ const x = anchorX + directionX * displacement;
13240
+ const y = anchorY + directionY * displacement;
13241
+ const dotRadius = 0.65 + influence * 0.85;
13242
+ context.globalAlpha = 0.17 + influence * 0.72;
13243
+ context.beginPath();
13244
+ context.arc(x, y, dotRadius, 0, TWO_PI);
13245
+ context.fill();
13246
+ }
13247
+ context.globalAlpha = 1;
13248
+ if (!reduce) frame = window.requestAnimationFrame(draw);
13249
+ };
13250
+ const handlePointerMove = (event) => {
13251
+ if (!pointerEnabled) return;
13252
+ const rect = canvas.getBoundingClientRect();
13253
+ pointer.inside = true;
13254
+ pointer.targetX = event.clientX - rect.left;
13255
+ pointer.targetY = event.clientY - rect.top;
13256
+ };
13257
+ const handlePointerLeave = () => {
13258
+ pointer.inside = false;
13259
+ };
13260
+ const resizeObserver = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(resize);
13261
+ resize();
13262
+ resizeObserver?.observe(canvas);
13263
+ canvas.addEventListener("pointermove", handlePointerMove, { passive: true });
13264
+ canvas.addEventListener("pointerleave", handlePointerLeave);
13265
+ draw(0);
13266
+ return () => {
13267
+ if (frame) window.cancelAnimationFrame(frame);
13268
+ resizeObserver?.disconnect();
13269
+ canvas.removeEventListener("pointermove", handlePointerMove);
13270
+ canvas.removeEventListener("pointerleave", handlePointerLeave);
13271
+ };
13497
13272
  }, [
13498
- allComplete,
13499
- collapseOnComplete,
13500
- setOpen
13273
+ canHover,
13274
+ interactive,
13275
+ reduce
13501
13276
  ]);
13502
- useLayoutEffect(() => {
13503
- const viewport = viewportRef.current;
13504
- if (!viewport || itemCount === 0) return;
13505
- const frame = requestAnimationFrame(() => {
13506
- if (viewport.scrollHeight <= viewport.clientHeight) return;
13507
- if (typeof viewport.scrollTo === "function") viewport.scrollTo({
13508
- top: viewport.scrollHeight,
13509
- behavior: reduce ? "auto" : "smooth"
13510
- });
13511
- else viewport.scrollTop = viewport.scrollHeight;
13512
- });
13513
- return () => cancelAnimationFrame(frame);
13514
- }, [itemCount, reduce]);
13515
- return /* @__PURE__ */ jsxs("section", {
13516
- "aria-label": "Agent task list",
13517
- className: cn("w-full overflow-hidden rounded-2xl border border-border/70", className),
13518
- children: [/* @__PURE__ */ jsxs("button", {
13519
- id: triggerId,
13520
- type: "button",
13521
- "aria-expanded": currentOpen,
13522
- "aria-controls": contentId,
13523
- onClick: () => setOpen(!currentOpen),
13524
- className: "group flex h-11 w-full items-center gap-2.5 rounded-2xl px-3.5 text-left outline-none focus-visible:ring-2 focus-visible:ring-ring",
13277
+ return /* @__PURE__ */ jsx(m.div, {
13278
+ "aria-hidden": "true",
13279
+ initial: false,
13280
+ animate: { opacity: OVERLAY_OPACITY[status] },
13281
+ transition: {
13282
+ duration: reduce ? 0 : 0.4,
13283
+ ease: EASE_OUT
13284
+ },
13285
+ className: "absolute inset-0 overflow-hidden bg-muted",
13286
+ children: /* @__PURE__ */ jsx("canvas", {
13287
+ ref: canvasRef,
13288
+ className: "absolute inset-0 size-full text-foreground"
13289
+ })
13290
+ });
13291
+ }
13292
+ function ImageGeneration({ children, status = "generating", label, prompt, resolution = "1024 \xD7 1024", aspectRatio = "1 / 1", size = "compact", interactive = true, statusText, showStatus = true, onRetry, className, mediaClassName, statusClassName }) {
13293
+ const reduce = useReducedMotion() ?? false;
13294
+ const active = status === "queued" || status === "generating" || status === "refining";
13295
+ const mediaState = MEDIA_STATE[status];
13296
+ const resolvedStatusText = statusText ?? STATUS_TEXT[status];
13297
+ const resolvedLabel = label ?? (prompt ? `${resolvedStatusText}: ${prompt}` : resolvedStatusText);
13298
+ return /* @__PURE__ */ jsx("div", {
13299
+ "data-slot": "image-generation",
13300
+ "data-state": status,
13301
+ "aria-busy": active,
13302
+ className: cn("w-full", className),
13303
+ children: /* @__PURE__ */ jsxs("div", {
13304
+ className: cn("w-full", size === "compact" && "mx-auto max-w-52"),
13525
13305
  children: [
13526
- /* @__PURE__ */ jsx(TodoHeaderIcon, { complete: allComplete }),
13527
- /* @__PURE__ */ jsx("h3", {
13528
- className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground/90",
13529
- children: title
13530
- }),
13531
- /* @__PURE__ */ jsxs("span", {
13532
- className: cn("shrink-0 text-xs font-medium tabular-nums text-muted-foreground", allComplete && "text-emerald-600 dark:text-emerald-400"),
13533
- children: [/* @__PURE__ */ jsxs("span", {
13534
- className: "sr-only",
13535
- children: [
13536
- completed,
13537
- " of ",
13538
- items.length,
13539
- " tasks completed"
13540
- ]
13541
- }), /* @__PURE__ */ jsxs("span", {
13542
- "aria-hidden": "true",
13543
- className: "inline-flex",
13544
- children: [
13545
- /* @__PURE__ */ jsx(ActionSwapRollText, {
13546
- value: String(completed),
13547
- children: completed
13548
- }),
13549
- /* @__PURE__ */ jsx("span", { children: "/" }),
13550
- /* @__PURE__ */ jsx("span", { children: items.length })
13551
- ]
13552
- })]
13306
+ /* @__PURE__ */ jsxs("div", {
13307
+ role: "img",
13308
+ "aria-label": resolvedLabel,
13309
+ style: { aspectRatio },
13310
+ className: "relative isolate w-full overflow-hidden rounded-xl bg-muted",
13311
+ children: [
13312
+ /* @__PURE__ */ jsx(m.div, {
13313
+ "aria-hidden": children ? void 0 : true,
13314
+ initial: false,
13315
+ animate: reduce ? { opacity: mediaState.opacity } : {
13316
+ filter: mediaState.filter,
13317
+ opacity: mediaState.opacity,
13318
+ scale: mediaState.scale
13319
+ },
13320
+ transition: reduce ? { duration: 0 } : {
13321
+ duration: 0.4,
13322
+ ease: EASE_OUT
13323
+ },
13324
+ className: cn("absolute inset-0 [&>*]:size-full [&>*]:object-cover [&_img]:size-full [&_img]:object-cover", mediaClassName),
13325
+ children
13326
+ }),
13327
+ /* @__PURE__ */ jsx(AnimatePresence, {
13328
+ initial: false,
13329
+ children: active ? /* @__PURE__ */ jsx(m.div, {
13330
+ initial: { opacity: 0 },
13331
+ animate: { opacity: 1 },
13332
+ exit: { opacity: 0 },
13333
+ transition: {
13334
+ duration: reduce ? 0 : 0.25,
13335
+ ease: EASE_OUT
13336
+ },
13337
+ className: "absolute inset-0",
13338
+ children: /* @__PURE__ */ jsx(DitherField, {
13339
+ interactive,
13340
+ reduce,
13341
+ status
13342
+ })
13343
+ }, "dither-field") : null
13344
+ }),
13345
+ resolution ? /* @__PURE__ */ jsx("span", {
13346
+ className: "absolute top-2 right-2 z-10 rounded-full bg-background/75 px-2 py-0.5 font-mono text-micro tabular-nums text-muted-foreground",
13347
+ children: resolution
13348
+ }) : null
13349
+ ]
13553
13350
  }),
13554
- /* @__PURE__ */ jsx(m.span, {
13555
- "aria-hidden": "true",
13556
- animate: { rotate: currentOpen ? 180 : 0 },
13557
- transition: reduce ? { duration: 0 } : SPRING_SWAP,
13558
- className: "text-muted-foreground/50 transition-colors group-hover:text-muted-foreground",
13559
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" })
13560
- })
13561
- ]
13562
- }), /* @__PURE__ */ jsx(AgentDisclosure, {
13563
- id: contentId,
13564
- role: "region",
13565
- "aria-labelledby": triggerId,
13566
- open: currentOpen,
13567
- children: /* @__PURE__ */ jsxs("div", {
13568
- ref: viewportRef,
13569
- className: "scrollbar-hide overflow-y-auto px-2 pb-2",
13570
- style: { maxHeight },
13571
- children: [/* @__PURE__ */ jsx("ol", {
13572
- "aria-live": allComplete ? "polite" : "off",
13573
- className: "space-y-0",
13574
- children: /* @__PURE__ */ jsx(AnimatePresence, {
13351
+ /* @__PURE__ */ jsx(AnimatePresence, {
13352
+ initial: false,
13353
+ children: showStatus || prompt ? /* @__PURE__ */ jsxs(m.div, {
13575
13354
  initial: false,
13576
- mode: "popLayout",
13577
- children: items.map((item) => {
13578
- const status = item.status ?? "pending";
13579
- return /* @__PURE__ */ jsxs(m.li, {
13580
- layout: "position",
13581
- initial: reduce ? { opacity: 1 } : {
13582
- opacity: 0,
13583
- y: 6
13584
- },
13585
- animate: {
13586
- opacity: 1,
13587
- y: 0
13588
- },
13589
- exit: reduce ? { opacity: 0 } : {
13590
- opacity: 0,
13591
- y: -3
13592
- },
13593
- transition: reduce ? { duration: 0 } : {
13594
- opacity: {
13595
- duration: 0.18,
13355
+ className: "mt-3 text-left",
13356
+ children: [/* @__PURE__ */ jsxs("div", {
13357
+ "aria-live": "polite",
13358
+ className: cn(showStatus ? "flex min-h-5 items-center gap-2" : "contents", "text-sm font-medium text-foreground", status === "error" && "text-destructive", statusClassName),
13359
+ children: [showStatus ? /* @__PURE__ */ jsx(DitherMark, {
13360
+ status,
13361
+ reduce
13362
+ }) : null, /* @__PURE__ */ jsx(AnimatePresence, {
13363
+ mode: "popLayout",
13364
+ initial: false,
13365
+ children: showStatus ? /* @__PURE__ */ jsx(m.span, {
13366
+ initial: reduce ? false : {
13367
+ opacity: 0,
13368
+ y: 4
13369
+ },
13370
+ animate: {
13371
+ opacity: 1,
13372
+ y: 0
13373
+ },
13374
+ exit: reduce ? void 0 : {
13375
+ opacity: 0,
13376
+ y: -4
13377
+ },
13378
+ transition: {
13379
+ duration: reduce ? 0 : 0.15,
13596
13380
  ease: EASE_OUT
13597
13381
  },
13598
- y: SPRING_LAYOUT,
13599
- layout: SPRING_LAYOUT
13600
- },
13601
- className: "flex min-h-9 items-center gap-2.5 rounded-xl px-1.5 py-1",
13602
- children: [
13603
- /* @__PURE__ */ jsx(TodoStatusIcon, {
13604
- status,
13605
- progress: item.progress
13606
- }),
13607
- /* @__PURE__ */ jsxs("span", {
13608
- className: "sr-only",
13609
- children: [statusLabel(status), ": "]
13610
- }),
13611
- /* @__PURE__ */ jsx("span", {
13612
- className: cn("min-w-0 flex-1 truncate text-sm leading-5", status === "pending" && "text-muted-foreground/65", status === "in-progress" && "text-foreground", status === "completed" && "text-muted-foreground/60", status === "cancelled" && "text-muted-foreground/55"),
13613
- children: /* @__PURE__ */ jsxs("span", {
13614
- className: "relative inline-block max-w-full",
13615
- children: [item.title, /* @__PURE__ */ jsx(m.span, {
13616
- "aria-hidden": "true",
13617
- initial: false,
13618
- animate: {
13619
- scaleX: status === "completed" ? 1 : 0,
13620
- opacity: status === "completed" ? 1 : 0
13621
- },
13622
- transition: reduce ? { duration: 0 } : {
13623
- duration: 0.28,
13624
- ease: EASE_OUT,
13625
- delay: 0.06
13626
- },
13627
- className: "absolute inset-x-0 top-1/2 h-px origin-left bg-current"
13628
- })]
13629
- })
13630
- }),
13631
- item.detail ? /* @__PURE__ */ jsx("span", {
13632
- className: "shrink-0 text-sm text-muted-foreground/55",
13633
- children: item.detail
13634
- }) : null
13635
- ]
13636
- }, item.id);
13637
- })
13638
- })
13639
- }), !items.length && /* @__PURE__ */ jsx("p", {
13640
- className: "px-1.5 py-2 text-sm text-muted-foreground",
13641
- children: "No tasks yet"
13382
+ children: resolvedStatusText
13383
+ }, resolvedStatusText) : null
13384
+ })]
13385
+ }), prompt ? /* @__PURE__ */ jsxs("p", {
13386
+ className: "mt-0.5 truncate text-xs text-muted-foreground",
13387
+ children: [
13388
+ "\u201C",
13389
+ prompt,
13390
+ "\u201D"
13391
+ ]
13392
+ }) : null]
13393
+ }, "status-block") : null
13394
+ }),
13395
+ status === "error" && onRetry ? /* @__PURE__ */ jsxs(m.button, {
13396
+ type: "button",
13397
+ onClick: onRetry,
13398
+ whileTap: reduce ? void 0 : { scale: 0.96 },
13399
+ transition: SPRING_PRESS,
13400
+ className: "mt-3 inline-flex min-h-10 items-center gap-2 rounded-full px-3 text-sm font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring",
13401
+ children: [/* @__PURE__ */ jsx(RotateCcw, {
13402
+ "aria-hidden": "true",
13403
+ className: "size-4"
13404
+ }), "Try again"]
13405
+ }) : null
13406
+ ]
13407
+ })
13408
+ });
13409
+ }
13410
+ function AgentPlan({ steps, activeIndex, className, ...props }) {
13411
+ const total = steps.length;
13412
+ const completed = progressOf(activeIndex, total);
13413
+ const allDone = completed >= total;
13414
+ const progress = pct(completed, total);
13415
+ return /* @__PURE__ */ jsxs("div", {
13416
+ "data-slot": "agent-plan",
13417
+ className: cn("flex w-full max-w-sm flex-col gap-3", className),
13418
+ ...props,
13419
+ children: [
13420
+ /* @__PURE__ */ jsxs("div", {
13421
+ className: "flex items-center justify-between",
13422
+ children: [/* @__PURE__ */ jsx("span", {
13423
+ className: "text-body font-medium",
13424
+ children: "Plan"
13425
+ }), /* @__PURE__ */ jsxs("span", {
13426
+ className: cn(mono, "text-foreground/35 tabular-nums"),
13427
+ children: [
13428
+ completed,
13429
+ " of ",
13430
+ total
13431
+ ]
13642
13432
  })]
13433
+ }),
13434
+ /* @__PURE__ */ jsx("div", {
13435
+ className: "bg-foreground/[0.06] h-[3px] w-full overflow-hidden rounded-full",
13436
+ children: /* @__PURE__ */ jsx("span", {
13437
+ className: "bg-foreground/80 block h-full rounded-full transition-[width] duration-500",
13438
+ style: { width: `${progress}%` }
13439
+ })
13440
+ }),
13441
+ /* @__PURE__ */ jsx("ul", {
13442
+ className: "flex flex-col gap-2.5",
13443
+ children: steps.map((step, i) => {
13444
+ const done = allDone || i < completed;
13445
+ const active = !allDone && i === completed;
13446
+ return /* @__PURE__ */ jsxs("li", {
13447
+ className: "flex items-center gap-2.5 text-body",
13448
+ children: [/* @__PURE__ */ jsx("span", {
13449
+ className: "flex size-4 shrink-0 items-center justify-center",
13450
+ children: done ? /* @__PURE__ */ jsx(Check, { className: "text-foreground/35 size-3.5" }) : active ? /* @__PURE__ */ jsx(LoaderCircle, { className: "text-foreground/90 size-3.5 animate-spin motion-reduce:animate-none" }) : /* @__PURE__ */ jsx("span", {
13451
+ "aria-hidden": true,
13452
+ className: "bg-foreground/15 size-1.5 rounded-full"
13453
+ })
13454
+ }), /* @__PURE__ */ jsx("span", {
13455
+ className: cn(done && "text-foreground/40", active && "text-foreground/90", !done && !active && "text-foreground/35"),
13456
+ children: step
13457
+ })]
13458
+ }, step);
13459
+ })
13643
13460
  })
13644
- })]
13461
+ ]
13462
+ });
13463
+ }
13464
+ function sessionAgentPlanPresentation(items) {
13465
+ if (items.length === 0) return void 0;
13466
+ const steps = items.flatMap((item) => {
13467
+ const title = item.title.trim();
13468
+ return title ? [title] : [];
13469
+ });
13470
+ if (steps.length !== items.length) return void 0;
13471
+ let activeIndex = 0;
13472
+ while (activeIndex < items.length && items[activeIndex]?.status === "completed") activeIndex += 1;
13473
+ if (items.slice(activeIndex + 1).some((item) => item.status === "completed")) return void 0;
13474
+ return {
13475
+ steps,
13476
+ activeIndex
13477
+ };
13478
+ }
13479
+ function SessionAgentPlan({ presentation, className }) {
13480
+ return /* @__PURE__ */ jsx(AgentPlan, {
13481
+ steps: presentation.steps,
13482
+ activeIndex: presentation.activeIndex,
13483
+ "aria-label": `Plan progress: ${Math.min(presentation.activeIndex, presentation.steps.length)} of ${presentation.steps.length} steps completed`,
13484
+ className
13645
13485
  });
13646
13486
  }
13647
13487
  function getStatusCopy(status) {
@@ -13655,7 +13495,7 @@ function getStatusCopy(status) {
13655
13495
  }
13656
13496
  function getStatusBadgeClass(status) {
13657
13497
  if (status === "pending") return "border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400";
13658
- if (status === "approving" || status === "running") return "border-blue-500/30 bg-blue-500/10 text-blue-600 dark:text-blue-400";
13498
+ if (status === "approving" || status === "running") return "border-primary/30 bg-primary/10 text-primary";
13659
13499
  if (status === "approved" || status === "complete") return "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400";
13660
13500
  return "border-rose-500/30 bg-rose-500/10 text-rose-600 dark:text-rose-400";
13661
13501
  }
@@ -13702,7 +13542,7 @@ function ToolApproval({ tool, title = "Allow this tool to run?", description, pa
13702
13542
  children: tool
13703
13543
  })]
13704
13544
  }), /* @__PURE__ */ jsx("span", {
13705
- className: cn("shrink-0 rounded-full border px-2 py-0.5 text-[0.6875rem] font-medium transition-colors", getStatusBadgeClass(status)),
13545
+ className: cn("shrink-0 rounded-full border px-2 py-0.5 text-caption font-medium transition-colors", getStatusBadgeClass(status)),
13706
13546
  children: getStatusCopy(status)
13707
13547
  })]
13708
13548
  }),
@@ -13960,7 +13800,7 @@ function getTodos(input, summary) {
13960
13800
  const title = getString(record, "content", "title", "text", "label");
13961
13801
  if (!title) return [];
13962
13802
  const rawStatus = getString(record, "status");
13963
- const status = rawStatus === "in_progress" ? "in-progress" : rawStatus === "completed" ? "completed" : rawStatus === "cancelled" ? "cancelled" : "pending";
13803
+ const status = rawStatus === "in_progress" || rawStatus === "in-progress" ? "in-progress" : rawStatus === "completed" ? "completed" : rawStatus === "cancelled" ? "cancelled" : "pending";
13964
13804
  return [{
13965
13805
  id: `${index}-${title}`,
13966
13806
  title,
@@ -14029,7 +13869,21 @@ function sourceLabelFor(name, language) {
14029
13869
  if (language === "text") return "Text";
14030
13870
  return language.toUpperCase();
14031
13871
  }
14032
- function normalizeFleetToolPart(part, chatStatus) {
13872
+ var normalizeCache = /* @__PURE__ */ new WeakMap();
13873
+ function normalizeToolPart(part, chatStatus) {
13874
+ if (part && typeof part === "object") {
13875
+ const cached = normalizeCache.get(part);
13876
+ if (cached && cached.chatStatus === chatStatus) return cached.value;
13877
+ const value = normalizeToolPartUncached(part, chatStatus);
13878
+ normalizeCache.set(part, {
13879
+ chatStatus,
13880
+ value
13881
+ });
13882
+ return value;
13883
+ }
13884
+ return normalizeToolPartUncached(part, chatStatus);
13885
+ }
13886
+ function normalizeToolPartUncached(part, chatStatus) {
14033
13887
  const source = asRecord(part);
14034
13888
  if (!source) return void 0;
14035
13889
  const name = toolName(source);
@@ -14040,7 +13894,6 @@ function normalizeFleetToolPart(part, chatStatus) {
14040
13894
  const status = resultStatus(source, chatStatus);
14041
13895
  const command = getString(input, "command", "cmd", "code", "script");
14042
13896
  const sourceLanguage = sourceLanguageFor(name, command);
14043
- const thought = getString(input, "thought", "text");
14044
13897
  const metadata = [];
14045
13898
  if (outputSummary.durationMs !== void 0) metadata.push(`${outputSummary.durationMs}ms`);
14046
13899
  if (outputSummary.kernelRestarted) metadata.push("kernel restarted");
@@ -14049,7 +13902,7 @@ function normalizeFleetToolPart(part, chatStatus) {
14049
13902
  const citations = lowerName.includes("search") || lowerName.includes("web") || lowerName.includes("source") || lowerName.includes("citation") ? getCitations(outputSummary) : [];
14050
13903
  const imageUrl = lowerName.includes("image") || lowerName.includes("generat") ? getImageUrl(outputSummary) : void 0;
14051
13904
  const approval = getApproval(input, outputSummary);
14052
- const content = getOutputContent(outputSummary, output) || (lowerName === "thinking" || lowerName === "reasoning" ? thought ?? "" : "");
13905
+ const content = getOutputContent(outputSummary, output);
14053
13906
  const hasOutputContent = Boolean(content.trim());
14054
13907
  const id = typeof source.toolCallId === "string" && source.toolCallId ? source.toolCallId : `${name}-${JSON.stringify(input ?? {})}`;
14055
13908
  let detail;
@@ -14096,7 +13949,7 @@ function normalizeFleetToolPart(part, chatStatus) {
14096
13949
  detail
14097
13950
  };
14098
13951
  }
14099
- function toFleetPlanItems(items) {
13952
+ function toSessionPlanItems(items) {
14100
13953
  return items.map((item) => ({
14101
13954
  id: String(item.id),
14102
13955
  title: typeof item.title === "string" ? item.title : "",
@@ -14148,17 +14001,17 @@ function SourceBlock({ code, language, languageLabel, status }) {
14148
14001
  wrap: true
14149
14002
  });
14150
14003
  }
14151
- var BeuiToolRenderer = memo(function BeuiToolRenderer2({ part, chatStatus, fallback }) {
14152
- const normalized = normalizeFleetToolPart(part, chatStatus);
14004
+ var SpecializedToolRenderer = memo(function SpecializedToolRenderer2({ part, chatStatus, fallback }) {
14005
+ const normalized = normalizeToolPart(part, chatStatus);
14153
14006
  if (!normalized || normalized.lowerName === "question") return fallback ?? null;
14154
14007
  const { detail, status } = normalized;
14155
14008
  if (!detail) return fallback ?? null;
14156
14009
  if (detail.kind === "todo") {
14157
- const planItems = toFleetPlanItems(detail.items);
14010
+ const planItems = toSessionPlanItems(detail.items);
14158
14011
  const pendingDecision = Boolean(part.input?.pendingDecision);
14159
14012
  if (normalized.lowerName === "planwrite" && pendingDecision) return fallback ?? null;
14160
- const planPresentation = normalized.lowerName === "planwrite" && part.input?.executing ? fleetAgentPlanPresentation(planItems) : void 0;
14161
- if (planPresentation) return /* @__PURE__ */ jsx(FleetAgentPlan, {
14013
+ const planPresentation = normalized.lowerName === "planwrite" && part.input?.executing ? sessionAgentPlanPresentation(planItems) : void 0;
14014
+ if (planPresentation) return /* @__PURE__ */ jsx(SessionAgentPlan, {
14162
14015
  presentation: planPresentation,
14163
14016
  className: "mb-2"
14164
14017
  });
@@ -14228,15 +14081,12 @@ var BeuiToolRenderer = memo(function BeuiToolRenderer2({ part, chatStatus, fallb
14228
14081
  ]
14229
14082
  });
14230
14083
  });
14231
- var fleet_pi_tool_renderer_exports = /* @__PURE__ */ __exportAll({ FleetPiToolRenderer: () => FleetPiToolRenderer });
14232
- var FleetPiToolRenderer = memo(function FleetPiToolRenderer2(props) {
14084
+ var session_tool_renderer_exports = /* @__PURE__ */ __exportAll({ SessionToolRenderer: () => SessionToolRenderer });
14085
+ var SessionToolRenderer = memo(function SessionToolRenderer2(props) {
14233
14086
  const partType = props.part.type;
14234
14087
  if (partType === "tool-Thinking" || partType === "tool-FleetReasoning") return null;
14235
- const fallback = /* @__PURE__ */ jsx(ToolRenderer, {
14236
- ...props,
14237
- toolRenderers: PI_TOOL_RENDERERS
14238
- });
14239
- if (partType.startsWith("tool-")) return /* @__PURE__ */ jsx(BeuiToolRenderer, {
14088
+ const fallback = /* @__PURE__ */ jsx(ToolRenderer, { ...props });
14089
+ if (partType.startsWith("tool-")) return /* @__PURE__ */ jsx(SpecializedToolRenderer, {
14240
14090
  ...props,
14241
14091
  fallback
14242
14092
  });
@@ -14244,8 +14094,8 @@ var FleetPiToolRenderer = memo(function FleetPiToolRenderer2(props) {
14244
14094
  });
14245
14095
 
14246
14096
  export {
14247
- fleet_pi_tool_renderer_exports,
14248
- FleetPiToolRenderer
14097
+ session_tool_renderer_exports,
14098
+ SessionToolRenderer
14249
14099
  };
14250
14100
  /**
14251
14101
  * @license lucide-react v1.38.0 - ISC