@qredence/fleet 0.5.1 → 0.5.7

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 (200) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/bin/fleet-prime.mjs +6 -0
  3. package/dist/web/client/assets/action-swap-roll-BB8DFMuf.js +1 -0
  4. package/dist/web/client/assets/agent-activity-CDcDNVC6.js +1 -0
  5. package/dist/web/client/assets/agent-disclosure-B8SnhQXL.js +1 -0
  6. package/dist/web/client/assets/analytics-stub-B8MIkiDB.js +1 -0
  7. package/dist/web/client/assets/{artifacts-panel-CX62LQ13.js → artifacts-panel-CmHYXfoo.js} +1 -1
  8. package/dist/web/client/assets/button-BV9NafmI.js +1 -0
  9. package/dist/web/client/assets/{chat-CsepBQwy.js → chat-W-yOMyG_.js} +1 -1
  10. package/dist/web/client/assets/chat-command-palette-DiG-i3uJ.js +1 -0
  11. package/dist/web/client/assets/check-JjHKAZas.js +1 -0
  12. package/dist/web/client/assets/chevron-up-CnSvySGH.js +1 -0
  13. package/dist/web/client/assets/circle-alert-CONlFReH.js +1 -0
  14. package/dist/web/client/assets/circle-x-CkKCB__4.js +1 -0
  15. package/dist/web/client/assets/citations-CpTFUvx7.js +2 -0
  16. package/dist/web/client/assets/collapsible-BoXtZZWN.js +1 -0
  17. package/dist/web/client/assets/command-Cx-UYeQ9.js +1 -0
  18. package/dist/web/client/assets/createBaseUIEventDetails-DV0dQrBX.js +1 -0
  19. package/dist/web/client/assets/dialog-Dh7WpGIu.js +1 -0
  20. package/dist/web/client/assets/dist-BPaFisIZ.js +41 -0
  21. package/dist/web/client/assets/earth-DGZXAN5r.js +1 -0
  22. package/dist/web/client/assets/ease-u56MhKYS.js +1 -0
  23. package/dist/web/client/assets/file-text-T-NcAlZs.js +1 -0
  24. package/dist/web/client/assets/fleet-message-queue-B6zAK-hX.js +1 -0
  25. package/dist/web/client/assets/{fleet-pi-tool-renderer-BD_ZAjlG.js → fleet-pi-tool-renderer-Btq9mDUe.js} +29 -29
  26. package/dist/web/client/assets/fleet-reasoning-panel-MtbSdoCv.js +1 -0
  27. package/dist/web/client/assets/fleet-subagent-list-iszvrvy_.js +1 -0
  28. package/dist/web/client/assets/fleet-tool-timeline-COzPrwr8.js +1 -0
  29. package/dist/web/client/assets/{fork-picker-dialog-C2cVJUbf.js → fork-picker-dialog-CAhWx0G5.js} +1 -1
  30. package/dist/web/client/assets/gauge-DNpstbBn.js +1 -0
  31. package/dist/web/client/assets/generative-text-renderer-C1JrmYfx.js +6 -0
  32. package/dist/web/client/assets/globals-Bfr0jrPq.css +2 -0
  33. package/dist/web/client/assets/horizontal-resize-Bl3AyBJg.js +1 -0
  34. package/dist/web/client/assets/image-BbPmlw-n.js +1 -0
  35. package/dist/web/client/assets/index-QgUwd4m8.js +12 -0
  36. package/dist/web/client/assets/input-Bol3TP4v.js +1 -0
  37. package/dist/web/client/assets/input-group-D5gi9zBK.js +1 -0
  38. package/dist/web/client/assets/{ipython-tool-BfeIa0nK.js → ipython-tool-BrMePqD-.js} +1 -1
  39. package/dist/web/client/assets/{markdown-DG7pUdsX.js → markdown-RD_ydkyD.js} +2 -2
  40. package/dist/web/client/assets/{markdown-code-BgMzpy7O.js → markdown-code-ETqXqY8E.js} +1 -1
  41. package/dist/web/client/assets/message-square-hbDao-A1.js +1 -0
  42. package/dist/web/client/assets/model-selector-list-CJY9pyt2.js +1 -0
  43. package/dist/web/client/assets/notify-DKTqXChG.js +1 -0
  44. package/dist/web/client/assets/{openui-renderer-DlUo6ehT.js → openui-renderer-BZMghkzQ.js} +8 -8
  45. package/dist/web/client/assets/{prime-agent-artifacts-CHGb5V_j.js → prime-agent-artifacts-C-g1VPiW.js} +1 -1
  46. package/dist/web/client/assets/prompt-suggestions-CXM6knMK.js +1 -0
  47. package/dist/web/client/assets/provider-catalog-CHKFGwHr.js +1 -0
  48. package/dist/web/client/assets/provider-label-KkqVX1CI.js +1 -0
  49. package/dist/web/client/assets/range-BWOHiLNe.js +1 -0
  50. package/dist/web/client/assets/refresh-cw-IThTJ3j-.js +1 -0
  51. package/dist/web/client/assets/repl-panel-CCh4ly7J.js +1 -0
  52. package/dist/web/client/assets/{resource-helpers-ULlyU8qK.js → resource-helpers-Q2T0YCMO.js} +1 -1
  53. package/dist/web/client/assets/resources-panel-Bo8dfUdm.js +1 -0
  54. package/dist/web/client/assets/right-panel-context-B2VAZ2p4.js +1 -0
  55. package/dist/web/client/assets/right-panel-registry-C5fQcBKw.js +2 -0
  56. package/dist/web/client/assets/routes-C1hRkRkv.js +16 -0
  57. package/dist/web/client/assets/safe-external-url-D3PJJIcM.js +1 -0
  58. package/dist/web/client/assets/session-insights-panel-CQdT90Op.js +1 -0
  59. package/dist/web/client/assets/settings-dialog-CvvM6T0m.js +1 -0
  60. package/dist/web/client/assets/{sparkles-C5H3Jtgf.js → shield-check-CkA2viVW.js} +1 -1
  61. package/dist/web/client/assets/{skeleton-loaders-fStjEeRP.js → skeleton-loaders-DjGv9LLA.js} +1 -1
  62. package/dist/web/client/assets/sparkles-DuclzqlE.js +1 -0
  63. package/dist/web/client/assets/subagent-chat-panel-tGCg6gcn.js +1 -0
  64. package/dist/web/client/assets/subagent-transcript-NO0PR8RU.js +1 -0
  65. package/dist/web/client/assets/subagent-utils-CQbaJ1g-.js +1 -0
  66. package/dist/web/client/assets/subagents-panel-BkFLsQQY.js +1 -0
  67. package/dist/web/client/assets/surfaces-cW-gp56p.js +1 -0
  68. package/dist/web/client/assets/switch-CcOFiQBK.js +1 -0
  69. package/dist/web/client/assets/terminal-DOS1s1gm.js +1 -0
  70. package/dist/web/client/assets/toast-ATq44uAL.js +1 -0
  71. package/dist/web/client/assets/tool-result-pklnrxSW.js +4 -0
  72. package/dist/web/client/assets/use-reduced-motion-eORd7fqW.js +9 -0
  73. package/dist/web/client/assets/useBaseUiId-CHqXB2UQ.js +1 -0
  74. package/dist/web/client/assets/useControlled-CJJ9BOQB.js +1 -0
  75. package/dist/web/client/assets/workspace-panel-BmMW7h7b.js +1 -0
  76. package/dist/web/client/assets/wrench-BJNNe07k.js +1 -0
  77. package/dist/web/client/assets/x-CsRC_tCI.js +1 -0
  78. package/dist/web/client/bundle-budget.json +10 -0
  79. package/dist/web/server/_tanstack-start-manifest_v-B4BnRTa_-DR7WQTT5.js +90 -0
  80. package/dist/web/server/agent-activity-Dx6AlDhN-JXOL2EXK.js +514 -0
  81. package/dist/web/server/{artifacts-panel-D9w1DHAN-FGRDCYU2.js → artifacts-panel-CloS3-ij-XWYXKL6A.js} +30 -22
  82. package/dist/web/server/{chat-command-palette-BaenPkCN-BHSOPGU4.js → chat-command-palette-Cc0uGvNm-GKENKTO7.js} +48 -22
  83. package/dist/web/server/{chunk-KPNGZR2R.js → chunk-3B6M63AO.js} +206 -209
  84. package/dist/web/server/chunk-3D4Z32XA.js +22 -0
  85. package/dist/web/server/chunk-3SSHBMDS.js +196 -0
  86. package/dist/web/server/chunk-4PQ6OD6J.js +22 -0
  87. package/dist/web/server/{chunk-5AVQZ4AZ.js → chunk-4UBOIY2S.js} +2 -1
  88. package/dist/web/server/chunk-56SEDI5N.js +19 -0
  89. package/dist/web/server/chunk-6QNW66XR.js +19 -0
  90. package/dist/web/server/chunk-744IIIDL.js +19 -0
  91. package/dist/web/server/{chunk-52SJQXO4.js → chunk-7PQTPSEE.js} +568 -568
  92. package/dist/web/server/{chunk-XYYNYFFD.js → chunk-7SR6WDM2.js} +2 -2
  93. package/dist/web/server/chunk-ANL4B775.js +60 -0
  94. package/dist/web/server/chunk-BNQWMQHD.js +35 -0
  95. package/dist/web/server/{chunk-X2TUFLTP.js → chunk-C5X6G26O.js} +436 -454
  96. package/dist/web/server/chunk-C66BSNA6.js +42 -0
  97. package/dist/web/server/{chunk-3GSFXWL5.js → chunk-DEUBJJZN.js} +4 -59
  98. package/dist/web/server/chunk-E365EOXJ.js +35 -0
  99. package/dist/web/server/{chunk-5WZFFNFY.js → chunk-EFAGCVZ3.js} +2 -23
  100. package/dist/web/server/{chunk-Y6LJ4WBI.js → chunk-EGQ6ZX4D.js} +563 -830
  101. package/dist/web/server/{chunk-DO3TVNGA.js → chunk-EKBKGAWX.js} +12 -10
  102. package/dist/web/server/{chunk-RPROZ2JC.js → chunk-F6MGAW3L.js} +133 -133
  103. package/dist/web/server/chunk-GABXCOY3.js +37 -0
  104. package/dist/web/server/chunk-GV7DJIHY.js +36 -0
  105. package/dist/web/server/{chunk-PWK2HJIV.js → chunk-HSJMLO36.js} +5 -252
  106. package/dist/web/server/{chunk-46VQY7SG.js → chunk-HU4AIJV3.js} +4 -4
  107. package/dist/web/server/{chunk-H64JLONZ.js → chunk-HZY3LBGP.js} +146 -2
  108. package/dist/web/server/{chunk-3IKSPTYI.js → chunk-J6MRJXUH.js} +22 -15
  109. package/dist/web/server/{chunk-FE4KN6T2.js → chunk-JOSTE7WK.js} +7 -5
  110. package/dist/web/server/{chunk-QJBEWT4E.js → chunk-K3BXQG3N.js} +27 -292
  111. package/dist/web/server/chunk-K4ESBQ3R.js +20 -0
  112. package/dist/web/server/chunk-KOIPYBJF.js +3773 -0
  113. package/dist/web/server/{chunk-44IVTHDV.js → chunk-KZSM3BHO.js} +28 -119
  114. package/dist/web/server/chunk-L46H6IDX.js +13 -0
  115. package/dist/web/server/chunk-LNGWHEE6.js +206 -0
  116. package/dist/web/server/{chunk-2U7PWSJX.js → chunk-MOSVTKH5.js} +262 -3661
  117. package/dist/web/server/{chunk-MDYA4NXK.js → chunk-NJRYX4A2.js} +4 -4
  118. package/dist/web/server/chunk-NNMZQN7Q.js +296 -0
  119. package/dist/web/server/{chunk-VHCAD46L.js → chunk-NPPG2GTW.js} +7 -7
  120. package/dist/web/server/{chunk-AZZHUVJR.js → chunk-PJNYH5SR.js} +7 -303
  121. package/dist/web/server/{chunk-7APYEQIO.js → chunk-QAE5SXDK.js} +1 -24
  122. package/dist/web/server/chunk-QTFCJGOY.js +189 -0
  123. package/dist/web/server/{chunk-FBOO3G67.js → chunk-RANJ6OJ3.js} +9 -9
  124. package/dist/web/server/chunk-RPBSDXJ4.js +62 -0
  125. package/dist/web/server/{chunk-PCJ5EKFE.js → chunk-RYHIJMFD.js} +63 -34
  126. package/dist/web/server/{chunk-NLIUTTKL.js → chunk-S3PQ6HKH.js} +1 -16
  127. package/dist/web/server/chunk-SG4W4SPQ.js +31 -0
  128. package/dist/web/server/{chunk-LESNF5O4.js → chunk-T23OO4SC.js} +2 -11
  129. package/dist/web/server/{chunk-FVWDJNXR.js → chunk-UNZJQ7CY.js} +6 -4
  130. package/dist/web/server/chunk-V3S6BVXO.js +22 -0
  131. package/dist/web/server/{chunk-M2FGGPNA.js → chunk-VGDP4YDU.js} +70 -45
  132. package/dist/web/server/{chunk-WK7CQS2N.js → chunk-W5GRNHV5.js} +51 -49
  133. package/dist/web/server/{chunk-HBZ6YKRB.js → chunk-WN77JNYY.js} +2 -2
  134. package/dist/web/server/{chunk-B2F6MLVZ.js → chunk-XFVL5ITL.js} +2246 -2228
  135. package/dist/web/server/{chunk-EIVNRYP3.js → chunk-XKYEXPLQ.js} +2 -17
  136. package/dist/web/server/{chunk-6GMKRR3C.js → chunk-XNYQSCB2.js} +2 -2
  137. package/dist/web/server/chunk-YHXAXJ6I.js +22 -0
  138. package/dist/web/server/chunk-YLMXYMLG.js +86 -0
  139. package/dist/web/server/chunk-YNGDUWCF.js +56 -0
  140. package/dist/web/server/chunk-ZJFA4F5X.js +280 -0
  141. package/dist/web/server/fleet-message-queue-Bn0_3Efe-G4BZR2EU.js +74 -0
  142. package/dist/web/server/fleet-pi-tool-renderer-C52SZmPx-CIAH3IV7.js +51 -0
  143. package/dist/web/server/fleet-reasoning-panel-C_e7wzVm-SDHEWDQT.js +199 -0
  144. package/dist/web/server/fleet-subagent-list-CQltKswG-EKCMQHDI.js +18 -0
  145. package/dist/web/server/fleet-tool-timeline-KENErMKg-HTN7SW3D.js +16 -0
  146. package/dist/web/server/{fork-picker-dialog-BZzfxdQd-Y725VJ7G.js → fork-picker-dialog-DK9YGQuB-4QEFWRU4.js} +6 -5
  147. package/dist/web/server/{markdown-Boni3lHk-AZGKDNAR.js → markdown-QcSUaLyd-6DJUK5NC.js} +1 -1
  148. package/dist/web/server/{markdown-code-BrWukbg3-D2GN4Y77.js → markdown-code-Dyo1_13a-52ZQZSPE.js} +2 -2
  149. package/dist/web/server/model-selector-list-CEfWjRc--GBW2GUO6.js +289 -0
  150. package/dist/web/server/{openui-renderer-Cg4RSE9k-7BTJIYZJ.js → openui-renderer-Dk0Ak9cW-MUJQHDAS.js} +19 -16
  151. package/dist/web/server/prompt-suggestions-BOmHi4-J-C563CHFU.js +30 -0
  152. package/dist/web/server/{repl-panel-BEQrC2ef-V3YEZ7EO.js → repl-panel-D9E8nkQy-L45ZNG2V.js} +4 -3
  153. package/dist/web/server/{resources-panel-CwKh4U9f-D3VDEMDW.js → resources-panel-B03M8bEp-SZG726N5.js} +7 -6
  154. package/dist/web/server/{router-CEahIUpn-SRG7XKIH.js → router-BE9HcX2W-JMQ3JWE5.js} +1756 -1374
  155. package/dist/web/server/{routes-BznemByz-F4DJAYIM.js → routes-CJTRGB1Z-WJKXJFFT.js} +3748 -3955
  156. package/dist/web/server/server.js +3 -3
  157. package/dist/web/server/{session-insights-panel-JfeTHE0d-3HZB3ZWI.js → session-insights-panel-BHZyKDTo-LRMAMA3O.js} +4 -2
  158. package/dist/web/server/{settings-dialog-DgeBMORv-7SRSENPM.js → settings-dialog-yDibpbBH-TCLJ7NRJ.js} +172 -161
  159. package/dist/web/server/{start-CLAD7RcD-56S4BWMM.js → start-BYVnok_H-IA6TWGA3.js} +1 -1
  160. package/dist/web/server/subagent-chat-panel-B1YoZIKO-DFRUDQJ2.js +82 -0
  161. package/dist/web/server/subagents-panel-dJJwpsEL-FTWWCHND.js +200 -0
  162. package/dist/web/server/{workspace-panel-y54P79_B-VPIYUXF6.js → workspace-panel-BC_H8Jri-5MHAEQQS.js} +22 -18
  163. package/package.json +5 -5
  164. package/dist/web/client/assets/analytics-stub-Jh3lkb8P.js +0 -1
  165. package/dist/web/client/assets/button-0At5xSyU.js +0 -1
  166. package/dist/web/client/assets/chat-command-palette-C4sSf8Kg.js +0 -1
  167. package/dist/web/client/assets/collapsible-DmyYcezk.js +0 -1
  168. package/dist/web/client/assets/command-CB6emP8m.js +0 -2
  169. package/dist/web/client/assets/conversation-turns-ByFoWPXe.js +0 -6
  170. package/dist/web/client/assets/dialog-DZ44tBtH.js +0 -1
  171. package/dist/web/client/assets/dist-MNgIFxqY.js +0 -41
  172. package/dist/web/client/assets/ease-vFBiNFNK.js +0 -9
  173. package/dist/web/client/assets/file-text-BhQ0ZnoU.js +0 -1
  174. package/dist/web/client/assets/globals-CqqQdk2S.css +0 -2
  175. package/dist/web/client/assets/horizontal-resize-C1TpRLNC.js +0 -1
  176. package/dist/web/client/assets/index-DweoFRMs.js +0 -12
  177. package/dist/web/client/assets/input-CqC82Agz.js +0 -1
  178. package/dist/web/client/assets/input-group-H0TG-mkU.js +0 -1
  179. package/dist/web/client/assets/notify-Duj26eeZ.js +0 -1
  180. package/dist/web/client/assets/provider-catalog-BZhZuKSz.js +0 -1
  181. package/dist/web/client/assets/provider-label-jKm8v18u.js +0 -1
  182. package/dist/web/client/assets/range-vSJ7Ux_5.js +0 -2
  183. package/dist/web/client/assets/repl-panel-DiGS6uCw.js +0 -1
  184. package/dist/web/client/assets/resources-panel-DSU7VGX2.js +0 -1
  185. package/dist/web/client/assets/routes-CxlNCi_v.js +0 -16
  186. package/dist/web/client/assets/safe-external-url-Bl_78dpZ.js +0 -1
  187. package/dist/web/client/assets/session-insights-panel-DwmwiikS.js +0 -1
  188. package/dist/web/client/assets/settings-dialog-CkfpTKfM.js +0 -1
  189. package/dist/web/client/assets/subagents-panel-DGnsK6Nx.js +0 -1
  190. package/dist/web/client/assets/switch-BFEBpUEU.js +0 -1
  191. package/dist/web/client/assets/toast-C4s7FYYa.js +0 -1
  192. package/dist/web/client/assets/tool-result-CBzwwUE9.js +0 -4
  193. package/dist/web/client/assets/useBaseUiId-B9f7fokB.js +0 -1
  194. package/dist/web/client/assets/useControlled-CoY1jSuL.js +0 -1
  195. package/dist/web/client/assets/workspace-panel-CjdXlEvd.js +0 -1
  196. package/dist/web/client/assets/x-BgciQ7_C.js +0 -1
  197. package/dist/web/server/_tanstack-start-manifest_v-bDUlyKY0-KFW35JRO.js +0 -82
  198. package/dist/web/server/chunk-ZEVZFLIY.js +0 -334
  199. package/dist/web/server/fleet-pi-tool-renderer-lJvZWmBJ-4M5YI6VS.js +0 -35
  200. package/dist/web/server/subagents-panel-CzZe3co7-2VZ5JTWF.js +0 -332
