@artooi/agents-web-components 0.0.0-stage → 0.1.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 (543) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/LICENSE +21 -0
  3. package/README.md +4397 -2
  4. package/dist/agents-web-components.bundle.js +5708 -0
  5. package/dist/agents-web-components.bundle.js.map +7 -0
  6. package/dist/bundle.d.ts +3 -0
  7. package/dist/bundle.d.ts.map +1 -0
  8. package/dist/chat.d.ts +3 -0
  9. package/dist/chat.d.ts.map +1 -0
  10. package/dist/chat.js +16373 -0
  11. package/dist/chat.js.map +7 -0
  12. package/dist/chunk-ARNLFGCC.js +7715 -0
  13. package/dist/chunk-ARNLFGCC.js.map +7 -0
  14. package/dist/constants.d.ts +575 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/core/activity_registration.d.ts +19 -0
  17. package/dist/core/activity_registration.d.ts.map +1 -0
  18. package/dist/core/activity_registry.d.ts +46 -0
  19. package/dist/core/activity_registry.d.ts.map +1 -0
  20. package/dist/core/activity_renderer.d.ts +20 -0
  21. package/dist/core/activity_renderer.d.ts.map +1 -0
  22. package/dist/core/ag_ui_chat.d.ts +836 -0
  23. package/dist/core/ag_ui_chat.d.ts.map +1 -0
  24. package/dist/core/agui_client.d.ts +370 -0
  25. package/dist/core/agui_client.d.ts.map +1 -0
  26. package/dist/core/attachment.d.ts +42 -0
  27. package/dist/core/attachment.d.ts.map +1 -0
  28. package/dist/core/chat_registry.d.ts +23 -0
  29. package/dist/core/chat_registry.d.ts.map +1 -0
  30. package/dist/core/client_seed.d.ts +27 -0
  31. package/dist/core/client_seed.d.ts.map +1 -0
  32. package/dist/core/conversation_store.d.ts +195 -0
  33. package/dist/core/conversation_store.d.ts.map +1 -0
  34. package/dist/core/create_http_agent.d.ts +57 -0
  35. package/dist/core/create_http_agent.d.ts.map +1 -0
  36. package/dist/core/define_chat.d.ts +13 -0
  37. package/dist/core/define_chat.d.ts.map +1 -0
  38. package/dist/core/events/attachments_detail.d.ts +9 -0
  39. package/dist/core/events/attachments_detail.d.ts.map +1 -0
  40. package/dist/core/events/bar_height_detail.d.ts +6 -0
  41. package/dist/core/events/bar_height_detail.d.ts.map +1 -0
  42. package/dist/core/events/custom_agent_detail.d.ts +8 -0
  43. package/dist/core/events/custom_agent_detail.d.ts.map +1 -0
  44. package/dist/core/events/dock_width_detail.d.ts +8 -0
  45. package/dist/core/events/dock_width_detail.d.ts.map +1 -0
  46. package/dist/core/events/feedback_detail.d.ts +28 -0
  47. package/dist/core/events/feedback_detail.d.ts.map +1 -0
  48. package/dist/core/events/invalidate_detail.d.ts +16 -0
  49. package/dist/core/events/invalidate_detail.d.ts.map +1 -0
  50. package/dist/core/events/maximize_detail.d.ts +5 -0
  51. package/dist/core/events/maximize_detail.d.ts.map +1 -0
  52. package/dist/core/events/run_finished_detail.d.ts +36 -0
  53. package/dist/core/events/run_finished_detail.d.ts.map +1 -0
  54. package/dist/core/events/state_detail.d.ts +5 -0
  55. package/dist/core/events/state_detail.d.ts.map +1 -0
  56. package/dist/core/events/submit_detail.d.ts +8 -0
  57. package/dist/core/events/submit_detail.d.ts.map +1 -0
  58. package/dist/core/events/thread_detail.d.ts +27 -0
  59. package/dist/core/events/thread_detail.d.ts.map +1 -0
  60. package/dist/core/events/thread_title_detail.d.ts +8 -0
  61. package/dist/core/events/thread_title_detail.d.ts.map +1 -0
  62. package/dist/core/events/toggle_detail.d.ts +5 -0
  63. package/dist/core/events/toggle_detail.d.ts.map +1 -0
  64. package/dist/core/events/tool_run.d.ts +11 -0
  65. package/dist/core/events/tool_run.d.ts.map +1 -0
  66. package/dist/core/events/unread_detail.d.ts +11 -0
  67. package/dist/core/events/unread_detail.d.ts.map +1 -0
  68. package/dist/core/message_role.d.ts +4 -0
  69. package/dist/core/message_role.d.ts.map +1 -0
  70. package/dist/core/read_flag.d.ts +11 -0
  71. package/dist/core/read_flag.d.ts.map +1 -0
  72. package/dist/core/read_json_attribute.d.ts +15 -0
  73. package/dist/core/read_json_attribute.d.ts.map +1 -0
  74. package/dist/core/read_max_tool_rounds.d.ts +9 -0
  75. package/dist/core/read_max_tool_rounds.d.ts.map +1 -0
  76. package/dist/core/remote_conversation_store.d.ts +71 -0
  77. package/dist/core/remote_conversation_store.d.ts.map +1 -0
  78. package/dist/core/run_handlers.d.ts +85 -0
  79. package/dist/core/run_handlers.d.ts.map +1 -0
  80. package/dist/core/run_index.d.ts +58 -0
  81. package/dist/core/run_index.d.ts.map +1 -0
  82. package/dist/core/storage_scope.d.ts +118 -0
  83. package/dist/core/storage_scope.d.ts.map +1 -0
  84. package/dist/core/tool_outcome.d.ts +27 -0
  85. package/dist/core/tool_outcome.d.ts.map +1 -0
  86. package/dist/core/transcribe_audio.d.ts +32 -0
  87. package/dist/core/transcribe_audio.d.ts.map +1 -0
  88. package/dist/core/upload_attachment.d.ts +44 -0
  89. package/dist/core/upload_attachment.d.ts.map +1 -0
  90. package/dist/core/utils.d.ts +117 -0
  91. package/dist/core/utils.d.ts.map +1 -0
  92. package/dist/dom/animations.d.ts +122 -0
  93. package/dist/dom/animations.d.ts.map +1 -0
  94. package/dist/dom/dom_driver.d.ts +28 -0
  95. package/dist/dom/dom_driver.d.ts.map +1 -0
  96. package/dist/dom/highlight_overlay.d.ts +39 -0
  97. package/dist/dom/highlight_overlay.d.ts.map +1 -0
  98. package/dist/dom/native_setter.d.ts +5 -0
  99. package/dist/dom/native_setter.d.ts.map +1 -0
  100. package/dist/dom/ring_color.d.ts +16 -0
  101. package/dist/dom/ring_color.d.ts.map +1 -0
  102. package/dist/dom/utils.d.ts +3 -0
  103. package/dist/dom/utils.d.ts.map +1 -0
  104. package/dist/index.d.ts +62 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +223 -0
  107. package/dist/index.js.map +7 -0
  108. package/dist/skills/fill_template.d.ts +16 -0
  109. package/dist/skills/fill_template.d.ts.map +1 -0
  110. package/dist/skills/parse_skills.d.ts +8 -0
  111. package/dist/skills/parse_skills.d.ts.map +1 -0
  112. package/dist/skills/skill.d.ts +33 -0
  113. package/dist/skills/skill.d.ts.map +1 -0
  114. package/dist/skills/skill_catalog.d.ts +69 -0
  115. package/dist/skills/skill_catalog.d.ts.map +1 -0
  116. package/dist/skills/skill_name_from.d.ts +12 -0
  117. package/dist/skills/skill_name_from.d.ts.map +1 -0
  118. package/dist/tools/chat_surface_tools.d.ts +77 -0
  119. package/dist/tools/chat_surface_tools.d.ts.map +1 -0
  120. package/dist/tools/client_tool_registry.d.ts +58 -0
  121. package/dist/tools/client_tool_registry.d.ts.map +1 -0
  122. package/dist/tools/is_destructive.d.ts +14 -0
  123. package/dist/tools/is_destructive.d.ts.map +1 -0
  124. package/dist/tools/is_navigates.d.ts +9 -0
  125. package/dist/tools/is_navigates.d.ts.map +1 -0
  126. package/dist/tools/page_action_tools.d.ts +30 -0
  127. package/dist/tools/page_action_tools.d.ts.map +1 -0
  128. package/dist/tools/page_map.d.ts +16 -0
  129. package/dist/tools/page_map.d.ts.map +1 -0
  130. package/dist/tools/page_state.d.ts +27 -0
  131. package/dist/tools/page_state.d.ts.map +1 -0
  132. package/dist/tools/parse_tool_catalog.d.ts +21 -0
  133. package/dist/tools/parse_tool_catalog.d.ts.map +1 -0
  134. package/dist/tools/route_map.d.ts +37 -0
  135. package/dist/tools/route_map.d.ts.map +1 -0
  136. package/dist/tools/tool_catalog.d.ts +86 -0
  137. package/dist/tools/tool_catalog.d.ts.map +1 -0
  138. package/dist/tools/tool_dispatch.d.ts +82 -0
  139. package/dist/tools/tool_dispatch.d.ts.map +1 -0
  140. package/dist/ui/charts/chart_block.d.ts +57 -0
  141. package/dist/ui/charts/chart_block.d.ts.map +1 -0
  142. package/dist/ui/charts/chart_spec_from.d.ts +12 -0
  143. package/dist/ui/charts/chart_spec_from.d.ts.map +1 -0
  144. package/dist/ui/charts/chart_styles.d.ts +2 -0
  145. package/dist/ui/charts/chart_styles.d.ts.map +1 -0
  146. package/dist/ui/charts/chart_tool.d.ts +15 -0
  147. package/dist/ui/charts/chart_tool.d.ts.map +1 -0
  148. package/dist/ui/composer/attachment_styles.d.ts +2 -0
  149. package/dist/ui/composer/attachment_styles.d.ts.map +1 -0
  150. package/dist/ui/composer/attachment_tray.d.ts +53 -0
  151. package/dist/ui/composer/attachment_tray.d.ts.map +1 -0
  152. package/dist/ui/composer/auto_grow.d.ts +10 -0
  153. package/dist/ui/composer/auto_grow.d.ts.map +1 -0
  154. package/dist/ui/composer/build_composer.d.ts +32 -0
  155. package/dist/ui/composer/build_composer.d.ts.map +1 -0
  156. package/dist/ui/composer/composer_attachments.d.ts +57 -0
  157. package/dist/ui/composer/composer_attachments.d.ts.map +1 -0
  158. package/dist/ui/composer/composer_styles.d.ts +2 -0
  159. package/dist/ui/composer/composer_styles.d.ts.map +1 -0
  160. package/dist/ui/composer/composer_voice.d.ts +48 -0
  161. package/dist/ui/composer/composer_voice.d.ts.map +1 -0
  162. package/dist/ui/composer/skill_styles.d.ts +2 -0
  163. package/dist/ui/composer/skill_styles.d.ts.map +1 -0
  164. package/dist/ui/composer/skills_menu.d.ts +34 -0
  165. package/dist/ui/composer/skills_menu.d.ts.map +1 -0
  166. package/dist/ui/composer/voice_input.d.ts +46 -0
  167. package/dist/ui/composer/voice_input.d.ts.map +1 -0
  168. package/dist/ui/excerpts/attach_copy_buttons.d.ts +13 -0
  169. package/dist/ui/excerpts/attach_copy_buttons.d.ts.map +1 -0
  170. package/dist/ui/excerpts/copy_payload.d.ts +30 -0
  171. package/dist/ui/excerpts/copy_payload.d.ts.map +1 -0
  172. package/dist/ui/excerpts/page_quote_offer.d.ts +33 -0
  173. package/dist/ui/excerpts/page_quote_offer.d.ts.map +1 -0
  174. package/dist/ui/excerpts/place_offer.d.ts +9 -0
  175. package/dist/ui/excerpts/place_offer.d.ts.map +1 -0
  176. package/dist/ui/excerpts/quote_selection.d.ts +66 -0
  177. package/dist/ui/excerpts/quote_selection.d.ts.map +1 -0
  178. package/dist/ui/excerpts/transcript_quote_offer.d.ts +57 -0
  179. package/dist/ui/excerpts/transcript_quote_offer.d.ts.map +1 -0
  180. package/dist/ui/fill_ui_string.d.ts +32 -0
  181. package/dist/ui/fill_ui_string.d.ts.map +1 -0
  182. package/dist/ui/history/checkpoint_menu.d.ts +41 -0
  183. package/dist/ui/history/checkpoint_menu.d.ts.map +1 -0
  184. package/dist/ui/history/conversation_history.d.ts +317 -0
  185. package/dist/ui/history/conversation_history.d.ts.map +1 -0
  186. package/dist/ui/history/history_styles.d.ts +2 -0
  187. package/dist/ui/history/history_styles.d.ts.map +1 -0
  188. package/dist/ui/history/relative_time.d.ts +23 -0
  189. package/dist/ui/history/relative_time.d.ts.map +1 -0
  190. package/dist/ui/history/thread_drawer.d.ts +64 -0
  191. package/dist/ui/history/thread_drawer.d.ts.map +1 -0
  192. package/dist/ui/history/utils.d.ts +2 -0
  193. package/dist/ui/history/utils.d.ts.map +1 -0
  194. package/dist/ui/interrupts/approval_card.d.ts +64 -0
  195. package/dist/ui/interrupts/approval_card.d.ts.map +1 -0
  196. package/dist/ui/interrupts/approval_styles.d.ts +2 -0
  197. package/dist/ui/interrupts/approval_styles.d.ts.map +1 -0
  198. package/dist/ui/interrupts/confirmation_card.d.ts +51 -0
  199. package/dist/ui/interrupts/confirmation_card.d.ts.map +1 -0
  200. package/dist/ui/interrupts/confirmation_styles.d.ts +2 -0
  201. package/dist/ui/interrupts/confirmation_styles.d.ts.map +1 -0
  202. package/dist/ui/interrupts/pending_decision.d.ts +22 -0
  203. package/dist/ui/interrupts/pending_decision.d.ts.map +1 -0
  204. package/dist/ui/interrupts/question_card.d.ts +49 -0
  205. package/dist/ui/interrupts/question_card.d.ts.map +1 -0
  206. package/dist/ui/interrupts/question_styles.d.ts +2 -0
  207. package/dist/ui/interrupts/question_styles.d.ts.map +1 -0
  208. package/dist/ui/place/place.d.ts +17 -0
  209. package/dist/ui/place/place.d.ts.map +1 -0
  210. package/dist/ui/place/place_chip.d.ts +26 -0
  211. package/dist/ui/place/place_chip.d.ts.map +1 -0
  212. package/dist/ui/place/place_from_route.d.ts +9 -0
  213. package/dist/ui/place/place_from_route.d.ts.map +1 -0
  214. package/dist/ui/place/place_styles.d.ts +2 -0
  215. package/dist/ui/place/place_styles.d.ts.map +1 -0
  216. package/dist/ui/placement/clamp_launcher.d.ts +20 -0
  217. package/dist/ui/placement/clamp_launcher.d.ts.map +1 -0
  218. package/dist/ui/placement/clamp_panel.d.ts +13 -0
  219. package/dist/ui/placement/clamp_panel.d.ts.map +1 -0
  220. package/dist/ui/placement/collapse_styles.d.ts +2 -0
  221. package/dist/ui/placement/collapse_styles.d.ts.map +1 -0
  222. package/dist/ui/placement/dock_styles.d.ts +2 -0
  223. package/dist/ui/placement/dock_styles.d.ts.map +1 -0
  224. package/dist/ui/placement/embedded_styles.d.ts +2 -0
  225. package/dist/ui/placement/embedded_styles.d.ts.map +1 -0
  226. package/dist/ui/placement/launcher_drag.d.ts +49 -0
  227. package/dist/ui/placement/launcher_drag.d.ts.map +1 -0
  228. package/dist/ui/placement/launcher_placement.d.ts +77 -0
  229. package/dist/ui/placement/launcher_placement.d.ts.map +1 -0
  230. package/dist/ui/placement/launcher_styles.d.ts +2 -0
  231. package/dist/ui/placement/launcher_styles.d.ts.map +1 -0
  232. package/dist/ui/placement/page_styles.d.ts +2 -0
  233. package/dist/ui/placement/page_styles.d.ts.map +1 -0
  234. package/dist/ui/placement/panel_drag.d.ts +40 -0
  235. package/dist/ui/placement/panel_drag.d.ts.map +1 -0
  236. package/dist/ui/placement/panel_placement.d.ts +173 -0
  237. package/dist/ui/placement/panel_placement.d.ts.map +1 -0
  238. package/dist/ui/placement/place_widget.d.ts +31 -0
  239. package/dist/ui/placement/place_widget.d.ts.map +1 -0
  240. package/dist/ui/placement/preset_styles.d.ts +2 -0
  241. package/dist/ui/placement/preset_styles.d.ts.map +1 -0
  242. package/dist/ui/placement/resize_handle.d.ts +78 -0
  243. package/dist/ui/placement/resize_handle.d.ts.map +1 -0
  244. package/dist/ui/placement/resize_styles.d.ts +2 -0
  245. package/dist/ui/placement/resize_styles.d.ts.map +1 -0
  246. package/dist/ui/placement/sidebar_styles.d.ts +2 -0
  247. package/dist/ui/placement/sidebar_styles.d.ts.map +1 -0
  248. package/dist/ui/placement/small_viewport_styles.d.ts +2 -0
  249. package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -0
  250. package/dist/ui/placement/surface_for.d.ts +93 -0
  251. package/dist/ui/placement/surface_for.d.ts.map +1 -0
  252. package/dist/ui/progress/prettify_tool_name.d.ts +11 -0
  253. package/dist/ui/progress/prettify_tool_name.d.ts.map +1 -0
  254. package/dist/ui/progress/run_announcer.d.ts +41 -0
  255. package/dist/ui/progress/run_announcer.d.ts.map +1 -0
  256. package/dist/ui/progress/run_notice.d.ts +21 -0
  257. package/dist/ui/progress/run_notice.d.ts.map +1 -0
  258. package/dist/ui/progress/run_notice_styles.d.ts +2 -0
  259. package/dist/ui/progress/run_notice_styles.d.ts.map +1 -0
  260. package/dist/ui/progress/subagent_panel.d.ts +101 -0
  261. package/dist/ui/progress/subagent_panel.d.ts.map +1 -0
  262. package/dist/ui/progress/subagent_progress.d.ts +57 -0
  263. package/dist/ui/progress/subagent_progress.d.ts.map +1 -0
  264. package/dist/ui/progress/subagent_update.d.ts +28 -0
  265. package/dist/ui/progress/subagent_update.d.ts.map +1 -0
  266. package/dist/ui/progress/thoughts_block.d.ts +57 -0
  267. package/dist/ui/progress/thoughts_block.d.ts.map +1 -0
  268. package/dist/ui/progress/thoughts_styles.d.ts +2 -0
  269. package/dist/ui/progress/thoughts_styles.d.ts.map +1 -0
  270. package/dist/ui/progress/tool_call_card.d.ts +167 -0
  271. package/dist/ui/progress/tool_call_card.d.ts.map +1 -0
  272. package/dist/ui/progress/tool_group_styles.d.ts +2 -0
  273. package/dist/ui/progress/tool_group_styles.d.ts.map +1 -0
  274. package/dist/ui/progress/tool_step_group.d.ts +50 -0
  275. package/dist/ui/progress/tool_step_group.d.ts.map +1 -0
  276. package/dist/ui/progress/tool_step_styles.d.ts +2 -0
  277. package/dist/ui/progress/tool_step_styles.d.ts.map +1 -0
  278. package/dist/ui/shell/adopt_styles.d.ts +28 -0
  279. package/dist/ui/shell/adopt_styles.d.ts.map +1 -0
  280. package/dist/ui/shell/build_header.d.ts +45 -0
  281. package/dist/ui/shell/build_header.d.ts.map +1 -0
  282. package/dist/ui/shell/build_launcher.d.ts +33 -0
  283. package/dist/ui/shell/build_launcher.d.ts.map +1 -0
  284. package/dist/ui/shell/collapse_glyph.d.ts +14 -0
  285. package/dist/ui/shell/collapse_glyph.d.ts.map +1 -0
  286. package/dist/ui/shell/frame_styles.d.ts +2 -0
  287. package/dist/ui/shell/frame_styles.d.ts.map +1 -0
  288. package/dist/ui/shell/glyph_slot.d.ts +7 -0
  289. package/dist/ui/shell/glyph_slot.d.ts.map +1 -0
  290. package/dist/ui/shell/header_button.d.ts +11 -0
  291. package/dist/ui/shell/header_button.d.ts.map +1 -0
  292. package/dist/ui/shell/icon_element.d.ts +12 -0
  293. package/dist/ui/shell/icon_element.d.ts.map +1 -0
  294. package/dist/ui/shell/is_unread_badge_enabled.d.ts +10 -0
  295. package/dist/ui/shell/is_unread_badge_enabled.d.ts.map +1 -0
  296. package/dist/ui/shell/read_launcher_icon_url.d.ts +8 -0
  297. package/dist/ui/shell/read_launcher_icon_url.d.ts.map +1 -0
  298. package/dist/ui/shell/theme_styles.d.ts +2 -0
  299. package/dist/ui/shell/theme_styles.d.ts.map +1 -0
  300. package/dist/ui/shell/token_styles.d.ts +2 -0
  301. package/dist/ui/shell/token_styles.d.ts.map +1 -0
  302. package/dist/ui/styles.d.ts +2 -0
  303. package/dist/ui/styles.d.ts.map +1 -0
  304. package/dist/ui/themes/classic_styles.d.ts +2 -0
  305. package/dist/ui/themes/classic_styles.d.ts.map +1 -0
  306. package/dist/ui/themes/classic_tokens.d.ts +2 -0
  307. package/dist/ui/themes/classic_tokens.d.ts.map +1 -0
  308. package/dist/ui/themes/code_tokens.d.ts +2 -0
  309. package/dist/ui/themes/code_tokens.d.ts.map +1 -0
  310. package/dist/ui/themes/ledger_styles.d.ts +2 -0
  311. package/dist/ui/themes/ledger_styles.d.ts.map +1 -0
  312. package/dist/ui/themes/ledger_tokens.d.ts +2 -0
  313. package/dist/ui/themes/ledger_tokens.d.ts.map +1 -0
  314. package/dist/ui/themes/modern_styles.d.ts +2 -0
  315. package/dist/ui/themes/modern_styles.d.ts.map +1 -0
  316. package/dist/ui/themes/quiet_styles.d.ts +2 -0
  317. package/dist/ui/themes/quiet_styles.d.ts.map +1 -0
  318. package/dist/ui/themes/scheme_styles.d.ts +2 -0
  319. package/dist/ui/themes/scheme_styles.d.ts.map +1 -0
  320. package/dist/ui/themes/soft_styles.d.ts +2 -0
  321. package/dist/ui/themes/soft_styles.d.ts.map +1 -0
  322. package/dist/ui/themes/soft_tokens.d.ts +2 -0
  323. package/dist/ui/themes/soft_tokens.d.ts.map +1 -0
  324. package/dist/ui/themes/theme_hosts.d.ts +15 -0
  325. package/dist/ui/themes/theme_hosts.d.ts.map +1 -0
  326. package/dist/ui/transcript/answer_actions.d.ts +50 -0
  327. package/dist/ui/transcript/answer_actions.d.ts.map +1 -0
  328. package/dist/ui/transcript/answer_stream.d.ts +56 -0
  329. package/dist/ui/transcript/answer_stream.d.ts.map +1 -0
  330. package/dist/ui/transcript/attachment_chip_styles.d.ts +2 -0
  331. package/dist/ui/transcript/attachment_chip_styles.d.ts.map +1 -0
  332. package/dist/ui/transcript/attachment_chips.d.ts +21 -0
  333. package/dist/ui/transcript/attachment_chips.d.ts.map +1 -0
  334. package/dist/ui/transcript/build_transcript.d.ts +21 -0
  335. package/dist/ui/transcript/build_transcript.d.ts.map +1 -0
  336. package/dist/ui/transcript/greeting_styles.d.ts +2 -0
  337. package/dist/ui/transcript/greeting_styles.d.ts.map +1 -0
  338. package/dist/ui/transcript/groups_tool_steps.d.ts +13 -0
  339. package/dist/ui/transcript/groups_tool_steps.d.ts.map +1 -0
  340. package/dist/ui/transcript/message_action_styles.d.ts +2 -0
  341. package/dist/ui/transcript/message_action_styles.d.ts.map +1 -0
  342. package/dist/ui/transcript/message_actions.d.ts +74 -0
  343. package/dist/ui/transcript/message_actions.d.ts.map +1 -0
  344. package/dist/ui/transcript/message_styles.d.ts +2 -0
  345. package/dist/ui/transcript/message_styles.d.ts.map +1 -0
  346. package/dist/ui/transcript/render_markdown.d.ts +40 -0
  347. package/dist/ui/transcript/render_markdown.d.ts.map +1 -0
  348. package/dist/ui/transcript/render_or_warn.d.ts +16 -0
  349. package/dist/ui/transcript/render_or_warn.d.ts.map +1 -0
  350. package/dist/ui/transcript/reveal_words.d.ts +8 -0
  351. package/dist/ui/transcript/reveal_words.d.ts.map +1 -0
  352. package/dist/ui/transcript/starter_chips.d.ts +21 -0
  353. package/dist/ui/transcript/starter_chips.d.ts.map +1 -0
  354. package/dist/ui/transcript/stick_to_bottom.d.ts +55 -0
  355. package/dist/ui/transcript/stick_to_bottom.d.ts.map +1 -0
  356. package/dist/ui/transcript/suggestion_chips.d.ts +29 -0
  357. package/dist/ui/transcript/suggestion_chips.d.ts.map +1 -0
  358. package/dist/ui/transcript/transcript.d.ts +196 -0
  359. package/dist/ui/transcript/transcript.d.ts.map +1 -0
  360. package/dist/ui/transcript/transcript_styles.d.ts +2 -0
  361. package/dist/ui/transcript/transcript_styles.d.ts.map +1 -0
  362. package/dist/ui/ui_strings.d.ts +352 -0
  363. package/dist/ui/ui_strings.d.ts.map +1 -0
  364. package/dist/version.d.ts +2 -0
  365. package/dist/version.d.ts.map +1 -0
  366. package/package.json +86 -3
  367. package/src/bundle.ts +2 -0
  368. package/src/chat.ts +2 -0
  369. package/src/constants.ts +650 -0
  370. package/src/core/activity_registration.ts +19 -0
  371. package/src/core/activity_registry.ts +133 -0
  372. package/src/core/activity_renderer.ts +19 -0
  373. package/src/core/ag_ui_chat.ts +3966 -0
  374. package/src/core/agui_client.ts +1028 -0
  375. package/src/core/attachment.ts +62 -0
  376. package/src/core/chat_registry.ts +53 -0
  377. package/src/core/client_seed.ts +27 -0
  378. package/src/core/conversation_store.ts +478 -0
  379. package/src/core/create_http_agent.ts +97 -0
  380. package/src/core/define_chat.ts +25 -0
  381. package/src/core/events/attachments_detail.ts +9 -0
  382. package/src/core/events/bar_height_detail.ts +5 -0
  383. package/src/core/events/custom_agent_detail.ts +7 -0
  384. package/src/core/events/dock_width_detail.ts +7 -0
  385. package/src/core/events/feedback_detail.ts +27 -0
  386. package/src/core/events/invalidate_detail.ts +15 -0
  387. package/src/core/events/maximize_detail.ts +4 -0
  388. package/src/core/events/run_finished_detail.ts +36 -0
  389. package/src/core/events/state_detail.ts +4 -0
  390. package/src/core/events/submit_detail.ts +8 -0
  391. package/src/core/events/thread_detail.ts +26 -0
  392. package/src/core/events/thread_title_detail.ts +7 -0
  393. package/src/core/events/toggle_detail.ts +4 -0
  394. package/src/core/events/tool_run.ts +10 -0
  395. package/src/core/events/unread_detail.ts +10 -0
  396. package/src/core/message_role.ts +4 -0
  397. package/src/core/read_flag.ts +13 -0
  398. package/src/core/read_json_attribute.ts +30 -0
  399. package/src/core/read_max_tool_rounds.ts +13 -0
  400. package/src/core/remote_conversation_store.ts +279 -0
  401. package/src/core/run_handlers.ts +524 -0
  402. package/src/core/run_index.ts +114 -0
  403. package/src/core/storage_scope.ts +291 -0
  404. package/src/core/tool_outcome.ts +39 -0
  405. package/src/core/transcribe_audio.ts +76 -0
  406. package/src/core/upload_attachment.ts +130 -0
  407. package/src/core/utils.ts +230 -0
  408. package/src/dom/animations.ts +341 -0
  409. package/src/dom/dom_driver.ts +91 -0
  410. package/src/dom/highlight_overlay.ts +204 -0
  411. package/src/dom/native_setter.ts +40 -0
  412. package/src/dom/ring_color.ts +206 -0
  413. package/src/dom/utils.ts +5 -0
  414. package/src/index.ts +220 -0
  415. package/src/skills/fill_template.ts +31 -0
  416. package/src/skills/parse_skills.ts +31 -0
  417. package/src/skills/skill.ts +32 -0
  418. package/src/skills/skill_catalog.ts +172 -0
  419. package/src/skills/skill_name_from.ts +19 -0
  420. package/src/tools/chat_surface_tools.ts +183 -0
  421. package/src/tools/client_tool_registry.ts +80 -0
  422. package/src/tools/is_destructive.ts +17 -0
  423. package/src/tools/is_navigates.ts +12 -0
  424. package/src/tools/page_action_tools.ts +123 -0
  425. package/src/tools/page_map.ts +26 -0
  426. package/src/tools/page_state.ts +57 -0
  427. package/src/tools/parse_tool_catalog.ts +41 -0
  428. package/src/tools/route_map.ts +132 -0
  429. package/src/tools/tool_catalog.ts +334 -0
  430. package/src/tools/tool_dispatch.ts +453 -0
  431. package/src/ui/charts/chart_block.ts +519 -0
  432. package/src/ui/charts/chart_spec_from.ts +125 -0
  433. package/src/ui/charts/chart_styles.ts +63 -0
  434. package/src/ui/charts/chart_tool.ts +72 -0
  435. package/src/ui/composer/attachment_styles.ts +71 -0
  436. package/src/ui/composer/attachment_tray.ts +295 -0
  437. package/src/ui/composer/auto_grow.ts +12 -0
  438. package/src/ui/composer/build_composer.ts +114 -0
  439. package/src/ui/composer/composer_attachments.ts +324 -0
  440. package/src/ui/composer/composer_styles.ts +177 -0
  441. package/src/ui/composer/composer_voice.ts +93 -0
  442. package/src/ui/composer/skill_styles.ts +120 -0
  443. package/src/ui/composer/skills_menu.ts +188 -0
  444. package/src/ui/composer/voice_input.ts +282 -0
  445. package/src/ui/excerpts/attach_copy_buttons.ts +73 -0
  446. package/src/ui/excerpts/copy_payload.ts +156 -0
  447. package/src/ui/excerpts/page_quote_offer.ts +203 -0
  448. package/src/ui/excerpts/place_offer.ts +24 -0
  449. package/src/ui/excerpts/quote_selection.ts +345 -0
  450. package/src/ui/excerpts/transcript_quote_offer.ts +175 -0
  451. package/src/ui/fill_ui_string.ts +41 -0
  452. package/src/ui/history/checkpoint_menu.ts +300 -0
  453. package/src/ui/history/conversation_history.ts +1169 -0
  454. package/src/ui/history/history_styles.ts +492 -0
  455. package/src/ui/history/relative_time.ts +50 -0
  456. package/src/ui/history/thread_drawer.ts +471 -0
  457. package/src/ui/history/utils.ts +11 -0
  458. package/src/ui/interrupts/approval_card.ts +202 -0
  459. package/src/ui/interrupts/approval_styles.ts +52 -0
  460. package/src/ui/interrupts/confirmation_card.ts +138 -0
  461. package/src/ui/interrupts/confirmation_styles.ts +114 -0
  462. package/src/ui/interrupts/pending_decision.ts +33 -0
  463. package/src/ui/interrupts/question_card.ts +213 -0
  464. package/src/ui/interrupts/question_styles.ts +73 -0
  465. package/src/ui/place/place.ts +16 -0
  466. package/src/ui/place/place_chip.ts +146 -0
  467. package/src/ui/place/place_from_route.ts +27 -0
  468. package/src/ui/place/place_styles.ts +108 -0
  469. package/src/ui/placement/clamp_launcher.ts +38 -0
  470. package/src/ui/placement/clamp_panel.ts +30 -0
  471. package/src/ui/placement/collapse_styles.ts +472 -0
  472. package/src/ui/placement/dock_styles.ts +116 -0
  473. package/src/ui/placement/embedded_styles.ts +14 -0
  474. package/src/ui/placement/launcher_drag.ts +206 -0
  475. package/src/ui/placement/launcher_placement.ts +133 -0
  476. package/src/ui/placement/launcher_styles.ts +189 -0
  477. package/src/ui/placement/page_styles.ts +47 -0
  478. package/src/ui/placement/panel_drag.ts +138 -0
  479. package/src/ui/placement/panel_placement.ts +1975 -0
  480. package/src/ui/placement/place_widget.ts +64 -0
  481. package/src/ui/placement/preset_styles.ts +49 -0
  482. package/src/ui/placement/resize_handle.ts +229 -0
  483. package/src/ui/placement/resize_styles.ts +201 -0
  484. package/src/ui/placement/sidebar_styles.ts +113 -0
  485. package/src/ui/placement/small_viewport_styles.ts +70 -0
  486. package/src/ui/placement/surface_for.ts +183 -0
  487. package/src/ui/progress/prettify_tool_name.ts +16 -0
  488. package/src/ui/progress/run_announcer.ts +67 -0
  489. package/src/ui/progress/run_notice.ts +61 -0
  490. package/src/ui/progress/run_notice_styles.ts +52 -0
  491. package/src/ui/progress/subagent_panel.ts +227 -0
  492. package/src/ui/progress/subagent_progress.ts +200 -0
  493. package/src/ui/progress/subagent_update.ts +89 -0
  494. package/src/ui/progress/thoughts_block.ts +165 -0
  495. package/src/ui/progress/thoughts_styles.ts +74 -0
  496. package/src/ui/progress/tool_call_card.ts +429 -0
  497. package/src/ui/progress/tool_group_styles.ts +313 -0
  498. package/src/ui/progress/tool_step_group.ts +317 -0
  499. package/src/ui/progress/tool_step_styles.ts +486 -0
  500. package/src/ui/shell/adopt_styles.ts +34 -0
  501. package/src/ui/shell/build_header.ts +121 -0
  502. package/src/ui/shell/build_launcher.ts +79 -0
  503. package/src/ui/shell/collapse_glyph.ts +42 -0
  504. package/src/ui/shell/frame_styles.ts +147 -0
  505. package/src/ui/shell/glyph_slot.ts +12 -0
  506. package/src/ui/shell/header_button.ts +22 -0
  507. package/src/ui/shell/icon_element.ts +33 -0
  508. package/src/ui/shell/is_unread_badge_enabled.ts +11 -0
  509. package/src/ui/shell/read_launcher_icon_url.ts +9 -0
  510. package/src/ui/shell/theme_styles.ts +11 -0
  511. package/src/ui/shell/token_styles.ts +480 -0
  512. package/src/ui/styles.ts +110 -0
  513. package/src/ui/themes/classic_styles.ts +32 -0
  514. package/src/ui/themes/classic_tokens.ts +51 -0
  515. package/src/ui/themes/code_tokens.ts +21 -0
  516. package/src/ui/themes/ledger_styles.ts +169 -0
  517. package/src/ui/themes/ledger_tokens.ts +33 -0
  518. package/src/ui/themes/modern_styles.ts +80 -0
  519. package/src/ui/themes/quiet_styles.ts +118 -0
  520. package/src/ui/themes/scheme_styles.ts +26 -0
  521. package/src/ui/themes/soft_styles.ts +149 -0
  522. package/src/ui/themes/soft_tokens.ts +29 -0
  523. package/src/ui/themes/theme_hosts.ts +14 -0
  524. package/src/ui/transcript/answer_actions.ts +165 -0
  525. package/src/ui/transcript/answer_stream.ts +123 -0
  526. package/src/ui/transcript/attachment_chip_styles.ts +116 -0
  527. package/src/ui/transcript/attachment_chips.ts +82 -0
  528. package/src/ui/transcript/build_transcript.ts +67 -0
  529. package/src/ui/transcript/greeting_styles.ts +171 -0
  530. package/src/ui/transcript/groups_tool_steps.ts +16 -0
  531. package/src/ui/transcript/message_action_styles.ts +155 -0
  532. package/src/ui/transcript/message_actions.ts +234 -0
  533. package/src/ui/transcript/message_styles.ts +262 -0
  534. package/src/ui/transcript/render_markdown.ts +181 -0
  535. package/src/ui/transcript/render_or_warn.ts +22 -0
  536. package/src/ui/transcript/reveal_words.ts +41 -0
  537. package/src/ui/transcript/starter_chips.ts +42 -0
  538. package/src/ui/transcript/stick_to_bottom.ts +126 -0
  539. package/src/ui/transcript/suggestion_chips.ts +73 -0
  540. package/src/ui/transcript/transcript.ts +555 -0
  541. package/src/ui/transcript/transcript_styles.ts +153 -0
  542. package/src/ui/ui_strings.ts +550 -0
  543. package/src/version.ts +1 -0
