@artooi/agents-web-components 0.0.0-stage → 0.1.1

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 +77 -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,524 @@
1
+ import {
2
+ CUSTOM_AGENT_EVENT,
3
+ INVALIDATE_CUSTOM_NAME,
4
+ INVALIDATE_EVENT,
5
+ MESSAGE_ROLE,
6
+ RUN_FINISHED_EVENT,
7
+ SUBAGENT_CUSTOM_NAME,
8
+ TOOL_CALL_STATUS,
9
+ } from "../constants.js";
10
+ import { attachCopyButtons } from "../ui/excerpts/attach_copy_buttons.js";
11
+ import type { RunAnnouncer } from "../ui/progress/run_announcer.js";
12
+ import type { SubAgentProgress } from "../ui/progress/subagent_progress.js";
13
+ import type { AnswerActions } from "../ui/transcript/answer_actions.js";
14
+ import type { AnswerStream } from "../ui/transcript/answer_stream.js";
15
+ import type { Transcript } from "../ui/transcript/transcript.js";
16
+ import type { UiStrings } from "../ui/ui_strings.js";
17
+ import type { ActivityRegistry } from "./activity_registry.js";
18
+ import type { AgUiClientHandlers } from "./agui_client.js";
19
+ import type { CustomAgentDetail } from "./events/custom_agent_detail.js";
20
+ import type { InvalidateDetail } from "./events/invalidate_detail.js";
21
+ import type { RunFinishedDetail } from "./events/run_finished_detail.js";
22
+ import type { ToolRun } from "./events/tool_run.js";
23
+ import type { MessageRole } from "./message_role.js";
24
+ import { toolStatusFromOutcome } from "./tool_outcome.js";
25
+
26
+ /** What the run's event handlers need from the element that owns them. */
27
+ export interface RunHandlersHost {
28
+ /** The custom element, which the run's events are dispatched on. */
29
+ readonly element: HTMLElement;
30
+ /** The transcript the run draws into. */
31
+ readonly transcript: Transcript;
32
+ /** The answer streaming into its bubble. */
33
+ readonly stream: AnswerStream;
34
+ /** The action row under each finished answer. */
35
+ readonly actions: AnswerActions;
36
+ /** The activity renderers, and the blocks they drew. */
37
+ readonly activities: ActivityRegistry;
38
+ /** A delegated sub-agent's progress, on the card that delegated. */
39
+ readonly subagents: SubAgentProgress;
40
+ /** The screen-reader status region. */
41
+ readonly announcer: RunAnnouncer;
42
+ /** The resolved string table. */
43
+ readonly strings: () => UiStrings;
44
+ /** Whether an interaction is already in flight, which the composer owns. */
45
+ readonly running: () => boolean;
46
+ /** Swap the composer between Send and Stop; settling sends a queued turn. */
47
+ readonly setRunning: (running: boolean) => void;
48
+ /** The element's `appendMessage`, which a failed run's bubble opens through. */
49
+ readonly appendMessage: (role: MessageRole, content: string) => HTMLDivElement;
50
+ /** Note an assistant answer finished on `threadId`, which may be unseen. */
51
+ readonly noteUnread: (threadId: string) => void;
52
+ }
53
+
54
+ /**
55
+ * What one conversation's runs accumulate for the host between an
56
+ * interaction's first round and its settle.
57
+ *
58
+ * A record per conversation rather than fields on the controller, because a
59
+ * run can outlive the conversation it belongs to. Cancelling is a request, not
60
+ * an ending: a stopped run reports how it ended once its request has closed --
61
+ * or once a host tool's handler, which cancelling cannot interrupt, has
62
+ * returned -- and by then New chat may have cleared the transcript and the next
63
+ * message may already be running. Each handler table keeps the record it was
64
+ * built with, so that report describes the run that made it and nothing the
65
+ * next conversation did.
66
+ */
67
+ interface RunLedger {
68
+ /**
69
+ * Tool calls made during the current interaction, in the order they started,
70
+ * so {@link RUN_FINISHED_EVENT} can report them once the whole thing settles.
71
+ * Spans tool rounds and an approval interrupt; emptied when the event fires.
72
+ */
73
+ readonly tools: { readonly id: string; readonly name: string }[];
74
+ /**
75
+ * Which of those calls had a result streamed back, and so ran on the server.
76
+ *
77
+ * Kept here rather than read from the transcript's cards, because New chat
78
+ * clears the transcript and a run it cut off reports afterwards: a booking
79
+ * the server made would come out as the host's own tool, which is the one
80
+ * side the documented listener skips a refetch for.
81
+ */
82
+ readonly serverSettled: Set<string>;
83
+ /**
84
+ * Keys announced during this interaction, de-duplicated in first-seen order.
85
+ *
86
+ * Per element, never module-level: a second mounted chat is a second run, and
87
+ * sharing this would tell one page to refetch on the other's writes. Emptied
88
+ * by {@link RunHandlers.#dispatchRunFinished}, which is the one place that has
89
+ * read it.
90
+ */
91
+ readonly invalidated: Set<string>;
92
+ /**
93
+ * Whether this turn already announced how it ended.
94
+ *
95
+ * `onSettled` is the terminal guarantee and fires however the run ended, so
96
+ * it is the only place that can promise the user hears *something*. But a
97
+ * stopped or failed run has already said the truer thing from `onCancelled`
98
+ * or `onError`, and "assistant answered" after "response stopped" is worse
99
+ * than silence.
100
+ */
101
+ announcedOutcome: boolean;
102
+ /** How the interaction ended so far; read and reset when the run-finished event fires. */
103
+ outcome: RunFinishedDetail["outcome"];
104
+ }
105
+
106
+ /** An empty ledger, for a conversation nothing has run in yet. */
107
+ function emptyLedger(): RunLedger {
108
+ return {
109
+ tools: [],
110
+ serverSettled: new Set<string>(),
111
+ invalidated: new Set<string>(),
112
+ announcedOutcome: false,
113
+ outcome: "completed",
114
+ };
115
+ }
116
+
117
+ /** Handlers with the same signatures as `table`, each doing nothing once `attached` is false. */
118
+ function whileAttached<T extends object>(table: T, attached: () => boolean): T {
119
+ const guarded: Record<string, (...args: unknown[]) => void> = {};
120
+ for (const [name, handler] of Object.entries(table) as [string, (...args: unknown[]) => void][]) {
121
+ guarded[name] = (...args) => {
122
+ if (attached()) {
123
+ handler(...args);
124
+ }
125
+ };
126
+ }
127
+ return guarded as T;
128
+ }
129
+
130
+ /**
131
+ * The AG-UI event handlers a run is drawn by, and what one interaction
132
+ * accumulates for the host between its first round and its settle: the tool
133
+ * calls it made, the keys it invalidated, and whether it already said how it
134
+ * ended.
135
+ *
136
+ * A controller rather than a factory. The handlers hold nothing of their own,
137
+ * but that bookkeeping is state, and it has never belonged to one handler
138
+ * table: a table is built per client -- the conversation's own, rebuilt after
139
+ * a reset, and one for each checkpoint continuation -- and every table built
140
+ * for one conversation reports into the same bookkeeping. {@link forClient}
141
+ * still returns a fresh table per call.
142
+ *
143
+ * Owned one-to-one by an `<ag-ui-chat>`, and holding no state outside the
144
+ * instance.
145
+ */
146
+ export class RunHandlers {
147
+ readonly #host: RunHandlersHost;
148
+ /**
149
+ * The bookkeeping of the conversation on screen. Replaced rather than
150
+ * emptied by {@link detach}, so a table built before then keeps its own.
151
+ */
152
+ #ledger: RunLedger = emptyLedger();
153
+
154
+ constructor(host: RunHandlersHost) {
155
+ this.#host = host;
156
+ }
157
+
158
+ /**
159
+ * Detach every handler table built so far, because the conversation they
160
+ * drew into has been cleared away.
161
+ *
162
+ * The element calls this when it resets, having first cancelled what was
163
+ * running. A cancelled run still ends later, and a detached table still
164
+ * reports to the host what that run did: a run stopped part-way may already
165
+ * have written something, and {@link RUN_FINISHED_EVENT} fires on
166
+ * cancellation for exactly that reason. Everything else it would do -- draw a
167
+ * stopped note, announce, put the composer back to Send, settle the pending
168
+ * cards -- would land in a transcript and a composer that now belong to
169
+ * another conversation, possibly mid-run, and is dropped. So is any event the
170
+ * run streams after the reset, invalidations included: an abort closes the
171
+ * request those would arrive on, so what a cancelled run still delivers is
172
+ * how it ended.
173
+ */
174
+ detach(): void {
175
+ this.#ledger = emptyLedger();
176
+ }
177
+
178
+ /**
179
+ * A handler table for one AG-UI client. Every table built for the current
180
+ * conversation draws into the same transcript and shares its bookkeeping, so
181
+ * a continuation run reports into the interaction the user is looking at.
182
+ *
183
+ * `threadId` is the thread the client was built for, named on the
184
+ * run-finished detail. Taken here rather than read when the run settles,
185
+ * because a stopped run settles after the reset that stopped it, when the
186
+ * thread on screen is already the next one.
187
+ */
188
+ forClient(threadId: string): AgUiClientHandlers {
189
+ const ledger = this.#ledger;
190
+ const attached = (): boolean => ledger === this.#ledger;
191
+ const { onSettled, onError, onCancelled, ...drawing } = this.#tableFor(ledger, threadId);
192
+ const guarded = whileAttached({ onError, onCancelled }, attached);
193
+ return {
194
+ ...whileAttached(drawing, attached),
195
+ // Recorded outside the check, like the settle: a detached run's ending is
196
+ // still true, and the ledger is the only place it can be kept for the report.
197
+ onError: (message) => {
198
+ ledger.outcome = "failed";
199
+ guarded.onError(message);
200
+ },
201
+ onCancelled: () => {
202
+ ledger.outcome = "stopped";
203
+ guarded.onCancelled();
204
+ },
205
+ onSettled: () => {
206
+ if (attached()) {
207
+ onSettled();
208
+ }
209
+ // Last, so a listener that refetches sees a transcript that has already
210
+ // stopped changing -- and outside the check, because what a run did is
211
+ // true whichever conversation is on screen when it ends.
212
+ this.#dispatchRunFinished(ledger, threadId);
213
+ },
214
+ };
215
+ }
216
+
217
+ /**
218
+ * The handler table itself, recording into `ledger`. {@link forClient}
219
+ * decides how much of it still runs once the table is detached. An answer is
220
+ * attributed to `threadId`, the thread the client was built for.
221
+ */
222
+ #tableFor(ledger: RunLedger, threadId: string): AgUiClientHandlers {
223
+ return {
224
+ onRunStart: () => {
225
+ // Per *round*, so guard on the turn: a run that calls three tools fires
226
+ // this three times and the user needs telling once.
227
+ if (!this.#host.running()) {
228
+ ledger.announcedOutcome = false;
229
+ this.#host.announcer.announce(this.#host.strings().announceResponding);
230
+ }
231
+ this.#host.setRunning(true);
232
+ // Open the answer group on the turn's first run so the pending
233
+ // indicator (and everything after) lands inside the well. Idempotent:
234
+ // later rounds of the same turn reuse it.
235
+ this.#host.transcript.ensureGroup();
236
+ this.#host.transcript.showPending();
237
+ },
238
+ onReasoningStart: () => {
239
+ // The model is thinking: swap the pending dots for a live thoughts
240
+ // region at the top of the turn's answer group.
241
+ this.#host.transcript.hidePending();
242
+ // A later round in the same turn finds the region already there, and
243
+ // restarts its clock and its live label.
244
+ this.#host.transcript.showThoughts().begin();
245
+ },
246
+ onReasoningDelta: (buffer) => {
247
+ this.#host.transcript.showThoughts().stream(buffer);
248
+ },
249
+ onReasoningEnd: () => {
250
+ // Settle the header to how long it took, but leave the region expanded
251
+ // until the answer text starts: it collapses on the first text delta.
252
+ this.#host.transcript.settleThoughts();
253
+ },
254
+ onTextDelta: (buffer) => {
255
+ this.#host.transcript.hidePending();
256
+ // The answer has begun — fold the thoughts away so they don't crowd it.
257
+ this.#host.transcript.collapseThoughts();
258
+ this.#host.stream.queue(buffer);
259
+ this.#host.stream.countDelta();
260
+ },
261
+ onTextEnd: (buffer, message) => {
262
+ // A text message that carried no content is a declaration, not an
263
+ // answer, and drawing one puts an empty bubble above every tool call.
264
+ //
265
+ // `TOOL_CALL_START` names the assistant message a call belongs to, and
266
+ // a response whose first part is a tool call has no text to open that
267
+ // message with. pydantic-ai 2.37 started opening and closing an empty
268
+ // one there so the id names a message the stream actually announced --
269
+ // before that it named one no event carried, which a client could only
270
+ // answer by inventing an id of its own that matches nothing echoed
271
+ // back. So this envelope is a correctness fix upstream, it is legal
272
+ // AG-UI, and any server may send one.
273
+ //
274
+ // `ConversationHistory.replay` already declines to draw a bubble for
275
+ // an assistant message with no text. Without the same rule
276
+ // here the live transcript and the reloaded one disagree about the
277
+ // same conversation, which is the harder half of the bug to notice.
278
+ if (buffer === "") {
279
+ this.#host.stream.end();
280
+ return;
281
+ }
282
+ const bubble = this.#host.stream.into(buffer);
283
+ // Only reveal word-by-word when the message arrived at once. If it
284
+ // streamed across multiple deltas it already revealed progressively, so
285
+ // wrapping it now would replay the finished response one word at a time.
286
+ if (this.#host.stream.deltas <= 1) {
287
+ this.#host.transcript.revealWords(bubble);
288
+ }
289
+ attachCopyButtons(bubble, this.#host.strings());
290
+ this.#host.actions.attach(bubble, message);
291
+ this.#host.stream.end();
292
+ this.#host.noteUnread(threadId);
293
+ },
294
+ onToolCall: (call) => {
295
+ this.#host.transcript.hidePending();
296
+ // A call ends the reasoning before it, whether or not its end arrived,
297
+ // and a turn of reasoning then calls has no text delta to settle it.
298
+ this.#host.transcript.settleThoughts();
299
+ // A skill activation is an ordinary `load_capability` tool call — the
300
+ // deferred-capability mechanism pydantic-ai already uses — so it arrives
301
+ // here rather than on a channel of its own. Render it as a notice and
302
+ // *return*: falling through would show a raw tool card beside the chip,
303
+ // which is worse than the card alone.
304
+ if (this.#host.transcript.noticeIfSkillLoad(call)) {
305
+ return;
306
+ }
307
+ // Recorded after the skill-load return: a capability load is the agent
308
+ // arranging itself, not work a host's data could have moved under.
309
+ ledger.tools.push({ id: call.id, name: call.name });
310
+ this.#host.transcript.cardFor(call);
311
+ },
312
+ onActivity: (activityType, content, messageId) => {
313
+ this.#host.activities.draw(messageId, activityType, content);
314
+ },
315
+ onCustomEvent: (name, value) => {
316
+ if (name === INVALIDATE_CUSTOM_NAME) {
317
+ this.#dispatchInvalidation(ledger, value);
318
+ return;
319
+ }
320
+ if (name === SUBAGENT_CUSTOM_NAME) {
321
+ this.#host.subagents.report(value);
322
+ return;
323
+ }
324
+ // Straight out to the host page, uninterpreted. This is the imperative
325
+ // carrier: whatever it means, it means it to the page, not to the
326
+ // transcript -- so it is dispatched and deliberately not rendered,
327
+ // persisted or replayed. A host that does not know the name simply has
328
+ // no listener, which is the graceful outcome the open field is for.
329
+ this.#host.element.dispatchEvent(
330
+ new CustomEvent<CustomAgentDetail>(CUSTOM_AGENT_EVENT, {
331
+ detail: { name, value },
332
+ bubbles: true,
333
+ composed: true,
334
+ }),
335
+ );
336
+ },
337
+ // The delegation's own lifetime, on the protocol's events rather than the
338
+ // CUSTOM channel its steps ride. Both end at the same panel.
339
+ onSubAgentStarted: (subagentRunId, agent, parentToolCallId) => {
340
+ this.#host.subagents.start(subagentRunId, agent, parentToolCallId);
341
+ },
342
+ onSubAgentFinished: (subagentRunId) => {
343
+ this.#host.subagents.finish(subagentRunId);
344
+ },
345
+ onSubAgentError: (subagentRunId, message) => {
346
+ this.#host.subagents.fail(subagentRunId, message);
347
+ },
348
+ onMessagesSnapshot: () => {
349
+ // Honoured for persistence and announced, not re-rendered.
350
+ //
351
+ // The store follows the server, because the server is authoritative
352
+ // about what the conversation *is* -- and it would follow it anyway:
353
+ // `@ag-ui/client` replaces `agent.messages` before any subscriber runs,
354
+ // and the run loop persists `agent.messages`. Done in silence, the
355
+ // screen and the store would disagree until a reload served a
356
+ // transcript the reader had never seen.
357
+ //
358
+ // Not re-rendered from the snapshot: a snapshot can land mid-run, and rebuilding the
359
+ // transcript then would destroy the in-flight run's own UI state -- the streaming
360
+ // bubble, the open answer group, and every tool card keyed by call id,
361
+ // some of which are still waiting on results. Telling the reader costs
362
+ // none of that, and this is the same answer the same question already
363
+ // got for compaction, one handler up.
364
+ this.#host.transcript.appendNotice(
365
+ "\u{1F504}",
366
+ this.#host.strings().historyReplaced,
367
+ "history-replaced",
368
+ );
369
+ },
370
+ onToolResult: (toolCallId, content, outcome) => {
371
+ const card = this.#host.transcript.card(toolCallId);
372
+ if (card === undefined) {
373
+ return;
374
+ }
375
+ // Settled as the server says it ended, not as "it ended": a refusal
376
+ // settled as DONE is a green card, and a booking the server declined
377
+ // reads, at a glance, as a booking that was made. An absent or
378
+ // unrecognised outcome still means DONE, so a server that never states
379
+ // one renders every call as done.
380
+ card.settle(toolStatusFromOutcome(outcome), content);
381
+ this.#host.transcript.markServerSettled(toolCallId);
382
+ ledger.serverSettled.add(toolCallId);
383
+ // The card stops being the live thing the moment it settles, and the
384
+ // server goes straight back to the model with the result -- a wait with
385
+ // nothing on screen to own it, and the longest one in a run when the
386
+ // result is a large inlined attachment being re-sent with every request.
387
+ // The dots go back where ``onToolCall`` took them from, after the card,
388
+ // and whatever comes next clears them: reasoning, the first text delta,
389
+ // the round ending, or ``onSettled``'s terminal guarantee.
390
+ //
391
+ // Not the same case as the one ``ToolDispatch.execute`` refuses to show
392
+ // them for. That runs after the run has ended, so there is nothing left to
393
+ // clear them and they would hang -- which is what happened before 0.2.1
394
+ // and is why they were removed from here too. The terminal guarantee
395
+ // that shipped in the same release is what makes showing them safe now.
396
+ this.#host.transcript.showPending();
397
+ },
398
+ onActivityChanged: (messageId, activityType, content) => {
399
+ this.#host.activities.draw(messageId, activityType, content);
400
+ },
401
+ onRunEnd: () => {
402
+ // Per-round end; the button stays on Stop until the whole interaction
403
+ // settles — the user must be able to cancel between tool rounds.
404
+ this.#host.transcript.hidePending();
405
+ this.#host.stream.end();
406
+ },
407
+ onError: (message) => {
408
+ ledger.announcedOutcome = true;
409
+ this.#host.announcer.announce(this.#host.strings().announceFailed);
410
+ this.#host.transcript.hidePending();
411
+ const bubble = this.#host.appendMessage(MESSAGE_ROLE.ASSISTANT, `⚠️ ${message}`);
412
+ bubble.classList.add("message--failed");
413
+ // A failure is the one message whose action row is only worth having
414
+ // for Retry: there is nothing here worth copying and nothing to rate.
415
+ // A dropped connection with no way back was the whole of the gap --
416
+ // uploads had a retry and runs did not.
417
+ //
418
+ // Not a `run-notice`: that element's contract is that it "never
419
+ // settles, takes no action, and carries no controls", and is explicitly
420
+ // "distinct from an error, which is a failure". This is a failure, so
421
+ // it stays an error and gains the control instead.
422
+ this.#host.actions.attach(bubble, { rateable: false });
423
+ this.#host.transcript.revealWords(bubble);
424
+ this.#host.stream.end();
425
+ },
426
+ onCancelled: () => {
427
+ // Deliberate stop, not a failure: keep whatever partial text already
428
+ // streamed and add a muted note instead of an error bubble.
429
+ ledger.announcedOutcome = true;
430
+ this.#host.announcer.announce(this.#host.strings().announceStopped);
431
+ this.#host.transcript.hidePending();
432
+ this.#host.transcript.appendStoppedNote();
433
+ this.#host.stream.end();
434
+ },
435
+ onSettled: () => {
436
+ // Terminal guarantee: whatever path ended the run, return to rest.
437
+ if (!ledger.announcedOutcome) {
438
+ this.#host.announcer.announce(this.#host.strings().announceAnswerReady);
439
+ }
440
+ this.#host.transcript.hidePending();
441
+ this.#host.setRunning(false);
442
+ this.#host.stream.end();
443
+ // A tool card still pending at settle would hang forever: a call Stop or
444
+ // RUN_ERROR ended before it ran, a server tool whose result never
445
+ // streamed because the connection dropped, an approved call Stop kept
446
+ // from resuming. None of them finished and nobody refused them, so the
447
+ // card says exactly that, in the words the client sends the agent for
448
+ // the same call on the next request.
449
+ for (const card of this.#host.transcript.cards()) {
450
+ if (!card.settled) {
451
+ card.settle(TOOL_CALL_STATUS.INTERRUPTED, this.#host.strings().callNotFinished);
452
+ }
453
+ }
454
+ this.#host.transcript.closeGroup();
455
+ },
456
+ };
457
+ }
458
+
459
+ /**
460
+ * Tell the host the interaction is over and what ran in it.
461
+ *
462
+ * Last thing in `onSettled`, so a listener that refetches sees a transcript
463
+ * that has already stopped changing. `side` is read from the streamed-result
464
+ * bookkeeping rather than from the tool list: whether a call executed on the
465
+ * server is a fact about the run, and a name can appear on both sides across a
466
+ * conversation.
467
+ */
468
+ #dispatchRunFinished(ledger: RunLedger, threadId: string): void {
469
+ const tools: ToolRun[] = ledger.tools.map(({ id, name }) => ({
470
+ name,
471
+ side: ledger.serverSettled.has(id) ? "server" : "client",
472
+ }));
473
+ const invalidated = [...ledger.invalidated];
474
+ ledger.tools.length = 0;
475
+ ledger.serverSettled.clear();
476
+ ledger.invalidated.clear();
477
+ const outcome = ledger.outcome;
478
+ ledger.outcome = "completed";
479
+ this.#host.element.dispatchEvent(
480
+ new CustomEvent<RunFinishedDetail>(RUN_FINISHED_EVENT, {
481
+ detail: { threadId, tools, invalidated, outcome },
482
+ bubbles: true,
483
+ composed: true,
484
+ }),
485
+ );
486
+ }
487
+
488
+ /**
489
+ * Route one invalidation to the host, and remember it for the run summary.
490
+ *
491
+ * Dispatched immediately rather than only at the end, because that is what
492
+ * makes a long multi-step run feel live -- the list refreshes as the third of
493
+ * eight writes lands. The accumulated set rides
494
+ * {@link RUN_FINISHED_EVENT} as well, so a host that would rather refetch once
495
+ * upgrades by reading one extra field instead of adding a listener.
496
+ *
497
+ * Nothing is rendered, persisted or replayed. An invalidation is an
498
+ * imperative: it has no place in the transcript and no meaning once acted on,
499
+ * and replaying one on every thread load would be a refetch storm. That is the
500
+ * whole reason the server sends it as `CUSTOM` rather than as an activity.
501
+ */
502
+ #dispatchInvalidation(ledger: RunLedger, value: unknown): void {
503
+ const payload = (value ?? {}) as { keys?: unknown; reason?: unknown };
504
+ // Defensive about the payload, not about the name: `value` is typed
505
+ // `unknown` by the protocol, so a server can put anything there, and a
506
+ // malformed announcement must not take the run down with it.
507
+ const keys = Array.isArray(payload.keys)
508
+ ? payload.keys.filter((key): key is string => typeof key === "string")
509
+ : [];
510
+ if (keys.length === 0) {
511
+ return;
512
+ }
513
+ for (const key of keys) {
514
+ ledger.invalidated.add(key);
515
+ }
516
+ this.#host.element.dispatchEvent(
517
+ new CustomEvent<InvalidateDetail>(INVALIDATE_EVENT, {
518
+ detail: { keys, reason: typeof payload.reason === "string" ? payload.reason : null },
519
+ bubbles: true,
520
+ composed: true,
521
+ }),
522
+ );
523
+ }
524
+ }
@@ -0,0 +1,114 @@
1
+ import { withCredentials } from "./utils.js";
2
+
3
+ /** One row of the server run index (django-ag-ui's `RunsView` wire shape). */
4
+ export interface RunRow {
5
+ readonly run_id: string;
6
+ readonly thread_id: string | null;
7
+ readonly parent_run_id: string | null;
8
+ readonly started_at: string | null;
9
+ /** Whether the run has a snapshot to seed from — see {@link RunIndex}. */
10
+ readonly continuable: boolean;
11
+ /**
12
+ * The run's first user message, one line, already truncated by the server —
13
+ * the only field in a row a person recognises a conversation by.
14
+ *
15
+ * Optional because a server predating the field does not send it, and
16
+ * `null` where the run holds no words to show (seeded from history alone, or
17
+ * opened with an image and no caption). A row without one falls back to the
18
+ * time plus a short id.
19
+ */
20
+ readonly preview?: string | null;
21
+ }
22
+
23
+ /** Live header source, read per request so rotated tokens / CSRF reach the server. */
24
+ type HeadersProvider = () => Record<string, string>;
25
+
26
+ /** Live cookie policy, read per request; see `RemoteConversationStore`'s note. */
27
+ type CredentialsProvider = () => RequestCredentials | undefined;
28
+
29
+ /**
30
+ * Reads the server's run index and derives the resume / fork URLs beside it.
31
+ *
32
+ * Backed by django-ag-ui's owner-scoped `RunsView` — the URL passed to
33
+ * `<ag-ui-chat>` as `data-runs-url`:
34
+ *
35
+ * - `GET <url>` → the user's runs, newest first.
36
+ *
37
+ * Only `continuable` rows can be resumed: the server reports whether a run has
38
+ * a saved snapshot to seed from, and a run that never reached a provider-valid
39
+ * boundary has none. Offer the action only for those rows ({@link continuable}
40
+ * filters them) and treat the rest as informational.
41
+ *
42
+ * Resume and fork are siblings of the index rather than separate configuration
43
+ * — django-ag-ui mounts `runs/`, `resume/<id>/` and `fork/<id>/` under one
44
+ * prefix — so this one URL locates all three.
45
+ */
46
+ export class RunIndex {
47
+ readonly #url: string;
48
+ readonly #headers: HeadersProvider;
49
+ readonly #credentials: CredentialsProvider;
50
+
51
+ constructor(
52
+ url: string,
53
+ headers: HeadersProvider = () => ({}),
54
+ credentials: CredentialsProvider = () => undefined,
55
+ ) {
56
+ this.#url = url.endsWith("/") ? url : `${url}/`;
57
+ this.#headers = headers;
58
+ this.#credentials = credentials;
59
+ }
60
+
61
+ /**
62
+ * The user's runs, or `[]` when the endpoint is unreachable or errors — the
63
+ * caller renders its empty state rather than a transport fault the user can
64
+ * do nothing about.
65
+ */
66
+ async list(): Promise<readonly RunRow[]> {
67
+ try {
68
+ const response = await fetch(
69
+ this.#url,
70
+ withCredentials(
71
+ {
72
+ method: "GET",
73
+ headers: { Accept: "application/json", ...this.#headers() },
74
+ },
75
+ this.#credentials(),
76
+ ),
77
+ );
78
+ if (!response.ok) {
79
+ return [];
80
+ }
81
+ const body = (await response.json()) as { runs?: readonly RunRow[] };
82
+ return body.runs ?? [];
83
+ } catch {
84
+ return [];
85
+ }
86
+ }
87
+
88
+ /** The rows a client may actually continue. */
89
+ async continuable(): Promise<readonly RunRow[]> {
90
+ return (await this.list()).filter((run) => run.continuable);
91
+ }
92
+
93
+ /** The endpoint that continues `runId` as a new run. */
94
+ resumeUrl(runId: string): string {
95
+ return this.#sibling("resume", runId);
96
+ }
97
+
98
+ /** The endpoint that branches `runId` into a new run, leaving the source untouched. */
99
+ forkUrl(runId: string): string {
100
+ return this.#sibling("fork", runId);
101
+ }
102
+
103
+ /**
104
+ * `<mount>/<verb>/<runId>/`, derived from the index URL's own prefix.
105
+ *
106
+ * String surgery on the trailing `runs/` rather than `new URL`, because the
107
+ * configured value may be root-relative (`/agent/runs/`), the common case in
108
+ * a Django template, and `new URL` needs an absolute base.
109
+ */
110
+ #sibling(verb: string, runId: string): string {
111
+ const prefix = this.#url.slice(0, -"runs/".length);
112
+ return `${prefix}${verb}/${encodeURIComponent(runId)}/`;
113
+ }
114
+ }