@@ -1,46 +1,40 @@
1
1
  import {
2
- LazyMarkdown,
3
- Terminal,
4
- useHoverCapable
5
- } from "./chunk-44IVTHDV.js";
2
+ Image
3
+ } from "./chunk-GV7DJIHY.js";
6
4
  import {
7
5
  notify
8
- } from "./chunk-EIVNRYP3.js";
6
+ } from "./chunk-K4ESBQ3R.js";
7
+ import {
8
+ LazyMarkdown,
9
+ useHoverCapable
10
+ } from "./chunk-KZSM3BHO.js";
9
11
  import {
10
- CircleX,
11
- Copy,
12
- Wrench
13
- } from "./chunk-PWK2HJIV.js";
12
+ Copy
13
+ } from "./chunk-LNGWHEE6.js";
14
14
  import {
15
15
  AnimatePresence,
16
- EASE_OUT,
17
- SPRING_LAYOUT,
18
- m,
19
16
  useReducedMotion
20
- } from "./chunk-QJBEWT4E.js";
21
- import {
22
- CircleCheck,
23
- LoaderCircle
24
- } from "./chunk-PKCTG7EW.js";
17
+ } from "./chunk-ZJFA4F5X.js";
25
18
  import {
26
19
  ChevronRight
27
20
  } from "./chunk-7QCDOBZ3.js";
21
+ import {
22
+ EASE_OUT,
23
+ SPRING_LAYOUT,
24
+ m
25
+ } from "./chunk-K3BXQG3N.js";
28
26
  import {
29
27
  segmentOpenUIContent
30
28
  } from "./chunk-NFRJDPB3.js";
31
- import {
32
- ChevronDown
33
- } from "./chunk-QLY3L4A2.js";
34
29
  import {
35
30
  Check
36
- } from "./chunk-NLIUTTKL.js";
31
+ } from "./chunk-6QNW66XR.js";
37
32
  import {
38
33
  X
39
- } from "./chunk-X2TUFLTP.js";
34
+ } from "./chunk-YHXAXJ6I.js";
40
35
  import {
41
- CircleAlert,
42
36
  FileText
43
- } from "./chunk-7APYEQIO.js";
37
+ } from "./chunk-QAE5SXDK.js";
44
38
  import {
45
39
  createLucideIcon
46
40
  } from "./chunk-E26EAQIM.js";
@@ -48,7 +42,7 @@ import {
48
42
  cn
49
43
  } from "./chunk-DJMHPJBP.js";
50
44
 
51
- // web/app/dist/server/assets/conversation-turns-wRm6Ard7.js
45
+ // web/app/dist/server/assets/generative-text-renderer-DuVL688Q.js
52
46
  import { Suspense, cloneElement, createContext, lazy, memo, useCallback, useContext, useEffect, useEffectEvent, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
53
47
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
54
48
  import { createPortal } from "react-dom";
@@ -92,65 +86,6 @@ var FileCode = createLucideIcon("file-code", [
92
86
  key: "yinavb"
93
87
  }]
94
88
  ]);
