@cardstack/boxel-cli 0.9.0 → 0.10.0-unstable.0

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 (995) hide show
  1. package/README.md +12 -0
  2. package/bundled-test-harness/assets/account-switch-failed-GCSVbJML.js +23 -0
  3. package/bundled-test-harness/assets/account-switch-failed-GsWni_Gk.css +18 -0
  4. package/bundled-test-harness/assets/account-switch-failed-test-CdZWNths.js +45 -0
  5. package/bundled-test-harness/assets/add-workspace-c7L50Gx8.js +141 -0
  6. package/bundled-test-harness/assets/add-workspace-test-BZxHa6Pe.js +72 -0
  7. package/bundled-test-harness/assets/advanced-color-picker-0pGF-3WG.js +504 -0
  8. package/bundled-test-harness/assets/advanced-color-picker-pbO4HWc_.js +2 -0
  9. package/bundled-test-harness/assets/ai-assistant-test-Dnm4o9vK.js +2211 -0
  10. package/bundled-test-harness/assets/ai-module-creation-test-C6253CMt.js +151 -0
  11. package/bundled-test-harness/assets/aibot-message-miKyGeKk.js +278 -0
  12. package/bundled-test-harness/assets/app-i8pGdQkw.js +22855 -0
  13. package/bundled-test-harness/assets/app-zC7o6PyQ.css +2718 -0
  14. package/bundled-test-harness/assets/audio-file-def-DHnydP0t.js +133 -0
  15. package/bundled-test-harness/assets/auth-container-BP2gSoo4.css +51 -0
  16. package/bundled-test-harness/assets/auth-container-DN94iVfX.js +24 -0
  17. package/bundled-test-harness/assets/avif-meta-extractor-Bo5zRX1V.js +162 -0
  18. package/bundled-test-harness/assets/base64-image-B0RYxzHT.js +2 -0
  19. package/bundled-test-harness/assets/base64-image-Bxjqdwew.js +262 -0
  20. package/bundled-test-harness/assets/big-integer-7RLj5_7H.js +89 -0
  21. package/bundled-test-harness/assets/big-integer-C9sJxKVy.js +2 -0
  22. package/bundled-test-harness/assets/binary-upload-dedupe-test-DZo3EaV0.js +308 -0
  23. package/bundled-test-harness/assets/boolean-CcKPYUph.js +94 -0
  24. package/bundled-test-harness/assets/boolean-DvsSmtM7.js +2 -0
  25. package/bundled-test-harness/assets/brand-functional-palette-KpVSY2Sa.js +137 -0
  26. package/bundled-test-harness/assets/brand-logo-DDiOec0t.js +295 -0
  27. package/bundled-test-harness/assets/broken-link-template-test-DAngUbFJ.js +192 -0
  28. package/bundled-test-harness/assets/bundled-base-C_lumba6.js +254 -0
  29. package/bundled-test-harness/assets/bundled-base-modules-test-CSF7Rl4Z.js +54 -0
  30. package/bundled-test-harness/assets/buried-stack-item-scroll-test-B0J_EP88.js +236 -0
  31. package/bundled-test-harness/assets/bxl-expression-test-Dej7WgI6.js +250 -0
  32. package/bundled-test-harness/assets/can-invoke-test-elyUcOKT.js +401 -0
  33. package/bundled-test-harness/assets/card-api-CjWXCkqh.js +8 -0
  34. package/bundled-test-harness/assets/card-api-Dzje0smT.js +4393 -0
  35. package/bundled-test-harness/assets/card-api-test-DA8d4Ooc.js +198 -0
  36. package/bundled-test-harness/assets/card-basics-test-mp1Odo-l.js +5364 -0
  37. package/bundled-test-harness/assets/card-chooser-paging-test-y8OfboYd.js +235 -0
  38. package/bundled-test-harness/assets/card-chooser-test-nmg2zkDj.js +393 -0
  39. package/bundled-test-harness/assets/card-collection-BXiO3i7R.js +118 -0
  40. package/bundled-test-harness/assets/card-context-search-results-Dbhn7lvW.js +30 -0
  41. package/bundled-test-harness/assets/card-context-search-results-test-DVXT-YC5.js +184 -0
  42. package/bundled-test-harness/assets/card-def-field-def-relationships-test-mX4rxrtO.js +562 -0
  43. package/bundled-test-harness/assets/card-delete-test-BxFsqFnX.js +466 -0
  44. package/bundled-test-harness/assets/card-error-C-7hjxu9.js +72 -0
  45. package/bundled-test-harness/assets/card-error-awaiting-index-test-BvfY2eaW.js +53 -0
  46. package/bundled-test-harness/assets/card-error-detail-nMwopDir.js +271 -0
  47. package/bundled-test-harness/assets/card-info-CTFxdohf.js +2 -0
  48. package/bundled-test-harness/assets/card-list-B9QrkJ97.js +2 -0
  49. package/bundled-test-harness/assets/card-list-XbwLCXZS.js +202 -0
  50. package/bundled-test-harness/assets/card-resource-JGLjQUy6.js +86 -0
  51. package/bundled-test-harness/assets/cards-grid-CWG41hZE.js +344 -0
  52. package/bundled-test-harness/assets/cards-grid-DSpX99p6.js +2 -0
  53. package/bundled-test-harness/assets/cards-grid-layout-Bht0LwZy.js +2 -0
  54. package/bundled-test-harness/assets/cards-grid-layout-CdpKlHUb.js +111 -0
  55. package/bundled-test-harness/assets/check-correctness-test-C4BrUeKA.js +554 -0
  56. package/bundled-test-harness/assets/clip-BEVvLrXx.js +2 -0
  57. package/bundled-test-harness/assets/clip-CoB714qX.js +92 -0
  58. package/bundled-test-harness/assets/code-ref-C2uguisI.js +2 -0
  59. package/bundled-test-harness/assets/code-ref-Cy7sV5a4.js +138 -0
  60. package/bundled-test-harness/assets/code-submode-availability-test-BsA_Ul01.js +198 -0
  61. package/bundled-test-harness/assets/code-submode-test-DkBhpEPB.js +1839 -0
  62. package/bundled-test-harness/assets/codeblocks-test-B1eZ2_JF.js +418 -0
  63. package/bundled-test-harness/assets/codemirror-editor-C6pxSm5y.js +2 -0
  64. package/bundled-test-harness/assets/codemirror-editor-DzM46Cd8.js +701 -0
  65. package/bundled-test-harness/assets/codemirror-embed-toolbar-test-BemP-ZdG.js +366 -0
  66. package/bundled-test-harness/assets/color-C-jGNFWZ.js +2 -0
  67. package/bundled-test-harness/assets/color-field-test-DPIRaBec.js +212 -0
  68. package/bundled-test-harness/assets/color-picker-field-Bv4IjS-d.js +139 -0
  69. package/bundled-test-harness/assets/color-picker-field-D1bYCQIg.js +2 -0
  70. package/bundled-test-harness/assets/color-wheel-picker-IIaCQplL.js +283 -0
  71. package/bundled-test-harness/assets/color-wheel-picker-Kw-UN3kV.js +2 -0
  72. package/bundled-test-harness/assets/color-zzCBneih.js +65 -0
  73. package/bundled-test-harness/assets/command-data-BMBtjT1E.js +95 -0
  74. package/bundled-test-harness/assets/command-data-BXC5Z0oA.js +2 -0
  75. package/bundled-test-harness/assets/compaction-test-CxUKnxlQ.js +150 -0
  76. package/bundled-test-harness/assets/components-Ct_agx0G.js +14294 -0
  77. package/bundled-test-harness/assets/computed-test-C-lpGQQ3.js +1320 -0
  78. package/bundled-test-harness/assets/container-BdPu8rvc.css +5565 -0
  79. package/bundled-test-harness/assets/container-Dj-5prh9.js +11288 -0
  80. package/bundled-test-harness/assets/contains-many-component-CAWqzX8W.js +2 -0
  81. package/bundled-test-harness/assets/contrast-checker-addon-BTLD7oMx.js +2 -0
  82. package/bundled-test-harness/assets/contrast-checker-addon-DBzizR04.js +71 -0
  83. package/bundled-test-harness/assets/convert-to-class-name-test-zZuKxYvF.js +17 -0
  84. package/bundled-test-harness/assets/coordinate-Bw8va6tO.js +48 -0
  85. package/bundled-test-harness/assets/copy-file-to-realm-test-DtCKPzqj.js +148 -0
  86. package/bundled-test-harness/assets/country-B_tWpLlO.js +199 -0
  87. package/bundled-test-harness/assets/create-file-modal-D-VPyEYp.js +570 -0
  88. package/bundled-test-harness/assets/create-listing-modal-test-hyLkQY0u.js +273 -0
  89. package/bundled-test-harness/assets/create-listing-pr-request-test-rjWFA_5S.js +117 -0
  90. package/bundled-test-harness/assets/create-spec-test-HKIxZGxK.js +256 -0
  91. package/bundled-test-harness/assets/create-specs-9-ELVyJP.js +215 -0
  92. package/bundled-test-harness/assets/create-submission-workflow-test-DNZrbRX8.js +132 -0
  93. package/bundled-test-harness/assets/credential-fields-test-xPEdA911.js +157 -0
  94. package/bundled-test-harness/assets/css-value-Du3HL39X.js +48 -0
  95. package/bundled-test-harness/assets/csv-file-def-EHRmilrp.js +277 -0
  96. package/bundled-test-harness/assets/currency-y6ZCHIqG.js +134 -0
  97. package/bundled-test-harness/assets/date-B27PrSFT.js +183 -0
  98. package/bundled-test-harness/assets/date-CiP5Eb9i.js +2 -0
  99. package/bundled-test-harness/assets/date-time-fields-test-Clf5vxRW.js +359 -0
  100. package/bundled-test-harness/assets/datetime-BEbR9YgU.js +201 -0
  101. package/bundled-test-harness/assets/datetime-DPnrt1wl.js +2 -0
  102. package/bundled-test-harness/assets/datetime-stamp-AuT7F7qn.js +2 -0
  103. package/bundled-test-harness/assets/datetime-stamp-CGwP2P3f.js +81 -0
  104. package/bundled-test-harness/assets/day-BFLxZ9bQ.js +2 -0
  105. package/bundled-test-harness/assets/day-CQoEkqgE.js +113 -0
  106. package/bundled-test-harness/assets/debug-message-test-CzgOpfcI.js +117 -0
  107. package/bundled-test-harness/assets/dist-B-fYvxfL.js +389 -0
  108. package/bundled-test-harness/assets/dist-C2IXvIKX.js +323 -0
  109. package/bundled-test-harness/assets/dist-CdNZu43l.js +1710 -0
  110. package/bundled-test-harness/assets/docx-file-def-BQMw460_.js +60 -0
  111. package/bundled-test-harness/assets/docx-meta-extractor-DBlmH_kV.js +60 -0
  112. package/bundled-test-harness/assets/docx-meta-extractor-Dw4gZ0ae.js +2 -0
  113. package/bundled-test-harness/assets/duration-B0SnEiw1.js +184 -0
  114. package/bundled-test-harness/assets/duration-DbjJTFeA.js +2 -0
  115. package/bundled-test-harness/assets/email-C-8cyWiQ.js +80 -0
  116. package/bundled-test-harness/assets/email-field-test-BOBmvQqx.js +75 -0
  117. package/bundled-test-harness/assets/email-xUgCst-p.js +2 -0
  118. package/bundled-test-harness/assets/enum-BWiCyJlu.js +167 -0
  119. package/bundled-test-harness/assets/enum-CzYjivhO.js +2 -0
  120. package/bundled-test-harness/assets/enum-field-test-Bea9EsQR.js +953 -0
  121. package/bundled-test-harness/assets/error-display-test-Cbl2D_0c.js +343 -0
  122. package/bundled-test-harness/assets/ethereum-address-Bw_J05bD.js +78 -0
  123. package/bundled-test-harness/assets/ethereum-address-C9wHMBt3.js +2 -0
  124. package/bundled-test-harness/assets/expiration-warning-BHcJEjZt.js +90 -0
  125. package/bundled-test-harness/assets/expiration-warning-_G8SKZd0.js +2 -0
  126. package/bundled-test-harness/assets/externals-CKblKBo1.js +4393 -0
  127. package/bundled-test-harness/assets/fallback-banner-BqCrvTDt.js +24 -0
  128. package/bundled-test-harness/assets/fallback-banner-live-delete-test-D_AYMvf6.js +207 -0
  129. package/bundled-test-harness/assets/fallback-banner-test-B8Ne9a5g.js +225 -0
  130. package/bundled-test-harness/assets/fallback-banner-test-C7oaSxd1.js +53 -0
  131. package/bundled-test-harness/assets/fallback-models-test-DY-PvU9k.js +161 -0
  132. package/bundled-test-harness/assets/field-component-Bj8YthPE.js +2 -0
  133. package/bundled-test-harness/assets/field-configuration-test-B5LztQ47.js +548 -0
  134. package/bundled-test-harness/assets/field-edit-Cx_haspD.js +36 -0
  135. package/bundled-test-harness/assets/field-edit-DQZWUz3F.js +2 -0
  136. package/bundled-test-harness/assets/field-markdown-domain-test-DnqK3CrE.js +616 -0
  137. package/bundled-test-harness/assets/field-markdown-oversize-test-BEpbXIvl.js +88 -0
  138. package/bundled-test-harness/assets/field-markdown-primitives-test-BDORWoOk.js +365 -0
  139. package/bundled-test-harness/assets/field-markdown-specialized-test-BmIzadYq.js +534 -0
  140. package/bundled-test-harness/assets/field-test-helpers-CRF9-jFw.js +45 -0
  141. package/bundled-test-harness/assets/file-api-DPMJghBY.js +7 -0
  142. package/bundled-test-harness/assets/file-attachment-test-DFLXg3xV.js +796 -0
  143. package/bundled-test-harness/assets/file-chooser-panel-test-B4DzCWkt.js +153 -0
  144. package/bundled-test-harness/assets/file-chooser-test-DpjOWgpB.js +504 -0
  145. package/bundled-test-harness/assets/file-def-edit-Bstl7Kkl.js +2 -0
  146. package/bundled-test-harness/assets/file-def-edit-C1dzJxmQ.js +26 -0
  147. package/bundled-test-harness/assets/file-def-embedded-CUy4G7Vc.js +2 -0
  148. package/bundled-test-harness/assets/file-def-embedded-DJs6P5t0.js +38 -0
  149. package/bundled-test-harness/assets/file-def-fitted-BlrBFfLh.js +38 -0
  150. package/bundled-test-harness/assets/file-def-fitted-Bo5Qfkyf.js +2 -0
  151. package/bundled-test-harness/assets/file-def-isolated-BsHydanv.js +38 -0
  152. package/bundled-test-harness/assets/file-def-isolated-Dp-Lc99-.js +2 -0
  153. package/bundled-test-harness/assets/file-def-serialization-test-CISKpt_o.js +89 -0
  154. package/bundled-test-harness/assets/file-menu-items-7_ltrFZq.js +117 -0
  155. package/bundled-test-harness/assets/file-menu-items-BnRG9ydE.js +2 -0
  156. package/bundled-test-harness/assets/file-preview-stage-CV3qZpiK.js +72 -0
  157. package/bundled-test-harness/assets/file-preview-stage-DTA5X8rX.js +2 -0
  158. package/bundled-test-harness/assets/file-shell-embedded-BpmiVzIG.js +2 -0
  159. package/bundled-test-harness/assets/file-shell-embedded-CEv0-6OE.js +68 -0
  160. package/bundled-test-harness/assets/file-shell-fitted-C6k3GnMc.js +2 -0
  161. package/bundled-test-harness/assets/file-shell-fitted-iSTg3PJa.js +98 -0
  162. package/bundled-test-harness/assets/file-shell-isolated-C-pEod2J.js +195 -0
  163. package/bundled-test-harness/assets/file-shell-isolated-DI9oU7ix.js +2 -0
  164. package/bundled-test-harness/assets/file-tree-from-index-BtOOMqnb.js +151 -0
  165. package/bundled-test-harness/assets/file-tree-from-index-test-T8w3hPw_.js +96 -0
  166. package/bundled-test-harness/assets/film-5n9_gRqZ.js +4074 -0
  167. package/bundled-test-harness/assets/film-Ca2Vzlfu.js +13 -0
  168. package/bundled-test-harness/assets/film-DEvhBbBu.js +2 -0
  169. package/bundled-test-harness/assets/fitted-6OGuHgoU.js +2 -0
  170. package/bundled-test-harness/assets/fitted-B2l1jlSp.js +34 -0
  171. package/bundled-test-harness/assets/flac-meta-extractor-BoJqvmDC.js +99 -0
  172. package/bundled-test-harness/assets/font-file-def-Czzt5paT.js +64 -0
  173. package/bundled-test-harness/assets/font-meta-extractor-DQYT_e5b.js +2 -0
  174. package/bundled-test-harness/assets/font-meta-extractor-IHD-pG8V.js +303 -0
  175. package/bundled-test-harness/assets/formatted-aibot-message-test-Djsl8RzE.js +109 -0
  176. package/bundled-test-harness/assets/from-elsewhere-BXcLYxxu.js +131 -0
  177. package/bundled-test-harness/assets/frontmatter-field-CciolgL3.js +41 -0
  178. package/bundled-test-harness/assets/garbage-collection-test-BTOLAfB6.js +403 -0
  179. package/bundled-test-harness/assets/gauge-C1loqGq3.js +2 -0
  180. package/bundled-test-harness/assets/gauge-u8dxl90d.js +106 -0
  181. package/bundled-test-harness/assets/general-test-Cd5WtVvd.js +926 -0
  182. package/bundled-test-harness/assets/get-relationship-membership-state-test-DJAuhOVM.js +1308 -0
  183. package/bundled-test-harness/assets/gif-meta-extractor-tSaPtuYW.js +114 -0
  184. package/bundled-test-harness/assets/glimmer-motion-and-choreo-in-cards-test-DNSy5l59.js +160 -0
  185. package/bundled-test-harness/assets/glimmer-motion-and-choreo-test-B6BbQxYq.js +74 -0
  186. package/bundled-test-harness/assets/helper-m6jA5HmU.js +478 -0
  187. package/bundled-test-harness/assets/host-submode-test-CsgdksBi.js +1243 -0
  188. package/bundled-test-harness/assets/html-file-def-yKtdMSa-.js +82 -0
  189. package/bundled-test-harness/assets/hydratable-card-CxNfbqly.js +147 -0
  190. package/bundled-test-harness/assets/hydratable-card-test-NJ4CI4ey.js +426 -0
  191. package/bundled-test-harness/assets/icons-B3SAtRoj.js +894 -0
  192. package/bundled-test-harness/assets/image-file-def-B0rpS3Yy.js +3 -0
  193. package/bundled-test-harness/assets/image-file-def-DUFmjNL8.js +65 -0
  194. package/bundled-test-harness/assets/image-olOUqgMQ.js +47 -0
  195. package/bundled-test-harness/assets/index-changes-test-D7OE-99k.js +367 -0
  196. package/bundled-test-harness/assets/index-query-engine-test-BBKqgSmg.js +2593 -0
  197. package/bundled-test-harness/assets/inspector-test-DV6Ms2uz.js +1930 -0
  198. package/bundled-test-harness/assets/instance-filter-matcher-test-Bs4kf7E8.js +788 -0
  199. package/bundled-test-harness/assets/interact-submode-creation-and-permissions-test-DIfgRhIN.js +475 -0
  200. package/bundled-test-harness/assets/interact-submode-setup-D4M_e580.js +566 -0
  201. package/bundled-test-harness/assets/is-component-declaration-test-jPGRTVh1.js +50 -0
  202. package/bundled-test-harness/assets/iso-bmff-DHtkSbQM.js +205 -0
  203. package/bundled-test-harness/assets/iso-bmff-zmOHoSVg.js +2 -0
  204. package/bundled-test-harness/assets/isolated-and-edit-BAnwcK1T.js +2 -0
  205. package/bundled-test-harness/assets/job-priority-header-test-7j2f3Dtl.js +81 -0
  206. package/bundled-test-harness/assets/job-scoped-instance-residency-test-DPzVQUL3.js +103 -0
  207. package/bundled-test-harness/assets/join-the-community-Ft5fjeIA.js +86 -0
  208. package/bundled-test-harness/assets/jpg-meta-extractor-Dsq6rZ8F.js +88 -0
  209. package/bundled-test-harness/assets/json-field-CxOZvp3k.js +19 -0
  210. package/bundled-test-harness/assets/json-field-ojdwGD6T.js +2 -0
  211. package/bundled-test-harness/assets/json-file-def-Da_5-zSM.js +298 -0
  212. package/bundled-test-harness/assets/last-modified-date-BnyJsc04.js +43 -0
  213. package/bundled-test-harness/assets/last-modified-date-test-DFl2mo1B.js +28 -0
  214. package/bundled-test-harness/assets/links-to-editor-DO24-71w.js +2 -0
  215. package/bundled-test-harness/assets/links-to-many-component-C7DabwAY.js +2 -0
  216. package/bundled-test-harness/assets/linksto-broken-link-placeholder-test-D4lDhvnQ.js +398 -0
  217. package/bundled-test-harness/assets/linksto-error-sentinel-test-oWgDz00K.js +238 -0
  218. package/bundled-test-harness/assets/linksto-many-broken-link-placeholder-test-CpSl7zJ7.js +354 -0
  219. package/bundled-test-harness/assets/linksto-many-per-slot-access-test-DJY3J8Xl.js +303 -0
  220. package/bundled-test-harness/assets/linksto-sentinel-reload-test-BxzfoONe.js +197 -0
  221. package/bundled-test-harness/assets/linksto-sentinel-roundtrip-test-DyE99km_.js +260 -0
  222. package/bundled-test-harness/assets/linksto-singular-js-access-contract-test-dcWAAgxt.js +196 -0
  223. package/bundled-test-harness/assets/llm-model-DrswiczZ.js +64 -0
  224. package/bundled-test-harness/assets/login-C-EIG0-Q.css +543 -0
  225. package/bundled-test-harness/assets/login-CNeL-9IC.js +408 -0
  226. package/bundled-test-harness/assets/login-error-text-test-CEH2tjNP.js +51 -0
  227. package/bundled-test-harness/assets/login-test-BpMx7qwV.js +246 -0
  228. package/bundled-test-harness/assets/m4a-meta-extractor-BJkMHUIK.js +204 -0
  229. package/bundled-test-harness/assets/main-BaUgfpPE.js +5 -0
  230. package/bundled-test-harness/assets/markdown-ByEGbwov.js +7 -0
  231. package/bundled-test-harness/assets/markdown-KJzgTg-A.js +2 -0
  232. package/bundled-test-harness/assets/markdown-editor-mode-select-BUGPXaSE.js +2 -0
  233. package/bundled-test-harness/assets/markdown-editor-mode-select-DBk8dG0O.js +54 -0
  234. package/bundled-test-harness/assets/markdown-embed-chooser-modal-test-BIlEmna9.js +470 -0
  235. package/bundled-test-harness/assets/markdown-embed-preview-pane-test-B6rscKpk.js +447 -0
  236. package/bundled-test-harness/assets/markdown-embed-preview-test-CTQw1wq-.js +368 -0
  237. package/bundled-test-harness/assets/markdown-fallback-BVsco6gJ.js +2 -0
  238. package/bundled-test-harness/assets/markdown-fallback-test-C_CIFEzH.js +316 -0
  239. package/bundled-test-harness/assets/markdown-highlighting-test-D6YvywF5.js +244 -0
  240. package/bundled-test-harness/assets/markdown-preview-1TSMSUv0.js +64 -0
  241. package/bundled-test-harness/assets/markdown-preview-jbuUjLoD.js +72 -0
  242. package/bundled-test-harness/assets/markdown-preview-test-zuU5uoA_.js +238 -0
  243. package/bundled-test-harness/assets/markdown-skill-frontmatter-test-CoicGRkb.js +146 -0
  244. package/bundled-test-harness/assets/menu-items-DZ_uOoYu.js +2 -0
  245. package/bundled-test-harness/assets/message-tool-test-K6LgTq5d.js +33 -0
  246. package/bundled-test-harness/assets/metadata-fields-WiOuUCDl.js +1415 -0
  247. package/bundled-test-harness/assets/metadata-fields-iu5AfQp3.js +2 -0
  248. package/bundled-test-harness/assets/midi-audio-def-CD2-4Wjx.js +52 -0
  249. package/bundled-test-harness/assets/midi-meta-extractor-CE3sLiEV.js +284 -0
  250. package/bundled-test-harness/assets/midi-meta-extractor-O7c8LHYV.js +2 -0
  251. package/bundled-test-harness/assets/migrate-skill-test-Beh-AeSN.js +161 -0
  252. package/bundled-test-harness/assets/mini-BNXINKKF.js +85 -0
  253. package/bundled-test-harness/assets/mini-C43Q4BWp.js +1519 -0
  254. package/bundled-test-harness/assets/mini-card-chooser-test-B1GMp-31.js +272 -0
  255. package/bundled-test-harness/assets/mini-file-chooser-test-CbI1vrQn.js +201 -0
  256. package/bundled-test-harness/assets/missing-template-BPhJRbDs.js +48 -0
  257. package/bundled-test-harness/assets/missing-template-DP-Pi-HQ.js +2 -0
  258. package/bundled-test-harness/assets/modal-KpPz2f8x.js +322 -0
  259. package/bundled-test-harness/assets/modal-container-0Efz_h2z.js +40 -0
  260. package/bundled-test-harness/assets/model-cost-tier-test-D-5VSjh6.js +173 -0
  261. package/bundled-test-harness/assets/module-contents-service-BRkTETb6.js +256 -0
  262. package/bundled-test-harness/assets/moment-Cln59YUK.js +3474 -0
  263. package/bundled-test-harness/assets/monaco-AbHCoDJY.js +143 -0
  264. package/bundled-test-harness/assets/monaco-test-DCPi18sy.js +100 -0
  265. package/bundled-test-harness/assets/monaco-test-waiter-lvFEYpFj.js +190 -0
  266. package/bundled-test-harness/assets/month-1eUIsvWN.js +2 -0
  267. package/bundled-test-harness/assets/month-BeUdWMWQ.js +123 -0
  268. package/bundled-test-harness/assets/month-day-Bbsd8YbR.js +192 -0
  269. package/bundled-test-harness/assets/month-day-Dks5STJu.js +2 -0
  270. package/bundled-test-harness/assets/month-year-pL_rpUhX.js +2 -0
  271. package/bundled-test-harness/assets/month-year-wH_YnYgL.js +93 -0
  272. package/bundled-test-harness/assets/mp3-meta-extractor-C3u34UHM.js +476 -0
  273. package/bundled-test-harness/assets/mp4-meta-extractor-Bj3F7dxs.js +188 -0
  274. package/bundled-test-harness/assets/multiple-stacks-test-mkNdTUMI.js +208 -0
  275. package/bundled-test-harness/assets/nested-query-field-render-test-BQLn3wg9.js +249 -0
  276. package/bundled-test-harness/assets/no-stacks-test-DpwZQAJ-.js +48 -0
  277. package/bundled-test-harness/assets/number-DZa-fHpu.js +151 -0
  278. package/bundled-test-harness/assets/number-Dvua76YP.js +3 -0
  279. package/bundled-test-harness/assets/number-field-test-BiaH2eaB.js +184 -0
  280. package/bundled-test-harness/assets/number-input-D5nDYDkK.js +82 -0
  281. package/bundled-test-harness/assets/office-extract-JzYva33g.js +27 -0
  282. package/bundled-test-harness/assets/office-extract-XMpsyYRh.js +2 -0
  283. package/bundled-test-harness/assets/ogg-meta-extractor-DJosZ9LA.js +225 -0
  284. package/bundled-test-harness/assets/on-key-BBVkS8Bi.js +472 -0
  285. package/bundled-test-harness/assets/ooxml-BlAE2w4d.js +172 -0
  286. package/bundled-test-harness/assets/ooxml-D-p8OmuM.js +2 -0
  287. package/bundled-test-harness/assets/open-image-in-new-tab-test-DWBU5pw9.js +52 -0
  288. package/bundled-test-harness/assets/operation-lowering-test-nzqprueU.js +2812 -0
  289. package/bundled-test-harness/assets/operations-CPvfTuY3.js +766 -0
  290. package/bundled-test-harness/assets/operations-invocation-test-C75T6zn3.js +523 -0
  291. package/bundled-test-harness/assets/operations-query-test-BoCszQEW.js +459 -0
  292. package/bundled-test-harness/assets/operations-test-79ipSnpM.js +2518 -0
  293. package/bundled-test-harness/assets/operations-x3Aw2Nky.js +3 -0
  294. package/bundled-test-harness/assets/operator-mode-acceptance-test-jjsYtt96.js +1188 -0
  295. package/bundled-test-harness/assets/operator-mode-card-chooser-test-hZP9gEQK.js +1036 -0
  296. package/bundled-test-harness/assets/operator-mode-links-test-DN16SuIx.js +793 -0
  297. package/bundled-test-harness/assets/operator-mode-state-service-gwiTSiWX.js +1275 -0
  298. package/bundled-test-harness/assets/operator-mode-state-service-test-Dt2qnKKP.js +206 -0
  299. package/bundled-test-harness/assets/operator-mode-test-BZnnxO9q.js +683 -0
  300. package/bundled-test-harness/assets/operator-mode-ui-test-O--qEo-y.js +1027 -0
  301. package/bundled-test-harness/assets/overlay-menu-items-test-Bl2k0aAa.js +317 -0
  302. package/bundled-test-harness/assets/overlays-CdN_JokA.js +270 -0
  303. package/bundled-test-harness/assets/overlays-clip-test-DpbR1ZTz.js +91 -0
  304. package/bundled-test-harness/assets/overlays-detached-element-test-cLgEGvMs.js +56 -0
  305. package/bundled-test-harness/assets/pane-PYdezM7g.js +330 -0
  306. package/bundled-test-harness/assets/panel-7FDqkxrr.js +474 -0
  307. package/bundled-test-harness/assets/panel-C3E0s49q.js +3540 -0
  308. package/bundled-test-harness/assets/past-sessions-test-BsjEeoze.js +321 -0
  309. package/bundled-test-harness/assets/patch-fields-test-CsixJmSr.js +1014 -0
  310. package/bundled-test-harness/assets/patch-instance-test-CBDgTi0L.js +348 -0
  311. package/bundled-test-harness/assets/pdf-file-def-9VNjnqDa.js +76 -0
  312. package/bundled-test-harness/assets/pdf-meta-extractor-BF4e5kMR.js +156 -0
  313. package/bundled-test-harness/assets/pdf-meta-extractor-D8Bxh2cc.js +2 -0
  314. package/bundled-test-harness/assets/pdf-viewer-Bu413sN8.js +112 -0
  315. package/bundled-test-harness/assets/pdf-viewer-GKDi_xmf.js +2 -0
  316. package/bundled-test-harness/assets/percentage-TOr6qK2T.js +84 -0
  317. package/bundled-test-harness/assets/permission-checking-realm-test-BRNVYszm.js +306 -0
  318. package/bundled-test-harness/assets/phone-number-D5SR8nWu.js +236 -0
  319. package/bundled-test-harness/assets/phone-number-field-test-DffwtqGd.js +73 -0
  320. package/bundled-test-harness/assets/phone-number-hf_xIVGQ.js +2 -0
  321. package/bundled-test-harness/assets/plate-Vojc88hM.js +41 -0
  322. package/bundled-test-harness/assets/plate-dTUzEMj5.js +2 -0
  323. package/bundled-test-harness/assets/player-CmRw0uM5.js +82 -0
  324. package/bundled-test-harness/assets/player-Dt85lPZl.js +2 -0
  325. package/bundled-test-harness/assets/plural-field-components-test-DNpGuH1D.js +198 -0
  326. package/bundled-test-harness/assets/png-image-def-GY7gjqya.js +48 -0
  327. package/bundled-test-harness/assets/png-meta-extractor-4pI611re.js +2 -0
  328. package/bundled-test-harness/assets/png-meta-extractor-CHp_rpAi.js +111 -0
  329. package/bundled-test-harness/assets/policy-scoped-search-test-CipPu7tY.js +339 -0
  330. package/bundled-test-harness/assets/pptx-file-def-lBBiebvn.js +60 -0
  331. package/bundled-test-harness/assets/pptx-meta-extractor-BjJYWiOJ.js +77 -0
  332. package/bundled-test-harness/assets/pptx-meta-extractor-DbT-dPRg.js +2 -0
  333. package/bundled-test-harness/assets/prerender-persistence-block-test-ClHMVvJt.js +124 -0
  334. package/bundled-test-harness/assets/prerender-serialize-cycle-test-LdqaMTK8.js +134 -0
  335. package/bundled-test-harness/assets/preview-CYlam_aW.js +74 -0
  336. package/bundled-test-harness/assets/preview-format-CiSo4kEa.js +41 -0
  337. package/bundled-test-harness/assets/preview-format-test-MsB1TOLB.js +103 -0
  338. package/bundled-test-harness/assets/process-card-B3xBGkv1.js +2 -0
  339. package/bundled-test-harness/assets/process-card-DumVcx9E.js +114 -0
  340. package/bundled-test-harness/assets/process-card-test-C44H8yVy.js +94 -0
  341. package/bundled-test-harness/assets/profile-settings-modal-ipYzrVTz.js +708 -0
  342. package/bundled-test-harness/assets/progress-circle-DJ6WSO2E.js +95 -0
  343. package/bundled-test-harness/assets/progress-circle-q358_9Sn.js +2 -0
  344. package/bundled-test-harness/assets/quarter-BjO5DlU2.js +2 -0
  345. package/bundled-test-harness/assets/quarter-_D72FwfS.js +168 -0
  346. package/bundled-test-harness/assets/query-field-membership-status-test-CzDyfK49.js +323 -0
  347. package/bundled-test-harness/assets/query-field-page-optin-test-B-x3vsmC.js +126 -0
  348. package/bundled-test-harness/assets/query-field-schema-test-DFw6KuYv.js +231 -0
  349. package/bundled-test-harness/assets/query-field-stale-prerender-test-DSQ-cv_O.js +152 -0
  350. package/bundled-test-harness/assets/query-fields-test-DQiMFRCe.js +535 -0
  351. package/bundled-test-harness/assets/rail-CNspDFyn.js +44 -0
  352. package/bundled-test-harness/assets/rail-D2YcQ0VP.js +2 -0
  353. package/bundled-test-harness/assets/realm-82Z5RUM_.js +95 -0
  354. package/bundled-test-harness/assets/realm-config-SgrwqjRu.js +844 -0
  355. package/bundled-test-harness/assets/realm-config-policy-standing-test-C6sQNk2u.js +290 -0
  356. package/bundled-test-harness/assets/realm-config-routing-rule-edit-test-DcYXBlvi.js +274 -0
  357. package/bundled-test-harness/assets/realm-config-settings-test-DblJv06X.js +187 -0
  358. package/bundled-test-harness/assets/realm-dropdown-CDvL8k3B.js +560 -0
  359. package/bundled-test-harness/assets/realm-et890flh.js +2 -0
  360. package/bundled-test-harness/assets/realm-field-test-pBK_x-Xw.js +100 -0
  361. package/bundled-test-harness/assets/realm-indexing-test-DSFn2F8F.js +4380 -0
  362. package/bundled-test-harness/assets/realm-policy-test-DYnLqzTS.js +1141 -0
  363. package/bundled-test-harness/assets/realm-test-DOZT2EG5.js +2363 -0
  364. package/bundled-test-harness/assets/realm-url-tooltip-qaXTjRb-.js +56 -0
  365. package/bundled-test-harness/assets/realm-url-tooltip-test-DGTEeLH9.js +78 -0
  366. package/bundled-test-harness/assets/reasoning-test-BRkhvYjr.js +234 -0
  367. package/bundled-test-harness/assets/recent-colors-addon-BreXcpg8.js +2 -0
  368. package/bundled-test-harness/assets/recent-colors-addon-CmCkbJ2_.js +61 -0
  369. package/bundled-test-harness/assets/relationship-loading-state-test-B6UGYKzG.js +290 -0
  370. package/bundled-test-harness/assets/relative-time-BjHvL023.js +2 -0
  371. package/bundled-test-harness/assets/relative-time-ChYKOMIM.js +129 -0
  372. package/bundled-test-harness/assets/remix-card-test-CpV0kKfq.js +58 -0
  373. package/bundled-test-harness/assets/rendered-markdown-CJa7IzCC.js +263 -0
  374. package/bundled-test-harness/assets/rendered-markdown-test-CVKsHS4P.js +587 -0
  375. package/bundled-test-harness/assets/resident-instance-reuse-test-jQfW1NMn.js +82 -0
  376. package/bundled-test-harness/assets/response-field-B2-daCl2.js +38 -0
  377. package/bundled-test-harness/assets/result-tile-BSg4mzbc.js +140 -0
  378. package/bundled-test-harness/assets/rich-markdown-BtP1yamM.js +2 -0
  379. package/bundled-test-harness/assets/rich-markdown-C6rQUngb.js +218 -0
  380. package/bundled-test-harness/assets/rich-markdown-field-test-9yB6ykCe.js +1647 -0
  381. package/bundled-test-harness/assets/room-C7tKd02X.js +1008 -0
  382. package/bundled-test-harness/assets/room-message-test-DsMmRYpV.js +445 -0
  383. package/bundled-test-harness/assets/room-test-golI1H61.js +95 -0
  384. package/bundled-test-harness/assets/run-realm-code-CbXk6bnK.js +1600 -0
  385. package/bundled-test-harness/assets/run-realm-code-test-B9JeesaW.js +2468 -0
  386. package/bundled-test-harness/assets/schema-generation-test-uLLGm5Vh.js +28 -0
  387. package/bundled-test-harness/assets/score-BQhCQdUP.js +2 -0
  388. package/bundled-test-harness/assets/score-CoWEzENH.js +100 -0
  389. package/bundled-test-harness/assets/scrolling-test-WHWEkKeZ.js +384 -0
  390. package/bundled-test-harness/assets/search-BkQYpQDY.js +605 -0
  391. package/bundled-test-harness/assets/search-adorn-test-CW92JPOk.js +136 -0
  392. package/bundled-test-harness/assets/search-entries-BU4w6Ymc.js +472 -0
  393. package/bundled-test-harness/assets/search-entries-result-test-9eydsDtD.js +234 -0
  394. package/bundled-test-harness/assets/search-entries-test-ByUREx0G.js +1486 -0
  395. package/bundled-test-harness/assets/search-result-header-UFkdo0Bx.js +128 -0
  396. package/bundled-test-harness/assets/search-results-DrHTuVRZ.js +266 -0
  397. package/bundled-test-harness/assets/search-results-test-krtQQM57.js +578 -0
  398. package/bundled-test-harness/assets/search-selection-menu-test-DoqSbez7.js +108 -0
  399. package/bundled-test-harness/assets/search-sheet-persistence-test-4ZPaEY-y.js +131 -0
  400. package/bundled-test-harness/assets/search-test-BYpq32RM.js +2241 -0
  401. package/bundled-test-harness/assets/searchable-BXw4T11q.js +192 -0
  402. package/bundled-test-harness/assets/searchable-CVvPDA3Q.js +2 -0
  403. package/bundled-test-harness/assets/searchable-option-test-BhLFI4ei.js +322 -0
  404. package/bundled-test-harness/assets/searchable-search-doc-test-DrNLCF73.js +1271 -0
  405. package/bundled-test-harness/assets/secure-sign-in-VNQhe0ae.js +130 -0
  406. package/bundled-test-harness/assets/secure-sign-in-Za8PX9cD.css +24 -0
  407. package/bundled-test-harness/assets/secure-sign-in-aunWHCrB.js +73 -0
  408. package/bundled-test-harness/assets/secure-sign-in-test-BcY1TcNd.js +32 -0
  409. package/bundled-test-harness/assets/secure-sign-in-test-DRdz89BT.js +245 -0
  410. package/bundled-test-harness/assets/sending-test-mbHpGZUu.js +576 -0
  411. package/bundled-test-harness/assets/serialization-rri-form-audit-test-nypV9J82.js +136 -0
  412. package/bundled-test-harness/assets/serialization-test-aLwrFv4d.js +8758 -0
  413. package/bundled-test-harness/assets/setup-Dgn0s6Zk.js +772 -0
  414. package/bundled-test-harness/assets/shared-link-target-reuse-test-D9MR2UNc.js +207 -0
  415. package/bundled-test-harness/assets/show-card-Dwfk332M.js +67 -0
  416. package/bundled-test-harness/assets/show-card-test-CRPwwJvc.js +365 -0
  417. package/bundled-test-harness/assets/show-file-DLdFPHMR.js +34 -0
  418. package/bundled-test-harness/assets/signed-capture-DUR9PohQ.js +204 -0
  419. package/bundled-test-harness/assets/signed-capture-link-test-DfTAB6OT.js +132 -0
  420. package/bundled-test-harness/assets/single-stack-test-Crr_8nti.js +652 -0
  421. package/bundled-test-harness/assets/skill-DQ00VonZ.js +3 -0
  422. package/bundled-test-harness/assets/skill-reference-LEitQV9i.js +112 -0
  423. package/bundled-test-harness/assets/skill-yZXS1VHQ.js +76 -0
  424. package/bundled-test-harness/assets/skills-test-D3-C-Dbm.js +648 -0
  425. package/bundled-test-harness/assets/slider-picker-B6AxKL2j.js +245 -0
  426. package/bundled-test-harness/assets/slider-picker-C4Tc5o-s.js +2 -0
  427. package/bundled-test-harness/assets/spec-Cl_LB6nC.js +602 -0
  428. package/bundled-test-harness/assets/spinner-BHFM7zcR.js +39 -0
  429. package/bundled-test-harness/assets/spinner-DvAvsyDT.css +21 -0
  430. package/bundled-test-harness/assets/store-BV6WX8oV.js +2205 -0
  431. package/bundled-test-harness/assets/store-module-rebuild-test-HyphFJiF.js +454 -0
  432. package/bundled-test-harness/assets/store-search-test-nUeJ5opb.js +175 -0
  433. package/bundled-test-harness/assets/store-test-BebUIJAg.js +3460 -0
  434. package/bundled-test-harness/assets/string-BHZZwNlZ.js +9 -0
  435. package/bundled-test-harness/assets/submode-switcher-D-U9cXo0.js +169 -0
  436. package/bundled-test-harness/assets/svg-meta-extractor-BsG4w2nX.js +42 -0
  437. package/bundled-test-harness/assets/swatches-picker-4vFztxHo.js +33 -0
  438. package/bundled-test-harness/assets/swatches-picker-C7RE7uJ8.js +2 -0
  439. package/bundled-test-harness/assets/switch-submode-CuA0Zfjn.js +79 -0
  440. package/bundled-test-harness/assets/switch-submode-test-i1Qic_Cp.js +168 -0
  441. package/bundled-test-harness/assets/tag-CZNs3DPN.js +105 -0
  442. package/bundled-test-harness/assets/tests-BneuP252.js +3523 -0
  443. package/bundled-test-harness/assets/text-area-DAShQQBe.js +9 -0
  444. package/bundled-test-harness/assets/text-file-def-D2Rs6nS1.js +151 -0
  445. package/bundled-test-harness/assets/text-input-validator-test-C9IG-1GZ.js +156 -0
  446. package/bundled-test-harness/assets/theme-Dm8LWaRK.js +9 -0
  447. package/bundled-test-harness/assets/theme-card-test-Cbb6tAap.js +621 -0
  448. package/bundled-test-harness/assets/theme-scheme-island-test-DOVLakx3.js +264 -0
  449. package/bundled-test-harness/assets/three-d-model-def-DWSPQGgD.js +70 -0
  450. package/bundled-test-harness/assets/time--_Txqya1.js +126 -0
  451. package/bundled-test-harness/assets/time-DKD7Bdjd.js +2 -0
  452. package/bundled-test-harness/assets/time-slots-BZaugjq_.js +2 -0
  453. package/bundled-test-harness/assets/time-slots-C85M0rWl.js +85 -0
  454. package/bundled-test-harness/assets/timeline-B3KGDm3M.js +2 -0
  455. package/bundled-test-harness/assets/timeline-BMwgaZZu.js +59 -0
  456. package/bundled-test-harness/assets/to-device-streaming-test-CMp5bFiz.js +163 -0
  457. package/bundled-test-harness/assets/token-usage-test-CXA0b8Ep.js +166 -0
  458. package/bundled-test-harness/assets/tool-field-BGLelnsr.js +94 -0
  459. package/bundled-test-harness/assets/tool-field-BOFuDDt3.js +2 -0
  460. package/bundled-test-harness/assets/tools-CTjy7Aub.js +725 -0
  461. package/bundled-test-harness/assets/tools-calling-test--JR-7AK7.js +200 -0
  462. package/bundled-test-harness/assets/tools-test-6yAW3W5I.js +2820 -0
  463. package/bundled-test-harness/assets/tools-test-DhpMUQkz.js +1624 -0
  464. package/bundled-test-harness/assets/ts-file-def-CDbf8aw2.js +159 -0
  465. package/bundled-test-harness/assets/update-room-skills-test-DoKsS_1C.js +240 -0
  466. package/bundled-test-harness/assets/url-D0ooeJxC.js +2 -0
  467. package/bundled-test-harness/assets/url-mFskVPSX.js +96 -0
  468. package/bundled-test-harness/assets/video-file-def-AcmWqzev.js +76 -0
  469. package/bundled-test-harness/assets/wav-meta-extractor-CbTLruQf.js +368 -0
  470. package/bundled-test-harness/assets/webm-meta-extractor-C9JH-CMX.js +178 -0
  471. package/bundled-test-harness/assets/webp-meta-extractor-C6sHm4J7.js +98 -0
  472. package/bundled-test-harness/assets/website-Bxuk_OmR.js +92 -0
  473. package/bundled-test-harness/assets/week-Bxssxce7.js +2 -0
  474. package/bundled-test-harness/assets/week-DQLj9974.js +111 -0
  475. package/bundled-test-harness/assets/welcome-to-boxel-BH82RsW5.js +172 -0
  476. package/bundled-test-harness/assets/workspace-DJ_s2x4g.js +614 -0
  477. package/bundled-test-harness/assets/workspace-a11y-test-BJbZNgoP.js +197 -0
  478. package/bundled-test-harness/assets/workspace-behavior-test-BLBARTfb.js +200 -0
  479. package/bundled-test-harness/assets/workspace-chooser-BpmlVrVn.js +2219 -0
  480. package/bundled-test-harness/assets/workspace-chooser-CqLR2Dzh.css +1296 -0
  481. package/bundled-test-harness/assets/workspace-chooser-catalog-order-test-CmAVNAWC.js +36 -0
  482. package/bundled-test-harness/assets/workspace-chooser-unreachable-notice-test-DEfG7Uh9.js +60 -0
  483. package/bundled-test-harness/assets/workspace-delete-multiple-test-DE7Z8ooj.js +212 -0
  484. package/bundled-test-harness/assets/workspace-delete-summary-test-CwtG_zLH.js +63 -0
  485. package/bundled-test-harness/assets/workspace-timestamp-labels-test-DFAaRmJW.js +58 -0
  486. package/bundled-test-harness/assets/xlsx-file-def-DcvaRYnZ.js +60 -0
  487. package/bundled-test-harness/assets/xlsx-meta-extractor-0RlViVaf.js +101 -0
  488. package/bundled-test-harness/assets/xlsx-meta-extractor-BH30Vuem.js +2 -0
  489. package/bundled-test-harness/assets/year-B_MBk_hE.js +78 -0
  490. package/bundled-test-harness/assets/year-hSpccI9L.js +2 -0
  491. package/bundled-test-harness/assets/zip-file-def-c84iddi9.js +288 -0
  492. package/bundled-test-harness/index.html +78 -68
  493. package/bundled-test-harness/tests/index.html +78 -68
  494. package/bundled-types/host-app/components/matrix/account-switch-failed.gts +2 -2
  495. package/bundled-types/host-app/components/matrix/auth.gts +2 -2
  496. package/bundled-types/host-app/components/matrix/cli-auth.gts +7 -6
  497. package/bundled-types/host-app/components/matrix/forgot-password.gts +43 -129
  498. package/bundled-types/host-app/components/matrix/login.gts +15 -118
  499. package/bundled-types/host-app/components/matrix/register-user.gts +45 -226
  500. package/bundled-types/host-app/components/matrix/secure-sign-in.gts +235 -0
  501. package/bundled-types/host-app/components/operator-mode/container.gts +13 -1
  502. package/bundled-types/host-app/components/operator-mode/profile-info-popover.gts +1 -1
  503. package/bundled-types/host-app/config/environment.ts +1 -1
  504. package/bundled-types/host-app/lib/secure-sign-in.ts +130 -0
  505. package/bundled-types/host-app/services/matrix-service.ts +46 -0
  506. package/bundled-types/host-app/services/monaco-service.ts +0 -5
  507. package/bundled-types/host-app/utils/login-token.ts +23 -10
  508. package/dist/api.js +1 -1
  509. package/dist/index.js +289 -285
  510. package/package.json +1 -1
  511. package/src/build-program.ts +6 -2
  512. package/src/commands/profile.ts +72 -3
  513. package/src/lib/profile-manager.ts +5 -1
  514. package/src/lib/secure-session.ts +29 -0
  515. package/src/lib/sso-login.ts +94 -15
  516. package/bundled-test-harness/assets/account-switch-failed-B3pr_iC3.js +0 -32
  517. package/bundled-test-harness/assets/account-switch-failed-DTGZZo-G.css +0 -61
  518. package/bundled-test-harness/assets/account-switch-failed-test-9ENVgvlx.js +0 -45
  519. package/bundled-test-harness/assets/add-workspace-BAbk0250.js +0 -141
  520. package/bundled-test-harness/assets/add-workspace-test-ChAja_t-.js +0 -72
  521. package/bundled-test-harness/assets/advanced-color-picker-C-xBFJ2S.js +0 -504
  522. package/bundled-test-harness/assets/advanced-color-picker-bWAmCT-8.js +0 -2
  523. package/bundled-test-harness/assets/ai-assistant-test-BJ9yetuC.js +0 -2211
  524. package/bundled-test-harness/assets/ai-module-creation-test-Bw3TKS9d.js +0 -151
  525. package/bundled-test-harness/assets/aibot-message-DkgHT6eJ.js +0 -465
  526. package/bundled-test-harness/assets/app-DW5QjtRp.js +0 -22816
  527. package/bundled-test-harness/assets/app-yCDjO4mk.css +0 -2718
  528. package/bundled-test-harness/assets/audio-file-def-bJ3cXVmC.js +0 -133
  529. package/bundled-test-harness/assets/avif-meta-extractor-CrSDfYEt.js +0 -162
  530. package/bundled-test-harness/assets/base64-image-C7UBjK5W.js +0 -262
  531. package/bundled-test-harness/assets/base64-image-CjWpxROT.js +0 -2
  532. package/bundled-test-harness/assets/big-integer-BBql7oGZ.js +0 -89
  533. package/bundled-test-harness/assets/big-integer-B_TrzRy_.js +0 -2
  534. package/bundled-test-harness/assets/binary-upload-dedupe-test-BiX8kS7D.js +0 -308
  535. package/bundled-test-harness/assets/boolean-9LNUUTfw.js +0 -2
  536. package/bundled-test-harness/assets/boolean-BAmK01TF.js +0 -94
  537. package/bundled-test-harness/assets/brand-functional-palette-CFuoS-LS.js +0 -137
  538. package/bundled-test-harness/assets/brand-logo-By89eknI.js +0 -295
  539. package/bundled-test-harness/assets/broken-link-template-test-odBriDSP.js +0 -192
  540. package/bundled-test-harness/assets/bundled-base-CLQkkmN4.js +0 -254
  541. package/bundled-test-harness/assets/bundled-base-modules-test-BYrTaTwa.js +0 -54
  542. package/bundled-test-harness/assets/buried-stack-item-scroll-test-DU4bM5nd.js +0 -236
  543. package/bundled-test-harness/assets/bxl-expression-test-Cs9JaZbC.js +0 -250
  544. package/bundled-test-harness/assets/can-invoke-test-ccMc06BU.js +0 -401
  545. package/bundled-test-harness/assets/card-api-Bn65NUT0.js +0 -8
  546. package/bundled-test-harness/assets/card-api-test-COrFXu2i.js +0 -198
  547. package/bundled-test-harness/assets/card-api-u1pOrwS6.js +0 -4393
  548. package/bundled-test-harness/assets/card-basics-test-D4rn3iN-.js +0 -5364
  549. package/bundled-test-harness/assets/card-chooser-paging-test-bZhdrUXt.js +0 -235
  550. package/bundled-test-harness/assets/card-chooser-test-D9w1duob.js +0 -393
  551. package/bundled-test-harness/assets/card-collection-ClCV-__1.js +0 -118
  552. package/bundled-test-harness/assets/card-context-search-results-H_rN3Upz.js +0 -30
  553. package/bundled-test-harness/assets/card-context-search-results-test-jciyaouV.js +0 -184
  554. package/bundled-test-harness/assets/card-def-field-def-relationships-test-BVZoQzM8.js +0 -562
  555. package/bundled-test-harness/assets/card-delete-test-CuLcZFnY.js +0 -466
  556. package/bundled-test-harness/assets/card-error-DIOivSkD.js +0 -72
  557. package/bundled-test-harness/assets/card-error-awaiting-index-test-JMwcRONq.js +0 -53
  558. package/bundled-test-harness/assets/card-error-detail-96jWBx6B.js +0 -271
  559. package/bundled-test-harness/assets/card-info-BxPtwG1h.js +0 -2
  560. package/bundled-test-harness/assets/card-list-B34qY3io.js +0 -2
  561. package/bundled-test-harness/assets/card-list-BpCaKkZJ.js +0 -202
  562. package/bundled-test-harness/assets/card-resource-DcPbIwH9.js +0 -86
  563. package/bundled-test-harness/assets/cards-grid-CTN8nBT_.js +0 -344
  564. package/bundled-test-harness/assets/cards-grid-Cx44vL-M.js +0 -2
  565. package/bundled-test-harness/assets/cards-grid-layout-BdL0Uzxl.js +0 -111
  566. package/bundled-test-harness/assets/cards-grid-layout-Dn8Yb4ma.js +0 -2
  567. package/bundled-test-harness/assets/check-correctness-test-BfMV-MC0.js +0 -554
  568. package/bundled-test-harness/assets/clip-CK6mVuyN.js +0 -92
  569. package/bundled-test-harness/assets/clip-CfXD1JTr.js +0 -2
  570. package/bundled-test-harness/assets/code-ref-85Bih6Zl.js +0 -138
  571. package/bundled-test-harness/assets/code-ref-DATHaoyt.js +0 -2
  572. package/bundled-test-harness/assets/code-submode-availability-test-DLYlx0wo.js +0 -198
  573. package/bundled-test-harness/assets/code-submode-test-CDIi7MjD.js +0 -1824
  574. package/bundled-test-harness/assets/codeblocks-test-CNPyTvuv.js +0 -418
  575. package/bundled-test-harness/assets/codemirror-editor-BPOPTR-f.js +0 -2
  576. package/bundled-test-harness/assets/codemirror-editor-DPhG0pec.js +0 -701
  577. package/bundled-test-harness/assets/codemirror-embed-toolbar-test-Dk5lFOUq.js +0 -366
  578. package/bundled-test-harness/assets/color-BxN5gRSg.js +0 -65
  579. package/bundled-test-harness/assets/color-CrunRcis.js +0 -2
  580. package/bundled-test-harness/assets/color-field-test-COjFIpXV.js +0 -212
  581. package/bundled-test-harness/assets/color-picker-field-C-GS1CIw.js +0 -139
  582. package/bundled-test-harness/assets/color-picker-field-D3RXhbCK.js +0 -2
  583. package/bundled-test-harness/assets/color-wheel-picker-Bz8cBmf4.js +0 -283
  584. package/bundled-test-harness/assets/color-wheel-picker-DrwPrB8B.js +0 -2
  585. package/bundled-test-harness/assets/command-data-BxXgtNBf.js +0 -2
  586. package/bundled-test-harness/assets/command-data-ZdkcpEgG.js +0 -95
  587. package/bundled-test-harness/assets/compaction-test-DS7DTGT_.js +0 -150
  588. package/bundled-test-harness/assets/components-CbCTWAON.js +0 -17777
  589. package/bundled-test-harness/assets/computed-test-D_OrXDtR.js +0 -1320
  590. package/bundled-test-harness/assets/container-DDolu1gk.js +0 -11109
  591. package/bundled-test-harness/assets/container-DndcCIMv.css +0 -5169
  592. package/bundled-test-harness/assets/contains-many-component-BtgnAXih.js +0 -2
  593. package/bundled-test-harness/assets/contrast-checker-addon-kwtLKWdL.js +0 -2
  594. package/bundled-test-harness/assets/contrast-checker-addon-zFY5cen1.js +0 -71
  595. package/bundled-test-harness/assets/convert-to-class-name-test-BcGWl2K1.js +0 -17
  596. package/bundled-test-harness/assets/coordinate-D72EF1Pl.js +0 -48
  597. package/bundled-test-harness/assets/copy-file-to-realm-test-CYoDX4YV.js +0 -148
  598. package/bundled-test-harness/assets/country-B-iIe5v8.js +0 -199
  599. package/bundled-test-harness/assets/create-file-modal-PpvMksjR.js +0 -570
  600. package/bundled-test-harness/assets/create-listing-modal-test-CQtEf_UD.js +0 -273
  601. package/bundled-test-harness/assets/create-listing-pr-request-test-CDtKWyfk.js +0 -117
  602. package/bundled-test-harness/assets/create-spec-test-Cbqk8I9T.js +0 -256
  603. package/bundled-test-harness/assets/create-specs-CZg2cpnh.js +0 -215
  604. package/bundled-test-harness/assets/create-submission-workflow-test-CYrxF7bg.js +0 -132
  605. package/bundled-test-harness/assets/credential-fields-test-Di4jCJgU.js +0 -157
  606. package/bundled-test-harness/assets/css-value-CceJyI5o.js +0 -48
  607. package/bundled-test-harness/assets/csv-file-def-DJL2aZI9.js +0 -277
  608. package/bundled-test-harness/assets/currency-Bn5WIqzF.js +0 -134
  609. package/bundled-test-harness/assets/date-XI2CVYA2.js +0 -2
  610. package/bundled-test-harness/assets/date-h83UJcFR.js +0 -183
  611. package/bundled-test-harness/assets/date-time-fields-test-Cterr2mj.js +0 -359
  612. package/bundled-test-harness/assets/datetime-DadI80tC.js +0 -201
  613. package/bundled-test-harness/assets/datetime-Dpb_Sejj.js +0 -2
  614. package/bundled-test-harness/assets/datetime-stamp-C4vv397u.js +0 -81
  615. package/bundled-test-harness/assets/datetime-stamp-DIsJdQux.js +0 -2
  616. package/bundled-test-harness/assets/day-C4pZoGNM.js +0 -113
  617. package/bundled-test-harness/assets/day-D0goBhKb.js +0 -2
  618. package/bundled-test-harness/assets/debug-message-test-CV0sj-fl.js +0 -117
  619. package/bundled-test-harness/assets/dist-CAIttNZm.js +0 -1710
  620. package/bundled-test-harness/assets/dist-CLbqnmnm.js +0 -389
  621. package/bundled-test-harness/assets/dist-qkBOmIQy.js +0 -323
  622. package/bundled-test-harness/assets/docx-file-def-hz2tVQKf.js +0 -60
  623. package/bundled-test-harness/assets/docx-meta-extractor-CeRshlxL.js +0 -60
  624. package/bundled-test-harness/assets/docx-meta-extractor-muK5CKF3.js +0 -2
  625. package/bundled-test-harness/assets/duration-BYx1dLfm.js +0 -2
  626. package/bundled-test-harness/assets/duration-FAmTFeUa.js +0 -184
  627. package/bundled-test-harness/assets/email-D-bFy_C1.js +0 -80
  628. package/bundled-test-harness/assets/email-field-test-CY9K2zur.js +0 -75
  629. package/bundled-test-harness/assets/email-j4DZNH2-.js +0 -2
  630. package/bundled-test-harness/assets/enum-B7_baAn_.js +0 -167
  631. package/bundled-test-harness/assets/enum-BQqNzVQS.js +0 -2
  632. package/bundled-test-harness/assets/enum-field-test-BJ9Epz15.js +0 -953
  633. package/bundled-test-harness/assets/error-display-test-CbDWjJ2F.js +0 -343
  634. package/bundled-test-harness/assets/ethereum-address-BOLEnKsm.js +0 -78
  635. package/bundled-test-harness/assets/ethereum-address-s3Kvb2wG.js +0 -2
  636. package/bundled-test-harness/assets/expiration-warning-BaIP1MOZ.js +0 -2
  637. package/bundled-test-harness/assets/expiration-warning-gjEtxPk0.js +0 -90
  638. package/bundled-test-harness/assets/externals-Bih8ejPS.js +0 -4393
  639. package/bundled-test-harness/assets/fallback-banner-MlImHjSD.js +0 -24
  640. package/bundled-test-harness/assets/fallback-banner-live-delete-test-Bm7IKXPf.js +0 -207
  641. package/bundled-test-harness/assets/fallback-banner-test-C7TGA0Ob.js +0 -53
  642. package/bundled-test-harness/assets/fallback-banner-test-lvuaVRXu.js +0 -225
  643. package/bundled-test-harness/assets/fallback-models-test-Dy7iIKUS.js +0 -161
  644. package/bundled-test-harness/assets/field-component-DBoOxTke.js +0 -2
  645. package/bundled-test-harness/assets/field-configuration-test-DnAnzyC-.js +0 -548
  646. package/bundled-test-harness/assets/field-edit-DdJ8Akso.js +0 -2
  647. package/bundled-test-harness/assets/field-edit-XAop92l8.js +0 -36
  648. package/bundled-test-harness/assets/field-markdown-domain-test-cZCqbcjj.js +0 -616
  649. package/bundled-test-harness/assets/field-markdown-oversize-test-BuATetVz.js +0 -88
  650. package/bundled-test-harness/assets/field-markdown-primitives-test-BsubQfhv.js +0 -365
  651. package/bundled-test-harness/assets/field-markdown-specialized-test-4eNLiYpF.js +0 -534
  652. package/bundled-test-harness/assets/field-test-helpers-9I7cHnaU.js +0 -45
  653. package/bundled-test-harness/assets/file-api-CC86I7Er.js +0 -7
  654. package/bundled-test-harness/assets/file-attachment-test-o9191GMb.js +0 -796
  655. package/bundled-test-harness/assets/file-chooser-panel-test-C8aZuJlk.js +0 -153
  656. package/bundled-test-harness/assets/file-chooser-test-B0Tn8CCR.js +0 -504
  657. package/bundled-test-harness/assets/file-def-edit-BSiF2Lje.js +0 -2
  658. package/bundled-test-harness/assets/file-def-edit-C5TYBp_q.js +0 -26
  659. package/bundled-test-harness/assets/file-def-embedded-BLVTCiVB.js +0 -2
  660. package/bundled-test-harness/assets/file-def-embedded-Bep4iD6s.js +0 -38
  661. package/bundled-test-harness/assets/file-def-fitted-BTs-AS78.js +0 -2
  662. package/bundled-test-harness/assets/file-def-fitted-DcPitdYu.js +0 -38
  663. package/bundled-test-harness/assets/file-def-isolated-Kg1YVhm-.js +0 -38
  664. package/bundled-test-harness/assets/file-def-isolated-tK5JWCam.js +0 -2
  665. package/bundled-test-harness/assets/file-def-serialization-test-D4wnd5XK.js +0 -89
  666. package/bundled-test-harness/assets/file-menu-items-CH4-naSK.js +0 -117
  667. package/bundled-test-harness/assets/file-menu-items-emUxx3ZI.js +0 -2
  668. package/bundled-test-harness/assets/file-preview-stage-B1McIWwu.js +0 -2
  669. package/bundled-test-harness/assets/file-preview-stage-BgZLNMN4.js +0 -72
  670. package/bundled-test-harness/assets/file-shell-embedded-BmfuwWfU.js +0 -2
  671. package/bundled-test-harness/assets/file-shell-embedded-zh8CJanA.js +0 -68
  672. package/bundled-test-harness/assets/file-shell-fitted-DSFUNRGJ.js +0 -2
  673. package/bundled-test-harness/assets/file-shell-fitted-DXKDH0fn.js +0 -98
  674. package/bundled-test-harness/assets/file-shell-isolated-0F1MFv4q.js +0 -2
  675. package/bundled-test-harness/assets/file-shell-isolated-DduZZzmi.js +0 -195
  676. package/bundled-test-harness/assets/file-tree-from-index-BzDvvUHy.js +0 -151
  677. package/bundled-test-harness/assets/file-tree-from-index-test-D0hfI4a1.js +0 -96
  678. package/bundled-test-harness/assets/film-BN_HVXBU.js +0 -13
  679. package/bundled-test-harness/assets/film-CKkbUi0L.js +0 -2
  680. package/bundled-test-harness/assets/film-CMNJITZ-.js +0 -4074
  681. package/bundled-test-harness/assets/fitted-CAvdcKpu.js +0 -34
  682. package/bundled-test-harness/assets/fitted-CbKOwd1u.js +0 -2
  683. package/bundled-test-harness/assets/flac-meta-extractor-e8qajPSl.js +0 -99
  684. package/bundled-test-harness/assets/font-file-def-9atde5W8.js +0 -64
  685. package/bundled-test-harness/assets/font-meta-extractor-IralDC8M.js +0 -303
  686. package/bundled-test-harness/assets/font-meta-extractor-zPBVOfoR.js +0 -2
  687. package/bundled-test-harness/assets/formatted-aibot-message-test-CWOiZUng.js +0 -109
  688. package/bundled-test-harness/assets/from-elsewhere-ChxbtsBa.js +0 -131
  689. package/bundled-test-harness/assets/frontmatter-field-cdig7KR9.js +0 -41
  690. package/bundled-test-harness/assets/garbage-collection-test-Dg-ww_Sb.js +0 -403
  691. package/bundled-test-harness/assets/gauge-B45nLOGe.js +0 -106
  692. package/bundled-test-harness/assets/gauge-BK-768BM.js +0 -2
  693. package/bundled-test-harness/assets/general-test-D7cn7PUr.js +0 -926
  694. package/bundled-test-harness/assets/get-relationship-membership-state-test-Skmj9V6y.js +0 -1308
  695. package/bundled-test-harness/assets/gif-meta-extractor-BychhK9q.js +0 -114
  696. package/bundled-test-harness/assets/glimmer-motion-and-choreo-in-cards-test-C09YUmk4.js +0 -160
  697. package/bundled-test-harness/assets/glimmer-motion-and-choreo-test-DYskx_Kk.js +0 -74
  698. package/bundled-test-harness/assets/helper-BHX0HLF2.js +0 -478
  699. package/bundled-test-harness/assets/host-submode-test-Clw_QnvF.js +0 -1243
  700. package/bundled-test-harness/assets/html-file-def-C0P9giwU.js +0 -82
  701. package/bundled-test-harness/assets/hydratable-card-DnjrxKsT.js +0 -147
  702. package/bundled-test-harness/assets/hydratable-card-test-BAmWHfv1.js +0 -426
  703. package/bundled-test-harness/assets/icons-DBXBZgLe.js +0 -894
  704. package/bundled-test-harness/assets/image-Cip6ojDd.js +0 -47
  705. package/bundled-test-harness/assets/image-file-def-BdQxjZcN.js +0 -65
  706. package/bundled-test-harness/assets/image-file-def-DP4aqWcS.js +0 -3
  707. package/bundled-test-harness/assets/index-changes-test-D8b_56Ke.js +0 -367
  708. package/bundled-test-harness/assets/index-query-engine-test-CCyaUwMX.js +0 -2593
  709. package/bundled-test-harness/assets/inspector-test-BJTVGdOO.js +0 -1930
  710. package/bundled-test-harness/assets/instance-filter-matcher-test-DjsPrXL7.js +0 -788
  711. package/bundled-test-harness/assets/interact-submode-creation-and-permissions-test-DSqM0vxh.js +0 -475
  712. package/bundled-test-harness/assets/interact-submode-setup-DF31UMX-.js +0 -566
  713. package/bundled-test-harness/assets/is-component-declaration-test-Did47eG9.js +0 -50
  714. package/bundled-test-harness/assets/iso-bmff-LuWkGL__.js +0 -205
  715. package/bundled-test-harness/assets/iso-bmff-_flO6c20.js +0 -2
  716. package/bundled-test-harness/assets/isolated-and-edit-frocLHin.js +0 -2
  717. package/bundled-test-harness/assets/job-priority-header-test-DHLAXfp7.js +0 -81
  718. package/bundled-test-harness/assets/job-scoped-instance-residency-test-C1Bt5j98.js +0 -103
  719. package/bundled-test-harness/assets/join-the-community-BBUSO2cs.js +0 -86
  720. package/bundled-test-harness/assets/jpg-meta-extractor-CoybO4Hq.js +0 -88
  721. package/bundled-test-harness/assets/json-field-8sdH5RQb.js +0 -2
  722. package/bundled-test-harness/assets/json-field-BDD3iTUh.js +0 -19
  723. package/bundled-test-harness/assets/json-file-def-BKibsfc6.js +0 -298
  724. package/bundled-test-harness/assets/last-modified-date-CR5jru2m.js +0 -43
  725. package/bundled-test-harness/assets/last-modified-date-test-jJ00YdTm.js +0 -28
  726. package/bundled-test-harness/assets/links-to-editor-rDoCYaN-.js +0 -2
  727. package/bundled-test-harness/assets/links-to-many-component-BqZT88Fb.js +0 -2
  728. package/bundled-test-harness/assets/linksto-broken-link-placeholder-test-Cp1Eb_4U.js +0 -398
  729. package/bundled-test-harness/assets/linksto-error-sentinel-test-Bddavnh_.js +0 -238
  730. package/bundled-test-harness/assets/linksto-many-broken-link-placeholder-test-c5WegXnR.js +0 -354
  731. package/bundled-test-harness/assets/linksto-many-per-slot-access-test-CWskzfGW.js +0 -303
  732. package/bundled-test-harness/assets/linksto-sentinel-reload-test-ByeVNhr8.js +0 -197
  733. package/bundled-test-harness/assets/linksto-sentinel-roundtrip-test-DP26i6Gb.js +0 -260
  734. package/bundled-test-harness/assets/linksto-singular-js-access-contract-test-fDUXx8tO.js +0 -196
  735. package/bundled-test-harness/assets/llm-model-BcLEkTV7.js +0 -64
  736. package/bundled-test-harness/assets/login-CeuuNVvU.css +0 -139
  737. package/bundled-test-harness/assets/login-DV0WlJv-.js +0 -348
  738. package/bundled-test-harness/assets/login-error-text-test-BMGY_9gW.js +0 -51
  739. package/bundled-test-harness/assets/login-test-CL9YpMH5.js +0 -246
  740. package/bundled-test-harness/assets/m4a-meta-extractor-CHO1JQtb.js +0 -204
  741. package/bundled-test-harness/assets/main-CPLT8JNu.js +0 -5
  742. package/bundled-test-harness/assets/markdown-BvBALLGh.js +0 -7
  743. package/bundled-test-harness/assets/markdown-DFezmrFD.js +0 -2
  744. package/bundled-test-harness/assets/markdown-editor-mode-select-Au64bcIO.js +0 -2
  745. package/bundled-test-harness/assets/markdown-editor-mode-select-rK9PP8rv.js +0 -54
  746. package/bundled-test-harness/assets/markdown-embed-chooser-modal-test-CIxizf5k.js +0 -470
  747. package/bundled-test-harness/assets/markdown-embed-preview-pane-test-C7GoNN7l.js +0 -447
  748. package/bundled-test-harness/assets/markdown-embed-preview-test-CDnj4uhd.js +0 -368
  749. package/bundled-test-harness/assets/markdown-fallback-n7PsLNmO.js +0 -2
  750. package/bundled-test-harness/assets/markdown-fallback-test-DTHT6OwQ.js +0 -316
  751. package/bundled-test-harness/assets/markdown-highlighting-test-DJ-4WSE_.js +0 -244
  752. package/bundled-test-harness/assets/markdown-preview-Ccelx5W-.js +0 -64
  753. package/bundled-test-harness/assets/markdown-preview-JXuMC_ve.js +0 -72
  754. package/bundled-test-harness/assets/markdown-preview-test-ByZqrpPk.js +0 -238
  755. package/bundled-test-harness/assets/markdown-skill-frontmatter-test-DAHGeL4K.js +0 -146
  756. package/bundled-test-harness/assets/menu-items-DzJm9H_H.js +0 -2
  757. package/bundled-test-harness/assets/message-tool-test-lmdrIEdY.js +0 -33
  758. package/bundled-test-harness/assets/metadata-fields-BZZr4Qe5.js +0 -2
  759. package/bundled-test-harness/assets/metadata-fields-BtdjGsKE.js +0 -1415
  760. package/bundled-test-harness/assets/midi-audio-def-uYbYFmFi.js +0 -52
  761. package/bundled-test-harness/assets/midi-meta-extractor-DNI5gc1q.js +0 -284
  762. package/bundled-test-harness/assets/midi-meta-extractor-DbKZ4fMG.js +0 -2
  763. package/bundled-test-harness/assets/migrate-skill-test-DI1xceiL.js +0 -161
  764. package/bundled-test-harness/assets/mini-CNoDyHqG.js +0 -1519
  765. package/bundled-test-harness/assets/mini-DexlIeKK.js +0 -85
  766. package/bundled-test-harness/assets/mini-card-chooser-test-DT5eIf1_.js +0 -272
  767. package/bundled-test-harness/assets/mini-file-chooser-test-DTQnKTZJ.js +0 -201
  768. package/bundled-test-harness/assets/missing-template-DL2mwddM.js +0 -2
  769. package/bundled-test-harness/assets/missing-template-ltqlJ4JC.js +0 -48
  770. package/bundled-test-harness/assets/modal-container-DRnt95-S.js +0 -40
  771. package/bundled-test-harness/assets/modal-zE95eEFp.js +0 -322
  772. package/bundled-test-harness/assets/model-cost-tier-test-CcFz7hcv.js +0 -173
  773. package/bundled-test-harness/assets/module-contents-service-Dk_zWt-V.js +0 -256
  774. package/bundled-test-harness/assets/month-BqReBYWo.js +0 -2
  775. package/bundled-test-harness/assets/month-RhvmIp40.js +0 -123
  776. package/bundled-test-harness/assets/month-day-XFAQA72z.js +0 -2
  777. package/bundled-test-harness/assets/month-day-XzKpk6nz.js +0 -192
  778. package/bundled-test-harness/assets/month-year-BeuNr2Cl.js +0 -2
  779. package/bundled-test-harness/assets/month-year-DhU7hATV.js +0 -93
  780. package/bundled-test-harness/assets/mp3-meta-extractor-Dx2RnJc5.js +0 -476
  781. package/bundled-test-harness/assets/mp4-meta-extractor--k0m8KsT.js +0 -188
  782. package/bundled-test-harness/assets/multiple-stacks-test-bC24IWcJ.js +0 -208
  783. package/bundled-test-harness/assets/nested-query-field-render-test-qxElXx1e.js +0 -249
  784. package/bundled-test-harness/assets/no-stacks-test-Br7IGAgV.js +0 -48
  785. package/bundled-test-harness/assets/number-73SsCMEF.js +0 -3
  786. package/bundled-test-harness/assets/number-CicTBWQd.js +0 -151
  787. package/bundled-test-harness/assets/number-field-test-kV5zXo1J.js +0 -184
  788. package/bundled-test-harness/assets/number-input-CQy4xUeA.js +0 -82
  789. package/bundled-test-harness/assets/office-extract-Bo8sbNkK.js +0 -27
  790. package/bundled-test-harness/assets/office-extract-CfBaoRMD.js +0 -2
  791. package/bundled-test-harness/assets/ogg-meta-extractor-aIf5q_Rq.js +0 -225
  792. package/bundled-test-harness/assets/on-key-C8acaldQ.js +0 -472
  793. package/bundled-test-harness/assets/ooxml-Bu3iZezv.js +0 -172
  794. package/bundled-test-harness/assets/ooxml-jQPBQK25.js +0 -2
  795. package/bundled-test-harness/assets/open-image-in-new-tab-test-CP7q3kMm.js +0 -52
  796. package/bundled-test-harness/assets/operation-lowering-test-9Mdr0hRT.js +0 -2812
  797. package/bundled-test-harness/assets/operations-R9b661Qn.js +0 -3
  798. package/bundled-test-harness/assets/operations-Zv_V3Api.js +0 -766
  799. package/bundled-test-harness/assets/operations-invocation-test-BJPpWb2H.js +0 -523
  800. package/bundled-test-harness/assets/operations-query-test-DufdmPQF.js +0 -459
  801. package/bundled-test-harness/assets/operations-test-CzT051YH.js +0 -2518
  802. package/bundled-test-harness/assets/operator-mode-acceptance-test-ByOIOcD0.js +0 -1188
  803. package/bundled-test-harness/assets/operator-mode-card-chooser-test-CNhR9mvv.js +0 -1036
  804. package/bundled-test-harness/assets/operator-mode-links-test-CuxSVTPR.js +0 -793
  805. package/bundled-test-harness/assets/operator-mode-state-service-CCeHt5SH.js +0 -1275
  806. package/bundled-test-harness/assets/operator-mode-state-service-test-C8TI9WWg.js +0 -206
  807. package/bundled-test-harness/assets/operator-mode-test-DG-mG8Tn.js +0 -683
  808. package/bundled-test-harness/assets/operator-mode-ui-test-DB7xhjS0.js +0 -1027
  809. package/bundled-test-harness/assets/overlay-menu-items-test-C6rcdF_S.js +0 -317
  810. package/bundled-test-harness/assets/overlays-D2zmPxzK.js +0 -270
  811. package/bundled-test-harness/assets/overlays-clip-test-Clpq3JzQ.js +0 -91
  812. package/bundled-test-harness/assets/overlays-detached-element-test-BtsTeJch.js +0 -56
  813. package/bundled-test-harness/assets/pane-f-IYhcWT.js +0 -330
  814. package/bundled-test-harness/assets/panel-B3PCSBbf.js +0 -3540
  815. package/bundled-test-harness/assets/panel-Ban7zCBP.js +0 -474
  816. package/bundled-test-harness/assets/past-sessions-test-uM2m-oKV.js +0 -321
  817. package/bundled-test-harness/assets/patch-fields-test-COPjDhnt.js +0 -1014
  818. package/bundled-test-harness/assets/patch-instance-test-CRb3dfby.js +0 -348
  819. package/bundled-test-harness/assets/pdf-file-def-J_yOUU8_.js +0 -76
  820. package/bundled-test-harness/assets/pdf-meta-extractor-83T5Bdo7.js +0 -156
  821. package/bundled-test-harness/assets/pdf-meta-extractor-INFIklMy.js +0 -2
  822. package/bundled-test-harness/assets/pdf-viewer-B4rRluWA.js +0 -2
  823. package/bundled-test-harness/assets/pdf-viewer-vYem8ozk.js +0 -112
  824. package/bundled-test-harness/assets/percentage-ChagfNRG.js +0 -84
  825. package/bundled-test-harness/assets/permission-checking-realm-test-Dmb2a428.js +0 -306
  826. package/bundled-test-harness/assets/phone-number-BiD2eaSd.js +0 -236
  827. package/bundled-test-harness/assets/phone-number-C-wt4_UK.js +0 -2
  828. package/bundled-test-harness/assets/phone-number-field-test-BHzAmuBP.js +0 -73
  829. package/bundled-test-harness/assets/plate-CqN2nM6P.js +0 -41
  830. package/bundled-test-harness/assets/plate-DaIfpORN.js +0 -2
  831. package/bundled-test-harness/assets/player-CGt5fTd5.js +0 -2
  832. package/bundled-test-harness/assets/player-CN0l44LK.js +0 -82
  833. package/bundled-test-harness/assets/plural-field-components-test-CO2g2opW.js +0 -198
  834. package/bundled-test-harness/assets/png-image-def-B_oou2wS.js +0 -48
  835. package/bundled-test-harness/assets/png-meta-extractor-BfPz1qP_.js +0 -2
  836. package/bundled-test-harness/assets/png-meta-extractor-C8ai8sPw.js +0 -111
  837. package/bundled-test-harness/assets/policy-scoped-search-test-BRRp2a1A.js +0 -339
  838. package/bundled-test-harness/assets/pptx-file-def-C3qYEHDM.js +0 -60
  839. package/bundled-test-harness/assets/pptx-meta-extractor-8IuoBq4I.js +0 -77
  840. package/bundled-test-harness/assets/pptx-meta-extractor-BPhy9RMM.js +0 -2
  841. package/bundled-test-harness/assets/prerender-persistence-block-test-Cteb_Rs_.js +0 -124
  842. package/bundled-test-harness/assets/prerender-serialize-cycle-test-CH7b6Ra9.js +0 -134
  843. package/bundled-test-harness/assets/preview-CmERZpI6.js +0 -74
  844. package/bundled-test-harness/assets/preview-format-BPMlCSbb.js +0 -41
  845. package/bundled-test-harness/assets/preview-format-test-B7sA8fbZ.js +0 -103
  846. package/bundled-test-harness/assets/process-card-CtDzDB-_.js +0 -2
  847. package/bundled-test-harness/assets/process-card-erbWKY5h.js +0 -114
  848. package/bundled-test-harness/assets/process-card-test-DXOt1jDW.js +0 -94
  849. package/bundled-test-harness/assets/profile-settings-modal-11BrR058.js +0 -708
  850. package/bundled-test-harness/assets/progress-circle-Cd79Zqh2.js +0 -2
  851. package/bundled-test-harness/assets/progress-circle-sc-W5aUl.js +0 -95
  852. package/bundled-test-harness/assets/quarter-B61kCpcD.js +0 -168
  853. package/bundled-test-harness/assets/quarter-d5jkTzcz.js +0 -2
  854. package/bundled-test-harness/assets/query-field-membership-status-test-BmpVfohw.js +0 -323
  855. package/bundled-test-harness/assets/query-field-page-optin-test-9_Cce-OJ.js +0 -126
  856. package/bundled-test-harness/assets/query-field-schema-test-CwV7xanX.js +0 -231
  857. package/bundled-test-harness/assets/query-field-stale-prerender-test-RkdnZ-VV.js +0 -152
  858. package/bundled-test-harness/assets/query-fields-test-BLxYkTAM.js +0 -535
  859. package/bundled-test-harness/assets/rail-CFPU0tFe.js +0 -2
  860. package/bundled-test-harness/assets/rail-CQ53Dakr.js +0 -44
  861. package/bundled-test-harness/assets/realm-DdVH9lSZ.js +0 -95
  862. package/bundled-test-harness/assets/realm-DdsFw3b-.js +0 -2
  863. package/bundled-test-harness/assets/realm-config-DIslxoB7.js +0 -844
  864. package/bundled-test-harness/assets/realm-config-policy-standing-test-b4WxNDor.js +0 -290
  865. package/bundled-test-harness/assets/realm-config-routing-rule-edit-test-C-rcvkkD.js +0 -274
  866. package/bundled-test-harness/assets/realm-config-settings-test-DDUkM3zw.js +0 -187
  867. package/bundled-test-harness/assets/realm-dropdown-1j55Dy-1.js +0 -560
  868. package/bundled-test-harness/assets/realm-field-test-D-uEtFKO.js +0 -100
  869. package/bundled-test-harness/assets/realm-indexing-test-U9m0epR-.js +0 -4380
  870. package/bundled-test-harness/assets/realm-policy-test-DhKabhlk.js +0 -1141
  871. package/bundled-test-harness/assets/realm-test-BX6C9SS5.js +0 -2363
  872. package/bundled-test-harness/assets/realm-url-tooltip-BjjcKqBx.js +0 -56
  873. package/bundled-test-harness/assets/realm-url-tooltip-test-DW0ZwEEE.js +0 -78
  874. package/bundled-test-harness/assets/reasoning-test-BWT94KXG.js +0 -234
  875. package/bundled-test-harness/assets/recent-colors-addon-CfgmgilF.js +0 -61
  876. package/bundled-test-harness/assets/recent-colors-addon-D--Ry3Pf.js +0 -2
  877. package/bundled-test-harness/assets/relationship-loading-state-test-C5R6jao_.js +0 -290
  878. package/bundled-test-harness/assets/relative-time-Bq7pqums.js +0 -2
  879. package/bundled-test-harness/assets/relative-time-D0QyW4ig.js +0 -129
  880. package/bundled-test-harness/assets/remix-card-test-Cy0h3Xdf.js +0 -58
  881. package/bundled-test-harness/assets/rendered-markdown-Hw_EF8SO.js +0 -263
  882. package/bundled-test-harness/assets/rendered-markdown-test-CqeF-UZd.js +0 -587
  883. package/bundled-test-harness/assets/resident-instance-reuse-test-BiI6L40n.js +0 -82
  884. package/bundled-test-harness/assets/response-field-BCxG5phG.js +0 -38
  885. package/bundled-test-harness/assets/result-tile-DMzRnTP8.js +0 -140
  886. package/bundled-test-harness/assets/rich-markdown-C4RUl7L0.js +0 -2
  887. package/bundled-test-harness/assets/rich-markdown-DxQSCg-o.js +0 -218
  888. package/bundled-test-harness/assets/rich-markdown-field-test-B7wpedKs.js +0 -1647
  889. package/bundled-test-harness/assets/room-D0M0Zwrs.js +0 -1008
  890. package/bundled-test-harness/assets/room-message-test-BWWd4xC8.js +0 -445
  891. package/bundled-test-harness/assets/room-test-DFH-nOwi.js +0 -95
  892. package/bundled-test-harness/assets/run-realm-code-DyVyEDBl.js +0 -1600
  893. package/bundled-test-harness/assets/run-realm-code-test-BpxF-tOz.js +0 -2468
  894. package/bundled-test-harness/assets/schema-generation-test-DjaJqpYP.js +0 -28
  895. package/bundled-test-harness/assets/score-Cfp34BE7.js +0 -2
  896. package/bundled-test-harness/assets/score-DIWWpeyf.js +0 -100
  897. package/bundled-test-harness/assets/scrolling-test-hA_uBwBg.js +0 -384
  898. package/bundled-test-harness/assets/search-C0-b7dJI.js +0 -605
  899. package/bundled-test-harness/assets/search-adorn-test-C6KP3AwA.js +0 -136
  900. package/bundled-test-harness/assets/search-entries-BfPq5sPS.js +0 -472
  901. package/bundled-test-harness/assets/search-entries-result-test-Bl9u_BOD.js +0 -234
  902. package/bundled-test-harness/assets/search-entries-test-BDC_lS43.js +0 -1486
  903. package/bundled-test-harness/assets/search-result-header-DCAze_cg.js +0 -128
  904. package/bundled-test-harness/assets/search-results-Dd0enVun.js +0 -266
  905. package/bundled-test-harness/assets/search-results-test-T5KEEII4.js +0 -578
  906. package/bundled-test-harness/assets/search-selection-menu-test-CCssnBq1.js +0 -108
  907. package/bundled-test-harness/assets/search-sheet-persistence-test-BzQiO-FK.js +0 -131
  908. package/bundled-test-harness/assets/search-test-fyCWb24m.js +0 -2241
  909. package/bundled-test-harness/assets/searchable-BkgeKQMl.js +0 -2
  910. package/bundled-test-harness/assets/searchable-D_6p6fyb.js +0 -192
  911. package/bundled-test-harness/assets/searchable-option-test-CnCUYGaq.js +0 -322
  912. package/bundled-test-harness/assets/searchable-search-doc-test-B8Q0D98v.js +0 -1271
  913. package/bundled-test-harness/assets/sending-test-D5PGBDys.js +0 -576
  914. package/bundled-test-harness/assets/serialization-rri-form-audit-test-BRJ1cJ31.js +0 -136
  915. package/bundled-test-harness/assets/serialization-test-DM6hK258.js +0 -8758
  916. package/bundled-test-harness/assets/setup-C_GgVgzM.js +0 -772
  917. package/bundled-test-harness/assets/shared-link-target-reuse-test-Be-lSKib.js +0 -207
  918. package/bundled-test-harness/assets/show-card-BFG6KR1m.js +0 -67
  919. package/bundled-test-harness/assets/show-card-test-l0wMrfZq.js +0 -365
  920. package/bundled-test-harness/assets/show-file-B8-FRVHj.js +0 -34
  921. package/bundled-test-harness/assets/signed-capture-D_Q44TQ7.js +0 -204
  922. package/bundled-test-harness/assets/signed-capture-link-test-DOS5xpYv.js +0 -132
  923. package/bundled-test-harness/assets/single-stack-test-BIEtzHVS.js +0 -652
  924. package/bundled-test-harness/assets/skill-BUTGmSsm.js +0 -76
  925. package/bundled-test-harness/assets/skill-Bo7R_2Ud.js +0 -3
  926. package/bundled-test-harness/assets/skill-reference-Cs64py3k.js +0 -112
  927. package/bundled-test-harness/assets/skills-test-CXxSIkYa.js +0 -648
  928. package/bundled-test-harness/assets/slider-picker-C81errGI.js +0 -245
  929. package/bundled-test-harness/assets/slider-picker-mvKsy6cR.js +0 -2
  930. package/bundled-test-harness/assets/spec-B55lJurX.js +0 -602
  931. package/bundled-test-harness/assets/store-DyQ0KiyI.js +0 -2205
  932. package/bundled-test-harness/assets/store-module-rebuild-test-C7532_bS.js +0 -454
  933. package/bundled-test-harness/assets/store-search-test-80NMJuoW.js +0 -175
  934. package/bundled-test-harness/assets/store-test-dHiWXXMs.js +0 -3460
  935. package/bundled-test-harness/assets/string-DHlQEHYm.js +0 -9
  936. package/bundled-test-harness/assets/submode-switcher-DQv-CD6G.js +0 -169
  937. package/bundled-test-harness/assets/svg-meta-extractor-Uw_EJytF.js +0 -42
  938. package/bundled-test-harness/assets/swatches-picker-CaEoibN1.js +0 -33
  939. package/bundled-test-harness/assets/swatches-picker-gPl50JbP.js +0 -2
  940. package/bundled-test-harness/assets/switch-submode-BKDnJd4m.js +0 -79
  941. package/bundled-test-harness/assets/switch-submode-test-_E2mVk4z.js +0 -168
  942. package/bundled-test-harness/assets/tag-B60lDr-j.js +0 -105
  943. package/bundled-test-harness/assets/tests-BBBgPBB6.js +0 -3520
  944. package/bundled-test-harness/assets/text-area-CJjWmwpi.js +0 -9
  945. package/bundled-test-harness/assets/text-file-def-u_dl0i2z.js +0 -151
  946. package/bundled-test-harness/assets/text-input-validator-test-BTwnkSS2.js +0 -156
  947. package/bundled-test-harness/assets/theme-BK-fAHVn.js +0 -9
  948. package/bundled-test-harness/assets/theme-card-test-BQmT7rqr.js +0 -621
  949. package/bundled-test-harness/assets/theme-scheme-island-test-Oi3aeyp1.js +0 -264
  950. package/bundled-test-harness/assets/three-d-model-def-B4KckPVC.js +0 -70
  951. package/bundled-test-harness/assets/time-BcuaSkHg.js +0 -126
  952. package/bundled-test-harness/assets/time-f7Irg7Z7.js +0 -2
  953. package/bundled-test-harness/assets/time-slots-ClYIZN53.js +0 -2
  954. package/bundled-test-harness/assets/time-slots-TI1aaqRN.js +0 -85
  955. package/bundled-test-harness/assets/timeline-Cof9eyq0.js +0 -59
  956. package/bundled-test-harness/assets/timeline-DFWQtCWE.js +0 -2
  957. package/bundled-test-harness/assets/to-device-streaming-test-BDrUUlOt.js +0 -163
  958. package/bundled-test-harness/assets/token-usage-test-CiZo03fY.js +0 -166
  959. package/bundled-test-harness/assets/tool-field-BXHr9r0w.js +0 -94
  960. package/bundled-test-harness/assets/tool-field-CoRO5C4R.js +0 -2
  961. package/bundled-test-harness/assets/tools-CmVaYDIS.js +0 -725
  962. package/bundled-test-harness/assets/tools-calling-test-B454__XF.js +0 -200
  963. package/bundled-test-harness/assets/tools-test-CLu51dJO.js +0 -1624
  964. package/bundled-test-harness/assets/tools-test-XGRAvVug.js +0 -2820
  965. package/bundled-test-harness/assets/ts-file-def-C05BDwdg.js +0 -159
  966. package/bundled-test-harness/assets/update-room-skills-test-jOvP14JX.js +0 -240
  967. package/bundled-test-harness/assets/url-BFf2CNo-.js +0 -2
  968. package/bundled-test-harness/assets/url-CYm-CeXp.js +0 -96
  969. package/bundled-test-harness/assets/video-file-def-B2UIrOFS.js +0 -76
  970. package/bundled-test-harness/assets/wav-meta-extractor-BNkv7e2f.js +0 -368
  971. package/bundled-test-harness/assets/webm-meta-extractor-C933kYyc.js +0 -178
  972. package/bundled-test-harness/assets/webp-meta-extractor-BLz0z1pZ.js +0 -98
  973. package/bundled-test-harness/assets/website-BuOMUW1v.js +0 -92
  974. package/bundled-test-harness/assets/week-Bo0666ji.js +0 -111
  975. package/bundled-test-harness/assets/week-CaVFA8Vc.js +0 -2
  976. package/bundled-test-harness/assets/welcome-to-boxel-PWard7GF.js +0 -172
  977. package/bundled-test-harness/assets/workspace-KXfFTQNV.js +0 -614
  978. package/bundled-test-harness/assets/workspace-a11y-test-Buwb-rfO.js +0 -197
  979. package/bundled-test-harness/assets/workspace-behavior-test-CbgFUOOo.js +0 -200
  980. package/bundled-test-harness/assets/workspace-chooser-BmQvhhrl.js +0 -2248
  981. package/bundled-test-harness/assets/workspace-chooser-Cu84Gd_E.css +0 -1317
  982. package/bundled-test-harness/assets/workspace-chooser-catalog-order-test-rcRw6sni.js +0 -36
  983. package/bundled-test-harness/assets/workspace-chooser-unreachable-notice-test-DUXnBIdY.js +0 -60
  984. package/bundled-test-harness/assets/workspace-delete-multiple-test-DjRKhZ2g.js +0 -212
  985. package/bundled-test-harness/assets/workspace-delete-summary-test-CvkLVYyN.js +0 -63
  986. package/bundled-test-harness/assets/workspace-timestamp-labels-test-AYJT4inv.js +0 -58
  987. package/bundled-test-harness/assets/xlsx-file-def-DuKdbGrJ.js +0 -60
  988. package/bundled-test-harness/assets/xlsx-meta-extractor-Bz-C2JWP.js +0 -101
  989. package/bundled-test-harness/assets/xlsx-meta-extractor-ClwwgABg.js +0 -2
  990. package/bundled-test-harness/assets/year-B6ctHikl.js +0 -2
  991. package/bundled-test-harness/assets/year-C11uAQE6.js +0 -78
  992. package/bundled-test-harness/assets/zip-file-def-B8XN-OS_.js +0 -288
  993. package/bundled-types/host-app/components/matrix/auth-button.gts +0 -39
  994. package/bundled-types/host-app/components/matrix/auth-container.gts +0 -69
  995. package/bundled-types/host-app/components/matrix/auth-form-field.gts +0 -43
