@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.
- package/CHANGELOG.md +77 -0
- package/LICENSE +21 -0
- package/README.md +4397 -2
- package/dist/agents-web-components.bundle.js +5708 -0
- package/dist/agents-web-components.bundle.js.map +7 -0
- package/dist/bundle.d.ts +3 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/chat.d.ts +3 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +16373 -0
- package/dist/chat.js.map +7 -0
- package/dist/chunk-ARNLFGCC.js +7715 -0
- package/dist/chunk-ARNLFGCC.js.map +7 -0
- package/dist/constants.d.ts +575 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/core/activity_registration.d.ts +19 -0
- package/dist/core/activity_registration.d.ts.map +1 -0
- package/dist/core/activity_registry.d.ts +46 -0
- package/dist/core/activity_registry.d.ts.map +1 -0
- package/dist/core/activity_renderer.d.ts +20 -0
- package/dist/core/activity_renderer.d.ts.map +1 -0
- package/dist/core/ag_ui_chat.d.ts +836 -0
- package/dist/core/ag_ui_chat.d.ts.map +1 -0
- package/dist/core/agui_client.d.ts +370 -0
- package/dist/core/agui_client.d.ts.map +1 -0
- package/dist/core/attachment.d.ts +42 -0
- package/dist/core/attachment.d.ts.map +1 -0
- package/dist/core/chat_registry.d.ts +23 -0
- package/dist/core/chat_registry.d.ts.map +1 -0
- package/dist/core/client_seed.d.ts +27 -0
- package/dist/core/client_seed.d.ts.map +1 -0
- package/dist/core/conversation_store.d.ts +195 -0
- package/dist/core/conversation_store.d.ts.map +1 -0
- package/dist/core/create_http_agent.d.ts +57 -0
- package/dist/core/create_http_agent.d.ts.map +1 -0
- package/dist/core/define_chat.d.ts +13 -0
- package/dist/core/define_chat.d.ts.map +1 -0
- package/dist/core/events/attachments_detail.d.ts +9 -0
- package/dist/core/events/attachments_detail.d.ts.map +1 -0
- package/dist/core/events/bar_height_detail.d.ts +6 -0
- package/dist/core/events/bar_height_detail.d.ts.map +1 -0
- package/dist/core/events/custom_agent_detail.d.ts +8 -0
- package/dist/core/events/custom_agent_detail.d.ts.map +1 -0
- package/dist/core/events/dock_width_detail.d.ts +8 -0
- package/dist/core/events/dock_width_detail.d.ts.map +1 -0
- package/dist/core/events/feedback_detail.d.ts +28 -0
- package/dist/core/events/feedback_detail.d.ts.map +1 -0
- package/dist/core/events/invalidate_detail.d.ts +16 -0
- package/dist/core/events/invalidate_detail.d.ts.map +1 -0
- package/dist/core/events/maximize_detail.d.ts +5 -0
- package/dist/core/events/maximize_detail.d.ts.map +1 -0
- package/dist/core/events/run_finished_detail.d.ts +36 -0
- package/dist/core/events/run_finished_detail.d.ts.map +1 -0
- package/dist/core/events/state_detail.d.ts +5 -0
- package/dist/core/events/state_detail.d.ts.map +1 -0
- package/dist/core/events/submit_detail.d.ts +8 -0
- package/dist/core/events/submit_detail.d.ts.map +1 -0
- package/dist/core/events/thread_detail.d.ts +27 -0
- package/dist/core/events/thread_detail.d.ts.map +1 -0
- package/dist/core/events/thread_title_detail.d.ts +8 -0
- package/dist/core/events/thread_title_detail.d.ts.map +1 -0
- package/dist/core/events/toggle_detail.d.ts +5 -0
- package/dist/core/events/toggle_detail.d.ts.map +1 -0
- package/dist/core/events/tool_run.d.ts +11 -0
- package/dist/core/events/tool_run.d.ts.map +1 -0
- package/dist/core/events/unread_detail.d.ts +11 -0
- package/dist/core/events/unread_detail.d.ts.map +1 -0
- package/dist/core/message_role.d.ts +4 -0
- package/dist/core/message_role.d.ts.map +1 -0
- package/dist/core/read_flag.d.ts +11 -0
- package/dist/core/read_flag.d.ts.map +1 -0
- package/dist/core/read_json_attribute.d.ts +15 -0
- package/dist/core/read_json_attribute.d.ts.map +1 -0
- package/dist/core/read_max_tool_rounds.d.ts +9 -0
- package/dist/core/read_max_tool_rounds.d.ts.map +1 -0
- package/dist/core/remote_conversation_store.d.ts +71 -0
- package/dist/core/remote_conversation_store.d.ts.map +1 -0
- package/dist/core/run_handlers.d.ts +85 -0
- package/dist/core/run_handlers.d.ts.map +1 -0
- package/dist/core/run_index.d.ts +58 -0
- package/dist/core/run_index.d.ts.map +1 -0
- package/dist/core/storage_scope.d.ts +118 -0
- package/dist/core/storage_scope.d.ts.map +1 -0
- package/dist/core/tool_outcome.d.ts +27 -0
- package/dist/core/tool_outcome.d.ts.map +1 -0
- package/dist/core/transcribe_audio.d.ts +32 -0
- package/dist/core/transcribe_audio.d.ts.map +1 -0
- package/dist/core/upload_attachment.d.ts +44 -0
- package/dist/core/upload_attachment.d.ts.map +1 -0
- package/dist/core/utils.d.ts +117 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/dom/animations.d.ts +122 -0
- package/dist/dom/animations.d.ts.map +1 -0
- package/dist/dom/dom_driver.d.ts +28 -0
- package/dist/dom/dom_driver.d.ts.map +1 -0
- package/dist/dom/highlight_overlay.d.ts +39 -0
- package/dist/dom/highlight_overlay.d.ts.map +1 -0
- package/dist/dom/native_setter.d.ts +5 -0
- package/dist/dom/native_setter.d.ts.map +1 -0
- package/dist/dom/ring_color.d.ts +16 -0
- package/dist/dom/ring_color.d.ts.map +1 -0
- package/dist/dom/utils.d.ts +3 -0
- package/dist/dom/utils.d.ts.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +223 -0
- package/dist/index.js.map +7 -0
- package/dist/skills/fill_template.d.ts +16 -0
- package/dist/skills/fill_template.d.ts.map +1 -0
- package/dist/skills/parse_skills.d.ts +8 -0
- package/dist/skills/parse_skills.d.ts.map +1 -0
- package/dist/skills/skill.d.ts +33 -0
- package/dist/skills/skill.d.ts.map +1 -0
- package/dist/skills/skill_catalog.d.ts +69 -0
- package/dist/skills/skill_catalog.d.ts.map +1 -0
- package/dist/skills/skill_name_from.d.ts +12 -0
- package/dist/skills/skill_name_from.d.ts.map +1 -0
- package/dist/tools/chat_surface_tools.d.ts +77 -0
- package/dist/tools/chat_surface_tools.d.ts.map +1 -0
- package/dist/tools/client_tool_registry.d.ts +58 -0
- package/dist/tools/client_tool_registry.d.ts.map +1 -0
- package/dist/tools/is_destructive.d.ts +14 -0
- package/dist/tools/is_destructive.d.ts.map +1 -0
- package/dist/tools/is_navigates.d.ts +9 -0
- package/dist/tools/is_navigates.d.ts.map +1 -0
- package/dist/tools/page_action_tools.d.ts +30 -0
- package/dist/tools/page_action_tools.d.ts.map +1 -0
- package/dist/tools/page_map.d.ts +16 -0
- package/dist/tools/page_map.d.ts.map +1 -0
- package/dist/tools/page_state.d.ts +27 -0
- package/dist/tools/page_state.d.ts.map +1 -0
- package/dist/tools/parse_tool_catalog.d.ts +21 -0
- package/dist/tools/parse_tool_catalog.d.ts.map +1 -0
- package/dist/tools/route_map.d.ts +37 -0
- package/dist/tools/route_map.d.ts.map +1 -0
- package/dist/tools/tool_catalog.d.ts +86 -0
- package/dist/tools/tool_catalog.d.ts.map +1 -0
- package/dist/tools/tool_dispatch.d.ts +82 -0
- package/dist/tools/tool_dispatch.d.ts.map +1 -0
- package/dist/ui/charts/chart_block.d.ts +57 -0
- package/dist/ui/charts/chart_block.d.ts.map +1 -0
- package/dist/ui/charts/chart_spec_from.d.ts +12 -0
- package/dist/ui/charts/chart_spec_from.d.ts.map +1 -0
- package/dist/ui/charts/chart_styles.d.ts +2 -0
- package/dist/ui/charts/chart_styles.d.ts.map +1 -0
- package/dist/ui/charts/chart_tool.d.ts +15 -0
- package/dist/ui/charts/chart_tool.d.ts.map +1 -0
- package/dist/ui/composer/attachment_styles.d.ts +2 -0
- package/dist/ui/composer/attachment_styles.d.ts.map +1 -0
- package/dist/ui/composer/attachment_tray.d.ts +53 -0
- package/dist/ui/composer/attachment_tray.d.ts.map +1 -0
- package/dist/ui/composer/auto_grow.d.ts +10 -0
- package/dist/ui/composer/auto_grow.d.ts.map +1 -0
- package/dist/ui/composer/build_composer.d.ts +32 -0
- package/dist/ui/composer/build_composer.d.ts.map +1 -0
- package/dist/ui/composer/composer_attachments.d.ts +57 -0
- package/dist/ui/composer/composer_attachments.d.ts.map +1 -0
- package/dist/ui/composer/composer_styles.d.ts +2 -0
- package/dist/ui/composer/composer_styles.d.ts.map +1 -0
- package/dist/ui/composer/composer_voice.d.ts +48 -0
- package/dist/ui/composer/composer_voice.d.ts.map +1 -0
- package/dist/ui/composer/skill_styles.d.ts +2 -0
- package/dist/ui/composer/skill_styles.d.ts.map +1 -0
- package/dist/ui/composer/skills_menu.d.ts +34 -0
- package/dist/ui/composer/skills_menu.d.ts.map +1 -0
- package/dist/ui/composer/voice_input.d.ts +46 -0
- package/dist/ui/composer/voice_input.d.ts.map +1 -0
- package/dist/ui/excerpts/attach_copy_buttons.d.ts +13 -0
- package/dist/ui/excerpts/attach_copy_buttons.d.ts.map +1 -0
- package/dist/ui/excerpts/copy_payload.d.ts +30 -0
- package/dist/ui/excerpts/copy_payload.d.ts.map +1 -0
- package/dist/ui/excerpts/page_quote_offer.d.ts +33 -0
- package/dist/ui/excerpts/page_quote_offer.d.ts.map +1 -0
- package/dist/ui/excerpts/place_offer.d.ts +9 -0
- package/dist/ui/excerpts/place_offer.d.ts.map +1 -0
- package/dist/ui/excerpts/quote_selection.d.ts +66 -0
- package/dist/ui/excerpts/quote_selection.d.ts.map +1 -0
- package/dist/ui/excerpts/transcript_quote_offer.d.ts +57 -0
- package/dist/ui/excerpts/transcript_quote_offer.d.ts.map +1 -0
- package/dist/ui/fill_ui_string.d.ts +32 -0
- package/dist/ui/fill_ui_string.d.ts.map +1 -0
- package/dist/ui/history/checkpoint_menu.d.ts +41 -0
- package/dist/ui/history/checkpoint_menu.d.ts.map +1 -0
- package/dist/ui/history/conversation_history.d.ts +317 -0
- package/dist/ui/history/conversation_history.d.ts.map +1 -0
- package/dist/ui/history/history_styles.d.ts +2 -0
- package/dist/ui/history/history_styles.d.ts.map +1 -0
- package/dist/ui/history/relative_time.d.ts +23 -0
- package/dist/ui/history/relative_time.d.ts.map +1 -0
- package/dist/ui/history/thread_drawer.d.ts +64 -0
- package/dist/ui/history/thread_drawer.d.ts.map +1 -0
- package/dist/ui/history/utils.d.ts +2 -0
- package/dist/ui/history/utils.d.ts.map +1 -0
- package/dist/ui/interrupts/approval_card.d.ts +64 -0
- package/dist/ui/interrupts/approval_card.d.ts.map +1 -0
- package/dist/ui/interrupts/approval_styles.d.ts +2 -0
- package/dist/ui/interrupts/approval_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/confirmation_card.d.ts +51 -0
- package/dist/ui/interrupts/confirmation_card.d.ts.map +1 -0
- package/dist/ui/interrupts/confirmation_styles.d.ts +2 -0
- package/dist/ui/interrupts/confirmation_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/pending_decision.d.ts +22 -0
- package/dist/ui/interrupts/pending_decision.d.ts.map +1 -0
- package/dist/ui/interrupts/question_card.d.ts +49 -0
- package/dist/ui/interrupts/question_card.d.ts.map +1 -0
- package/dist/ui/interrupts/question_styles.d.ts +2 -0
- package/dist/ui/interrupts/question_styles.d.ts.map +1 -0
- package/dist/ui/place/place.d.ts +17 -0
- package/dist/ui/place/place.d.ts.map +1 -0
- package/dist/ui/place/place_chip.d.ts +26 -0
- package/dist/ui/place/place_chip.d.ts.map +1 -0
- package/dist/ui/place/place_from_route.d.ts +9 -0
- package/dist/ui/place/place_from_route.d.ts.map +1 -0
- package/dist/ui/place/place_styles.d.ts +2 -0
- package/dist/ui/place/place_styles.d.ts.map +1 -0
- package/dist/ui/placement/clamp_launcher.d.ts +20 -0
- package/dist/ui/placement/clamp_launcher.d.ts.map +1 -0
- package/dist/ui/placement/clamp_panel.d.ts +13 -0
- package/dist/ui/placement/clamp_panel.d.ts.map +1 -0
- package/dist/ui/placement/collapse_styles.d.ts +2 -0
- package/dist/ui/placement/collapse_styles.d.ts.map +1 -0
- package/dist/ui/placement/dock_styles.d.ts +2 -0
- package/dist/ui/placement/dock_styles.d.ts.map +1 -0
- package/dist/ui/placement/embedded_styles.d.ts +2 -0
- package/dist/ui/placement/embedded_styles.d.ts.map +1 -0
- package/dist/ui/placement/launcher_drag.d.ts +49 -0
- package/dist/ui/placement/launcher_drag.d.ts.map +1 -0
- package/dist/ui/placement/launcher_placement.d.ts +77 -0
- package/dist/ui/placement/launcher_placement.d.ts.map +1 -0
- package/dist/ui/placement/launcher_styles.d.ts +2 -0
- package/dist/ui/placement/launcher_styles.d.ts.map +1 -0
- package/dist/ui/placement/page_styles.d.ts +2 -0
- package/dist/ui/placement/page_styles.d.ts.map +1 -0
- package/dist/ui/placement/panel_drag.d.ts +40 -0
- package/dist/ui/placement/panel_drag.d.ts.map +1 -0
- package/dist/ui/placement/panel_placement.d.ts +173 -0
- package/dist/ui/placement/panel_placement.d.ts.map +1 -0
- package/dist/ui/placement/place_widget.d.ts +31 -0
- package/dist/ui/placement/place_widget.d.ts.map +1 -0
- package/dist/ui/placement/preset_styles.d.ts +2 -0
- package/dist/ui/placement/preset_styles.d.ts.map +1 -0
- package/dist/ui/placement/resize_handle.d.ts +78 -0
- package/dist/ui/placement/resize_handle.d.ts.map +1 -0
- package/dist/ui/placement/resize_styles.d.ts +2 -0
- package/dist/ui/placement/resize_styles.d.ts.map +1 -0
- package/dist/ui/placement/sidebar_styles.d.ts +2 -0
- package/dist/ui/placement/sidebar_styles.d.ts.map +1 -0
- package/dist/ui/placement/small_viewport_styles.d.ts +2 -0
- package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -0
- package/dist/ui/placement/surface_for.d.ts +93 -0
- package/dist/ui/placement/surface_for.d.ts.map +1 -0
- package/dist/ui/progress/prettify_tool_name.d.ts +11 -0
- package/dist/ui/progress/prettify_tool_name.d.ts.map +1 -0
- package/dist/ui/progress/run_announcer.d.ts +41 -0
- package/dist/ui/progress/run_announcer.d.ts.map +1 -0
- package/dist/ui/progress/run_notice.d.ts +21 -0
- package/dist/ui/progress/run_notice.d.ts.map +1 -0
- package/dist/ui/progress/run_notice_styles.d.ts +2 -0
- package/dist/ui/progress/run_notice_styles.d.ts.map +1 -0
- package/dist/ui/progress/subagent_panel.d.ts +101 -0
- package/dist/ui/progress/subagent_panel.d.ts.map +1 -0
- package/dist/ui/progress/subagent_progress.d.ts +57 -0
- package/dist/ui/progress/subagent_progress.d.ts.map +1 -0
- package/dist/ui/progress/subagent_update.d.ts +28 -0
- package/dist/ui/progress/subagent_update.d.ts.map +1 -0
- package/dist/ui/progress/thoughts_block.d.ts +57 -0
- package/dist/ui/progress/thoughts_block.d.ts.map +1 -0
- package/dist/ui/progress/thoughts_styles.d.ts +2 -0
- package/dist/ui/progress/thoughts_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_call_card.d.ts +167 -0
- package/dist/ui/progress/tool_call_card.d.ts.map +1 -0
- package/dist/ui/progress/tool_group_styles.d.ts +2 -0
- package/dist/ui/progress/tool_group_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_group.d.ts +50 -0
- package/dist/ui/progress/tool_step_group.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_styles.d.ts +2 -0
- package/dist/ui/progress/tool_step_styles.d.ts.map +1 -0
- package/dist/ui/shell/adopt_styles.d.ts +28 -0
- package/dist/ui/shell/adopt_styles.d.ts.map +1 -0
- package/dist/ui/shell/build_header.d.ts +45 -0
- package/dist/ui/shell/build_header.d.ts.map +1 -0
- package/dist/ui/shell/build_launcher.d.ts +33 -0
- package/dist/ui/shell/build_launcher.d.ts.map +1 -0
- package/dist/ui/shell/collapse_glyph.d.ts +14 -0
- package/dist/ui/shell/collapse_glyph.d.ts.map +1 -0
- package/dist/ui/shell/frame_styles.d.ts +2 -0
- package/dist/ui/shell/frame_styles.d.ts.map +1 -0
- package/dist/ui/shell/glyph_slot.d.ts +7 -0
- package/dist/ui/shell/glyph_slot.d.ts.map +1 -0
- package/dist/ui/shell/header_button.d.ts +11 -0
- package/dist/ui/shell/header_button.d.ts.map +1 -0
- package/dist/ui/shell/icon_element.d.ts +12 -0
- package/dist/ui/shell/icon_element.d.ts.map +1 -0
- package/dist/ui/shell/is_unread_badge_enabled.d.ts +10 -0
- package/dist/ui/shell/is_unread_badge_enabled.d.ts.map +1 -0
- package/dist/ui/shell/read_launcher_icon_url.d.ts +8 -0
- package/dist/ui/shell/read_launcher_icon_url.d.ts.map +1 -0
- package/dist/ui/shell/theme_styles.d.ts +2 -0
- package/dist/ui/shell/theme_styles.d.ts.map +1 -0
- package/dist/ui/shell/token_styles.d.ts +2 -0
- package/dist/ui/shell/token_styles.d.ts.map +1 -0
- package/dist/ui/styles.d.ts +2 -0
- package/dist/ui/styles.d.ts.map +1 -0
- package/dist/ui/themes/classic_styles.d.ts +2 -0
- package/dist/ui/themes/classic_styles.d.ts.map +1 -0
- package/dist/ui/themes/classic_tokens.d.ts +2 -0
- package/dist/ui/themes/classic_tokens.d.ts.map +1 -0
- package/dist/ui/themes/code_tokens.d.ts +2 -0
- package/dist/ui/themes/code_tokens.d.ts.map +1 -0
- package/dist/ui/themes/ledger_styles.d.ts +2 -0
- package/dist/ui/themes/ledger_styles.d.ts.map +1 -0
- package/dist/ui/themes/ledger_tokens.d.ts +2 -0
- package/dist/ui/themes/ledger_tokens.d.ts.map +1 -0
- package/dist/ui/themes/modern_styles.d.ts +2 -0
- package/dist/ui/themes/modern_styles.d.ts.map +1 -0
- package/dist/ui/themes/quiet_styles.d.ts +2 -0
- package/dist/ui/themes/quiet_styles.d.ts.map +1 -0
- package/dist/ui/themes/scheme_styles.d.ts +2 -0
- package/dist/ui/themes/scheme_styles.d.ts.map +1 -0
- package/dist/ui/themes/soft_styles.d.ts +2 -0
- package/dist/ui/themes/soft_styles.d.ts.map +1 -0
- package/dist/ui/themes/soft_tokens.d.ts +2 -0
- package/dist/ui/themes/soft_tokens.d.ts.map +1 -0
- package/dist/ui/themes/theme_hosts.d.ts +15 -0
- package/dist/ui/themes/theme_hosts.d.ts.map +1 -0
- package/dist/ui/transcript/answer_actions.d.ts +50 -0
- package/dist/ui/transcript/answer_actions.d.ts.map +1 -0
- package/dist/ui/transcript/answer_stream.d.ts +56 -0
- package/dist/ui/transcript/answer_stream.d.ts.map +1 -0
- package/dist/ui/transcript/attachment_chip_styles.d.ts +2 -0
- package/dist/ui/transcript/attachment_chip_styles.d.ts.map +1 -0
- package/dist/ui/transcript/attachment_chips.d.ts +21 -0
- package/dist/ui/transcript/attachment_chips.d.ts.map +1 -0
- package/dist/ui/transcript/build_transcript.d.ts +21 -0
- package/dist/ui/transcript/build_transcript.d.ts.map +1 -0
- package/dist/ui/transcript/greeting_styles.d.ts +2 -0
- package/dist/ui/transcript/greeting_styles.d.ts.map +1 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts +13 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts.map +1 -0
- package/dist/ui/transcript/message_action_styles.d.ts +2 -0
- package/dist/ui/transcript/message_action_styles.d.ts.map +1 -0
- package/dist/ui/transcript/message_actions.d.ts +74 -0
- package/dist/ui/transcript/message_actions.d.ts.map +1 -0
- package/dist/ui/transcript/message_styles.d.ts +2 -0
- package/dist/ui/transcript/message_styles.d.ts.map +1 -0
- package/dist/ui/transcript/render_markdown.d.ts +40 -0
- package/dist/ui/transcript/render_markdown.d.ts.map +1 -0
- package/dist/ui/transcript/render_or_warn.d.ts +16 -0
- package/dist/ui/transcript/render_or_warn.d.ts.map +1 -0
- package/dist/ui/transcript/reveal_words.d.ts +8 -0
- package/dist/ui/transcript/reveal_words.d.ts.map +1 -0
- package/dist/ui/transcript/starter_chips.d.ts +21 -0
- package/dist/ui/transcript/starter_chips.d.ts.map +1 -0
- package/dist/ui/transcript/stick_to_bottom.d.ts +55 -0
- package/dist/ui/transcript/stick_to_bottom.d.ts.map +1 -0
- package/dist/ui/transcript/suggestion_chips.d.ts +29 -0
- package/dist/ui/transcript/suggestion_chips.d.ts.map +1 -0
- package/dist/ui/transcript/transcript.d.ts +196 -0
- package/dist/ui/transcript/transcript.d.ts.map +1 -0
- package/dist/ui/transcript/transcript_styles.d.ts +2 -0
- package/dist/ui/transcript/transcript_styles.d.ts.map +1 -0
- package/dist/ui/ui_strings.d.ts +352 -0
- package/dist/ui/ui_strings.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +86 -3
- package/src/bundle.ts +2 -0
- package/src/chat.ts +2 -0
- package/src/constants.ts +650 -0
- package/src/core/activity_registration.ts +19 -0
- package/src/core/activity_registry.ts +133 -0
- package/src/core/activity_renderer.ts +19 -0
- package/src/core/ag_ui_chat.ts +3966 -0
- package/src/core/agui_client.ts +1028 -0
- package/src/core/attachment.ts +62 -0
- package/src/core/chat_registry.ts +53 -0
- package/src/core/client_seed.ts +27 -0
- package/src/core/conversation_store.ts +478 -0
- package/src/core/create_http_agent.ts +97 -0
- package/src/core/define_chat.ts +25 -0
- package/src/core/events/attachments_detail.ts +9 -0
- package/src/core/events/bar_height_detail.ts +5 -0
- package/src/core/events/custom_agent_detail.ts +7 -0
- package/src/core/events/dock_width_detail.ts +7 -0
- package/src/core/events/feedback_detail.ts +27 -0
- package/src/core/events/invalidate_detail.ts +15 -0
- package/src/core/events/maximize_detail.ts +4 -0
- package/src/core/events/run_finished_detail.ts +36 -0
- package/src/core/events/state_detail.ts +4 -0
- package/src/core/events/submit_detail.ts +8 -0
- package/src/core/events/thread_detail.ts +26 -0
- package/src/core/events/thread_title_detail.ts +7 -0
- package/src/core/events/toggle_detail.ts +4 -0
- package/src/core/events/tool_run.ts +10 -0
- package/src/core/events/unread_detail.ts +10 -0
- package/src/core/message_role.ts +4 -0
- package/src/core/read_flag.ts +13 -0
- package/src/core/read_json_attribute.ts +30 -0
- package/src/core/read_max_tool_rounds.ts +13 -0
- package/src/core/remote_conversation_store.ts +279 -0
- package/src/core/run_handlers.ts +524 -0
- package/src/core/run_index.ts +114 -0
- package/src/core/storage_scope.ts +291 -0
- package/src/core/tool_outcome.ts +39 -0
- package/src/core/transcribe_audio.ts +76 -0
- package/src/core/upload_attachment.ts +130 -0
- package/src/core/utils.ts +230 -0
- package/src/dom/animations.ts +341 -0
- package/src/dom/dom_driver.ts +91 -0
- package/src/dom/highlight_overlay.ts +204 -0
- package/src/dom/native_setter.ts +40 -0
- package/src/dom/ring_color.ts +206 -0
- package/src/dom/utils.ts +5 -0
- package/src/index.ts +220 -0
- package/src/skills/fill_template.ts +31 -0
- package/src/skills/parse_skills.ts +31 -0
- package/src/skills/skill.ts +32 -0
- package/src/skills/skill_catalog.ts +172 -0
- package/src/skills/skill_name_from.ts +19 -0
- package/src/tools/chat_surface_tools.ts +183 -0
- package/src/tools/client_tool_registry.ts +80 -0
- package/src/tools/is_destructive.ts +17 -0
- package/src/tools/is_navigates.ts +12 -0
- package/src/tools/page_action_tools.ts +123 -0
- package/src/tools/page_map.ts +26 -0
- package/src/tools/page_state.ts +57 -0
- package/src/tools/parse_tool_catalog.ts +41 -0
- package/src/tools/route_map.ts +132 -0
- package/src/tools/tool_catalog.ts +334 -0
- package/src/tools/tool_dispatch.ts +453 -0
- package/src/ui/charts/chart_block.ts +519 -0
- package/src/ui/charts/chart_spec_from.ts +125 -0
- package/src/ui/charts/chart_styles.ts +63 -0
- package/src/ui/charts/chart_tool.ts +72 -0
- package/src/ui/composer/attachment_styles.ts +71 -0
- package/src/ui/composer/attachment_tray.ts +295 -0
- package/src/ui/composer/auto_grow.ts +12 -0
- package/src/ui/composer/build_composer.ts +114 -0
- package/src/ui/composer/composer_attachments.ts +324 -0
- package/src/ui/composer/composer_styles.ts +177 -0
- package/src/ui/composer/composer_voice.ts +93 -0
- package/src/ui/composer/skill_styles.ts +120 -0
- package/src/ui/composer/skills_menu.ts +188 -0
- package/src/ui/composer/voice_input.ts +282 -0
- package/src/ui/excerpts/attach_copy_buttons.ts +73 -0
- package/src/ui/excerpts/copy_payload.ts +156 -0
- package/src/ui/excerpts/page_quote_offer.ts +203 -0
- package/src/ui/excerpts/place_offer.ts +24 -0
- package/src/ui/excerpts/quote_selection.ts +345 -0
- package/src/ui/excerpts/transcript_quote_offer.ts +175 -0
- package/src/ui/fill_ui_string.ts +41 -0
- package/src/ui/history/checkpoint_menu.ts +300 -0
- package/src/ui/history/conversation_history.ts +1169 -0
- package/src/ui/history/history_styles.ts +492 -0
- package/src/ui/history/relative_time.ts +50 -0
- package/src/ui/history/thread_drawer.ts +471 -0
- package/src/ui/history/utils.ts +11 -0
- package/src/ui/interrupts/approval_card.ts +202 -0
- package/src/ui/interrupts/approval_styles.ts +52 -0
- package/src/ui/interrupts/confirmation_card.ts +138 -0
- package/src/ui/interrupts/confirmation_styles.ts +114 -0
- package/src/ui/interrupts/pending_decision.ts +33 -0
- package/src/ui/interrupts/question_card.ts +213 -0
- package/src/ui/interrupts/question_styles.ts +73 -0
- package/src/ui/place/place.ts +16 -0
- package/src/ui/place/place_chip.ts +146 -0
- package/src/ui/place/place_from_route.ts +27 -0
- package/src/ui/place/place_styles.ts +108 -0
- package/src/ui/placement/clamp_launcher.ts +38 -0
- package/src/ui/placement/clamp_panel.ts +30 -0
- package/src/ui/placement/collapse_styles.ts +472 -0
- package/src/ui/placement/dock_styles.ts +116 -0
- package/src/ui/placement/embedded_styles.ts +14 -0
- package/src/ui/placement/launcher_drag.ts +206 -0
- package/src/ui/placement/launcher_placement.ts +133 -0
- package/src/ui/placement/launcher_styles.ts +189 -0
- package/src/ui/placement/page_styles.ts +47 -0
- package/src/ui/placement/panel_drag.ts +138 -0
- package/src/ui/placement/panel_placement.ts +1975 -0
- package/src/ui/placement/place_widget.ts +64 -0
- package/src/ui/placement/preset_styles.ts +49 -0
- package/src/ui/placement/resize_handle.ts +229 -0
- package/src/ui/placement/resize_styles.ts +201 -0
- package/src/ui/placement/sidebar_styles.ts +113 -0
- package/src/ui/placement/small_viewport_styles.ts +70 -0
- package/src/ui/placement/surface_for.ts +183 -0
- package/src/ui/progress/prettify_tool_name.ts +16 -0
- package/src/ui/progress/run_announcer.ts +67 -0
- package/src/ui/progress/run_notice.ts +61 -0
- package/src/ui/progress/run_notice_styles.ts +52 -0
- package/src/ui/progress/subagent_panel.ts +227 -0
- package/src/ui/progress/subagent_progress.ts +200 -0
- package/src/ui/progress/subagent_update.ts +89 -0
- package/src/ui/progress/thoughts_block.ts +165 -0
- package/src/ui/progress/thoughts_styles.ts +74 -0
- package/src/ui/progress/tool_call_card.ts +429 -0
- package/src/ui/progress/tool_group_styles.ts +313 -0
- package/src/ui/progress/tool_step_group.ts +317 -0
- package/src/ui/progress/tool_step_styles.ts +486 -0
- package/src/ui/shell/adopt_styles.ts +34 -0
- package/src/ui/shell/build_header.ts +121 -0
- package/src/ui/shell/build_launcher.ts +79 -0
- package/src/ui/shell/collapse_glyph.ts +42 -0
- package/src/ui/shell/frame_styles.ts +147 -0
- package/src/ui/shell/glyph_slot.ts +12 -0
- package/src/ui/shell/header_button.ts +22 -0
- package/src/ui/shell/icon_element.ts +33 -0
- package/src/ui/shell/is_unread_badge_enabled.ts +11 -0
- package/src/ui/shell/read_launcher_icon_url.ts +9 -0
- package/src/ui/shell/theme_styles.ts +11 -0
- package/src/ui/shell/token_styles.ts +480 -0
- package/src/ui/styles.ts +110 -0
- package/src/ui/themes/classic_styles.ts +32 -0
- package/src/ui/themes/classic_tokens.ts +51 -0
- package/src/ui/themes/code_tokens.ts +21 -0
- package/src/ui/themes/ledger_styles.ts +169 -0
- package/src/ui/themes/ledger_tokens.ts +33 -0
- package/src/ui/themes/modern_styles.ts +80 -0
- package/src/ui/themes/quiet_styles.ts +118 -0
- package/src/ui/themes/scheme_styles.ts +26 -0
- package/src/ui/themes/soft_styles.ts +149 -0
- package/src/ui/themes/soft_tokens.ts +29 -0
- package/src/ui/themes/theme_hosts.ts +14 -0
- package/src/ui/transcript/answer_actions.ts +165 -0
- package/src/ui/transcript/answer_stream.ts +123 -0
- package/src/ui/transcript/attachment_chip_styles.ts +116 -0
- package/src/ui/transcript/attachment_chips.ts +82 -0
- package/src/ui/transcript/build_transcript.ts +67 -0
- package/src/ui/transcript/greeting_styles.ts +171 -0
- package/src/ui/transcript/groups_tool_steps.ts +16 -0
- package/src/ui/transcript/message_action_styles.ts +155 -0
- package/src/ui/transcript/message_actions.ts +234 -0
- package/src/ui/transcript/message_styles.ts +262 -0
- package/src/ui/transcript/render_markdown.ts +181 -0
- package/src/ui/transcript/render_or_warn.ts +22 -0
- package/src/ui/transcript/reveal_words.ts +41 -0
- package/src/ui/transcript/starter_chips.ts +42 -0
- package/src/ui/transcript/stick_to_bottom.ts +126 -0
- package/src/ui/transcript/suggestion_chips.ts +73 -0
- package/src/ui/transcript/transcript.ts +555 -0
- package/src/ui/transcript/transcript_styles.ts +153 -0
- package/src/ui/ui_strings.ts +550 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a text selection out of the shadow tree, and shaping it for the
|
|
3
|
+
* composer.
|
|
4
|
+
*
|
|
5
|
+
* Selection is the one DOM API shadow encapsulation genuinely broke, and it
|
|
6
|
+
* broke it in two different directions. WebKit rescopes a selection made inside
|
|
7
|
+
* a shadow tree to the **host** element, so `document.getSelection()` reports
|
|
8
|
+
* the whole widget and none of the words; Chromium exposes the shadow nodes
|
|
9
|
+
* directly, so the same call reports exactly the words. `getComposedRanges` is
|
|
10
|
+
* the settled answer to both -- it hands back real endpoints for each shadow
|
|
11
|
+
* root it is *given permission to see* -- but it is recent enough that the
|
|
12
|
+
* direct read has to stay behind it.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The longest quotation put into the composer, in characters.
|
|
17
|
+
*
|
|
18
|
+
* A cap rather than no cap because the point of a quotation is to say *which*
|
|
19
|
+
* part of an answer the next question is about. Select-all-then-quote is a
|
|
20
|
+
* gesture the transcript already answers -- it is the whole conversation, which
|
|
21
|
+
* the model has -- and pasting it back costs the user tokens to say nothing.
|
|
22
|
+
*/
|
|
23
|
+
export const MAX_QUOTE_CHARS = 500;
|
|
24
|
+
|
|
25
|
+
/** A selection worth offering to quote. */
|
|
26
|
+
export interface QuotableSelection {
|
|
27
|
+
/** The selected text, trimmed. Never empty. */
|
|
28
|
+
readonly text: string;
|
|
29
|
+
/**
|
|
30
|
+
* One **line** of the selection, for placing the affordance beside it.
|
|
31
|
+
*
|
|
32
|
+
* Deliberately not the selection's bounding box. See {@link lineToHangFrom}:
|
|
33
|
+
* the union of a selection spanning several elements has a centre with no
|
|
34
|
+
* selected text anywhere near it.
|
|
35
|
+
*/
|
|
36
|
+
readonly rect: DOMRect;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Where a gesture ended, in viewport coordinates. */
|
|
40
|
+
export interface Point {
|
|
41
|
+
readonly x: number;
|
|
42
|
+
readonly y: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A `Selection` on an engine new enough to reach into a shadow tree. */
|
|
46
|
+
type ComposedSelection = Selection & {
|
|
47
|
+
getComposedRanges?: (...args: readonly unknown[]) => readonly AbstractRange[];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The current selection, when it lies wholly inside `container`.
|
|
52
|
+
*
|
|
53
|
+
* `roots` are the shadow roots the read is allowed to look inside, in the shape
|
|
54
|
+
* `getComposedRanges` itself takes. Pass the one holding `container` for a
|
|
55
|
+
* selection made in a shadow tree, or nothing at all for one made in the page.
|
|
56
|
+
*
|
|
57
|
+
* `near` is where the gesture ended, when a pointer made it -- it decides which
|
|
58
|
+
* line of a multi-line selection the offer is hung from.
|
|
59
|
+
*
|
|
60
|
+
* `null` for no selection, a collapsed one, whitespace only, or one that
|
|
61
|
+
* starts or ends outside `container` -- a drag that ran off the transcript and
|
|
62
|
+
* into the page is not a quotation from the transcript.
|
|
63
|
+
*/
|
|
64
|
+
export function quotableSelection(
|
|
65
|
+
container: HTMLElement,
|
|
66
|
+
roots: readonly ShadowRoot[] = [],
|
|
67
|
+
near?: Point,
|
|
68
|
+
): QuotableSelection | null {
|
|
69
|
+
for (const endpoints of endpointCandidates(roots)) {
|
|
70
|
+
if (!container.contains(endpoints.startContainer)) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (!container.contains(endpoints.endContainer)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// A live `Range` regardless of what the engine handed back: `getComposedRanges`
|
|
77
|
+
// returns `StaticRange`s, which carry endpoints and nothing else -- no text,
|
|
78
|
+
// no geometry. Both are what this is for.
|
|
79
|
+
const range = document.createRange();
|
|
80
|
+
range.setStart(endpoints.startContainer, endpoints.startOffset);
|
|
81
|
+
range.setEnd(endpoints.endContainer, endpoints.endOffset);
|
|
82
|
+
const text = renderedText(range).trim();
|
|
83
|
+
if (text === "") {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
return { text, rect: lineToHangFrom(range, near) };
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Wrap `text` as a markdown blockquote, ready to be followed by a question.
|
|
93
|
+
*
|
|
94
|
+
* Markdown rather than a bespoke fence because the transcript renders markdown
|
|
95
|
+
* and the server reads markdown: a quotation that survives both ends without a
|
|
96
|
+
* convention to agree on first. The trailing blank line is what leaves the
|
|
97
|
+
* caret on a fresh paragraph, which is the whole point of quoting into a
|
|
98
|
+
* composer rather than sending straight away.
|
|
99
|
+
*/
|
|
100
|
+
export function asQuote(text: string): string {
|
|
101
|
+
const lines = tidy(text);
|
|
102
|
+
if (lines.length === 0) {
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
const capped = cap(lines.join("\n"));
|
|
106
|
+
const quoted = capped
|
|
107
|
+
.split("\n")
|
|
108
|
+
// `trimEnd` so a blank line inside the selection becomes a bare ">" rather
|
|
109
|
+
// than "> " -- trailing whitespace markdown treats as a line break.
|
|
110
|
+
.map((line) => `> ${line}`.trimEnd())
|
|
111
|
+
.join("\n");
|
|
112
|
+
return `${quoted}\n\n`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The selection's lines, with the *markup's* whitespace taken back out.
|
|
117
|
+
*
|
|
118
|
+
* A selection crossing block elements carries the source's own layout with it:
|
|
119
|
+
* every newline and every run of indentation between one element and the next
|
|
120
|
+
* is a text node like any other. Quoting a form as marked up produced twenty-
|
|
121
|
+
* four lines of which twelve were a bare ">", the rest indented by wherever
|
|
122
|
+
* they happened to sit in the HTML. That is not a quotation of anything.
|
|
123
|
+
*
|
|
124
|
+
* Two rules, and deliberately only two. Runs of blank lines collapse to one,
|
|
125
|
+
* because the gap between two blocks is one gap however it was written. And the
|
|
126
|
+
* indentation every line shares is removed, not each line's own -- a quotation
|
|
127
|
+
* from a code block keeps its shape, which trimming each line would flatten.
|
|
128
|
+
*/
|
|
129
|
+
function tidy(text: string): readonly string[] {
|
|
130
|
+
const lines = text.split(/\r\n?|\n/).map((line) => line.trimEnd());
|
|
131
|
+
const indents = lines.filter((line) => line !== "").map(indentOf);
|
|
132
|
+
const shared = indents.length === 0 ? 0 : Math.min(...indents);
|
|
133
|
+
const kept: string[] = [];
|
|
134
|
+
for (const line of lines) {
|
|
135
|
+
const dedented = line.slice(shared);
|
|
136
|
+
// No leading blank lines, and never two in a row.
|
|
137
|
+
if (dedented === "" && (kept.length === 0 || kept[kept.length - 1] === "")) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
kept.push(dedented);
|
|
141
|
+
}
|
|
142
|
+
while (kept[kept.length - 1] === "") {
|
|
143
|
+
kept.pop();
|
|
144
|
+
}
|
|
145
|
+
return kept;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** How many spaces of indentation `line` opens with. */
|
|
149
|
+
function indentOf(line: string): number {
|
|
150
|
+
return line.length - line.trimStart().length;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** `text`, cut to {@link MAX_QUOTE_CHARS} if it runs past it. */
|
|
154
|
+
function cap(text: string): string {
|
|
155
|
+
return text.length > MAX_QUOTE_CHARS ? `${text.slice(0, MAX_QUOTE_CHARS).trimEnd()}...` : text;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The selected text **as rendered**, which is not what `Range.toString()` says.
|
|
160
|
+
*
|
|
161
|
+
* `toString()` concatenates the text nodes in the range and asks no questions
|
|
162
|
+
* about CSS, so a drag across an ordinary form quotes back the values of every
|
|
163
|
+
* `<option>` in a closed `<select>` -- words the user has never seen, presented
|
|
164
|
+
* to the model as something they pointed at. `checkVisibility()` is the
|
|
165
|
+
* platform's own answer to "is this actually rendered", and it reports exactly
|
|
166
|
+
* those options as hidden.
|
|
167
|
+
*
|
|
168
|
+
* Older engines without it keep the previous behaviour rather than a guess:
|
|
169
|
+
* quoting a few invisible words is a smaller failure than dropping visible ones
|
|
170
|
+
* because a hand-rolled visibility test was wrong.
|
|
171
|
+
*/
|
|
172
|
+
function renderedText(range: Range): string {
|
|
173
|
+
let text = "";
|
|
174
|
+
for (const node of textNodesIn(range)) {
|
|
175
|
+
// The element carries the styles; the text node has none of its own.
|
|
176
|
+
const parent = node.parentElement as HTMLElement;
|
|
177
|
+
if (!isRendered(parent)) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
// The end nodes are only partly inside the range; everything between them
|
|
181
|
+
// is wholly inside it.
|
|
182
|
+
const from = node === range.startContainer ? range.startOffset : 0;
|
|
183
|
+
const to = node === range.endContainer ? range.endOffset : node.data.length;
|
|
184
|
+
text += collapse(node.data.slice(from, to), parent);
|
|
185
|
+
}
|
|
186
|
+
return text;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Squeeze the runs of spaces the renderer squeezes, and keep the ones it keeps.
|
|
191
|
+
*
|
|
192
|
+
* Indentation between block elements is markup, not content: it is in the DOM
|
|
193
|
+
* as text nodes and it is on screen as nothing at all, because a collapsing
|
|
194
|
+
* `white-space` reduces it. Carrying it into a quotation is not merely untidy --
|
|
195
|
+
* four leading spaces inside a blockquote is a markdown **code block**, so a
|
|
196
|
+
* form quoted as marked up renders as source listing.
|
|
197
|
+
*
|
|
198
|
+
* Newlines survive on purpose, where CSS would collapse those too. They are the
|
|
199
|
+
* only record left of where one block ended and the next began, and a quotation
|
|
200
|
+
* of six form rows run together on one line is worse than one that keeps them
|
|
201
|
+
* apart. Preformatted text is passed through untouched: there the indentation
|
|
202
|
+
* *is* the content.
|
|
203
|
+
*/
|
|
204
|
+
function collapse(text: string, parent: HTMLElement): string {
|
|
205
|
+
if (PREFORMATTED.has(whiteSpaceOf(parent))) {
|
|
206
|
+
return text;
|
|
207
|
+
}
|
|
208
|
+
return (
|
|
209
|
+
text
|
|
210
|
+
// Whitespace *around* a newline goes with it. Leaving a space behind
|
|
211
|
+
// would indent every line of the quotation by one, for nothing.
|
|
212
|
+
.replace(/[^\S\n]*\n[^\S\n]*/g, "\n")
|
|
213
|
+
.replace(/[^\S\n]+/g, " ")
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** The `white-space` values under which every space is content. */
|
|
218
|
+
const PREFORMATTED = new Set(["pre", "pre-wrap", "break-spaces"]);
|
|
219
|
+
|
|
220
|
+
/** The computed `white-space` of `element`, or `""` where it cannot be read. */
|
|
221
|
+
function whiteSpaceOf(element: HTMLElement): string {
|
|
222
|
+
return window.getComputedStyle(element).whiteSpace;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Every text node the range touches, in document order. */
|
|
226
|
+
function textNodesIn(range: Range): readonly Text[] {
|
|
227
|
+
const root = range.commonAncestorContainer;
|
|
228
|
+
// A selection inside a single text node has that node as its own common
|
|
229
|
+
// ancestor, and a `TreeWalker` never visits its root.
|
|
230
|
+
if (root.nodeType === Node.TEXT_NODE) {
|
|
231
|
+
return [root as Text];
|
|
232
|
+
}
|
|
233
|
+
const found: Text[] = [];
|
|
234
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
235
|
+
for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
|
|
236
|
+
// The walker covers the whole subtree, which reaches past both ends of the
|
|
237
|
+
// range -- a sibling paragraph above the selection is in it too.
|
|
238
|
+
if (range.intersectsNode(node)) {
|
|
239
|
+
found.push(node as Text);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return found;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Whether `element` is actually drawn, where the engine will say. */
|
|
246
|
+
function isRendered(element: HTMLElement): boolean {
|
|
247
|
+
if (typeof element.checkVisibility !== "function") {
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
return element.checkVisibility({
|
|
251
|
+
contentVisibilityAuto: true,
|
|
252
|
+
opacityProperty: true,
|
|
253
|
+
visibilityProperty: true,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* The line of the selection to hang the offer from.
|
|
259
|
+
*
|
|
260
|
+
* **Not the bounding box.** A drag from a narrow column of a form down to a
|
|
261
|
+
* full-width line running under the chat panel beside it produced a union
|
|
262
|
+
* reaching from the column's left edge to the far end of that line -- and its
|
|
263
|
+
* centre landed most of the way across the page, behind the panel, on a line
|
|
264
|
+
* the user had not been looking at, while the pointer had let go by the column.
|
|
265
|
+
*
|
|
266
|
+
* Note what the fix is *not*: that centre was over selected text. It was over
|
|
267
|
+
* selected text nobody could see. A union is a shape the selection does not
|
|
268
|
+
* have, so no point derived from it belongs to any particular line.
|
|
269
|
+
*
|
|
270
|
+
* `near` is where the pointer let go. The line under it is where the user is
|
|
271
|
+
* looking, and it needs no engine-specific way to ask which end of the
|
|
272
|
+
* selection is its focus -- which the shadow-aware read does not carry anyway.
|
|
273
|
+
* Without a pointer -- a keyboard selection -- the first line is the one that
|
|
274
|
+
* exists whichever way the selection was made.
|
|
275
|
+
*
|
|
276
|
+
* The bounding box remains the fallback for a range that reports no line boxes
|
|
277
|
+
* at all, which is what a DOM with no layout does.
|
|
278
|
+
*/
|
|
279
|
+
function lineToHangFrom(range: Range, near: Point | undefined): DOMRect {
|
|
280
|
+
const lines = [...range.getClientRects()];
|
|
281
|
+
if (lines.length === 0) {
|
|
282
|
+
return range.getBoundingClientRect();
|
|
283
|
+
}
|
|
284
|
+
if (near === undefined) {
|
|
285
|
+
return lines[0] as DOMRect;
|
|
286
|
+
}
|
|
287
|
+
let closest = lines[0] as DOMRect;
|
|
288
|
+
let shortest = distanceTo(closest, near);
|
|
289
|
+
for (const line of lines.slice(1)) {
|
|
290
|
+
const distance = distanceTo(line, near);
|
|
291
|
+
if (distance < shortest) {
|
|
292
|
+
shortest = distance;
|
|
293
|
+
closest = line;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return closest;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/** How far `point` is from the nearest edge of `rect`, or 0 inside it. */
|
|
300
|
+
function distanceTo(rect: DOMRect, point: Point): number {
|
|
301
|
+
const dx = Math.max(rect.left - point.x, 0, point.x - rect.right);
|
|
302
|
+
const dy = Math.max(rect.top - point.y, 0, point.y - rect.bottom);
|
|
303
|
+
return Math.hypot(dx, dy);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Endpoint pairs to consider, best first.
|
|
308
|
+
*
|
|
309
|
+
* Both reads are offered rather than one being chosen, because which is correct
|
|
310
|
+
* is a property of the engine *and* of where the user dragged: an engine that
|
|
311
|
+
* rescopes to the host returns endpoints outside the transcript, and the caller
|
|
312
|
+
* rejects those on the same test it uses for a selection that genuinely ran off
|
|
313
|
+
* the transcript. One rule, no engine sniffing.
|
|
314
|
+
*/
|
|
315
|
+
function endpointCandidates(roots: readonly ShadowRoot[]): readonly AbstractRange[] {
|
|
316
|
+
const selection = window.getSelection();
|
|
317
|
+
if (selection === null) {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
const candidates = [...composedRanges(selection, roots)];
|
|
321
|
+
if (selection.rangeCount > 0) {
|
|
322
|
+
candidates.push(selection.getRangeAt(0));
|
|
323
|
+
}
|
|
324
|
+
return candidates;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/** The shadow-aware read, or nothing on an engine that does not have it. */
|
|
328
|
+
function composedRanges(
|
|
329
|
+
selection: Selection,
|
|
330
|
+
roots: readonly ShadowRoot[],
|
|
331
|
+
): readonly AbstractRange[] {
|
|
332
|
+
const composed = (selection as ComposedSelection).getComposedRanges;
|
|
333
|
+
if (composed === undefined) {
|
|
334
|
+
return [];
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
return composed.call(selection, { shadowRoots: roots });
|
|
338
|
+
} catch {
|
|
339
|
+
// The method shipped first with the shadow roots as rest parameters and
|
|
340
|
+
// only later as a dictionary member, and the earlier form rejects the
|
|
341
|
+
// options object outright rather than ignoring it. Lexical resolves the
|
|
342
|
+
// same split the same way, by trying both shapes at runtime.
|
|
343
|
+
return composed.call(selection, ...roots);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { UiStrings } from "../ui_strings.js";
|
|
2
|
+
import { attachQuoteOffer, type PageQuoteOffer } from "./page_quote_offer.js";
|
|
3
|
+
import { placeOffer } from "./place_offer.js";
|
|
4
|
+
import { asQuote, quotableSelection } from "./quote_selection.js";
|
|
5
|
+
|
|
6
|
+
/** What the quote offer needs from the element that owns it. */
|
|
7
|
+
export interface TranscriptQuoteHost {
|
|
8
|
+
/** The custom element: its opt-out attribute, and what a page offer excludes. */
|
|
9
|
+
readonly element: HTMLElement;
|
|
10
|
+
/** The shadow root a transcript selection is read through. */
|
|
11
|
+
readonly root: ShadowRoot;
|
|
12
|
+
/** The transcript, whose selections are offered. */
|
|
13
|
+
readonly messages: HTMLElement;
|
|
14
|
+
/** The transcript's positioning box, which the offer floats inside. */
|
|
15
|
+
readonly messagesWrap: HTMLElement;
|
|
16
|
+
/** The composer a quotation is written into. */
|
|
17
|
+
readonly input: HTMLTextAreaElement;
|
|
18
|
+
/** The resolved string table. */
|
|
19
|
+
readonly strings: () => UiStrings;
|
|
20
|
+
/** Resize the composer to what it now holds. */
|
|
21
|
+
readonly autoGrow: () => void;
|
|
22
|
+
/** The element's public `quote`, so a host that replaced it is the one called. */
|
|
23
|
+
readonly quote: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Quoting a selection into the composer: the offer floated beside a selection
|
|
28
|
+
* in the transcript, the same offer over the host page, and the quotation
|
|
29
|
+
* itself.
|
|
30
|
+
*
|
|
31
|
+
* Owned one-to-one by an `<ag-ui-chat>`, and holding no state outside the
|
|
32
|
+
* instance.
|
|
33
|
+
*/
|
|
34
|
+
export class TranscriptQuoteOffer {
|
|
35
|
+
/**
|
|
36
|
+
* Offer to quote the current selection, floated beside it.
|
|
37
|
+
*
|
|
38
|
+
* Shares the transcript's positioning box with the jump button for the same
|
|
39
|
+
* reason: it is positioned against the transcript, and must not scroll away
|
|
40
|
+
* with the words it is pointing at.
|
|
41
|
+
*/
|
|
42
|
+
readonly button: HTMLButtonElement = document.createElement("button");
|
|
43
|
+
|
|
44
|
+
readonly #host: TranscriptQuoteHost;
|
|
45
|
+
/** What {@link button} would quote, while it is showing. */
|
|
46
|
+
#quoting = "";
|
|
47
|
+
/** The host-page offer, while one is attached; see {@link offerInPage}. */
|
|
48
|
+
#pageQuote: PageQuoteOffer | null = null;
|
|
49
|
+
|
|
50
|
+
constructor(host: TranscriptQuoteHost) {
|
|
51
|
+
this.#host = host;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** The quotation behind `AgUiChat.quote`, whose doc is the contract. */
|
|
55
|
+
insert(text: string): void {
|
|
56
|
+
const quoted = asQuote(text);
|
|
57
|
+
if (quoted === "") {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const input = this.#host.input;
|
|
61
|
+
// Appended after whatever is already typed, on a fresh paragraph: a second
|
|
62
|
+
// quotation is a second thing being asked about, not a replacement for the
|
|
63
|
+
// first. Trailing blank lines are dropped so repeated quoting does not
|
|
64
|
+
// accumulate gaps.
|
|
65
|
+
const current = input.value.replace(/\s+$/, "");
|
|
66
|
+
input.value = current === "" ? quoted : `${current}\n\n${quoted}`;
|
|
67
|
+
this.#host.autoGrow();
|
|
68
|
+
input.focus();
|
|
69
|
+
const end = input.value.length;
|
|
70
|
+
input.setSelectionRange(end, end);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The offer behind `AgUiChat.offerQuoteInPage`, whose doc is the contract. */
|
|
74
|
+
offerInPage(within: HTMLElement): () => void {
|
|
75
|
+
this.#pageQuote?.detach();
|
|
76
|
+
const offer = attachQuoteOffer({
|
|
77
|
+
within,
|
|
78
|
+
label: this.#host.strings().quoteSelection,
|
|
79
|
+
exclude: this.#host.element,
|
|
80
|
+
onQuote: (text) => this.#host.quote(text),
|
|
81
|
+
});
|
|
82
|
+
this.#pageQuote = offer;
|
|
83
|
+
return () => {
|
|
84
|
+
offer.detach();
|
|
85
|
+
if (this.#pageQuote === offer) {
|
|
86
|
+
this.#pageQuote = null;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Take the host-page offer down. It listens on the host's document, not on
|
|
93
|
+
* anything of ours, so nothing else would ever take it down.
|
|
94
|
+
*/
|
|
95
|
+
detachPageOffer(): void {
|
|
96
|
+
this.#pageQuote?.detach();
|
|
97
|
+
this.#pageQuote = null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Build the offer and listen for settled selections in the transcript.
|
|
102
|
+
*
|
|
103
|
+
* The button and the transcript outlive a connection, so the listeners go
|
|
104
|
+
* under `signal`, which the element aborts when it leaves the document.
|
|
105
|
+
*/
|
|
106
|
+
mount(signal: AbortSignal): void {
|
|
107
|
+
const button = this.button;
|
|
108
|
+
button.className = "quote-selection";
|
|
109
|
+
button.type = "button";
|
|
110
|
+
button.setAttribute("part", "quote-selection");
|
|
111
|
+
button.textContent = this.#host.strings().quoteSelection;
|
|
112
|
+
button.hidden = true;
|
|
113
|
+
// `mousedown` rather than `click`: pressing anywhere else collapses the
|
|
114
|
+
// selection first, and by the time a click lands there is nothing left to
|
|
115
|
+
// quote. Preventing the default keeps the selection alive long enough to
|
|
116
|
+
// read it.
|
|
117
|
+
button.addEventListener(
|
|
118
|
+
"mousedown",
|
|
119
|
+
(event) => {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
},
|
|
122
|
+
{ signal },
|
|
123
|
+
);
|
|
124
|
+
button.addEventListener(
|
|
125
|
+
"click",
|
|
126
|
+
() => {
|
|
127
|
+
this.#host.quote(this.#quoting);
|
|
128
|
+
window.getSelection()?.removeAllRanges();
|
|
129
|
+
this.#hide();
|
|
130
|
+
},
|
|
131
|
+
{ signal },
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// A settled selection, by either input. `mouseup` rather than
|
|
135
|
+
// `selectionchange` so the offer does not chase the pointer mid-drag; the
|
|
136
|
+
// second half of the same gesture, `mousedown`, retires the previous offer
|
|
137
|
+
// before the new selection exists.
|
|
138
|
+
const messages = this.#host.messages;
|
|
139
|
+
messages.addEventListener("mouseup", (event) => this.#onSelectionSettled(event), { signal });
|
|
140
|
+
messages.addEventListener("keyup", () => this.#onSelectionSettled(), { signal });
|
|
141
|
+
messages.addEventListener("mousedown", () => this.#hide(), { signal });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Whether the transcript offers to quote what the user selects. */
|
|
145
|
+
#enabled(): boolean {
|
|
146
|
+
return this.#host.element.getAttribute("data-quote-selection") !== "false";
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Offer to quote the settled selection, or retire the offer.
|
|
151
|
+
*
|
|
152
|
+
* `event` is passed for its coordinates and only those: they say which line
|
|
153
|
+
* of a selection spanning several messages the offer should hang from. A
|
|
154
|
+
* keyboard selection has none, and the first line is used instead.
|
|
155
|
+
*/
|
|
156
|
+
#onSelectionSettled(event?: MouseEvent): void {
|
|
157
|
+
if (!this.#enabled()) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const near = event === undefined ? undefined : { x: event.clientX, y: event.clientY };
|
|
161
|
+
const selected = quotableSelection(this.#host.messages, [this.#host.root], near);
|
|
162
|
+
if (selected === null) {
|
|
163
|
+
this.#hide();
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
this.#quoting = selected.text;
|
|
167
|
+
placeOffer(this.button, selected.rect, this.#host.messagesWrap.getBoundingClientRect());
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Retire the offer, and forget what it was pointing at. */
|
|
171
|
+
#hide(): void {
|
|
172
|
+
this.button.hidden = true;
|
|
173
|
+
this.#quoting = "";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** A `{token}` placeholder, named the way every key in the string table names one. */
|
|
2
|
+
const TOKEN_RE = /\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fill the `{token}` placeholders of a string-table template.
|
|
6
|
+
*
|
|
7
|
+
* Every string-table template goes through here rather than through
|
|
8
|
+
* `template.replace("{token}", value)`, which was wrong in two ways at once:
|
|
9
|
+
*
|
|
10
|
+
* - **A string replacement interprets dollar patterns in the value.** `$&`
|
|
11
|
+
* inserts the matched token, and `` $` `` and `$'` the text either side of it,
|
|
12
|
+
* so a queued message reading `costs $& more` was labelled
|
|
13
|
+
* `Do not send "costs {text} more"`. Several of these values are text a user
|
|
14
|
+
* or a server wrote -- a queued message, a tool name, a skill title, an
|
|
15
|
+
* agent name -- so the value has to land verbatim. A replacer function's
|
|
16
|
+
* return value is never interpreted, which is the whole fix.
|
|
17
|
+
* - **A string pattern replaces only the first occurrence**, so a translation
|
|
18
|
+
* that uses a token twice was left half filled.
|
|
19
|
+
*
|
|
20
|
+
* One pass over the template, so a value that itself contains a `{token}` is
|
|
21
|
+
* inserted as written rather than filled in turn: a skill titled
|
|
22
|
+
* `Fill {fields}` stays that, where chained replacements filled it twice.
|
|
23
|
+
*
|
|
24
|
+
* A token with no entry in `values` is left as written. Every call site passes
|
|
25
|
+
* the tokens its key documents, so that is a translation carrying a token the
|
|
26
|
+
* call site does not know, and printing it is more honest than dropping it.
|
|
27
|
+
* `skills/fill_template.ts` is the prompt-side counterpart, and its contract is
|
|
28
|
+
* different on purpose: a prompt reports what it could not fill so a send can
|
|
29
|
+
* be refused.
|
|
30
|
+
*
|
|
31
|
+
* @param template - A string-table value, e.g. `strings.removeQueued`.
|
|
32
|
+
* @param values - The value for each token the template's key documents.
|
|
33
|
+
*/
|
|
34
|
+
export function fillUiString(
|
|
35
|
+
template: string,
|
|
36
|
+
values: Readonly<Record<string, string | number>>,
|
|
37
|
+
): string {
|
|
38
|
+
return template.replace(TOKEN_RE, (token, key: string) =>
|
|
39
|
+
Object.hasOwn(values, key) ? String(values[key]) : token,
|
|
40
|
+
);
|
|
41
|
+
}
|