95
- var FilePenLine = createLucideIcon("file-pen-line", [
96
- ["path", {
97
- d: "M14.364 13.634a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506l4.013-4.009a1 1 0 0 0-3.004-3.004z",
98
- key: "ukzhwg"
99
- }],
100
- ["path", {
101
- d: "M14.487 7.858A1 1 0 0 1 14 7V2",
102
- key: "1klhew"
103
- }],
104
- ["path", {
105
- d: "M20 19.645V20a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l2.516 2.516",
106
- key: "rxaxab"
107
- }],
108
- ["path", {
109
- d: "M8 18h1",
110
- key: "13wk12"
111
- }]
112
- ]);
113
- var FileSearch = createLucideIcon("file-search", [
114
- ["path", {
115
- d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
116
- key: "1oefj6"
117
- }],
118
- ["path", {
119
- d: "M14 2v5a1 1 0 0 0 1 1h5",
120
- key: "wfsgrz"
121
- }],
122
- ["circle", {
123
- cx: "11.5",
124
- cy: "14.5",
125
- r: "2.5",
126
- key: "1bq0ko"
127
- }],
128
- ["path", {
129
- d: "M13.3 16.3 15 18",
130
- key: "2quom7"
131
- }]
132
- ]);
133
- var Image = createLucideIcon("image", [
134
- ["rect", {
135
- width: "18",
136
- height: "18",
137
- x: "3",
138
- y: "3",
139
- rx: "2",
140
- ry: "2",
141
- key: "1m3agn"
142
- }],
143
- ["circle", {
144
- cx: "9",
145
- cy: "9",
146
- r: "2",
147
- key: "af1f0g"
148
- }],
149
- ["path", {
150
- d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",
151
- key: "1xmnt7"
152
- }]
153
- ]);
154
89
  var MessageSideContext = createContext(void 0);
