@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,230 @@
1
+ // Non-exported-from-index helpers shared by the core modules.
2
+
3
+ import { randomUUID } from "@ag-ui/client";
4
+ import type { Message } from "@ag-ui/core";
5
+ import type { ClientConversationStore } from "./conversation_store.js";
6
+
7
+ /**
8
+ * Overlay a `credentials` mode onto a fetch `init`, or hand the `init` back
9
+ * untouched when none is configured.
10
+ *
11
+ * Absent and `undefined` differ: `exactOptionalPropertyTypes` rejects an
12
+ * explicit `credentials: undefined`, and writing one anyway would state a mode
13
+ * where the point is to leave the browser's own default in place.
14
+ */
15
+ export function withCredentials(
16
+ init: RequestInit | undefined,
17
+ credentials: RequestCredentials | undefined,
18
+ ): RequestInit | undefined {
19
+ return credentials === undefined ? init : { ...init, credentials };
20
+ }
21
+
22
+ /**
23
+ * Start a new conversation in `store` and return its id.
24
+ *
25
+ * `newThread` is optional on the interface, so a store without it is
26
+ * driven the only other way the interface allows: mint an id here and make it
27
+ * active. That path loses the store's own note that the thread is new, so a
28
+ * remote store would go on to ask the server for a conversation that cannot
29
+ * exist yet — which is why every store in this package implements the method.
30
+ *
31
+ * What neither path does is clear the thread being left behind. Starting a
32
+ * conversation is not a reason to destroy the previous one.
33
+ */
34
+ export function mintThread(store: ClientConversationStore): string {
35
+ if (store.newThread !== undefined) {
36
+ return store.newThread();
37
+ }
38
+ const id = randomUUID();
39
+ store.setActiveThread(id);
40
+ return id;
41
+ }
42
+
43
+ /**
44
+ * Announce host credentials about to leave the document's origin.
45
+ *
46
+ * `endpoint` and its six sibling URL attributes are plain HTML, and a page that
47
+ * interpolates one from a query parameter or from tenant-authored
48
+ * configuration has handed an attacker the destination. The browser preflights
49
+ * the custom header, any server willing to answer `Access-Control-Allow-Headers`
50
+ * receives it, and the token leaves on the element's very first request —
51
+ * before the user has done anything. Nothing else in this package compares a
52
+ * configured URL against an expected origin, so without this the delivery is
53
+ * silent, which is the only part of that sequence worth changing.
54
+ *
55
+ * A warning rather than a refusal because a cross-origin agent is a documented
56
+ * deployment: refusing would break working installations to defend against a
57
+ * page that is already interpolating untrusted data into its own markup. What
58
+ * it removes is the silence.
59
+ *
60
+ * `warned` is supplied by the caller rather than held here, per this package's
61
+ * rule against shared mutable state: two elements on one page must each get
62
+ * their own notice, and the set lives exactly as long as its owner.
63
+ *
64
+ * Every configured URL goes through this, not the agent endpoint alone. The
65
+ * tool catalog, the skills list, the thread and attachment endpoints and the
66
+ * upload target are all named by the same kind of host attribute and all carry
67
+ * the same headers, so covering one of them and not the rest would report the
68
+ * least interesting of the seven.
69
+ */
70
+ export function warnOnCrossOriginCredentials(
71
+ url: string | URL,
72
+ credentialNames: readonly string[],
73
+ trustedOrigins: readonly string[],
74
+ warned: Set<string>,
75
+ ): void {
76
+ if (credentialNames.length === 0) {
77
+ return;
78
+ }
79
+ // Resolved against the document, so a relative endpoint — the ordinary case —
80
+ // lands on this origin and says nothing.
81
+ const destination = new URL(String(url), location.href).origin;
82
+ if (
83
+ destination === location.origin ||
84
+ trustedOrigins.includes(destination) ||
85
+ warned.has(destination)
86
+ ) {
87
+ return;
88
+ }
89
+ warned.add(destination);
90
+ console.warn(
91
+ `<ag-ui-chat>: sending host credentials (${credentialNames.join(", ")}) to ` +
92
+ `${destination}, which is not this page's origin (${location.origin}). Those headers ` +
93
+ "are the page's own authentication, and whichever server answers the browser's " +
94
+ "preflight receives them — so a URL attribute built from a query parameter or from " +
95
+ "tenant-authored configuration is a channel for the token to leave on. If this " +
96
+ "destination is deliberate, name it in `trustedOrigins` to confirm it and " +
97
+ "silence this notice. Reported once per origin.",
98
+ );
99
+ }
100
+
101
+ /**
102
+ * The tokens of a comma-separated attribute value, trimmed, with empty ones
103
+ * dropped -- so `"scroll, drag,"` is `["scroll", "drag"]`.
104
+ *
105
+ * Shared by every attribute that names a set of opt-ins, so each one reads a
106
+ * stray space or a trailing comma the same way.
107
+ */
108
+ export function commaTokens(value: string): string[] {
109
+ return value
110
+ .split(",")
111
+ .map((token) => token.trim())
112
+ .filter((token) => token !== "");
113
+ }
114
+
115
+ /**
116
+ * `messages` with a result for every tool call that has none, each placed at the
117
+ * end of the round that made the call.
118
+ *
119
+ * **Why every call.** Several model providers reject a request carrying a tool
120
+ * call with no result, and a conversation that sends one cannot continue. A run
121
+ * leaves calls unanswered in more ways than any one path can list: Stop while
122
+ * the stream is still arriving, a round ending on `RUN_ERROR`, a name no tool
123
+ * here owns, a server that never streamed a result, a page reloaded mid-run.
124
+ * Answering whatever is unanswered, rather than each of those where it happens,
125
+ * is what keeps a path nobody listed from sending one.
126
+ *
127
+ * **Where each result goes.** At the end of its round: the assistant turns
128
+ * carrying calls, then the results that follow them. That is the shape the run
129
+ * loop writes for a round it executed, and a provider reads a result only in the
130
+ * turn straight after the calls; appended at the end of history, it would sit
131
+ * behind a user turn or a reply the conversation has moved on to. A call with a
132
+ * result after a *later* turn is left alone, since it is answered.
133
+ *
134
+ * `answer` builds the one message for a call id, so the caller decides what is
135
+ * true to say and where the label for a reload goes. Calls in `except` are about
136
+ * to be answered by something else -- a resumed approval, or a navigation
137
+ * result -- and must not be answered twice.
138
+ *
139
+ * Returns `messages` itself when nothing is owed.
140
+ *
141
+ * Every condition deciding a round's end is one branch arc, which a coverage
142
+ * gate reports as covered with any part of it deleted. Each is held by a test in
143
+ * `ag_ui_chat_unanswered_tool_calls.test.ts`: a result continuing the round by
144
+ * "answers it after the round's own results"; a turn without calls closing it by
145
+ * "sends a not-finished result for a call that arrived before it"; a turn with
146
+ * calls after a result closing it by "answers each round's open call before the
147
+ * next round starts"; the answered check by "sends the decline Stop gave the
148
+ * open approval"; and the exclusion by "leaves the call it resumes for the
149
+ * server to answer".
150
+ */
151
+ export function answerUnansweredCalls(
152
+ messages: readonly Message[],
153
+ answer: (toolCallId: string) => Message,
154
+ except: ReadonlySet<string> = new Set(),
155
+ ): readonly Message[] {
156
+ const answered = new Set<string>(except);
157
+ for (const message of messages) {
158
+ if (message.role === "tool") {
159
+ answered.add(message.toolCallId);
160
+ }
161
+ }
162
+ const result: Message[] = [];
163
+ let owed: string[] = [];
164
+ let afterResult = false;
165
+ for (const message of messages) {
166
+ const calls = message.role === "assistant" ? toolCallIds(message.toolCalls) : [];
167
+ const continuesRound = message.role === "tool" || (calls.length > 0 && !afterResult);
168
+ if (!continuesRound) {
169
+ result.push(...owed.map(answer));
170
+ owed = [];
171
+ }
172
+ result.push(message);
173
+ afterResult = message.role === "tool";
174
+ for (const id of calls) {
175
+ if (!answered.has(id)) {
176
+ // Marked as it is owed, so a store holding the same id twice gets one
177
+ // answer rather than two, which a provider rejects just the same.
178
+ answered.add(id);
179
+ owed.push(id);
180
+ }
181
+ }
182
+ }
183
+ if (result.length + owed.length === messages.length) {
184
+ return messages;
185
+ }
186
+ result.push(...owed.map(answer));
187
+ return result;
188
+ }
189
+
190
+ /**
191
+ * The ids of the tool calls an assistant turn carries, skipping anything without
192
+ * one.
193
+ *
194
+ * The field is read off the wire or out of a store, and neither is held to its
195
+ * declared type: a server dumping Python models sends `null` for no calls, and a
196
+ * stored conversation may be hand-edited or written by an older version. A throw
197
+ * here would cost the whole request, so a shapeless entry is passed over.
198
+ */
199
+ function toolCallIds(value: unknown): string[] {
200
+ // `Object()` boxes a `null` or a primitive entry into something with no `id`,
201
+ // so one read covers every shape without a branch per shape.
202
+ return Array.isArray(value)
203
+ ? value
204
+ .map((call: unknown) => (Object(call) as { id?: unknown }).id)
205
+ .filter((id): id is string => typeof id === "string")
206
+ : [];
207
+ }
208
+
209
+ /**
210
+ * A key a message carries in its `metadata`, or the same key at the message's
211
+ * top level when its metadata has none.
212
+ *
213
+ * Two keys are read this way, a tool message's `outcome` and a user message's
214
+ * `attachments`, and both for the same reason. `@ag-ui/client` 1.0 strips every
215
+ * key its schemas do not declare, off an inbound event and off the outgoing
216
+ * input, and `metadata` is the one place it declares open by key, so that is
217
+ * where this component writes them. A conversation stored by an earlier release
218
+ * has them at the top level instead, and a reload has to replay it as it
219
+ * settled.
220
+ *
221
+ * Metadata first, so a message carrying both says what the newer writer said.
222
+ * The result is `unknown` because it comes out of a store, which is not trusted
223
+ * to hold the shape anything here wrote; the caller narrows it. `Object()` boxes
224
+ * an absent, `null` or primitive `metadata` into an object with neither key,
225
+ * which reads as no metadata without a branch per shape.
226
+ */
227
+ export function metadataOrTopLevel(message: Message, key: "outcome" | "attachments"): unknown {
228
+ const metadata = Object((message as { metadata?: unknown }).metadata) as Record<string, unknown>;
229
+ return metadata[key] ?? (message as unknown as Record<string, unknown>)[key];
230
+ }
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Visible-action animation primitives.
3
+ *
4
+ * These run against the **host page** DOM (not the element's shadow root) so a
5
+ * user watches the agent type, highlight, and click at human-readable speed.
6
+ * Each is configurable; pass small/zero durations in tests (or use fake timers).
7
+ */
8
+
9
+ import { showHighlightOverlay } from "./highlight_overlay.js";
10
+ import { setNativeChecked, setNativeValue } from "./native_setter.js";
11
+ import { ringColor } from "./ring_color.js";
12
+ import { dispatchInputAndChange } from "./utils.js";
13
+
14
+ function delay(ms: number): Promise<void> {
15
+ return new Promise<void>((resolve) => {
16
+ setTimeout(resolve, ms);
17
+ });
18
+ }
19
+
20
+ /**
21
+ * Whether the user has asked the OS/browser to minimise motion.
22
+ *
23
+ * Honoured by every primitive that moves something, except `typeInto` and
24
+ * `highlightThenClick`, which keep their explicit durations. The flash drops its fade
25
+ * but still holds the ring: reduced motion asks for no animation, not no feedback.
26
+ */
27
+ export function prefersReducedMotion(): boolean {
28
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
29
+ }
30
+
31
+ /** Like {@link delay}, but resolves immediately under reduced motion. */
32
+ function motionDelay(ms: number): Promise<void> {
33
+ if (ms <= 0 || prefersReducedMotion()) {
34
+ return Promise.resolve();
35
+ }
36
+ return delay(ms);
37
+ }
38
+
39
+ /**
40
+ * Which `<ag-ui-chat>` a ring speaks for. The ring is drawn in the host page, which a
41
+ * token set on the chat never reaches, so the chat is read directly.
42
+ */
43
+ export interface RingOwnerOptions {
44
+ /** The chat whose ring colour and accent to use. Default: the latest connected. */
45
+ chat?: HTMLElement;
46
+ }
47
+
48
+ /** The soft halo of the press and toggle rings: the ring colour at 40%. */
49
+ function ringShadow(el: HTMLElement, chat: HTMLElement | undefined): string {
50
+ return `0 0 0 3px color-mix(in srgb, ${ringColor(el, chat)} 40%, transparent)`;
51
+ }
52
+
53
+ /** Outline `el` in the ring colour and return the function that restores its own outline. */
54
+ function outlineElement(el: HTMLElement, chat: HTMLElement | undefined): () => void {
55
+ const previousOutline = el.style.outline;
56
+ const previousOffset = el.style.outlineOffset;
57
+ el.style.outline = `2px solid ${ringColor(el, chat)}`;
58
+ el.style.outlineOffset = "2px";
59
+ return () => {
60
+ el.style.outline = previousOutline;
61
+ el.style.outlineOffset = previousOffset;
62
+ };
63
+ }
64
+
65
+ /** An element whose `value` can be typed into. */
66
+ export type TextLikeElement = HTMLInputElement | HTMLTextAreaElement;
67
+
68
+ export interface TypeOptions {
69
+ /** Milliseconds between characters. Default 35. */
70
+ charDelayMs?: number;
71
+ }
72
+
73
+ /**
74
+ * Clear `el` and type `value` one character at a time, firing an `input` event
75
+ * per character as a real user would, then a final `change`.
76
+ */
77
+ export async function typeInto(
78
+ el: TextLikeElement,
79
+ value: string,
80
+ options: TypeOptions = {},
81
+ ): Promise<void> {
82
+ const charDelayMs = options.charDelayMs ?? 35;
83
+ setNativeValue(el, "");
84
+ el.dispatchEvent(new Event("input", { bubbles: true }));
85
+ for (const char of value) {
86
+ setNativeValue(el, el.value + char);
87
+ el.dispatchEvent(new Event("input", { bubbles: true }));
88
+ if (charDelayMs > 0) {
89
+ await delay(charDelayMs);
90
+ }
91
+ }
92
+ el.dispatchEvent(new Event("change", { bubbles: true }));
93
+ }
94
+
95
+ export interface HighlightClickOptions extends RingOwnerOptions {
96
+ /** Milliseconds to hold the highlight before clicking. Default 280. */
97
+ highlightMs?: number;
98
+ }
99
+
100
+ /** Outline `el`, pause so the user sees it, then click and restore. */
101
+ export async function highlightThenClick(
102
+ el: HTMLElement,
103
+ options: HighlightClickOptions = {},
104
+ ): Promise<void> {
105
+ const restore = outlineElement(el, options.chat);
106
+ await delay(options.highlightMs ?? 280);
107
+ restore();
108
+ el.click();
109
+ }
110
+
111
+ export interface ScrollOptions {
112
+ /**
113
+ * How long to wait for a moving scroll to settle before giving up.
114
+ * Default 600.
115
+ */
116
+ settleMs?: number;
117
+ }
118
+
119
+ const SCROLL_SETTLE_MS = 600;
120
+
121
+ /** How long to give a smooth scroll to start moving before assuming it will not. */
122
+ const SCROLL_START_MS = 100;
123
+
124
+ /**
125
+ * Scroll `el` to the vertical centre of the viewport.
126
+ *
127
+ * Resolves once the scroll settles, so a ring is not drawn mid-glide. Awaiting is
128
+ * optional; the scroll is requested synchronously.
129
+ */
130
+ export function scrollIntoCenterView(el: HTMLElement, options: ScrollOptions = {}): Promise<void> {
131
+ const reduced = prefersReducedMotion();
132
+ el.scrollIntoView({
133
+ block: "center",
134
+ inline: "nearest",
135
+ behavior: reduced ? "auto" : "smooth",
136
+ });
137
+ if (reduced) {
138
+ return Promise.resolve();
139
+ }
140
+ return new Promise<void>((resolve) => {
141
+ let timer: ReturnType<typeof setTimeout>;
142
+ const settle = (): void => {
143
+ clearTimeout(timer);
144
+ document.removeEventListener("scroll", started, true);
145
+ document.removeEventListener("scrollend", settle, true);
146
+ resolve();
147
+ };
148
+ const started = (): void => {
149
+ document.removeEventListener("scroll", started, true);
150
+ clearTimeout(timer);
151
+ timer = setTimeout(settle, options.settleMs ?? SCROLL_SETTLE_MS);
152
+ };
153
+ // Neither event bubbles, so listen on the document in the capture phase. Two timeouts:
154
+ // an element already in view never fires scrollend (the short probe), and once moving,
155
+ // the longer budget covers browsers without scrollend.
156
+ timer = setTimeout(settle, SCROLL_START_MS);
157
+ document.addEventListener("scroll", started, true);
158
+ document.addEventListener("scrollend", settle, true);
159
+ });
160
+ }
161
+
162
+ /** Total on-screen life of the flash ring, hold plus fade. */
163
+ const FLASH_MS = 1200;
164
+
165
+ /** Share of {@link FLASH_MS} spent fading out rather than holding. */
166
+ const FLASH_FADE_RATIO = 1 / 3;
167
+
168
+ export interface FlashOptions extends RingOwnerOptions {
169
+ /** Total milliseconds the ring is on screen, hold plus fade. Default 1200. */
170
+ flashMs?: number;
171
+ /**
172
+ * Ring colour. Defaults to `--ag-ui-highlight-ring-color` (on the target,
173
+ * then on the chat), then the target's `--ag-ui-accent`, then the chat's
174
+ * accent.
175
+ */
176
+ color?: string;
177
+ /**
178
+ * Dim everything except the target. Draws an overlay outside the element instead of an
179
+ * outline (see {@link showHighlightOverlay}); it takes no pointer event, so the page
180
+ * stays usable.
181
+ */
182
+ scrim?: boolean;
183
+ /** Draw the ring as a moving gradient. Also an overlay, for the same reason. */
184
+ gradient?: boolean;
185
+ /** Gap between the target's box and an overlay ring. Default 4. */
186
+ ringPadding?: number;
187
+ /**
188
+ * Move keyboard focus to the element as well. Defaults to false for
189
+ * {@link flash} and true for {@link focusWithFlash}.
190
+ */
191
+ focus?: boolean;
192
+ }
193
+
194
+ async function flashRing(
195
+ el: HTMLElement,
196
+ options: FlashOptions,
197
+ focusByDefault: boolean,
198
+ ): Promise<void> {
199
+ if (options.focus ?? focusByDefault) {
200
+ // preventScroll: focus()'s instant scroll would fight a smooth scroll still in flight.
201
+ el.focus({ preventScroll: true });
202
+ }
203
+ const flashMs = options.flashMs ?? FLASH_MS;
204
+ if (flashMs <= 0) {
205
+ return;
206
+ }
207
+ // A scrim or gradient cannot be an outline (a colour only, and clipped with the target).
208
+ if (options.scrim === true || options.gradient === true) {
209
+ const dismiss = showHighlightOverlay(el, {
210
+ scrim: options.scrim === true,
211
+ gradient: options.gradient === true,
212
+ ...(options.color === undefined ? {} : { color: options.color }),
213
+ ...(options.ringPadding === undefined ? {} : { padding: options.ringPadding }),
214
+ ...(options.chat === undefined ? {} : { chat: options.chat }),
215
+ });
216
+ await delay(flashMs);
217
+ dismiss();
218
+ return;
219
+ }
220
+ const previousOutline = el.style.outline;
221
+ const previousOffset = el.style.outlineOffset;
222
+ const previousTransition = el.style.transition;
223
+ const color = options.color ?? ringColor(el, options.chat);
224
+ // outline, not box-shadow: an overflow:hidden ancestor sharing the target's box clips a shadow away.
225
+ el.style.outline = `3px solid ${color}`;
226
+ el.style.outlineOffset = "2px";
227
+ const fadeMs = prefersReducedMotion() ? 0 : Math.round(flashMs * FLASH_FADE_RATIO);
228
+ await delay(flashMs - fadeMs);
229
+ if (fadeMs > 0) {
230
+ // Setting the transition and the new colour in one task is fine: transitions start from the after-change style.
231
+ el.style.transition = `outline-color ${fadeMs}ms ease-out`;
232
+ el.style.outline = "3px solid transparent";
233
+ await delay(fadeMs);
234
+ }
235
+ el.style.outline = previousOutline;
236
+ el.style.outlineOffset = previousOffset;
237
+ el.style.transition = previousTransition;
238
+ }
239
+
240
+ /**
241
+ * Flash a ring around `el` without touching focus.
242
+ *
243
+ * Prefer this over {@link focusWithFlash} when the point is to show the user
244
+ * something: moving focus steals it from the composer, can fire blur validation
245
+ * on whatever they were mid-edit in, and can close an open menu.
246
+ */
247
+ export function flash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {
248
+ return flashRing(el, options, false);
249
+ }
250
+
251
+ /**
252
+ * Focus `el` and flash a ring around it. Focus moves unless `options.focus`
253
+ * says otherwise; use {@link flash} to leave focus where the user put it.
254
+ */
255
+ export function focusWithFlash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {
256
+ return flashRing(el, options, true);
257
+ }
258
+
259
+ export interface PressOptions extends RingOwnerOptions {
260
+ /** Milliseconds to hold the pressed state before clicking. Default 140. */
261
+ pressMs?: number;
262
+ }
263
+
264
+ /**
265
+ * Show a brief pressed affordance on a control — a slight scale-down plus
266
+ * accent ring — then click it and restore. Reads as a press rather than the
267
+ * plain outline {@link highlightThenClick} draws.
268
+ */
269
+ export async function pressThenClick(el: HTMLElement, options: PressOptions = {}): Promise<void> {
270
+ const pressMs = options.pressMs ?? 140;
271
+ const previousTransform = el.style.transform;
272
+ const previousTransition = el.style.transition;
273
+ const previousShadow = el.style.boxShadow;
274
+ el.style.transition = "transform 80ms ease";
275
+ el.style.transform = "scale(0.96)";
276
+ el.style.boxShadow = ringShadow(el, options.chat);
277
+ await motionDelay(pressMs);
278
+ el.style.transform = previousTransform;
279
+ el.style.transition = previousTransition;
280
+ el.style.boxShadow = previousShadow;
281
+ el.click();
282
+ }
283
+
284
+ export interface SelectOptions extends RingOwnerOptions {
285
+ /** Milliseconds to hold the highlight before committing. Default 220. */
286
+ highlightMs?: number;
287
+ }
288
+
289
+ /** Find an option in `el` whose value or visible text equals `value`. */
290
+ function findOption(el: HTMLSelectElement, value: string): HTMLOptionElement | null {
291
+ for (const option of Array.from(el.options)) {
292
+ if (option.value === value || option.text === value) {
293
+ return option;
294
+ }
295
+ }
296
+ return null;
297
+ }
298
+
299
+ /**
300
+ * Outline a `<select>`, pause so the user sees the pick, then set it to the
301
+ * option matching `value` (by value or visible text) and fire `input` +
302
+ * `change`. Throws when no option matches.
303
+ */
304
+ export async function selectOption(
305
+ el: HTMLSelectElement,
306
+ value: string,
307
+ options: SelectOptions = {},
308
+ ): Promise<void> {
309
+ const option = findOption(el, value);
310
+ if (option === null) {
311
+ throw new Error(`no <option> matching "${value}"`);
312
+ }
313
+ const restore = outlineElement(el, options.chat);
314
+ await motionDelay(options.highlightMs ?? 220);
315
+ setNativeValue(el, option.value);
316
+ dispatchInputAndChange(el);
317
+ restore();
318
+ }
319
+
320
+ export interface ToggleOptions extends RingOwnerOptions {
321
+ /** Milliseconds to hold the flash. Default 200. */
322
+ flashMs?: number;
323
+ }
324
+
325
+ /**
326
+ * Flash a ring around a checkbox/radio, set its `checked` state, and fire
327
+ * `input` + `change` so frameworks observe the flip.
328
+ */
329
+ export async function toggleControl(
330
+ el: HTMLInputElement,
331
+ checked: boolean,
332
+ options: ToggleOptions = {},
333
+ ): Promise<void> {
334
+ const flashMs = options.flashMs ?? 200;
335
+ const previousShadow = el.style.boxShadow;
336
+ el.style.boxShadow = ringShadow(el, options.chat);
337
+ await motionDelay(flashMs);
338
+ setNativeChecked(el, checked);
339
+ dispatchInputAndChange(el);
340
+ el.style.boxShadow = previousShadow;
341
+ }
@@ -0,0 +1,91 @@
1
+ import {
2
+ type FlashOptions,
3
+ focusWithFlash,
4
+ type HighlightClickOptions,
5
+ highlightThenClick,
6
+ type PressOptions,
7
+ pressThenClick,
8
+ type SelectOptions,
9
+ scrollIntoCenterView,
10
+ selectOption,
11
+ type TextLikeElement,
12
+ type ToggleOptions,
13
+ type TypeOptions,
14
+ toggleControl,
15
+ typeInto,
16
+ } from "./animations.js";
17
+ import { setNativeChecked, setNativeValue } from "./native_setter.js";
18
+ import { dispatchInputAndChange } from "./utils.js";
19
+
20
+ /**
21
+ * Every flash option except `focus`, which is not on offer: a field has to hold
22
+ * focus to be typed into.
23
+ */
24
+ export interface FillFieldOptions extends TypeOptions, Omit<FlashOptions, "focus"> {}
25
+
26
+ /**
27
+ * Scroll to, focus (with a flash), and type `value` into a text field.
28
+ *
29
+ * The scroll is awaited — typing into an element still gliding past shows the
30
+ * user nothing.
31
+ */
32
+ export async function fillField(
33
+ el: TextLikeElement,
34
+ value: string,
35
+ options: FillFieldOptions = {},
36
+ ): Promise<void> {
37
+ await scrollIntoCenterView(el);
38
+ await focusWithFlash(el, { ...options, flashMs: options.flashMs ?? 0 });
39
+ await typeInto(el, value, options);
40
+ }
41
+
42
+ /** Scroll to, highlight, and click an element. */
43
+ export async function clickElement(
44
+ el: HTMLElement,
45
+ options: HighlightClickOptions = {},
46
+ ): Promise<void> {
47
+ await scrollIntoCenterView(el);
48
+ await highlightThenClick(el, options);
49
+ }
50
+
51
+ /** Scroll to a button/control and click it with a visible "press" animation. */
52
+ export async function pressButton(el: HTMLElement, options: PressOptions = {}): Promise<void> {
53
+ await scrollIntoCenterView(el);
54
+ await pressThenClick(el, options);
55
+ }
56
+
57
+ /** Scroll to a `<select>`, highlight it, and pick the matching option (animated). */
58
+ export async function selectControl(
59
+ el: HTMLSelectElement,
60
+ value: string,
61
+ options: SelectOptions = {},
62
+ ): Promise<void> {
63
+ await scrollIntoCenterView(el);
64
+ await selectOption(el, value, options);
65
+ }
66
+
67
+ /** Scroll to a checkbox/radio, flash it, and set its checked state (animated). */
68
+ export async function toggleCheckbox(
69
+ el: HTMLInputElement,
70
+ checked: boolean,
71
+ options: ToggleOptions = {},
72
+ ): Promise<void> {
73
+ await scrollIntoCenterView(el);
74
+ await toggleControl(el, checked, options);
75
+ }
76
+
77
+ /**
78
+ * Set a `<select>` or checkbox value without animation, dispatching the `input`
79
+ * and `change` events frameworks listen for.
80
+ */
81
+ export function setControlValue(
82
+ el: HTMLInputElement | HTMLSelectElement,
83
+ value: string | boolean,
84
+ ): void {
85
+ if (el instanceof HTMLInputElement && el.type === "checkbox") {
86
+ setNativeChecked(el, Boolean(value));
87
+ } else {
88
+ setNativeValue(el, String(value));
89
+ }
90
+ dispatchInputAndChange(el);
91
+ }