@@ -0,0 +1,73 @@
1
+ import type { UiStrings } from "../ui_strings.js";
2
+
3
+ /**
4
+ * Most prompts one push may draw.
5
+ *
6
+ * **Keep in step with `MAX_SUGGESTIONS` in django-ag-ui's
7
+ * `agent/suggestions_activity.py`**, which raises past it. Mirroring is the
8
+ * whole point: this side silently draws no more than its limit and has no
9
+ * channel to report the difference, so a producer that does not know the same
10
+ * number ships suggestions that never appear. That is the hole the chart bounds
11
+ * exist to close, and it was found there by shipping it.
12
+ */
13
+ export const MAX_SUGGESTIONS = 4;
14
+
15
+ /** Longest one prompt may be. Mirrored for the same reason as the count. */
16
+ export const MAX_SUGGESTION_CHARS = 120;
17
+
18
+ /** The `prompts` a `suggestions` activity carries, or `null` when it carries none. */
19
+ export function suggestionPrompts(content: unknown): string[] | null {
20
+ if (typeof content !== "object" || content === null) {
21
+ return null;
22
+ }
23
+ const raw = (content as { prompts?: unknown }).prompts;
24
+ if (!Array.isArray(raw)) {
25
+ return null;
26
+ }
27
+ const prompts = raw
28
+ .filter((prompt): prompt is string => typeof prompt === "string")
29
+ .map((prompt) => prompt.trim())
30
+ .filter((prompt) => prompt !== "" && prompt.length <= MAX_SUGGESTION_CHARS)
31
+ .slice(0, MAX_SUGGESTIONS);
32
+ return prompts.length === 0 ? null : prompts;
33
+ }
34
+
35
+ /**
36
+ * Draw follow-up prompts as chips that send themselves when clicked.
37
+ *
38
+ * Returns `null` when nothing survives, which is the registry's signal to draw
39
+ * nothing rather than an empty row -- the same contract the chart renderer uses
40
+ * for a spec it cannot draw.
41
+ *
42
+ * Buttons rather than links or list items: each one performs an action in the
43
+ * page, and the thing it sends is the label, so the accessible name is the
44
+ * prompt itself and needs no `aria-label` restating it.
45
+ */
46
+ export function renderSuggestionChips(
47
+ content: unknown,
48
+ strings: UiStrings,
49
+ onPick: (prompt: string) => void,
50
+ ): HTMLElement | null {
51
+ const prompts = suggestionPrompts(content);
52
+ if (prompts === null) {
53
+ return null;
54
+ }
55
+ const row = document.createElement("div");
56
+ row.className = "suggestions";
57
+ row.setAttribute("part", "suggestions");
58
+ // A group, labelled: without it a screen reader meets a row of unrelated
59
+ // buttons with no hint that they are the assistant's offer rather than the
60
+ // page's own controls.
61
+ row.setAttribute("role", "group");
62
+ row.setAttribute("aria-label", strings.suggestions);
63
+ for (const prompt of prompts) {
64
+ const chip = document.createElement("button");
65
+ chip.type = "button";
66
+ chip.className = "suggestion-chip";
67
+ chip.setAttribute("part", "suggestion-chip");
68
+ chip.textContent = prompt;
69
+ chip.addEventListener("click", () => onPick(prompt));
70
+ row.appendChild(chip);
71
+ }
72
+ return row;
73
+ }
@@ -0,0 +1,555 @@
1
+ import { MESSAGE_ROLE, type ToolGroupDisplayMode, X_SUMMARY_KEY } from "../../constants.js";
2
+ import type { AgUiToolCall } from "../../core/agui_client.js";
3
+ import type { MessageRole } from "../../core/message_role.js";
4
+ import { skillNameFrom } from "../../skills/skill_name_from.js";
5
+ import type { ChartRenderer, ClientTool } from "../../tools/client_tool_registry.js";
6
+ import { attachCopyButtons } from "../excerpts/attach_copy_buttons.js";
7
+ import { fillUiString } from "../fill_ui_string.js";
8
+ import { prettifyToolName } from "../progress/prettify_tool_name.js";
9
+ import { renderRunNotice } from "../progress/run_notice.js";
10
+ import { ThoughtsBlock } from "../progress/thoughts_block.js";
11
+ import {
12
+ ToolCallCard,
13
+ type ToolDisplayMode,
14
+ type ToolPayload,
15
+ } from "../progress/tool_call_card.js";
16
+ import { ToolStepGroup } from "../progress/tool_step_group.js";
17
+ import type { UiStrings } from "../ui_strings.js";
18
+ import { groupsToolSteps } from "./groups_tool_steps.js";
19
+ import { renderMarkdown } from "./render_markdown.js";
20
+ import { renderOrWarn } from "./render_or_warn.js";
21
+ import { wrapWords } from "./reveal_words.js";
22
+ import { createStickToBottom, type StickToBottom } from "./stick_to_bottom.js";
23
+
24
+ /** What the transcript needs from the element that owns it. */
25
+ export interface TranscriptHost {
26
+ /** The custom element: its text-animation attribute, and the `data-empty` stamp. */
27
+ readonly element: HTMLElement;
28
+ /** The scrolling message list. */
29
+ readonly messages: HTMLDivElement;
30
+ /** The empty-state region at the top of the list. */
31
+ readonly emptyWrap: HTMLDivElement;
32
+ /** The resolved string table. */
33
+ readonly strings: () => UiStrings;
34
+ /** The element's `allowImages`, read per render. */
35
+ readonly allowImages: () => boolean;
36
+ /** Resolve a frontend tool by name, for its `x-summary`. */
37
+ readonly resolveTool: (name: string) => ClientTool | null;
38
+ /** The element's `toolSummaries`, read per card. */
39
+ readonly toolSummaries: () => Record<string, string>;
40
+ /** The server catalog's label for a tool, if it sent one. */
41
+ readonly serverSummary: (name: string) => string | undefined;
42
+ /** The element's `formatToolPayload`, asked per region of a card. */
43
+ readonly formatToolPayload: (payload: ToolPayload) => Node | string | null;
44
+ /** The element's `toolDisplay`, read per card: it decides whether calls fold into a step group. */
45
+ readonly toolDisplay: () => ToolDisplayMode;
46
+ /** The element's `toolGroupDisplay`, read per row: it decides what a lone step offers. */
47
+ readonly toolGroupDisplay: () => ToolGroupDisplayMode;
48
+ }
49
+
50
+ /**
51
+ * The transcript: the bubbles, the open answer group, the pending dots, the
52
+ * reasoning region, the tool cards by call id, and the scroller that follows
53
+ * the foot.
54
+ *
55
+ * The hub most other parts of the element draw into, so it holds only the
56
+ * transcript's own state and asks the element for nothing but configuration.
57
+ *
58
+ * Owned one-to-one by an `<ag-ui-chat>`, and holding no state outside the
59
+ * instance.
60
+ */
61
+ export class Transcript {
62
+ readonly #host: TranscriptHost;
63
+ /** Tool-call cards awaiting execution, keyed by call id. */
64
+ readonly #toolCards = new Map<string, ToolCallCard>();
65
+ /** Card elements by call id, so a rendering handler can find its own card. */
66
+ readonly #cardElements = new Map<string, HTMLElement>();
67
+ /**
68
+ * Cards whose call is being run, by call id. A card leaves the awaiting ones
69
+ * the moment its call is dispatched, and a handler that opens a prompt on its
70
+ * own card is still running long after, so it is found here.
71
+ */
72
+ readonly #running = new Map<string | undefined, ToolCallCard>();
73
+ /**
74
+ * Call ids whose card was already settled from a streamed server-side result
75
+ * (`TOOL_CALL_RESULT`), so the post-run executeTool sweep doesn't overwrite
76
+ * the real output with the generic "executed on the server" fallback.
77
+ */
78
+ readonly #serverSettled = new Set<string>();
79
+ /** Follows the foot of the transcript, and stops when the reader scrolls away. */
80
+ #scroller!: StickToBottom;
81
+ #pending: HTMLDivElement | null = null;
82
+ // The current assistant turn's grouping container. One `.answer`
83
+ // wraps everything a single answer produces — streamed text, tool cards, the
84
+ // pending indicator — so it can be boxed as one "well" by CSS. Opened on the
85
+ // turn's first run start, closed at settle, so it spans the whole multi-round
86
+ // frontend-tool loop (which is several AG-UI runs), not one run. `null`
87
+ // between turns; user bubbles never enter it.
88
+ #currentGroup: HTMLDivElement | null = null;
89
+ // The current turn's streamed-reasoning region, shown at the top of
90
+ // the answer group while a reasoning model thinks and collapsed once the
91
+ // answer's first text token arrives. `null` outside a reasoning turn.
92
+ #thoughts: ThoughtsBlock | null = null;
93
+ /** The step group behind each group element, so a new card can find its run. */
94
+ readonly #stepGroups = new WeakMap<Element, ToolStepGroup>();
95
+ /**
96
+ * An empty comment after each step group that has rendered output, which
97
+ * every later output is placed before, so a group's outputs come out in call
98
+ * order. Every card of a round joins its group before any handler runs, so
99
+ * placing each output straight after the group would put the newest first;
100
+ * and a marker rather than the last output, because an output may be a
101
+ * fragment, which leaves nothing behind to place the next one after.
102
+ */
103
+ readonly #groupEnds = new WeakMap<Element, Comment>();
104
+ /**
105
+ * The step group element each placed output belongs to. A tool's own output
106
+ * does not end its group: the next call joins the group above it. Without
107
+ * that, replay -- which draws each restored call's output before the next
108
+ * call's card -- would split a run the live stream drew as one group.
109
+ */
110
+ readonly #outputGroups = new WeakMap<Node, Element>();
111
+
112
+ constructor(host: TranscriptHost) {
113
+ this.#host = host;
114
+ }
115
+
116
+ /**
117
+ * Start following the foot of the list, and wire the jump button to it.
118
+ * Called while rendering rather than at construction: the viewport has to
119
+ * exist and the observer has to have something to observe. The button
120
+ * outlives a connection, so its listener goes under `signal`.
121
+ */
122
+ mountScroller(jumpButton: HTMLButtonElement, signal: AbortSignal): void {
123
+ jumpButton.addEventListener(
124
+ "click",
125
+ () => {
126
+ this.jump();
127
+ },
128
+ { signal },
129
+ );
130
+ this.#scroller = createStickToBottom({
131
+ viewport: this.#host.messages,
132
+ onMissedContent: (missed) => {
133
+ jumpButton.dataset["missed"] = String(missed);
134
+ },
135
+ });
136
+ }
137
+
138
+ /** Stop following, when the element leaves the document. */
139
+ disposeScroller(): void {
140
+ this.#scroller.dispose();
141
+ }
142
+
143
+ /** Keep the list at its foot, if the reader is there. */
144
+ follow(): void {
145
+ this.#scroller.follow();
146
+ }
147
+
148
+ /** Go to the foot, whether or not the reader had scrolled away. */
149
+ jump(): void {
150
+ this.#scroller.jump();
151
+ }
152
+
153
+ /** Whether the empty-state region is showing, which is when nothing else is. */
154
+ isEmpty(): boolean {
155
+ return !this.#host.emptyWrap.hidden;
156
+ }
157
+
158
+ /** The card drawn for a call id, while it is still awaiting execution. */
159
+ card(callId: string): ToolCallCard | undefined {
160
+ return this.#toolCards.get(callId);
161
+ }
162
+
163
+ /** Every card still awaiting execution. */
164
+ cards(): IterableIterator<ToolCallCard> {
165
+ return this.#toolCards.values();
166
+ }
167
+
168
+ /** Stop tracking a call's card as awaiting execution. */
169
+ forgetCard(callId: string): void {
170
+ this.#toolCards.delete(callId);
171
+ }
172
+
173
+ /** Remember the element a call's card is, for a renderer to place itself against. */
174
+ setCardElement(callId: string, element: HTMLElement): void {
175
+ this.#cardElements.set(callId, element);
176
+ }
177
+
178
+ /** Record that a call's card was settled from a streamed server-side result. */
179
+ markServerSettled(callId: string): void {
180
+ this.#serverSettled.add(callId);
181
+ }
182
+
183
+ /** Whether a call's card was settled from a streamed server-side result. */
184
+ isServerSettled(callId: string): boolean {
185
+ return this.#serverSettled.has(callId);
186
+ }
187
+
188
+ /** Fold the reasoning region away, once the answer has begun. */
189
+ collapseThoughts(): void {
190
+ this.#thoughts?.collapse();
191
+ }
192
+
193
+ /**
194
+ * Stop the reasoning region's clock and settle its header, when reasoning
195
+ * ends or whatever replaces its end arrives first. A no-op without one.
196
+ */
197
+ settleThoughts(): void {
198
+ this.#thoughts?.settle();
199
+ }
200
+
201
+ /**
202
+ * Close the turn's answer group. Drop it if the turn rendered nothing
203
+ * (e.g. a server-only round that streamed no text/card) so an opted-in
204
+ * well leaves no empty box behind.
205
+ */
206
+ closeGroup(): void {
207
+ if (this.#currentGroup !== null && this.#currentGroup.childElementCount === 0) {
208
+ this.#currentGroup.remove();
209
+ this.updateEmptyState();
210
+ }
211
+ // A turn can end with its reasoning never ended, by a stop, an error or a
212
+ // server that sent no end, and the live label must not outlive the turn.
213
+ this.settleThoughts();
214
+ this.#currentGroup = null;
215
+ this.#thoughts = null;
216
+ }
217
+
218
+ /**
219
+ * Let go of the open turn: its group, its reasoning region, its pending dots
220
+ * and the cards awaiting execution. The first half of wiping the transcript.
221
+ */
222
+ releaseTurn(): void {
223
+ this.#currentGroup = null;
224
+ this.#thoughts = null;
225
+ this.hidePending();
226
+ this.#toolCards.clear();
227
+ }
228
+
229
+ /** Forget which cards settled from the server and where each card is. */
230
+ forgetCards(): void {
231
+ this.#serverSettled.clear();
232
+ this.#cardElements.clear();
233
+ this.#running.clear();
234
+ }
235
+
236
+ /** Remember the card of a call being run, for {@link setAsking}. */
237
+ holdRunning(callId: string, card: ToolCallCard): void {
238
+ this.#running.set(callId, card);
239
+ }
240
+
241
+ /**
242
+ * Say whether a prompt is open on the card of a running call. A call id of
243
+ * none, or one no card was held for, has no card to say it on.
244
+ */
245
+ setAsking(callId: string | undefined, asking: boolean): void {
246
+ this.#running.get(callId)?.setAsking(asking);
247
+ }
248
+
249
+ /** Empty the list back to its empty-state region. The last half of wiping it. */
250
+ empty(): void {
251
+ this.#host.messages.replaceChildren(this.#host.emptyWrap);
252
+ this.updateEmptyState();
253
+ }
254
+
255
+ /** The bubble behind `AgUiChat.appendMessage`, whose doc is the contract. */
256
+ append(role: MessageRole, content: string): HTMLDivElement {
257
+ const bubble = document.createElement("div");
258
+ bubble.className = `message message--${role}`;
259
+ bubble.setAttribute("part", `message message-${role}`);
260
+ if (role === MESSAGE_ROLE.ASSISTANT) {
261
+ bubble.innerHTML = renderMarkdown(content, { allowImages: this.#host.allowImages() });
262
+ // A finished bubble: rehydrated history, or a whole message appended at
263
+ // once. The streaming bubble gets its buttons in onTextEnd instead.
264
+ attachCopyButtons(bubble, this.#host.strings());
265
+ this.ensureGroup().appendChild(bubble);
266
+ } else {
267
+ this.#currentGroup = null;
268
+ bubble.textContent = content;
269
+ this.#host.messages.appendChild(bubble);
270
+ }
271
+ this.updateEmptyState();
272
+ // A user bubble means someone just pressed Send, which is as deliberate as
273
+ // pressing the jump button -- so it goes to the bottom even if they had
274
+ // scrolled away to re-read something before typing.
275
+ if (role === MESSAGE_ROLE.USER) {
276
+ this.jump();
277
+ } else {
278
+ this.follow();
279
+ }
280
+ return bubble;
281
+ }
282
+
283
+ /**
284
+ * The open answer group, creating and appending it on first use. Everything a
285
+ * single assistant turn renders (text, tool cards, the pending indicator)
286
+ * goes inside it, so the opt-in `data-answer-well` styling can box the whole
287
+ * turn. Idempotent across the turn's runs — it persists until the run's
288
+ * settle closes it, see {@link closeGroup}.
289
+ */
290
+ ensureGroup(): HTMLDivElement {
291
+ if (this.#currentGroup === null) {
292
+ const group = document.createElement("div");
293
+ group.className = "answer";
294
+ group.setAttribute("part", "answer");
295
+ this.#currentGroup = group;
296
+ this.#host.messages.appendChild(group);
297
+ this.updateEmptyState();
298
+ }
299
+ return this.#currentGroup;
300
+ }
301
+
302
+ /**
303
+ * Word-by-word reveal for the `word` text-animation mode, applied to a
304
+ * completed assistant bubble. `fade` is pure CSS (no JS); `none` is a no-op.
305
+ */
306
+ revealWords(bubble: HTMLDivElement): void {
307
+ if (this.#host.element.getAttribute("data-text-animation") === "word") {
308
+ wrapWords(bubble);
309
+ }
310
+ }
311
+
312
+ /**
313
+ * Hide the empty-state region once the message list holds anything else, and
314
+ * say so on the host as `data-empty`.
315
+ *
316
+ * Stamped on the host because the layout has to answer it: where the
317
+ * composer sits is decided outside the list this region lives in, and no
318
+ * selector reaches from inside the list back up to the list's siblings. It is
319
+ * also a documented styling hook for a host's own chrome around a full-page
320
+ * chat.
321
+ */
322
+ updateEmptyState(): void {
323
+ this.#host.emptyWrap.hidden = this.#host.messages.childElementCount > 1;
324
+ this.#host.element.toggleAttribute("data-empty", !this.#host.emptyWrap.hidden);
325
+ }
326
+
327
+ /** A muted "⏹ Stopped" line in the transcript (distinct from the ⚠️ error bubble). */
328
+ appendStoppedNote(): void {
329
+ const note = document.createElement("div");
330
+ note.className = "stopped-note";
331
+ note.setAttribute("part", "stopped");
332
+ note.setAttribute("role", "status");
333
+ note.textContent = this.#host.strings().stopped;
334
+ this.ensureGroup().appendChild(note);
335
+ this.updateEmptyState();
336
+ this.follow();
337
+ }
338
+
339
+ /**
340
+ * Show a "thinking" indicator while the agent is being awaited — both the
341
+ * silent stretch before the first token and the gap after a tool result
342
+ * while the next round is requested. Idempotent.
343
+ */
344
+ showPending(): void {
345
+ if (this.#pending !== null) {
346
+ return;
347
+ }
348
+ const pending = document.createElement("div");
349
+ pending.className = "pending";
350
+ pending.setAttribute("part", "pending");
351
+ pending.setAttribute("role", "status");
352
+ pending.setAttribute("aria-label", this.#host.strings().thinking);
353
+ for (let i = 0; i < 3; i += 1) {
354
+ const dot = document.createElement("span");
355
+ dot.className = "pending-dot";
356
+ pending.appendChild(dot);
357
+ }
358
+ this.#pending = pending;
359
+ this.ensureGroup().appendChild(pending);
360
+ this.updateEmptyState();
361
+ this.follow();
362
+ }
363
+
364
+ /** Remove the pending indicator if shown. */
365
+ hidePending(): void {
366
+ this.#pending?.remove();
367
+ this.#pending = null;
368
+ }
369
+
370
+ /**
371
+ * The current turn's thoughts region, creating it (at the top of the answer
372
+ * group, above any streamed text or tool cards) on first sight. Idempotent
373
+ * across a turn's reasoning tokens.
374
+ */
375
+ showThoughts(): ThoughtsBlock {
376
+ if (this.#thoughts === null) {
377
+ this.#thoughts = new ThoughtsBlock(this.#host.strings());
378
+ const group = this.ensureGroup();
379
+ group.insertBefore(this.#thoughts.element, group.firstChild);
380
+ this.updateEmptyState();
381
+ this.follow();
382
+ }
383
+ return this.#thoughts;
384
+ }
385
+
386
+ /**
387
+ * Render a skill notice for a `load_capability` call; ``true`` when handled.
388
+ *
389
+ * Shared by the live stream and history replay so the transcript looks the
390
+ * same before and after a reload.
391
+ */
392
+ noticeIfSkillLoad(call: AgUiToolCall): boolean {
393
+ const skill = skillNameFrom(call);
394
+ if (skill === null) {
395
+ return false;
396
+ }
397
+ this.appendNotice(
398
+ "✨",
399
+ fillUiString(this.#host.strings().usingSkill, { name: skill }),
400
+ "skill",
401
+ );
402
+ return true;
403
+ }
404
+
405
+ /**
406
+ * An inline notice about something the run did.
407
+ *
408
+ * Goes through {@link ensureGroup} like a tool card so it lands *inside* the
409
+ * assistant turn it annotates rather than floating between turns, and does
410
+ * the same empty-state and scroll bookkeeping afterwards.
411
+ *
412
+ * `undo` is offered only where the agent rearranged the user's own window --
413
+ * see {@link renderRunNotice} for why a notice may carry that one control and
414
+ * nothing else.
415
+ */
416
+ appendNotice(
417
+ icon: string,
418
+ text: string,
419
+ kind: string,
420
+ undo?: { readonly label: string; readonly onActivate: () => void },
421
+ ): void {
422
+ this.ensureGroup().appendChild(renderRunNotice(icon, text, kind, undo));
423
+ this.updateEmptyState();
424
+ this.follow();
425
+ }
426
+
427
+ /**
428
+ * Place a tool's rendered node against its own card.
429
+ *
430
+ * Anchored rather than appended because a client tool's handler does not run
431
+ * until the round is over: appending would put the node after everything the
432
+ * model said next, visibly detached from the call that produced it, and in a
433
+ * different order than the same transcript takes on reload. The card was
434
+ * created inline, in the right place, so anchoring makes *when* the handler
435
+ * runs stop mattering.
436
+ */
437
+ renderToolOutput(render: ChartRenderer, call: AgUiToolCall): void {
438
+ const node = renderOrWarn(() => render(call.args), `tool ${call.name}`);
439
+ if (node === null) {
440
+ return;
441
+ }
442
+ // `after` rather than an insert-or-append branch: both callers set the card
443
+ // element immediately before calling, and a parentless anchor makes `after`
444
+ // a no-op, so the alternative would be a branch nothing can reach.
445
+ //
446
+ // A card folded into a step group has its output placed after the group
447
+ // rather than inside it, so a chart is never hidden one click down.
448
+ const anchor = this.#cardElements.get(call.id);
449
+ const group = anchor?.closest(".tool-group");
450
+ if (group === null || group === undefined) {
451
+ anchor?.after(node);
452
+ } else {
453
+ let end = this.#groupEnds.get(group);
454
+ if (end === undefined) {
455
+ end = document.createComment("");
456
+ group.after(end);
457
+ this.#groupEnds.set(group, end);
458
+ }
459
+ const placed = node instanceof DocumentFragment ? [...node.children] : [node];
460
+ end.before(node);
461
+ for (const output of placed) {
462
+ this.#outputGroups.set(output, group);
463
+ }
464
+ }
465
+ this.afterGrew();
466
+ }
467
+
468
+ /** Update the empty state and follow the foot, after the transcript grew. */
469
+ afterGrew(): void {
470
+ this.updateEmptyState();
471
+ this.follow();
472
+ }
473
+
474
+ /**
475
+ * The card for ``call``, creating and appending it on first sight.
476
+ *
477
+ * The run's tool-call handler creates the card (pending) during the run; the
478
+ * tool's execution later retrieves the same card to settle it.
479
+ */
480
+ cardFor(call: AgUiToolCall): ToolCallCard {
481
+ const existing = this.#toolCards.get(call.id);
482
+ if (existing !== undefined) {
483
+ return existing;
484
+ }
485
+ // Prefer the tool's own `x-summary`; then an explicit `toolSummaries`
486
+ // entry; then the fetched server catalog (`data-tools-url`). All cover
487
+ // server-side tools whose schema never reached the browser.
488
+ const labelled = this.#host.resolveTool(call.name)?.parameters[X_SUMMARY_KEY];
489
+ const summary =
490
+ typeof labelled === "string"
491
+ ? labelled
492
+ : (this.#host.toolSummaries()[call.name] ??
493
+ this.#host.serverSummary(call.name) ??
494
+ prettifyToolName(call.name));
495
+ const card = new ToolCallCard(call.name, call.args, summary, this.#host.strings(), {
496
+ // A thunk over the live property, not the property itself: the card keeps
497
+ // this for the life of the call, and the result region is filled when the
498
+ // tool settles -- which can be long after a host set the hook.
499
+ formatPayload: (payload) => this.#host.formatToolPayload(payload),
500
+ });
501
+ this.#toolCards.set(call.id, card);
502
+ if (groupsToolSteps(this.#host.toolDisplay())) {
503
+ this.#stepGroup().add(card.element, summary);
504
+ } else {
505
+ this.ensureGroup().appendChild(card.element);
506
+ }
507
+ this.updateEmptyState();
508
+ this.follow();
509
+ return card;
510
+ }
511
+
512
+ /** Redraw every step group's row, for a change of the inner display, which no card announces. */
513
+ refreshStepGroups(): void {
514
+ for (const element of this.#host.messages.querySelectorAll(".tool-group")) {
515
+ this.#stepGroups.get(element)?.refresh();
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Open the step group ``card`` sits in, at once, ahead of a prompt about to be
521
+ * drawn inside it. A no-op for a card drawn in a card display mode, which has
522
+ * no group.
523
+ */
524
+ revealStep(card: ToolCallCard): void {
525
+ const group = card.element.closest(".tool-group");
526
+ (group === null ? undefined : this.#stepGroups.get(group))?.reveal();
527
+ }
528
+
529
+ /**
530
+ * The step group a new card joins. Consecutive cards share one, and so do
531
+ * cards separated only by the group's own rendered output; anything else in
532
+ * between (text, a confirmation, a question) starts the next.
533
+ *
534
+ * The pending dots are not skipped over: a tool call takes them down before
535
+ * its card is drawn, so they are never what a card finds at the foot of the
536
+ * turn.
537
+ */
538
+ #stepGroup(): ToolStepGroup {
539
+ const answer = this.ensureGroup();
540
+ const last = answer.lastElementChild;
541
+ const existing =
542
+ last === null ? undefined : this.#stepGroups.get(this.#outputGroups.get(last) ?? last);
543
+ if (existing !== undefined) {
544
+ return existing;
545
+ }
546
+ const group = new ToolStepGroup(this.#host.strings(), this.#host.toolGroupDisplay);
547
+ this.#stepGroups.set(group.element, group);
548
+ if (last === null) {
549
+ answer.prepend(group.element);
550
+ } else {
551
+ last.after(group.element);
552
+ }
553
+ return group;
554
+ }
555
+ }