@@ -0,0 +1,2820 @@
1
+ import { s as __toESM } from "./chunk-Rp0pCe6z.js";
2
+ import { r as initializeDeferredDecorator, t as decorateFieldV2 } from "./runtime--fcdnjmJ-BoCBNIsz.js";
3
+ import { $n as APP_BOXEL_TOOL_REQUESTS_KEY, Ar as testRealmURL, In as APP_BOXEL_CONTINUATION_OF_CONTENT_KEY, Po as isCardInstance, Pr as AI_BOT_EXECUTOR, Sc as Deferred, Vn as APP_BOXEL_MESSAGE_MSGTYPE, Yn as APP_BOXEL_RESPONSE_STREAM_EVENT_TYPE, Zn as APP_BOXEL_STOP_GENERATING_EVENT_TYPE, er as APP_BOXEL_TOOL_RESULT_EVENT_TYPE, nr as APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE, rr as APP_BOXEL_TOOL_RESULT_WITH_OUTPUT_MSGTYPE, tr as APP_BOXEL_TOOL_RESULT_REL_TYPE, zn as APP_BOXEL_HAS_CONTINUATION_CONTENT_KEY, zr as buildToolFunctionNameFromResolvedRef } from "./runtime-common-ClpqhbwG.js";
4
+ import { y as rri } from "./paths-BYHDgqsT.js";
5
+ import { J as skillCardRef } from "./constants-CqKWhRfY.js";
6
+ import { t as config } from "./environment-DIUJgBKt.js";
7
+ import { wt as setComponentTemplate } from "./cache-DtDz7X5V-Wn8jRDfL.js";
8
+ import { H as templateFactory } from "./index-DaCZcoCY-CgzbilMy.js";
9
+ import "./component-BJO47HTh.js";
10
+ import { t as Component } from "./dist-CkA1rgqO.js";
11
+ import "./template-factory-ds9s0u8l.js";
12
+ import { t as OperatorModeContainer } from "./container-Dj-5prh9.js";
13
+ import { t as STOPPED_TOOL_CALL_REASON } from "./stop-DKx-M3jV.js";
14
+ import { M as waitUntil, T as settled, a as find, d as click, o as waitFor, s as fillIn } from "./dist-BOAdzfkP.js";
15
+ import { t as require_qunit } from "./qunit-C-Foo4Nd.js";
16
+ import { D as realmConfigCardJSON, F as setupLocalIndexing, I as setupOnSave, L as setupRealmCacheTeardown, M as setupCardLogs, P as setupIntegrationTestRealm, Z as withCachedRealmSetup, g as delay, lt as setupRenderingTest, o as addSkillToAiAssistant, ot as setupOperatorModeStateCleanup, t as setupMockMatrix, wt as percySnapshot } from "./mock-matrix-DPQ0j2MD.js";
17
+ import { r as getService } from "./dist-CPfIHBla.js";
18
+ import { A as field, H as linksTo, U as linksToMany, a as CardDef, l as FieldDef, s as Component$1, w as contains } from "./card-api-Dzje0smT.js";
19
+ import { t as string_default } from "./string-BHZZwNlZ.js";
20
+ import { n as renderComponent } from "./render-component-B15Z0e2v.js";
21
+ //#region tests/integration/components/ai-assistant-panel/e75beeb704.css
22
+ var import_qunit = /* @__PURE__ */ __toESM(require_qunit());
23
+ //#endregion
24
+ //#region tests/integration/components/ai-assistant-panel/tools-test.gts
25
+ function registeredRealmPrefixes() {
26
+ let { virtualNetwork } = getService("network");
27
+ return Object.fromEntries(virtualNetwork.knownRealms().map((prefix) => [prefix, virtualNetwork.toURLHref(prefix)]));
28
+ }
29
+ (0, import_qunit.module)("Integration | ai-assistant-panel | tools", function(hooks) {
30
+ const realmName = "Operator Mode Workspace";
31
+ const readOnlyRealmName = "Read Only Workspace";
32
+ const readOnlyRealmURL = "http://test-realm/read-only/";
33
+ const searchCardsToolName = buildToolFunctionNameFromResolvedRef({
34
+ module: "@cardstack/boxel-host/commands/search-cards",
35
+ name: "SearchCardsByTypeAndTitleTool"
36
+ });
37
+ let loader;
38
+ let operatorModeStateService;
39
+ setupRenderingTest(hooks);
40
+ setupOperatorModeStateCleanup(hooks);
41
+ hooks.beforeEach(function() {
42
+ loader = getService("loader-service").loader;
43
+ });
44
+ setupLocalIndexing(hooks);
45
+ setupRealmCacheTeardown(hooks);
46
+ setupOnSave(hooks);
47
+ setupCardLogs(hooks, async () => await loader.import("@cardstack/base/card-api"));
48
+ let mockMatrixUtils = setupMockMatrix(hooks, {
49
+ loggedInAs: "@testuser:localhost",
50
+ activeRealms: [testRealmURL, readOnlyRealmURL],
51
+ realmPermissions: {
52
+ [testRealmURL]: ["read", "write"],
53
+ [readOnlyRealmURL]: ["read"]
54
+ },
55
+ autostart: true,
56
+ now: (() => {
57
+ let clock = new Date(2024, 8, 19).getTime();
58
+ return () => clock += 10;
59
+ })()
60
+ });
61
+ let { createAndJoinRoom, simulateRemoteMessage, simulateToDeviceEvent, getRoomEvents } = mockMatrixUtils;
62
+ let noop = () => {};
63
+ hooks.beforeEach(async function() {
64
+ operatorModeStateService = getService("operator-mode-state-service");
65
+ class Pet extends CardDef {
66
+ static displayName = "Pet";
67
+ static {
68
+ decorateFieldV2(this.prototype, "name", [field], function() {
69
+ return contains(string_default);
70
+ });
71
+ }
72
+ #name = (initializeDeferredDecorator(this, "name"), void 0);
73
+ static {
74
+ decorateFieldV2(this.prototype, "cardTitle", [field], function() {
75
+ return contains(string_default, { computeVia: function() {
76
+ return this.name;
77
+ } });
78
+ });
79
+ }
80
+ #cardTitle = (initializeDeferredDecorator(this, "cardTitle"), void 0);
81
+ static fitted = class Fitted extends Component$1 {
82
+ static {
83
+ setComponentTemplate(templateFactory({
84
+ "id": "IHMPzHnr",
85
+ "block": "[[[10,\"h3\"],[15,\"data-test-pet\",[30,1,[\"name\"]]],[12],[1,\"\\n \"],[8,[30,2,[\"name\"]],null,null,null],[1,\"\\n\"],[13]],[\"@model\",\"@fields\"],[]]",
86
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
87
+ "isStrictMode": true
88
+ }), this);
89
+ }
90
+ };
91
+ }
92
+ class Address extends FieldDef {
93
+ static displayName = "Address";
94
+ static {
95
+ decorateFieldV2(this.prototype, "city", [field], function() {
96
+ return contains(string_default);
97
+ });
98
+ }
99
+ #city = (initializeDeferredDecorator(this, "city"), void 0);
100
+ static {
101
+ decorateFieldV2(this.prototype, "country", [field], function() {
102
+ return contains(string_default);
103
+ });
104
+ }
105
+ #country = (initializeDeferredDecorator(this, "country"), void 0);
106
+ static embedded = class Embedded extends Component$1 {
107
+ static {
108
+ setComponentTemplate(templateFactory({
109
+ "id": "0uTOjQm9",
110
+ "block": "[[[10,0],[14,\"data-test-address\",\"\"],[12],[1,\"\\n \"],[10,\"h3\"],[15,\"data-test-city\",[30,1,[\"city\"]]],[12],[1,\"\\n \"],[8,[30,2,[\"city\"]],null,null,null],[1,\"\\n \"],[13],[1,\"\\n \"],[10,\"h3\"],[15,\"data-test-country\",[30,1,[\"country\"]]],[12],[1,\"\\n \"],[8,[30,2,[\"country\"]],null,null,null],[1,\"\\n \"],[13],[1,\"\\n\"],[13]],[\"@model\",\"@fields\"],[]]",
111
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
112
+ "isStrictMode": true
113
+ }), this);
114
+ }
115
+ };
116
+ }
117
+ class Person extends CardDef {
118
+ static displayName = "Person";
119
+ static {
120
+ decorateFieldV2(this.prototype, "firstName", [field], function() {
121
+ return contains(string_default);
122
+ });
123
+ }
124
+ #firstName = (initializeDeferredDecorator(this, "firstName"), void 0);
125
+ static {
126
+ decorateFieldV2(this.prototype, "pet", [field], function() {
127
+ return linksTo(Pet);
128
+ });
129
+ }
130
+ #pet = (initializeDeferredDecorator(this, "pet"), void 0);
131
+ static {
132
+ decorateFieldV2(this.prototype, "friends", [field], function() {
133
+ return linksToMany(Pet);
134
+ });
135
+ }
136
+ #friends = (initializeDeferredDecorator(this, "friends"), void 0);
137
+ static {
138
+ decorateFieldV2(this.prototype, "firstLetterOfTheName", [field], function() {
139
+ return contains(string_default, { computeVia: function() {
140
+ return this.firstName[0];
141
+ } });
142
+ });
143
+ }
144
+ #firstLetterOfTheName = (initializeDeferredDecorator(this, "firstLetterOfTheName"), void 0);
145
+ static {
146
+ decorateFieldV2(this.prototype, "cardTitle", [field], function() {
147
+ return contains(string_default, { computeVia: function() {
148
+ return this.firstName;
149
+ } });
150
+ });
151
+ }
152
+ #cardTitle = (initializeDeferredDecorator(this, "cardTitle"), void 0);
153
+ static {
154
+ decorateFieldV2(this.prototype, "address", [field], function() {
155
+ return contains(Address);
156
+ });
157
+ }
158
+ #address = (initializeDeferredDecorator(this, "address"), void 0);
159
+ static isolated = class Isolated extends Component$1 {
160
+ static {
161
+ setComponentTemplate(templateFactory({
162
+ "id": "86ylgsLt",
163
+ "block": "[[[10,\"h2\"],[15,\"data-test-person\",[30,1,[\"firstName\"]]],[14,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"],[12],[1,\"\\n \"],[8,[30,2,[\"firstName\"]],[[24,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"]],null,null],[1,\"\\n\"],[13],[1,\"\\n\"],[10,2],[15,\"data-test-first-letter-of-the-name\",[30,1,[\"firstLetterOfTheName\"]]],[14,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"],[12],[1,\"\\n \"],[8,[30,2,[\"firstLetterOfTheName\"]],[[24,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"]],null,null],[1,\"\\n\"],[13],[1,\"\\nPet:\\n\"],[10,0],[14,0,\"pet-container\"],[14,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"],[12],[1,\"\\n \"],[8,[30,2,[\"pet\"]],[[24,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"]],null,null],[1,\"\\n\"],[13],[1,\"\\nFriends:\\n\"],[8,[30,2,[\"friends\"]],[[24,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"]],null,null],[1,\"\\n\"],[10,0],[14,\"data-test-addresses\",\"\"],[14,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"],[12],[1,\"Address: \"],[8,[30,2,[\"address\"]],[[24,\"data-scopedcss-a14586af1f-8d94048c9a\",\"\"]],null,null],[13],[1,\"\\n\"]],[\"@model\",\"@fields\"],[]]",
164
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
165
+ "isStrictMode": true
166
+ }), this);
167
+ }
168
+ };
169
+ }
170
+ let petMango = new Pet({ name: "Mango" });
171
+ let petJackie = new Pet({ name: "Jackie" });
172
+ await withCachedRealmSetup(async () => {
173
+ await setupIntegrationTestRealm({
174
+ mockMatrixUtils,
175
+ contents: {
176
+ "address.gts": { Address },
177
+ "hello.txt": "Hello, world!",
178
+ "person.gts": { Person },
179
+ "pet.gts": { Pet },
180
+ "Pet/mango.json": petMango,
181
+ "Pet/jackie.json": petJackie,
182
+ "Person/fadhlan.json": new Person({
183
+ firstName: "Fadhlan",
184
+ address: new Address({
185
+ city: "Bandung",
186
+ country: "Indonesia"
187
+ }),
188
+ pet: petMango
189
+ }),
190
+ "Person/burcu.json": new Person({
191
+ firstName: "Burcu",
192
+ friends: [petJackie, petMango]
193
+ }),
194
+ "Person/mickey.json": new Person({ firstName: "Mickey" }),
195
+ "Person/justin.json": new Person({ firstName: "Justin" }),
196
+ "Person/ian.json": new Person({ firstName: "Ian" }),
197
+ "Person/matic.json": new Person({ firstName: "Matic" }),
198
+ "Person/buck.json": new Person({ firstName: "Buck" }),
199
+ "Person/hassan.json": new Person({ firstName: "Hassan" }),
200
+ "Skill/boxel-environment.json": { data: {
201
+ attributes: {
202
+ title: "Boxel Environment",
203
+ description: "Test environment skill",
204
+ instructions: "Test skill card for environment commands",
205
+ commands: [
206
+ {
207
+ codeRef: {
208
+ name: "SearchCardsByTypeAndTitleTool",
209
+ module: "@cardstack/boxel-host/commands/search-cards"
210
+ },
211
+ requiresApproval: false
212
+ },
213
+ {
214
+ codeRef: {
215
+ name: "SearchCardsByQueryTool",
216
+ module: "@cardstack/boxel-host/commands/search-cards"
217
+ },
218
+ requiresApproval: false
219
+ },
220
+ {
221
+ codeRef: {
222
+ name: "default",
223
+ module: "@cardstack/boxel-host/commands/read-file-for-ai-assistant"
224
+ },
225
+ requiresApproval: false
226
+ },
227
+ {
228
+ codeRef: {
229
+ name: "default",
230
+ module: "@cardstack/boxel-host/commands/read-card-for-ai-assistant"
231
+ },
232
+ requiresApproval: false
233
+ }
234
+ ]
235
+ },
236
+ meta: { adoptsFrom: skillCardRef }
237
+ } },
238
+ "realm.json": realmConfigCardJSON({ name: realmName })
239
+ }
240
+ });
241
+ await setupIntegrationTestRealm({
242
+ mockMatrixUtils,
243
+ realmURL: readOnlyRealmURL,
244
+ contents: {
245
+ "pet.gts": `
246
+ import { contains, field, CardDef } from "@cardstack/base/card-api";
247
+ import StringField from "@cardstack/base/string";
248
+ export class Pet extends CardDef {
249
+ static displayName = 'Pet';
250
+ @field name = contains(StringField);
251
+ }
252
+ `,
253
+ "person.gts": `
254
+ import { contains, field, linksTo, CardDef } from "@cardstack/base/card-api";
255
+ import StringField from "@cardstack/base/string";
256
+ import { Pet } from "./pet";
257
+ export class Person extends CardDef {
258
+ static displayName = 'Person';
259
+ @field firstName = contains(StringField);
260
+ @field pet = linksTo(Pet);
261
+ }
262
+ `,
263
+ "Person/ian.json": { data: {
264
+ type: "card",
265
+ attributes: { firstName: "Ian" },
266
+ relationships: { pet: { data: {
267
+ type: "card",
268
+ id: `${readOnlyRealmURL}Pet/rose`
269
+ } } },
270
+ meta: { adoptsFrom: {
271
+ module: "./person",
272
+ name: "Person"
273
+ } }
274
+ } },
275
+ "Pet/rose.json": { data: {
276
+ type: "card",
277
+ attributes: { name: "Rose" },
278
+ meta: { adoptsFrom: {
279
+ module: "./pet",
280
+ name: "Pet"
281
+ } }
282
+ } },
283
+ "realm.json": realmConfigCardJSON({ name: readOnlyRealmName })
284
+ }
285
+ });
286
+ });
287
+ });
288
+ function setCardInOperatorModeState(cardURL, format = "isolated") {
289
+ operatorModeStateService.restore({ stacks: cardURL ? [[{
290
+ id: cardURL,
291
+ format
292
+ }]] : [[]] });
293
+ }
294
+ async function openAiAssistant() {
295
+ await waitFor("[data-test-open-ai-assistant]");
296
+ await click("[data-test-open-ai-assistant]");
297
+ await waitFor("[data-test-room-settled]");
298
+ let roomId = document.querySelector("[data-test-room]")?.getAttribute("data-test-room");
299
+ if (!roomId) throw new Error("Expected a room ID");
300
+ return roomId;
301
+ }
302
+ async function renderAiAssistantPanel(id) {
303
+ setCardInOperatorModeState(id);
304
+ await renderComponent(class TestDriver extends Component {
305
+ static {
306
+ setComponentTemplate(templateFactory({
307
+ "id": "hk0qKyFP",
308
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
309
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
310
+ "scope": () => [OperatorModeContainer, noop],
311
+ "isStrictMode": true
312
+ }), this);
313
+ }
314
+ });
315
+ return await openAiAssistant();
316
+ }
317
+ const TOOL_RESULT_TIMEOUT_MS = 1e4;
318
+ async function waitForToolResult() {
319
+ let startedAt = performance.now();
320
+ try {
321
+ await waitFor("[data-test-tool-result-header]", { timeout: TOOL_RESULT_TIMEOUT_MS });
322
+ } catch (e) {
323
+ let applyButtons = [...document.querySelectorAll("[data-test-tool-call-apply]")].map((el) => el.getAttribute("data-test-tool-call-apply"));
324
+ console.error(`[tool-result-wait] no result header after ${Math.round(performance.now() - startedAt)}ms; messages=${document.querySelectorAll("[data-test-message-idx]").length}; applyStates=${JSON.stringify(applyButtons)} (a tool that reached "applied" points at the result card load; see any [tool-result-card] lines)`);
325
+ throw e;
326
+ }
327
+ console.log(`[tool-result-wait] result header after ${Math.round(performance.now() - startedAt)}ms`);
328
+ }
329
+ (0, import_qunit.test)("it allows chat commands to change cards in the stack", async function(assert) {
330
+ assert.expect(4);
331
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Person/fadhlan`);
332
+ await waitFor("[data-test-person]");
333
+ assert.dom("[data-test-boxel-card-header-title]").hasText("Person - Fadhlan");
334
+ assert.dom("[data-test-person]").hasText("Fadhlan");
335
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
336
+ body: "i am the body",
337
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
338
+ format: "org.matrix.custom.html",
339
+ isStreamingFinished: true,
340
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
341
+ id: "change-cards-in-stack",
342
+ name: "patchCardInstance",
343
+ arguments: JSON.stringify({ attributes: {
344
+ cardId: `${testRealmURL}Person/fadhlan`,
345
+ patch: { attributes: { firstName: "Dave" } }
346
+ } })
347
+ }],
348
+ "m.relates_to": {
349
+ rel_type: "m.replace",
350
+ event_id: "patch1"
351
+ }
352
+ });
353
+ await waitFor("[data-test-tool-call-apply]");
354
+ this.onSave((_, json) => {
355
+ if (typeof json === "string") throw new Error("expected JSON save data");
356
+ assert.strictEqual(json.data.attributes?.firstName, "Dave");
357
+ });
358
+ await click("[data-test-tool-call-apply]");
359
+ await waitFor("[data-test-tool-call-card-idle]");
360
+ assert.dom("[data-test-person]").hasText("Dave");
361
+ });
362
+ (0, import_qunit.test)("when a command is being prepared, apply button is shown in preparing state", async function(assert) {
363
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
364
+ await renderComponent(class TestDriver extends Component {
365
+ static {
366
+ setComponentTemplate(templateFactory({
367
+ "id": "hk0qKyFP",
368
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
369
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
370
+ "scope": () => [OperatorModeContainer, noop],
371
+ "isStrictMode": true
372
+ }), this);
373
+ }
374
+ });
375
+ await waitFor("[data-test-person=\"Fadhlan\"]");
376
+ let roomId = createAndJoinRoom({
377
+ sender: "@testuser:localhost",
378
+ name: "test room 1"
379
+ });
380
+ let initialEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
381
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
382
+ body: "Changing",
383
+ format: "org.matrix.custom.html",
384
+ isStreamingFinished: false
385
+ });
386
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
387
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
388
+ body: "Changing first name to Evie",
389
+ format: "org.matrix.custom.html",
390
+ isStreamingFinished: false,
391
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
392
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
393
+ name: "patchCardInstance"
394
+ }],
395
+ "m.relates_to": {
396
+ rel_type: "m.replace",
397
+ event_id: initialEventId
398
+ }
399
+ });
400
+ await settled();
401
+ await click("[data-test-open-ai-assistant]");
402
+ await waitFor("[data-test-room-name=\"test room 1\"]");
403
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
404
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
405
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists();
406
+ });
407
+ (0, import_qunit.test)("it does not display the streaming indicator when ai bot sends a command", async function(assert) {
408
+ simulateRemoteMessage(await renderAiAssistantPanel(), "@aibot:localhost", {
409
+ body: "i am the body",
410
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
411
+ format: "org.matrix.custom.html",
412
+ isStreamingFinished: true,
413
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
414
+ id: "fb8fef81-2142-4861-a902-d5614b0aea52",
415
+ name: "patchCardInstance",
416
+ arguments: JSON.stringify({ attributes: {
417
+ cardId: `${testRealmURL}Person/fadhlan`,
418
+ patch: { attributes: { firstName: "Dave" } }
419
+ } })
420
+ }]
421
+ });
422
+ await waitFor("[data-test-message-idx=\"0\"]");
423
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-ai-avatar]").doesNotHaveClass("ai-avatar-animated", "ai bot patch message does not have a spinner");
424
+ });
425
+ (0, import_qunit.test)("when command is done streaming, apply button is shown in ready state", async function(assert) {
426
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
427
+ await renderComponent(class TestDriver extends Component {
428
+ static {
429
+ setComponentTemplate(templateFactory({
430
+ "id": "hk0qKyFP",
431
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
432
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
433
+ "scope": () => [OperatorModeContainer, noop],
434
+ "isStrictMode": true
435
+ }), this);
436
+ }
437
+ });
438
+ await waitFor("[data-test-person=\"Fadhlan\"]");
439
+ let roomId = createAndJoinRoom({
440
+ sender: "@testuser:localhost",
441
+ name: "test room 1"
442
+ });
443
+ let initialEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
444
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
445
+ body: "Changing",
446
+ format: "org.matrix.custom.html",
447
+ isStreamingFinished: false
448
+ });
449
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
450
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
451
+ body: "Changing first names",
452
+ format: "org.matrix.custom.html",
453
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
454
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
455
+ name: "patchCardInstance"
456
+ }],
457
+ isStreamingFinished: false,
458
+ "m.relates_to": {
459
+ rel_type: "m.replace",
460
+ event_id: initialEventId
461
+ }
462
+ });
463
+ await settled();
464
+ await click("[data-test-open-ai-assistant]");
465
+ await waitFor("[data-test-room-name=\"test room 1\"]");
466
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
467
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
468
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists({ count: 1 });
469
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
470
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
471
+ body: "Changing first names",
472
+ format: "org.matrix.custom.html",
473
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
474
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
475
+ name: "patchCardInstance",
476
+ arguments: JSON.stringify({ attributes: {
477
+ cardId: `${testRealmURL}Person/fadhlan`,
478
+ patch: { attributes: { firstName: "Evie" } }
479
+ } })
480
+ }, {
481
+ id: "f2da5504-b92f-480a-986a-56ec606d240e",
482
+ name: "patchCardInstance",
483
+ arguments: JSON.stringify({ attributes: {
484
+ cardId: `${testRealmURL}Person/hassan`,
485
+ patch: { attributes: { firstName: "Ivana" } }
486
+ } })
487
+ }],
488
+ isStreamingFinished: false,
489
+ "m.relates_to": {
490
+ rel_type: "m.replace",
491
+ event_id: initialEventId
492
+ }
493
+ });
494
+ await settled();
495
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
496
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
497
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists({ count: 2 });
498
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
499
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
500
+ body: "Changing first names",
501
+ format: "org.matrix.custom.html",
502
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
503
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
504
+ name: "patchCardInstance",
505
+ arguments: JSON.stringify({ attributes: {
506
+ cardId: `${testRealmURL}Person/fadhlan`,
507
+ patch: { attributes: { firstName: "Evie" } }
508
+ } })
509
+ }, {
510
+ id: "f2da5504-b92f-480a-986a-56ec606d240e",
511
+ name: "patchCardInstance",
512
+ arguments: JSON.stringify({ attributes: {
513
+ cardId: `${testRealmURL}Person/hassan`,
514
+ patch: { attributes: { firstName: "Ivana" } }
515
+ } })
516
+ }],
517
+ isStreamingFinished: true,
518
+ "m.relates_to": {
519
+ rel_type: "m.replace",
520
+ event_id: initialEventId
521
+ }
522
+ });
523
+ await settled();
524
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
525
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
526
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists({ count: 0 });
527
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"ready\"]").exists({ count: 2 });
528
+ });
529
+ (0, import_qunit.test)("after command is executed, a command result event will be dispatched", async function(assert) {
530
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
531
+ await renderComponent(class TestDriver extends Component {
532
+ static {
533
+ setComponentTemplate(templateFactory({
534
+ "id": "hk0qKyFP",
535
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
536
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
537
+ "scope": () => [OperatorModeContainer, noop],
538
+ "isStrictMode": true
539
+ }), this);
540
+ }
541
+ });
542
+ await waitFor("[data-test-person=\"Fadhlan\"]");
543
+ let roomId = createAndJoinRoom({
544
+ sender: "@testuser:localhost",
545
+ name: "test room 1"
546
+ });
547
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
548
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
549
+ body: "Changing first name to Evie",
550
+ format: "org.matrix.custom.html",
551
+ isStreamingFinished: true,
552
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
553
+ id: "result-event-dispatch",
554
+ name: "patchCardInstance",
555
+ arguments: JSON.stringify({ attributes: {
556
+ cardId: `${testRealmURL}Person/fadhlan`,
557
+ patch: { attributes: { firstName: "Evie" } }
558
+ } })
559
+ }]
560
+ });
561
+ let commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation" && event.content["m.relates_to"]?.key === "applied");
562
+ assert.strictEqual(commandResultEvents.length, 0, "command result event is not dispatched");
563
+ await settled();
564
+ await click("[data-test-open-ai-assistant]");
565
+ await waitFor("[data-test-room-name=\"test room 1\"]");
566
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
567
+ await click("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
568
+ await waitFor("[data-test-tool-call-card-idle]");
569
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists();
570
+ commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation" && event.content["m.relates_to"]?.key === "applied");
571
+ assert.strictEqual(commandResultEvents.length, 1, "command result event is dispatched");
572
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).context, {
573
+ agentId: getService("matrix-service").agentId,
574
+ submode: "interact",
575
+ debug: false,
576
+ openCardIds: ["http://test-realm/test/Person/fadhlan"],
577
+ realmPrefixes: registeredRealmPrefixes(),
578
+ realmUrl: "http://test-realm/test/",
579
+ realmPermissions: {
580
+ canRead: true,
581
+ canWrite: true
582
+ }
583
+ }, "command result event contains the context");
584
+ });
585
+ (0, import_qunit.test)("after search command is executed, a command result event is dispatched", async function(assert) {
586
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
587
+ await renderComponent(class TestDriver extends Component {
588
+ static {
589
+ setComponentTemplate(templateFactory({
590
+ "id": "hk0qKyFP",
591
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
592
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
593
+ "scope": () => [OperatorModeContainer, noop],
594
+ "isStrictMode": true
595
+ }), this);
596
+ }
597
+ });
598
+ await waitFor("[data-test-person=\"Fadhlan\"]");
599
+ let roomId = createAndJoinRoom({
600
+ sender: "@testuser:localhost",
601
+ name: "test room 1"
602
+ });
603
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
604
+ body: "Changing first name to Evie",
605
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
606
+ format: "org.matrix.custom.html",
607
+ isStreamingFinished: true,
608
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
609
+ id: "search-result-dispatch",
610
+ name: "patchCardInstance",
611
+ arguments: JSON.stringify({ attributes: {
612
+ cardId: `${testRealmURL}Person/fadhlan`,
613
+ patch: { attributes: { firstName: "Evie" } }
614
+ } })
615
+ }]
616
+ });
617
+ let commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === APP_BOXEL_TOOL_RESULT_EVENT_TYPE);
618
+ assert.strictEqual(commandResultEvents.length, 0, "command result event is not dispatched");
619
+ await settled();
620
+ await click("[data-test-open-ai-assistant]");
621
+ await waitFor("[data-test-room-name=\"test room 1\"]");
622
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
623
+ await click("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
624
+ await waitFor("[data-test-tool-call-card-idle]");
625
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists();
626
+ commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === APP_BOXEL_TOOL_RESULT_EVENT_TYPE);
627
+ assert.strictEqual(commandResultEvents.length, 1, "command result event is dispatched");
628
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).context, {
629
+ agentId: getService("matrix-service").agentId,
630
+ submode: "interact",
631
+ debug: false,
632
+ openCardIds: ["http://test-realm/test/Person/fadhlan"],
633
+ realmPrefixes: registeredRealmPrefixes(),
634
+ realmUrl: "http://test-realm/test/",
635
+ realmPermissions: {
636
+ canRead: true,
637
+ canWrite: true
638
+ }
639
+ }, "command result event contains the context");
640
+ });
641
+ (0, import_qunit.test)("it can search for card instances that is of the same card type as the card shared", async function(assert) {
642
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Pet/mango.json`);
643
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
644
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
645
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
646
+ body: "Search for the following card",
647
+ format: "org.matrix.custom.html",
648
+ isStreamingFinished: true,
649
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
650
+ id: "search1",
651
+ name: searchCardsToolName,
652
+ arguments: JSON.stringify({
653
+ description: "Searching for card",
654
+ attributes: { type: {
655
+ module: `${testRealmURL}pet`,
656
+ name: "Pet"
657
+ } }
658
+ })
659
+ }],
660
+ data: { context: { agentId: getService("matrix-service").agentId } }
661
+ });
662
+ await waitForToolResult();
663
+ assert.dom("[data-test-ai-message-content]").containsText("Search for the following card");
664
+ assert.dom("[data-test-ai-message-content] [data-test-view-code-button]").exists({ count: 1 });
665
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-boxel-card-header-title]").containsText("Search Results");
666
+ assert.dom(".result-list li").exists({ count: 2 });
667
+ assert.dom(".result-list li:nth-child(1)").containsText("Jackie");
668
+ assert.dom(".result-list li:nth-child(2)").containsText("Mango");
669
+ assert.dom("[data-test-toggle-show-button]").doesNotExist();
670
+ });
671
+ (0, import_qunit.test)("it can search for card instances based upon title of card", async function(assert) {
672
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Pet/mango.json`);
673
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
674
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
675
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
676
+ body: "Search for the following card",
677
+ format: "org.matrix.custom.html",
678
+ isStreamingFinished: true,
679
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
680
+ id: "search1",
681
+ name: searchCardsToolName,
682
+ arguments: JSON.stringify({
683
+ description: "Searching for card",
684
+ attributes: { cardTitle: "Mango" }
685
+ })
686
+ }],
687
+ data: { context: { agentId: getService("matrix-service").agentId } }
688
+ });
689
+ await waitForToolResult();
690
+ assert.dom("[data-test-ai-message-content]").containsText("Search for the following card");
691
+ assert.dom("[data-test-ai-message-content] [data-test-view-code-button]").exists({ count: 1 });
692
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-boxel-card-header-title]").containsText("Search Results");
693
+ assert.dom(".result-list li:nth-child(1)").containsText("Mango");
694
+ assert.dom("[data-test-toggle-show-button]").doesNotExist();
695
+ });
696
+ (0, import_qunit.test)("toggle more search results", async function(assert) {
697
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Person/fadhlan.json`);
698
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
699
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
700
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
701
+ body: "Search for the following card",
702
+ format: "org.matrix.custom.html",
703
+ isStreamingFinished: true,
704
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
705
+ id: "721c8c78-d8c1-4cc1-a7e9-51d2d3143e4d",
706
+ name: searchCardsToolName,
707
+ arguments: JSON.stringify({
708
+ description: "Searching for card",
709
+ attributes: { type: {
710
+ module: `${testRealmURL}person`,
711
+ name: "Person"
712
+ } }
713
+ })
714
+ }],
715
+ data: { context: { agentId: getService("matrix-service").agentId } }
716
+ });
717
+ await waitForToolResult();
718
+ let header = find("[data-test-tool-result-container] [data-test-tool-result-header]");
719
+ let resultCard = find("[data-test-tool-result-container] [data-test-boxel-tool-call-result]");
720
+ let headerStyle = window.getComputedStyle(header);
721
+ let cardStyle = window.getComputedStyle(resultCard);
722
+ assert.strictEqual(cardStyle.backgroundColor, headerStyle.backgroundColor, "result body container shares the header background (no dark seam)");
723
+ assert.strictEqual(cardStyle.color, headerStyle.color, "result body inherits the dark foreground, so embedded content stays readable");
724
+ assert.notStrictEqual(cardStyle.color, cardStyle.backgroundColor, "result body text contrasts with its background");
725
+ assert.dom(".result-list li:nth-child(6)").doesNotExist();
726
+ assert.dom("[data-test-toggle-show-button]").containsText("Show 3 more results");
727
+ await click("[data-test-toggle-show-button]");
728
+ await waitFor(".result-list li", { count: 8 });
729
+ assert.dom("[data-test-toggle-show-button]").containsText("See Less");
730
+ assert.dom(".result-list li:nth-child(1)").containsText("Buck");
731
+ assert.dom(".result-list li:nth-child(2)").containsText("Burcu");
732
+ assert.dom(".result-list li:nth-child(3)").containsText("Fadhlan");
733
+ assert.dom(".result-list li:nth-child(4)").containsText("Hassan");
734
+ assert.dom(".result-list li:nth-child(5)").containsText("Ian");
735
+ assert.dom(".result-list li:nth-child(6)").containsText("Justin");
736
+ assert.dom(".result-list li:nth-child(7)").containsText("Matic");
737
+ assert.dom(".result-list li:nth-child(8)").containsText("Mickey");
738
+ await click("[data-test-toggle-show-button]");
739
+ assert.dom(".result-list li:nth-child(1)").containsText("Buck");
740
+ assert.dom(".result-list li:nth-child(2)").containsText("Burcu");
741
+ assert.dom(".result-list li:nth-child(3)").containsText("Fadhlan");
742
+ assert.dom(".result-list li:nth-child(4)").containsText("Hassan");
743
+ assert.dom(".result-list li:nth-child(5)").containsText("Ian");
744
+ assert.dom(".result-list li:nth-child(6)").doesNotExist();
745
+ });
746
+ (0, import_qunit.test)("it can copy search results card to workspace", async function(assert) {
747
+ const id = `${testRealmURL}Person/fadhlan`;
748
+ const roomId = await renderAiAssistantPanel(`${id}.json`);
749
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
750
+ const toolArgs = {
751
+ description: "Search for Person cards",
752
+ attributes: { type: {
753
+ module: `${testRealmURL}person`,
754
+ name: "Person"
755
+ } }
756
+ };
757
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
758
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
759
+ body: "Search for the following card",
760
+ format: "org.matrix.custom.html",
761
+ isStreamingFinished: true,
762
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
763
+ id: "fd4515fb-ed4d-4005-9782-4e844d7d4d9c",
764
+ name: searchCardsToolName,
765
+ arguments: JSON.stringify(toolArgs)
766
+ }],
767
+ data: { context: { agentId: getService("matrix-service").agentId } }
768
+ });
769
+ await waitForToolResult();
770
+ assert.dom(`[data-test-stack-card="${id}"]`).exists();
771
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-boxel-card-header-title]").containsText("Search Results");
772
+ let resultListItem = "[data-test-result-list] > li";
773
+ assert.dom(`${resultListItem}:nth-child(1)`).containsText("Buck");
774
+ assert.dom(`${resultListItem}:nth-child(5)`).containsText("Ian");
775
+ const rightStackItem = "[data-test-operator-mode-stack=\"1\"] [data-test-stack-card-index=\"0\"]";
776
+ assert.dom(rightStackItem).doesNotExist();
777
+ await click("[data-test-tool-result-container] [data-test-more-options-button]");
778
+ await click("[data-test-boxel-menu-item-text=\"Copy to Workspace\"]");
779
+ assert.dom(`${rightStackItem} [data-test-boxel-card-header-title]`).hasText("Search Results - Search Results");
780
+ const savedCard = `[data-test-card="${document.querySelector(rightStackItem)?.getAttribute("data-stack-card")}"] [data-test-tool-result-isolated]`;
781
+ assert.dom(`${savedCard} header`).hasText("Search Results 8 Results");
782
+ assert.dom(`${savedCard} [data-test-boxel-field]`).exists({ count: 2 });
783
+ assert.dom(`${savedCard} [data-test-boxel-field]:nth-child(1)`).hasText(`Description Query: { "type": { "module": "http://test-realm/test/person", "name": "Person" } }`);
784
+ resultListItem = `${savedCard} ${resultListItem}`;
785
+ assert.dom(resultListItem).exists({ count: 8 });
786
+ assert.dom(`${resultListItem}:nth-child(1)`).containsText("Buck");
787
+ assert.dom(`${resultListItem}:nth-child(6)`).containsText("Justin");
788
+ assert.dom(`${resultListItem}:nth-child(8)`).containsText("Mickey");
789
+ });
790
+ (0, import_qunit.test)("copy to workspace menu item is shown for writable realm", async function(assert) {
791
+ const roomId = await renderAiAssistantPanel(`${`${testRealmURL}Person/fadhlan`}.json`);
792
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
793
+ const toolArgs = {
794
+ description: "Search for Person cards",
795
+ attributes: { type: {
796
+ module: `${testRealmURL}person`,
797
+ name: "Person"
798
+ } }
799
+ };
800
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
801
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
802
+ body: "Search for the following card",
803
+ format: "org.matrix.custom.html",
804
+ isStreamingFinished: true,
805
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
806
+ id: "9a5b7422-87de-4a93-9f07-9b7c40b75b1e",
807
+ name: searchCardsToolName,
808
+ arguments: JSON.stringify(toolArgs)
809
+ }],
810
+ data: { context: { agentId: getService("matrix-service").agentId } }
811
+ });
812
+ await waitForToolResult();
813
+ await click("[data-test-tool-result-container] [data-test-more-options-button]");
814
+ assert.dom("[data-test-boxel-menu-item-text=\"Copy to Workspace\"]").exists();
815
+ });
816
+ (0, import_qunit.test)("copy to workspace menu item is hidden for read-only realm", async function(assert) {
817
+ const roomId = await renderAiAssistantPanel(`${`${readOnlyRealmURL}Person/ian`}.json`);
818
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
819
+ const toolArgs = {
820
+ description: "Search for Person cards",
821
+ attributes: { type: {
822
+ module: `${testRealmURL}person`,
823
+ name: "Person"
824
+ } }
825
+ };
826
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
827
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
828
+ body: "Search for the following card",
829
+ format: "org.matrix.custom.html",
830
+ isStreamingFinished: true,
831
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
832
+ id: "6c6e2d73-8e09-4b44-a0d9-688f36b73be8",
833
+ name: searchCardsToolName,
834
+ arguments: JSON.stringify(toolArgs)
835
+ }],
836
+ data: { context: { agentId: getService("matrix-service").agentId } }
837
+ });
838
+ await waitForToolResult();
839
+ assert.dom("[data-test-tool-result-container] [data-test-more-options-button]").doesNotExist();
840
+ assert.dom("[data-test-boxel-menu-item-text=\"Copy to Workspace\"]").doesNotExist();
841
+ });
842
+ (0, import_qunit.test)("it can copy search results card to workspace (no cards in stack)", async function(assert) {
843
+ const id = `${testRealmURL}Person/fadhlan`;
844
+ const roomId = await renderAiAssistantPanel(`${id}.json`);
845
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
846
+ const toolArgs = {
847
+ description: "Search for Person cards",
848
+ attributes: { type: {
849
+ module: `${testRealmURL}person`,
850
+ name: "Person"
851
+ } }
852
+ };
853
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
854
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
855
+ body: "Search for the following card",
856
+ format: "org.matrix.custom.html",
857
+ isStreamingFinished: true,
858
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
859
+ id: "ffd1a3d0-0bd4-491a-a907-b96ec9d8902c",
860
+ name: searchCardsToolName,
861
+ arguments: JSON.stringify(toolArgs)
862
+ }],
863
+ data: { context: { agentId: getService("matrix-service").agentId } }
864
+ });
865
+ await waitForToolResult();
866
+ assert.dom(`[data-test-stack-card="${id}"]`).exists();
867
+ await click("[data-test-close-button]");
868
+ assert.dom(`[data-test-stack-card="${id}"]`).doesNotExist();
869
+ assert.dom(`[data-test-stack-card="${testRealmURL}index"]`).exists();
870
+ await click("[data-test-close-button]");
871
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-boxel-card-header-title]").containsText("Search Results");
872
+ assert.dom("[data-test-tool-result-container] [data-test-toggle-show-button]").containsText("Show 3 more results");
873
+ let resultListItem = "[data-test-result-list] > li";
874
+ assert.dom(`${resultListItem}:nth-child(1)`).containsText("Buck");
875
+ assert.dom(`${resultListItem}:nth-child(5)`).containsText("Ian");
876
+ const stackItem = "[data-test-operator-mode-stack=\"0\"] [data-test-stack-card-index=\"0\"]";
877
+ assert.dom(stackItem).doesNotExist();
878
+ await click("[data-test-tool-result-container] [data-test-more-options-button]");
879
+ await click("[data-test-boxel-menu-item-text=\"Copy to Workspace\"]");
880
+ assert.dom(`${stackItem} [data-test-boxel-card-header-title]`).hasText("Search Results - Search Results");
881
+ const savedCard = `[data-test-card="${document.querySelector(stackItem)?.getAttribute("data-stack-card")}"] [data-test-tool-result-isolated]`;
882
+ assert.dom(`${savedCard} header`).hasText("Search Results 8 Results");
883
+ assert.dom(`${savedCard} [data-test-boxel-field]`).exists({ count: 2 });
884
+ assert.dom(`${savedCard} [data-test-boxel-field]:nth-child(1)`).hasText(`Description Query: { "type": { "module": "http://test-realm/test/person", "name": "Person" } }`);
885
+ resultListItem = `${savedCard} ${resultListItem}`;
886
+ assert.dom(resultListItem).exists({ count: 8 });
887
+ assert.dom(`${resultListItem}:nth-child(1)`).containsText("Buck");
888
+ assert.dom(`${resultListItem}:nth-child(6)`).containsText("Justin");
889
+ assert.dom(`${resultListItem}:nth-child(8)`).containsText("Mickey");
890
+ });
891
+ (0, import_qunit.test)("it maintains status of View Code panel as additional events stream in", async function(assert) {
892
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
893
+ await renderComponent(class TestDriver extends Component {
894
+ static {
895
+ setComponentTemplate(templateFactory({
896
+ "id": "hk0qKyFP",
897
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
898
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
899
+ "scope": () => [OperatorModeContainer, noop],
900
+ "isStrictMode": true
901
+ }), this);
902
+ }
903
+ });
904
+ await waitFor("[data-test-person=\"Fadhlan\"]");
905
+ simulateRemoteMessage(createAndJoinRoom({
906
+ sender: "@testuser:localhost",
907
+ name: "test room 1"
908
+ }), "@aibot:localhost", {
909
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
910
+ body: "Changing first name to Evie",
911
+ format: "org.matrix.custom.html",
912
+ isStreamingFinished: true,
913
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
914
+ id: "view-code-panel-status",
915
+ name: "patchCardInstance",
916
+ arguments: JSON.stringify({ attributes: {
917
+ cardId: `${testRealmURL}Person/fadhlan`,
918
+ patch: { attributes: { firstName: "Evie" } }
919
+ } })
920
+ }]
921
+ });
922
+ await settled();
923
+ await click("[data-test-open-ai-assistant]");
924
+ await waitFor("[data-test-room-name=\"test room 1\"]");
925
+ assert.dom("[data-test-ai-message-content] [data-test-editor]").doesNotExist("View Code panel should not yet be open");
926
+ await click("[data-test-view-code-button]");
927
+ assert.dom("[data-test-ai-message-content] [data-test-editor]").exists("View Code panel should be open");
928
+ await fillIn("[data-test-message-field]", "Asking a question about what I saw in the proposed code...");
929
+ await click("[data-test-send-message-btn]");
930
+ assert.dom("[data-test-ai-message-content] [data-test-editor]").exists("View Code panel should remain open");
931
+ await percySnapshot(assert);
932
+ });
933
+ (0, import_qunit.test)("\"Hide Info\" collapses the code area even after the message re-mounts while expanded", async function(assert) {
934
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
935
+ await renderComponent(class TestDriver extends Component {
936
+ static {
937
+ setComponentTemplate(templateFactory({
938
+ "id": "hk0qKyFP",
939
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
940
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
941
+ "scope": () => [OperatorModeContainer, noop],
942
+ "isStrictMode": true
943
+ }), this);
944
+ }
945
+ });
946
+ await waitFor("[data-test-person=\"Fadhlan\"]");
947
+ simulateRemoteMessage(createAndJoinRoom({
948
+ sender: "@testuser:localhost",
949
+ name: "test room 1"
950
+ }), "@aibot:localhost", {
951
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
952
+ body: "Changing first name to Evie",
953
+ format: "org.matrix.custom.html",
954
+ isStreamingFinished: true,
955
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
956
+ id: "hide-info-height",
957
+ name: "patchCardInstance",
958
+ arguments: JSON.stringify({ attributes: {
959
+ cardId: `${testRealmURL}Person/fadhlan`,
960
+ patch: { attributes: { firstName: "Evie" } }
961
+ } })
962
+ }]
963
+ });
964
+ await settled();
965
+ await click("[data-test-open-ai-assistant]");
966
+ await waitFor("[data-test-room-name=\"test room 1\"]");
967
+ await click("[data-test-view-code-button]");
968
+ await waitFor("[data-test-editor]");
969
+ await click("[data-test-close-ai-assistant]");
970
+ await click("[data-test-open-ai-assistant]");
971
+ await waitFor("[data-test-editor]");
972
+ await settled();
973
+ await click("[data-test-view-code-button]");
974
+ assert.dom("[data-test-editor]").doesNotExist("code editor is removed after Hide Info");
975
+ let codeBlockSelector = "[data-test-tool-call-id=\"hide-info-height\"] [data-test-tool-code-block]";
976
+ assert.dom(codeBlockSelector).exists("tool code block element exists");
977
+ let codeBlock = find(codeBlockSelector);
978
+ assert.strictEqual(codeBlock.style.height, "", "no inline height is left behind so the block collapses to its header-only height");
979
+ });
980
+ (0, import_qunit.test)("expanding a tall tool call does not leave an empty gap below the code", async function(assert) {
981
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
982
+ await renderComponent(class TestDriver extends Component {
983
+ static {
984
+ setComponentTemplate(templateFactory({
985
+ "id": "hk0qKyFP",
986
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
987
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
988
+ "scope": () => [OperatorModeContainer, noop],
989
+ "isStrictMode": true
990
+ }), this);
991
+ }
992
+ });
993
+ await waitFor("[data-test-person=\"Fadhlan\"]");
994
+ let roomId = createAndJoinRoom({
995
+ sender: "@testuser:localhost",
996
+ name: "test room 1"
997
+ });
998
+ let attributes = Object.fromEntries(Array.from({ length: 30 }, (_, i) => [`field${i}`, `value ${i}`]));
999
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1000
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1001
+ body: "Applying a large patch",
1002
+ format: "org.matrix.custom.html",
1003
+ isStreamingFinished: true,
1004
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1005
+ id: "tall-tool-call",
1006
+ name: "patchCardInstance",
1007
+ arguments: JSON.stringify({ attributes: {
1008
+ cardId: `${testRealmURL}Person/fadhlan`,
1009
+ patch: { attributes }
1010
+ } })
1011
+ }]
1012
+ });
1013
+ await settled();
1014
+ await click("[data-test-open-ai-assistant]");
1015
+ await waitFor("[data-test-room-name=\"test room 1\"]");
1016
+ await click("[data-test-view-code-button]");
1017
+ await waitFor("[data-test-editor]");
1018
+ await settled();
1019
+ let codeBlockSelector = "[data-test-tool-call-id=\"tall-tool-call\"] [data-test-tool-code-block]";
1020
+ assert.dom(codeBlockSelector).exists("tool code block element exists");
1021
+ let codeBlock = find(codeBlockSelector);
1022
+ assert.strictEqual(codeBlock.style.height, "", "no inline height is stamped when the code is expanded");
1023
+ let childrenHeight = [...codeBlock.children].reduce((sum, child) => sum + child.offsetHeight, 0);
1024
+ assert.ok(codeBlock.offsetHeight <= childrenHeight + 4, `expanded code block height (${codeBlock.offsetHeight}px) should not exceed its rendered children (${childrenHeight}px)`);
1025
+ });
1026
+ (0, import_qunit.test)("when command in a message with continuations is done streaming, apply button is shown in ready state", async function(assert) {
1027
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1028
+ await renderComponent(class TestDriver extends Component {
1029
+ static {
1030
+ setComponentTemplate(templateFactory({
1031
+ "id": "hk0qKyFP",
1032
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1033
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1034
+ "scope": () => [OperatorModeContainer, noop],
1035
+ "isStrictMode": true
1036
+ }), this);
1037
+ }
1038
+ });
1039
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1040
+ let roomId = createAndJoinRoom({
1041
+ sender: "@testuser:localhost",
1042
+ name: "test room 1"
1043
+ });
1044
+ let initialEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1045
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1046
+ body: "Changing",
1047
+ format: "org.matrix.custom.html",
1048
+ isStreamingFinished: false
1049
+ });
1050
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1051
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1052
+ body: "Changing first",
1053
+ format: "org.matrix.custom.html",
1054
+ isStreamingFinished: true,
1055
+ [APP_BOXEL_HAS_CONTINUATION_CONTENT_KEY]: true,
1056
+ "m.relates_to": {
1057
+ rel_type: "m.replace",
1058
+ event_id: initialEventId
1059
+ }
1060
+ });
1061
+ let continuationEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1062
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1063
+ body: "Changing first names",
1064
+ format: "org.matrix.custom.html",
1065
+ [APP_BOXEL_CONTINUATION_OF_CONTENT_KEY]: initialEventId,
1066
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1067
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
1068
+ name: "patchCard"
1069
+ }],
1070
+ isStreamingFinished: false
1071
+ });
1072
+ await settled();
1073
+ await click("[data-test-open-ai-assistant]");
1074
+ await waitFor("[data-test-room-name=\"test room 1\"]");
1075
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
1076
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1077
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists({ count: 1 });
1078
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1079
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1080
+ body: "Changing first names",
1081
+ format: "org.matrix.custom.html",
1082
+ [APP_BOXEL_CONTINUATION_OF_CONTENT_KEY]: initialEventId,
1083
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1084
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
1085
+ name: "patchCard",
1086
+ arguments: JSON.stringify({ attributes: {
1087
+ cardId: `${testRealmURL}Person/fadhlan`,
1088
+ patch: { attributes: { firstName: "Evie" } }
1089
+ } })
1090
+ }, {
1091
+ id: "f2da5504-b92f-480a-986a-56ec606d240e",
1092
+ name: "patchCard",
1093
+ arguments: JSON.stringify({ attributes: {
1094
+ cardId: `${testRealmURL}Person/hassan`,
1095
+ patch: { attributes: { firstName: "Ivana" } }
1096
+ } })
1097
+ }],
1098
+ isStreamingFinished: false,
1099
+ "m.relates_to": {
1100
+ rel_type: "m.replace",
1101
+ event_id: continuationEventId
1102
+ }
1103
+ });
1104
+ await settled();
1105
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
1106
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1107
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists({ count: 2 });
1108
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1109
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1110
+ body: "Changing first names",
1111
+ format: "org.matrix.custom.html",
1112
+ [APP_BOXEL_CONTINUATION_OF_CONTENT_KEY]: initialEventId,
1113
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1114
+ id: "6545dc5a-01a1-47d6-b2f7-493d2ff5a0c2",
1115
+ name: "patchCard",
1116
+ arguments: JSON.stringify({ attributes: {
1117
+ cardId: `${testRealmURL}Person/fadhlan`,
1118
+ patch: { attributes: { firstName: "Evie" } }
1119
+ } })
1120
+ }, {
1121
+ id: "f2da5504-b92f-480a-986a-56ec606d240e",
1122
+ name: "patchCard",
1123
+ arguments: JSON.stringify({ attributes: {
1124
+ cardId: `${testRealmURL}Person/hassan`,
1125
+ patch: { attributes: { firstName: "Ivana" } }
1126
+ } })
1127
+ }],
1128
+ isStreamingFinished: true,
1129
+ "m.relates_to": {
1130
+ rel_type: "m.replace",
1131
+ event_id: continuationEventId
1132
+ }
1133
+ });
1134
+ await settled();
1135
+ assert.dom("[data-test-message-idx]").exists({ count: 1 });
1136
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1137
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"preparing\"]").exists({ count: 0 });
1138
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"ready\"]").exists({ count: 2 });
1139
+ });
1140
+ (0, import_qunit.skip)("command that returns a FileForAttachmentCard result is specially handled to attach the file", async function(assert) {
1141
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1142
+ await renderComponent(class TestDriver extends Component {
1143
+ static {
1144
+ setComponentTemplate(templateFactory({
1145
+ "id": "hk0qKyFP",
1146
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1147
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1148
+ "scope": () => [OperatorModeContainer, noop],
1149
+ "isStrictMode": true
1150
+ }), this);
1151
+ }
1152
+ });
1153
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1154
+ let roomId = createAndJoinRoom({
1155
+ sender: "@testuser:localhost",
1156
+ name: "test room 1"
1157
+ });
1158
+ await settled();
1159
+ await click("[data-test-open-ai-assistant]");
1160
+ await waitFor("[data-test-room-name=\"test room 1\"]", { timeout: 1e4 });
1161
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
1162
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1163
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1164
+ body: "Reading hello file",
1165
+ format: "org.matrix.custom.html",
1166
+ isStreamingFinished: true,
1167
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1168
+ id: "0ce51dc1-c819-4d6d-9f4f-77fbf60e9a0a",
1169
+ name: "read-file-for-ai-assistant_a831",
1170
+ arguments: JSON.stringify({ attributes: { fileIdentifier: `${testRealmURL}hello.txt` } })
1171
+ }]
1172
+ });
1173
+ let commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation" && event.content["m.relates_to"]?.key === "applied");
1174
+ assert.strictEqual(commandResultEvents.length, 0, "command result event is not dispatched");
1175
+ await settled();
1176
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1177
+ await click("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1178
+ await waitFor("[data-test-tool-call-card-idle]");
1179
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists();
1180
+ commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation" && event.content["m.relates_to"]?.key === "applied");
1181
+ assert.strictEqual(commandResultEvents.length, 1, "command result event is dispatched");
1182
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).attachedFiles.length, 1, "command result event contains an attached file");
1183
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).attachedFiles[0].name, "hello.txt", "command result event contains attached file");
1184
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).attachedFiles[0].sourceUrl, "http://test-realm/test/hello.txt", "command result event contains file whose url was reference in the input of the command as an attached file");
1185
+ });
1186
+ (0, import_qunit.skip)("command that returns a CardForAttachmentCard result is specially handled to attach the card", async function(assert) {
1187
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1188
+ await renderComponent(class TestDriver extends Component {
1189
+ static {
1190
+ setComponentTemplate(templateFactory({
1191
+ "id": "hk0qKyFP",
1192
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1193
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1194
+ "scope": () => [OperatorModeContainer, noop],
1195
+ "isStrictMode": true
1196
+ }), this);
1197
+ }
1198
+ });
1199
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1200
+ let roomId = createAndJoinRoom({
1201
+ sender: "@testuser:localhost",
1202
+ name: "test room 1"
1203
+ });
1204
+ await settled();
1205
+ await click("[data-test-open-ai-assistant]");
1206
+ await waitFor("[data-test-room-name=\"test room 1\"]", { timeout: 1e4 });
1207
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
1208
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1209
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1210
+ body: "Reading card",
1211
+ format: "org.matrix.custom.html",
1212
+ isStreamingFinished: true,
1213
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1214
+ id: "1ef9a66a-2201-4874-a156-9705acb1ac13",
1215
+ name: "read-card-for-ai-assistant_dd38",
1216
+ arguments: JSON.stringify({ attributes: { cardId: `${testRealmURL}Pet/mango` } })
1217
+ }]
1218
+ });
1219
+ let commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation" && event.content["m.relates_to"]?.key === "applied");
1220
+ assert.strictEqual(commandResultEvents.length, 0, "command result event is not dispatched");
1221
+ await settled();
1222
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1223
+ await click("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1224
+ await waitFor("[data-test-tool-call-card-idle]");
1225
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists();
1226
+ commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation" && event.content["m.relates_to"]?.key === "applied");
1227
+ assert.strictEqual(commandResultEvents.length, 1, "command result event is dispatched");
1228
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).attachedCards.length, 1, "command result event contains an attached file");
1229
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).attachedCards[0].name, "Mango", "command result event contains attached card");
1230
+ assert.deepEqual(JSON.parse(commandResultEvents[0].content.data).attachedCards[0].sourceUrl, "http://test-realm/test/Pet/mango", "command result event contains file whose url was reference in the input of the command as an attached file");
1231
+ });
1232
+ (0, import_qunit.test)("commandResult event_id is sourced from current room state, not a streaming snapshot", async function(assert) {
1233
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1234
+ await renderComponent(class TestDriver extends Component {
1235
+ static {
1236
+ setComponentTemplate(templateFactory({
1237
+ "id": "hk0qKyFP",
1238
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1239
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1240
+ "scope": () => [OperatorModeContainer, noop],
1241
+ "isStrictMode": true
1242
+ }), this);
1243
+ }
1244
+ });
1245
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1246
+ let roomId = createAndJoinRoom({
1247
+ sender: "@testuser:localhost",
1248
+ name: "test room 1"
1249
+ });
1250
+ let commandRequestId = "cmd-request-id";
1251
+ let streamingEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1252
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1253
+ body: "Changing",
1254
+ format: "org.matrix.custom.html",
1255
+ isStreamingFinished: false
1256
+ });
1257
+ let replacedEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1258
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1259
+ body: "Changing first name to Evie",
1260
+ format: "org.matrix.custom.html",
1261
+ isStreamingFinished: true,
1262
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1263
+ id: commandRequestId,
1264
+ name: "patchCardInstance",
1265
+ arguments: JSON.stringify({ attributes: {
1266
+ cardId: `${testRealmURL}Person/fadhlan`,
1267
+ patch: { attributes: { firstName: "Evie" } }
1268
+ } })
1269
+ }],
1270
+ "m.relates_to": {
1271
+ rel_type: "m.replace",
1272
+ event_id: streamingEventId
1273
+ }
1274
+ });
1275
+ await settled();
1276
+ await click("[data-test-open-ai-assistant]");
1277
+ await waitFor("[data-test-room-name=\"test room 1\"]");
1278
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1279
+ await click("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1280
+ await waitFor("[data-test-tool-call-card-idle]");
1281
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists("MessageTool status should flip to applied even though commandResult.m.relates_to.event_id is the m.replace id, not the streaming id the cache is keyed by");
1282
+ let commandResultEvents = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content["m.relates_to"]?.rel_type === "app.boxel.toolAnnotation");
1283
+ assert.strictEqual(commandResultEvents.length, 1, "exactly one commandResult should be dispatched");
1284
+ assert.strictEqual(commandResultEvents[0].content["m.relates_to"]?.event_id, replacedEventId, "commandResult.m.relates_to.event_id should be the bot message event_id currently in room.events that owns the toolRequest, not a stale snapshot of the streaming/original id");
1285
+ assert.notStrictEqual(commandResultEvents[0].content["m.relates_to"]?.event_id, streamingEventId, "commandResult should not reference the original/streaming event_id once a later event in room.events owns the toolRequest");
1286
+ });
1287
+ (0, import_qunit.test)("an applied command on a streamed bot message still renders applied after reload (m.replace edits stripped)", async function(assert) {
1288
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1289
+ await renderComponent(class TestDriver extends Component {
1290
+ static {
1291
+ setComponentTemplate(templateFactory({
1292
+ "id": "hk0qKyFP",
1293
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1294
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1295
+ "scope": () => [OperatorModeContainer, noop],
1296
+ "isStrictMode": true
1297
+ }), this);
1298
+ }
1299
+ });
1300
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1301
+ let roomId = createAndJoinRoom({
1302
+ sender: "@testuser:localhost",
1303
+ name: "test room 1"
1304
+ });
1305
+ let commandRequestId = "cmd-request-id";
1306
+ let strippedEditEventId = "stripped-edit-event-id";
1307
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1308
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1309
+ body: "Changing first name to Evie",
1310
+ format: "org.matrix.custom.html",
1311
+ isStreamingFinished: true,
1312
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1313
+ id: commandRequestId,
1314
+ name: "patchCardInstance",
1315
+ arguments: JSON.stringify({ attributes: {
1316
+ cardId: `${testRealmURL}Person/fadhlan`,
1317
+ patch: { attributes: { firstName: "Evie" } }
1318
+ } })
1319
+ }]
1320
+ });
1321
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1322
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
1323
+ commandRequestId,
1324
+ "m.relates_to": {
1325
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
1326
+ key: "applied",
1327
+ event_id: strippedEditEventId
1328
+ },
1329
+ data: {}
1330
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
1331
+ await settled();
1332
+ await click("[data-test-open-ai-assistant]");
1333
+ await waitFor("[data-test-room-name=\"test room 1\"]");
1334
+ await waitFor("[data-test-message-idx=\"0\"]");
1335
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists("a command applied before reload still renders applied even though its commandResult links to a stripped m.replace edit id; correlation is by commandRequestId, not the dangling event_id");
1336
+ });
1337
+ (0, import_qunit.test)("an applied commandResult flips only its own bot message, not a sibling message that also carries a command", async function(assert) {
1338
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1339
+ await renderComponent(class TestDriver extends Component {
1340
+ static {
1341
+ setComponentTemplate(templateFactory({
1342
+ "id": "hk0qKyFP",
1343
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1344
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1345
+ "scope": () => [OperatorModeContainer, noop],
1346
+ "isStrictMode": true
1347
+ }), this);
1348
+ }
1349
+ });
1350
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1351
+ let roomId = createAndJoinRoom({
1352
+ sender: "@testuser:localhost",
1353
+ name: "test room 1"
1354
+ });
1355
+ let firstCommandRequestId = "first-cmd-request-id";
1356
+ let secondCommandRequestId = "second-cmd-request-id";
1357
+ let strippedEditEventId = "stripped-edit-event-id";
1358
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1359
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1360
+ body: "Changing first name to Evie",
1361
+ format: "org.matrix.custom.html",
1362
+ isStreamingFinished: true,
1363
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1364
+ id: firstCommandRequestId,
1365
+ name: "patchCardInstance",
1366
+ arguments: JSON.stringify({ attributes: {
1367
+ cardId: `${testRealmURL}Person/fadhlan`,
1368
+ patch: { attributes: { firstName: "Evie" } }
1369
+ } })
1370
+ }]
1371
+ });
1372
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1373
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1374
+ body: "Changing first name to Mango",
1375
+ format: "org.matrix.custom.html",
1376
+ isStreamingFinished: true,
1377
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1378
+ id: secondCommandRequestId,
1379
+ name: "patchCardInstance",
1380
+ arguments: JSON.stringify({ attributes: {
1381
+ cardId: `${testRealmURL}Person/fadhlan`,
1382
+ patch: { attributes: { firstName: "Mango" } }
1383
+ } })
1384
+ }]
1385
+ });
1386
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1387
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
1388
+ commandRequestId: secondCommandRequestId,
1389
+ "m.relates_to": {
1390
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
1391
+ key: "applied",
1392
+ event_id: strippedEditEventId
1393
+ },
1394
+ data: {}
1395
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
1396
+ await settled();
1397
+ await click("[data-test-open-ai-assistant]");
1398
+ await waitFor("[data-test-room-name=\"test room 1\"]");
1399
+ await waitFor("[data-test-message-idx=\"1\"]");
1400
+ assert.dom("[data-test-message-idx=\"1\"] [data-test-apply-state=\"applied\"]").exists("the bot message whose commandRequestId owns the applied result renders applied");
1401
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"ready\"]").exists("the sibling bot message, which has no result of its own, stays ready — the applied status did not bleed across messages");
1402
+ });
1403
+ (0, import_qunit.test)("Accept All bar does not flash for an always-auto-executed command (checkCorrectness)", async function(assert) {
1404
+ simulateRemoteMessage(await renderAiAssistantPanel(), "@aibot:localhost", {
1405
+ body: "checking correctness",
1406
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1407
+ format: "org.matrix.custom.html",
1408
+ isStreamingFinished: true,
1409
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1410
+ id: "cs-11647-check-correctness",
1411
+ name: "checkCorrectness",
1412
+ arguments: "{}"
1413
+ }],
1414
+ data: { context: { agentId: getService("matrix-service").agentId } }
1415
+ });
1416
+ await waitFor("[data-test-message-idx=\"0\"]");
1417
+ assert.dom("[data-test-accept-all]").doesNotExist("Accept All button must not paint in the debounce window before auto-execute starts");
1418
+ await settled();
1419
+ assert.dom("[data-test-accept-all]").doesNotExist("Accept All button still hidden after the auto-execute debounce window elapses");
1420
+ });
1421
+ (0, import_qunit.test)("Accept All bar does not flash for a requiresApproval=false command", async function(assert) {
1422
+ setCardInOperatorModeState(`${testRealmURL}Person/fadhlan`);
1423
+ await renderComponent(class TestDriver extends Component {
1424
+ static {
1425
+ setComponentTemplate(templateFactory({
1426
+ "id": "hk0qKyFP",
1427
+ "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1428
+ "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/components/ai-assistant-panel/tools-test.gts",
1429
+ "scope": () => [OperatorModeContainer, noop],
1430
+ "isStrictMode": true
1431
+ }), this);
1432
+ }
1433
+ });
1434
+ await waitFor("[data-test-person=\"Fadhlan\"]");
1435
+ createAndJoinRoom({
1436
+ sender: "@testuser:localhost",
1437
+ name: "auto-exec via skill"
1438
+ });
1439
+ await settled();
1440
+ await click("[data-test-open-ai-assistant]");
1441
+ await waitFor("[data-test-room-name=\"auto-exec via skill\"]", { timeout: 1e4 });
1442
+ await addSkillToAiAssistant(`${testRealmURL}Skill/boxel-environment`);
1443
+ simulateRemoteMessage(document.querySelector("[data-test-room]").getAttribute("data-test-room"), "@aibot:localhost", {
1444
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1445
+ body: "Reading hello file",
1446
+ format: "org.matrix.custom.html",
1447
+ isStreamingFinished: true,
1448
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1449
+ id: "cs-11647-no-approval",
1450
+ name: "read-file-for-ai-assistant_a831",
1451
+ arguments: JSON.stringify({ attributes: { fileIdentifier: `${testRealmURL}hello.txt` } })
1452
+ }],
1453
+ data: { context: { agentId: getService("matrix-service").agentId } }
1454
+ });
1455
+ await waitFor("[data-test-message-idx=\"0\"]");
1456
+ assert.dom("[data-test-accept-all]").doesNotExist("Accept All button suppressed for requiresApproval=false commands");
1457
+ });
1458
+ (0, import_qunit.test)("per-command Apply button does not flash Run before auto-execute starts", async function(assert) {
1459
+ simulateRemoteMessage(await renderAiAssistantPanel(), "@aibot:localhost", {
1460
+ body: "checking correctness",
1461
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1462
+ format: "org.matrix.custom.html",
1463
+ isStreamingFinished: true,
1464
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1465
+ id: "cs-11647-apply-button",
1466
+ name: "checkCorrectness",
1467
+ arguments: "{}"
1468
+ }],
1469
+ data: { context: { agentId: getService("matrix-service").agentId } }
1470
+ });
1471
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1472
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"ready\"]").doesNotExist("per-command Apply button must not show the ready/Run state for an auto-executed command");
1473
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-apply=\"applying\"]").exists("per-command Apply button shows the applying spinner instead");
1474
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-tool-call-card-idle]").doesNotExist("data-test-tool-call-card-idle agrees with applyButtonState while the synthetic spinner is on");
1475
+ });
1476
+ (0, import_qunit.test)("stuck-processing helper dispatches an invalid commandResult for each auto-executable command", async function(assert) {
1477
+ let roomId = await renderAiAssistantPanel();
1478
+ let matrixService = getService("matrix-service");
1479
+ let toolService = getService("tool-service");
1480
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1481
+ body: "checking correctness",
1482
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1483
+ format: "org.matrix.custom.html",
1484
+ isStreamingFinished: true,
1485
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1486
+ id: "cs-11647-stuck-auto",
1487
+ name: "checkCorrectness",
1488
+ arguments: "{}"
1489
+ }, {
1490
+ id: "cs-11647-stuck-manual",
1491
+ name: "patchCardInstance",
1492
+ arguments: JSON.stringify({ attributes: {
1493
+ cardId: `${testRealmURL}Person/fadhlan`,
1494
+ patch: { attributes: { firstName: "Dave" } }
1495
+ } })
1496
+ }],
1497
+ data: { context: { agentId: matrixService.agentId } }
1498
+ });
1499
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-tool-call-apply]");
1500
+ let roomResource = matrixService.roomResources.get(roomId);
1501
+ let message = roomResource.messages.find((m) => m.tools?.length === 2);
1502
+ assert.ok(message, "two-command bot message lands in the room resource");
1503
+ let captured = [];
1504
+ let originalSend = matrixService.sendToolResultEvent.bind(matrixService);
1505
+ matrixService.sendToolResultEvent = async (params) => {
1506
+ captured.push({
1507
+ toolCallId: params.toolCallId,
1508
+ failureReason: params.failureReason
1509
+ });
1510
+ };
1511
+ try {
1512
+ await toolService.invalidateAutoExecutableToolsForStuckProcessing(roomResource, roomId, message.eventId);
1513
+ } finally {
1514
+ matrixService.sendToolResultEvent = originalSend;
1515
+ }
1516
+ assert.strictEqual(captured.length, 1, "only the auto-executable command is invalidated; manual-approval command is left in ready");
1517
+ assert.strictEqual(captured[0]?.toolCallId, "cs-11647-stuck-auto", "the dispatched invalid event targets the auto-executable command");
1518
+ assert.true((captured[0]?.failureReason ?? "").startsWith("Room processing did not finish within"), "failureReason surfaces the stuck-processing cause for the invalidToolCallState alert");
1519
+ });
1520
+ (0, import_qunit.test)("an invalid result is terminal for auto-execution: a later drain pass does not re-resolve the request", async function(assert) {
1521
+ let roomId = await renderAiAssistantPanel();
1522
+ let matrixService = getService("matrix-service");
1523
+ let toolService = getService("tool-service");
1524
+ let captured = [];
1525
+ let originalSend = matrixService.sendToolResultEvent.bind(matrixService);
1526
+ matrixService.sendToolResultEvent = async (params) => {
1527
+ captured.push({
1528
+ toolCallId: params.toolCallId,
1529
+ status: params.status
1530
+ });
1531
+ };
1532
+ try {
1533
+ let eventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1534
+ body: "Do the thing",
1535
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1536
+ format: "org.matrix.custom.html",
1537
+ isStreamingFinished: true,
1538
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1539
+ id: "cs-12103-invalid-terminal",
1540
+ name: "no-such-command",
1541
+ arguments: JSON.stringify({
1542
+ description: "do it",
1543
+ attributes: {}
1544
+ })
1545
+ }],
1546
+ data: { context: { agentId: matrixService.agentId } }
1547
+ });
1548
+ await settled();
1549
+ assert.deepEqual(captured, [{
1550
+ toolCallId: "cs-12103-invalid-terminal",
1551
+ status: "invalid"
1552
+ }], "validation resolves the request invalid exactly once");
1553
+ assert.true(toolService.claimedToolRequestIds.has("cs-12103-invalid-terminal"), "the terminal resolution is recorded locally, not just in the (still in-flight) result event");
1554
+ toolService.queueEventForToolProcessing({
1555
+ event_id: eventId,
1556
+ room_id: roomId,
1557
+ content: {}
1558
+ });
1559
+ await settled();
1560
+ assert.strictEqual(captured.length, 1, "the resolved request gets no second result and is not executed");
1561
+ } finally {
1562
+ matrixService.sendToolResultEvent = originalSend;
1563
+ }
1564
+ });
1565
+ (0, import_qunit.test)("overlapping drain passes resolve a tool request exactly once", async function(assert) {
1566
+ let roomId = await renderAiAssistantPanel();
1567
+ let matrixService = getService("matrix-service");
1568
+ let toolService = getService("tool-service");
1569
+ let captured = [];
1570
+ let originalSend = matrixService.sendToolResultEvent.bind(matrixService);
1571
+ matrixService.sendToolResultEvent = async (params) => {
1572
+ captured.push({
1573
+ toolCallId: params.toolCallId,
1574
+ status: params.status
1575
+ });
1576
+ };
1577
+ let overlapAgentId = "overlap-test-agent";
1578
+ let originalAgentId = matrixService.agentId;
1579
+ try {
1580
+ let eventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1581
+ body: "Do the thing",
1582
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1583
+ format: "org.matrix.custom.html",
1584
+ isStreamingFinished: true,
1585
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1586
+ id: "overlap-victim",
1587
+ name: "checkCorrectness",
1588
+ arguments: "not parseable json, so validation resolves invalid"
1589
+ }],
1590
+ data: { context: { agentId: overlapAgentId } }
1591
+ });
1592
+ await settled();
1593
+ assert.strictEqual(captured.length, 0, "the not-our-agent message is left unresolved by the timeline drain");
1594
+ matrixService.agentId = overlapAgentId;
1595
+ let svc = toolService;
1596
+ svc.toolProcessingEventQueue.push(`${roomId}|${eventId}`);
1597
+ let firstPass = svc.drainToolProcessingQueue();
1598
+ await Promise.resolve();
1599
+ svc.flushToolProcessingQueue = void 0;
1600
+ svc.toolProcessingEventQueue.push(`${roomId}|${eventId}`);
1601
+ let secondPass = svc.drainToolProcessingQueue();
1602
+ await Promise.all([firstPass, secondPass]);
1603
+ await settled();
1604
+ assert.deepEqual(captured, [{
1605
+ toolCallId: "overlap-victim",
1606
+ status: "invalid"
1607
+ }], "the request gets exactly one terminal result across both passes");
1608
+ } finally {
1609
+ matrixService.agentId = originalAgentId;
1610
+ matrixService.sendToolResultEvent = originalSend;
1611
+ }
1612
+ });
1613
+ const discoveredSkillUrl = `${testRealmURL}Skill/boxel-environment`;
1614
+ const discoveredHostToolName = buildToolFunctionNameFromResolvedRef({
1615
+ module: "@cardstack/boxel-host/commands/read-file-for-ai-assistant",
1616
+ name: "default"
1617
+ });
1618
+ function simulateDiscoveredToolResult(roomId) {
1619
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1620
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_OUTPUT_MSGTYPE,
1621
+ commandRequestId: "earlier-skill-read",
1622
+ "m.relates_to": {
1623
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
1624
+ key: "applied",
1625
+ event_id: "earlier-bot-message"
1626
+ },
1627
+ data: {
1628
+ attachedFiles: [],
1629
+ discoveredTools: [{
1630
+ sourceSkillUrl: discoveredSkillUrl,
1631
+ codeRef: {
1632
+ module: "@cardstack/boxel-host/commands/read-file-for-ai-assistant",
1633
+ name: "default"
1634
+ },
1635
+ functionName: discoveredHostToolName,
1636
+ requiresApproval: false,
1637
+ definition: {
1638
+ type: "function",
1639
+ function: {
1640
+ name: discoveredHostToolName,
1641
+ description: "Read a file",
1642
+ parameters: {
1643
+ type: "object",
1644
+ properties: {}
1645
+ }
1646
+ }
1647
+ }
1648
+ }]
1649
+ }
1650
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
1651
+ }
1652
+ async function seedDiscoveredHostToolTurn(roomId) {
1653
+ let agentId = getService("matrix-service").agentId;
1654
+ simulateDiscoveredToolResult(roomId);
1655
+ let streamingEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1656
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1657
+ body: "Reading",
1658
+ format: "org.matrix.custom.html",
1659
+ isStreamingFinished: false,
1660
+ data: { context: { agentId } }
1661
+ });
1662
+ await settled();
1663
+ return streamingEventId;
1664
+ }
1665
+ function holdDiscoveredSkillLoads() {
1666
+ let store = getService("store");
1667
+ let release = new Deferred();
1668
+ let heldLoads = 0;
1669
+ let originalGet = store.get;
1670
+ store.get = async (id, ...rest) => {
1671
+ if (id === discoveredSkillUrl) {
1672
+ heldLoads++;
1673
+ await release.promise;
1674
+ }
1675
+ return originalGet.call(store, id, ...rest);
1676
+ };
1677
+ return {
1678
+ get heldLoads() {
1679
+ return heldLoads;
1680
+ },
1681
+ async reached() {
1682
+ await waitUntil(() => heldLoads > 0, {
1683
+ timeout: 5e3,
1684
+ timeoutMessage: "the final edit never started resolving the discovered host tool (no load of its skill within 5s)"
1685
+ });
1686
+ },
1687
+ release() {
1688
+ release.fulfill();
1689
+ store.get = originalGet;
1690
+ }
1691
+ };
1692
+ }
1693
+ function failDiscoveredSkillLoads() {
1694
+ let store = getService("store");
1695
+ let originalGet = store.get;
1696
+ store.get = async (id, ...rest) => {
1697
+ if (id === discoveredSkillUrl) throw new Error("simulated skill load failure");
1698
+ return originalGet.call(store, id, ...rest);
1699
+ };
1700
+ return { restore() {
1701
+ store.get = originalGet;
1702
+ } };
1703
+ }
1704
+ function finalEditWithHostTool(streamingEventId, body, toolRequests) {
1705
+ return {
1706
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1707
+ body,
1708
+ format: "org.matrix.custom.html",
1709
+ isStreamingFinished: true,
1710
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [...toolRequests, {
1711
+ id: "slow-host-read",
1712
+ name: discoveredHostToolName,
1713
+ arguments: JSON.stringify({ attributes: { fileIdentifier: `${testRealmURL}hello.txt` } })
1714
+ }],
1715
+ "m.relates_to": {
1716
+ rel_type: "m.replace",
1717
+ event_id: streamingEventId
1718
+ },
1719
+ data: { context: { agentId: getService("matrix-service").agentId } }
1720
+ };
1721
+ }
1722
+ async function drainIsValidating(toolCallId) {
1723
+ let toolService = getService("tool-service");
1724
+ await waitUntil(() => toolService.validationSteps.has(toolCallId), {
1725
+ timeout: 5e3,
1726
+ timeoutMessage: `the tool drain never started validating ${toolCallId}`
1727
+ });
1728
+ }
1729
+ (0, import_qunit.test)("a host tool whose resolution outlasts a room-processing restart still runs", async function(assert) {
1730
+ let roomId = await renderAiAssistantPanel();
1731
+ let streamingEventId = await seedDiscoveredHostToolTurn(roomId);
1732
+ let hold = holdDiscoveredSkillLoads();
1733
+ try {
1734
+ simulateRemoteMessage(roomId, "@aibot:localhost", finalEditWithHostTool(streamingEventId, "Reading", [{
1735
+ id: "bot-run-read",
1736
+ name: "readRealmFile",
1737
+ arguments: JSON.stringify({ path: "hello.txt" }),
1738
+ executedBy: AI_BOT_EXECUTOR
1739
+ }]));
1740
+ await hold.reached();
1741
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1742
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
1743
+ commandRequestId: "bot-run-read",
1744
+ "m.relates_to": {
1745
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
1746
+ key: "applied",
1747
+ event_id: streamingEventId
1748
+ }
1749
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
1750
+ await drainIsValidating("slow-host-read");
1751
+ assert.strictEqual(hold.heldLoads, 1, "neither the restarted room pass nor the drain starts a second resolution");
1752
+ } finally {
1753
+ hold.release();
1754
+ }
1755
+ await settled();
1756
+ let hostToolResults = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "slow-host-read");
1757
+ assert.strictEqual(hostToolResults.length, 1, "the host tool resolved after the restart is run and its result posted");
1758
+ assert.strictEqual(hostToolResults[0]?.content["m.relates_to"]?.key, "applied", "the host tool ran successfully");
1759
+ assert.dom("[data-test-tool-call-apply=\"applying\"]").doesNotExist("no tool is left spinning in the applying state");
1760
+ });
1761
+ (0, import_qunit.test)("a response-stream preview that arrives while the final edit resolves its tools does not overwrite it", async function(assert) {
1762
+ let roomId = await renderAiAssistantPanel();
1763
+ let streamingEventId = await seedDiscoveredHostToolTurn(roomId);
1764
+ let matrixService = getService("matrix-service");
1765
+ let hold = holdDiscoveredSkillLoads();
1766
+ try {
1767
+ simulateRemoteMessage(roomId, "@aibot:localhost", finalEditWithHostTool(streamingEventId, "The final answer.", []));
1768
+ await hold.reached();
1769
+ simulateToDeviceEvent(APP_BOXEL_RESPONSE_STREAM_EVENT_TYPE, {
1770
+ roomId,
1771
+ parentEventId: streamingEventId,
1772
+ sequence: 99,
1773
+ body: "A stale preview.",
1774
+ reasoning: "",
1775
+ toolRequests: []
1776
+ }, matrixService.aiBotUserId);
1777
+ await delay(100);
1778
+ } finally {
1779
+ hold.release();
1780
+ }
1781
+ await settled();
1782
+ let message = matrixService.roomResources.get(roomId).messageForEventId(streamingEventId);
1783
+ assert.strictEqual(message.body, "The final answer.", "the final edit keeps its body");
1784
+ assert.true(message.isStreamingFinished, "the message stays finished");
1785
+ assert.dom(`[data-test-room="${roomId}"]`).doesNotContainText("A stale preview.");
1786
+ });
1787
+ (0, import_qunit.test)("a host tool whose command never resolves gets a terminal invalid result and the room keeps processing", async function(assert) {
1788
+ let roomId = await renderAiAssistantPanel();
1789
+ let streamingEventId = await seedDiscoveredHostToolTurn(roomId);
1790
+ let fail = failDiscoveredSkillLoads();
1791
+ try {
1792
+ simulateRemoteMessage(roomId, "@aibot:localhost", finalEditWithHostTool(streamingEventId, "Reading", []));
1793
+ await settled();
1794
+ } finally {
1795
+ fail.restore();
1796
+ }
1797
+ await settled();
1798
+ let hostToolResults = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "slow-host-read");
1799
+ assert.strictEqual(hostToolResults.length, 1, "exactly one terminal result is posted for the request that never resolved");
1800
+ assert.strictEqual(hostToolResults[0]?.content["m.relates_to"]?.key, "invalid", "the unresolvable tool is reported invalid");
1801
+ assert.dom("[data-test-tool-call-apply=\"applying\"]").doesNotExist("no tool is left spinning in the applying state");
1802
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1803
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1804
+ body: "Still alive",
1805
+ format: "org.matrix.custom.html",
1806
+ isStreamingFinished: true,
1807
+ data: { context: { agentId: getService("matrix-service").agentId } }
1808
+ });
1809
+ await settled();
1810
+ assert.dom(`[data-test-room="${roomId}"]`).containsText("Still alive", "the room keeps processing later events");
1811
+ });
1812
+ (0, import_qunit.test)("a host tool renamed by the final edit runs as the renamed tool, not the stale one", async function(assert) {
1813
+ let roomId = await renderAiAssistantPanel();
1814
+ let streamingEventId = await seedDiscoveredHostToolTurn(roomId);
1815
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1816
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1817
+ body: "Reading",
1818
+ format: "org.matrix.custom.html",
1819
+ isStreamingFinished: false,
1820
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1821
+ id: "slow-host-read",
1822
+ name: "read-file-for"
1823
+ }],
1824
+ "m.relates_to": {
1825
+ rel_type: "m.replace",
1826
+ event_id: streamingEventId
1827
+ },
1828
+ data: { context: { agentId: getService("matrix-service").agentId } }
1829
+ });
1830
+ await settled();
1831
+ let hold = holdDiscoveredSkillLoads();
1832
+ try {
1833
+ simulateRemoteMessage(roomId, "@aibot:localhost", finalEditWithHostTool(streamingEventId, "Reading", []));
1834
+ await hold.reached();
1835
+ await drainIsValidating("slow-host-read");
1836
+ assert.strictEqual(getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "slow-host-read").length, 0, "the drain waits for the renamed tool instead of validating the stale name");
1837
+ } finally {
1838
+ hold.release();
1839
+ }
1840
+ await settled();
1841
+ let hostToolResults = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "slow-host-read");
1842
+ assert.strictEqual(hostToolResults.length, 1, "exactly one result");
1843
+ assert.strictEqual(hostToolResults[0]?.content["m.relates_to"]?.key, "applied", "the renamed tool ran");
1844
+ });
1845
+ (0, import_qunit.test)("a call that already has a result is not answered again when its command no longer resolves", async function(assert) {
1846
+ let roomId = await renderAiAssistantPanel();
1847
+ let streamingEventId = await seedDiscoveredHostToolTurn(roomId);
1848
+ let fail = failDiscoveredSkillLoads();
1849
+ try {
1850
+ simulateRemoteMessage(roomId, "@aibot:localhost", finalEditWithHostTool(streamingEventId, "Reading", []));
1851
+ simulateRemoteMessage(roomId, "@testuser:localhost", {
1852
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
1853
+ commandRequestId: "slow-host-read",
1854
+ "m.relates_to": {
1855
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
1856
+ key: "applied",
1857
+ event_id: streamingEventId
1858
+ }
1859
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
1860
+ await settled();
1861
+ } finally {
1862
+ fail.restore();
1863
+ }
1864
+ let hostToolResults = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "slow-host-read");
1865
+ assert.deepEqual(hostToolResults.map((event) => event.content["m.relates_to"]?.key), ["applied"], "only the existing result, no contradictory invalid");
1866
+ });
1867
+ (0, import_qunit.test)("a call whose command fails to load gets a terminal invalid result saying it could not be prepared", async function(assert) {
1868
+ let roomId = await renderAiAssistantPanel();
1869
+ let streamingEventId = await seedDiscoveredHostToolTurn(roomId);
1870
+ let loaderPrototype = Object.getPrototypeOf(getService("loader-service").loader);
1871
+ let originalImport = loaderPrototype.import;
1872
+ loaderPrototype.import = async function(moduleId, ...rest) {
1873
+ if (String(moduleId).includes("read-file-for-ai-assistant")) throw new Error("simulated command module load failure");
1874
+ return originalImport.call(this, moduleId, ...rest);
1875
+ };
1876
+ try {
1877
+ simulateRemoteMessage(roomId, "@aibot:localhost", finalEditWithHostTool(streamingEventId, "Reading", []));
1878
+ await settled();
1879
+ } finally {
1880
+ loaderPrototype.import = originalImport;
1881
+ }
1882
+ let hostToolResults = getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "slow-host-read");
1883
+ assert.strictEqual(hostToolResults.length, 1, "exactly one result");
1884
+ assert.strictEqual(hostToolResults[0]?.content["m.relates_to"]?.key, "invalid", "the call is reported invalid");
1885
+ assert.true(String(hostToolResults[0]?.content.failureReason).includes("could not be prepared (simulated command module load failure)"), `the reason names the load failure: ${hostToolResults[0]?.content.failureReason}`);
1886
+ assert.dom("[data-test-tool-call-apply=\"applying\"]").doesNotExist("no tool is left spinning in the applying state");
1887
+ });
1888
+ (0, import_qunit.test)("another agent's call that first resolved to no command is resolved again when its request finishes", async function(assert) {
1889
+ let roomId = await renderAiAssistantPanel();
1890
+ let otherAgentContext = { context: { agentId: "another-agent" } };
1891
+ let streamingEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1892
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1893
+ body: "Reading",
1894
+ format: "org.matrix.custom.html",
1895
+ isStreamingFinished: false,
1896
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1897
+ id: "other-agent-read",
1898
+ name: discoveredHostToolName
1899
+ }],
1900
+ data: otherAgentContext
1901
+ });
1902
+ await settled();
1903
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
1904
+ let tool = () => roomResource.messageForEventId(streamingEventId).tools.find((t) => t.id === "other-agent-read");
1905
+ assert.strictEqual(tool().codeRef, void 0, "no command is found yet");
1906
+ simulateDiscoveredToolResult(roomId);
1907
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
1908
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1909
+ body: "Reading",
1910
+ format: "org.matrix.custom.html",
1911
+ isStreamingFinished: true,
1912
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1913
+ id: "other-agent-read",
1914
+ name: discoveredHostToolName,
1915
+ arguments: JSON.stringify({ attributes: { fileIdentifier: `${testRealmURL}hello.txt` } })
1916
+ }],
1917
+ "m.relates_to": {
1918
+ rel_type: "m.replace",
1919
+ event_id: streamingEventId
1920
+ },
1921
+ data: otherAgentContext
1922
+ });
1923
+ await settled();
1924
+ assert.strictEqual(tool().codeRef?.module, "@cardstack/boxel-host/commands/read-file-for-ai-assistant", "the finished call resolves to its command in a tab whose drain doesn't run it");
1925
+ assert.strictEqual(tool().actionVerb, "Send", "the command's action verb");
1926
+ assert.strictEqual(getRoomEvents(roomId).filter((event) => event.type === "app.boxel.toolResult" && event.content.commandRequestId === "other-agent-read").length, 0, "this tab does not run another agent's call");
1927
+ });
1928
+ (0, import_qunit.test)("Accept All bar still renders for a command that requires user approval", async function(assert) {
1929
+ simulateRemoteMessage(await renderAiAssistantPanel(`${testRealmURL}Person/fadhlan`), "@aibot:localhost", {
1930
+ body: "patching",
1931
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1932
+ format: "org.matrix.custom.html",
1933
+ isStreamingFinished: true,
1934
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1935
+ id: "cs-11647-patch",
1936
+ name: "patchCardInstance",
1937
+ arguments: JSON.stringify({ attributes: {
1938
+ cardId: `${testRealmURL}Person/fadhlan`,
1939
+ patch: { attributes: { firstName: "Dave" } }
1940
+ } })
1941
+ }]
1942
+ });
1943
+ await waitFor("[data-test-accept-all]");
1944
+ assert.dom("[data-test-accept-all]").exists("manual approval bar still renders for commands that need user approval");
1945
+ assert.dom("[data-test-stop-generating]").doesNotExist("nothing runs until the user approves, so there is no Stop");
1946
+ });
1947
+ function stubToolValidation({ held = false, heldToolIds, rejectSend } = {}) {
1948
+ let toolService = getService("tool-service");
1949
+ let matrixService = getService("matrix-service");
1950
+ let release;
1951
+ let released = held || heldToolIds ? new Promise((resolve) => release = resolve) : Promise.resolve();
1952
+ let validating = /* @__PURE__ */ new Set();
1953
+ let originalValidate = toolService.validate;
1954
+ toolService.validate = async (messageTool) => {
1955
+ if (messageTool.id) validating.add(messageTool.id);
1956
+ if (!heldToolIds || heldToolIds.includes(messageTool.id ?? "")) await released;
1957
+ return true;
1958
+ };
1959
+ let results = [];
1960
+ let originalSend = matrixService.sendToolResultEvent;
1961
+ matrixService.sendToolResultEvent = async function(params) {
1962
+ results.push({
1963
+ toolCallId: params.toolCallId,
1964
+ status: params.status,
1965
+ failureReason: params.failureReason,
1966
+ resumesAssistant: params.resumesAssistant
1967
+ });
1968
+ if (rejectSend?.(params)) throw new Error("the result could not be sent");
1969
+ return originalSend.call(this, params);
1970
+ };
1971
+ return {
1972
+ results,
1973
+ validating,
1974
+ release: () => release?.(),
1975
+ restore() {
1976
+ release?.();
1977
+ toolService.validate = originalValidate;
1978
+ matrixService.sendToolResultEvent = originalSend;
1979
+ }
1980
+ };
1981
+ }
1982
+ function checkCorrectnessCall(toolCallId) {
1983
+ return {
1984
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
1985
+ id: toolCallId,
1986
+ name: "checkCorrectness",
1987
+ arguments: "{}"
1988
+ }],
1989
+ data: { context: { agentId: getService("matrix-service").agentId } }
1990
+ };
1991
+ }
1992
+ async function stopWhileStreaming(roomId, toolCallId, stop, toolRequests = checkCorrectnessCall(toolCallId)) {
1993
+ let streamingEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
1994
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
1995
+ body: "Checking",
1996
+ format: "org.matrix.custom.html",
1997
+ isStreamingFinished: false,
1998
+ data: { context: { agentId: getService("matrix-service").agentId } }
1999
+ });
2000
+ await waitFor("[data-test-stop-generating]");
2001
+ await stop();
2002
+ await waitUntil(() => !document.querySelector("[data-test-stop-generating]"));
2003
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2004
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2005
+ body: "Checking correctness",
2006
+ format: "org.matrix.custom.html",
2007
+ isStreamingFinished: true,
2008
+ ...toolRequests,
2009
+ "m.relates_to": {
2010
+ rel_type: "m.replace",
2011
+ event_id: streamingEventId
2012
+ }
2013
+ });
2014
+ return streamingEventId;
2015
+ }
2016
+ function patchPersonCall(toolCallId) {
2017
+ return {
2018
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
2019
+ id: toolCallId,
2020
+ name: "patchCardInstance",
2021
+ arguments: JSON.stringify({ attributes: {
2022
+ cardId: `${testRealmURL}Person/fadhlan`,
2023
+ patch: { attributes: { firstName: "Dave" } }
2024
+ } })
2025
+ }],
2026
+ data: { context: { agentId: getService("matrix-service").agentId } }
2027
+ };
2028
+ }
2029
+ (0, import_qunit.test)("Stop is offered while a tool of the answer runs", async function(assert) {
2030
+ let roomId = await renderAiAssistantPanel();
2031
+ let stub = stubToolValidation({ held: true });
2032
+ try {
2033
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2034
+ body: "checking correctness",
2035
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2036
+ format: "org.matrix.custom.html",
2037
+ isStreamingFinished: true,
2038
+ ...checkCorrectnessCall("running-tool")
2039
+ });
2040
+ await waitFor("[data-test-stop-generating]");
2041
+ assert.dom("[data-test-ai-assistant-action-bar]").containsText("Running tools", "the bar says tools are running");
2042
+ } finally {
2043
+ stub.restore();
2044
+ }
2045
+ });
2046
+ (0, import_qunit.test)("a tool the user stopped before it started never runs", async function(assert) {
2047
+ let roomId = await renderAiAssistantPanel();
2048
+ let stub = stubToolValidation();
2049
+ try {
2050
+ await stopWhileStreaming(roomId, "stopped-before-run", () => click("[data-test-stop-generating]"));
2051
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2052
+ await settled();
2053
+ assert.strictEqual(JSON.stringify(stub.results), JSON.stringify([{
2054
+ toolCallId: "stopped-before-run",
2055
+ status: "canceled",
2056
+ failureReason: STOPPED_TOOL_CALL_REASON
2057
+ }]), "the tool is answered as canceled instead of run");
2058
+ assert.dom("[data-test-tool-call-apply=\"canceled\"]").exists("the tool reads as canceled");
2059
+ assert.dom("[data-test-stop-generating]").doesNotExist("Stop is not offered again for the stopped loop");
2060
+ } finally {
2061
+ stub.restore();
2062
+ }
2063
+ });
2064
+ (0, import_qunit.test)("a stop sent from the user's other client keeps a tool here from starting", async function(assert) {
2065
+ let roomId = await renderAiAssistantPanel();
2066
+ let stub = stubToolValidation();
2067
+ try {
2068
+ await stopWhileStreaming(roomId, "stopped-elsewhere", async () => {
2069
+ simulateRemoteMessage(roomId, "@testuser:localhost", {}, { type: APP_BOXEL_STOP_GENERATING_EVENT_TYPE });
2070
+ });
2071
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2072
+ await settled();
2073
+ assert.strictEqual(JSON.stringify(stub.results.map(({ toolCallId, status }) => ({
2074
+ toolCallId,
2075
+ status
2076
+ }))), JSON.stringify([{
2077
+ toolCallId: "stopped-elsewhere",
2078
+ status: "canceled"
2079
+ }]));
2080
+ } finally {
2081
+ stub.restore();
2082
+ }
2083
+ });
2084
+ (0, import_qunit.test)("a stop whose timestamp reads earlier than the answer still stops that answer", async function(assert) {
2085
+ let roomId = await renderAiAssistantPanel();
2086
+ let stub = stubToolValidation();
2087
+ try {
2088
+ await stopWhileStreaming(roomId, "stopped-with-skewed-clock", async () => {
2089
+ simulateRemoteMessage(roomId, "@testuser:localhost", {}, {
2090
+ type: APP_BOXEL_STOP_GENERATING_EVENT_TYPE,
2091
+ origin_server_ts: 1
2092
+ });
2093
+ });
2094
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2095
+ await settled();
2096
+ assert.strictEqual(JSON.stringify(stub.results.map(({ toolCallId, status }) => ({
2097
+ toolCallId,
2098
+ status
2099
+ }))), JSON.stringify([{
2100
+ toolCallId: "stopped-with-skewed-clock",
2101
+ status: "canceled"
2102
+ }]));
2103
+ } finally {
2104
+ stub.restore();
2105
+ }
2106
+ });
2107
+ (0, import_qunit.test)("a stop the server has not confirmed yet holds although its clock reads earlier than the prompt", async function(assert) {
2108
+ let roomId = await renderAiAssistantPanel();
2109
+ let stub = stubToolValidation();
2110
+ let releaseSend;
2111
+ let held = false;
2112
+ mockMatrixUtils.setSendEventInterceptor(async () => {
2113
+ if (held) return;
2114
+ held = true;
2115
+ await new Promise((resolve) => releaseSend = resolve);
2116
+ });
2117
+ try {
2118
+ let serverAhead = Date.now() + 3600 * 1e3;
2119
+ simulateRemoteMessage(roomId, "@testuser:localhost", {
2120
+ body: "check it",
2121
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2122
+ format: "org.matrix.custom.html"
2123
+ }, { origin_server_ts: serverAhead });
2124
+ let streamingEventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
2125
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2126
+ body: "Checking",
2127
+ format: "org.matrix.custom.html",
2128
+ isStreamingFinished: false,
2129
+ data: { context: { agentId: getService("matrix-service").agentId } }
2130
+ }, { origin_server_ts: serverAhead + 1 });
2131
+ await waitFor("[data-test-stop-generating]");
2132
+ let matrixService = getService("matrix-service");
2133
+ matrixService.sendStopGeneratingEvent(roomId);
2134
+ let roomResource = matrixService.roomResources.get(roomId);
2135
+ await waitUntil(() => roomResource.events.some((event) => event.type === "app.boxel.stopGenerating" && event.status === "sending"));
2136
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2137
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2138
+ body: "Checking correctness",
2139
+ format: "org.matrix.custom.html",
2140
+ isStreamingFinished: true,
2141
+ ...checkCorrectnessCall("stopped-while-sending"),
2142
+ "m.relates_to": {
2143
+ rel_type: "m.replace",
2144
+ event_id: streamingEventId
2145
+ }
2146
+ }, { origin_server_ts: serverAhead + 2 });
2147
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2148
+ await settled();
2149
+ assert.strictEqual(JSON.stringify(stub.results.map(({ toolCallId, status }) => ({
2150
+ toolCallId,
2151
+ status
2152
+ }))), JSON.stringify([{
2153
+ toolCallId: "stopped-while-sending",
2154
+ status: "canceled"
2155
+ }]));
2156
+ } finally {
2157
+ mockMatrixUtils.setSendEventInterceptor(void 0);
2158
+ releaseSend?.();
2159
+ stub.restore();
2160
+ }
2161
+ });
2162
+ (0, import_qunit.test)("a stop during a later tool's validation keeps the tools validated before it from starting", async function(assert) {
2163
+ let roomId = await renderAiAssistantPanel();
2164
+ let stub = stubToolValidation({ heldToolIds: ["validated-last"] });
2165
+ try {
2166
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2167
+ body: "checking correctness twice",
2168
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2169
+ format: "org.matrix.custom.html",
2170
+ isStreamingFinished: true,
2171
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
2172
+ id: "validated-first",
2173
+ name: "checkCorrectness",
2174
+ arguments: "{}"
2175
+ }, {
2176
+ id: "validated-last",
2177
+ name: "checkCorrectness",
2178
+ arguments: "{}"
2179
+ }],
2180
+ data: { context: { agentId: getService("matrix-service").agentId } }
2181
+ });
2182
+ await waitUntil(() => stub.validating.has("validated-last"), { timeout: 1e4 });
2183
+ simulateRemoteMessage(roomId, "@testuser:localhost", {}, { type: APP_BOXEL_STOP_GENERATING_EVENT_TYPE });
2184
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
2185
+ await waitUntil(() => roomResource.stopState.inForce !== void 0);
2186
+ stub.release();
2187
+ await waitUntil(() => stub.results.length === 2, { timeout: 1e4 });
2188
+ await settled();
2189
+ assert.strictEqual(JSON.stringify(stub.results.map(({ toolCallId, status }) => ({
2190
+ toolCallId,
2191
+ status
2192
+ }))), JSON.stringify([{
2193
+ toolCallId: "validated-first",
2194
+ status: "canceled"
2195
+ }, {
2196
+ toolCallId: "validated-last",
2197
+ status: "canceled"
2198
+ }]), "neither tool had started when the user stopped, so neither runs");
2199
+ } finally {
2200
+ stub.restore();
2201
+ }
2202
+ });
2203
+ (0, import_qunit.test)("Stop is not offered for a tool another of the user's clients runs", async function(assert) {
2204
+ simulateRemoteMessage(await renderAiAssistantPanel(), "@aibot:localhost", {
2205
+ body: "checking correctness",
2206
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2207
+ format: "org.matrix.custom.html",
2208
+ isStreamingFinished: true,
2209
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
2210
+ id: "other-client-tool",
2211
+ name: "checkCorrectness",
2212
+ arguments: "{}"
2213
+ }],
2214
+ data: { context: { agentId: "another-client-agent" } }
2215
+ });
2216
+ await waitFor("[data-test-accept-all]");
2217
+ assert.dom("[data-test-stop-generating]").doesNotExist("only the client that runs the tool offers Stop for it");
2218
+ assert.dom("[data-test-accept-all]").exists("this client offers the call like any other");
2219
+ });
2220
+ (0, import_qunit.test)("a message from the user after a stop lets the next tools run", async function(assert) {
2221
+ let roomId = await renderAiAssistantPanel();
2222
+ let stub = stubToolValidation();
2223
+ try {
2224
+ await stopWhileStreaming(roomId, "stopped-first", () => click("[data-test-stop-generating]"));
2225
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2226
+ simulateRemoteMessage(roomId, "@testuser:localhost", {
2227
+ body: "try again",
2228
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2229
+ format: "org.matrix.custom.html"
2230
+ });
2231
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2232
+ body: "checking correctness again",
2233
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2234
+ format: "org.matrix.custom.html",
2235
+ isStreamingFinished: true,
2236
+ ...checkCorrectnessCall("after-new-message")
2237
+ });
2238
+ await waitUntil(() => stub.results.some((r) => r.toolCallId === "after-new-message"), { timeout: 2e4 });
2239
+ await settled();
2240
+ assert.notStrictEqual(stub.results.find((r) => r.toolCallId === "after-new-message")?.status, "canceled", "the stop no longer applies after the user writes again");
2241
+ } finally {
2242
+ stub.restore();
2243
+ }
2244
+ });
2245
+ (0, import_qunit.test)("running a tool of the stopped answer by hand resumes the assistant", async function(assert) {
2246
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Person/fadhlan`);
2247
+ let stub = stubToolValidation();
2248
+ try {
2249
+ await stopWhileStreaming(roomId, "run-after-stop", () => click("[data-test-stop-generating]"), patchPersonCall("run-after-stop"));
2250
+ await waitFor("[data-test-tool-call-apply=\"ready\"]");
2251
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
2252
+ assert.ok(roomResource.stopState.inForce, "the stop is in force");
2253
+ await click("[data-test-tool-call-apply]");
2254
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2255
+ await settled();
2256
+ assert.strictEqual(JSON.stringify(stub.results), JSON.stringify([{
2257
+ toolCallId: "run-after-stop",
2258
+ status: "applied",
2259
+ resumesAssistant: true
2260
+ }]), "the result says the user asked for the call to go ahead");
2261
+ assert.notOk(roomResource.stopState.inForce, "the result lifts the stop");
2262
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2263
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2264
+ body: "Applied, now",
2265
+ format: "org.matrix.custom.html",
2266
+ isStreamingFinished: false,
2267
+ data: { context: { agentId: getService("matrix-service").agentId } }
2268
+ });
2269
+ await waitFor("[data-test-stop-generating]");
2270
+ assert.dom("[data-test-stop-generating]").exists("Stop is offered again for the answer that follows");
2271
+ } finally {
2272
+ stub.restore();
2273
+ }
2274
+ });
2275
+ (0, import_qunit.test)("approving a held call asks the assistant to go on; declining one does not", async function(assert) {
2276
+ let roomId = await renderAiAssistantPanel();
2277
+ let stub = stubToolValidation();
2278
+ try {
2279
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2280
+ body: "may I read these?",
2281
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2282
+ format: "org.matrix.custom.html",
2283
+ isStreamingFinished: true,
2284
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: ["approved-read", "declined-read"].map((id) => ({
2285
+ id,
2286
+ name: "readUrl",
2287
+ arguments: JSON.stringify({ url: `https://example.com/${id}` }),
2288
+ executedBy: AI_BOT_EXECUTOR,
2289
+ approvalRequired: true
2290
+ }))
2291
+ });
2292
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
2293
+ await waitUntil(() => roomResource.messages[0]?.tools.length === 2, { timeout: 1e4 });
2294
+ let [approved, declined] = roomResource.messages[0].tools;
2295
+ let toolService = getService("tool-service");
2296
+ await toolService.answerApproval.unlinked().perform(approved, "approve");
2297
+ await toolService.answerApproval.unlinked().perform(declined, "decline");
2298
+ await settled();
2299
+ assert.strictEqual(JSON.stringify(stub.results.map(({ toolCallId, status, resumesAssistant }) => ({
2300
+ toolCallId,
2301
+ status,
2302
+ resumesAssistant
2303
+ }))), JSON.stringify([{
2304
+ toolCallId: "approved-read",
2305
+ status: "approved",
2306
+ resumesAssistant: true
2307
+ }, {
2308
+ toolCallId: "declined-read",
2309
+ status: "invalid"
2310
+ }]));
2311
+ } finally {
2312
+ stub.restore();
2313
+ }
2314
+ });
2315
+ (0, import_qunit.test)("a canceled result that cannot be sent shows the tool as failed, not spinning", async function(assert) {
2316
+ let roomId = await renderAiAssistantPanel();
2317
+ let stub = stubToolValidation({ rejectSend: ({ status }) => status === "canceled" });
2318
+ try {
2319
+ await stopWhileStreaming(roomId, "canceled-send-fails", () => click("[data-test-stop-generating]"));
2320
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2321
+ await settled();
2322
+ assert.strictEqual(stub.results[0]?.status, "canceled");
2323
+ assert.dom("[data-test-tool-call-apply=\"failed\"]").exists("the tool offers Retry instead of a spinner");
2324
+ } finally {
2325
+ stub.restore();
2326
+ }
2327
+ });
2328
+ (0, import_qunit.test)("a tool already running when the user stops keeps its spinner until its result lands", async function(assert) {
2329
+ let roomId = await renderAiAssistantPanel();
2330
+ let toolService = getService("tool-service");
2331
+ toolService.currentlyExecutingToolRequestIds.add("already-running");
2332
+ try {
2333
+ let eventId = await stopWhileStreaming(roomId, "already-running", () => click("[data-test-stop-generating]"));
2334
+ await waitFor("[data-test-tool-call-apply=\"applying\"]");
2335
+ assert.dom("[data-test-tool-call-apply=\"canceled\"]").doesNotExist("a running tool is not shown as canceled");
2336
+ await settled();
2337
+ toolService.currentlyExecutingToolRequestIds.delete("already-running");
2338
+ simulateRemoteMessage(roomId, "@testuser:localhost", {
2339
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
2340
+ commandRequestId: "already-running",
2341
+ "m.relates_to": {
2342
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
2343
+ key: "applied",
2344
+ event_id: eventId
2345
+ }
2346
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
2347
+ await waitFor("[data-test-tool-call-apply=\"applied\"]", { timeout: 1e4 });
2348
+ assert.dom("[data-test-tool-call-apply=\"applied\"]").exists("its result still lands");
2349
+ } finally {
2350
+ toolService.currentlyExecutingToolRequestIds.delete("already-running");
2351
+ }
2352
+ });
2353
+ (0, import_qunit.test)("Stop is not offered for an answer that ended in an error", async function(assert) {
2354
+ simulateRemoteMessage(await renderAiAssistantPanel(), "@aibot:localhost", {
2355
+ body: "reading",
2356
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2357
+ format: "org.matrix.custom.html",
2358
+ isStreamingFinished: true,
2359
+ errorMessage: "The model stopped answering",
2360
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
2361
+ id: "read-that-never-ran",
2362
+ name: "readUrl",
2363
+ arguments: JSON.stringify({ url: "https://example.com" }),
2364
+ executedBy: AI_BOT_EXECUTOR
2365
+ }]
2366
+ });
2367
+ await waitFor("[data-test-message-idx=\"0\"]");
2368
+ await settled();
2369
+ assert.dom("[data-test-stop-generating]").doesNotExist("the bot never reached its call, so nothing is running");
2370
+ });
2371
+ (0, import_qunit.test)("Stop is not offered for a tool whose result could not be sent", async function(assert) {
2372
+ let roomId = await renderAiAssistantPanel();
2373
+ let stub = stubToolValidation({ held: true });
2374
+ try {
2375
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2376
+ body: "checking correctness",
2377
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2378
+ format: "org.matrix.custom.html",
2379
+ isStreamingFinished: true,
2380
+ ...checkCorrectnessCall("result-never-sent")
2381
+ });
2382
+ await waitFor("[data-test-stop-generating]");
2383
+ getService("matrix-service").failedToolState.set("result-never-sent", /* @__PURE__ */ new Error("the result could not be sent"));
2384
+ await settled();
2385
+ assert.dom("[data-test-stop-generating]").doesNotExist("no result will ever come, so nothing is running");
2386
+ } finally {
2387
+ stub.restore();
2388
+ }
2389
+ });
2390
+ (0, import_qunit.test)("a stopped answer's tool stays stopped after the user writes again", async function(assert) {
2391
+ let roomId = await renderAiAssistantPanel();
2392
+ let stub = stubToolValidation({ held: true });
2393
+ try {
2394
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2395
+ body: "checking correctness",
2396
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2397
+ format: "org.matrix.custom.html",
2398
+ isStreamingFinished: true,
2399
+ ...checkCorrectnessCall("stopped-then-written")
2400
+ });
2401
+ await waitUntil(() => stub.validating.has("stopped-then-written"), { timeout: 1e4 });
2402
+ simulateRemoteMessage(roomId, "@testuser:localhost", {}, { type: APP_BOXEL_STOP_GENERATING_EVENT_TYPE });
2403
+ simulateRemoteMessage(roomId, "@testuser:localhost", {
2404
+ body: "never mind",
2405
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2406
+ format: "org.matrix.custom.html"
2407
+ });
2408
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
2409
+ await waitUntil(() => roomResource.messages.length === 2);
2410
+ assert.notOk(roomResource.stopState.inForce, "the stop is lifted");
2411
+ stub.release();
2412
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2413
+ await settled();
2414
+ assert.strictEqual(stub.results[0]?.status, "canceled", "the tool the user stopped never runs, lifted stop or not");
2415
+ } finally {
2416
+ stub.restore();
2417
+ }
2418
+ });
2419
+ (0, import_qunit.test)("running one tool of a stopped answer by hand does not start its others", async function(assert) {
2420
+ let roomId = await renderAiAssistantPanel();
2421
+ let stub = stubToolValidation({ heldToolIds: ["left-over"] });
2422
+ try {
2423
+ let eventId = await stopWhileStreaming(roomId, "left-over", () => click("[data-test-stop-generating]"), {
2424
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [...patchPersonCall("run-by-hand")[APP_BOXEL_TOOL_REQUESTS_KEY], {
2425
+ id: "left-over",
2426
+ name: "checkCorrectness",
2427
+ arguments: "{}"
2428
+ }],
2429
+ data: { context: { agentId: getService("matrix-service").agentId } }
2430
+ });
2431
+ await waitUntil(() => stub.validating.has("left-over"), { timeout: 1e4 });
2432
+ simulateRemoteMessage(roomId, "@testuser:localhost", {
2433
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
2434
+ commandRequestId: "run-by-hand",
2435
+ resumesAssistant: true,
2436
+ "m.relates_to": {
2437
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
2438
+ key: "applied",
2439
+ event_id: eventId
2440
+ }
2441
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
2442
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
2443
+ await waitUntil(() => !roomResource.stopState.inForce);
2444
+ stub.release();
2445
+ await waitUntil(() => stub.results.length > 0, { timeout: 1e4 });
2446
+ await settled();
2447
+ assert.strictEqual(JSON.stringify(stub.results.map(({ toolCallId, status }) => ({
2448
+ toolCallId,
2449
+ status
2450
+ }))), JSON.stringify([{
2451
+ toolCallId: "left-over",
2452
+ status: "canceled"
2453
+ }]), "the user asked for one call, not the rest");
2454
+ } finally {
2455
+ stub.restore();
2456
+ }
2457
+ });
2458
+ (0, import_qunit.test)("a call's latest result and the room's last activity follow the timeline, not the order events arrived in", async function(assert) {
2459
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Person/fadhlan`);
2460
+ let now = Date.now();
2461
+ let eventId = simulateRemoteMessage(roomId, "@aibot:localhost", {
2462
+ body: "patching",
2463
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2464
+ format: "org.matrix.custom.html",
2465
+ isStreamingFinished: true,
2466
+ ...patchPersonCall("retried-patch")
2467
+ }, { origin_server_ts: now });
2468
+ let result = (key, origin_server_ts) => simulateRemoteMessage(roomId, "@testuser:localhost", {
2469
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_NO_OUTPUT_MSGTYPE,
2470
+ commandRequestId: "retried-patch",
2471
+ "m.relates_to": {
2472
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
2473
+ key,
2474
+ event_id: eventId
2475
+ }
2476
+ }, {
2477
+ type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE,
2478
+ origin_server_ts
2479
+ });
2480
+ result("applied", now + 2e3);
2481
+ await waitFor("[data-test-tool-call-apply=\"applied\"]");
2482
+ result("failed", now + 1e3);
2483
+ await settled();
2484
+ assert.dom("[data-test-tool-call-apply=\"applied\"]").exists("the later result is the outcome, whenever it arrived");
2485
+ let roomResource = getService("matrix-service").roomResources.get(roomId);
2486
+ assert.strictEqual(roomResource.lastActiveTimestamp, now + 2e3, "the room was last active at its newest event");
2487
+ });
2488
+ function simulateShowCardResult(roomId, snapshotFirstName, cardId = `${testRealmURL}Person/fadhlan`) {
2489
+ let snapshotUrl = "mxc://mock-server/fadhlan-snapshot";
2490
+ let matrixService = getService("matrix-service");
2491
+ let originalDownload = matrixService.downloadCardFileDef.bind(matrixService);
2492
+ matrixService.downloadCardFileDef = async (serializedFile) => {
2493
+ if (serializedFile.url !== snapshotUrl) return originalDownload(serializedFile);
2494
+ return { data: {
2495
+ id: cardId,
2496
+ type: "card",
2497
+ attributes: { firstName: snapshotFirstName },
2498
+ meta: { adoptsFrom: {
2499
+ module: `${testRealmURL}person`,
2500
+ name: "Person"
2501
+ } }
2502
+ } };
2503
+ };
2504
+ let commandRequestId = "show-card-request-id";
2505
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2506
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2507
+ body: "Showing the card",
2508
+ format: "org.matrix.custom.html",
2509
+ isStreamingFinished: true,
2510
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
2511
+ id: commandRequestId,
2512
+ name: "showCard",
2513
+ arguments: JSON.stringify({ attributes: { cardId } })
2514
+ }]
2515
+ });
2516
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2517
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_OUTPUT_MSGTYPE,
2518
+ commandRequestId,
2519
+ "m.relates_to": {
2520
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
2521
+ key: "applied",
2522
+ event_id: "bot-message-event-id"
2523
+ },
2524
+ data: { card: {
2525
+ url: snapshotUrl,
2526
+ sourceUrl: cardId,
2527
+ name: "Fadhlan",
2528
+ contentType: "application/vnd.card+json"
2529
+ } }
2530
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
2531
+ }
2532
+ (0, import_qunit.test)("rendering a tool result that snapshots a card already in the store leaves the live instance untouched", async function(assert) {
2533
+ let roomId = await renderAiAssistantPanel(`${testRealmURL}Person/fadhlan`);
2534
+ await waitFor("[data-test-person=\"Fadhlan\"]");
2535
+ let savedFirstNames = [];
2536
+ this.onSave((_, json) => {
2537
+ if (typeof json === "string") throw new Error("expected JSON save data");
2538
+ savedFirstNames.push(json.data.attributes?.firstName);
2539
+ });
2540
+ simulateShowCardResult(roomId, "Stale");
2541
+ await waitFor("[data-test-boxel-tool-call-result]");
2542
+ await settled();
2543
+ assert.dom("[data-test-person]").hasText("Fadhlan", "the card in the stack still shows the live data");
2544
+ let live = getService("store").peek(`${testRealmURL}Person/fadhlan`);
2545
+ assert.strictEqual(live?.firstName, "Fadhlan", "the resident instance keeps its live fields");
2546
+ assert.dom("[data-test-boxel-tool-call-result]").containsText("Fadhlan", "the tool result renders the live card");
2547
+ assert.deepEqual(savedFirstNames, [], "rendering the tool result does not save anything");
2548
+ live.firstName = "Fadhlan Updated";
2549
+ await settled();
2550
+ assert.dom("[data-test-boxel-tool-call-result]").containsText("Fadhlan Updated", "the tool result follows the resident instance");
2551
+ assert.deepEqual(savedFirstNames, ["Fadhlan Updated"], "the autosave writes the live value");
2552
+ });
2553
+ (0, import_qunit.test)("rendering a tool result that snapshots a card not yet in the store loads the live card instead of the snapshot", async function(assert) {
2554
+ let roomId = await renderAiAssistantPanel();
2555
+ this.onSave(() => {
2556
+ assert.ok(false, "rendering a tool result must not trigger a save");
2557
+ });
2558
+ simulateShowCardResult(roomId, "Stale");
2559
+ await waitFor("[data-test-boxel-tool-call-result]");
2560
+ await settled();
2561
+ let live = getService("store").peek(`${testRealmURL}Person/fadhlan`);
2562
+ assert.strictEqual(live?.firstName, "Fadhlan", "the store holds the live card, not the room snapshot");
2563
+ assert.dom("[data-test-boxel-tool-call-result]").containsText("Fadhlan", "the tool result renders the live card");
2564
+ });
2565
+ (0, import_qunit.test)("rendering a tool result whose live card no longer exists renders the snapshot without installing it under the card id", async function(assert) {
2566
+ let roomId = await renderAiAssistantPanel();
2567
+ this.onSave(() => {
2568
+ assert.ok(false, "rendering a tool result must not trigger a save");
2569
+ });
2570
+ let deletedId = `${testRealmURL}Person/deleted`;
2571
+ simulateShowCardResult(roomId, "Snapshot", deletedId);
2572
+ await waitFor("[data-test-boxel-tool-call-result]");
2573
+ await settled();
2574
+ assert.dom("[data-test-boxel-tool-call-result]").containsText("Snapshot", "the tool result falls back to rendering the snapshot");
2575
+ let store = getService("store");
2576
+ assert.false(isCardInstance(store.peek(deletedId)), "the snapshot is not installed in the store under the realm id");
2577
+ });
2578
+ function simulateToolResult(roomId, { requestId, toolName, resultDoc }) {
2579
+ let resultUrl = `mxc://mock-server/${requestId}-result`;
2580
+ let matrixService = getService("matrix-service");
2581
+ let originalDownload = matrixService.downloadCardFileDef.bind(matrixService);
2582
+ matrixService.downloadCardFileDef = async (serializedFile) => {
2583
+ if (serializedFile.url !== resultUrl) return originalDownload(serializedFile);
2584
+ return resultDoc;
2585
+ };
2586
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2587
+ msgtype: APP_BOXEL_MESSAGE_MSGTYPE,
2588
+ body: `Running ${toolName}`,
2589
+ format: "org.matrix.custom.html",
2590
+ isStreamingFinished: true,
2591
+ [APP_BOXEL_TOOL_REQUESTS_KEY]: [{
2592
+ id: requestId,
2593
+ name: toolName,
2594
+ arguments: "{}"
2595
+ }]
2596
+ });
2597
+ simulateRemoteMessage(roomId, "@aibot:localhost", {
2598
+ msgtype: APP_BOXEL_TOOL_RESULT_WITH_OUTPUT_MSGTYPE,
2599
+ commandRequestId: requestId,
2600
+ "m.relates_to": {
2601
+ rel_type: APP_BOXEL_TOOL_RESULT_REL_TYPE,
2602
+ key: "applied",
2603
+ event_id: "bot-message-event-id"
2604
+ },
2605
+ data: { card: {
2606
+ url: resultUrl,
2607
+ sourceUrl: resultUrl,
2608
+ name: `${toolName} result`,
2609
+ contentType: "application/vnd.card+json"
2610
+ } }
2611
+ }, { type: APP_BOXEL_TOOL_RESULT_EVENT_TYPE });
2612
+ }
2613
+ function baseCommandResultDoc(name, attributes) {
2614
+ return { data: {
2615
+ type: "card",
2616
+ attributes,
2617
+ meta: { adoptsFrom: {
2618
+ module: rri("@cardstack/base/command"),
2619
+ name
2620
+ } }
2621
+ } };
2622
+ }
2623
+ (0, import_qunit.test)("a result card whose type has no view of its own stays out of the chat", async function(assert) {
2624
+ simulateToolResult(await renderAiAssistantPanel(), {
2625
+ requestId: "data-only-result",
2626
+ toolName: "oneShotLLMRequest",
2627
+ resultDoc: baseCommandResultDoc("OneShotLLMRequestResult", { output: "a reply for the model" })
2628
+ });
2629
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-apply-state]");
2630
+ await settled();
2631
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists("the tool row shows the call as applied");
2632
+ assert.dom("[data-test-tool-result-container]").doesNotExist("the data-only result card is not rendered");
2633
+ });
2634
+ (0, import_qunit.test)("a result card whose type has its own embedded view is shown", async function(assert) {
2635
+ simulateToolResult(await renderAiAssistantPanel(), {
2636
+ requestId: "patch-fields-result",
2637
+ toolName: "patchFields",
2638
+ resultDoc: baseCommandResultDoc("PatchFieldsOutput", {
2639
+ success: true,
2640
+ updatedFields: ["firstName"],
2641
+ errors: {}
2642
+ })
2643
+ });
2644
+ await waitFor("[data-test-tool-result-container]");
2645
+ assert.dom("[data-test-tool-result-header] [data-test-boxel-card-header-title]").containsText("Patch Fields Result");
2646
+ assert.dom("[data-test-boxel-tool-call-result]").containsText("Updated 1 field: firstName.");
2647
+ });
2648
+ (0, import_qunit.test)("a failed correctness check shows its failed state without a result card", async function(assert) {
2649
+ simulateToolResult(await renderAiAssistantPanel(), {
2650
+ requestId: "failed-correctness-check",
2651
+ toolName: "checkCorrectness",
2652
+ resultDoc: baseCommandResultDoc("CorrectnessResultCard", {
2653
+ correct: false,
2654
+ errors: ["The card does not render"],
2655
+ warnings: []
2656
+ })
2657
+ });
2658
+ await waitFor("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied-with-error\"]");
2659
+ assert.dom("[data-test-message-idx=\"0\"] .room-message-tool.is-failed").exists("the tool row shows the failed check");
2660
+ assert.dom("[data-test-tool-result-container]").doesNotExist("the correctness result card is not rendered");
2661
+ });
2662
+ (0, import_qunit.test)("a view-visually result shows the image the assistant looked at", async function(assert) {
2663
+ let roomId = await renderAiAssistantPanel();
2664
+ let imageUrl = new URL("/_matrix/client/v1/media/download/localhost/brand-guide-capture", config.matrixURL).href;
2665
+ let pngBytes = Uint8Array.from(atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="), (c) => c.charCodeAt(0));
2666
+ mockMatrixUtils.getUploadedContents().set(imageUrl, pngBytes.buffer);
2667
+ simulateToolResult(roomId, {
2668
+ requestId: "view-visually-result",
2669
+ toolName: "view-visually",
2670
+ resultDoc: baseCommandResultDoc("ViewVisuallyResult", {
2671
+ sourceUrl: `${testRealmURL}brand-guide.html`,
2672
+ kind: "file",
2673
+ format: "isolated",
2674
+ attachedImages: [{
2675
+ name: "brand-guide.html (isolated).png",
2676
+ url: imageUrl,
2677
+ contentType: "image/png"
2678
+ }]
2679
+ })
2680
+ });
2681
+ await waitFor("[data-test-view-visually-image][src^=\"blob:\"]");
2682
+ assert.dom("[data-test-view-visually-title]").hasText("View of brand-guide.html");
2683
+ assert.dom("[data-test-boxel-tool-call-result]").containsText(`${testRealmURL}brand-guide.html`);
2684
+ let image = find("[data-test-view-visually-image]");
2685
+ await image.decode();
2686
+ assert.strictEqual(image.naturalWidth, 1, "the image loads from the room media downloaded with the session");
2687
+ });
2688
+ (0, import_qunit.test)("room media is loaded with the Matrix session only from the homeserver", async function(assert) {
2689
+ let matrixService = getService("matrix-service");
2690
+ let elsewhere = "https://elsewhere.example/_matrix/client/v1/media/download/x/y";
2691
+ assert.strictEqual(await matrixService.loadRoomMedia(elsewhere), elsewhere, "a URL on another origin comes back unchanged, without a download");
2692
+ let realmFile = `${testRealmURL}brand-guide.png`;
2693
+ assert.strictEqual(await matrixService.loadRoomMedia(realmFile), realmFile, "a URL that is not room media comes back unchanged");
2694
+ let homeserverApi = new URL("/_matrix/client/v3/sync", config.matrixURL).href;
2695
+ assert.strictEqual(await matrixService.loadRoomMedia(homeserverApi), homeserverApi, "a homeserver URL outside its media downloads comes back unchanged");
2696
+ });
2697
+ (0, import_qunit.test)("a run-realm-code result lists the files it saved and the captures it took", async function(assert) {
2698
+ let roomId = await renderAiAssistantPanel();
2699
+ let captureUrl = new URL("/_matrix/client/v1/media/download/localhost/run-capture", config.matrixURL).href;
2700
+ let pngBytes = Uint8Array.from(atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="), (c) => c.charCodeAt(0));
2701
+ mockMatrixUtils.getUploadedContents().set(captureUrl, pngBytes.buffer);
2702
+ let savedFile = `${testRealmURL}brand-guide.html`;
2703
+ simulateToolResult(roomId, {
2704
+ requestId: "run-realm-code-result",
2705
+ toolName: "run-realm-code",
2706
+ resultDoc: baseCommandResultDoc("RunRealmCodeResult", {
2707
+ files: [{
2708
+ fileUrl: savedFile,
2709
+ status: "saved"
2710
+ }],
2711
+ scriptResult: "done",
2712
+ captures: [{
2713
+ name: "brand-guide.html (isolated).png",
2714
+ url: captureUrl,
2715
+ contentType: "image/png"
2716
+ }]
2717
+ })
2718
+ });
2719
+ await waitFor("[data-test-realm-code-capture][src^=\"blob:\"]");
2720
+ assert.dom(`[data-test-realm-code-file="${savedFile}"]`).containsText("saved", "the saved file is listed with its status");
2721
+ assert.dom("[data-test-boxel-tool-call-result]").doesNotContainText("done", "the script's own result stays out of the chat");
2722
+ });
2723
+ (0, import_qunit.test)("a run-realm-code result says why it could not show a card", async function(assert) {
2724
+ simulateToolResult(await renderAiAssistantPanel(), {
2725
+ requestId: "run-realm-code-not-shown",
2726
+ toolName: "run-realm-code",
2727
+ resultDoc: baseCommandResultDoc("RunRealmCodeResult", {
2728
+ files: [],
2729
+ scriptResult: JSON.stringify({ show: "images/red.png" }),
2730
+ captures: [],
2731
+ showError: "The card was not shown. images/red.png is a file"
2732
+ })
2733
+ });
2734
+ await waitFor("[data-test-realm-code-show-error]");
2735
+ assert.dom("[data-test-realm-code-show-error]").containsText("The card was not shown", "the reason is shown");
2736
+ });
2737
+ (0, import_qunit.test)("a run-realm-code result lists its failed UI actions only", async function(assert) {
2738
+ simulateToolResult(await renderAiAssistantPanel(), {
2739
+ requestId: "run-realm-code-ui-actions",
2740
+ toolName: "run-realm-code",
2741
+ resultDoc: baseCommandResultDoc("RunRealmCodeResult", {
2742
+ files: [],
2743
+ scriptResult: "",
2744
+ captures: [],
2745
+ uiActions: [{
2746
+ action: "openFile",
2747
+ target: `${testRealmURL}pet.gts`,
2748
+ status: "done"
2749
+ }, {
2750
+ action: "previewFormat",
2751
+ target: `${testRealmURL}Pet/mango (fitted)`,
2752
+ status: "failed",
2753
+ detail: "Card not found"
2754
+ }]
2755
+ })
2756
+ });
2757
+ await waitFor("[data-test-realm-code-ui-action=\"previewFormat\"]");
2758
+ assert.dom("[data-test-realm-code-ui-action=\"openFile\"]").doesNotExist("a done action is not listed");
2759
+ assert.dom("[data-test-realm-code-ui-action=\"previewFormat\"]").containsText("Card not found", "a failed action says why");
2760
+ });
2761
+ (0, import_qunit.test)("a run-realm-code result lists the workspaces it created and deleted", async function(assert) {
2762
+ let roomId = await renderAiAssistantPanel();
2763
+ let created = "http://test-realm/new-workspace/";
2764
+ let deleted = "http://test-realm/old-workspace/";
2765
+ simulateToolResult(roomId, {
2766
+ requestId: "run-realm-code-workspaces",
2767
+ toolName: "run-realm-code",
2768
+ resultDoc: baseCommandResultDoc("RunRealmCodeResult", {
2769
+ files: [],
2770
+ scriptResult: "",
2771
+ captures: [],
2772
+ createdWorkspaces: [created],
2773
+ deletedWorkspaces: [deleted]
2774
+ })
2775
+ });
2776
+ await waitFor("[data-test-realm-code-created-workspace]");
2777
+ assert.dom("[data-test-realm-code-created-workspace]").containsText(created, "the created workspace is listed");
2778
+ assert.dom("[data-test-realm-code-deleted-workspace]").containsText(deleted, "the deleted workspace is listed");
2779
+ });
2780
+ (0, import_qunit.test)("a run-realm-code result that wrote nothing and had no failure stays out of the chat", async function(assert) {
2781
+ let roomId = await renderAiAssistantPanel();
2782
+ let store = getService("store");
2783
+ let addWithoutPersisting = store.addWithoutPersisting.bind(store);
2784
+ let resultCardMade = new Promise((resolve) => {
2785
+ store.addWithoutPersisting = async (...args) => {
2786
+ let card = await addWithoutPersisting(...args);
2787
+ resolve();
2788
+ return card;
2789
+ };
2790
+ });
2791
+ simulateToolResult(roomId, {
2792
+ requestId: "run-realm-code-read-only",
2793
+ toolName: "run-realm-code",
2794
+ resultDoc: baseCommandResultDoc("RunRealmCodeResult", {
2795
+ files: [],
2796
+ scriptResult: JSON.stringify({ show: "Pet/mango" }),
2797
+ captures: [{
2798
+ name: "pet.gts (isolated).png",
2799
+ url: new URL("/_matrix/client/v1/media/download/localhost/read-only-capture", config.matrixURL).href,
2800
+ contentType: "image/png"
2801
+ }],
2802
+ shownCard: `${testRealmURL}Pet/mango`,
2803
+ uiActions: [{
2804
+ action: "switchSubmode",
2805
+ target: "code",
2806
+ status: "done"
2807
+ }, {
2808
+ action: "openFile",
2809
+ target: `${testRealmURL}pet.gts`,
2810
+ status: "done"
2811
+ }]
2812
+ })
2813
+ });
2814
+ await resultCardMade;
2815
+ await settled();
2816
+ assert.dom("[data-test-message-idx=\"0\"] [data-test-apply-state=\"applied\"]").exists("the tool row shows the call as applied");
2817
+ assert.dom("[data-test-tool-result-container]").doesNotExist("a run that only read, captured, and opened things has no result card");
2818
+ });
2819
+ });
2820
+ //#endregion