@qredence/fleet 0.6.1 → 0.6.3

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