@hgt-weprotalk/mira-client 0.1.40 → 0.1.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/components/chat-widget/ChatWidget.d.ts +1 -1
  2. package/dist/components/chat-widget/ChatWidget.d.ts.map +1 -1
  3. package/dist/components/chat-widget/hooks/index.d.ts +2 -0
  4. package/dist/components/chat-widget/hooks/index.d.ts.map +1 -1
  5. package/dist/components/chat-widget/hooks/useChatWidgetPanelControlsRegistration.d.ts +12 -0
  6. package/dist/components/chat-widget/hooks/useChatWidgetPanelControlsRegistration.d.ts.map +1 -0
  7. package/dist/components/chat-widget/hooks/useZendeskWebWidgetLauncher.d.ts +10 -0
  8. package/dist/components/chat-widget/hooks/useZendeskWebWidgetLauncher.d.ts.map +1 -0
  9. package/dist/components/chat-widget/shell/ChatWidgetBody.d.ts.map +1 -1
  10. package/dist/components/chat-widget/types/chat-widget.d.ts +10 -0
  11. package/dist/components/chat-widget/types/chat-widget.d.ts.map +1 -1
  12. package/dist/config/runtime.d.ts +2 -0
  13. package/dist/config/runtime.d.ts.map +1 -1
  14. package/dist/embed/mira-chat-bootstrap.js +64 -22
  15. package/dist/embed/mira-chat-host.js +2 -2
  16. package/dist/embed/mira-chat-widget.css +1 -1
  17. package/dist/embed/mira-chat-widget.js +44 -32
  18. package/dist/embed/miraChatHostFacade.d.ts +12 -0
  19. package/dist/embed/miraChatHostFacade.d.ts.map +1 -0
  20. package/dist/embed/scriptEmbedBridge.d.ts +4 -0
  21. package/dist/embed/scriptEmbedBridge.d.ts.map +1 -1
  22. package/dist/index.cjs +40 -28
  23. package/dist/index.js +2802 -2579
  24. package/dist/mira-client.css +1 -1
  25. package/dist/services/zendesk/webWidgetFallback.d.ts +13 -0
  26. package/dist/services/zendesk/webWidgetFallback.d.ts.map +1 -0
  27. package/dist/services/zendesk/zendeskWebWidgetLauncherHide.css.d.ts +5 -0
  28. package/dist/services/zendesk/zendeskWebWidgetLauncherHide.css.d.ts.map +1 -0
  29. package/dist/services/zendesk/zendeskWebWidgetMiraPosition.d.ts +5 -0
  30. package/dist/services/zendesk/zendeskWebWidgetMiraPosition.d.ts.map +1 -0
  31. package/dist/services/zendesk/zendeskWebWidgetPosition.types.d.ts +17 -0
  32. package/dist/services/zendesk/zendeskWebWidgetPosition.types.d.ts.map +1 -0
  33. package/dist/store/chatWidgetState.d.ts +2 -0
  34. package/dist/store/chatWidgetState.d.ts.map +1 -1
  35. package/dist/store/index.d.ts.map +1 -1
  36. package/dist/store/slices/chatSlice.d.ts.map +1 -1
  37. package/dist/types/miraChatHost.d.ts +21 -0
  38. package/dist/types/miraChatHost.d.ts.map +1 -0
  39. package/dist/use-cases-bootstrap.js +64 -22
  40. package/dist/utils/launcherAvatar.d.ts +3 -3
  41. package/dist/utils/launcherAvatar.d.ts.map +1 -1
  42. package/dist/utils/launcherAvatar.types.d.ts +9 -0
  43. package/dist/utils/launcherAvatar.types.d.ts.map +1 -0
  44. package/dist/utils/launcherAvatarByName.d.ts +7 -0
  45. package/dist/utils/launcherAvatarByName.d.ts.map +1 -0
  46. package/package.json +83 -83
@@ -1,6 +1,6 @@
1
1
  import type { ChatWidgetProps } from "./types";
2
2
  import "./chat-widget.css";
3
3
  /** 右下角客服挂件:config/byName → Zendesk SDK → 会话 bootstrap */
4
- declare const ChatWidget: ({ scriptEmbed, locale, agentName, site, launcherAvatar, apiBaseUrl, launcherUnreadEnabled, integrationId, onInitError, }: ChatWidgetProps) => import("react").JSX.Element;
4
+ declare const ChatWidget: ({ scriptEmbed, locale, agentName, site, launcherAvatar, apiBaseUrl, launcherUnreadEnabled, integrationId, zendeskSnippetKey, onInitError, panelControlsRef, }: ChatWidgetProps) => import("react").JSX.Element;
5
5
  export default ChatWidget;
6
6
  //# sourceMappingURL=ChatWidget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../../src/components/chat-widget/ChatWidget.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,mBAAmB,CAAC;AAE3B,yDAAyD;AACzD,QAAA,MAAM,UAAU,GAAI,0HAUjB,eAAe,gCA8IjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../../src/components/chat-widget/ChatWidget.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,mBAAmB,CAAC;AAE3B,yDAAyD;AACzD,QAAA,MAAM,UAAU,GAAI,+JAYjB,eAAe,gCAuIjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -1,3 +1,5 @@
1
+ export { useChatWidgetPanelControlsRegistration } from "./useChatWidgetPanelControlsRegistration";
2
+ export { useIsZendeskWebWidgetFallback, useZendeskWebWidgetLauncher, } from "./useZendeskWebWidgetLauncher";
1
3
  export { useChatWidgetPanelState } from "./useChatWidgetPanelState";
2
4
  export { useChatPanelViewportClamp } from "./useChatPanelViewportClamp";
3
5
  export { useGuideBubbleHide } from "./useGuideBubbleHide";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sCAAsC,EAAE,MAAM,0CAA0C,CAAC;AAClG,OAAO,EACL,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type RefObject } from "react";
2
+ import type { ChatWidgetPanelControls } from "../types/chat-widget";
3
+ interface UseChatWidgetPanelControlsRegistrationOptions {
4
+ scriptEmbed: boolean;
5
+ panelControlsRef?: RefObject<ChatWidgetPanelControls | null>;
6
+ setPanelOpen: (open: boolean) => void;
7
+ setOpenSilently: (open: boolean) => void;
8
+ }
9
+ /** 面板开合注册到 Script embed bridge 与 `window.MiraChatHost` facade */
10
+ export declare function useChatWidgetPanelControlsRegistration({ scriptEmbed, panelControlsRef, setPanelOpen, setOpenSilently, }: UseChatWidgetPanelControlsRegistrationOptions): void;
11
+ export {};
12
+ //# sourceMappingURL=useChatWidgetPanelControlsRegistration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatWidgetPanelControlsRegistration.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/hooks/useChatWidgetPanelControlsRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAclD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,UAAU,6CAA6C;IACrD,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,SAAS,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;IAC7D,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C;AAED,iEAAiE;AACjE,wBAAgB,sCAAsC,CAAC,EACrD,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,eAAe,GAChB,EAAE,6CAA6C,GAAG,IAAI,CAmDtD"}
@@ -0,0 +1,10 @@
1
+ /** Zendesk Web Widget 回退态:Mira Launcher 驱动 zE open/close */
2
+ export declare function useZendeskWebWidgetLauncher(enabled: boolean): {
3
+ isOpen: boolean;
4
+ hasUnread: boolean;
5
+ handleToggleOpen: () => void;
6
+ isPanelVisible: boolean;
7
+ isPanelClosing: boolean;
8
+ };
9
+ export declare const useIsZendeskWebWidgetFallback: () => boolean;
10
+ //# sourceMappingURL=useZendeskWebWidgetLauncher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useZendeskWebWidgetLauncher.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/hooks/useZendeskWebWidgetLauncher.ts"],"names":[],"mappings":"AAQA,4DAA4D;AAC5D,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO;;;;;;EAwC3D;AAED,eAAO,MAAM,6BAA6B,QAAO,OACoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWidgetBody.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/shell/ChatWidgetBody.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAIpD,sCAAsC;AACtC,QAAA,MAAM,cAAc,GAAI,gIAQrB,mBAAmB,gCAmGrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"ChatWidgetBody.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/shell/ChatWidgetBody.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAOpD,sCAAsC;AACtC,QAAA,MAAM,cAAc,GAAI,gIAQrB,mBAAmB,gCA2HrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -1,4 +1,10 @@
1
+ import type { RefObject } from "react";
1
2
  import type { Locale } from "@/i18n";