155
90
  var MessageBubbleContext = createContext({
156
91
  animateIn: true,
@@ -585,8 +520,8 @@ function useMessageScrollerRail({ navigation, followThreshold, contentRef, viewp
585
520
  scheduleRailSync,
586
521
  scrollToRailItem: useCallback((item) => {
587
522
  const viewport = viewportRef.current;
588
- const target2 = railTargetsRef.current.get(item.id);
589
- if (!viewport || !target2) return;
523
+ const target = railTargetsRef.current.get(item.id);
524
+ if (!viewport || !target) return;
590
525
  const lastItem = railItems.at(-1)?.id === item.id;
591
526
  setActiveRailId(item.id);
592
527
  if (lastItem) {
@@ -597,7 +532,7 @@ function useMessageScrollerRail({ navigation, followThreshold, contentRef, viewp
597
532
  setFollowing(false);
598
533
  markProgrammaticScroll(reduce || !smooth ? "auto" : "smooth");
599
534
  const viewportRect = viewport.getBoundingClientRect();
600
- const targetRect = target2.getBoundingClientRect();
535
+ const targetRect = target.getBoundingClientRect();
601
536
  const top = viewport.scrollTop + targetRect.top - viewportRect.top - (viewport.clientHeight - targetRect.height) / 2;
602
537
  const behavior = reduce || !smooth ? "auto" : "smooth";
603
538
  if (typeof viewport.scrollTo === "function") viewport.scrollTo({
@@ -812,537 +747,169 @@ function MessageContent({ className, ...props }) {
812
747
  ...props
813
748
  });
814
749
  }
815
- var ErrorMessage = memo(function ErrorMessage2({ title = "Something went wrong", message, className }) {
816
- return /* @__PURE__ */ jsx("div", {
817
- className: cn("flex justify-start", className),
818
- children: /* @__PURE__ */ jsxs("div", {
819
- className: "rounded-[8px] border border-red-500/30 bg-red-500/10 px-4 py-2.5 text-sm text-an-foreground",
820
- children: [/* @__PURE__ */ jsx("div", {
821
- className: "font-medium text-an-foreground",
822
- children: title
823
- }), /* @__PURE__ */ jsx("div", {
824
- className: "mt-0.5 text-an-foreground-muted",
825
- children: message
826
- })]
827
- })
750
+ function ImageLightbox({ open, onClose, images, initialIndex = 0 }) {
751
+ const [currentIndex, setCurrentIndex] = useState(initialIndex);
752
+ const hasMultipleImages = images.length > 1;
753
+ useEffect(() => {
754
+ if (open) setCurrentIndex(initialIndex);
755
+ }, [open, initialIndex]);
756
+ const goToPrevious = useCallback((event) => {
757
+ event?.stopPropagation();
758
+ setCurrentIndex((prev) => prev > 0 ? prev - 1 : images.length - 1);
759
+ }, [images.length]);
760
+ const goToNext = useCallback((event) => {
761
+ event?.stopPropagation();
762
+ setCurrentIndex((prev) => prev < images.length - 1 ? prev + 1 : 0);
763
+ }, [images.length]);
764
+ const onLightboxKeyDown = useEffectEvent((event) => {
765
+ switch (event.key) {
766
+ case "ArrowLeft":
767
+ event.preventDefault();
768
+ if (hasMultipleImages) goToPrevious();
769
+ break;
770
+ case "ArrowRight":
771
+ event.preventDefault();
772
+ if (hasMultipleImages) goToNext();
773
+ }
828
774
  });
829
- });
830
- function formatPayload(value) {
831
- if (typeof value === "string") return value;
832
- if (value === void 0) return "";
833
- try {
834
- return JSON.stringify(value, null, 2) ?? "";
835
- } catch {
836
- return String(value);
837
- }
838
- }
839
- function PayloadPart({ part }) {
840
- const payload = formatPayload(part.payload);
841
- return /* @__PURE__ */ jsxs("section", {
842
- "data-payload-kind": part.kind,
843
- className: "w-full min-w-0 overflow-hidden rounded-xl border border-border/60 bg-muted/40 text-sm",
775
+ useEffect(() => {
776
+ if (!open) return;
777
+ const handler = (event) => onLightboxKeyDown(event);
778
+ window.addEventListener("keydown", handler, true);
779
+ return () => window.removeEventListener("keydown", handler, true);
780
+ }, [open]);
781
+ useEffect(() => {
782
+ if (!open) return;
783
+ const previousOverflow = document.body.style.overflow;
784
+ document.body.style.overflow = "hidden";
785
+ return () => {
786
+ document.body.style.overflow = previousOverflow;
787
+ };
788
+ }, [open]);
789
+ const dialogRef = useRef(null);
790
+ const onLightDismiss = useEffectEvent((event) => {
791
+ if (dialogRef.current && event.target === dialogRef.current) onClose();
792
+ });
793
+ useEffect(() => {
794
+ if (!open) return;
795
+ const dialog = dialogRef.current;
796
+ if (!dialog) return;
797
+ if (!dialog.open) dialog.showModal();
798
+ const handler = (event) => onLightDismiss(event);
799
+ dialog.addEventListener("click", handler);
800
+ return () => {
801
+ dialog.removeEventListener("click", handler);
802
+ if (dialog.open) dialog.close();
803
+ };
804
+ }, [open]);
805
+ if (typeof document === "undefined") return null;
806
+ if (!open) return null;
807
+ const currentImage = images[currentIndex] ?? images[0];
808
+ if (!currentImage?.url) return null;
809
+ return createPortal(/* @__PURE__ */ jsxs("dialog", {
810
+ ref: dialogRef,
811
+ "aria-label": "Image viewer",
812
+ onClose: () => onClose(),
813
+ className: "fixed inset-0 z-50 m-0 flex h-full max-h-none w-full max-w-none items-center justify-center border-0 bg-black/90 p-0 backdrop:bg-transparent",
844
814
  children: [
845
- /* @__PURE__ */ jsx("div", {
846
- className: "border-b border-border/50 px-3 py-2 text-xs font-medium text-muted-foreground",
847
- children: part.title
815
+ /* @__PURE__ */ jsx("button", {
816
+ type: "button",
817
+ onClick: onClose,
818
+ "aria-label": "Close fullscreen (Esc)",
819
+ className: "absolute top-4 right-4 z-10 inline-flex size-9 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
820
+ children: /* @__PURE__ */ jsx(X, { className: "size-5" })
848
821
  }),
849
- part.text ? /* @__PURE__ */ jsx("pre", {
850
- className: "m-0 whitespace-pre-wrap break-words px-3 py-3 font-mono text-xs leading-5 text-foreground/80",
851
- children: part.text
852
- }) : null,
853
- payload ? /* @__PURE__ */ jsxs("details", {
854
- open: true,
855
- className: "border-t border-border/50 px-3 py-2",
856
- children: [/* @__PURE__ */ jsx("summary", {
857
- className: "cursor-pointer text-xs font-medium text-muted-foreground",
858
- children: "Payload"
859
- }), /* @__PURE__ */ jsx("pre", {
860
- className: "m-0 mt-2 max-w-full whitespace-pre-wrap break-words font-mono text-xs leading-5 text-foreground/70",
861
- children: payload
822
+ hasMultipleImages && /* @__PURE__ */ jsx("button", {
823
+ type: "button",
824
+ onClick: goToPrevious,
825
+ "aria-label": "Previous image (\u2190)",
826
+ className: "absolute top-1/2 left-4 z-10 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
827
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-6" })
828
+ }),
829
+ /* @__PURE__ */ jsx("img", {
830
+ src: currentImage.url,
831
+ alt: currentImage.filename ?? "Image preview",
832
+ className: "max-h-[85vh] max-w-[90vw] object-contain select-none",
833
+ onClick: (event) => event.stopPropagation(),
834
+ draggable: false
835
+ }),
836
+ hasMultipleImages && /* @__PURE__ */ jsx("button", {
837
+ type: "button",
838
+ onClick: goToNext,
839
+ "aria-label": "Next image (\u2192)",
840
+ className: "absolute top-1/2 right-4 z-10 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
841
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-6" })
842
+ }),
843
+ hasMultipleImages && /* @__PURE__ */ jsxs("div", {
844
+ className: "absolute bottom-6 left-1/2 flex -translate-x-1/2 flex-col items-center gap-3",
845
+ children: [/* @__PURE__ */ jsx("div", {
846
+ className: "flex gap-2",
847
+ children: images.map((image, idx) => /* @__PURE__ */ jsx("button", {
848
+ type: "button",
849
+ onClick: (event) => {
850
+ event.stopPropagation();
851
+ setCurrentIndex(idx);
852
+ },
853
+ "aria-label": `Go to image ${idx + 1}`,
854
+ className: cn("size-2 rounded-full transition-all", idx === currentIndex ? "scale-125 bg-white" : "bg-white/40 hover:bg-white/60")
855
+ }, image.url))
856
+ }), /* @__PURE__ */ jsxs("span", {
857
+ className: "text-sm text-white/70",
858
+ children: [
859
+ currentIndex + 1,
860
+ " / ",
861
+ images.length
862
+ ]
862
863
  })]
863
- }) : null
864
+ })
864
865
  ]
865
- });
866
+ }), document.body);
866
867
  }
867
- function isRecord$2(value) {
868
- return typeof value === "object" && value !== null;
868
+ function formatFileSize(bytes) {
869
+ if (bytes < 1024) return `${bytes} B`;
870
+ if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
871
+ return `${(bytes / 1048576).toFixed(1)} MB`;
869
872
  }
870
- function parseStructuredJson(value) {
871
- if (typeof value !== "string") return value;
872
- const trimmed = value.trim();
873
- if (!trimmed) return value;
874
- try {
875
- const parsed = JSON.parse(trimmed);
876
- return isRecord$2(parsed) || Array.isArray(parsed) ? parsed : value;
877
- } catch {
878
- return value;
879
- }
880
- }
881
- function normalizeToolPart(part) {
882
- if (!isRecord$2(part)) return part;
883
- if (typeof part.type !== "string" || !part.type.startsWith("tool-")) return part;
884
- const normalizedInput = parseStructuredJson(part.input);
885
- const normalizedOutput = parseStructuredJson(part.output);
886
- const normalizedResult = parseStructuredJson(part.result);
887
- const inputChanged = normalizedInput !== part.input;
888
- const outputChanged = normalizedOutput !== part.output;
889
- const resultChanged = normalizedResult !== part.result;
890
- if (!inputChanged && !outputChanged && !resultChanged) return part;
891
- const normalizedPart = { ...part };
892
- if (inputChanged) normalizedPart.input = normalizedInput;
893
- if (outputChanged) normalizedPart.output = normalizedOutput;
894
- if (resultChanged) normalizedPart.result = normalizedResult;
895
- return normalizedPart;
896
- }
897
- function normalizeAssistantToolParts(parts) {
898
- let changed = false;
899
- const normalizedParts = parts.map((part) => {
900
- const normalizedPart = normalizeToolPart(part);
901
- if (normalizedPart !== part) changed = true;
902
- return normalizedPart;
903
- });
904
- return changed ? normalizedParts : parts;
905
- }
906
- var timeFormatter = new Intl.DateTimeFormat("en-US", {
907
- hour: "numeric",
908
- minute: "2-digit",
909
- hour12: true
910
- });
911
- var dateFormatter = new Intl.DateTimeFormat("en-US", {
912
- month: "short",
913
- day: "numeric"
914
- });
915
- function formatTimestamp(date) {
916
- const now = /* @__PURE__ */ new Date();
917
- if (date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate()) return timeFormatter.format(date);
918
- return dateFormatter.format(date);
919
- }
920
- function CopyButton({ text, onCopied }) {
921
- const [copied, setCopied] = useState(false);
922
- const copiedTimerRef = useRef(null);
923
- useEffect(() => {
924
- return () => {
925
- if (copiedTimerRef.current) window.clearTimeout(copiedTimerRef.current);
926
- };
927
- }, []);
928
- const handleCopy = async () => {
929
- try {
930
- await navigator.clipboard.writeText(text);
931
- setCopied(true);
932
- if (copiedTimerRef.current) window.clearTimeout(copiedTimerRef.current);
933
- copiedTimerRef.current = window.setTimeout(() => {
934
- setCopied(false);
935
- copiedTimerRef.current = null;
936
- }, 2e3);
937
- notify.success("Copied to clipboard");
938
- onCopied?.();
939
- } catch {
940
- notify.error("Failed to copy to clipboard");
941
- }
942
- };
943
- return /* @__PURE__ */ jsx("button", {
944
- type: "button",
945
- tabIndex: -1,
946
- "aria-label": copied ? "Copied" : "Copy message",
947
- onClick: handleCopy,
948
- onPointerDown: (event) => {
949
- event.stopPropagation();
950
- },
951
- onMouseDown: (event) => event.stopPropagation(),
952
- className: cn("flex size-6 items-center justify-center rounded-md transition-[background-color,opacity,transform] duration-150 ease-out active:scale-[0.97]", "bg-transparent opacity-50 hover:bg-an-foreground/10 hover:opacity-100"),
953
- children: /* @__PURE__ */ jsxs("div", {
954
- className: "relative h-3.5 w-3.5",
955
- children: [/* @__PURE__ */ jsx(Copy, { className: cn("absolute inset-0 h-3.5 w-3.5 text-an-foreground-muted transition-[opacity,transform] duration-150 ease-out", copied ? "scale-50 opacity-0" : "scale-100 opacity-100") }), /* @__PURE__ */ jsx(Check, { className: cn("absolute inset-0 h-3.5 w-3.5 text-an-foreground-muted transition-[opacity,transform] duration-150 ease-out", copied ? "scale-100 opacity-100" : "scale-50 opacity-0") })]
956
- })
957
- });
958
- }
959
- function MessageToolbar({ text, timestamp, heightClass, hoverClass, isVisible, alignClass, onCopied }) {
960
- return /* @__PURE__ */ jsxs("div", {
961
- className: cn("pointer-events-none flex items-center gap-1 pt-1 text-xs text-an-foreground-muted/70 opacity-0 transition-opacity duration-100", heightClass, alignClass, hoverClass, isVisible && "pointer-events-auto opacity-100"),
962
- onMouseDown: (event) => event.stopPropagation(),
963
- onPointerDown: (event) => event.stopPropagation(),
964
- children: [timestamp && /* @__PURE__ */ jsx("span", { children: timestamp }), text && /* @__PURE__ */ jsx(CopyButton, {
965
- text,
966
- onCopied
967
- })]
968
- });
969
- }
970
- function isRecord$1(value) {
971
- return typeof value === "object" && value !== null;
972
- }
973
- function isTextPart(part) {
974
- return isRecord$1(part) && part.type === "text" && typeof part.text === "string";
975
- }
976
- function isErrorPart(part) {
977
- return isRecord$1(part) && part.type === "error" && typeof part.message === "string";
978
- }
979
- function isPayloadPart(part) {
980
- return isRecord$1(part) && part.type === "payload" && typeof part.kind === "string" && typeof part.title === "string";
981
- }
982
- function isV5ToolPart(part) {
983
- if (!isRecord$1(part)) return false;
984
- const partType = part.type;
985
- return partType === "dynamic-tool" || typeof partType === "string" && partType.startsWith("tool-");
986
- }
987
- function getTextFromParts(parts, joiner) {
988
- const texts = [];
989
- for (const part of parts) if (isTextPart(part)) texts.push(part.text);
990
- return texts.join(joiner);
991
- }
992
- memo(function UserTurn(props) {
993
- const { message, UserMessageComponent, userMessageClassName, onCopied, display } = props;
994
- const { enableImagePreview, showCopyToolbar, isMounted, isCopyVisible } = display;
995
- const text = getTextFromParts(message.parts ?? [], "");
996
- const hasParts = (message.parts ?? []).length > 0;
997
- if (!text && !hasParts) return null;
998
- const userCreatedAt = message?.createdAt;
999
- const userCopyKey = `user-${message.id}`;
1000
- const userTimestamp = isMounted && userCreatedAt ? formatTimestamp(new Date(userCreatedAt)) : void 0;
1001
- return /* @__PURE__ */ jsxs("div", {
1002
- className: "group/user-message",
1003
- children: [/* @__PURE__ */ jsx(UserMessageComponent, {
1004
- message,
1005
- className: userMessageClassName,
1006
- enableImagePreview
1007
- }), (showCopyToolbar && Boolean(text) || Boolean(userTimestamp)) && /* @__PURE__ */ jsx(MessageToolbar, {
1008
- text: showCopyToolbar ? text : "",
1009
- timestamp: userTimestamp,
1010
- heightClass: "h-[28px]",
1011
- hoverClass: "group-hover/user-message:opacity-100 group-hover/user-message:pointer-events-auto",
1012
- isVisible: isCopyVisible,
1013
- alignClass: "justify-end",
1014
- onCopied: () => onCopied(userCopyKey)
1015
- })]
1016
- });
1017
- });
1018
- memo(function AssistantTurn(props) {
1019
- const { assistantMsgs, turnKey, ToolRendererComponent, TextRendererComponent, toolRenderers, onOpenUIAction, onOpenUIArtifactReady, onOpenArtifact, onCopied, stream, copy, display } = props;
1020
- const { isLast: isLastTurn, isStreaming } = stream;
1021
- const { enabled: showCopyToolbar, isVisible: isCopyVisible } = copy;
1022
- const { suppressQuestionTool } = display;
1023
- const assistantText = getTextFromParts(assistantMsgs.flatMap((msg) => msg.parts ?? []), "\n\n");
1024
- const isTurnStreaming = isStreaming && isLastTurn;
1025
- const showToolbar = showCopyToolbar && Boolean(assistantText.trim()) && !isTurnStreaming;
1026
- const copyKey = `assistant-${turnKey}-all`;
1027
- const toolbarText = showCopyToolbar ? assistantText : "";
1028
- return /* @__PURE__ */ jsxs("div", {
1029
- className: "group/assistant-turn",
1030
- children: [/* @__PURE__ */ jsx("div", {
1031
- className: "flex flex-col gap-3",
1032
- children: assistantMsgs.map((msg, i) => {
1033
- const isLastMsg = isLastTurn && i === assistantMsgs.length - 1;
1034
- return /* @__PURE__ */ jsx(AssistantParts, {
1035
- msg,
1036
- isLast: isLastMsg,
1037
- isStreaming,
1038
- suppressQuestionTool,
1039
- ToolRendererComponent,
1040
- TextRendererComponent,
1041
- toolRenderers,
1042
- onOpenUIAction,
1043
- onOpenUIArtifactReady,
1044
- onOpenArtifact
1045
- }, msg.id);
1046
- })
1047
- }), (showToolbar || isCopyVisible) && /* @__PURE__ */ jsx(MessageToolbar, {
1048
- text: toolbarText,
1049
- heightClass: "h-[48px] flex items-start w-full",
1050
- hoverClass: "group-hover/assistant-turn:opacity-100 group-hover/assistant-turn:pointer-events-auto",
1051
- isVisible: isCopyVisible,
1052
- alignClass: "justify-start",
1053
- onCopied: () => onCopied(copyKey)
1054
- })]
1055
- });
1056
- });
1057
- var TOOL_CALL_KEY_PREFIX = "tool-call:";
1058
- var UNKEYED_TOOL_KEY_PREFIX = "unkeyed-tool:";
1059
- function getAssistantToolElementKey(messageId, part, occurrence) {
1060
- if (part.toolCallId) return `${TOOL_CALL_KEY_PREFIX}${part.toolCallId}`;
1061
- return `${UNKEYED_TOOL_KEY_PREFIX}${messageId}:${part.type}:${occurrence}`;
1062
- }
1063
- function buildAssistantElements(parts, opts) {
1064
- const { messageId, isLast, isStreaming, suppressQuestionTool, suppressTextWhenPlanWrite = false, ToolRendererComponent, TextRendererComponent, toolRenderers, onOpenUIAction, onOpenUIArtifactReady, onOpenArtifact } = opts;
1065
- const elems = [];
1066
- const textChunks = [];
1067
- const hasPlanWritePresentation = suppressTextWhenPlanWrite && parts.some((part) => isV5ToolPart(part) && part.type === "tool-PlanWrite");
1068
- const taskPartIds = new Set(parts.filter((p) => isV5ToolPart(p) && (p.type === "tool-Task" || p.type === "tool-Agent") && typeof p.toolCallId === "string").map((p) => p.toolCallId));
1069
- const nestedToolsMap = /* @__PURE__ */ new Map();
1070
- const nestedToolIds = /* @__PURE__ */ new Set();
1071
- const unkeyedToolOccurrences = /* @__PURE__ */ new Map();
1072
- for (const part of parts) {
1073
- if (!isV5ToolPart(part)) continue;
1074
- if (part.type === "tool-TaskOutput") continue;
1075
- if (!part.toolCallId || !part.toolCallId.includes(":")) continue;
1076
- const parentId = part.toolCallId.split(":")[0];
1077
- if (!taskPartIds.has(parentId)) continue;
1078
- if (!nestedToolsMap.has(parentId)) nestedToolsMap.set(parentId, []);
1079
- nestedToolsMap.get(parentId).push(part);
1080
- nestedToolIds.add(part.toolCallId);
1081
- }
1082
- let i = 0;
1083
- while (i < parts.length) {
1084
- const part = parts[i];
1085
- if (isV5ToolPart(part) && part.type === "tool-TaskOutput") {
1086
- i++;
1087
- continue;
1088
- }
1089
- if (isTextPart(part)) {
1090
- const text2 = part.text;
1091
- if (text2 && !hasPlanWritePresentation) textChunks.push(text2);
1092
- i++;
1093
- continue;
1094
- }
1095
- if (isErrorPart(part)) {
1096
- elems.push(/* @__PURE__ */ jsx(ErrorMessage, {
1097
- title: part.title,
1098
- message: part.message
1099
- }, `${messageId}-error-${part.title}-${part.message}`));
1100
- i++;
1101
- continue;
1102
- }
1103
- if (isPayloadPart(part)) {
1104
- elems.push(/* @__PURE__ */ jsx(PayloadPart, { part }, `${messageId}-payload-${i}`));
1105
- i++;
1106
- continue;
1107
- }
1108
- if (isV5ToolPart(part)) {
1109
- if (suppressQuestionTool && part.type === "tool-Question") {
1110
- i++;
1111
- continue;
1112
- }
1113
- if (part.toolCallId && nestedToolIds.has(part.toolCallId)) {
1114
- i++;
1115
- continue;
1116
- }
1117
- const chatStreamingStatus = isLast && isStreaming ? "streaming" : void 0;
1118
- const toolCallId = part.toolCallId;
1119
- const nestedTools = (part.type === "tool-Task" || part.type === "tool-Agent") && toolCallId ? nestedToolsMap.get(toolCallId) || [] : void 0;
1120
- const occurrence = part.toolCallId ? 0 : unkeyedToolOccurrences.get(part.type) ?? 0;
1121
- if (!part.toolCallId) unkeyedToolOccurrences.set(part.type, occurrence + 1);
1122
- elems.push(/* @__PURE__ */ jsx(ToolRendererComponent, {
1123
- part,
1124
- nestedTools,
1125
- chatStatus: chatStreamingStatus,
1126
- toolRenderers
1127
- }, getAssistantToolElementKey(messageId, part, occurrence)));
1128
- i++;
1129
- continue;
1130
- }
1131
- i++;
1132
- }
1133
- const text = textChunks.join("\n\n");
1134
- if (text) elems.push(/* @__PURE__ */ jsx("div", {
1135
- className: "group/assistant-text text-[14px]",
1136
- children: /* @__PURE__ */ jsx(TextRendererComponent, {
1137
- content: text,
1138
- isStreaming,
1139
- messageId,
1140
- onOpenUIAction,
1141
- onOpenUIArtifactReady,
1142
- onOpenArtifact,
1143
- className: "leading-relaxed [&_p]:leading-relaxed"
1144
- })
1145
- }, `${messageId}-text-final`));
1146
- return elems;
1147
- }
1148
- function AssistantParts({ msg, isLast, isStreaming, suppressQuestionTool, ToolRendererComponent, TextRendererComponent, toolRenderers, onOpenUIAction, onOpenUIArtifactReady, onOpenArtifact }) {
1149
- const parts = useMemo(() => normalizeAssistantToolParts(msg.parts ?? []), [msg.parts]);
1150
- const elements = useMemo(() => buildAssistantElements(parts, {
1151
- messageId: msg.id,
1152
- isLast,
1153
- isStreaming,
1154
- suppressQuestionTool,
1155
- ToolRendererComponent,
1156
- TextRendererComponent,
1157
- toolRenderers,
1158
- onOpenUIAction,
1159
- onOpenUIArtifactReady,
1160
- onOpenArtifact
1161
- }), [
1162
- parts,
1163
- msg.id,
1164
- isLast,
1165
- isStreaming,
1166
- suppressQuestionTool,
1167
- ToolRendererComponent,
1168
- TextRendererComponent,
1169
- toolRenderers,
1170
- onOpenUIAction,
1171
- onOpenUIArtifactReady,
1172
- onOpenArtifact
1173
- ]);
1174
- if (elements.length > 1) return /* @__PURE__ */ jsx("div", {
1175
- className: "group/assistant-turn flex flex-col gap-3",
1176
- children: elements
1177
- });
1178
- return /* @__PURE__ */ jsx("div", {
1179
- className: "group/assistant-turn",
1180
- children: elements
1181
- });
1182
- }
1183
- function ImageLightbox({ open, onClose, images, initialIndex = 0 }) {
1184
- const [currentIndex, setCurrentIndex] = useState(initialIndex);
1185
- const hasMultipleImages = images.length > 1;
1186
- useEffect(() => {
1187
- if (open) setCurrentIndex(initialIndex);
1188
- }, [open, initialIndex]);
1189
- const goToPrevious = useCallback((event) => {
1190
- event?.stopPropagation();
1191
- setCurrentIndex((prev) => prev > 0 ? prev - 1 : images.length - 1);
1192
- }, [images.length]);
1193
- const goToNext = useCallback((event) => {
1194
- event?.stopPropagation();
1195
- setCurrentIndex((prev) => prev < images.length - 1 ? prev + 1 : 0);
1196
- }, [images.length]);
1197
- const onLightboxKeyDown = useEffectEvent((event) => {
1198
- switch (event.key) {
1199
- case "ArrowLeft":
1200
- event.preventDefault();
1201
- if (hasMultipleImages) goToPrevious();
1202
- break;
1203
- case "ArrowRight":
1204
- event.preventDefault();
1205
- if (hasMultipleImages) goToNext();
1206
- }
1207
- });
1208
- useEffect(() => {
1209
- if (!open) return;
1210
- const handler = (event) => onLightboxKeyDown(event);
1211
- window.addEventListener("keydown", handler, true);
1212
- return () => window.removeEventListener("keydown", handler, true);
1213
- }, [open]);
1214
- useEffect(() => {
1215
- if (!open) return;
1216
- const previousOverflow = document.body.style.overflow;
1217
- document.body.style.overflow = "hidden";
1218
- return () => {
1219
- document.body.style.overflow = previousOverflow;
1220
- };
1221
- }, [open]);
1222
- const dialogRef = useRef(null);
1223
- const onLightDismiss = useEffectEvent((event) => {
1224
- if (dialogRef.current && event.target === dialogRef.current) onClose();
1225
- });
1226
- useEffect(() => {
1227
- if (!open) return;
1228
- const dialog = dialogRef.current;
1229
- if (!dialog) return;
1230
- if (!dialog.open) dialog.showModal();
1231
- const handler = (event) => onLightDismiss(event);
1232
- dialog.addEventListener("click", handler);
1233
- return () => {
1234
- dialog.removeEventListener("click", handler);
1235
- if (dialog.open) dialog.close();
1236
- };
1237
- }, [open]);
1238
- if (typeof document === "undefined") return null;
1239
- if (!open) return null;
1240
- const currentImage = images[currentIndex] ?? images[0];
1241
- if (!currentImage?.url) return null;
1242
- return createPortal(/* @__PURE__ */ jsxs("dialog", {
1243
- ref: dialogRef,
1244
- "aria-label": "Image viewer",
1245
- onClose: () => onClose(),
1246
- className: "fixed inset-0 z-50 m-0 flex h-full max-h-none w-full max-w-none items-center justify-center border-0 bg-black/90 p-0 backdrop:bg-transparent",
1247
- children: [
1248
- /* @__PURE__ */ jsx("button", {
1249
- type: "button",
1250
- onClick: onClose,
1251
- "aria-label": "Close fullscreen (Esc)",
1252
- className: "absolute top-4 right-4 z-10 inline-flex size-9 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
1253
- children: /* @__PURE__ */ jsx(X, { className: "size-5" })
1254
- }),
1255
- hasMultipleImages && /* @__PURE__ */ jsx("button", {
1256
- type: "button",
1257
- onClick: goToPrevious,
1258
- "aria-label": "Previous image (\u2190)",
1259
- className: "absolute top-1/2 left-4 z-10 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
1260
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-6" })
1261
- }),
1262
- /* @__PURE__ */ jsx("img", {
1263
- src: currentImage.url,
1264
- alt: currentImage.filename ?? "Image preview",
1265
- className: "max-h-[85vh] max-w-[90vw] object-contain select-none",
1266
- onClick: (event) => event.stopPropagation(),
1267
- draggable: false
1268
- }),
1269
- hasMultipleImages && /* @__PURE__ */ jsx("button", {
1270
- type: "button",
1271
- onClick: goToNext,
1272
- "aria-label": "Next image (\u2192)",
1273
- className: "absolute top-1/2 right-4 z-10 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
1274
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-6" })
1275
- }),
1276
- hasMultipleImages && /* @__PURE__ */ jsxs("div", {
1277
- className: "absolute bottom-6 left-1/2 flex -translate-x-1/2 flex-col items-center gap-3",
1278
- children: [/* @__PURE__ */ jsx("div", {
1279
- className: "flex gap-2",
1280
- children: images.map((image, idx) => /* @__PURE__ */ jsx("button", {
1281
- type: "button",
1282
- onClick: (event) => {
1283
- event.stopPropagation();
1284
- setCurrentIndex(idx);
1285
- },
1286
- "aria-label": `Go to image ${idx + 1}`,
1287
- className: cn("size-2 rounded-full transition-all", idx === currentIndex ? "scale-125 bg-white" : "bg-white/40 hover:bg-white/60")
1288
- }, image.url))
1289
- }), /* @__PURE__ */ jsxs("span", {
1290
- className: "text-sm text-white/70",
1291
- children: [
1292
- currentIndex + 1,
1293
- " / ",
1294
- images.length
1295
- ]
1296
- })]
1297
- })
1298
- ]
1299
- }), document.body);
1300
- }
1301
- function formatFileSize(bytes) {
1302
- if (bytes < 1024) return `${bytes} B`;
1303
- if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
1304
- return `${(bytes / 1048576).toFixed(1)} MB`;
1305
- }
1306
- function getFileIconName(filename, isImage) {
1307
- if (isImage) return "image";
1308
- const ext = filename.split(".").pop()?.toLowerCase();
1309
- if ([
1310
- "js",
1311
- "ts",
1312
- "jsx",
1313
- "tsx",
1314
- "py",
1315
- "rb",
1316
- "go",
1317
- "rs",
1318
- "java",
1319
- "kt",
1320
- "swift",
1321
- "c",
1322
- "cpp",
1323
- "h",
1324
- "hpp",
1325
- "cs",
1326
- "php"
1327
- ].includes(ext || "")) return "code";
1328
- if ([
1329
- "json",
1330
- "yaml",
1331
- "yml",
1332
- "xml"
1333
- ].includes(ext || "")) return "data";
1334
- return "text";
1335
- }
1336
- function renderFileIcon(iconName) {
1337
- switch (iconName) {
1338
- case "image":
1339
- return /* @__PURE__ */ jsx(Image, { className: "size-4 text-muted-foreground" });
1340
- case "code":
1341
- return /* @__PURE__ */ jsx(FileCode, { className: "size-4 text-muted-foreground" });
1342
- case "data":
1343
- return /* @__PURE__ */ jsx(FileBraces, { className: "size-4 text-muted-foreground" });
1344
- default:
1345
- return /* @__PURE__ */ jsx(FileText, { className: "size-4 text-muted-foreground" });
873
+ function getFileIconName(filename, isImage) {
874
+ if (isImage) return "image";
875
+ const ext = filename.split(".").pop()?.toLowerCase();
876
+ if ([
877
+ "js",
878
+ "ts",
879
+ "jsx",
880
+ "tsx",
881
+ "py",
882
+ "rb",
883
+ "go",
884
+ "rs",
885
+ "java",
886
+ "kt",
887
+ "swift",
888
+ "c",
889
+ "cpp",
890
+ "h",
891
+ "hpp",
892
+ "cs",
893
+ "php"
894
+ ].includes(ext || "")) return "code";
895
+ if ([
896
+ "json",
897
+ "yaml",
898
+ "yml",
899
+ "xml"
900
+ ].includes(ext || "")) return "data";
901
+ return "text";
902
+ }
903
+ function renderFileIcon(iconName) {
904
+ switch (iconName) {
905
+ case "image":
906
+ return /* @__PURE__ */ jsx(Image, { className: "size-4 text-muted-foreground" });
907
+ case "code":
908
+ return /* @__PURE__ */ jsx(FileCode, { className: "size-4 text-muted-foreground" });
909
+ case "data":
910
+ return /* @__PURE__ */ jsx(FileBraces, { className: "size-4 text-muted-foreground" });
911
+ default:
912
+ return /* @__PURE__ */ jsx(FileText, { className: "size-4 text-muted-foreground" });
1346
913
  }
1347
914
  }
1348
915
  function FileAttachment({ id, filename, size, isImage, url, onRemove, className, display = "chip", enableImagePreview = true }) {
@@ -1430,11 +997,33 @@ function FileAttachment({ id, filename, size, isImage, url, onRemove, className,
1430
997
  ]
1431
998
  });
1432
999
  }
1433
- function isRecord(value) {
1000
+ function isRecord$2(value) {
1001
+ return typeof value === "object" && value !== null;
1002
+ }
1003
+ function isTextPart(part) {
1004
+ return isRecord$2(part) && part.type === "text" && typeof part.text === "string";
1005
+ }
1006
+ function isErrorPart(part) {
1007
+ return isRecord$2(part) && part.type === "error" && typeof part.message === "string";
1008
+ }
1009
+ function isPayloadPart(part) {
1010
+ return isRecord$2(part) && part.type === "payload" && typeof part.kind === "string" && typeof part.title === "string";
1011
+ }
1012
+ function isV5ToolPart(part) {
1013
+ if (!isRecord$2(part)) return false;
1014
+ const partType = part.type;
1015
+ return partType === "dynamic-tool" || typeof partType === "string" && partType.startsWith("tool-");
1016
+ }
1017
+ function getTextFromParts(parts, joiner) {
1018
+ const texts = [];
1019
+ for (const part of parts) if (isTextPart(part)) texts.push(part.text);
1020
+ return texts.join(joiner);
1021
+ }
1022
+ function isRecord$1(value) {
1434
1023
  return typeof value === "object" && value !== null;
1435
1024
  }
1436
1025
  function getImageUrlFromPart(part) {
1437
- if (!isRecord(part)) return null;
1026
+ if (!isRecord$1(part)) return null;
1438
1027
  const type = part.type;
1439
1028
  if (typeof type !== "string") return null;
1440
1029
  if (type === "image") {
@@ -1452,7 +1041,7 @@ function getImageUrlFromPart(part) {
1452
1041
  return null;
1453
1042
  }
1454
1043
  function getFileFromPart(part) {
1455
- if (!isRecord(part)) return null;
1044
+ if (!isRecord$1(part)) return null;
1456
1045
  if (part.type !== "file") return null;
1457
1046
  const filePart = part;
1458
1047
  const filename = filePart.filename || filePart.name || filePart.fileName || "Attachment";
@@ -1473,7 +1062,7 @@ var UserMessage = memo(function UserMessage2({ message, className, enableImagePr
1473
1062
  const file = getFileFromPart(part);
1474
1063
  if (file) files.push(file);
1475
1064
  }
1476
- if (isRecord(message) && Array.isArray(message.experimental_attachments)) {
1065
+ if (isRecord$1(message) && Array.isArray(message.experimental_attachments)) {
1477
1066
  for (const att of message.experimental_attachments) if (att.contentType?.startsWith("image/") && att.url) images.push(att.url);
1478
1067
  }
1479
1068
  if (!text && images.length === 0 && files.length === 0) return null;
@@ -1529,221 +1118,350 @@ var UserMessage = memo(function UserMessage2({ message, className, enableImagePr
1529
1118
  ]
1530
1119
  });
1531
1120
  });
1532
- var LazyGenerativeTextRenderer = lazy(() => import("./openui-renderer-Cg4RSE9k-7BTJIYZJ.js").then((n) => n.n).then(({ GenerativeTextRenderer }) => ({ default: GenerativeTextRenderer })));
1533
- function PlainTextFallback({ className, content }) {
1121
+ var ErrorMessage = memo(function ErrorMessage2({ title = "Something went wrong", message, className }) {
1534
1122
  return /* @__PURE__ */ jsx("div", {
1535
- className: className ? `${className} whitespace-pre-wrap` : "whitespace-pre-wrap",
1536
- children: content
1123
+ className: cn("flex justify-start", className),
1124
+ children: /* @__PURE__ */ jsxs("div", {
1125
+ className: "rounded-[8px] border border-red-500/30 bg-red-500/10 px-4 py-2.5 text-sm text-an-foreground",
1126
+ children: [/* @__PURE__ */ jsx("div", {
1127
+ className: "font-medium text-an-foreground",
1128
+ children: title
1129
+ }), /* @__PURE__ */ jsx("div", {
1130
+ className: "mt-0.5 text-an-foreground-muted",
1131
+ children: message
1132
+ })]
1133
+ })
1134
+ });
1135
+ });
1136
+ function formatPayload(value) {
1137
+ if (typeof value === "string") return value;
1138
+ if (value === void 0) return "";
1139
+ try {
1140
+ return JSON.stringify(value, null, 2) ?? "";
1141
+ } catch {
1142
+ return String(value);
1143
+ }
1144
+ }
1145
+ function PayloadPart({ part }) {
1146
+ const payload = formatPayload(part.payload);
1147
+ return /* @__PURE__ */ jsxs("section", {
1148
+ "data-payload-kind": part.kind,
1149
+ className: "w-full min-w-0 overflow-hidden rounded-xl border border-border/60 bg-muted/40 text-sm",
1150
+ children: [
1151
+ /* @__PURE__ */ jsx("div", {
1152
+ className: "border-b border-border/50 px-3 py-2 text-xs font-medium text-muted-foreground",
1153
+ children: part.title
1154
+ }),
1155
+ part.text ? /* @__PURE__ */ jsx("pre", {
1156
+ className: "m-0 whitespace-pre-wrap break-words px-3 py-3 font-mono text-xs leading-5 text-foreground/80",
1157
+ children: part.text
1158
+ }) : null,
1159
+ payload ? /* @__PURE__ */ jsxs("details", {
1160
+ open: true,
1161
+ className: "border-t border-border/50 px-3 py-2",
1162
+ children: [/* @__PURE__ */ jsx("summary", {
1163
+ className: "cursor-pointer text-xs font-medium text-muted-foreground",
1164
+ children: "Payload"
1165
+ }), /* @__PURE__ */ jsx("pre", {
1166
+ className: "m-0 mt-2 max-w-full whitespace-pre-wrap break-words font-mono text-xs leading-5 text-foreground/70",
1167
+ children: payload
1168
+ })]
1169
+ }) : null
1170
+ ]
1171
+ });
1172
+ }
1173
+ function isRecord(value) {
1174
+ return typeof value === "object" && value !== null;
1175
+ }
1176
+ function parseStructuredJson(value) {
1177
+ if (typeof value !== "string") return value;
1178
+ const trimmed = value.trim();
1179
+ if (!trimmed) return value;
1180
+ try {
1181
+ const parsed = JSON.parse(trimmed);
1182
+ return isRecord(parsed) || Array.isArray(parsed) ? parsed : value;
1183
+ } catch {
1184
+ return value;
1185
+ }
1186
+ }
1187
+ function normalizeToolPart(part) {
1188
+ if (!isRecord(part)) return part;
1189
+ if (typeof part.type !== "string" || !part.type.startsWith("tool-")) return part;
1190
+ const normalizedInput = parseStructuredJson(part.input);
1191
+ const normalizedOutput = parseStructuredJson(part.output);
1192
+ const normalizedResult = parseStructuredJson(part.result);
1193
+ const inputChanged = normalizedInput !== part.input;
1194
+ const outputChanged = normalizedOutput !== part.output;
1195
+ const resultChanged = normalizedResult !== part.result;
1196
+ if (!inputChanged && !outputChanged && !resultChanged) return part;
1197
+ const normalizedPart = { ...part };
1198
+ if (inputChanged) normalizedPart.input = normalizedInput;
1199
+ if (outputChanged) normalizedPart.output = normalizedOutput;
1200
+ if (resultChanged) normalizedPart.result = normalizedResult;
1201
+ return normalizedPart;
1202
+ }
1203
+ function normalizeAssistantToolParts(parts) {
1204
+ let changed = false;
1205
+ const normalizedParts = parts.map((part) => {
1206
+ const normalizedPart = normalizeToolPart(part);
1207
+ if (normalizedPart !== part) changed = true;
1208
+ return normalizedPart;
1209
+ });
1210
+ return changed ? normalizedParts : parts;
1211
+ }
1212
+ var timeFormatter = new Intl.DateTimeFormat("en-US", {
1213
+ hour: "numeric",
1214
+ minute: "2-digit",
1215
+ hour12: true
1216
+ });
1217
+ var dateFormatter = new Intl.DateTimeFormat("en-US", {
1218
+ month: "short",
1219
+ day: "numeric"
1220
+ });
1221
+ function formatTimestamp(date) {
1222
+ const now = /* @__PURE__ */ new Date();
1223
+ if (date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate()) return timeFormatter.format(date);
1224
+ return dateFormatter.format(date);
1225
+ }
1226
+ function CopyButton({ text, onCopied }) {
1227
+ const [copied, setCopied] = useState(false);
1228
+ const copiedTimerRef = useRef(null);
1229
+ useEffect(() => {
1230
+ return () => {
1231
+ if (copiedTimerRef.current) window.clearTimeout(copiedTimerRef.current);
1232
+ };
1233
+ }, []);
1234
+ const handleCopy = async () => {
1235
+ try {
1236
+ await navigator.clipboard.writeText(text);
1237
+ setCopied(true);
1238
+ if (copiedTimerRef.current) window.clearTimeout(copiedTimerRef.current);
1239
+ copiedTimerRef.current = window.setTimeout(() => {
1240
+ setCopied(false);
1241
+ copiedTimerRef.current = null;
1242
+ }, 2e3);
1243
+ notify.success("Copied to clipboard");
1244
+ onCopied?.();
1245
+ } catch {
1246
+ notify.error("Failed to copy to clipboard");
1247
+ }
1248
+ };
1249
+ return /* @__PURE__ */ jsx("button", {
1250
+ type: "button",
1251
+ tabIndex: -1,
1252
+ "aria-label": copied ? "Copied" : "Copy message",
1253
+ onClick: handleCopy,
1254
+ onPointerDown: (event) => {
1255
+ event.stopPropagation();
1256
+ },
1257
+ onMouseDown: (event) => event.stopPropagation(),
1258
+ className: cn("flex size-6 items-center justify-center rounded-md transition-[background-color,opacity,transform] duration-150 ease-out active:scale-[0.97]", "bg-transparent opacity-50 hover:bg-an-foreground/10 hover:opacity-100"),
1259
+ children: /* @__PURE__ */ jsxs("div", {
1260
+ className: "relative h-3.5 w-3.5",
1261
+ children: [/* @__PURE__ */ jsx(Copy, { className: cn("absolute inset-0 h-3.5 w-3.5 text-an-foreground-muted transition-[opacity,transform] duration-150 ease-out", copied ? "scale-50 opacity-0" : "scale-100 opacity-100") }), /* @__PURE__ */ jsx(Check, { className: cn("absolute inset-0 h-3.5 w-3.5 text-an-foreground-muted transition-[opacity,transform] duration-150 ease-out", copied ? "scale-100 opacity-100" : "scale-50 opacity-0") })]
1262
+ })
1537
1263
  });
1538
1264
  }
1539
- function FleetGenerativeTextRenderer(props) {
1540
- if (!useMemo(() => segmentOpenUIContent(props.content).some((segment) => segment.type === "openui"), [props.content])) return /* @__PURE__ */ jsx(LazyMarkdown, {
1541
- className: props.className,
1542
- content: props.content
1543
- });
1544
- return /* @__PURE__ */ jsx(Suspense, {
1545
- fallback: /* @__PURE__ */ jsx(PlainTextFallback, {
1546
- className: props.className,
1547
- content: props.content
1548
- }),
1549
- children: /* @__PURE__ */ jsx(LazyGenerativeTextRenderer, { ...props })
1265
+ function MessageToolbar({ text, timestamp, heightClass, hoverClass, isVisible, alignClass, onCopied }) {
1266
+ return /* @__PURE__ */ jsxs("div", {
1267
+ className: cn("pointer-events-none flex items-center gap-1 pt-1 text-xs text-an-foreground-muted/70 opacity-0 transition-opacity duration-100", heightClass, alignClass, hoverClass, isVisible && "pointer-events-auto opacity-100"),
1268
+ onMouseDown: (event) => event.stopPropagation(),
1269
+ onPointerDown: (event) => event.stopPropagation(),
1270
+ children: [timestamp && /* @__PURE__ */ jsx("span", { children: timestamp }), text && /* @__PURE__ */ jsx(CopyButton, {
1271
+ text,
1272
+ onCopied
1273
+ })]
1550
1274
  });
1551
1275
  }
1552
- function orderedRlmChildren(children, tree) {
1553
- const byId = new Map(children.map((child) => [child.id, child]));
1554
- const visited = /* @__PURE__ */ new Set();
1555
- const ordered = [];
1556
- const visit = (id) => {
1557
- if (visited.has(id)) return;
1558
- visited.add(id);
1559
- const child = byId.get(id);
1560
- if (child) ordered.push(child);
1561
- for (const nextId of tree?.nodes[id]?.childrenIds ?? []) visit(nextId);
1562
- };
1563
- for (const id of tree?.rootChildrenIds ?? []) visit(id);
1564
- for (const child of children) visit(child.id);
1565
- return ordered;
1566
- }
1567
- function rlmStatusIcon(status2) {
1568
- if (status2 === "done") return /* @__PURE__ */ jsx(CircleCheck, { className: "size-3.5 text-emerald-600 dark:text-emerald-400" });
1569
- if (status2 === "error") return /* @__PURE__ */ jsx(CircleAlert, { className: "size-3.5 text-destructive" });
1570
- if (status2 === "cancelled") return /* @__PURE__ */ jsx(CircleX, { className: "size-3.5 text-muted-foreground" });
1571
- return /* @__PURE__ */ jsx(LoaderCircle, { className: "size-3.5 animate-spin text-blue-600 dark:text-blue-400" });
1572
- }
1573
- function FleetSubagentList({ children, tree, className }) {
1574
- const agents = useMemo(() => orderedRlmChildren(children, tree), [children, tree]);
1575
- const active = agents.some((child) => child.status === "queued" || child.status === "running");
1576
- const [open, setOpen] = useState(active);
1577
- if (agents.length === 0) return null;
1578
- return /* @__PURE__ */ jsxs("section", {
1579
- className: cn("mt-2 rounded-xl border border-border/60 bg-muted/20", className),
1580
- children: [/* @__PURE__ */ jsxs("button", {
1581
- type: "button",
1582
- "aria-expanded": open || active,
1583
- onClick: () => setOpen((current) => !current),
1584
- className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1585
- children: [
1586
- active ? /* @__PURE__ */ jsx(LoaderCircle, { className: "size-3.5 animate-spin text-blue-600 dark:text-blue-400" }) : /* @__PURE__ */ jsx(CircleCheck, { className: "size-3.5 text-emerald-600 dark:text-emerald-400" }),
1587
- /* @__PURE__ */ jsx("span", {
1588
- className: "flex-1 font-medium",
1589
- children: active ? "Subagents working" : "Subagents completed"
1590
- }),
1591
- /* @__PURE__ */ jsx("span", {
1592
- className: "text-xs text-muted-foreground",
1593
- children: agents.length
1594
- }),
1595
- /* @__PURE__ */ jsx(ChevronDown, { className: cn("size-3.5 text-muted-foreground transition-transform", (open || active) && "rotate-180") })
1596
- ]
1597
- }), open || active ? /* @__PURE__ */ jsx("div", {
1598
- className: "space-y-1 border-t border-border/50 px-3 py-2",
1599
- children: agents.map((child) => /* @__PURE__ */ jsxs("div", {
1600
- className: "flex min-w-0 items-start gap-2",
1601
- style: { paddingLeft: `${Math.max(0, child.depth ?? 0) * 12}px` },
1602
- children: [
1603
- /* @__PURE__ */ jsx("span", {
1604
- className: "mt-0.5 shrink-0",
1605
- children: rlmStatusIcon(child.status)
1606
- }),
1607
- /* @__PURE__ */ jsxs("div", {
1608
- className: "min-w-0 flex-1",
1609
- children: [/* @__PURE__ */ jsxs("div", {
1610
- className: "flex min-w-0 items-baseline gap-2",
1611
- children: [/* @__PURE__ */ jsx("span", {
1612
- className: "truncate text-sm text-foreground/85",
1613
- children: child.label
1614
- }), child.model ? /* @__PURE__ */ jsx("span", {
1615
- className: "truncate font-mono text-[10px] text-muted-foreground",
1616
- children: child.model
1617
- }) : null]
1618
- }), child.answerPreview || child.activity?.toolName || child.error ? /* @__PURE__ */ jsx("p", {
1619
- className: "truncate text-xs text-muted-foreground",
1620
- children: child.error ?? child.answerPreview ?? child.activity?.toolName
1621
- }) : null]
1622
- }),
1623
- /* @__PURE__ */ jsx("span", {
1624
- className: "shrink-0 text-[10px] capitalize text-muted-foreground",
1625
- children: child.status
1626
- })
1627
- ]
1628
- }, child.id))
1629
- }) : null]
1276
+ memo(function UserTurn(props) {
1277
+ const { message, UserMessageComponent, userMessageClassName, onCopied, display } = props;
1278
+ const { enableImagePreview, showCopyToolbar, isMounted, isCopyVisible } = display;
1279
+ const text = getTextFromParts(message.parts ?? [], "");
1280
+ const hasParts = (message.parts ?? []).length > 0;
1281
+ if (!text && !hasParts) return null;
1282
+ const userCreatedAt = message?.createdAt;
1283
+ const userCopyKey = `user-${message.id}`;
1284
+ const userTimestamp = isMounted && userCreatedAt ? formatTimestamp(new Date(userCreatedAt)) : void 0;
1285
+ return /* @__PURE__ */ jsxs("div", {
1286
+ className: "group/user-message",
1287
+ children: [/* @__PURE__ */ jsx(UserMessageComponent, {
1288
+ message,
1289
+ className: userMessageClassName,
1290
+ enableImagePreview
1291
+ }), (showCopyToolbar && Boolean(text) || Boolean(userTimestamp)) && /* @__PURE__ */ jsx(MessageToolbar, {
1292
+ text: showCopyToolbar ? text : "",
1293
+ timestamp: userTimestamp,
1294
+ heightClass: "h-[28px]",
1295
+ hoverClass: "group-hover/user-message:opacity-100 group-hover/user-message:pointer-events-auto",
1296
+ isVisible: isCopyVisible,
1297
+ alignClass: "justify-end",
1298
+ onCopied: () => onCopied(userCopyKey)
1299
+ })]
1630
1300
  });
1301
+ });
1302
+ memo(function AssistantTurn(props) {
1303
+ const { assistantMsgs, turnKey, ToolRendererComponent, TextRendererComponent, toolRenderers, onOpenUIAction, onOpenUIArtifactReady, onOpenArtifact, onCopied, stream, copy, display } = props;
1304
+ const { isLast: isLastTurn, isStreaming } = stream;
1305
+ const { enabled: showCopyToolbar, isVisible: isCopyVisible } = copy;
1306
+ const { suppressQuestionTool } = display;
1307
+ const assistantText = getTextFromParts(assistantMsgs.flatMap((msg) => msg.parts ?? []), "\n\n");
1308
+ const isTurnStreaming = isStreaming && isLastTurn;
1309
+ const showToolbar = showCopyToolbar && Boolean(assistantText.trim()) && !isTurnStreaming;
1310
+ const copyKey = `assistant-${turnKey}-all`;
1311
+ const toolbarText = showCopyToolbar ? assistantText : "";
1312
+ return /* @__PURE__ */ jsxs("div", {
1313
+ className: "group/assistant-turn",
1314
+ children: [/* @__PURE__ */ jsx("div", {
1315
+ className: "flex flex-col gap-3",
1316
+ children: assistantMsgs.map((msg, i) => {
1317
+ const isLastMsg = isLastTurn && i === assistantMsgs.length - 1;
1318
+ return /* @__PURE__ */ jsx(AssistantParts, {
1319
+ msg,
1320
+ isLast: isLastMsg,
1321
+ isStreaming,
1322
+ suppressQuestionTool,
1323
+ ToolRendererComponent,
1324
+ TextRendererComponent,
1325
+ toolRenderers,
1326
+ onOpenUIAction,
1327
+ onOpenUIArtifactReady,
1328
+ onOpenArtifact
1329
+ }, msg.id);
1330
+ })
1331
+ }), (showToolbar || isCopyVisible) && /* @__PURE__ */ jsx(MessageToolbar, {
1332
+ text: toolbarText,
1333
+ heightClass: "h-[48px] flex items-start w-full",
1334
+ hoverClass: "group-hover/assistant-turn:opacity-100 group-hover/assistant-turn:pointer-events-auto",
1335
+ isVisible: isCopyVisible,
1336
+ alignClass: "justify-start",
1337
+ onCopied: () => onCopied(copyKey)
1338
+ })]
1339
+ });
1340
+ });
1341
+ var TOOL_CALL_KEY_PREFIX = "tool-call:";
1342
+ var UNKEYED_TOOL_KEY_PREFIX = "unkeyed-tool:";
1343
+ function getAssistantToolElementKey(messageId, part, occurrence) {
1344
+ if (part.toolCallId) return `${TOOL_CALL_KEY_PREFIX}${part.toolCallId}`;
1345
+ return `${UNKEYED_TOOL_KEY_PREFIX}${messageId}:${part.type}:${occurrence}`;
1631
1346
  }
1632
- function record(value) {
1633
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
1634
- }
1635
- function target(input, fallback) {
1636
- const source = record(input);
1637
- for (const key of [
1638
- "path",
1639
- "filePath",
1640
- "command",
1641
- "cmd",
1642
- "query",
1643
- "pattern",
1644
- "code"
1645
- ]) if (typeof source?.[key] === "string" && source[key]) return source[key];
1646
- return fallback;
1647
- }
1648
- function status(part, streaming) {
1649
- const state = part.state;
1650
- if (state === "output-error" || state === "error") return "error";
1651
- if (state === "cancelled" || state === "canceled" || state === "aborted") return "cancelled";
1652
- if (state === "input-streaming" || state === "streaming") return streaming ? "running" : "cancelled";
1653
- return streaming && part.output === void 0 && part.result === void 0 ? "running" : "complete";
1654
- }
1655
- function toolStep(part, fallbackId, streaming) {
1656
- const type = part.type;
1657
- if (typeof type !== "string" || !type.startsWith("tool-") || type === "tool-FleetReasoning" || type === "tool-Thinking") return void 0;
1658
- const name = type.slice(5);
1659
- const lower = name.toLowerCase();
1660
- const icon = lower.includes("edit") || lower.includes("write") || lower.includes("patch") ? FilePenLine : lower.includes("read") || lower.includes("search") || lower.includes("grep") || lower.includes("glob") ? FileSearch : lower.includes("bash") || lower.includes("shell") || lower.includes("python") || lower.includes("ipython") ? Terminal : Wrench;
1661
- const verb = lower.includes("edit") || lower.includes("write") || lower.includes("patch") ? "Edited" : lower.includes("read") ? "Read" : lower.includes("search") || lower.includes("grep") || lower.includes("glob") ? "Searched" : lower.includes("bash") || lower.includes("shell") || lower.includes("python") || lower.includes("ipython") ? "Ran" : name;
1662
- return {
1663
- id: typeof part.toolCallId === "string" ? part.toolCallId : fallbackId,
1664
- icon,
1665
- verb,
1666
- target: target(part.input ?? part.args, name),
1667
- status: status(part, streaming)
1668
- };
1669
- }
1670
- function artifactStep(artifact) {
1671
- const icon = artifact.kind === "diff" ? FilePenLine : artifact.kind === "bash" || artifact.kind === "ipython" ? Terminal : Wrench;
1672
- return {
1673
- id: `artifact:${artifact.id}`,
1674
- icon,
1675
- verb: artifact.kind === "compaction" ? "Compacted" : artifact.kind === "refinement" ? "Refined" : artifact.kind === "recap" ? "Recapped" : artifact.kind === "rlm" ? "Delegated" : artifact.kind === "diff" ? "Edited" : "Completed",
1676
- target: artifact.title,
1677
- status: artifact.status === "success" ? "complete" : artifact.status
1678
- };
1679
- }
1680
- function statusClass(status2) {
1681
- if (status2 === "running") return "text-blue-600 dark:text-blue-400";
1682
- if (status2 === "error") return "text-destructive";
1683
- if (status2 === "cancelled") return "text-muted-foreground";
1684
- return "text-emerald-600 dark:text-emerald-400";
1347
+ function buildAssistantElements(parts, opts) {
1348
+ const { messageId, isLast, isStreaming, suppressQuestionTool, suppressTextWhenPlanWrite = false, ToolRendererComponent, TextRendererComponent, toolRenderers, onOpenUIAction, onOpenUIArtifactReady, onOpenArtifact } = opts;
1349
+ const elems = [];
1350
+ const textChunks = [];
1351
+ const hasPlanWritePresentation = suppressTextWhenPlanWrite && parts.some((part) => isV5ToolPart(part) && part.type === "tool-PlanWrite");
1352
+ const taskPartIds = new Set(parts.filter((p) => isV5ToolPart(p) && (p.type === "tool-Task" || p.type === "tool-Agent") && typeof p.toolCallId === "string").map((p) => p.toolCallId));
1353
+ const nestedToolsMap = /* @__PURE__ */ new Map();
1354
+ const nestedToolIds = /* @__PURE__ */ new Set();
1355
+ const unkeyedToolOccurrences = /* @__PURE__ */ new Map();
1356
+ for (const part of parts) {
1357
+ if (!isV5ToolPart(part)) continue;
1358
+ if (part.type === "tool-TaskOutput") continue;
1359
+ if (!part.toolCallId || !part.toolCallId.includes(":")) continue;
1360
+ const parentId = part.toolCallId.split(":")[0];
1361
+ if (!taskPartIds.has(parentId)) continue;
1362
+ if (!nestedToolsMap.has(parentId)) nestedToolsMap.set(parentId, []);
1363
+ nestedToolsMap.get(parentId).push(part);
1364
+ nestedToolIds.add(part.toolCallId);
1365
+ }
1366
+ let i = 0;
1367
+ while (i < parts.length) {
1368
+ const part = parts[i];
1369
+ if (isV5ToolPart(part) && part.type === "tool-TaskOutput") {
1370
+ i++;
1371
+ continue;
1372
+ }
1373
+ if (isTextPart(part)) {
1374
+ const text2 = part.text;
1375
+ if (text2 && !hasPlanWritePresentation) textChunks.push(text2);
1376
+ i++;
1377
+ continue;
1378
+ }
1379
+ if (isErrorPart(part)) {
1380
+ elems.push(/* @__PURE__ */ jsx(ErrorMessage, {
1381
+ title: part.title,
1382
+ message: part.message
1383
+ }, `${messageId}-error-${part.title}-${part.message}`));
1384
+ i++;
1385
+ continue;
1386
+ }
1387
+ if (isPayloadPart(part)) {
1388
+ elems.push(/* @__PURE__ */ jsx(PayloadPart, { part }, `${messageId}-payload-${i}`));
1389
+ i++;
1390
+ continue;
1391
+ }
1392
+ if (isV5ToolPart(part)) {
1393
+ if (suppressQuestionTool && part.type === "tool-Question") {
1394
+ i++;
1395
+ continue;
1396
+ }
1397
+ if (part.toolCallId && nestedToolIds.has(part.toolCallId)) {
1398
+ i++;
1399
+ continue;
1400
+ }
1401
+ const chatStreamingStatus = isLast && isStreaming ? "streaming" : void 0;
1402
+ const toolCallId = part.toolCallId;
1403
+ const nestedTools = (part.type === "tool-Task" || part.type === "tool-Agent") && toolCallId ? nestedToolsMap.get(toolCallId) || [] : void 0;
1404
+ const occurrence = part.toolCallId ? 0 : unkeyedToolOccurrences.get(part.type) ?? 0;
1405
+ if (!part.toolCallId) unkeyedToolOccurrences.set(part.type, occurrence + 1);
1406
+ elems.push(/* @__PURE__ */ jsx(ToolRendererComponent, {
1407
+ part,
1408
+ nestedTools,
1409
+ chatStatus: chatStreamingStatus,
1410
+ toolRenderers
1411
+ }, getAssistantToolElementKey(messageId, part, occurrence)));
1412
+ i++;
1413
+ continue;
1414
+ }
1415
+ i++;
1416
+ }
1417
+ const text = textChunks.join("\n\n");
1418
+ if (text) elems.push(/* @__PURE__ */ jsx("div", {
1419
+ className: "group/assistant-text text-[14px]",
1420
+ children: /* @__PURE__ */ jsx(TextRendererComponent, {
1421
+ content: text,
1422
+ isStreaming,
1423
+ messageId,
1424
+ onOpenUIAction,
1425
+ onOpenUIArtifactReady,
1426
+ onOpenArtifact,
1427
+ className: "leading-relaxed [&_p]:leading-relaxed"
1428
+ })
1429
+ }, `${messageId}-text-final`));
1430
+ return elems;
1685
1431
  }
1686
- function FleetToolTimeline({ messages, artifacts = [], streaming, className }) {
1687
- const steps = useMemo(() => {
1688
- const seen = /* @__PURE__ */ new Set();
1689
- const fromMessages = messages.flatMap((message) => message.parts.flatMap((part, index) => {
1690
- const step = toolStep(record(part) ?? {}, `${message.id}:${index}`, streaming);
1691
- if (!step || seen.has(step.id)) return [];
1692
- seen.add(step.id);
1693
- return [step];
1694
- }));
1695
- const fromArtifacts = artifacts.flatMap((artifact) => {
1696
- if (artifact.sourceToolCallId && seen.has(artifact.sourceToolCallId)) return [];
1697
- const step = artifactStep(artifact);
1698
- if (seen.has(step.id)) return [];
1699
- seen.add(step.id);
1700
- return [step];
1701
- });
1702
- return [...fromMessages, ...fromArtifacts];
1703
- }, [
1704
- artifacts,
1705
- messages,
1706
- streaming
1432
+ function AssistantParts({ msg, isLast, isStreaming, suppressQuestionTool, ToolRendererComponent, TextRendererComponent, toolRenderers, onOpenUIAction, onOpenUIArtifactReady, onOpenArtifact }) {
1433
+ const parts = useMemo(() => normalizeAssistantToolParts(msg.parts ?? []), [msg.parts]);
1434
+ const elements = useMemo(() => buildAssistantElements(parts, {
1435
+ messageId: msg.id,
1436
+ isLast,
1437
+ isStreaming,
1438
+ suppressQuestionTool,
1439
+ ToolRendererComponent,
1440
+ TextRendererComponent,
1441
+ toolRenderers,
1442
+ onOpenUIAction,
1443
+ onOpenUIArtifactReady,
1444
+ onOpenArtifact
1445
+ }), [
1446
+ parts,
1447
+ msg.id,
1448
+ isLast,
1449
+ isStreaming,
1450
+ suppressQuestionTool,
1451
+ ToolRendererComponent,
1452
+ TextRendererComponent,
1453
+ toolRenderers,
1454
+ onOpenUIAction,
1455
+ onOpenUIArtifactReady,
1456
+ onOpenArtifact
1707
1457
  ]);
1708
- const [open, setOpen] = useState(true);
1709
- if (steps.length === 0) return null;
1710
- const active = steps.at(-1);
1711
- const ActiveIcon = active?.icon;
1712
- return /* @__PURE__ */ jsxs("section", {
1713
- className: cn("mb-2 rounded-xl border border-border/60 bg-muted/20", className),
1714
- children: [/* @__PURE__ */ jsxs("button", {
1715
- type: "button",
1716
- "aria-expanded": open,
1717
- onClick: () => setOpen((current) => !current),
1718
- className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1719
- children: [
1720
- active && ActiveIcon ? /* @__PURE__ */ jsx(ActiveIcon, { className: cn("size-3.5 shrink-0", statusClass(active.status), active.status === "running" && "animate-pulse") }) : null,
1721
- /* @__PURE__ */ jsx("span", {
1722
- className: "min-w-0 flex-1 truncate font-medium",
1723
- children: streaming && active ? `${active.verb} ${active.target}` : `${steps.length} tool ${steps.length === 1 ? "action" : "actions"}`
1724
- }),
1725
- /* @__PURE__ */ jsx(ChevronDown, { className: cn("size-3.5 text-muted-foreground transition-transform", open && "rotate-180") })
1726
- ]
1727
- }), open ? /* @__PURE__ */ jsx("div", {
1728
- className: "space-y-1 border-t border-border/50 px-3 py-2",
1729
- children: steps.map((step) => {
1730
- const Icon = step.icon;
1731
- return /* @__PURE__ */ jsxs("div", {
1732
- className: "flex min-w-0 items-center gap-2 text-xs",
1733
- children: [
1734
- /* @__PURE__ */ jsx(Icon, { className: cn("size-3.5 shrink-0", statusClass(step.status)) }),
1735
- /* @__PURE__ */ jsx("span", {
1736
- className: "shrink-0 text-muted-foreground",
1737
- children: step.verb
1738
- }),
1739
- /* @__PURE__ */ jsx("span", {
1740
- className: "min-w-0 flex-1 truncate font-mono text-foreground/75",
1741
- children: step.target
1742
- })
1743
- ]
1744
- }, step.id);
1745
- })
1746
- }) : null]
1458
+ if (elements.length > 1) return /* @__PURE__ */ jsx("div", {
1459
+ className: "group/assistant-turn flex flex-col gap-3",
1460
+ children: elements
1461
+ });
1462
+ return /* @__PURE__ */ jsx("div", {
1463
+ className: "group/assistant-turn",
1464
+ children: elements
1747
1465
  });
1748
1466
  }
1749
1467
  function groupMessages(messages) {
@@ -1769,25 +1487,40 @@ function groupMessages(messages) {
1769
1487
  if (current) turns.push(current);
1770
1488
  return turns;
1771
1489
  }
1490
+ var LazyGenerativeTextRenderer = lazy(() => import("./openui-renderer-Dk0Ak9cW-MUJQHDAS.js").then((n) => n.n).then(({ GenerativeTextRenderer }) => ({ default: GenerativeTextRenderer })));
1491
+ function PlainTextFallback({ className, content }) {
1492
+ return /* @__PURE__ */ jsx("div", {
1493
+ className: className ? `${className} whitespace-pre-wrap` : "whitespace-pre-wrap",
1494
+ children: content
1495
+ });
1496
+ }
1497
+ function FleetGenerativeTextRenderer(props) {
1498
+ if (!useMemo(() => segmentOpenUIContent(props.content).some((segment) => segment.type === "openui"), [props.content])) return /* @__PURE__ */ jsx(LazyMarkdown, {
1499
+ className: props.className,
1500
+ content: props.content
1501
+ });
1502
+ return /* @__PURE__ */ jsx(Suspense, {
1503
+ fallback: /* @__PURE__ */ jsx(PlainTextFallback, {
1504
+ className: props.className,
1505
+ content: props.content
1506
+ }),
1507
+ children: /* @__PURE__ */ jsx(LazyGenerativeTextRenderer, { ...props })
1508
+ });
1509
+ }
1772
1510
 
1773
1511
  export {
1774
1512
  ChevronLeft,
1775
- Image,
1776
1513
  MessageBubble,
1777
1514
  MessageBubbleContent,
1778
1515
  MessageScroller,
1779
1516
  Message,
1780
1517
  MessageContent,
1781
- normalizeAssistantToolParts,
1782
- buildAssistantElements,
1783
1518
  FileAttachment,
1784
1519
  UserMessage,
1785
- FleetGenerativeTextRenderer,
1786
- orderedRlmChildren,
1787
- rlmStatusIcon,
1788
- FleetSubagentList,
1789
- FleetToolTimeline,
1790
- groupMessages
1520
+ normalizeAssistantToolParts,
1521
+ buildAssistantElements,
1522
+ groupMessages,
1523
+ FleetGenerativeTextRenderer
1791
1524
  };
1792
1525
  /**
1793
1526
  * @license lucide-react v1.33.0 - ISC