@qualified-salesforce/web 0.0.1-oidc-bootstrap
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/41842993ec71d6628e4949e9a22b146b.svg +3 -0
- package/7271f3433ed82fc7f56adcd9e30275f4.svg +17 -0
- package/LICENSE.txt +82 -0
- package/components/helpers/entriesStringValidations.js +69 -0
- package/components/helpers/languages.js +32 -0
- package/components/shared/assertUnreachable.js +5 -0
- package/components/shared/controls/imageCropperHelpers.js +43 -0
- package/components/shared/meetingLoadingProgressSpec.js +116 -0
- package/constants.generated.js +9883 -0
- package/css/widget/multimodal_v2/host.split-css.css +162 -0
- package/css/widget/multimodal_v2/index.split-css.panda.css +5240 -0
- package/css/widget/widget.split-css.css +100 -0
- package/fonts/inter/Inter-Black.woff +0 -0
- package/fonts/inter/Inter-Black.woff2 +0 -0
- package/fonts/inter/Inter-BlackItalic.woff +0 -0
- package/fonts/inter/Inter-BlackItalic.woff2 +0 -0
- package/fonts/inter/Inter-Bold.woff +0 -0
- package/fonts/inter/Inter-Bold.woff2 +0 -0
- package/fonts/inter/Inter-BoldItalic.woff +0 -0
- package/fonts/inter/Inter-BoldItalic.woff2 +0 -0
- package/fonts/inter/Inter-ExtraBold.woff +0 -0
- package/fonts/inter/Inter-ExtraBold.woff2 +0 -0
- package/fonts/inter/Inter-ExtraBoldItalic.woff +0 -0
- package/fonts/inter/Inter-ExtraBoldItalic.woff2 +0 -0
- package/fonts/inter/Inter-ExtraLight.woff +0 -0
- package/fonts/inter/Inter-ExtraLight.woff2 +0 -0
- package/fonts/inter/Inter-ExtraLightItalic.woff +0 -0
- package/fonts/inter/Inter-ExtraLightItalic.woff2 +0 -0
- package/fonts/inter/Inter-Italic.woff +0 -0
- package/fonts/inter/Inter-Italic.woff2 +0 -0
- package/fonts/inter/Inter-Light.woff +0 -0
- package/fonts/inter/Inter-Light.woff2 +0 -0
- package/fonts/inter/Inter-LightItalic.woff +0 -0
- package/fonts/inter/Inter-LightItalic.woff2 +0 -0
- package/fonts/inter/Inter-Medium.woff +0 -0
- package/fonts/inter/Inter-Medium.woff2 +0 -0
- package/fonts/inter/Inter-MediumItalic.woff +0 -0
- package/fonts/inter/Inter-MediumItalic.woff2 +0 -0
- package/fonts/inter/Inter-Regular.woff +0 -0
- package/fonts/inter/Inter-Regular.woff2 +0 -0
- package/fonts/inter/Inter-SemiBold.woff +0 -0
- package/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
- package/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
- package/fonts/inter/Inter-Thin.woff +0 -0
- package/fonts/inter/Inter-Thin.woff2 +0 -0
- package/fonts/inter/Inter-ThinItalic.woff +0 -0
- package/fonts/inter/Inter-ThinItalic.woff2 +0 -0
- package/fonts/inter/Inter-italic.var.woff2 +0 -0
- package/fonts/inter/Inter-roman.var.woff2 +0 -0
- package/images/close.js +63 -0
- package/images/logo.js +22 -0
- package/js/4101.js +19721 -0
- package/js/daily-esm.js +9948 -0
- package/js/date-fns.js +427 -0
- package/js/multimodal_v2.js +1653 -0
- package/js/runtime.js +109 -0
- package/media/Inter-Black.796be8d8bf.woff2 +0 -0
- package/media/Inter-Black.b254104c56.woff +0 -0
- package/media/Inter-BlackItalic.70306b0eae.woff +0 -0
- package/media/Inter-BlackItalic.752f1e0aaa.woff2 +0 -0
- package/media/Inter-Bold.579e0f95ca.woff2 +0 -0
- package/media/Inter-Bold.b1234477a5.woff +0 -0
- package/media/Inter-BoldItalic.3d0d804323.woff +0 -0
- package/media/Inter-BoldItalic.828a494e04.woff2 +0 -0
- package/media/Inter-ExtraBold.208a9e6c99.woff +0 -0
- package/media/Inter-ExtraBold.d65f028165.woff2 +0 -0
- package/media/Inter-ExtraBoldItalic.30429962ec.woff +0 -0
- package/media/Inter-ExtraBoldItalic.8c7eac5ce3.woff2 +0 -0
- package/media/Inter-ExtraLight.15c082a57d.woff +0 -0
- package/media/Inter-ExtraLight.6824177d1e.woff2 +0 -0
- package/media/Inter-ExtraLightItalic.05138dddf3.woff2 +0 -0
- package/media/Inter-ExtraLightItalic.3beee54f59.woff +0 -0
- package/media/Inter-Italic.9beab78452.woff +0 -0
- package/media/Inter-Italic.d593a8df79.woff2 +0 -0
- package/media/Inter-Light.27083fa637.woff2 +0 -0
- package/media/Inter-Light.91dfddd842.woff +0 -0
- package/media/Inter-LightItalic.0a783b89b3.woff2 +0 -0
- package/media/Inter-LightItalic.f8ccf2813f.woff +0 -0
- package/media/Inter-Medium.dc792b508e.woff2 +0 -0
- package/media/Inter-Medium.ec7dd2d9d8.woff +0 -0
- package/media/Inter-MediumItalic.17301e5b40.woff +0 -0
- package/media/Inter-MediumItalic.84d3493a9f.woff2 +0 -0
- package/media/Inter-Regular.f1f0c35b32.woff2 +0 -0
- package/media/Inter-Regular.f356e84aa0.woff +0 -0
- package/media/Inter-SemiBold.55027e4724.woff +0 -0
- package/media/Inter-SemiBold.fcb100c760.woff2 +0 -0
- package/media/Inter-SemiBoldItalic.ab9105ed3b.woff +0 -0
- package/media/Inter-SemiBoldItalic.d90f295d0c.woff2 +0 -0
- package/media/Inter-Thin.16325d9b0f.woff +0 -0
- package/media/Inter-Thin.dafaa44d99.woff2 +0 -0
- package/media/Inter-ThinItalic.4fc662b3cf.woff2 +0 -0
- package/media/Inter-ThinItalic.d3d8994788.woff +0 -0
- package/media/Inter-italic.var.958a0b9742.woff2 +0 -0
- package/media/Inter-roman.var.b2129c009c.woff2 +0 -0
- package/package.json +20 -0
- package/packs/widget/api/docking/docking_host.js +97 -0
- package/packs/widget/api/docking/index.js +294 -0
- package/packs/widget/api/docking/shared.js +164 -0
- package/packs/widget/api/docking/viewport_lock.js +488 -0
- package/packs/widget/api/docking/viewport_resize.js +1203 -0
- package/packs/widget/esm/fonts/Inter-Black.796be8d8bf.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Black.b254104c56.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BlackItalic.70306b0eae.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BlackItalic.752f1e0aaa.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Bold.579e0f95ca.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Bold.b1234477a5.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BoldItalic.3d0d804323.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BoldItalic.828a494e04.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBold.208a9e6c99.woff +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBold.d65f028165.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBoldItalic.30429962ec.woff +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBoldItalic.8c7eac5ce3.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLight.15c082a57d.woff +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLight.6824177d1e.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLightItalic.05138dddf3.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLightItalic.3beee54f59.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Italic.9beab78452.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Italic.d593a8df79.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Light.27083fa637.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Light.91dfddd842.woff +0 -0
- package/packs/widget/esm/fonts/Inter-LightItalic.0a783b89b3.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-LightItalic.f8ccf2813f.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Medium.dc792b508e.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Medium.ec7dd2d9d8.woff +0 -0
- package/packs/widget/esm/fonts/Inter-MediumItalic.17301e5b40.woff +0 -0
- package/packs/widget/esm/fonts/Inter-MediumItalic.84d3493a9f.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Regular.f1f0c35b32.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Regular.f356e84aa0.woff +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBold.55027e4724.woff +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBold.fcb100c760.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBoldItalic.ab9105ed3b.woff +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBoldItalic.d90f295d0c.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Thin.16325d9b0f.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Thin.dafaa44d99.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ThinItalic.4fc662b3cf.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ThinItalic.d3d8994788.woff +0 -0
- package/packs/widget/esm/fonts/Inter-italic.var.958a0b9742.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-roman.var.b2129c009c.woff2 +0 -0
- package/packs/widget/esm/index.js +183 -0
- package/packs/widget/esm/qualified.css +5502 -0
- package/routes/app/offers/scripts/OfferMainScript.js +154 -0
- package/routes/app/offers/scripts/constants.js +71 -0
- package/routes/app/offers/scripts/main/ButtonManager.js +65 -0
- package/routes/app/offers/scripts/main/FormManager.js +325 -0
- package/routes/app/offers/scripts/main/MainContext.js +19 -0
- package/routes/app/offers/scripts/main/OfferManager.js +91 -0
- package/routes/app/offers/scripts/main/TriggerManager.js +125 -0
- package/routes/app/offers/scripts/rendering/ContentManager.js +53 -0
- package/routes/app/offers/scripts/rendering/LocationManager.js +83 -0
- package/routes/app/offers/scripts/rendering/RenderedOffer.js +188 -0
- package/routes/app/offers/scripts/rendering/Renderer.js +69 -0
- package/routes/app/offers/scripts/rendering/RenderingInitializer.js +62 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManager.js +31 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerFooter.js +81 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerHeader.js +81 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerModal.js +117 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerSidebar.js +75 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationResult.js +43 -0
- package/routes/app/offers/scripts/rendering/animations/Animator.js +78 -0
- package/routes/app/offers/scripts/rendering/animations/BaseAnimationManager.js +25 -0
- package/routes/app/offers/scripts/rendering/lib/BaseComponent.js +106 -0
- package/routes/app/offers/scripts/rendering/lib/FormComponent.js +134 -0
- package/routes/app/offers/scripts/rendering/lib/OfferComponent.js +144 -0
- package/routes/app/offers/scripts/rendering/lib/ScrollbarWidth.js +27 -0
- package/routes/app/offers/scripts/rendering/lib/decorators.js +20 -0
- package/routes/app/offers/scripts/rendering/locations/CSSVarsManager.js +66 -0
- package/routes/app/offers/scripts/rendering/locations/ElementResizeObserver.js +49 -0
- package/routes/app/offers/scripts/rendering/locations/footer.js +53 -0
- package/routes/app/offers/scripts/rendering/locations/header/AsyncBatchProcessor.js +70 -0
- package/routes/app/offers/scripts/rendering/locations/header/CSSTransitionObserver.js +182 -0
- package/routes/app/offers/scripts/rendering/locations/header/ElementStyleChangeObserver.js +138 -0
- package/routes/app/offers/scripts/rendering/locations/header/ExternalStyleManager.js +110 -0
- package/routes/app/offers/scripts/rendering/locations/header/Header.js +353 -0
- package/routes/app/offers/scripts/rendering/locations/header/InlineStyleManager.js +105 -0
- package/routes/app/offers/scripts/rendering/locations/header/MatchingElementsObserver.js +107 -0
- package/routes/app/offers/scripts/rendering/locations/header/NewElementsObserver.js +129 -0
- package/routes/app/offers/scripts/rendering/locations/header/RuleWrapper.js +46 -0
- package/routes/app/offers/scripts/rendering/locations/header/SelectorObservable.js +23 -0
- package/routes/app/offers/scripts/rendering/locations/header/SelectorObserver.js +61 -0
- package/routes/app/offers/scripts/rendering/locations/header/ShiftedElementsManager.js +45 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleElementManager.js +37 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleElementWrapper.js +62 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/ObservedSelectorValue.js +45 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/ObservedSelectors.js +62 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/StyleSelectorObserver.js +294 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/constants.js +21 -0
- package/routes/app/offers/scripts/rendering/locations/header/WindowResizeObserver.js +43 -0
- package/routes/app/offers/scripts/rendering/locations/header/utils.js +25 -0
- package/routes/app/offers/scripts/rendering/locations/popup.js +66 -0
- package/routes/app/offers/scripts/rendering/locations/sidebar.js +21 -0
- package/routes/app/offers/scripts/rendering/variations/ButtonBanner.js +105 -0
- package/routes/app/offers/scripts/rendering/variations/ButtonModal.js +114 -0
- package/routes/app/offers/scripts/rendering/variations/FormBanner.js +214 -0
- package/routes/app/offers/scripts/rendering/variations/FormModal.js +325 -0
- package/routes/app/offers/scripts/rendering/variations/LinkBanner.js +105 -0
- package/routes/app/offers/scripts/rendering/variations/components/Body.js +29 -0
- package/routes/app/offers/scripts/rendering/variations/components/Button.js +128 -0
- package/routes/app/offers/scripts/rendering/variations/components/DismissButton.js +39 -0
- package/routes/app/offers/scripts/rendering/variations/components/ForegroundImageBanner.js +110 -0
- package/routes/app/offers/scripts/rendering/variations/components/ForegroundImageModal.js +128 -0
- package/routes/app/offers/scripts/rendering/variations/components/Headline.js +94 -0
- package/routes/app/offers/scripts/rendering/variations/components/MultiFieldForm.js +302 -0
- package/routes/app/offers/scripts/rendering/variations/components/Tooltip.js +74 -0
- package/routes/app/offers/scripts/rendering/variations/icons.js +15 -0
- package/routes/app/offers/scripts/utils.js +115 -0
- package/routes/app/offers/utils/HTMLUtils.js +10 -0
- package/routes/app/offers/utils/createTypeGuard.js +32 -0
- package/routes/app/offers/utils/promise-utils.js +22 -0
- package/routes/app/websiteBuilder/stores/storeHelpers.js +18 -0
- package/sounds/message-initial.mp3 +0 -0
- package/sounds/message-received.mp3 +0 -0
- package/sounds/message-sent.mp3 +0 -0
- package/src/arrays.js +15 -0
- package/src/audio.js +106 -0
- package/src/bounded-set.js +16 -0
- package/src/bounding_box_observer.js +129 -0
- package/src/decorators.js +29 -0
- package/src/dom.js +128 -0
- package/src/dom_roots.js +26 -0
- package/src/embedded_forms/EmbeddedForm.js +638 -0
- package/src/embedded_forms/QualifiedEmbeddedForm.js +51 -0
- package/src/embedded_forms/QualifiedFormField.js +137 -0
- package/src/embedded_forms/utils.js +17 -0
- package/src/graphql-types.js +1686 -0
- package/src/iframes.js +86 -0
- package/src/localstorage.js +43 -0
- package/src/mirror/Shipper.js +133 -0
- package/src/mirror/constants.generated.js +13 -0
- package/src/mirror/constants.js +238 -0
- package/src/mirror/shipper/ChangeQueue.js +155 -0
- package/src/mirror/shipper/DOMSerializer.js +392 -0
- package/src/mirror/shipper/observers.js +441 -0
- package/src/mirror/shipper/utils.js +98 -0
- package/src/mixins/disposable.js +125 -0
- package/src/mixins/injectable.js +37 -0
- package/src/personalizations/personalization-manager.js +110 -0
- package/src/personalizations/strategies/node-freezing-strategy.js +174 -0
- package/src/personalizations/utils.js +187 -0
- package/src/promises.js +107 -0
- package/src/proxy.js +144 -0
- package/src/qualified_root.js +35 -0
- package/src/query_params.js +55 -0
- package/src/shadow-dom-helper.js +63 -0
- package/src/singleton_host.js +39 -0
- package/src/smart_website/trigger.js +49 -0
- package/src/smart_website/utils.js +149 -0
- package/src/string.js +53 -0
- package/src/timezone.js +57 -0
- package/src/timing.js +49 -0
- package/src/type-utils.js +76 -0
- package/src/url-utils.js +102 -0
- package/src/url.js +50 -0
- package/src/utils.js +72 -0
- package/src/validation.js.js +29 -0
- package/src/validation_ts.js +6 -0
- package/vendor/actioncable/adapters.js +6 -0
- package/vendor/actioncable/connection.js +204 -0
- package/vendor/actioncable/connection_monitor.js +129 -0
- package/vendor/actioncable/consumer.js +91 -0
- package/vendor/actioncable/index.js +34 -0
- package/vendor/actioncable/internal.js +22 -0
- package/vendor/actioncable/logger.js +28 -0
- package/vendor/actioncable/subscription.js +93 -0
- package/vendor/actioncable/subscriptions.js +89 -0
- package/vendor/open-telemetry-idgenerator.js +43 -0
- package/widget/analytics/facebook_tracker.js +8 -0
- package/widget/analytics/google_analytics_tracker.js +83 -0
- package/widget/analytics/google_tag_manager_tracker.js +22 -0
- package/widget/analytics.js +58 -0
- package/widget/api_handler/api_handler.js +730 -0
- package/widget/api_handler/base_api_handler.js +249 -0
- package/widget/booker_intent_tracker.js +391 -0
- package/widget/booker_outcome_tracker.js +329 -0
- package/widget/capture_widget_exceptions.js +150 -0
- package/widget/channel.js +282 -0
- package/widget/composite_experience_adapter.js +101 -0
- package/widget/constants.generated.js +350 -0
- package/widget/constants.js +21 -0
- package/widget/container.js +193 -0
- package/widget/content_activity_emitter.js +36 -0
- package/widget/data360_visitor.js +67 -0
- package/widget/date_provider.js +11 -0
- package/widget/debug_mode_state.js +175 -0
- package/widget/dummy_module.js +9 -0
- package/widget/eloqua_visitor.js +17 -0
- package/widget/form_cta_booker_intent.js +246 -0
- package/widget/hubspot_visitor.js +39 -0
- package/widget/inline_meeting_booker_page.js +90 -0
- package/widget/local_state/abstract_local_state.js +38 -0
- package/widget/local_state/debug_state/abstract_debug_flow.js +29 -0
- package/widget/local_state/debug_state/custom_form_flow.js +14 -0
- package/widget/local_state/debug_state/hubspot_form_flow.js +19 -0
- package/widget/local_state/debug_state/hubspot_v4_form_flow.js +19 -0
- package/widget/local_state/debug_state/marketo_form_flow.js +20 -0
- package/widget/local_state/debug_state/pardot_form_flow.js +18 -0
- package/widget/local_state/debug_state.js +362 -0
- package/widget/local_state/trace_state.js +20 -0
- package/widget/location_provider.js +9 -0
- package/widget/marketo_visitor.js +39 -0
- package/widget/meetings/tracing/buttons_forms_triggering_tracer.js +124 -0
- package/widget/meetings/tracing/spans/button_spans.js +18 -0
- package/widget/meetings/tracing/spans/form_spans.js +11 -0
- package/widget/multimodal_v2/assets_preloader.js +97 -0
- package/widget/multimodal_v2/components/AppLayout.js +93 -0
- package/widget/multimodal_v2/components/CursorOverlay.js +93 -0
- package/widget/multimodal_v2/components/PointerRectOverlay.js +74 -0
- package/widget/multimodal_v2/components/app/Artifact.js +109 -0
- package/widget/multimodal_v2/components/app/Background.js +27 -0
- package/widget/multimodal_v2/components/app/CalendarLoadingContent.js +255 -0
- package/widget/multimodal_v2/components/app/Chat.js +39 -0
- package/widget/multimodal_v2/components/app/CookieConsentModal.js +149 -0
- package/widget/multimodal_v2/components/app/Foreground.js +48 -0
- package/widget/multimodal_v2/components/app/HiddenInput.js +41 -0
- package/widget/multimodal_v2/components/app/Input.js +72 -0
- package/widget/multimodal_v2/components/app/LightboxExperience.js +769 -0
- package/widget/multimodal_v2/components/app/LoadingOverlay.js +97 -0
- package/widget/multimodal_v2/components/app/Main.js +985 -0
- package/widget/multimodal_v2/components/app/MessengerButton.js +160 -0
- package/widget/multimodal_v2/components/app/Multimodal.js +17 -0
- package/widget/multimodal_v2/components/app/OverlayControls.js +79 -0
- package/widget/multimodal_v2/components/app/Preview.js +32 -0
- package/widget/multimodal_v2/components/app/PrivacyDisclosure.js +57 -0
- package/widget/multimodal_v2/components/app/RotateDeviceOverlay.js +70 -0
- package/widget/multimodal_v2/components/app/Toolbar.js +156 -0
- package/widget/multimodal_v2/components/chat/ChatComposer.js +129 -0
- package/widget/multimodal_v2/components/chat/ChatInputForm.js +398 -0
- package/widget/multimodal_v2/components/chat/ColdStartQuestions.js +354 -0
- package/widget/multimodal_v2/components/chat/ComposerErrorBanner.js +62 -0
- package/widget/multimodal_v2/components/chat/PostCallSurvey.js +359 -0
- package/widget/multimodal_v2/components/chat/preview/FieldRequestRenderer.js +41 -0
- package/widget/multimodal_v2/components/chat/preview/PreviewMessageRenderer.js +60 -0
- package/widget/multimodal_v2/components/chat/preview/SharedOfferRenderer.js +143 -0
- package/widget/multimodal_v2/components/chat/preview/TextRenderer.js +27 -0
- package/widget/multimodal_v2/components/chat/preview/TimelinePreview.js +254 -0
- package/widget/multimodal_v2/components/chat/timeline/CalendarEventOfferRenderer.js +103 -0
- package/widget/multimodal_v2/components/chat/timeline/CalendarEventPickRenderer.js +148 -0
- package/widget/multimodal_v2/components/chat/timeline/FieldEntryRenderer.js +84 -0
- package/widget/multimodal_v2/components/chat/timeline/FieldRequestRenderer.js +56 -0
- package/widget/multimodal_v2/components/chat/timeline/InlinePrivacyDisclosure.js +66 -0
- package/widget/multimodal_v2/components/chat/timeline/LinkPreviewCard.js +70 -0
- package/widget/multimodal_v2/components/chat/timeline/MessageEntry.js +88 -0
- package/widget/multimodal_v2/components/chat/timeline/PresentContentRenderer.js +30 -0
- package/widget/multimodal_v2/components/chat/timeline/PresentDeckRenderer.js +279 -0
- package/widget/multimodal_v2/components/chat/timeline/PresentVideoRenderer.js +131 -0
- package/widget/multimodal_v2/components/chat/timeline/ShareContentRenderer.js +59 -0
- package/widget/multimodal_v2/components/chat/timeline/SharedOfferRenderer.js +131 -0
- package/widget/multimodal_v2/components/chat/timeline/SystemRenderer.js +82 -0
- package/widget/multimodal_v2/components/chat/timeline/TextRenderer.js +66 -0
- package/widget/multimodal_v2/components/chat/timeline/Timeline.js +158 -0
- package/widget/multimodal_v2/components/debug/DebugMultimodalPanel.js +327 -0
- package/widget/multimodal_v2/components/decks/index.js +160 -0
- package/widget/multimodal_v2/components/field_request/BooleanField.js +77 -0
- package/widget/multimodal_v2/components/field_request/FieldComponents.js +69 -0
- package/widget/multimodal_v2/components/field_request/Form.js +87 -0
- package/widget/multimodal_v2/components/field_request/MultiPicklistField.js +240 -0
- package/widget/multimodal_v2/components/field_request/PicklistField.js +166 -0
- package/widget/multimodal_v2/components/field_request/SingleLineInputField.js +69 -0
- package/widget/multimodal_v2/components/field_request/TextField.js +37 -0
- package/widget/multimodal_v2/components/field_request/index.js +170 -0
- package/widget/multimodal_v2/components/helpers/AutoScroll.js +37 -0
- package/widget/multimodal_v2/components/helpers/ErrorBoundary.js +53 -0
- package/widget/multimodal_v2/components/helpers/FocusTrapDialog.js +26 -0
- package/widget/multimodal_v2/components/helpers/ImpressionTracker.js +94 -0
- package/widget/multimodal_v2/components/helpers/ListRenderer.js +37 -0
- package/widget/multimodal_v2/components/helpers/Localization.js +76 -0
- package/widget/multimodal_v2/components/helpers/Persisted.js +166 -0
- package/widget/multimodal_v2/components/helpers/RichText.js +358 -0
- package/widget/multimodal_v2/components/helpers/ScreenReaderHeading.js +17 -0
- package/widget/multimodal_v2/components/helpers/Thumbnail.js +190 -0
- package/widget/multimodal_v2/components/helpers/VisuallyHidden.js +41 -0
- package/widget/multimodal_v2/components/helpers/content_click_payloads.js +58 -0
- package/widget/multimodal_v2/components/helpers/useDraggable.js +103 -0
- package/widget/multimodal_v2/components/helpers/useTextOverflow.js +44 -0
- package/widget/multimodal_v2/components/lightbox_gather/index.js +741 -0
- package/widget/multimodal_v2/components/meetings/ArtifactEntryPoint.js +252 -0
- package/widget/multimodal_v2/components/meetings/MeetingAdditionalAttendees.js +325 -0
- package/widget/multimodal_v2/components/meetings/MeetingBookerEntry.js +100 -0
- package/widget/multimodal_v2/components/meetings/MeetingDetailsCard.js +99 -0
- package/widget/multimodal_v2/components/meetings/MeetingErrorBanner.js +62 -0
- package/widget/multimodal_v2/components/meetings/MeetingOfferEmailStep.js +239 -0
- package/widget/multimodal_v2/components/meetings/MeetingOfferFooter.js +104 -0
- package/widget/multimodal_v2/components/meetings/MeetingOfferSelectionStep.js +60 -0
- package/widget/multimodal_v2/components/meetings/MeetingRepHeader.js +222 -0
- package/widget/multimodal_v2/components/meetings/MeetingStepShell.js +92 -0
- package/widget/multimodal_v2/components/meetings/MeetingSummaryRail.js +515 -0
- package/widget/multimodal_v2/components/meetings/MeetingTimeSelector.js +603 -0
- package/widget/multimodal_v2/components/meetings/MonthDatePicker.js +422 -0
- package/widget/multimodal_v2/components/meetings/NavigationButtons.js +76 -0
- package/widget/multimodal_v2/components/meetings/TimeSlotHeader.js +357 -0
- package/widget/multimodal_v2/components/meetings/WeekViewHeader.js +20 -0
- package/widget/multimodal_v2/components/meetings/constants.js +7 -0
- package/widget/multimodal_v2/components/meetings/index.js +47 -0
- package/widget/multimodal_v2/components/meetings/utils.js +328 -0
- package/widget/multimodal_v2/components/multimodal/Audio.js +28 -0
- package/widget/multimodal_v2/components/multimodal/Controls.js +188 -0
- package/widget/multimodal_v2/components/multimodal/LiveVideo.js +63 -0
- package/widget/multimodal_v2/components/multimodal/MultiModalComponent.js +424 -0
- package/widget/multimodal_v2/components/multimodal/MultimodalAvatar.js +36 -0
- package/widget/multimodal_v2/components/multimodal/OrbAvatar.js +326 -0
- package/widget/multimodal_v2/components/multimodal/Status.js +220 -0
- package/widget/multimodal_v2/components/multimodal/VideoAvatar.js +24 -0
- package/widget/multimodal_v2/components/multimodal/VideoPreview.js +114 -0
- package/widget/multimodal_v2/components/multimodal/useAudioLevelMonitoring.js +96 -0
- package/widget/multimodal_v2/components/multimodal/useMultimodal.js +434 -0
- package/widget/multimodal_v2/components/presentations/index.js +372 -0
- package/widget/multimodal_v2/components/shared/Avatar.js +92 -0
- package/widget/multimodal_v2/components/shared/AvatarGroup.js +135 -0
- package/widget/multimodal_v2/components/shared/Button.js +245 -0
- package/widget/multimodal_v2/components/shared/ButtonGroup.js +133 -0
- package/widget/multimodal_v2/components/shared/ComposerForm.js +98 -0
- package/widget/multimodal_v2/components/shared/SpeakingIndicator.js +239 -0
- package/widget/multimodal_v2/components/shared/ThinkingAnimation.js +165 -0
- package/widget/multimodal_v2/components/shared/Tooltip.js +266 -0
- package/widget/multimodal_v2/components/shared/controls/Dropdown.js +79 -0
- package/widget/multimodal_v2/components/shared/controls/PillToggle.js +142 -0
- package/widget/multimodal_v2/components/shared/controls/TextArea.js +114 -0
- package/widget/multimodal_v2/components/shared/toolCallLabels.js +12 -0
- package/widget/multimodal_v2/components/slides/SlidesThumbnail.js +47 -0
- package/widget/multimodal_v2/components/slides/index.js +61 -0
- package/widget/multimodal_v2/constants.js +88 -0
- package/widget/multimodal_v2/host.split-css.js +2 -0
- package/widget/multimodal_v2/host.string.js +96 -0
- package/widget/multimodal_v2/images/icons.js +582 -0
- package/widget/multimodal_v2/images/posters/piper_low_res.jpg +0 -0
- package/widget/multimodal_v2/index.js +23 -0
- package/widget/multimodal_v2/index.panda.js +28 -0
- package/widget/multimodal_v2/index.split-css.panda.js +2 -0
- package/widget/multimodal_v2/inline_meeting_booker.js +182 -0
- package/widget/multimodal_v2/locales/cs.js +196 -0
- package/widget/multimodal_v2/locales/da.js +196 -0
- package/widget/multimodal_v2/locales/de.js +196 -0
- package/widget/multimodal_v2/locales/en.js +196 -0
- package/widget/multimodal_v2/locales/en_AU.js +197 -0
- package/widget/multimodal_v2/locales/en_GB.js +197 -0
- package/widget/multimodal_v2/locales/es.js +197 -0
- package/widget/multimodal_v2/locales/es_LA.js +196 -0
- package/widget/multimodal_v2/locales/fi.js +196 -0
- package/widget/multimodal_v2/locales/fr.js +197 -0
- package/widget/multimodal_v2/locales/fr_CA.js +196 -0
- package/widget/multimodal_v2/locales/id.js +196 -0
- package/widget/multimodal_v2/locales/index.js +48 -0
- package/widget/multimodal_v2/locales/it.js +196 -0
- package/widget/multimodal_v2/locales/ja.js +196 -0
- package/widget/multimodal_v2/locales/ko.js +196 -0
- package/widget/multimodal_v2/locales/nb.js +196 -0
- package/widget/multimodal_v2/locales/nl.js +196 -0
- package/widget/multimodal_v2/locales/pl.js +196 -0
- package/widget/multimodal_v2/locales/pt_BR.js +196 -0
- package/widget/multimodal_v2/locales/ru.js +196 -0
- package/widget/multimodal_v2/locales/sv.js +196 -0
- package/widget/multimodal_v2/locales/th.js +196 -0
- package/widget/multimodal_v2/locales/tr.js +196 -0
- package/widget/multimodal_v2/locales/vi.js +196 -0
- package/widget/multimodal_v2/locales/zh_CN.js +196 -0
- package/widget/multimodal_v2/locales/zh_TW.js +196 -0
- package/widget/multimodal_v2/multimodal.js +633 -0
- package/widget/multimodal_v2/multimodal_channel.js +195 -0
- package/widget/multimodal_v2/signals/active_conversation_signal.js +33 -0
- package/widget/multimodal_v2/signals/allowed_conversation_mode_signal.js +38 -0
- package/widget/multimodal_v2/signals/artifact_signal.js +22 -0
- package/widget/multimodal_v2/signals/layout_signal.js +98 -0
- package/widget/multimodal_v2/signals/messages_signal.js +207 -0
- package/widget/multimodal_v2/signals/ui_state_signal.js +128 -0
- package/widget/multimodal_v2/stable_bundle_src.js +44 -0
- package/widget/multimodal_v2/stores/ai_conversation_store.js +221 -0
- package/widget/multimodal_v2/stores/artifact_store.js +205 -0
- package/widget/multimodal_v2/stores/base_store.js +16 -0
- package/widget/multimodal_v2/stores/call_store.js +770 -0
- package/widget/multimodal_v2/stores/call_ui_adapter.js +225 -0
- package/widget/multimodal_v2/stores/debug_multimodal_scenario_store.js +471 -0
- package/widget/multimodal_v2/stores/decks_store.js +285 -0
- package/widget/multimodal_v2/stores/device_store.js +63 -0
- package/widget/multimodal_v2/stores/docking_store.js +62 -0
- package/widget/multimodal_v2/stores/field_request_store.js +326 -0
- package/widget/multimodal_v2/stores/meeting_store.js +477 -0
- package/widget/multimodal_v2/stores/participant_store.js +73 -0
- package/widget/multimodal_v2/stores/post_call_survey_store.js +160 -0
- package/widget/multimodal_v2/stores/pounce_tracking_store.js +163 -0
- package/widget/multimodal_v2/stores/pounce_tracking_store_v2.js +511 -0
- package/widget/multimodal_v2/stores/presentations_store.js +111 -0
- package/widget/multimodal_v2/stores/root_store.js +1919 -0
- package/widget/multimodal_v2/stores/screen_share_store.js +217 -0
- package/widget/multimodal_v2/stores/slides_store.js +21 -0
- package/widget/multimodal_v2/stores/translation_store.js +185 -0
- package/widget/multimodal_v2/stores/ui_store.js +496 -0
- package/widget/multimodal_v2/stores/waiting_store.js +159 -0
- package/widget/multimodal_v2/stores/website_navigation_store.js +767 -0
- package/widget/multimodal_v2/styled-system/css/conditions.js +34 -0
- package/widget/multimodal_v2/styled-system/css/css.js +48 -0
- package/widget/multimodal_v2/styled-system/css/cva.js +96 -0
- package/widget/multimodal_v2/styled-system/css/cx.js +13 -0
- package/widget/multimodal_v2/styled-system/css/index.js +15 -0
- package/widget/multimodal_v2/styled-system/css/sva.js +69 -0
- package/widget/multimodal_v2/styled-system/helpers.js +384 -0
- package/widget/multimodal_v2/styled-system/jsx/create-style-context.js +96 -0
- package/widget/multimodal_v2/styled-system/jsx/factory-helper.js +19 -0
- package/widget/multimodal_v2/styled-system/jsx/factory.js +111 -0
- package/widget/multimodal_v2/styled-system/jsx/index.js +12 -0
- package/widget/multimodal_v2/styled-system/jsx/is-valid-prop.js +22 -0
- package/widget/multimodal_v2/types.js +105 -0
- package/widget/multimodal_v2/utils/auto_scroller.js +157 -0
- package/widget/multimodal_v2/utils/flip_animation.js +124 -0
- package/widget/multimodal_v2/utils/focus_gate.js +237 -0
- package/widget/multimodal_v2/utils/locale.js +16 -0
- package/widget/multimodal_v2/utils/media_queries.js +30 -0
- package/widget/multimodal_v2/utils/multimodal_cache.js +19 -0
- package/widget/multimodal_v2/utils/mutation_effect.js +14 -0
- package/widget/multimodal_v2/utils/navigation_interceptor.js +205 -0
- package/widget/multimodal_v2/utils/navigation_strategies/dom_swap.js +393 -0
- package/widget/multimodal_v2/utils/navigation_strategies/index.js +12 -0
- package/widget/multimodal_v2/utils/navigation_strategies/lwr.js +61 -0
- package/widget/multimodal_v2/utils/navigation_strategies/navigation_utils.js +46 -0
- package/widget/multimodal_v2/utils/navigation_strategies/next_js.js +24 -0
- package/widget/multimodal_v2/utils/navigation_strategies/wouter_v3.js +15 -0
- package/widget/multimodal_v2/utils/objects_map.js +38 -0
- package/widget/multimodal_v2/utils/perceived_voice_turn_tracker.js +345 -0
- package/widget/multimodal_v2/utils/sanitize_html.js +132 -0
- package/widget/multimodal_v2/utils/signals.js +97 -0
- package/widget/multimodal_v2/utils/slide_zoom.js +114 -0
- package/widget/multimodal_v2/utils/theme_styles.js +137 -0
- package/widget/multimodal_v2/utils/url_observer.js +52 -0
- package/widget/multimodal_v2/utils/voice_onset_detector.js +127 -0
- package/widget/page_mirror.js +89 -0
- package/widget/page_view_activity_emitter.js +71 -0
- package/widget/pardot_visitor.js +137 -0
- package/widget/personalization_observer.js +96 -0
- package/widget/personalizations_config.js +160 -0
- package/widget/qualified_form/constants.js +23 -0
- package/widget/qualified_form/phone_utils.js +38 -0
- package/widget/qualified_form/qualified_form_action.js +91 -0
- package/widget/qualified_form/qualified_form_action_orchestrator.js +21 -0
- package/widget/qualified_form/qualified_form_api.js +471 -0
- package/widget/scroll_disabler.js +109 -0
- package/widget/server-logger.js +156 -0
- package/widget/smart_website_config.js +112 -0
- package/widget/telemetry/context.js +75 -0
- package/widget/telemetry/index.js +16 -0
- package/widget/telemetry/messenger_uptime.js +80 -0
- package/widget/telemetry/metrics.js +120 -0
- package/widget/telemetry/span.js +82 -0
- package/widget/telemetry/telemetry.js +180 -0
- package/widget/telemetry/tracer.js +41 -0
- package/widget/telemetry/tracing_store.js +310 -0
- package/widget/tracker.js +916 -0
- package/widget/utils/native_globals.js +129 -0
- package/widget/v1_adapter.js +50 -0
- package/widget/v2_adapter.js +368 -0
- package/widget/visitor/base_visitor_state.js +11 -0
- package/widget/visitor/cookie_visitor_state.js +128 -0
- package/widget/visitor/in_memory_visitor_state.js +29 -0
- package/widget/visitor/visitor_state.js +384 -0
- package/widget/visitor.js +356 -0
- package/widget/widget/linked_widget_v2.js +227 -0
- package/widget/widget/page_mirror_factory.js +22 -0
- package/widget/widget/sentry.js +130 -0
- package/widget/widget/widget.js +1698 -0
- package/widget/widget.split-css.js +2 -0
- package/widget/widget_bootstrap.js +97 -0
- package/widget/widget_object.js +73 -0
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
import { __webpack_require__ } from "../../../js/runtime.js";
|
|
2
|
+
import { Ha } from "../../../js/daily-esm.js";
|
|
3
|
+
import { signals_core_module_r, signals_core_module_d, signals_core_module_w } from "../../../js/multimodal_v2.js";
|
|
4
|
+
import "../../telemetry/index.js";
|
|
5
|
+
import { getSentryClient } from "../../widget/sentry.js";
|
|
6
|
+
import "../constants.js";
|
|
7
|
+
import { resolveBundleBaseUrl } from "../stable_bundle_src.js";
|
|
8
|
+
import { VoiceOnsetDetector } from "../utils/voice_onset_detector.js";
|
|
9
|
+
import { default as AiConversationStore } from "./ai_conversation_store.js";
|
|
10
|
+
import { default as DeviceStore } from "./device_store.js";
|
|
11
|
+
import { default as ParticipantStore } from "./participant_store.js";
|
|
12
|
+
import { ConversationMode as types_ConversationMode, AvatarProvider as types_AvatarProvider } from "../types.js";
|
|
13
|
+
import "../../utils/native_globals.js";
|
|
14
|
+
import { PerceivedVoiceTurnTracker } from "../utils/perceived_voice_turn_tracker.js";
|
|
15
|
+
import { metrics } from "../../telemetry/metrics.js";
|
|
16
|
+
|
|
17
|
+
/* provided dependency */ var call_store_clearTimeout = __webpack_require__(68034).Kj;
|
|
18
|
+
/* provided dependency */ var call_store_setTimeout = __webpack_require__(68034).pS;
|
|
19
|
+
/* provided dependency */ var __nativeDocumentAddEventListener = __webpack_require__(68034).Qj;
|
|
20
|
+
/* provided dependency */ var __nativeDocumentRemoveEventListener = __webpack_require__(68034).LA;
|
|
21
|
+
function _extends() {
|
|
22
|
+
_extends = Object.assign || function(target) {
|
|
23
|
+
for(var i = 1; i < arguments.length; i++){
|
|
24
|
+
var source = arguments[i];
|
|
25
|
+
for(var key in source){
|
|
26
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
27
|
+
target[key] = source[key];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
return _extends.apply(this, arguments);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
function getCallMachineBundleFilename() {
|
|
48
|
+
if (typeof __CALL_MACHINE_BUNDLE_FILENAME__ !== "undefined") {
|
|
49
|
+
return __CALL_MACHINE_BUNDLE_FILENAME__;
|
|
50
|
+
}
|
|
51
|
+
return globalThis.__CALL_MACHINE_BUNDLE_FILENAME__;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A complete call-machine URL, set by the npm package's `setup()` before any call object exists.
|
|
55
|
+
*
|
|
56
|
+
* Takes precedence over base-plus-filename resolution because it is the only thing that can be
|
|
57
|
+
* right when a consumer's bundler re-emitted our asset: measured 2026-08-12, Vite rewrites the
|
|
58
|
+
* reference to `/assets/call-machine-object-bundle-0.83.1-<hash>.js` and webpack to a bare
|
|
59
|
+
* `/<hash>.js`, so appending our baked-in filename to either one's directory produces a URL that
|
|
60
|
+
* does not exist. Read on demand rather than captured, for the same reason the base is — under
|
|
61
|
+
* unbundled ESM the whole widget graph is evaluated before `setup()` runs a single line.
|
|
62
|
+
*/ function callMachineUrlOverride() {
|
|
63
|
+
return globalThis.__qualifiedCallMachineUrl;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolves the absolute URL for the call-machine sibling bundle.
|
|
67
|
+
*
|
|
68
|
+
* @param filename - The sibling filename (e.g., "call-machine-object-bundle.js")
|
|
69
|
+
* @param scriptSrc - The src of the currently-loaded script (captured at init time)
|
|
70
|
+
* @returns Absolute URL to the sibling file, or null if resolution fails
|
|
71
|
+
*/ function resolveCallMachineBundleUrl(filename, scriptSrc) {
|
|
72
|
+
if (!scriptSrc) return null;
|
|
73
|
+
try {
|
|
74
|
+
return new URL(filename, scriptSrc).toString();
|
|
75
|
+
} catch (unused) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
var call_store_CallStatus = /*#__PURE__*/ (/* unused pure expression or super */ null && (function(CallStatus) {
|
|
80
|
+
CallStatus["CONNECTING"] = "connecting";
|
|
81
|
+
CallStatus["ACTIVE"] = "active";
|
|
82
|
+
CallStatus["ENDED"] = "ended";
|
|
83
|
+
CallStatus["RESTARTING"] = "restarting";
|
|
84
|
+
return CallStatus;
|
|
85
|
+
}(call_store_CallStatus || {})));
|
|
86
|
+
var call_store_VideoStatus = /*#__PURE__*/ (/* unused pure expression or super */ null && (function(VideoStatus) {
|
|
87
|
+
VideoStatus["CONNECTING"] = "connecting";
|
|
88
|
+
VideoStatus["BLURRED"] = "blurred";
|
|
89
|
+
VideoStatus["ACTIVE"] = "active";
|
|
90
|
+
VideoStatus["VOICE_ONLY"] = "voice_only";
|
|
91
|
+
return VideoStatus;
|
|
92
|
+
}(call_store_VideoStatus || {})));
|
|
93
|
+
const CALL_AVAILABILITY_BUDGET_MS = 20000;
|
|
94
|
+
class CallStore {
|
|
95
|
+
/**
|
|
96
|
+
* Pre-loads the call object
|
|
97
|
+
*/ preload() {
|
|
98
|
+
try {
|
|
99
|
+
this.getOrCreateCallObject();
|
|
100
|
+
} catch (error) {
|
|
101
|
+
var _getSentryClient;
|
|
102
|
+
(_getSentryClient = getSentryClient({
|
|
103
|
+
project: "multimodal"
|
|
104
|
+
})) == null ? void 0 : _getSentryClient.captureException(error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
dispose() {
|
|
108
|
+
this.aiConversationStore.dispose();
|
|
109
|
+
// Remove channel event listeners only on full dispose (not on call end)
|
|
110
|
+
this.rootStore.channel.off("callEnded", this.handleCallEnded);
|
|
111
|
+
this.rootStore.channel.off("coffeeStateUpdate", this.handleCoffeeStateUpdate);
|
|
112
|
+
// Fully destroy the call object on dispose
|
|
113
|
+
this.destroyCallObject();
|
|
114
|
+
// Reset reconnecting state only on full dispose
|
|
115
|
+
this.isReconnecting.value = false;
|
|
116
|
+
this.isSilentRestart.value = false;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns the existing Daily call object or creates a new one.
|
|
120
|
+
* Only one call object is created per session (static singleton).
|
|
121
|
+
*/ getOrCreateCallObject() {
|
|
122
|
+
if (!this.persistentCallObject) {
|
|
123
|
+
const dailyConfig = {
|
|
124
|
+
avoidEval: true
|
|
125
|
+
};
|
|
126
|
+
// Only the strict-CSP self-hosted split-css package should resolve the rewritten
|
|
127
|
+
// call-machine bundle from a sibling file. Hosted snippets must keep using the
|
|
128
|
+
// backend-provided CDN URL so the bundle is served from assets.qualified... rather
|
|
129
|
+
// than a js.qualified... snippet host path.
|
|
130
|
+
const callMachineFilename = getCallMachineBundleFilename();
|
|
131
|
+
const selfHosted = Boolean(window.__qualifiedSplitCss);
|
|
132
|
+
// Resolved here rather than read from a module constant: under unbundled ESM the
|
|
133
|
+
// widget graph is evaluated by static import before `setup()` runs its first line,
|
|
134
|
+
// so a base URL captured at module-evaluation time can never see the override
|
|
135
|
+
// `setup()` sets. See stable_bundle_src.ts.
|
|
136
|
+
const bundleBaseUrl = resolveBundleBaseUrl();
|
|
137
|
+
const explicitUrl = callMachineUrlOverride();
|
|
138
|
+
const localBundleUrl = selfHosted ? explicitUrl != null ? explicitUrl : callMachineFilename ? resolveCallMachineBundleUrl(callMachineFilename, bundleBaseUrl) : null : null;
|
|
139
|
+
// A self-hosted build must serve the call machine from its own origin. Falling
|
|
140
|
+
// through to the backend-provided URL here looked harmless, because voice kept
|
|
141
|
+
// working either way — but it sourced 7 MB of executable JS off-origin, and which
|
|
142
|
+
// origin depended on a feature flag: Qualified's CDN with
|
|
143
|
+
// `piper_x_use_self_hosted_js` on, and c.daily.co with it off (its declared
|
|
144
|
+
// default), because the override below is then never set and Daily falls back to
|
|
145
|
+
// its own hard-coded URL. Both violate the self-hosting requirement and neither
|
|
146
|
+
// shows up in functional testing, so fail loudly rather than degrade quietly.
|
|
147
|
+
if (selfHosted && !localBundleUrl) {
|
|
148
|
+
throw new Error("Qualified: could not resolve the sibling call-machine bundle URL, and refuses " + "to fall back to a remote bundle in a self-hosted build. " + ("(explicitUrl=" + (explicitUrl != null ? explicitUrl : "<unset>") + ", ") + ("filename=" + (callMachineFilename != null ? callMachineFilename : "<unset>") + ", ") + ("baseUrl=" + (bundleBaseUrl != null ? bundleBaseUrl : "<null>") + ")"));
|
|
149
|
+
}
|
|
150
|
+
const bundleUrl = localBundleUrl != null ? localBundleUrl : this.rootStore.dailyCallObjectBundleUrl.value;
|
|
151
|
+
if (bundleUrl) {
|
|
152
|
+
dailyConfig.callObjectBundleUrlOverride = bundleUrl;
|
|
153
|
+
}
|
|
154
|
+
const dailyWsProxyUrl = this.rootStore.dailyWsProxyUrl.value;
|
|
155
|
+
if (dailyWsProxyUrl) {
|
|
156
|
+
dailyConfig.proxyUrl = dailyWsProxyUrl;
|
|
157
|
+
}
|
|
158
|
+
this.persistentCallObject = Ha.createCallObject({
|
|
159
|
+
dailyConfig
|
|
160
|
+
});
|
|
161
|
+
// Pre-load the call object as soon as it's created to avoid delays when joining a call
|
|
162
|
+
// No need to await Daily will handle it internally during .join()
|
|
163
|
+
this.persistentCallObject.load({
|
|
164
|
+
videoSource: false
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return this.persistentCallObject;
|
|
168
|
+
}
|
|
169
|
+
logCoffeeTimingMetrics(state) {
|
|
170
|
+
const provider = this.rootStore.featureFlags.piperXAnam ? types_AvatarProvider.ANAM : types_AvatarProvider.TAVUS;
|
|
171
|
+
// Anam: TTS is held until first video frame (= video_status ACTIVE), so gate on that.
|
|
172
|
+
const isCallActiveForProvider = provider === types_AvatarProvider.ANAM ? state.video_status === "active" : state.call_status === "active";
|
|
173
|
+
const isSessionConnected = isCallActiveForProvider || state.video_status === "voice_only";
|
|
174
|
+
if (isSessionConnected && this.aiConversationStore.availabilityTimeoutId !== null) {
|
|
175
|
+
call_store_clearTimeout(this.aiConversationStore.availabilityTimeoutId);
|
|
176
|
+
this.aiConversationStore.availabilityTimeoutId = null;
|
|
177
|
+
metrics.emitIncrement("multimodal_session_connected");
|
|
178
|
+
}
|
|
179
|
+
if (state.call_status === "active") {
|
|
180
|
+
this.resolveCallAvailabilityMetric("success");
|
|
181
|
+
}
|
|
182
|
+
// Log time from conversation start to all participants joined (once)
|
|
183
|
+
if (state.is_participants_joined) {
|
|
184
|
+
if (!this._callConnectedEmitted) {
|
|
185
|
+
this._callConnectedEmitted = true;
|
|
186
|
+
metrics.emitIncrement("multimodal_call_connected");
|
|
187
|
+
}
|
|
188
|
+
const startTimestamp = this.aiConversationStore.startConversationTimestamp;
|
|
189
|
+
if (startTimestamp !== null) {
|
|
190
|
+
if (this.aiConversationStore.startConversationTimeoutId !== null) {
|
|
191
|
+
call_store_clearTimeout(this.aiConversationStore.startConversationTimeoutId);
|
|
192
|
+
this.aiConversationStore.startConversationTimeoutId = null;
|
|
193
|
+
}
|
|
194
|
+
const deltaMs = performance.now() - startTimestamp;
|
|
195
|
+
metrics.emitTiming("multimodal_time_to_all_participants_joined_ms", deltaMs);
|
|
196
|
+
this.voiceGreetingStartTimestamp = startTimestamp;
|
|
197
|
+
this.aiConversationStore.startConversationTimestamp = null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (!this.isReconnecting.value && !this.isSilentRestart.value) {
|
|
201
|
+
const startedAt = this.rootStore.callInitiatedAt;
|
|
202
|
+
if (this._callActiveAt === null && isCallActiveForProvider && startedAt !== null) {
|
|
203
|
+
this._callActiveAt = performance.now();
|
|
204
|
+
metrics.emitTiming("multimodal_time_to_call_active_ms", this._callActiveAt - startedAt, {
|
|
205
|
+
provider
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
// Tavus-only: Anam's call-active is already video_status=ACTIVE, so delta would be ~0.
|
|
209
|
+
if (provider === types_AvatarProvider.TAVUS && this._videoActiveAt === null && state.video_status === "active" && this._callActiveAt !== null) {
|
|
210
|
+
this._videoActiveAt = performance.now();
|
|
211
|
+
metrics.emitTiming("multimodal_call_active_to_video_active_ms", this._videoActiveAt - this._callActiveAt, {
|
|
212
|
+
provider
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (this._vadActiveAt === null && state.is_audio_ready && this._callActiveAt !== null) {
|
|
216
|
+
this._vadActiveAt = performance.now();
|
|
217
|
+
metrics.emitTiming("multimodal_call_active_to_vad_active_ms", this._vadActiveAt - this._callActiveAt, {
|
|
218
|
+
provider,
|
|
219
|
+
voice_greeting_type: this.rootStore.hasCustomVoiceGreeting ? "custom" : "default"
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (this._initTimeAt === null && startedAt !== null && state.video_status === "active" && state.is_audio_ready) {
|
|
223
|
+
this._initTimeAt = performance.now();
|
|
224
|
+
metrics.emitTiming("multimodal_video_init_time_ms", this._initTimeAt - startedAt, {
|
|
225
|
+
provider
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Log time from participants joined to first bot speaking
|
|
230
|
+
if (state.is_bot_speaking && this.voiceGreetingStartTimestamp !== null) {
|
|
231
|
+
const deltaMs = performance.now() - this.voiceGreetingStartTimestamp;
|
|
232
|
+
metrics.emitTiming("multimodal_voice_greeting_ms", deltaMs);
|
|
233
|
+
this.voiceGreetingStartTimestamp = null;
|
|
234
|
+
this.userStoppedSpeakingTimestamp = null;
|
|
235
|
+
}
|
|
236
|
+
// Voice response latency: time from user stops speaking to bot starts speaking
|
|
237
|
+
if (state.is_user_speaking) {
|
|
238
|
+
this.userStoppedSpeakingTimestamp = null;
|
|
239
|
+
} else if (this.isVisitorSpeaking.value && !state.is_user_speaking) {
|
|
240
|
+
this.userStoppedSpeakingTimestamp = performance.now();
|
|
241
|
+
}
|
|
242
|
+
if (state.is_bot_speaking && this.userStoppedSpeakingTimestamp !== null) {
|
|
243
|
+
const deltaMs = performance.now() - this.userStoppedSpeakingTimestamp;
|
|
244
|
+
metrics.emitTiming("multimodal_voice_response_ms", deltaMs);
|
|
245
|
+
this.userStoppedSpeakingTimestamp = null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
get perceivedMetricEnabled() {
|
|
249
|
+
return this.rootStore.featureFlags.piperXPerceivedVoiceMetric === true;
|
|
250
|
+
}
|
|
251
|
+
constructor(rootStore){
|
|
252
|
+
this.rootStore = rootStore;
|
|
253
|
+
this.persistentCallObject = null;
|
|
254
|
+
this.dailyCall = signals_core_module_d(null);
|
|
255
|
+
this.isJoining = signals_core_module_d(false);
|
|
256
|
+
this.isJoined = signals_core_module_d(false);
|
|
257
|
+
this.error = signals_core_module_d(null);
|
|
258
|
+
this.agentSessionId = signals_core_module_d(null);
|
|
259
|
+
this.isReconnecting = signals_core_module_d(false);
|
|
260
|
+
this.isSilentRestart = signals_core_module_d(false);
|
|
261
|
+
this.voiceGreetingStartTimestamp = null;
|
|
262
|
+
this.isVisitorSpeaking = signals_core_module_d(false);
|
|
263
|
+
this.audioAnalyser = signals_core_module_d(null);
|
|
264
|
+
this.audioContext = null;
|
|
265
|
+
this.currentAudioTrackId = null;
|
|
266
|
+
this.userStoppedSpeakingTimestamp = null;
|
|
267
|
+
this._callConnectedEmitted = false;
|
|
268
|
+
this._videoActiveAt = null;
|
|
269
|
+
this._callActiveAt = null;
|
|
270
|
+
this._vadActiveAt = null;
|
|
271
|
+
this._initTimeAt = null;
|
|
272
|
+
this._playbackReadyNotified = false;
|
|
273
|
+
this.hasConnectedCall = false;
|
|
274
|
+
this.isHandlingFatalCallEnd = false;
|
|
275
|
+
this._availabilityTimeoutId = null;
|
|
276
|
+
this._availabilityResolved = false;
|
|
277
|
+
this.perceivedDetector = null;
|
|
278
|
+
this.perceivedTracker = null;
|
|
279
|
+
this.perceivedBotContext = null;
|
|
280
|
+
this.perceivedBotAnalyser = null;
|
|
281
|
+
this.perceivedBotSources = [];
|
|
282
|
+
this.currentBotTrackKey = null;
|
|
283
|
+
this.onVisibilityChange = null;
|
|
284
|
+
this.perceivedMetricUnavailable = false;
|
|
285
|
+
this.isCoffeeAudioReady = signals_core_module_w(()=>{
|
|
286
|
+
var _this_aiConversationStore_isCoffeeReady_value;
|
|
287
|
+
return (_this_aiConversationStore_isCoffeeReady_value = this.aiConversationStore.isCoffeeReady.value) != null ? _this_aiConversationStore_isCoffeeReady_value : false;
|
|
288
|
+
});
|
|
289
|
+
this.joinCall = async (roomUrl, token)=>{
|
|
290
|
+
if (this.dailyCall.value) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
metrics.emitIncrement("multimodal_call_initiated");
|
|
294
|
+
try {
|
|
295
|
+
this.isJoining.value = true;
|
|
296
|
+
this.error.value = null;
|
|
297
|
+
this.perceivedMetricUnavailable = false;
|
|
298
|
+
// Reuse existing call object or create one if needed
|
|
299
|
+
const call = this.getOrCreateCallObject();
|
|
300
|
+
this.dailyCall.value = call;
|
|
301
|
+
// Attach event listeners
|
|
302
|
+
call.on("participant-joined", this.participantStore.updateParticipants);
|
|
303
|
+
call.on("participant-updated", this.handleParticipantUpdated);
|
|
304
|
+
call.on("participant-left", this.participantStore.updateParticipants);
|
|
305
|
+
call.on("available-devices-updated", this.deviceStore.updateAvailableDevices);
|
|
306
|
+
call.on("selected-devices-updated", this.deviceStore.updateAvailableDevices);
|
|
307
|
+
call.on("error", this.handleError);
|
|
308
|
+
// TODO: Handle multiple concurrent call checks, see #21276
|
|
309
|
+
await call.join(_extends({
|
|
310
|
+
url: roomUrl
|
|
311
|
+
}, token && {
|
|
312
|
+
token
|
|
313
|
+
}, {
|
|
314
|
+
startAudioOff: true,
|
|
315
|
+
startVideoOff: true,
|
|
316
|
+
userName: "Visitor"
|
|
317
|
+
}));
|
|
318
|
+
this.startAvailabilityTimer();
|
|
319
|
+
call.setLocalAudio(true);
|
|
320
|
+
try {
|
|
321
|
+
call.updateInputSettings({
|
|
322
|
+
audio: {
|
|
323
|
+
processor: {
|
|
324
|
+
type: "noise-cancellation"
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
} catch (error) {
|
|
329
|
+
// eslint-disable-next-line no-console
|
|
330
|
+
console.error("Failed to turn on noise cancellation", error);
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
await this.rootStore.checkPermissions();
|
|
334
|
+
} catch (permissionError) {
|
|
335
|
+
var _getSentryClient;
|
|
336
|
+
(_getSentryClient = getSentryClient({
|
|
337
|
+
project: "multimodal"
|
|
338
|
+
})) == null ? void 0 : _getSentryClient.captureException(permissionError);
|
|
339
|
+
}
|
|
340
|
+
// Sync device store with actual call state (needed when reusing call object)
|
|
341
|
+
this.deviceStore.isMicMuted.value = !call.localAudio();
|
|
342
|
+
this.deviceStore.updateAvailableDevices();
|
|
343
|
+
} catch (err) {
|
|
344
|
+
const alreadyHandled = this.error.value !== null;
|
|
345
|
+
if (!alreadyHandled) {
|
|
346
|
+
var _getSentryClient1;
|
|
347
|
+
(_getSentryClient1 = getSentryClient({
|
|
348
|
+
project: "multimodal"
|
|
349
|
+
})) == null ? void 0 : _getSentryClient1.captureException(err);
|
|
350
|
+
if (this.rootStore.featureFlags.piperXAgent) {
|
|
351
|
+
metrics.emitIncrement("multimodal_client_error");
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
this.error.value = err instanceof Error ? err.message : "Failed to join call";
|
|
355
|
+
this.resetCallState();
|
|
356
|
+
} finally{
|
|
357
|
+
this.isJoining.value = false;
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
this.resetCallAvailabilityMetric = ()=>{
|
|
361
|
+
this.clearAvailabilityTimer();
|
|
362
|
+
this._availabilityResolved = false;
|
|
363
|
+
};
|
|
364
|
+
this.startAvailabilityTimer = ()=>{
|
|
365
|
+
this.clearAvailabilityTimer();
|
|
366
|
+
this._availabilityTimeoutId = call_store_setTimeout(()=>{
|
|
367
|
+
this._availabilityTimeoutId = null;
|
|
368
|
+
this.resolveCallAvailabilityMetric("timeout");
|
|
369
|
+
}, CALL_AVAILABILITY_BUDGET_MS);
|
|
370
|
+
};
|
|
371
|
+
this.clearAvailabilityTimer = ()=>{
|
|
372
|
+
if (this._availabilityTimeoutId !== null) {
|
|
373
|
+
call_store_clearTimeout(this._availabilityTimeoutId);
|
|
374
|
+
this._availabilityTimeoutId = null;
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
this.resolveCallAvailabilityMetric = (status)=>{
|
|
378
|
+
if (this._availabilityResolved) return;
|
|
379
|
+
this._availabilityResolved = true;
|
|
380
|
+
this.clearAvailabilityTimer();
|
|
381
|
+
metrics.emitIncrement("multimodal_call_availability", {
|
|
382
|
+
status
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
this.leaveCall = async ()=>{
|
|
386
|
+
const call = this.dailyCall.value;
|
|
387
|
+
if (!call) return;
|
|
388
|
+
try {
|
|
389
|
+
await call.leave();
|
|
390
|
+
} catch (unused) {
|
|
391
|
+
// Ignore leave errors
|
|
392
|
+
} finally{
|
|
393
|
+
// Reset call state but keep the call object for reuse
|
|
394
|
+
this.resetCallState();
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
this.handleRestart = async (silent)=>{
|
|
398
|
+
if (silent === void 0) silent = false;
|
|
399
|
+
signals_core_module_r(()=>{
|
|
400
|
+
this.isReconnecting.value = true;
|
|
401
|
+
this.isSilentRestart.value = silent;
|
|
402
|
+
this.rootStore.isVideoLoading.value = true;
|
|
403
|
+
this.rootStore.isBlurredVideoActive.value = false;
|
|
404
|
+
this.aiConversationStore.isCoffeeReady.value = false;
|
|
405
|
+
});
|
|
406
|
+
this.aiConversationStore.endConversation();
|
|
407
|
+
await this.leaveCall();
|
|
408
|
+
// Pass !silent as the restart param - silent restarts should show normal greeting
|
|
409
|
+
this.aiConversationStore.startConversation(!silent);
|
|
410
|
+
};
|
|
411
|
+
this.handleParticipantUpdated = ()=>{
|
|
412
|
+
this.participantStore.updateParticipants();
|
|
413
|
+
this.deviceStore.syncMediaState();
|
|
414
|
+
this.notifyPlaybackReady();
|
|
415
|
+
if (this.dailyCall.value) {
|
|
416
|
+
var _ref;
|
|
417
|
+
var _this_dailyCall_value_participants_local_tracks_audio, _this_dailyCall_value_participants_local_tracks, _this_dailyCall_value_participants_local, _this_dailyCall_value_participants;
|
|
418
|
+
const audioTrack = (_this_dailyCall_value_participants = this.dailyCall.value.participants()) == null ? void 0 : (_this_dailyCall_value_participants_local = _this_dailyCall_value_participants.local) == null ? void 0 : (_this_dailyCall_value_participants_local_tracks = _this_dailyCall_value_participants_local.tracks) == null ? void 0 : (_this_dailyCall_value_participants_local_tracks_audio = _this_dailyCall_value_participants_local_tracks.audio) == null ? void 0 : _this_dailyCall_value_participants_local_tracks_audio.persistentTrack;
|
|
419
|
+
const trackId = (_ref = audioTrack == null ? void 0 : audioTrack.id) != null ? _ref : null;
|
|
420
|
+
if (trackId !== this.currentAudioTrackId) {
|
|
421
|
+
this.setupAudioAnalyser(this.dailyCall.value);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (this.perceivedMetricEnabled && !this.perceivedMetricUnavailable) {
|
|
425
|
+
this.setupPerceivedVoiceMetric();
|
|
426
|
+
this.setupPerceivedBotAnalyser();
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
// When the coffee agent's audio track becomes renderable on this client (the track the visitor
|
|
430
|
+
// actually hears), tell the agent so it can release the gated greeting before the opening is
|
|
431
|
+
// dropped. Flag-gated; a no-op when off.
|
|
432
|
+
this.notifyPlaybackReady = ()=>{
|
|
433
|
+
var _this_participantStore_coffeeAgentParticipant_value_tracks_audio, _this_participantStore_coffeeAgentParticipant_value_tracks, _this_participantStore_coffeeAgentParticipant_value;
|
|
434
|
+
if (this._playbackReadyNotified) return;
|
|
435
|
+
if (!this.rootStore.featureFlags.piperXGateGreetingOnPlaybackReady) return;
|
|
436
|
+
const state = (_this_participantStore_coffeeAgentParticipant_value = this.participantStore.coffeeAgentParticipant.value) == null ? void 0 : (_this_participantStore_coffeeAgentParticipant_value_tracks = _this_participantStore_coffeeAgentParticipant_value.tracks) == null ? void 0 : (_this_participantStore_coffeeAgentParticipant_value_tracks_audio = _this_participantStore_coffeeAgentParticipant_value_tracks.audio) == null ? void 0 : _this_participantStore_coffeeAgentParticipant_value_tracks_audio.state;
|
|
437
|
+
if (state !== "playable") return;
|
|
438
|
+
this._playbackReadyNotified = true;
|
|
439
|
+
this.rootStore.channel.perform("notify_playback_ready", {});
|
|
440
|
+
};
|
|
441
|
+
this.handleSwitchToText = async ()=>{
|
|
442
|
+
this.aiConversationStore.endConversation();
|
|
443
|
+
await this.leaveCall();
|
|
444
|
+
this.rootStore.setConversationMode(types_ConversationMode.TEXT);
|
|
445
|
+
};
|
|
446
|
+
this.handleCoffeeStateUpdate = (state)=>{
|
|
447
|
+
this.logCoffeeTimingMetrics(state);
|
|
448
|
+
signals_core_module_r(()=>{
|
|
449
|
+
var _this_perceivedTracker, _this_perceivedTracker1, _this_perceivedTracker2, _this_perceivedTracker3;
|
|
450
|
+
// Participant IDs
|
|
451
|
+
if (state.agent_participant_id) {
|
|
452
|
+
this.agentSessionId.value = state.agent_participant_id;
|
|
453
|
+
}
|
|
454
|
+
if (state.is_audio_ready) {
|
|
455
|
+
this.aiConversationStore.isCoffeeReady.value = true;
|
|
456
|
+
}
|
|
457
|
+
// Participants joined
|
|
458
|
+
if (state.is_participants_joined) {
|
|
459
|
+
this.hasConnectedCall = true;
|
|
460
|
+
if (this.rootStore.conversationMode.voice.value) {
|
|
461
|
+
this.rootStore.isVideoLoading.value = false;
|
|
462
|
+
}
|
|
463
|
+
this.isReconnecting.value = false;
|
|
464
|
+
this.isSilentRestart.value = false;
|
|
465
|
+
}
|
|
466
|
+
if (state.avatar_provider !== undefined) {
|
|
467
|
+
var _state_avatar_provider;
|
|
468
|
+
this.rootStore.activeAvatarProvider.value = (_state_avatar_provider = state.avatar_provider) != null ? _state_avatar_provider : null;
|
|
469
|
+
}
|
|
470
|
+
// Video status
|
|
471
|
+
if (state.video_status === "blurred") {
|
|
472
|
+
this.rootStore.isVideoLoading.value = false;
|
|
473
|
+
this.rootStore.isBlurredVideoActive.value = true;
|
|
474
|
+
} else if (state.video_status === "active") {
|
|
475
|
+
this.rootStore.isVideoLoading.value = false;
|
|
476
|
+
this.rootStore.isBlurredVideoActive.value = false;
|
|
477
|
+
} else if (state.video_status === "voice_only") {
|
|
478
|
+
// Disable video first so voice becomes allowed even on a video-only experience;
|
|
479
|
+
// otherwise setConversationMode(VOICE) gets coerced straight back to VIDEO.
|
|
480
|
+
this.rootStore.updateConversationModeFailover({
|
|
481
|
+
videoDisabled: true
|
|
482
|
+
});
|
|
483
|
+
this.rootStore.setConversationMode(types_ConversationMode.VOICE);
|
|
484
|
+
this.rootStore.isVideoLoading.value = false;
|
|
485
|
+
this.rootStore.isBlurredVideoActive.value = false;
|
|
486
|
+
}
|
|
487
|
+
// Speaking state
|
|
488
|
+
this.rootStore.setTypingIndicator(state.is_bot_speaking);
|
|
489
|
+
this.isVisitorSpeaking.value = state.is_user_speaking;
|
|
490
|
+
(_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.setUserSpeaking(state.is_user_speaking);
|
|
491
|
+
(_this_perceivedTracker1 = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker1.setBotSpeaking(state.is_bot_speaking);
|
|
492
|
+
(_this_perceivedTracker2 = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker2.onAnswerBoundary(state.voice_answer_seq);
|
|
493
|
+
(_this_perceivedTracker3 = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker3.onServerOutcome(state.voice_turn_outcome, state.voice_turn_token);
|
|
494
|
+
});
|
|
495
|
+
// Terminal states (outside batch since they're async)
|
|
496
|
+
if (state.is_rep_joined && state.call_status === "ended") {
|
|
497
|
+
this.handleSwitchToText();
|
|
498
|
+
} else if (state.call_status === "restarting") {
|
|
499
|
+
if (this.rootStore.isVideoLoading.value || this.dailyCall.value) {
|
|
500
|
+
this.handleRestart(true);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
this.handleCallEnded = async ()=>{
|
|
505
|
+
this.rootStore.setTypingIndicator(false);
|
|
506
|
+
this.teardownAudioAnalyser();
|
|
507
|
+
this.teardownPerceivedVoiceMetric();
|
|
508
|
+
await this.aiConversationStore.handleEndResponse();
|
|
509
|
+
};
|
|
510
|
+
this.setupAudioAnalyser = (call)=>{
|
|
511
|
+
try {
|
|
512
|
+
var _call_participants, _localParticipant_tracks_audio, _localParticipant_tracks;
|
|
513
|
+
const localParticipant = (_call_participants = call.participants()) == null ? void 0 : _call_participants.local;
|
|
514
|
+
const audioTrack = localParticipant == null ? void 0 : (_localParticipant_tracks = localParticipant.tracks) == null ? void 0 : (_localParticipant_tracks_audio = _localParticipant_tracks.audio) == null ? void 0 : _localParticipant_tracks_audio.persistentTrack;
|
|
515
|
+
if (!audioTrack) return;
|
|
516
|
+
this.teardownAudioAnalyser();
|
|
517
|
+
this.currentAudioTrackId = audioTrack.id;
|
|
518
|
+
this.audioContext = new AudioContext();
|
|
519
|
+
if (this.audioContext.state === "suspended") {
|
|
520
|
+
void this.audioContext.resume().catch(()=>{});
|
|
521
|
+
}
|
|
522
|
+
const source = this.audioContext.createMediaStreamSource(new MediaStream([
|
|
523
|
+
audioTrack
|
|
524
|
+
]));
|
|
525
|
+
const analyser = this.audioContext.createAnalyser();
|
|
526
|
+
analyser.fftSize = 256;
|
|
527
|
+
analyser.smoothingTimeConstant = 0.4;
|
|
528
|
+
source.connect(analyser);
|
|
529
|
+
this.audioAnalyser.value = analyser;
|
|
530
|
+
} catch (unused) {
|
|
531
|
+
var _this_audioContext;
|
|
532
|
+
(_this_audioContext = this.audioContext) == null ? void 0 : _this_audioContext.close();
|
|
533
|
+
this.audioContext = null;
|
|
534
|
+
this.audioAnalyser.value = null;
|
|
535
|
+
this.currentAudioTrackId = null;
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
this.teardownAudioAnalyser = ()=>{
|
|
539
|
+
var _this_audioContext;
|
|
540
|
+
(_this_audioContext = this.audioContext) == null ? void 0 : _this_audioContext.close();
|
|
541
|
+
this.audioContext = null;
|
|
542
|
+
this.audioAnalyser.value = null;
|
|
543
|
+
this.currentAudioTrackId = null;
|
|
544
|
+
this.isVisitorSpeaking.value = false;
|
|
545
|
+
};
|
|
546
|
+
this.setupPerceivedVoiceMetric = ()=>{
|
|
547
|
+
if (!this.perceivedMetricEnabled || this.perceivedTracker || this.perceivedMetricUnavailable) return;
|
|
548
|
+
try {
|
|
549
|
+
const provider = this.rootStore.featureFlags.piperXAnam ? "anam" : "tavus";
|
|
550
|
+
this.perceivedTracker = new PerceivedVoiceTurnTracker({
|
|
551
|
+
budgetMs: (/* inlined export .RESPONSE_BUDGET_MS */25000),
|
|
552
|
+
emitTurn: (status)=>metrics.emitIncrement("multimodal_voice_perceived_turn", {
|
|
553
|
+
status,
|
|
554
|
+
provider
|
|
555
|
+
}),
|
|
556
|
+
emitLatency: (ms)=>metrics.emitTiming("multimodal_voice_perceived_response_ms", ms, {
|
|
557
|
+
provider
|
|
558
|
+
})
|
|
559
|
+
});
|
|
560
|
+
this.perceivedDetector = new VoiceOnsetDetector({
|
|
561
|
+
getMicAnalyser: ()=>this.audioAnalyser.value,
|
|
562
|
+
getBotAnalyser: ()=>this.perceivedBotAnalyser,
|
|
563
|
+
callbacks: {
|
|
564
|
+
onMicQuiet: (ts)=>{
|
|
565
|
+
var _this_perceivedTracker;
|
|
566
|
+
return (_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.onMicQuiet(ts);
|
|
567
|
+
},
|
|
568
|
+
onMicActive: (ts)=>{
|
|
569
|
+
var _this_perceivedTracker;
|
|
570
|
+
return (_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.onMicActive(ts);
|
|
571
|
+
},
|
|
572
|
+
onBotOnset: (ts)=>{
|
|
573
|
+
var _this_perceivedTracker;
|
|
574
|
+
return (_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.onBotOnset(ts);
|
|
575
|
+
},
|
|
576
|
+
onBotSilence: (ts)=>{
|
|
577
|
+
var _this_perceivedTracker;
|
|
578
|
+
return (_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.onBotSilence(ts);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
this.perceivedDetector.start();
|
|
583
|
+
this.onVisibilityChange = ()=>{
|
|
584
|
+
var _this_perceivedTracker;
|
|
585
|
+
if (document.visibilityState === "hidden") (_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.onHidden();
|
|
586
|
+
};
|
|
587
|
+
__nativeDocumentAddEventListener("visibilitychange", this.onVisibilityChange);
|
|
588
|
+
} catch (unused) {
|
|
589
|
+
this.teardownPerceivedVoiceMetric();
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
// At most one bot AudioContext is ever created here; never mutates the mic analyser's config.
|
|
593
|
+
// The audible bot audio can be on EITHER the coffee-agent track OR the Tavus avatar ("Tavus Echo
|
|
594
|
+
// Audio Stream") track, and which one is live varies by provider and — on the tavus_stream_audio
|
|
595
|
+
// path — per-utterance/failover state (coffee routes voice-mode audio on its own track and
|
|
596
|
+
// echo-mode audio through the avatar). So we feed *every* present bot track into ONE analyser and
|
|
597
|
+
// let an onset on either fire; this mirrors what the widget plays and the orb monitors, and can't
|
|
598
|
+
// silently mis-tap on failover. Rebuild only when the set of track ids actually changes (repeated
|
|
599
|
+
// participant-updated events with the same tracks are no-ops), disconnecting the previous sources
|
|
600
|
+
// first so track changes don't leak orphaned nodes into the persistent context.
|
|
601
|
+
this.setupPerceivedBotAnalyser = ()=>{
|
|
602
|
+
try {
|
|
603
|
+
var _ref, _ref1, _this_perceivedBotContext;
|
|
604
|
+
var _this_participantStore_avatarParticipant_value_tracks_audio, _this_participantStore_avatarParticipant_value_tracks, _this_participantStore_avatarParticipant_value, _this_participantStore_coffeeAgentParticipant_value_tracks_audio, _this_participantStore_coffeeAgentParticipant_value_tracks, _this_participantStore_coffeeAgentParticipant_value;
|
|
605
|
+
const avatarTrack = (_ref = (_this_participantStore_avatarParticipant_value = this.participantStore.avatarParticipant.value) == null ? void 0 : (_this_participantStore_avatarParticipant_value_tracks = _this_participantStore_avatarParticipant_value.tracks) == null ? void 0 : (_this_participantStore_avatarParticipant_value_tracks_audio = _this_participantStore_avatarParticipant_value_tracks.audio) == null ? void 0 : _this_participantStore_avatarParticipant_value_tracks_audio.persistentTrack) != null ? _ref : null;
|
|
606
|
+
const coffeeTrack = (_ref1 = (_this_participantStore_coffeeAgentParticipant_value = this.participantStore.coffeeAgentParticipant.value) == null ? void 0 : (_this_participantStore_coffeeAgentParticipant_value_tracks = _this_participantStore_coffeeAgentParticipant_value.tracks) == null ? void 0 : (_this_participantStore_coffeeAgentParticipant_value_tracks_audio = _this_participantStore_coffeeAgentParticipant_value_tracks.audio) == null ? void 0 : _this_participantStore_coffeeAgentParticipant_value_tracks_audio.persistentTrack) != null ? _ref1 : null;
|
|
607
|
+
const tracks = [
|
|
608
|
+
avatarTrack,
|
|
609
|
+
coffeeTrack
|
|
610
|
+
].filter((t)=>t != null);
|
|
611
|
+
if (tracks.length === 0) return;
|
|
612
|
+
const key = tracks.map((t)=>t.id).join("|");
|
|
613
|
+
if (key === this.currentBotTrackKey) return;
|
|
614
|
+
(_this_perceivedBotContext = this.perceivedBotContext) != null ? _this_perceivedBotContext : this.perceivedBotContext = new AudioContext();
|
|
615
|
+
// A context created off an async participant event may start suspended under autoplay
|
|
616
|
+
// policy; a suspended context yields silent analyser frames, so onsets never fire and every
|
|
617
|
+
// heard answer looks like `not_heard`. Resume best-effort (mirrors useAudioLevelMonitoring).
|
|
618
|
+
if (this.perceivedBotContext.state === "suspended") {
|
|
619
|
+
void this.perceivedBotContext.resume().catch(()=>{});
|
|
620
|
+
}
|
|
621
|
+
// Break the previous graph before rebuilding so a track change (reconnect/failover) doesn't
|
|
622
|
+
// leak orphaned source nodes into the persistent context.
|
|
623
|
+
this.disconnectPerceivedBotNodes();
|
|
624
|
+
const analyser = this.perceivedBotContext.createAnalyser();
|
|
625
|
+
analyser.fftSize = 256;
|
|
626
|
+
analyser.smoothingTimeConstant = 0.4;
|
|
627
|
+
for (const track of tracks){
|
|
628
|
+
const source = this.perceivedBotContext.createMediaStreamSource(new MediaStream([
|
|
629
|
+
track
|
|
630
|
+
]));
|
|
631
|
+
source.connect(analyser);
|
|
632
|
+
this.perceivedBotSources.push(source);
|
|
633
|
+
}
|
|
634
|
+
this.perceivedBotAnalyser = analyser;
|
|
635
|
+
this.currentBotTrackKey = key;
|
|
636
|
+
} catch (unused) {
|
|
637
|
+
// A genuine Web Audio failure (not the normal "track not ready yet", which returns early
|
|
638
|
+
// above): tearing down beats running the tracker + budget with a null analyser, which would
|
|
639
|
+
// classify every real answer as `not_heard` and depress the SLI. Disable for the session.
|
|
640
|
+
this.perceivedMetricUnavailable = true;
|
|
641
|
+
this.teardownPerceivedVoiceMetric();
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
this.disconnectPerceivedBotNodes = ()=>{
|
|
645
|
+
for (const source of this.perceivedBotSources){
|
|
646
|
+
try {
|
|
647
|
+
source.disconnect();
|
|
648
|
+
} catch (unused) {
|
|
649
|
+
/* already disconnected */ }
|
|
650
|
+
}
|
|
651
|
+
this.perceivedBotSources = [];
|
|
652
|
+
try {
|
|
653
|
+
var _this_perceivedBotAnalyser;
|
|
654
|
+
(_this_perceivedBotAnalyser = this.perceivedBotAnalyser) == null ? void 0 : _this_perceivedBotAnalyser.disconnect();
|
|
655
|
+
} catch (unused) {
|
|
656
|
+
/* already disconnected */ }
|
|
657
|
+
};
|
|
658
|
+
this.teardownPerceivedVoiceMetric = ()=>{
|
|
659
|
+
try {
|
|
660
|
+
var _this_perceivedDetector, _this_perceivedTracker, _this_perceivedBotContext;
|
|
661
|
+
(_this_perceivedDetector = this.perceivedDetector) == null ? void 0 : _this_perceivedDetector.stop();
|
|
662
|
+
(_this_perceivedTracker = this.perceivedTracker) == null ? void 0 : _this_perceivedTracker.dispose();
|
|
663
|
+
this.disconnectPerceivedBotNodes();
|
|
664
|
+
(_this_perceivedBotContext = this.perceivedBotContext) == null ? void 0 : _this_perceivedBotContext.close();
|
|
665
|
+
if (this.onVisibilityChange) {
|
|
666
|
+
__nativeDocumentRemoveEventListener("visibilitychange", this.onVisibilityChange);
|
|
667
|
+
}
|
|
668
|
+
} catch (unused) {
|
|
669
|
+
/* ignore */ } finally{
|
|
670
|
+
this.perceivedDetector = null;
|
|
671
|
+
this.perceivedTracker = null;
|
|
672
|
+
this.perceivedBotContext = null;
|
|
673
|
+
this.perceivedBotAnalyser = null;
|
|
674
|
+
this.perceivedBotSources = [];
|
|
675
|
+
this.currentBotTrackKey = null;
|
|
676
|
+
this.onVisibilityChange = null;
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
// Private methods
|
|
680
|
+
this.handleTavusConversationChange = (conversation)=>{
|
|
681
|
+
if ((conversation == null ? void 0 : conversation.conversation_url) && !this.dailyCall.value) {
|
|
682
|
+
this.joinCall(conversation.conversation_url, conversation.visitor_token);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
this.handleError = (event)=>{
|
|
686
|
+
var _getSentryClient;
|
|
687
|
+
(_getSentryClient = getSentryClient({
|
|
688
|
+
project: "multimodal"
|
|
689
|
+
})) == null ? void 0 : _getSentryClient.captureException(event);
|
|
690
|
+
if (this.rootStore.featureFlags.piperXAgent) {
|
|
691
|
+
metrics.emitIncrement("multimodal_client_error");
|
|
692
|
+
}
|
|
693
|
+
this.error.value = event.errorMsg || "Call error occurred";
|
|
694
|
+
void this.handleFatalActiveCallEnd();
|
|
695
|
+
};
|
|
696
|
+
this.handleFatalActiveCallEnd = async ()=>{
|
|
697
|
+
if (!this.hasConnectedCall || this.isReconnecting.value || this.isHandlingFatalCallEnd || !this.aiConversationStore.conversation.value) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
this.isHandlingFatalCallEnd = true;
|
|
701
|
+
try {
|
|
702
|
+
await this.aiConversationStore.endConversation();
|
|
703
|
+
} catch (error) {
|
|
704
|
+
var _getSentryClient;
|
|
705
|
+
(_getSentryClient = getSentryClient({
|
|
706
|
+
project: "multimodal"
|
|
707
|
+
})) == null ? void 0 : _getSentryClient.captureException(error);
|
|
708
|
+
} finally{
|
|
709
|
+
this.isHandlingFatalCallEnd = false;
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
/**
|
|
713
|
+
* Resets call-related state without destroying the call object.
|
|
714
|
+
* Used when leaving a call but wanting to rejoin later in the same session.
|
|
715
|
+
*/ this.resetCallState = ()=>{
|
|
716
|
+
this.hasConnectedCall = false;
|
|
717
|
+
this.clearAvailabilityTimer();
|
|
718
|
+
// Detach event listeners before resetting state
|
|
719
|
+
const call = this.dailyCall.value;
|
|
720
|
+
if (!call) return;
|
|
721
|
+
call.off("participant-joined", this.participantStore.updateParticipants);
|
|
722
|
+
call.off("participant-updated", this.handleParticipantUpdated);
|
|
723
|
+
call.off("participant-left", this.participantStore.updateParticipants);
|
|
724
|
+
call.off("available-devices-updated", this.deviceStore.updateAvailableDevices);
|
|
725
|
+
call.off("selected-devices-updated", this.deviceStore.updateAvailableDevices);
|
|
726
|
+
call.off("error", this.handleError);
|
|
727
|
+
this.voiceGreetingStartTimestamp = null;
|
|
728
|
+
this.teardownAudioAnalyser();
|
|
729
|
+
this.teardownPerceivedVoiceMetric();
|
|
730
|
+
this.userStoppedSpeakingTimestamp = null;
|
|
731
|
+
this._callConnectedEmitted = false;
|
|
732
|
+
this._videoActiveAt = null;
|
|
733
|
+
this._callActiveAt = null;
|
|
734
|
+
this._vadActiveAt = null;
|
|
735
|
+
this._initTimeAt = null;
|
|
736
|
+
this._playbackReadyNotified = false;
|
|
737
|
+
this.rootStore.callInitiatedAt = null;
|
|
738
|
+
signals_core_module_r(()=>{
|
|
739
|
+
this.dailyCall.value = null;
|
|
740
|
+
this.isJoined.value = false;
|
|
741
|
+
this.isJoining.value = false;
|
|
742
|
+
this.aiConversationStore.isCoffeeReady.value = false;
|
|
743
|
+
this.agentSessionId.value = null;
|
|
744
|
+
this.rootStore.isBlurredVideoActive.value = false;
|
|
745
|
+
this.participantStore.dispose();
|
|
746
|
+
this.deviceStore.dispose();
|
|
747
|
+
});
|
|
748
|
+
};
|
|
749
|
+
/**
|
|
750
|
+
* Fully destroys the Daily call object and cleans up all resources.
|
|
751
|
+
* Called only on full dispose of the CallStore.
|
|
752
|
+
*/ this.destroyCallObject = ()=>{
|
|
753
|
+
// resetCallState will detach event listeners using persistentCallObject
|
|
754
|
+
this.resetCallState();
|
|
755
|
+
if (this.persistentCallObject) {
|
|
756
|
+
this.persistentCallObject.destroy();
|
|
757
|
+
this.persistentCallObject = null;
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
this.aiConversationStore = new AiConversationStore(this);
|
|
761
|
+
this.aiConversationStore.conversation.subscribe(this.handleTavusConversationChange);
|
|
762
|
+
this.participantStore = new ParticipantStore(this);
|
|
763
|
+
this.deviceStore = new DeviceStore(this);
|
|
764
|
+
this.rootStore.channel.on("callEnded", this.handleCallEnded);
|
|
765
|
+
this.rootStore.channel.on("coffeeStateUpdate", this.handleCoffeeStateUpdate);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
export default CallStore;
|