3
+ /** 可选 ref:与 `window.MiraChatHost` 同源控制,仅供测试/高级集成 */
4
+ export interface ChatWidgetPanelControls {
5
+ open: () => void;
6
+ close: () => void;
7
+ }
2
8
  export interface ChatWidgetProps {
3
9
  /** Script CSR 嵌入(非 React 宿主加载 mira-chat-widget.js) */
4
10
  scriptEmbed?: boolean;
@@ -14,10 +20,14 @@ export interface ChatWidgetProps {
14
20
  apiBaseUrl?: string;
15
21
  /** Zendesk integrationId(对应 data-integration-id;覆盖 site 品牌映射) */
16
22
  integrationId?: string;
23
+ /** bootstrap 失败时 Web Widget snippet key(对应 data-zendesk-snippet-key) */
24
+ zendeskSnippetKey?: string;
17
25
  /** Launcher 未读红点;true 开启(默认关闭) */
18
26
  launcherUnreadEnabled?: boolean;
19
27
  /** bootstrap 失败时回调 */
20
28
  onInitError?: (error: Error) => void;
29
+ /** 挂载后写入 open/close,供宿主页 programmatic 打开面板 */
30
+ panelControlsRef?: RefObject<ChatWidgetPanelControls | null>;
21
31
  }
22
32
  export interface ChatWidgetBodyProps {
23
33
  isOpen: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-widget.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/types/chat-widget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB;IACtB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
1
+ {"version":3,"file":"chat-widget.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-widget/types/chat-widget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB;IACtB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,SAAS,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
@@ -16,6 +16,8 @@ export interface ChatWidgetRuntimeConfig {
16
16
  launcherAvatar?: string;
17
17
  /** Launcher 未读红点;true 开启(默认关闭) */
18
18
  launcherUnreadEnabled?: boolean;
19
+ /** bootstrap 失败时加载 Zendesk Web Widget snippet(Custom Launcher 回退) */
20
+ zendeskSnippetKey?: string;
19
21
  loginUserId?: string;
20
22
  userNickname?: string;
21
23
  hostUser?: HostUserInfo;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/config/runtime.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAC;AAE9F,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,iDAAiD;IACjD,MAAM,CAAC,EAAE,yBAAyB,CAAC;CACpC;AAID,mCAAmC;AACnC,eAAO,MAAM,0BAA0B,GACrC,QAAQ,uBAAuB,KAC9B,IAEF,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,0BAA0B,QAAO,uBAC/B,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/config/runtime.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAC;AAE9F,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,iDAAiD;IACjD,MAAM,CAAC,EAAE,yBAAyB,CAAC;CACpC;AAID,mCAAmC;AACnC,eAAO,MAAM,0BAA0B,GACrC,QAAQ,uBAAuB,KAC9B,IAEF,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,0BAA0B,QAAO,uBAC/B,CAAC"}
@@ -6,22 +6,22 @@
6
6
  /* ========== 宿主配置 ========== */
7
7
 
8
8
  /** @hgt-weprotalk/mira-client 版本(unpkg embed 资源) */
9
- const MIRA_CLIENT_NPM_VERSION = "0.1.40";
9
+ const MIRA_CLIENT_NPM_VERSION = "0.1.41";
10
10
 
11
11
  /** Widget 业务配置 */
12
12
  const WIDGET_CONFIG = {
13
+ zendeskSnippetKey: "f4f934fc-4156-4aa7-b4eb-15f70d87146b",
13
14
  agentName: "after_sales_assistant",
14
- site: "awol-us",
15
+ site: "awol-us2",
15
16
  locale: "en-US",
16
17
  apiBaseUrl: "https://admin.awolvision.com/prod-api",
17
- launcherAvatar:
18
- "https://s3.us-east-1.amazonaws.com/awol-showrooms/2026/09/02/02dde192149f41e59752af11d064f8bf.png",
18
+ // Launcher 头像由 GET /config/byName 的 launcherAvatar(或 avatar)提供,勿在此覆盖
19
19
  };
20
20
 
21
21
  /** unpkg embed 根路径(末尾 /) */
22
- const MIRA_CLIENT_EMBED_BASE = `https://unpkg.com/@hgt-weprotalk/mira-client@${MIRA_CLIENT_NPM_VERSION}/dist/embed/`;
22
+ // const MIRA_CLIENT_EMBED_BASE = `https://unpkg.com/@hgt-weprotalk/mira-client@${MIRA_CLIENT_NPM_VERSION}/dist/embed/`;
23
23
  /** 本地调试:使用本地 embed 资源 */
24
- // const MIRA_CLIENT_EMBED_BASE = `/embed/`;
24
+ const MIRA_CLIENT_EMBED_BASE = `/embed/`;
25
25
 
26
26
  /** PC:变量写在 :root 并映射到 .chat_widget */
27
27
  const HOST_LAYOUT_TOKENS_DESKTOP = {
@@ -39,6 +39,8 @@ const HOST_LAYOUT_TOKENS_MOBILE_ROOT = {};
39
39
 
40
40
  /**
41
41
  * 移动端 Launcher 尺寸与 inset(≤768px)
42
+ * 默认 button-bottom 80px;个别路由底部有 Tab/工具条时,可在该路由调用
43
+ * `MiraChatHostLayout.applyMobileLauncherBottom("120px")` 抬高,避免挡住宿主内容。
42
44
  */
43
45
  const HOST_LAYOUT_TOKENS_MOBILE_ON_BUTTON = {
44
46
  "--mira-chat-widget-button-width": "50px",
@@ -64,9 +66,6 @@ const HOST_Z_INDEX_TOKENS_MOBILE = {
64
66
  "--mira-chat-widget-z-index-panel": "999999",
65
67
  };
66
68
 
67
- /** Widget 初始化失败时加载的 Zendesk snippet */
68
- const ZENDESK_SNIPPET_KEY = "f4f934fc-4156-4aa7-b4eb-15f70d87146b";
69
-
70
69
  /* ========== 以下为加载逻辑(一般无需修改) ========== */
71
70
 
72
71
  (function () {
@@ -254,11 +253,53 @@ const ZENDESK_SNIPPET_KEY = "f4f934fc-4156-4aa7-b4eb-15f70d87146b";
254
253
  return result;
255
254
  };
256
255
 
256
+ const buildConfiguredHostLayoutInput = (mobileLauncherTokens) => ({
257
+ desktopRoot: {
258
+ ...HOST_LAYOUT_TOKENS_DESKTOP,
259
+ ...HOST_Z_INDEX_TOKENS,
260
+ },
261
+ mobileRoot: {
262
+ ...HOST_LAYOUT_TOKENS_MOBILE_ROOT,
263
+ ...HOST_Z_INDEX_TOKENS_MOBILE,
264
+ },
265
+ mobileLauncherTokens,
266
+ });
267
+
257
268
  const applyConfiguredHostLayout = () => {
269
+ window.MiraChatHostLayout.applyHostLayoutTokens(
270
+ buildConfiguredHostLayoutInput(HOST_LAYOUT_TOKENS_MOBILE_ON_BUTTON),
271
+ );
272
+ };
273
+
274
+ /** 特殊路由:覆盖移动端 Launcher 距底(如 "120px"),并同步 .chat_widget inset */
275
+ const applyMobileLauncherBottom = (bottom) => {
276
+ const normalized = String(bottom ?? "").trim();
277
+
278
+ if (!normalized) {
279
+ return;
280
+ }
281
+
282
+ window.MiraChatHostLayout.applyHostLayoutTokens(
283
+ buildConfiguredHostLayoutInput({
284
+ ...HOST_LAYOUT_TOKENS_MOBILE_ON_BUTTON,
285
+ "--mira-chat-widget-button-bottom": normalized,
286
+ }),
287
+ );
288
+ };
289
+
290
+ /** 特殊路由:覆盖 PC Launcher 距底(默认见 HOST_LAYOUT_TOKENS_DESKTOP) */
291
+ const applyDesktopLauncherBottom = (bottom) => {
292
+ const normalized = String(bottom ?? "").trim();
293
+
294
+ if (!normalized) {
295
+ return;
296
+ }
297
+
258
298
  window.MiraChatHostLayout.applyHostLayoutTokens({
259
299
  desktopRoot: {
260
300
  ...HOST_LAYOUT_TOKENS_DESKTOP,
261
301
  ...HOST_Z_INDEX_TOKENS,
302
+ "--mira-chat-widget-button-bottom": normalized,
262
303
  },
263
304
  mobileRoot: {
264
305
  ...HOST_LAYOUT_TOKENS_MOBILE_ROOT,
@@ -268,6 +309,10 @@ const ZENDESK_SNIPPET_KEY = "f4f934fc-4156-4aa7-b4eb-15f70d87146b";
268
309
  });
269
310
  };
270
311
 
312
+ window.MiraChatHostLayout.applyConfiguredHostLayout = applyConfiguredHostLayout;
313
+ window.MiraChatHostLayout.applyMobileLauncherBottom = applyMobileLauncherBottom;
314
+ window.MiraChatHostLayout.applyDesktopLauncherBottom = applyDesktopLauncherBottom;
315
+
271
316
  const ensureMountRoot = () => {
272
317
  if (document.getElementById(MOUNT_ID)) {
273
318
  return;
@@ -291,21 +336,18 @@ const ZENDESK_SNIPPET_KEY = "f4f934fc-4156-4aa7-b4eb-15f70d87146b";
291
336
  document.head.appendChild(link);
292
337
  };
293
338
 
294
- const loadZendeskSnippet = () => {
295
- if (document.getElementById("ze-snippet")) {
296
- return;
297
- }
298
-
299
- const script = document.createElement("script");
300
- script.id = "ze-snippet";
301
- script.src = `https://static.zdassets.com/ekr/snippet.js?key=${encodeURIComponent(ZENDESK_SNIPPET_KEY)}`;
302
- script.async = true;
303
- document.body.appendChild(script);
304
- };
339
+ const hostMiraChatOnReady = window.MiraChatHostConfig?.onReady;
340
+ const hostMiraChatOnInitError = window.MiraChatHostConfig?.onInitError;
305
341
 
306
342
  window.MiraChatHostConfig = {
307
- onInitError: () => {
308
- loadZendeskSnippet();
343
+ debug: window.MiraChatHostConfig?.debug,
344
+ onReady: (sdk) => {
345
+ hostMiraChatOnReady?.(sdk);
346
+ window.__MIRA_CHAT_HOST_REGISTRY__?.notifySdkReady();
347
+ },
348
+ onInitError: (error) => {
349
+ hostMiraChatOnInitError?.(error);
350
+ console.error("[mira-chat-host] widget init failed", error);
309
351
  },
310
352
  };
311
353
 
@@ -1,2 +1,2 @@
1
- (function(){var e=()=>{if(typeof crypto<`u`&&typeof crypto.randomUUID==`function`)return crypto.randomUUID();if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.floor(Math.random()*16);return(e===`x`?t:t&3|8).toString(16)})},t=`mira:tab-id`,n=()=>{let n=sessionStorage.getItem(t);if(n)return n;let r=e();return sessionStorage.setItem(t,r),r},r=`mira:tab-sync-debug`,i=()=>{try{return window.localStorage.getItem(r)===`1`}catch{return!1}},a=(e,t,n)=>{i()&&console.info(`[mira-tab-sync] publish`,{tabId:e,transport:n,type:t.type})},o=(e,t,n)=>{i()&&console.info(`[mira-tab-sync] dispatch`,{localTabId:e,source:n,foreign:t.tabId!==e,type:t.type,fromTabId:t.tabId})},s=`mira-chat-widget-sync`,c=`mira:tab-sync-signal`,l=(e,t)=>e.tabId!==t,u=e=>{try{let t=JSON.parse(e);return typeof t.type!=`string`||typeof t.tabId!=`string`?null:t}catch{return null}},d=()=>{let e=n(),t=new Set,r=typeof BroadcastChannel<`u`,i=(n,r)=>{o(e,n,r),t.forEach(e=>{e(n)})},l=t=>{let n={...t,tabId:e,ts:Date.now()};if(r){f?.postMessage(n),a(e,t,`broadcast-channel`);return}try{localStorage.setItem(c,JSON.stringify(n)),a(e,t,`local-storage`)}catch{}},d=e=>(t.add(e),()=>{t.delete(e)}),f=null;return r&&(f=new BroadcastChannel(s),f.addEventListener(`message`,e=>{!e.data?.type||typeof e.data.tabId!=`string`||i(e.data,`broadcast-channel`)})),window.addEventListener(`storage`,e=>{if(r||e.key!==`mira:tab-sync-signal`||!e.newValue)return;let t=u(e.newValue);t&&i(t,`storage`)}),{tabId:e,publish:l,subscribe:d}},f=null,p=()=>(f||=d(),f),m=e=>{p().publish(e)},h={},g=e=>{h={...h,...e}},ee={},_=()=>ee,v={get agentName(){return _().agentName||`after_sales_assistant`},get site(){return _().site||`awol-us`},get launcherAvatar(){return _().launcherAvatar||``},get apiBaseUrl(){return _().apiBaseUrl||`/agent-api/prod-api`}},te=`67ac5e61bda319808e8ee33f`,y={awol:`67ac625c068bf0420481ad97`,valerion:`67ac5e61bda319808e8ee33f`},b=e=>{let t=e.trim().toLowerCase();if(!t)return null;let n=t.indexOf(`-`);return n<=0?null:t.slice(0,n)},ne=e=>{let t=b(e);return t?y[t]??`67ac5e61bda319808e8ee33f`:te},re=()=>_().integrationId?.trim()||ne(v.site),x=null,ie=()=>(x||=d(),x),ae=e=>{ie().publish(e)},oe=`zendesk:visitor-id`,S=`mira:visitor-id`,C=null,w=!1,T=new Set,E=(e,t)=>{let n=localStorage.getItem(e);!n||localStorage.getItem(t)||localStorage.setItem(t,n)},se=()=>{T.forEach(e=>{e()})},ce=()=>{w||typeof window>`u`||(w=!0,window.addEventListener(`storage`,e=>{e.key!==`mira:visitor-id`||!e.newValue||C&&e.newValue!==C&&(C=e.newValue,se(),ae({type:`user-bound`}))}))},D=()=>{ce(),E(oe,S);let t=localStorage.getItem(S);if(t)return C=t,t;if(C)return C;let n=e();return localStorage.setItem(S,n),C=n,n},O=e=>`${v.apiBaseUrl.replace(/\/$/,``)}${e.startsWith(`/`)?e:`/${e}`}`,k=async e=>{let t=await e.json().catch(()=>({}));if(!e.ok||typeof t.code==`number`&&t.code!==200)throw Error(t.msg||t.message||`Request failed: ${e.status}`);return t.data},A=async(e,t)=>k(await fetch(O(e),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})),j=async(e,t)=>k(await fetch(O(e),{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})),le=async(e,t={})=>k(await fetch(`${O(e)}${M(t)}`,{method:`DELETE`,headers:{"Content-Type":`application/json`}})),ue=async e=>k(await fetch(O(e),{method:`GET`,headers:{"Content-Type":`application/json`}})),M=e=>{let t=new URLSearchParams;Object.entries(e).forEach(([e,n])=>{n!==void 0&&n!==``&&t.set(e,String(n))});let n=t.toString();return n?`?${n}`:``},N=async(e,t={})=>{let n=await fetch(`${O(e)}${M(t)}`,{method:`GET`,headers:{"Content-Type":`application/json`}}),r=await n.json().catch(()=>({}));if(!n.ok||typeof r.code==`number`&&r.code!==200)throw Error(r.msg||r.message||`Request failed: ${n.status}`);return{total:Number(r.total)||0,rows:Array.isArray(r.rows)?r.rows:[]}},P=e=>e.replace(/\\u([0-9a-f]{4})/gi,(e,t)=>String.fromCharCode(parseInt(t,16))),F=(e,t=!1)=>{e.onCompleted?.(t)},I=(e,t)=>{let n=e.trim();if(!n.startsWith(`data: `))return!1;let r;try{r=JSON.parse(n.slice(6))}catch{return!1}if(!r||typeof r!=`object`)return!1;let i=typeof r.status==`number`&&r.status>=400;if(r.event===`error`||i)return t.onError?.(r.msg||r.message||`Unknown error`),!0;if(!r.event)return!1;let{onMessage:a}=t;if(r.event===`message`){let e=P(r.data?.content||r.answer||``);return e&&a?.({answer:e}),!1}return r.event===`question_classification`?(t.onClassification?.({categoryName:r.data?.category_name||``}),!1):r.event===`retrival_knowledge`?(t.onRetrievalKnowledge?.({items:r.data?.retrival_knowledge||[]}),!1):r.event===`transfer_human`?(t.onTransferHuman?.({transferToHuman:!!r.data?.transfer_to_human}),!1):r.event===`knowledge_gap`?(t.onKnowledgeGap?.({knowledgeGap:!!(r.data?.knowledge_gap??!0)}),!1):r.event!==`done`&&r.event===`persist`&&(t.onPersist?.({sessionId:r.sessionId,questionMessageId:r.questionMessageId,answerMessageId:r.answerMessageId,categoryName:r.categoryName||``,transferToHuman:!!r.transferToHuman,knowledgeGap:!!r.knowledgeGap}),r.transferToHuman&&t.onTransferHuman?.({transferToHuman:!0}),!1)},L=async(e,t)=>{let{onError:n}=t;if(!e.ok){let r=await e.json().catch(()=>({}));n?.(r.msg||r.message||`Request failed: ${e.status}`),F(t,!0);return}let r=e.body?.getReader();if(!r){n?.(`Stream is not supported`),F(t,!0);return}let i=new TextDecoder(`utf-8`),a=``,o=!1;try{for(;;){let{done:e,value:n}=await r.read();if(e)break;a+=i.decode(n,{stream:!0});let s=a.split(`
2
- `);a=s.pop()||``;for(let e of s)if(I(e,t)){o=!0,F(t,!0);return}}if(a.trim()&&I(a,t)){o=!0,F(t,!0);return}o||F(t,!1)}catch(e){if(e instanceof Error&&e.name===`AbortError`){F(t,!1);return}n?.(String(e)),F(t,!0)}},R={PRESET_MSG:`PRESET_MSG`,LINK:`LINK`,COLLECT_FORM:`COLLECT_FORM`},z=new Set(Object.values(R)),B=e=>z.has(e),V=(e,t)=>{if(!e||typeof e!=`object`)return null;let n=e,r=typeof n.title==`string`?n.title.trim():``;if(!r)return null;let i=typeof n.effectType==`string`?n.effectType.trim():``;if(!B(i))return null;let a=i,o=typeof n.rounds==`number`&&Number.isFinite(n.rounds)?Math.max(0,Math.floor(n.rounds)):0,s=typeof n.sortOrder==`number`&&Number.isFinite(n.sortOrder)?n.sortOrder:t,c=n.effectConfig&&typeof n.effectConfig==`object`?n.effectConfig:{},l=typeof c.question==`string`?c.question.trim():``,u=a===R.PRESET_MSG?l||r:l||void 0;return{title:r,rounds:o,effectType:a,effectConfig:{url:typeof c.url==`string`?c.url:void 0,question:u,reply:typeof c.reply==`string`?c.reply:void 0},sortOrder:s}},H=(e=[])=>e.map((e,t)=>V(e,t)).filter(e=>e!==null).sort((e,t)=>e.sortOrder-t.sortOrder),U=e=>!e||typeof e!=`object`||Array.isArray(e)?null:e,W=e=>typeof e==`string`?e.trim():``,G=e=>{try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}},de=e=>{let t=U(e);if(!t)return null;let n=W(t.type);if(n===`text`){let e=W(t.text);return e?{type:`text`,text:e}:null}if(n===`image`){let e=W(t.imageUrl);return G(e)?{type:`image`,imageUrl:e,alt:W(t.alt)}:null}if(n===`link`){let e=W(t.label),n=W(t.action);if(!e)return null;if(n===`OPEN_CHAT`)return{type:`link`,label:e,action:`OPEN_CHAT`};if(n===`URL`){let n=W(t.url);return G(n)?{type:`link`,label:e,action:`URL`,url:n}:null}return null}if(n===`button`){let e=W(t.label),n=W(t.action);if(!e)return null;if(n===`OPEN_CHAT`)return{type:`button`,label:e,action:`OPEN_CHAT`};if(n===`URL`){let n=W(t.url);return G(n)?{type:`button`,label:e,action:`URL`,url:n}:null}return null}return null},fe=(e,t)=>{let n=U(e);if(!n)return null;let r=W(n.title);if(!r)return null;let i=W(n.iconUrl),a=typeof n.sortOrder==`number`&&Number.isFinite(n.sortOrder)?n.sortOrder:t,o=Array.isArray(n.blocks)?n.blocks:[];return{sortOrder:a,title:r,description:W(n.description),iconUrl:G(i)?i:``,blocks:o.map(e=>de(e)).filter(e=>e!==null)}},pe=e=>{let t=U(e);if(!t)return{enabled:!1,groups:[]};let n=(Array.isArray(t.groups)?t.groups:[]).map((e,t)=>fe(e,t)).filter(e=>e!==null).sort((e,t)=>e.sortOrder-t.sortOrder);return t.enabled===!1?{enabled:!1,groups:n}:{enabled:n.length>0,groups:n}},K={AI_CHAT:`AI_CHAT`,TRANSFERRING:`TRANSFERRING`,TRANSFERRED:`TRANSFERRED`,CLOSE:`CLOSE`},me=new Set(Object.values(K)),he=e=>{if(!e)return;let t=e.toUpperCase();if(me.has(t))return t},q=`/client/agentChat`,ge=e=>({...e,sessionStatus:he(e.sessionStatus)}),_e=(e=[])=>e.slice().sort((e,t)=>(e.sortOrder??0)-(t.sortOrder??0)).filter(e=>!!e.question?.trim()),ve=async(e,t=v.site)=>{let n=await ue(`${q}/config/byName/${encodeURIComponent(e)}?site=${encodeURIComponent(t)}`),r=re(),i=pe(n.guideBubble);return{agentId:n.id,agentName:n.agentName,integrationsId:r,title:n.name||``,avatar:n.avatar||``,launcherAvatar:n.launcherAvatar||``,openingStatement:n.greeting||``,transferWaitText:n.transferWaitText||``,suggestedQuestions:_e(n.recommendedQuestions),quickEntries:H(n.quickEntries),productCardsEnabled:n.productCardsEnabled??!0,guideBubble:i,placeholder:``}},ye=async({agentId:e,visitorId:t=D(),channel:n=`web`})=>{if(!e)throw Error(`Missing agentId, unable to create session`);let r=await A(`${q}/session`,{agentId:e,visitorId:t,channel:n});return{sessionId:r.sessionId,visitorId:r.visitorId||t,userId:r.userId||t}},be=async e=>{try{await A(`${q}/open`,{...e,channel:`web`})}catch{}},J=async()=>{let{agentName:e}=v;return ve(e)},xe=async({visitorId:e=D(),agentId:t,pageNum:n=1,pageSize:r=50}={})=>{let i=await N(`${q}/session/list`,{visitorId:e,agentId:t,pageNum:n,pageSize:r});return{...i,rows:i.rows.map(ge)}},Se=async({visitorId:e=D(),agentId:t,sessionId:n,pageNum:r=1,pageSize:i=200})=>N(`${q}/message/list`,{visitorId:e,agentId:t,sessionId:n,pageNum:r,pageSize:i}),Ce=async({sessionId:e,visitorId:t=D()})=>{await A(`${q}/session/${e}/close?${new URLSearchParams({visitorId:t}).toString()}`,{})},we=async({sessionId:e,sessionStatus:t,visitorId:n=D()})=>{await j(`${q}/session/${e}/status`,{sessionStatus:t,visitorId:n})},Te=async({messageIds:e,visitorId:t=D()})=>{e.length!==0&&await A(`${q}/message/read`,{messageIds:e,visitorId:t})},Ee=async({sessionId:e,visitorId:t=D()})=>{await le(`${q}/session/${e}`,{visitorId:t})},De=async()=>{let e=D();return{...await J(),sessionId:null,visitorId:e,userId:e,sessionStatus:K.AI_CHAT,conversationId:null,zendeskUserId:null,transferManual:0}},Y=null,X={initSession:async()=>(Y||=De().catch(e=>{throw Y=null,e}),Y),resetInitSession:()=>{Y=null},loadAgentConfig:J,createSession:ye,openSession:be,fetchSessionList:xe,fetchMessageList:Se,deleteSession:Ee,closeSession:Ce,updateSessionStatus:we,markMessagesRead:Te,sendMessage:async({query:t,agentId:n,sessionId:r,visitorId:i,clientMessageId:a,signal:o,...s})=>{await L(await fetch(O(`${q}/chat`),{method:`POST`,credentials:`include`,signal:o,headers:{"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify({agentId:n,sessionId:r,visitorId:i,content:t,clientMessageId:a||e()})}),s)},sendPresetMessage:async({agentId:e,sessionId:t,visitorId:n,recommendedQuestion:r,quickEntry:i})=>{let a={agentId:e,sessionId:t,visitorId:n};return r?a.recommendedQuestion=r:i&&(a.quickEntry=i),A(`${q}/message/preset`,a)},reportTransfer:async({agentId:e,sessionId:t,visitorId:n,eventType:r,conversationId:i,zendeskUserId:a})=>{if(!(!e||!t||!r||!i)&&!(r===`TRIGGER`&&!a))try{await A(`${q}/transfer`,{agentId:e,sessionId:t,visitorId:n||D(),eventType:r,conversationId:i,...a?{zendeskUserId:a}:{}})}catch{}},submitFeedback:async({agentId:e,sessionId:t,messageId:n,questionMessageId:r,visitorId:i,feedbackType:a,question:o,answer:s,type:c,feedbackContent:l})=>(await A(`${q}/feedback`,{agentId:e,sessionId:t,messageId:n,questionMessageId:r,visitorId:i,feedbackType:a,question:o,answer:s,...c?{type:c}:{},feedbackContent:l})).id,updateFeedback:async({feedbackId:e,agentId:t,sessionId:n,messageId:r,questionMessageId:i,visitorId:a,feedbackType:o,question:s,answer:c,type:l,feedbackContent:u})=>{await j(`${q}/feedback/${e}`,{agentId:t,sessionId:n,messageId:r,questionMessageId:i,visitorId:a,feedbackType:o,question:s,answer:c,...l?{type:l}:{},feedbackContent:u})},bindUser:async({loginUserId:e,userNickname:t,visitorId:n=D()})=>{if(!e.trim())throw Error(`loginUserId is required`);if(e===n)throw Error(`loginUserId must differ from visitorId`);return A(`${q}/bindUser`,{visitorId:n,loginUserId:e,...t?{userNickname:t}:{}})}},Oe=e=>{g({...e.loginUserId?{loginUserId:e.loginUserId}:{},...e.userNickname?{userNickname:e.userNickname}:{},...e.product?{productContext:e.product}:{},...e.loginUserId&&e.userName&&e.userEmail?{hostUser:{loginUserId:e.loginUserId,name:e.userName,email:e.userEmail,...e.userNickname?{userNickname:e.userNickname}:{}}}:{}})},ke=async e=>{let t=await X.bindUser(e);return m({type:`user-bound`}),t},Ae=async e=>{g({hostUser:{loginUserId:e.loginUserId,name:e.name,email:e.email,...e.userNickname?{userNickname:e.userNickname}:{}},loginUserId:e.loginUserId,...e.userNickname?{userNickname:e.userNickname}:{}});try{await X.bindUser({loginUserId:e.loginUserId,userNickname:e.userNickname})}catch{}return m({type:`user-bound`}),{ok:!0}},je=e=>(Oe(e),{ok:!0}),Z=async(e,t)=>{switch(e){case`bindUser`:return ke(t);case`setUser`:return Ae(t);case`setContext`:return je(t);default:throw Error(`Unknown SDK method: ${e}`)}},Q=e=>{let t=!1,n=new Map,r=(e,t)=>{n.get(e)?.forEach(e=>{e(t)})};return{sdk:{get ready(){return t},bindUser:e=>Z(`bindUser`,e),setContext:e=>Z(`setContext`,e),setUser:e=>Z(`setUser`,e),open:async()=>(e.open(),{ok:!0}),close:async()=>(e.close(),{ok:!0}),on(e,t){let r=String(e);return n.has(r)||n.set(r,new Set),n.get(r)?.add(t),()=>{n.get(r)?.delete(t)}}},markReady:()=>{t||(t=!0,r(`ready`,void 0))},emitHostEvent:(e,t)=>{r(String(e),t)}}},Me=`mira-chat-widget-mounted`,Ne=`mira-chat-ready`,Pe=()=>window.__MIRA_CHAT_WIDGET__??null,Fe=e=>{window.MiraChatHostConfig?.debug&&console.info(`[mira-chat-host] ${e}`)},$=()=>{if(window.MiraChat)return;let e=Pe();if(!e)return;let t=p(),{sdk:n,markReady:r,emitHostEvent:i}=Q({open:()=>{e.setPanelOpenSilently(!0),t.publish({type:`window-open`})},close:()=>{e.setPanelOpenSilently(!1),t.publish({type:`window-close`})}}),a=n.setContext.bind(n);n.setContext=async e=>{let n=await a(e);return t.publish({type:`context-updated`,payload:e}),n};let o=n.bindUser.bind(n);n.bindUser=async e=>{let n=await o(e);return t.publish({type:`user-bound`}),n};let s=n.setUser.bind(n);n.setUser=async e=>{let n=await s(e);return t.publish({type:`user-bound`}),n},window.MiraChat=n,n.on(`ready`,()=>{window.MiraChatHostConfig?.onReady?.(n),window.dispatchEvent(new CustomEvent(Ne)),Fe(`MiraChat SDK ready`)}),t.subscribe(n=>{if(l(n,t.tabId)){if(n.type===`window-open`){e.setPanelOpenSilently(!0);return}if(n.type===`window-close`){e.setPanelOpenSilently(!1);return}n.type===`context-updated`&&a(n.payload)}})};$(),window.addEventListener(Me,()=>{$()})})();
1
+ (function(){var e=()=>{if(typeof crypto<`u`&&typeof crypto.randomUUID==`function`)return crypto.randomUUID();if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.floor(Math.random()*16);return(e===`x`?t:t&3|8).toString(16)})},t=`mira:tab-id`,n=()=>{let n=sessionStorage.getItem(t);if(n)return n;let r=e();return sessionStorage.setItem(t,r),r},r=`mira:tab-sync-debug`,i=()=>{try{return window.localStorage.getItem(r)===`1`}catch{return!1}},a=(e,t,n)=>{i()&&console.info(`[mira-tab-sync] publish`,{tabId:e,transport:n,type:t.type})},o=(e,t,n)=>{i()&&console.info(`[mira-tab-sync] dispatch`,{localTabId:e,source:n,foreign:t.tabId!==e,type:t.type,fromTabId:t.tabId})},s=`mira-chat-widget-sync`,c=`mira:tab-sync-signal`,l=(e,t)=>e.tabId!==t,u=e=>{try{let t=JSON.parse(e);return typeof t.type!=`string`||typeof t.tabId!=`string`?null:t}catch{return null}},d=()=>{let e=n(),t=new Set,r=typeof BroadcastChannel<`u`,i=(n,r)=>{o(e,n,r),t.forEach(e=>{e(n)})},l=t=>{let n={...t,tabId:e,ts:Date.now()};if(r){f?.postMessage(n),a(e,t,`broadcast-channel`);return}try{localStorage.setItem(c,JSON.stringify(n)),a(e,t,`local-storage`)}catch{}},d=e=>(t.add(e),()=>{t.delete(e)}),f=null;return r&&(f=new BroadcastChannel(s),f.addEventListener(`message`,e=>{!e.data?.type||typeof e.data.tabId!=`string`||i(e.data,`broadcast-channel`)})),window.addEventListener(`storage`,e=>{if(r||e.key!==`mira:tab-sync-signal`||!e.newValue)return;let t=u(e.newValue);t&&i(t,`storage`)}),{tabId:e,publish:l,subscribe:d}},f=null,p=()=>(f||=d(),f),m=e=>{p().publish(e)},h=`pending`,g=null,_=!1,ee=()=>window.MiraChat?.ready?(window.MiraChat.open(),!0):!1,v=()=>{_&&(_=!1,y.open())},y={getProvider:()=>h,open:()=>{if(h===`zendesk`&&g){g.open();return}ee()||(_=!0)},close:()=>{if(h===`zendesk`&&g){g.close();return}window.MiraChat?.ready&&window.MiraChat.close(),_=!1}},te={registerZendeskFallback:e=>{b(),g=e,h=`zendesk`,v()},notifySdkReady:()=>{h!==`zendesk`&&(h=`mira`,v())},takePendingPanelOpen:()=>{let e=_;return _=!1,e}};function b(){return window.MiraChatHost||(window.MiraChatHost=y),window.__MIRA_CHAT_HOST_REGISTRY__=te,window.MiraChatHost}var x={},S=e=>{x={...x,...e}},ne={},C=()=>ne,w={get agentName(){return C().agentName||`after_sales_assistant`},get site(){return C().site||`valerion-us`},get launcherAvatar(){return C().launcherAvatar||``},get apiBaseUrl(){return C().apiBaseUrl||`/agent-api/prod-api`}},re=`67ac5e61bda319808e8ee33f`,ie={awol:`67ac625c068bf0420481ad97`,valerion:`67ac5e61bda319808e8ee33f`},ae=e=>{let t=e.trim().toLowerCase();if(!t)return null;let n=t.indexOf(`-`);return n<=0?null:t.slice(0,n)},oe=e=>{let t=ae(e);return t?ie[t]??`67ac5e61bda319808e8ee33f`:re},se=()=>C().integrationId?.trim()||oe(w.site),T=null,ce=()=>(T||=d(),T),le=e=>{ce().publish(e)},ue=`zendesk:visitor-id`,E=`mira:visitor-id`,D=null,O=!1,de=new Set,fe=(e,t)=>{let n=localStorage.getItem(e);!n||localStorage.getItem(t)||localStorage.setItem(t,n)},pe=()=>{de.forEach(e=>{e()})},me=()=>{O||typeof window>`u`||(O=!0,window.addEventListener(`storage`,e=>{e.key!==`mira:visitor-id`||!e.newValue||D&&e.newValue!==D&&(D=e.newValue,pe(),le({type:`user-bound`}))}))},k=()=>{me(),fe(ue,E);let t=localStorage.getItem(E);if(t)return D=t,t;if(D)return D;let n=e();return localStorage.setItem(E,n),D=n,n},A=e=>`${w.apiBaseUrl.replace(/\/$/,``)}${e.startsWith(`/`)?e:`/${e}`}`,j=async e=>{let t=await e.json().catch(()=>({}));if(!e.ok||typeof t.code==`number`&&t.code!==200)throw Error(t.msg||t.message||`Request failed: ${e.status}`);return t.data},M=async(e,t)=>j(await fetch(A(e),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})),N=async(e,t)=>j(await fetch(A(e),{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})),he=async(e,t={})=>j(await fetch(`${A(e)}${P(t)}`,{method:`DELETE`,headers:{"Content-Type":`application/json`}})),ge=async e=>j(await fetch(A(e),{method:`GET`,headers:{"Content-Type":`application/json`}})),P=e=>{let t=new URLSearchParams;Object.entries(e).forEach(([e,n])=>{n!==void 0&&n!==``&&t.set(e,String(n))});let n=t.toString();return n?`?${n}`:``},F=async(e,t={})=>{let n=await fetch(`${A(e)}${P(t)}`,{method:`GET`,headers:{"Content-Type":`application/json`}}),r=await n.json().catch(()=>({}));if(!n.ok||typeof r.code==`number`&&r.code!==200)throw Error(r.msg||r.message||`Request failed: ${n.status}`);return{total:Number(r.total)||0,rows:Array.isArray(r.rows)?r.rows:[]}},_e=e=>e.replace(/\\u([0-9a-f]{4})/gi,(e,t)=>String.fromCharCode(parseInt(t,16))),I=(e,t=!1)=>{e.onCompleted?.(t)},L=(e,t)=>{let n=e.trim();if(!n.startsWith(`data: `))return!1;let r;try{r=JSON.parse(n.slice(6))}catch{return!1}if(!r||typeof r!=`object`)return!1;let i=typeof r.status==`number`&&r.status>=400;if(r.event===`error`||i)return t.onError?.(r.msg||r.message||`Unknown error`),!0;if(!r.event)return!1;let{onMessage:a}=t;if(r.event===`message`){let e=_e(r.data?.content||r.answer||``);return e&&a?.({answer:e}),!1}return r.event===`question_classification`?(t.onClassification?.({categoryName:r.data?.category_name||``}),!1):r.event===`retrival_knowledge`?(t.onRetrievalKnowledge?.({items:r.data?.retrival_knowledge||[]}),!1):r.event===`transfer_human`?(t.onTransferHuman?.({transferToHuman:!!r.data?.transfer_to_human}),!1):r.event===`knowledge_gap`?(t.onKnowledgeGap?.({knowledgeGap:!!(r.data?.knowledge_gap??!0)}),!1):r.event!==`done`&&r.event===`persist`&&(t.onPersist?.({sessionId:r.sessionId,questionMessageId:r.questionMessageId,answerMessageId:r.answerMessageId,categoryName:r.categoryName||``,transferToHuman:!!r.transferToHuman,knowledgeGap:!!r.knowledgeGap}),r.transferToHuman&&t.onTransferHuman?.({transferToHuman:!0}),!1)},ve=async(e,t)=>{let{onError:n}=t;if(!e.ok){let r=await e.json().catch(()=>({}));n?.(r.msg||r.message||`Request failed: ${e.status}`),I(t,!0);return}let r=e.body?.getReader();if(!r){n?.(`Stream is not supported`),I(t,!0);return}let i=new TextDecoder(`utf-8`),a=``,o=!1;try{for(;;){let{done:e,value:n}=await r.read();if(e)break;a+=i.decode(n,{stream:!0});let s=a.split(`
2
+ `);a=s.pop()||``;for(let e of s)if(L(e,t)){o=!0,I(t,!0);return}}if(a.trim()&&L(a,t)){o=!0,I(t,!0);return}o||I(t,!1)}catch(e){if(e instanceof Error&&e.name===`AbortError`){I(t,!1);return}n?.(String(e)),I(t,!0)}},R={PRESET_MSG:`PRESET_MSG`,LINK:`LINK`,COLLECT_FORM:`COLLECT_FORM`},ye=new Set(Object.values(R)),be=e=>ye.has(e),xe=(e,t)=>{if(!e||typeof e!=`object`)return null;let n=e,r=typeof n.title==`string`?n.title.trim():``;if(!r)return null;let i=typeof n.effectType==`string`?n.effectType.trim():``;if(!be(i))return null;let a=i,o=typeof n.rounds==`number`&&Number.isFinite(n.rounds)?Math.max(0,Math.floor(n.rounds)):0,s=typeof n.sortOrder==`number`&&Number.isFinite(n.sortOrder)?n.sortOrder:t,c=n.effectConfig&&typeof n.effectConfig==`object`?n.effectConfig:{},l=typeof c.question==`string`?c.question.trim():``,u=a===R.PRESET_MSG?l||r:l||void 0;return{title:r,rounds:o,effectType:a,effectConfig:{url:typeof c.url==`string`?c.url:void 0,question:u,reply:typeof c.reply==`string`?c.reply:void 0},sortOrder:s}},Se=(e=[])=>e.map((e,t)=>xe(e,t)).filter(e=>e!==null).sort((e,t)=>e.sortOrder-t.sortOrder),z=e=>!e||typeof e!=`object`||Array.isArray(e)?null:e,B=e=>typeof e==`string`?e.trim():``,V=e=>{try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}},Ce=e=>{let t=z(e);if(!t)return null;let n=B(t.type);if(n===`text`){let e=B(t.text);return e?{type:`text`,text:e}:null}if(n===`image`){let e=B(t.imageUrl);return V(e)?{type:`image`,imageUrl:e,alt:B(t.alt)}:null}if(n===`link`){let e=B(t.label),n=B(t.action);if(!e)return null;if(n===`OPEN_CHAT`)return{type:`link`,label:e,action:`OPEN_CHAT`};if(n===`URL`){let n=B(t.url);return V(n)?{type:`link`,label:e,action:`URL`,url:n}:null}return null}if(n===`button`){let e=B(t.label),n=B(t.action);if(!e)return null;if(n===`OPEN_CHAT`)return{type:`button`,label:e,action:`OPEN_CHAT`};if(n===`URL`){let n=B(t.url);return V(n)?{type:`button`,label:e,action:`URL`,url:n}:null}return null}return null},we=(e,t)=>{let n=z(e);if(!n)return null;let r=B(n.title);if(!r)return null;let i=B(n.iconUrl),a=typeof n.sortOrder==`number`&&Number.isFinite(n.sortOrder)?n.sortOrder:t,o=Array.isArray(n.blocks)?n.blocks:[];return{sortOrder:a,title:r,description:B(n.description),iconUrl:V(i)?i:``,blocks:o.map(e=>Ce(e)).filter(e=>e!==null)}},Te=e=>{let t=z(e);if(!t)return{enabled:!1,groups:[]};let n=(Array.isArray(t.groups)?t.groups:[]).map((e,t)=>we(e,t)).filter(e=>e!==null).sort((e,t)=>e.sortOrder-t.sortOrder);return t.enabled===!1?{enabled:!1,groups:n}:{enabled:n.length>0,groups:n}},H={AI_CHAT:`AI_CHAT`,TRANSFERRING:`TRANSFERRING`,TRANSFERRED:`TRANSFERRED`,CLOSE:`CLOSE`},Ee=new Set(Object.values(H)),De=e=>{if(!e)return;let t=e.toUpperCase();if(Ee.has(t))return t},U=`/client/agentChat`,Oe=e=>({...e,sessionStatus:De(e.sessionStatus)}),ke=(e=[])=>e.slice().sort((e,t)=>(e.sortOrder??0)-(t.sortOrder??0)).filter(e=>!!e.question?.trim()),Ae=async(e,t=w.site)=>{let n=await ge(`${U}/config/byName/${encodeURIComponent(e)}?site=${encodeURIComponent(t)}`),r=se(),i=Te(n.guideBubble);return{agentId:n.id,agentName:n.agentName,integrationsId:r,title:n.name||``,avatar:n.avatar||``,launcherAvatar:n.launcherAvatar||``,openingStatement:n.greeting||``,transferWaitText:n.transferWaitText||``,suggestedQuestions:ke(n.recommendedQuestions),quickEntries:Se(n.quickEntries),productCardsEnabled:n.productCardsEnabled??!0,guideBubble:i,placeholder:``}},je=async({agentId:e,visitorId:t=k(),channel:n=`web`})=>{if(!e)throw Error(`Missing agentId, unable to create session`);let r=await M(`${U}/session`,{agentId:e,visitorId:t,channel:n});return{sessionId:r.sessionId,visitorId:r.visitorId||t,userId:r.userId||t}},Me=async e=>{try{await M(`${U}/open`,{...e,channel:`web`})}catch{}},W=async()=>{let{agentName:e}=w;return Ae(e)},Ne=async({visitorId:e=k(),agentId:t,pageNum:n=1,pageSize:r=50}={})=>{let i=await F(`${U}/session/list`,{visitorId:e,agentId:t,pageNum:n,pageSize:r});return{...i,rows:i.rows.map(Oe)}},Pe=async({visitorId:e=k(),agentId:t,sessionId:n,pageNum:r=1,pageSize:i=200})=>F(`${U}/message/list`,{visitorId:e,agentId:t,sessionId:n,pageNum:r,pageSize:i}),Fe=async({sessionId:e,visitorId:t=k()})=>{await M(`${U}/session/${e}/close?${new URLSearchParams({visitorId:t}).toString()}`,{})},Ie=async({sessionId:e,sessionStatus:t,visitorId:n=k()})=>{await N(`${U}/session/${e}/status`,{sessionStatus:t,visitorId:n})},Le=async({messageIds:e,visitorId:t=k()})=>{e.length!==0&&await M(`${U}/message/read`,{messageIds:e,visitorId:t})},Re=async({sessionId:e,visitorId:t=k()})=>{await he(`${U}/session/${e}`,{visitorId:t})},ze=async()=>{let e=k();return{...await W(),sessionId:null,visitorId:e,userId:e,sessionStatus:H.AI_CHAT,conversationId:null,zendeskUserId:null,transferManual:0}},G=null,K={initSession:async()=>(G||=ze().catch(e=>{throw G=null,e}),G),resetInitSession:()=>{G=null},loadAgentConfig:W,createSession:je,openSession:Me,fetchSessionList:Ne,fetchMessageList:Pe,deleteSession:Re,closeSession:Fe,updateSessionStatus:Ie,markMessagesRead:Le,sendMessage:async({query:t,agentId:n,sessionId:r,visitorId:i,clientMessageId:a,signal:o,...s})=>{await ve(await fetch(A(`${U}/chat`),{method:`POST`,credentials:`include`,signal:o,headers:{"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify({agentId:n,sessionId:r,visitorId:i,content:t,clientMessageId:a||e()})}),s)},sendPresetMessage:async({agentId:e,sessionId:t,visitorId:n,recommendedQuestion:r,quickEntry:i})=>{let a={agentId:e,sessionId:t,visitorId:n};return r?a.recommendedQuestion=r:i&&(a.quickEntry=i),M(`${U}/message/preset`,a)},reportTransfer:async({agentId:e,sessionId:t,visitorId:n,eventType:r,conversationId:i,zendeskUserId:a})=>{if(!(!e||!t||!r||!i)&&!(r===`TRIGGER`&&!a))try{await M(`${U}/transfer`,{agentId:e,sessionId:t,visitorId:n||k(),eventType:r,conversationId:i,...a?{zendeskUserId:a}:{}})}catch{}},submitFeedback:async({agentId:e,sessionId:t,messageId:n,questionMessageId:r,visitorId:i,feedbackType:a,question:o,answer:s,type:c,feedbackContent:l})=>(await M(`${U}/feedback`,{agentId:e,sessionId:t,messageId:n,questionMessageId:r,visitorId:i,feedbackType:a,question:o,answer:s,...c?{type:c}:{},feedbackContent:l})).id,updateFeedback:async({feedbackId:e,agentId:t,sessionId:n,messageId:r,questionMessageId:i,visitorId:a,feedbackType:o,question:s,answer:c,type:l,feedbackContent:u})=>{await N(`${U}/feedback/${e}`,{agentId:t,sessionId:n,messageId:r,questionMessageId:i,visitorId:a,feedbackType:o,question:s,answer:c,...l?{type:l}:{},feedbackContent:u})},bindUser:async({loginUserId:e,userNickname:t,visitorId:n=k()})=>{if(!e.trim())throw Error(`loginUserId is required`);if(e===n)throw Error(`loginUserId must differ from visitorId`);return M(`${U}/bindUser`,{visitorId:n,loginUserId:e,...t?{userNickname:t}:{}})}},Be=e=>{S({...e.loginUserId?{loginUserId:e.loginUserId}:{},...e.userNickname?{userNickname:e.userNickname}:{},...e.product?{productContext:e.product}:{},...e.loginUserId&&e.userName&&e.userEmail?{hostUser:{loginUserId:e.loginUserId,name:e.userName,email:e.userEmail,...e.userNickname?{userNickname:e.userNickname}:{}}}:{}})},Ve=async e=>{let t=await K.bindUser(e);return m({type:`user-bound`}),t},He=async e=>{S({hostUser:{loginUserId:e.loginUserId,name:e.name,email:e.email,...e.userNickname?{userNickname:e.userNickname}:{}},loginUserId:e.loginUserId,...e.userNickname?{userNickname:e.userNickname}:{}});try{await K.bindUser({loginUserId:e.loginUserId,userNickname:e.userNickname})}catch{}return m({type:`user-bound`}),{ok:!0}},Ue=e=>(Be(e),{ok:!0}),q=async(e,t)=>{switch(e){case`bindUser`:return Ve(t);case`setUser`:return He(t);case`setContext`:return Ue(t);default:throw Error(`Unknown SDK method: ${e}`)}},We=e=>{let t=!1,n=new Map,r=(e,t)=>{n.get(e)?.forEach(e=>{e(t)})};return{sdk:{get ready(){return t},bindUser:e=>q(`bindUser`,e),setContext:e=>q(`setContext`,e),setUser:e=>q(`setUser`,e),open:async()=>(e.open(),{ok:!0}),close:async()=>(e.close(),{ok:!0}),on(e,t){let r=String(e);return n.has(r)||n.set(r,new Set),n.get(r)?.add(t),()=>{n.get(r)?.delete(t)}}},markReady:()=>{t||(t=!0,r(`ready`,void 0))},emitHostEvent:(e,t)=>{r(String(e),t)}}},Ge=`mira-chat-widget-mounted`,J=`mira-chat-ready`,Ke=()=>window.__MIRA_CHAT_WIDGET__??null,Y=null,X=!1,Z=!1,Q=()=>{if(Z)return;Z=!0;let e=window.MiraChatHostConfig?.onReady;if(e){if(window.MiraChat){e(window.MiraChat);return}e()}},qe=e=>{Y=e},Je=()=>{!X||!Y||Xe()},Ye=(e,t)=>{Y?.(e,t)},Xe=()=>{if(!Y){X=!0,Q();return}X=!1,Ye(`ready`,void 0),window.dispatchEvent(new CustomEvent(J)),Q()},Ze=e=>{window.MiraChatHostConfig?.debug&&console.info(`[mira-chat-host] ${e}`)},$=()=>{if(b(),window.MiraChat)return;let e=Ke();if(!e)return;let t=p(),{sdk:n,markReady:r,emitHostEvent:i}=We({open:()=>{e.setPanelOpenSilently(!0),t.publish({type:`window-open`})},close:()=>{e.setPanelOpenSilently(!1),t.publish({type:`window-close`})}}),a=n.setContext.bind(n);n.setContext=async e=>{let n=await a(e);return t.publish({type:`context-updated`,payload:e}),n};let o=n.bindUser.bind(n);n.bindUser=async e=>{let n=await o(e);return t.publish({type:`user-bound`}),n};let s=n.setUser.bind(n);n.setUser=async e=>{let n=await s(e);return t.publish({type:`user-bound`}),n},window.MiraChat=n,qe((e,t)=>{if(e===`ready`&&r(),e===`init-error`){let e=t&&typeof t==`object`&&`message`in t?String(t.message):`Chat widget init failed`;window.MiraChatHostConfig?.onInitError?.(Error(e))}i(e,t)}),n.on(`ready`,()=>{window.__MIRA_CHAT_HOST_REGISTRY__?.notifySdkReady(),Q(),window.dispatchEvent(new CustomEvent(J)),Ze(`MiraChat SDK ready`)}),t.subscribe(n=>{if(l(n,t.tabId)){if(n.type===`window-open`){e.setPanelOpenSilently(!0);return}if(n.type===`window-close`){e.setPanelOpenSilently(!1);return}n.type===`context-updated`&&a(n.payload)}}),Je()};$(),window.addEventListener(Ge,()=>{$()})})();