@lark-apaas/aily-web-sdk 0.0.12-alpha.2 → 0.0.12-alpha.3

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/dist/index.cjs CHANGED
@@ -619,39 +619,43 @@ var _AgentIframeManager = class _AgentIframeManager {
619
619
  customParamsToken = config.customParamsToken.trim();
620
620
  if (!customParamsToken) {
621
621
  this.warn("customParamsToken cannot be empty. SDK initialization will continue without custom context.");
622
- return null;
623
622
  }
624
623
  }
625
624
  if (config.customParams === void 0) {
626
625
  if (customParamsToken !== void 0) {
627
626
  this.warn("customParamsToken requires customParams for jwt verification. SDK initialization will continue without custom context.");
628
- return null;
627
+ return {
628
+ customParamsToken
629
+ };
629
630
  }
630
631
  return null;
631
632
  }
632
633
  if (!this.isRecord(config.customParams)) {
633
634
  this.warn("customParams must be an object. SDK initialization will continue without custom context.");
634
- return null;
635
+ return {
636
+ customParams: config.customParams,
637
+ ...customParamsToken !== void 0 ? {
638
+ customParamsToken
639
+ } : {}
640
+ };
635
641
  }
636
642
  for (const [key, entry] of Object.entries(config.customParams)) {
637
643
  if (!this.isRecord(entry) || !("value" in entry) || entry.value === void 0) {
638
644
  this.warn(`customParams.${key} must include value. SDK initialization will continue without custom context.`);
639
- return null;
645
+ continue;
640
646
  }
641
647
  if ("desc" in entry && entry.desc !== void 0 && typeof entry.desc !== "string") {
642
648
  this.warn(`customParams.${key}.desc must be a string. SDK initialization will continue without custom context.`);
643
- return null;
644
649
  }
645
- if (!this.isValidCustomParamValue(entry.value)) {
650
+ if ("value" in entry && !this.isValidCustomParamValue(entry.value)) {
646
651
  this.warn(`customParams.${key}.value has invalid type. SDK initialization will continue without custom context.`);
647
- return null;
648
652
  }
649
653
  }
650
- return customParamsToken !== void 0 ? {
654
+ return {
651
655
  customParams: config.customParams,
652
- customParamsToken
653
- } : {
654
- customParams: config.customParams
656
+ ...customParamsToken !== void 0 ? {
657
+ customParamsToken
658
+ } : {}
655
659
  };
656
660
  }
657
661
  isValidCustomParamValue(value) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/iframe-manager.ts","../src/device-detector.ts","../src/message-bridge.ts","../src/agent-iframe-manager.ts"],"sourcesContent":["/*\n * index.ts\n * Author: perterpon.wang<perterpon.wang@bytedance.com>\n * Create: Tue Feb 10 2026\n */\n\nimport { IframeManager } from \"./iframe-manager\";\nimport { AgentIframeManager } from \"./agent-iframe-manager\";\n\nimport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n\tChatPanel,\n\tWebSDKConfig,\n} from \"./types/config\";\n\n/**\n * Initialize Aily Chat via iframe\n * This is the primary method for initializing the chat panel\n * @param root - Container element for the iframe\n * @param config - Configuration options\n * @returns ChatPanel instance for controlling the chat\n */\nexport async function initAilyChat(\n\troot: HTMLElement,\n\tconfig: WebSDKConfig,\n): Promise<ChatPanel> {\n\tconst manager = new IframeManager(root, config);\n\treturn manager.init();\n}\n\n/**\n * Initialize Agent Chat via iframe\n * @param root - Container element for the iframe\n * @param config - Agent SDK configuration\n * @returns Agent SDK instance for controlling the agent page\n */\nexport async function initAgentChat(\n\troot: HTMLElement,\n\tconfig: AgentSDKInitConfig,\n): Promise<AgentSDKInstance> {\n\tconst manager = new AgentIframeManager(root, config);\n\treturn manager.init();\n}\n\n// Export constants\nexport {\n\tAGENT_IFRAME_BASE_URL,\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetAgentIframeBaseURL,\n\tgetIframeBaseURL,\n\tIFRAME_BASE_URL,\n\tMESSAGE_TIMEOUT,\n} from \"./constants\";\n// Export types\nexport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n\tChatPanel,\n CustomParamEntry,\n CustomParams,\n\tWebSDKCommonConfig,\n\tWebSDKConfig,\n\tWebSDKConversionConfig,\n\tWebSDKEditorConfig,\n\tWebSDKEvents,\n\tWebSDKSkillInfo,\n} from \"./types/config\";\n\n// Export message types\nexport type {\n\tIframeEventMessage,\n\tIframeMessage,\n\tIframeMessageType,\n\tIframeRequestMessage,\n\tIframeResponseMessage,\n} from \"./types/message\";\n","/**\n * Constants for Aily Web SDK\n */\n\n/** Message business ID for postMessage identification */\nexport const MESSAGE_BIZ_ID = 'cui-sdk-message' as const;\nexport const PARENT_ORIGIN_QUERY_KEY = '__parentOrigin' as const;\n\n/** Iframe origins by environment */\nexport const IFRAME_ORIGIN: Record<string, string> = {\n production: 'https://aily.feishu.cn',\n staging: 'https://aily.feishu-pre.cn',\n boe: 'https://aily.feishu-boe.cn',\n development: 'http://localhost:3000',\n};\n\n/** Page paths for iframe apps */\nexport const CHAT_IFRAME_PATH = '/cui' as const;\nexport const AGENT_IFRAME_PATH = '/custom_agent/cui' as const;\n\n/** Chat iframe base URLs by environment */\nexport const IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${CHAT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${CHAT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${CHAT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${CHAT_IFRAME_PATH}`,\n};\n\n/** Agent iframe base URLs by environment */\nexport const AGENT_IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${AGENT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${AGENT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${AGENT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${AGENT_IFRAME_PATH}`,\n};\n\ntype IframeEnv = keyof typeof IFRAME_BASE_URL;\n\ninterface AilyWebSdkDebugConfig {\n iframeEnv?: string;\n}\n\ndeclare global {\n interface Window {\n __DEBUG__?: {\n ailyWebSdk?: AilyWebSdkDebugConfig;\n [key: string]: unknown;\n };\n }\n}\n\nfunction isIframeEnv(env?: string): env is IframeEnv {\n return Boolean(env && env in IFRAME_BASE_URL);\n}\n\nfunction resolveDebugIframeEnv(): IframeEnv | undefined {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n const debugIframeEnv = window.__DEBUG__?.ailyWebSdk?.iframeEnv;\n return isIframeEnv(debugIframeEnv) ? debugIframeEnv : undefined;\n}\n\n/**\n * Get iframe base URL based on environment\n */\nfunction resolveIframeEnv(env?: string): IframeEnv {\n if (isIframeEnv(env)) {\n return env;\n }\n\n const debugIframeEnv = resolveDebugIframeEnv();\n if (debugIframeEnv) {\n return debugIframeEnv;\n }\n\n // Auto-detect based on hostname\n // MiaoDa 宿主域名: miaoda.feishu[-env].cn, *.aiforce[-env][-preview].bytedance.net, *.force-pre.feishuapp.net, *.fsapp.kundou.cn, *.aiforce.run, *.aiforce.cloud\n const hostname =\n typeof window !== 'undefined' ? window.location.hostname : '';\n\n if (hostname.includes('aiforce-boe')) {\n return 'boe';\n }\n if (\n hostname.includes('aiforce-pre') ||\n hostname.includes('force-pre.feishuapp.net') ||\n hostname.includes('fsapp.kundou.cn')\n ) {\n return 'staging';\n }\n\n return 'production';\n}\n\nexport function getIframeBaseURL(env?: string): string {\n return IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/**\n * Get agent iframe base URL based on environment\n */\nexport function getAgentIframeBaseURL(env?: string): string {\n return AGENT_IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/** Timeout for postMessage requests (30 seconds) */\nexport const MESSAGE_TIMEOUT = 30 * 1000;\n\n/** Miaoda 渠道标识默认值(用户可通过 config.common.channelType 覆盖) */\nexport const DEFAULT_CHANNEL_TYPE = 'MIAODA_CUI_SDK';\nexport const DEFAULT_ANONYMOUS_CHANNEL_TYPE = 'MIAODA_ANONYMOUS_CUI_SDK';\n\n/** Allowed origins for postMessage (cui-iframe 的 origin) */\nexport const ALLOWED_ORIGINS = [\n IFRAME_ORIGIN.production,\n IFRAME_ORIGIN.staging,\n IFRAME_ORIGIN.boe,\n 'http://localhost:3000',\n 'http://localhost:5173',\n IFRAME_ORIGIN.development,\n];\n","import {\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetIframeBaseURL,\n\tMESSAGE_BIZ_ID,\n} from \"./constants\";\nimport { slardar } from \"@lark-apaas/internal-slardar\";\nimport { DeviceDetector } from \"./device-detector\";\nimport { MessageBridge } from \"./message-bridge\";\n\nimport type { ChatPanel, WebSDKConfig } from \"./types/config\";\n\n/**\n * IframeManager handles iframe creation and lifecycle\n *\n * iframe 采用自初始化模式:配置通过 URL hash 传入,iframe 加载后自行解析并渲染,\n * 与旧版 copilot iframe 的行为保持一致。宿主通过 postMessage 进行后续操作。\n */\nexport class IframeManager {\n\tprivate iframe: HTMLIFrameElement | null = null;\n\tprivate messageBridge: MessageBridge;\n\tprivate config: WebSDKConfig;\n\tprivate channelType: string;\n\tprivate root: HTMLElement;\n\tprivate deviceDetector: DeviceDetector | null = null;\n\n\tconstructor(root: HTMLElement, config: WebSDKConfig) {\n\t\tthis.root = root;\n\t\tthis.config = config;\n\t\tconst defaultChannel = config.anonymous\n\t\t\t? DEFAULT_ANONYMOUS_CHANNEL_TYPE\n\t\t\t: DEFAULT_CHANNEL_TYPE;\n\t\tthis.channelType = config.common?.channelType || defaultChannel;\n\t\tthis.messageBridge = new MessageBridge(getIframeBaseURL());\n\t}\n\n\t/**\n\t * Initialize the iframe and establish communication\n\t * 配置通过 URL hash 编码传入 iframe,iframe 加载后自行初始化\n\t */\n\tasync init(): Promise<ChatPanel> {\n\t\tconst initStart = performance.now();\n\n\t\t// Auto-detect device if not explicitly provided\n\t\tif (!this.config.device) {\n\t\t\tthis.deviceDetector = new DeviceDetector();\n\t\t\tthis.config.device = this.deviceDetector.getDevice();\n\t\t}\n\n\t\t// Create iframe element\n\t\tthis.iframe = document.createElement(\"iframe\");\n\t\tthis.iframe.src = this.buildIframeURL();\n\t\tthis.iframe.style.width = \"100%\";\n\t\tthis.iframe.style.height = \"100%\";\n\t\tthis.iframe.style.border = \"none\";\n\t\tthis.iframe.allow = \"microphone; clipboard-write\";\n\n\t\t// Attach to DOM\n\t\tthis.root.appendChild(this.iframe);\n\n\t\t// Attach message bridge (开始监听消息)\n\t\tthis.messageBridge.attach(this.iframe);\n\n\t\t// Setup event handlers (在 iframe 初始化完成之前就开始监听,确保不丢失事件)\n\t\tthis.setupEventHandlers();\n\n\t\t// Listen for device changes and push updates to iframe\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.observe((newDevice) => {\n\t\t\t\tthis.messageBridge.send(\"updateConfig\", { device: newDevice });\n\t\t\t});\n\t\t}\n\n\t\t// Wait for iframe to finish initialization (iframe 自行读取 URL 配置并渲染,完成后发送 ready 事件)\n\t\tawait this.waitForReady();\n\n\t\t// 上报 cui_init_total 耗时(iframe 创建 → init 完成)\n\t\tthis.reportInitMetrics(initStart);\n\n\t\t// Return ChatPanel interface\n\t\treturn this.createChatPanel();\n\t}\n\n\t/**\n\t * Destroy the iframe and cleanup\n\t */\n\tasync destroy(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.messageBridge.send(\"destroy\");\n\t\t} catch {\n\t\t\t// Ignore errors during destroy\n\t\t}\n\n\t\tthis.messageBridge.detach();\n\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.destroy();\n\t\t\tthis.deviceDetector = null;\n\t\t}\n\n\t\tif (this.iframe?.parentNode) {\n\t\t\tthis.iframe.parentNode.removeChild(this.iframe);\n\t\t}\n\n\t\tthis.iframe = null;\n\t}\n\n\t/**\n\t * 构建 iframe URL,将配置编码到 hash 中\n\t * 格式: {baseURL}#{params} 其中 config 为 base64(JSON.stringify(configWithoutEvents))\n\t *\n\t * 鉴权说明:SDK 不参与 token 获取/传递。iframe 自行处理飞书登录流程,\n\t * 允许用户在 iframe 中独立登录。匿名渠道跳过登录检查。\n\t */\n\tprivate buildIframeURL(): string {\n\t\tconst baseURL = getIframeBaseURL();\n\n\t\t// 移除 events(函数无法序列化)\n\t\tconst {\n\t\t\tevents: _events,\n\t\t\tanonymous: _anonymous,\n\t\t\t...configWithoutEvents\n\t\t} = this.config;\n\t\t// 注入 channelType/resourceType(SDK 内部控制,不暴露给消费者)\n\t\t// 补全 editor.skill 硬编码字段\n\t\tconst editorConfig = configWithoutEvents.editor?.skill\n\t\t\t? {\n\t\t\t\t\t...configWithoutEvents.editor,\n\t\t\t\t\tskill: {\n\t\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\t\tbuiltinType: \"unspecified\",\n\t\t\t\t\t\t...configWithoutEvents.editor.skill,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: configWithoutEvents.editor;\n\n\t\tconst iframeConfig = {\n\t\t\t...configWithoutEvents,\n\t\t\tcommon: {\n\t\t\t\t...configWithoutEvents.common,\n\t\t\t\tchannelType: this.channelType,\n\t\t\t\tresourceType:\n\t\t\t\t\tconfigWithoutEvents.common?.resourceType || this.channelType,\n\t\t\t},\n\t\t\teditor: editorConfig,\n\t\t};\n\t\tconst configBase64 = btoa(encodeURIComponent(JSON.stringify(iframeConfig)));\n\n\t\tconst params = new URLSearchParams({\n\t\t\tappKey: this.config.appKey,\n\t\t\tconfig: encodeURIComponent(configBase64),\n\t\t});\n\n\t\treturn `${baseURL}#${params.toString()}`;\n\t}\n\n\t/**\n\t * 等待 iframe 自行初始化完成后发送 ready 事件\n\t */\n\tprivate waitForReady(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tconst error = new Error(\"Iframe ready timeout\");\n\t\t\t\tslardar.captureException(error, { source: 'aily-web-sdk', module: 'iframe-ready' });\n\t\t\t\treject(error);\n\t\t\t}, 30000);\n\n\t\t\tconst checkMessage = (event: MessageEvent) => {\n\t\t\t\tif (\n\t\t\t\t\tevent.data?.messageBizId === MESSAGE_BIZ_ID &&\n\t\t\t\t\tevent.data?.type === \"event\" &&\n\t\t\t\t\tevent.data?.eventName === \"ready\"\n\t\t\t\t) {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\twindow.removeEventListener(\"message\", checkMessage);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\twindow.addEventListener(\"message\", checkMessage);\n\t\t});\n\t}\n\n\tprivate setupEventHandlers(): void {\n\t\tconst { events } = this.config;\n\t\tif (!events) return;\n\n\t\tif (events.onReady) {\n\t\t\tthis.messageBridge.onEvent(\"ready\", events.onReady);\n\t\t}\n\n\t\tif (events.onError) {\n\t\t\tthis.messageBridge.onEvent(\"error\", (data: unknown) => {\n\t\t\t\tconst msg = (data as { message?: string })?.message || \"Unknown error\";\n\t\t\t\tevents.onError?.(new Error(msg));\n\t\t\t});\n\t\t}\n\n\t\tif (events.onMessage) {\n\t\t\tthis.messageBridge.onEvent(\"onMessage\", events.onMessage);\n\t\t}\n\n\t\tif (events.onInited) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"inited\",\n\t\t\t\tevents.onInited as (data: unknown) => void,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onInitedWithWelcome) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"initedWithWelcome\",\n\t\t\t\tevents.onInitedWithWelcome,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onClose) {\n\t\t\tthis.messageBridge.onEvent(\"onClose\", events.onClose);\n\t\t}\n\t}\n\n\tprivate reportInitMetrics(initStart: number): void {\n\t\ttry {\n\t\t\tconst cost = performance.now() - initStart;\n\t\t\tslardar.sendEvent({\n\t\t\t\tname: \"cui_init_total\",\n\t\t\t\tmetrics: { cost },\n\t\t\t\tcategories: {\n\t\t\t\t\tarch: \"iframe-static\",\n\t\t\t\t\tappKey: this.config.appKey,\n\t\t\t\t\tchannelType: this.channelType,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch {\n\t\t\t// 性能上报失败不影响功能\n\t\t}\n\t}\n\n\tprivate createChatPanel(): ChatPanel {\n\t\treturn {\n\t\t\tsendMessage: async (data) => {\n\t\t\t\tawait this.messageBridge.send(\"sendMessage\", data);\n\t\t\t},\n\t\t\tclear: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clear\");\n\t\t\t},\n\t\t\tcancelMessage: async (messageItem) => {\n\t\t\t\tawait this.messageBridge.send(\"cancelMessage\", messageItem);\n\t\t\t},\n\t\t\tclearAndStop: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clearAndStop\");\n\t\t\t},\n\t\t\tupdateWelcomeMessage: async () => {\n\t\t\t\tawait this.messageBridge.send(\"updateWelcomeMessage\");\n\t\t\t},\n\t\t\tupdateConfig: async (config) => {\n\t\t\t\tawait this.messageBridge.send(\"updateConfig\", config);\n\t\t\t},\n\t\t\tobserveSkill: async (skillId, name, skillType) => {\n\t\t\t\tawait this.messageBridge.send(\"observeSkill\", {\n\t\t\t\t\tskillId,\n\t\t\t\t\tname,\n\t\t\t\t\tskillType,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetCurrentSkill: async (skill) => {\n\t\t\t\tawait this.messageBridge.send(\"setCurrentSkill\", skill);\n\t\t\t},\n\t\t\tdestroy: async () => {\n\t\t\t\tawait this.destroy();\n\t\t\t},\n\t\t};\n\t}\n}\n","const MOBILE_BREAKPOINT = 768;\n\ntype DeviceType = 'pc' | 'mobile';\ntype DeviceChangeCallback = (device: DeviceType) => void;\n\n/**\n * 设备类型自动检测器\n *\n * 使用 matchMedia + 768px 断点检测设备类型,与 miaoda useIsMobile 逻辑一致。\n * 检测在宿主页面(而非 iframe)中执行,结果通过 postMessage 推送给 iframe。\n */\nexport class DeviceDetector {\n private mediaQuery: MediaQueryList;\n private currentDevice: DeviceType;\n private callback: DeviceChangeCallback | null = null;\n private handleChange: (() => void) | null = null;\n\n constructor() {\n this.mediaQuery = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n this.currentDevice = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n }\n\n getDevice(): DeviceType {\n return this.currentDevice;\n }\n\n observe(callback: DeviceChangeCallback): void {\n this.callback = callback;\n this.handleChange = () => {\n const newDevice: DeviceType = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n if (newDevice !== this.currentDevice) {\n this.currentDevice = newDevice;\n this.callback?.(newDevice);\n }\n };\n this.mediaQuery.addEventListener('change', this.handleChange);\n }\n\n destroy(): void {\n if (this.handleChange) {\n this.mediaQuery.removeEventListener('change', this.handleChange);\n this.handleChange = null;\n }\n this.callback = null;\n }\n}\n","import { MESSAGE_TIMEOUT, ALLOWED_ORIGINS } from './constants';\nimport {\n MESSAGE_BIZ_ID,\n type IframeMessage,\n type IframeRequestMessage,\n type IframeResponseMessage,\n type IframeEventMessage,\n type IframeMessageType,\n} from './types/message';\nimport { slardar } from '@lark-apaas/internal-slardar';\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * MessageBridge handles postMessage communication between parent and iframe\n */\nexport class MessageBridge {\n private iframe: HTMLIFrameElement | null = null;\n private requestId = 0;\n private pendingRequests = new Map<number, PendingRequest>();\n private eventHandlers = new Map<string, ((data: unknown) => void)[]>();\n private targetOrigin: string;\n\n constructor(targetOrigin: string) {\n this.targetOrigin = new URL(targetOrigin).origin;\n this.handleMessage = this.handleMessage.bind(this);\n }\n\n /**\n * Attach to an iframe and start listening for messages\n */\n attach(iframe: HTMLIFrameElement): void {\n this.iframe = iframe;\n window.addEventListener('message', this.handleMessage);\n }\n\n /**\n * Detach from iframe and clean up\n */\n detach(): void {\n window.removeEventListener('message', this.handleMessage);\n this.iframe = null;\n // Clear all pending requests\n this.pendingRequests.forEach(({ reject }) => {\n reject(new Error('MessageBridge detached'));\n });\n this.pendingRequests.clear();\n }\n\n /**\n * Send a message to the iframe and wait for response\n */\n send<T = unknown>(type: IframeMessageType, data?: unknown): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!this.iframe?.contentWindow) {\n reject(new Error('Iframe not attached'));\n return;\n }\n\n this.requestId += 1;\n const id = this.requestId;\n const message: IframeRequestMessage = {\n messageBizId: MESSAGE_BIZ_ID,\n id,\n type,\n data,\n timestamp: Date.now(),\n isRequest: true,\n };\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n const error = new Error(`Message timeout: ${type}`);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', messageType: type });\n reject(error);\n }, MESSAGE_TIMEOUT);\n\n this.pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timer });\n\n this.iframe.contentWindow.postMessage(message, this.targetOrigin);\n });\n }\n\n /**\n * Register an event handler\n */\n onEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n handlers.push(handler);\n this.eventHandlers.set(eventName, handlers);\n }\n\n /**\n * Remove an event handler\n */\n offEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n this.eventHandlers.set(eventName, handlers);\n }\n }\n\n private handleMessage(event: MessageEvent<IframeMessage>): void {\n // Validate origin\n if (!ALLOWED_ORIGINS.includes(event.origin)) {\n return;\n }\n\n const { data } = event;\n\n // Validate message format\n if (data?.messageBizId !== MESSAGE_BIZ_ID) {\n return;\n }\n\n // Handle response messages\n if (this.isResponseMessage(data)) {\n const pending = this.pendingRequests.get(data.id);\n if (pending) {\n clearTimeout(pending.timer);\n this.pendingRequests.delete(data.id);\n\n if (data.error) {\n const error = new Error(data.error.message);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', errorCode: data.error.code });\n pending.reject(error);\n } else {\n pending.resolve(data.data);\n }\n }\n }\n\n // Handle event messages\n if (this.isEventMessage(data)) {\n const handlers = this.eventHandlers.get(data.eventName) || [];\n handlers.forEach((handler) => {\n try {\n handler(data.data);\n } catch {\n // Ignore handler errors\n }\n });\n }\n }\n\n private isResponseMessage(data: IframeMessage): data is IframeResponseMessage {\n return 'isResponse' in data && data.isResponse === true;\n }\n\n private isEventMessage(data: IframeMessage): data is IframeEventMessage {\n return data.type === 'event';\n }\n}\n","import { PARENT_ORIGIN_QUERY_KEY, getAgentIframeBaseURL } from './constants';\nimport { MessageBridge } from './message-bridge';\n\nimport type {\n AgentSDKInitConfig,\n AgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n} from './types/config';\nimport type {\n AgentReadyEventData,\n ParentContextMessageData,\n ParentContextResponseData,\n} from './types/message';\n\n/**\n * AgentIframeManager handles agent iframe creation and lifecycle.\n */\nexport class AgentIframeManager {\n private static readonly WARN_PREFIX = '[aily-web-sdk]';\n private iframe: HTMLIFrameElement | null = null;\n private readonly messageBridge: MessageBridge;\n private readonly config: AgentSDKInitConfig;\n private readonly root: HTMLElement;\n private readonly runtimeCustomContext: AgentSDKRuntimeCustomContext | null;\n private readonly contextVersion: string;\n private initialHandshakeCompleted = false;\n\n constructor(root: HTMLElement, config: AgentSDKInitConfig) {\n this.root = root;\n this.config = config;\n this.runtimeCustomContext = this.resolveRuntimeCustomContext(config);\n this.contextVersion = this.createContextVersion();\n this.messageBridge = new MessageBridge(getAgentIframeBaseURL());\n }\n\n async init(): Promise<AgentSDKInstance> {\n this.iframe = document.createElement('iframe');\n this.iframe.src = this.buildIframeURL();\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.style.border = 'none';\n this.iframe.allow = 'microphone; clipboard-write';\n\n const readyPromise = this.waitForReady();\n this.messageBridge.onEvent('ready', this.handleSubsequentReady);\n this.messageBridge.attach(this.iframe);\n this.root.appendChild(this.iframe);\n\n try {\n const readyData = await readyPromise;\n await this.sendParentContext(readyData);\n } catch (error) {\n this.warn(\n 'Agent SDK initialization encountered a non-blocking error. Initialization will continue without blocking the iframe lifecycle.',\n error\n );\n } finally {\n this.initialHandshakeCompleted = true;\n }\n\n return this.createAgentInstance();\n }\n\n async destroy(): Promise<void> {\n this.messageBridge.offEvent('ready', this.handleSubsequentReady);\n\n try {\n await this.messageBridge.send('destroy');\n } catch {\n // Ignore errors during destroy.\n }\n\n this.messageBridge.detach();\n this.removeIframe();\n this.initialHandshakeCompleted = false;\n }\n\n private buildIframeURL(): string {\n const baseURL = getAgentIframeBaseURL();\n const params = new URLSearchParams({\n channelToken: this.config.channelToken,\n [PARENT_ORIGIN_QUERY_KEY]: window.location.origin,\n });\n\n return `${baseURL}?${params.toString()}`;\n }\n\n private buildParentContext(): ParentContextMessageData {\n const parentContext: ParentContextMessageData = {\n parentOrigin: window.location.origin,\n };\n\n return parentContext;\n }\n\n private waitForReady(): Promise<AgentReadyEventData | undefined> {\n return new Promise((resolve, reject) => {\n const handleReady = (data: unknown) => {\n clearTimeout(timeout);\n this.messageBridge.offEvent('ready', handleReady);\n resolve(this.parseReadyEventData(data));\n };\n\n const timeout = setTimeout(() => {\n this.messageBridge.offEvent('ready', handleReady);\n reject(new Error('Iframe ready timeout'));\n }, 30000);\n\n this.messageBridge.onEvent('ready', handleReady);\n });\n }\n\n private readonly handleSubsequentReady = (data: unknown): void => {\n if (!this.initialHandshakeCompleted) {\n return;\n }\n\n void this.sendParentContext(this.parseReadyEventData(data)).catch(error => {\n this.warn(\n 'Failed to re-send initParentContext after iframe ready event.',\n error\n );\n });\n };\n\n private async sendParentContext(\n readyData?: AgentReadyEventData\n ): Promise<void> {\n const payload = this.buildParentContextForReady(readyData);\n let response: ParentContextResponseData | undefined;\n\n try {\n response = await this.messageBridge.send<ParentContextResponseData>(\n 'initParentContext',\n payload\n );\n } catch (error) {\n this.warn(\n 'Failed to send initParentContext during initialization.',\n error\n );\n return;\n }\n\n if (!this.runtimeCustomContext) {\n return;\n }\n\n if (response?.accepted !== true) {\n this.warn(\n 'Iframe rejected initParentContext custom context. Custom context will be ignored for this initialization.'\n );\n return;\n }\n\n if (\n payload.iframeSessionId &&\n response.iframeSessionId &&\n response.iframeSessionId !== payload.iframeSessionId\n ) {\n this.warn(\n 'Iframe returned mismatched iframeSessionId. Custom context acknowledgement will be ignored.'\n );\n return;\n }\n\n if (\n payload.contextVersion &&\n response.contextVersion &&\n response.contextVersion !== payload.contextVersion\n ) {\n this.warn(\n 'Iframe returned mismatched contextVersion. Custom context acknowledgement will be ignored.'\n );\n }\n }\n\n private buildParentContextForReady(\n readyData?: AgentReadyEventData\n ): ParentContextMessageData {\n const parentContext = this.buildParentContext();\n\n if (!this.runtimeCustomContext) {\n return parentContext;\n }\n\n if (!this.readySupportsRuntimeContext(readyData)) {\n this.warn(\n 'Current iframe version does not support custom context initParentContext protocol. SDK initialization will continue without custom context.'\n );\n return parentContext;\n }\n\n return {\n ...parentContext,\n protocolVersion: 2,\n iframeSessionId: readyData.iframeSessionId,\n contextVersion: this.contextVersion,\n runtimeCustomContext: this.runtimeCustomContext,\n };\n }\n\n private readySupportsRuntimeContext(\n readyData?: AgentReadyEventData\n ): readyData is AgentReadyEventData & {\n protocolVersion: 2;\n iframeSessionId: string;\n needsContext: true;\n } {\n return (\n readyData?.protocolVersion === 2 &&\n Boolean(readyData.iframeSessionId) &&\n readyData.needsContext === true\n );\n }\n\n private parseReadyEventData(data: unknown): AgentReadyEventData | undefined {\n if (!this.isRecord(data)) {\n return undefined;\n }\n\n return data as AgentReadyEventData;\n }\n\n private resolveRuntimeCustomContext(\n config: AgentSDKInitConfig\n ): AgentSDKRuntimeCustomContext | null {\n let customParamsToken: string | undefined;\n if (config.customParamsToken !== undefined) {\n customParamsToken = config.customParamsToken.trim();\n if (!customParamsToken) {\n this.warn(\n 'customParamsToken cannot be empty. SDK initialization will continue without custom context.'\n );\n return null;\n }\n }\n\n if (config.customParams === undefined) {\n if (customParamsToken !== undefined) {\n this.warn(\n 'customParamsToken requires customParams for jwt verification. SDK initialization will continue without custom context.'\n );\n return null;\n }\n\n return null;\n }\n\n if (!this.isRecord(config.customParams)) {\n this.warn(\n 'customParams must be an object. SDK initialization will continue without custom context.'\n );\n return null;\n }\n\n for (const [key, entry] of Object.entries(config.customParams)) {\n if (\n !this.isRecord(entry) ||\n !('value' in entry) ||\n entry.value === undefined\n ) {\n this.warn(\n `customParams.${key} must include value. SDK initialization will continue without custom context.`\n );\n return null;\n }\n\n if (\n 'desc' in entry &&\n entry.desc !== undefined &&\n typeof entry.desc !== 'string'\n ) {\n this.warn(\n `customParams.${key}.desc must be a string. SDK initialization will continue without custom context.`\n );\n return null;\n }\n\n if (!this.isValidCustomParamValue(entry.value)) {\n this.warn(\n `customParams.${key}.value has invalid type. SDK initialization will continue without custom context.`\n );\n return null;\n }\n }\n\n return customParamsToken !== undefined\n ? {\n customParams: config.customParams,\n customParamsToken,\n }\n : {\n customParams: config.customParams,\n };\n }\n\n private isValidCustomParamValue(value: unknown): boolean {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(\n item =>\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean' ||\n this.isRecord(item)\n );\n }\n\n return this.isRecord(value);\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n\n private createContextVersion(): string {\n return `ctx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n private warn(message: string, error?: unknown): void {\n if (error === undefined) {\n console.warn(AgentIframeManager.WARN_PREFIX, message);\n return;\n }\n\n console.warn(AgentIframeManager.WARN_PREFIX, message, error);\n }\n\n private removeIframe(): void {\n if (this.iframe?.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n this.iframe = null;\n }\n\n private createAgentInstance(): AgentSDKInstance {\n return {\n destroy: async () => {\n await this.destroy();\n },\n };\n }\n}\n"],"mappings":"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","names":["MESSAGE_BIZ_ID","PARENT_ORIGIN_QUERY_KEY","IFRAME_ORIGIN","production","staging","boe","development","CHAT_IFRAME_PATH","AGENT_IFRAME_PATH","IFRAME_BASE_URL","AGENT_IFRAME_BASE_URL","isIframeEnv","env","Boolean","resolveDebugIframeEnv","window","undefined","debugIframeEnv","__DEBUG__","ailyWebSdk","iframeEnv","resolveIframeEnv","hostname","location","includes","getIframeBaseURL","getAgentIframeBaseURL","MESSAGE_TIMEOUT","DEFAULT_CHANNEL_TYPE","DEFAULT_ANONYMOUS_CHANNEL_TYPE","ALLOWED_ORIGINS","import_internal_slardar","MOBILE_BREAKPOINT","DeviceDetector","mediaQuery","currentDevice","callback","handleChange","window","matchMedia","innerWidth","getDevice","observe","newDevice","addEventListener","destroy","removeEventListener","MessageBridge","targetOrigin","iframe","requestId","pendingRequests","Map","eventHandlers","URL","origin","handleMessage","bind","attach","window","addEventListener","detach","removeEventListener","forEach","reject","Error","clear","send","type","data","Promise","resolve","contentWindow","id","message","messageBizId","MESSAGE_BIZ_ID","timestamp","Date","now","isRequest","timer","setTimeout","delete","error","slardar","captureException","source","module","messageType","MESSAGE_TIMEOUT","set","postMessage","onEvent","eventName","handler","handlers","get","push","offEvent","index","indexOf","splice","event","ALLOWED_ORIGINS","includes","isResponseMessage","pending","clearTimeout","errorCode","code","isEventMessage","isResponse","IframeManager","root","config","iframe","messageBridge","channelType","deviceDetector","defaultChannel","anonymous","DEFAULT_ANONYMOUS_CHANNEL_TYPE","DEFAULT_CHANNEL_TYPE","common","MessageBridge","getIframeBaseURL","init","initStart","performance","now","device","DeviceDetector","getDevice","document","createElement","src","buildIframeURL","style","width","height","border","allow","appendChild","attach","setupEventHandlers","observe","newDevice","send","waitForReady","reportInitMetrics","createChatPanel","destroy","detach","parentNode","removeChild","baseURL","events","_events","_anonymous","configWithoutEvents","editorConfig","editor","skill","type","builtinType","iframeConfig","resourceType","configBase64","btoa","encodeURIComponent","JSON","stringify","params","URLSearchParams","appKey","toString","Promise","resolve","reject","timeout","setTimeout","error","Error","slardar","captureException","source","module","checkMessage","event","data","messageBizId","MESSAGE_BIZ_ID","eventName","clearTimeout","window","removeEventListener","addEventListener","onReady","onEvent","onError","msg","message","onMessage","onInited","onInitedWithWelcome","onClose","cost","sendEvent","name","metrics","categories","arch","sendMessage","clear","cancelMessage","messageItem","clearAndStop","updateWelcomeMessage","updateConfig","observeSkill","skillId","skillType","setCurrentSkill","AgentIframeManager","root","config","iframe","messageBridge","runtimeCustomContext","contextVersion","initialHandshakeCompleted","handleSubsequentReady","data","sendParentContext","parseReadyEventData","catch","error","warn","resolveRuntimeCustomContext","createContextVersion","MessageBridge","getAgentIframeBaseURL","init","document","createElement","src","buildIframeURL","style","width","height","border","allow","readyPromise","waitForReady","onEvent","attach","appendChild","readyData","createAgentInstance","destroy","offEvent","send","detach","removeIframe","baseURL","params","URLSearchParams","channelToken","PARENT_ORIGIN_QUERY_KEY","window","location","origin","toString","buildParentContext","parentContext","parentOrigin","Promise","resolve","reject","handleReady","clearTimeout","timeout","setTimeout","Error","payload","buildParentContextForReady","response","accepted","iframeSessionId","readySupportsRuntimeContext","protocolVersion","Boolean","needsContext","isRecord","undefined","customParamsToken","trim","customParams","key","entry","Object","entries","value","desc","isValidCustomParamValue","Array","isArray","every","item","Date","now","Math","random","slice","message","console","WARN_PREFIX","parentNode","removeChild","initAilyChat","root","config","manager","IframeManager","init","initAgentChat","AgentIframeManager"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/iframe-manager.ts","../src/device-detector.ts","../src/message-bridge.ts","../src/agent-iframe-manager.ts"],"sourcesContent":["/*\n * index.ts\n * Author: perterpon.wang<perterpon.wang@bytedance.com>\n * Create: Tue Feb 10 2026\n */\n\nimport { IframeManager } from \"./iframe-manager\";\nimport { AgentIframeManager } from \"./agent-iframe-manager\";\n\nimport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n\tChatPanel,\n\tWebSDKConfig,\n} from \"./types/config\";\n\n/**\n * Initialize Aily Chat via iframe\n * This is the primary method for initializing the chat panel\n * @param root - Container element for the iframe\n * @param config - Configuration options\n * @returns ChatPanel instance for controlling the chat\n */\nexport async function initAilyChat(\n\troot: HTMLElement,\n\tconfig: WebSDKConfig,\n): Promise<ChatPanel> {\n\tconst manager = new IframeManager(root, config);\n\treturn manager.init();\n}\n\n/**\n * Initialize Agent Chat via iframe\n * @param root - Container element for the iframe\n * @param config - Agent SDK configuration\n * @returns Agent SDK instance for controlling the agent page\n */\nexport async function initAgentChat(\n\troot: HTMLElement,\n\tconfig: AgentSDKInitConfig,\n): Promise<AgentSDKInstance> {\n\tconst manager = new AgentIframeManager(root, config);\n\treturn manager.init();\n}\n\n// Export constants\nexport {\n\tAGENT_IFRAME_BASE_URL,\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetAgentIframeBaseURL,\n\tgetIframeBaseURL,\n\tIFRAME_BASE_URL,\n\tMESSAGE_TIMEOUT,\n} from \"./constants\";\n// Export types\nexport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n\tChatPanel,\n CustomParamEntry,\n CustomParams,\n\tWebSDKCommonConfig,\n\tWebSDKConfig,\n\tWebSDKConversionConfig,\n\tWebSDKEditorConfig,\n\tWebSDKEvents,\n\tWebSDKSkillInfo,\n} from \"./types/config\";\n\n// Export message types\nexport type {\n\tIframeEventMessage,\n\tIframeMessage,\n\tIframeMessageType,\n\tIframeRequestMessage,\n\tIframeResponseMessage,\n} from \"./types/message\";\n","/**\n * Constants for Aily Web SDK\n */\n\n/** Message business ID for postMessage identification */\nexport const MESSAGE_BIZ_ID = 'cui-sdk-message' as const;\nexport const PARENT_ORIGIN_QUERY_KEY = '__parentOrigin' as const;\n\n/** Iframe origins by environment */\nexport const IFRAME_ORIGIN: Record<string, string> = {\n production: 'https://aily.feishu.cn',\n staging: 'https://aily.feishu-pre.cn',\n boe: 'https://aily.feishu-boe.cn',\n development: 'http://localhost:3000',\n};\n\n/** Page paths for iframe apps */\nexport const CHAT_IFRAME_PATH = '/cui' as const;\nexport const AGENT_IFRAME_PATH = '/custom_agent/cui' as const;\n\n/** Chat iframe base URLs by environment */\nexport const IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${CHAT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${CHAT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${CHAT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${CHAT_IFRAME_PATH}`,\n};\n\n/** Agent iframe base URLs by environment */\nexport const AGENT_IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${AGENT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${AGENT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${AGENT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${AGENT_IFRAME_PATH}`,\n};\n\ntype IframeEnv = keyof typeof IFRAME_BASE_URL;\n\ninterface AilyWebSdkDebugConfig {\n iframeEnv?: string;\n}\n\ndeclare global {\n interface Window {\n __DEBUG__?: {\n ailyWebSdk?: AilyWebSdkDebugConfig;\n [key: string]: unknown;\n };\n }\n}\n\nfunction isIframeEnv(env?: string): env is IframeEnv {\n return Boolean(env && env in IFRAME_BASE_URL);\n}\n\nfunction resolveDebugIframeEnv(): IframeEnv | undefined {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n const debugIframeEnv = window.__DEBUG__?.ailyWebSdk?.iframeEnv;\n return isIframeEnv(debugIframeEnv) ? debugIframeEnv : undefined;\n}\n\n/**\n * Get iframe base URL based on environment\n */\nfunction resolveIframeEnv(env?: string): IframeEnv {\n if (isIframeEnv(env)) {\n return env;\n }\n\n const debugIframeEnv = resolveDebugIframeEnv();\n if (debugIframeEnv) {\n return debugIframeEnv;\n }\n\n // Auto-detect based on hostname\n // MiaoDa 宿主域名: miaoda.feishu[-env].cn, *.aiforce[-env][-preview].bytedance.net, *.force-pre.feishuapp.net, *.fsapp.kundou.cn, *.aiforce.run, *.aiforce.cloud\n const hostname =\n typeof window !== 'undefined' ? window.location.hostname : '';\n\n if (hostname.includes('aiforce-boe')) {\n return 'boe';\n }\n if (\n hostname.includes('aiforce-pre') ||\n hostname.includes('force-pre.feishuapp.net') ||\n hostname.includes('fsapp.kundou.cn')\n ) {\n return 'staging';\n }\n\n return 'production';\n}\n\nexport function getIframeBaseURL(env?: string): string {\n return IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/**\n * Get agent iframe base URL based on environment\n */\nexport function getAgentIframeBaseURL(env?: string): string {\n return AGENT_IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/** Timeout for postMessage requests (30 seconds) */\nexport const MESSAGE_TIMEOUT = 30 * 1000;\n\n/** Miaoda 渠道标识默认值(用户可通过 config.common.channelType 覆盖) */\nexport const DEFAULT_CHANNEL_TYPE = 'MIAODA_CUI_SDK';\nexport const DEFAULT_ANONYMOUS_CHANNEL_TYPE = 'MIAODA_ANONYMOUS_CUI_SDK';\n\n/** Allowed origins for postMessage (cui-iframe 的 origin) */\nexport const ALLOWED_ORIGINS = [\n IFRAME_ORIGIN.production,\n IFRAME_ORIGIN.staging,\n IFRAME_ORIGIN.boe,\n 'http://localhost:3000',\n 'http://localhost:5173',\n IFRAME_ORIGIN.development,\n];\n","import {\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetIframeBaseURL,\n\tMESSAGE_BIZ_ID,\n} from \"./constants\";\nimport { slardar } from \"@lark-apaas/internal-slardar\";\nimport { DeviceDetector } from \"./device-detector\";\nimport { MessageBridge } from \"./message-bridge\";\n\nimport type { ChatPanel, WebSDKConfig } from \"./types/config\";\n\n/**\n * IframeManager handles iframe creation and lifecycle\n *\n * iframe 采用自初始化模式:配置通过 URL hash 传入,iframe 加载后自行解析并渲染,\n * 与旧版 copilot iframe 的行为保持一致。宿主通过 postMessage 进行后续操作。\n */\nexport class IframeManager {\n\tprivate iframe: HTMLIFrameElement | null = null;\n\tprivate messageBridge: MessageBridge;\n\tprivate config: WebSDKConfig;\n\tprivate channelType: string;\n\tprivate root: HTMLElement;\n\tprivate deviceDetector: DeviceDetector | null = null;\n\n\tconstructor(root: HTMLElement, config: WebSDKConfig) {\n\t\tthis.root = root;\n\t\tthis.config = config;\n\t\tconst defaultChannel = config.anonymous\n\t\t\t? DEFAULT_ANONYMOUS_CHANNEL_TYPE\n\t\t\t: DEFAULT_CHANNEL_TYPE;\n\t\tthis.channelType = config.common?.channelType || defaultChannel;\n\t\tthis.messageBridge = new MessageBridge(getIframeBaseURL());\n\t}\n\n\t/**\n\t * Initialize the iframe and establish communication\n\t * 配置通过 URL hash 编码传入 iframe,iframe 加载后自行初始化\n\t */\n\tasync init(): Promise<ChatPanel> {\n\t\tconst initStart = performance.now();\n\n\t\t// Auto-detect device if not explicitly provided\n\t\tif (!this.config.device) {\n\t\t\tthis.deviceDetector = new DeviceDetector();\n\t\t\tthis.config.device = this.deviceDetector.getDevice();\n\t\t}\n\n\t\t// Create iframe element\n\t\tthis.iframe = document.createElement(\"iframe\");\n\t\tthis.iframe.src = this.buildIframeURL();\n\t\tthis.iframe.style.width = \"100%\";\n\t\tthis.iframe.style.height = \"100%\";\n\t\tthis.iframe.style.border = \"none\";\n\t\tthis.iframe.allow = \"microphone; clipboard-write\";\n\n\t\t// Attach to DOM\n\t\tthis.root.appendChild(this.iframe);\n\n\t\t// Attach message bridge (开始监听消息)\n\t\tthis.messageBridge.attach(this.iframe);\n\n\t\t// Setup event handlers (在 iframe 初始化完成之前就开始监听,确保不丢失事件)\n\t\tthis.setupEventHandlers();\n\n\t\t// Listen for device changes and push updates to iframe\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.observe((newDevice) => {\n\t\t\t\tthis.messageBridge.send(\"updateConfig\", { device: newDevice });\n\t\t\t});\n\t\t}\n\n\t\t// Wait for iframe to finish initialization (iframe 自行读取 URL 配置并渲染,完成后发送 ready 事件)\n\t\tawait this.waitForReady();\n\n\t\t// 上报 cui_init_total 耗时(iframe 创建 → init 完成)\n\t\tthis.reportInitMetrics(initStart);\n\n\t\t// Return ChatPanel interface\n\t\treturn this.createChatPanel();\n\t}\n\n\t/**\n\t * Destroy the iframe and cleanup\n\t */\n\tasync destroy(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.messageBridge.send(\"destroy\");\n\t\t} catch {\n\t\t\t// Ignore errors during destroy\n\t\t}\n\n\t\tthis.messageBridge.detach();\n\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.destroy();\n\t\t\tthis.deviceDetector = null;\n\t\t}\n\n\t\tif (this.iframe?.parentNode) {\n\t\t\tthis.iframe.parentNode.removeChild(this.iframe);\n\t\t}\n\n\t\tthis.iframe = null;\n\t}\n\n\t/**\n\t * 构建 iframe URL,将配置编码到 hash 中\n\t * 格式: {baseURL}#{params} 其中 config 为 base64(JSON.stringify(configWithoutEvents))\n\t *\n\t * 鉴权说明:SDK 不参与 token 获取/传递。iframe 自行处理飞书登录流程,\n\t * 允许用户在 iframe 中独立登录。匿名渠道跳过登录检查。\n\t */\n\tprivate buildIframeURL(): string {\n\t\tconst baseURL = getIframeBaseURL();\n\n\t\t// 移除 events(函数无法序列化)\n\t\tconst {\n\t\t\tevents: _events,\n\t\t\tanonymous: _anonymous,\n\t\t\t...configWithoutEvents\n\t\t} = this.config;\n\t\t// 注入 channelType/resourceType(SDK 内部控制,不暴露给消费者)\n\t\t// 补全 editor.skill 硬编码字段\n\t\tconst editorConfig = configWithoutEvents.editor?.skill\n\t\t\t? {\n\t\t\t\t\t...configWithoutEvents.editor,\n\t\t\t\t\tskill: {\n\t\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\t\tbuiltinType: \"unspecified\",\n\t\t\t\t\t\t...configWithoutEvents.editor.skill,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: configWithoutEvents.editor;\n\n\t\tconst iframeConfig = {\n\t\t\t...configWithoutEvents,\n\t\t\tcommon: {\n\t\t\t\t...configWithoutEvents.common,\n\t\t\t\tchannelType: this.channelType,\n\t\t\t\tresourceType:\n\t\t\t\t\tconfigWithoutEvents.common?.resourceType || this.channelType,\n\t\t\t},\n\t\t\teditor: editorConfig,\n\t\t};\n\t\tconst configBase64 = btoa(encodeURIComponent(JSON.stringify(iframeConfig)));\n\n\t\tconst params = new URLSearchParams({\n\t\t\tappKey: this.config.appKey,\n\t\t\tconfig: encodeURIComponent(configBase64),\n\t\t});\n\n\t\treturn `${baseURL}#${params.toString()}`;\n\t}\n\n\t/**\n\t * 等待 iframe 自行初始化完成后发送 ready 事件\n\t */\n\tprivate waitForReady(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tconst error = new Error(\"Iframe ready timeout\");\n\t\t\t\tslardar.captureException(error, { source: 'aily-web-sdk', module: 'iframe-ready' });\n\t\t\t\treject(error);\n\t\t\t}, 30000);\n\n\t\t\tconst checkMessage = (event: MessageEvent) => {\n\t\t\t\tif (\n\t\t\t\t\tevent.data?.messageBizId === MESSAGE_BIZ_ID &&\n\t\t\t\t\tevent.data?.type === \"event\" &&\n\t\t\t\t\tevent.data?.eventName === \"ready\"\n\t\t\t\t) {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\twindow.removeEventListener(\"message\", checkMessage);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\twindow.addEventListener(\"message\", checkMessage);\n\t\t});\n\t}\n\n\tprivate setupEventHandlers(): void {\n\t\tconst { events } = this.config;\n\t\tif (!events) return;\n\n\t\tif (events.onReady) {\n\t\t\tthis.messageBridge.onEvent(\"ready\", events.onReady);\n\t\t}\n\n\t\tif (events.onError) {\n\t\t\tthis.messageBridge.onEvent(\"error\", (data: unknown) => {\n\t\t\t\tconst msg = (data as { message?: string })?.message || \"Unknown error\";\n\t\t\t\tevents.onError?.(new Error(msg));\n\t\t\t});\n\t\t}\n\n\t\tif (events.onMessage) {\n\t\t\tthis.messageBridge.onEvent(\"onMessage\", events.onMessage);\n\t\t}\n\n\t\tif (events.onInited) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"inited\",\n\t\t\t\tevents.onInited as (data: unknown) => void,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onInitedWithWelcome) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"initedWithWelcome\",\n\t\t\t\tevents.onInitedWithWelcome,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onClose) {\n\t\t\tthis.messageBridge.onEvent(\"onClose\", events.onClose);\n\t\t}\n\t}\n\n\tprivate reportInitMetrics(initStart: number): void {\n\t\ttry {\n\t\t\tconst cost = performance.now() - initStart;\n\t\t\tslardar.sendEvent({\n\t\t\t\tname: \"cui_init_total\",\n\t\t\t\tmetrics: { cost },\n\t\t\t\tcategories: {\n\t\t\t\t\tarch: \"iframe-static\",\n\t\t\t\t\tappKey: this.config.appKey,\n\t\t\t\t\tchannelType: this.channelType,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch {\n\t\t\t// 性能上报失败不影响功能\n\t\t}\n\t}\n\n\tprivate createChatPanel(): ChatPanel {\n\t\treturn {\n\t\t\tsendMessage: async (data) => {\n\t\t\t\tawait this.messageBridge.send(\"sendMessage\", data);\n\t\t\t},\n\t\t\tclear: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clear\");\n\t\t\t},\n\t\t\tcancelMessage: async (messageItem) => {\n\t\t\t\tawait this.messageBridge.send(\"cancelMessage\", messageItem);\n\t\t\t},\n\t\t\tclearAndStop: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clearAndStop\");\n\t\t\t},\n\t\t\tupdateWelcomeMessage: async () => {\n\t\t\t\tawait this.messageBridge.send(\"updateWelcomeMessage\");\n\t\t\t},\n\t\t\tupdateConfig: async (config) => {\n\t\t\t\tawait this.messageBridge.send(\"updateConfig\", config);\n\t\t\t},\n\t\t\tobserveSkill: async (skillId, name, skillType) => {\n\t\t\t\tawait this.messageBridge.send(\"observeSkill\", {\n\t\t\t\t\tskillId,\n\t\t\t\t\tname,\n\t\t\t\t\tskillType,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetCurrentSkill: async (skill) => {\n\t\t\t\tawait this.messageBridge.send(\"setCurrentSkill\", skill);\n\t\t\t},\n\t\t\tdestroy: async () => {\n\t\t\t\tawait this.destroy();\n\t\t\t},\n\t\t};\n\t}\n}\n","const MOBILE_BREAKPOINT = 768;\n\ntype DeviceType = 'pc' | 'mobile';\ntype DeviceChangeCallback = (device: DeviceType) => void;\n\n/**\n * 设备类型自动检测器\n *\n * 使用 matchMedia + 768px 断点检测设备类型,与 miaoda useIsMobile 逻辑一致。\n * 检测在宿主页面(而非 iframe)中执行,结果通过 postMessage 推送给 iframe。\n */\nexport class DeviceDetector {\n private mediaQuery: MediaQueryList;\n private currentDevice: DeviceType;\n private callback: DeviceChangeCallback | null = null;\n private handleChange: (() => void) | null = null;\n\n constructor() {\n this.mediaQuery = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n this.currentDevice = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n }\n\n getDevice(): DeviceType {\n return this.currentDevice;\n }\n\n observe(callback: DeviceChangeCallback): void {\n this.callback = callback;\n this.handleChange = () => {\n const newDevice: DeviceType = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n if (newDevice !== this.currentDevice) {\n this.currentDevice = newDevice;\n this.callback?.(newDevice);\n }\n };\n this.mediaQuery.addEventListener('change', this.handleChange);\n }\n\n destroy(): void {\n if (this.handleChange) {\n this.mediaQuery.removeEventListener('change', this.handleChange);\n this.handleChange = null;\n }\n this.callback = null;\n }\n}\n","import { MESSAGE_TIMEOUT, ALLOWED_ORIGINS } from './constants';\nimport {\n MESSAGE_BIZ_ID,\n type IframeMessage,\n type IframeRequestMessage,\n type IframeResponseMessage,\n type IframeEventMessage,\n type IframeMessageType,\n} from './types/message';\nimport { slardar } from '@lark-apaas/internal-slardar';\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * MessageBridge handles postMessage communication between parent and iframe\n */\nexport class MessageBridge {\n private iframe: HTMLIFrameElement | null = null;\n private requestId = 0;\n private pendingRequests = new Map<number, PendingRequest>();\n private eventHandlers = new Map<string, ((data: unknown) => void)[]>();\n private targetOrigin: string;\n\n constructor(targetOrigin: string) {\n this.targetOrigin = new URL(targetOrigin).origin;\n this.handleMessage = this.handleMessage.bind(this);\n }\n\n /**\n * Attach to an iframe and start listening for messages\n */\n attach(iframe: HTMLIFrameElement): void {\n this.iframe = iframe;\n window.addEventListener('message', this.handleMessage);\n }\n\n /**\n * Detach from iframe and clean up\n */\n detach(): void {\n window.removeEventListener('message', this.handleMessage);\n this.iframe = null;\n // Clear all pending requests\n this.pendingRequests.forEach(({ reject }) => {\n reject(new Error('MessageBridge detached'));\n });\n this.pendingRequests.clear();\n }\n\n /**\n * Send a message to the iframe and wait for response\n */\n send<T = unknown>(type: IframeMessageType, data?: unknown): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!this.iframe?.contentWindow) {\n reject(new Error('Iframe not attached'));\n return;\n }\n\n this.requestId += 1;\n const id = this.requestId;\n const message: IframeRequestMessage = {\n messageBizId: MESSAGE_BIZ_ID,\n id,\n type,\n data,\n timestamp: Date.now(),\n isRequest: true,\n };\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n const error = new Error(`Message timeout: ${type}`);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', messageType: type });\n reject(error);\n }, MESSAGE_TIMEOUT);\n\n this.pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timer });\n\n this.iframe.contentWindow.postMessage(message, this.targetOrigin);\n });\n }\n\n /**\n * Register an event handler\n */\n onEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n handlers.push(handler);\n this.eventHandlers.set(eventName, handlers);\n }\n\n /**\n * Remove an event handler\n */\n offEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n this.eventHandlers.set(eventName, handlers);\n }\n }\n\n private handleMessage(event: MessageEvent<IframeMessage>): void {\n // Validate origin\n if (!ALLOWED_ORIGINS.includes(event.origin)) {\n return;\n }\n\n const { data } = event;\n\n // Validate message format\n if (data?.messageBizId !== MESSAGE_BIZ_ID) {\n return;\n }\n\n // Handle response messages\n if (this.isResponseMessage(data)) {\n const pending = this.pendingRequests.get(data.id);\n if (pending) {\n clearTimeout(pending.timer);\n this.pendingRequests.delete(data.id);\n\n if (data.error) {\n const error = new Error(data.error.message);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', errorCode: data.error.code });\n pending.reject(error);\n } else {\n pending.resolve(data.data);\n }\n }\n }\n\n // Handle event messages\n if (this.isEventMessage(data)) {\n const handlers = this.eventHandlers.get(data.eventName) || [];\n handlers.forEach((handler) => {\n try {\n handler(data.data);\n } catch {\n // Ignore handler errors\n }\n });\n }\n }\n\n private isResponseMessage(data: IframeMessage): data is IframeResponseMessage {\n return 'isResponse' in data && data.isResponse === true;\n }\n\n private isEventMessage(data: IframeMessage): data is IframeEventMessage {\n return data.type === 'event';\n }\n}\n","import { PARENT_ORIGIN_QUERY_KEY, getAgentIframeBaseURL } from './constants';\nimport { MessageBridge } from './message-bridge';\n\nimport type {\n AgentSDKInitConfig,\n AgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n} from './types/config';\nimport type {\n AgentReadyEventData,\n ParentContextMessageData,\n ParentContextResponseData,\n} from './types/message';\n\ntype RuntimeCustomContextPayload = Partial<AgentSDKRuntimeCustomContext> & {\n customParams?: unknown;\n customParamsToken?: string;\n};\n\n/**\n * AgentIframeManager handles agent iframe creation and lifecycle.\n */\nexport class AgentIframeManager {\n private static readonly WARN_PREFIX = '[aily-web-sdk]';\n private iframe: HTMLIFrameElement | null = null;\n private readonly messageBridge: MessageBridge;\n private readonly config: AgentSDKInitConfig;\n private readonly root: HTMLElement;\n private readonly runtimeCustomContext: RuntimeCustomContextPayload | null;\n private readonly contextVersion: string;\n private initialHandshakeCompleted = false;\n\n constructor(root: HTMLElement, config: AgentSDKInitConfig) {\n this.root = root;\n this.config = config;\n this.runtimeCustomContext = this.resolveRuntimeCustomContext(config);\n this.contextVersion = this.createContextVersion();\n this.messageBridge = new MessageBridge(getAgentIframeBaseURL());\n }\n\n async init(): Promise<AgentSDKInstance> {\n this.iframe = document.createElement('iframe');\n this.iframe.src = this.buildIframeURL();\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.style.border = 'none';\n this.iframe.allow = 'microphone; clipboard-write';\n\n const readyPromise = this.waitForReady();\n this.messageBridge.onEvent('ready', this.handleSubsequentReady);\n this.messageBridge.attach(this.iframe);\n this.root.appendChild(this.iframe);\n\n try {\n const readyData = await readyPromise;\n await this.sendParentContext(readyData);\n } catch (error) {\n this.warn(\n 'Agent SDK initialization encountered a non-blocking error. Initialization will continue without blocking the iframe lifecycle.',\n error\n );\n } finally {\n this.initialHandshakeCompleted = true;\n }\n\n return this.createAgentInstance();\n }\n\n async destroy(): Promise<void> {\n this.messageBridge.offEvent('ready', this.handleSubsequentReady);\n\n try {\n await this.messageBridge.send('destroy');\n } catch {\n // Ignore errors during destroy.\n }\n\n this.messageBridge.detach();\n this.removeIframe();\n this.initialHandshakeCompleted = false;\n }\n\n private buildIframeURL(): string {\n const baseURL = getAgentIframeBaseURL();\n const params = new URLSearchParams({\n channelToken: this.config.channelToken,\n [PARENT_ORIGIN_QUERY_KEY]: window.location.origin,\n });\n\n return `${baseURL}?${params.toString()}`;\n }\n\n private buildParentContext(): ParentContextMessageData {\n const parentContext: ParentContextMessageData = {\n parentOrigin: window.location.origin,\n };\n\n return parentContext;\n }\n\n private waitForReady(): Promise<AgentReadyEventData | undefined> {\n return new Promise((resolve, reject) => {\n const handleReady = (data: unknown) => {\n clearTimeout(timeout);\n this.messageBridge.offEvent('ready', handleReady);\n resolve(this.parseReadyEventData(data));\n };\n\n const timeout = setTimeout(() => {\n this.messageBridge.offEvent('ready', handleReady);\n reject(new Error('Iframe ready timeout'));\n }, 30000);\n\n this.messageBridge.onEvent('ready', handleReady);\n });\n }\n\n private readonly handleSubsequentReady = (data: unknown): void => {\n if (!this.initialHandshakeCompleted) {\n return;\n }\n\n void this.sendParentContext(this.parseReadyEventData(data)).catch(error => {\n this.warn(\n 'Failed to re-send initParentContext after iframe ready event.',\n error\n );\n });\n };\n\n private async sendParentContext(\n readyData?: AgentReadyEventData\n ): Promise<void> {\n const payload = this.buildParentContextForReady(readyData);\n let response: ParentContextResponseData | undefined;\n\n try {\n response = await this.messageBridge.send<ParentContextResponseData>(\n 'initParentContext',\n payload\n );\n } catch (error) {\n this.warn(\n 'Failed to send initParentContext during initialization.',\n error\n );\n return;\n }\n\n if (!this.runtimeCustomContext) {\n return;\n }\n\n if (response?.accepted !== true) {\n this.warn(\n 'Iframe rejected initParentContext custom context. Custom context will be ignored for this initialization.'\n );\n return;\n }\n\n if (\n payload.iframeSessionId &&\n response.iframeSessionId &&\n response.iframeSessionId !== payload.iframeSessionId\n ) {\n this.warn(\n 'Iframe returned mismatched iframeSessionId. Custom context acknowledgement will be ignored.'\n );\n return;\n }\n\n if (\n payload.contextVersion &&\n response.contextVersion &&\n response.contextVersion !== payload.contextVersion\n ) {\n this.warn(\n 'Iframe returned mismatched contextVersion. Custom context acknowledgement will be ignored.'\n );\n }\n }\n\n private buildParentContextForReady(\n readyData?: AgentReadyEventData\n ): ParentContextMessageData {\n const parentContext = this.buildParentContext();\n\n if (!this.runtimeCustomContext) {\n return parentContext;\n }\n\n if (!this.readySupportsRuntimeContext(readyData)) {\n this.warn(\n 'Current iframe version does not support custom context initParentContext protocol. SDK initialization will continue without custom context.'\n );\n return parentContext;\n }\n\n return {\n ...parentContext,\n protocolVersion: 2,\n iframeSessionId: readyData.iframeSessionId,\n contextVersion: this.contextVersion,\n runtimeCustomContext: this.runtimeCustomContext,\n };\n }\n\n private readySupportsRuntimeContext(\n readyData?: AgentReadyEventData\n ): readyData is AgentReadyEventData & {\n protocolVersion: 2;\n iframeSessionId: string;\n needsContext: true;\n } {\n return (\n readyData?.protocolVersion === 2 &&\n Boolean(readyData.iframeSessionId) &&\n readyData.needsContext === true\n );\n }\n\n private parseReadyEventData(data: unknown): AgentReadyEventData | undefined {\n if (!this.isRecord(data)) {\n return undefined;\n }\n\n return data as AgentReadyEventData;\n }\n\n private resolveRuntimeCustomContext(\n config: AgentSDKInitConfig\n ): RuntimeCustomContextPayload | null {\n let customParamsToken: string | undefined;\n if (config.customParamsToken !== undefined) {\n customParamsToken = config.customParamsToken.trim();\n if (!customParamsToken) {\n this.warn(\n 'customParamsToken cannot be empty. SDK initialization will continue without custom context.'\n );\n }\n }\n\n if (config.customParams === undefined) {\n if (customParamsToken !== undefined) {\n this.warn(\n 'customParamsToken requires customParams for jwt verification. SDK initialization will continue without custom context.'\n );\n return {\n customParamsToken,\n };\n }\n\n return null;\n }\n\n if (!this.isRecord(config.customParams)) {\n this.warn(\n 'customParams must be an object. SDK initialization will continue without custom context.'\n );\n return {\n customParams: config.customParams,\n ...(customParamsToken !== undefined ? { customParamsToken } : {}),\n };\n }\n\n for (const [key, entry] of Object.entries(config.customParams)) {\n if (\n !this.isRecord(entry) ||\n !('value' in entry) ||\n entry.value === undefined\n ) {\n this.warn(\n `customParams.${key} must include value. SDK initialization will continue without custom context.`\n );\n continue;\n }\n\n if (\n 'desc' in entry &&\n entry.desc !== undefined &&\n typeof entry.desc !== 'string'\n ) {\n this.warn(\n `customParams.${key}.desc must be a string. SDK initialization will continue without custom context.`\n );\n }\n\n if ('value' in entry && !this.isValidCustomParamValue(entry.value)) {\n this.warn(\n `customParams.${key}.value has invalid type. SDK initialization will continue without custom context.`\n );\n }\n }\n\n return {\n customParams: config.customParams,\n ...(customParamsToken !== undefined ? { customParamsToken } : {}),\n };\n }\n\n private isValidCustomParamValue(value: unknown): boolean {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(\n item =>\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean' ||\n this.isRecord(item)\n );\n }\n\n return this.isRecord(value);\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n\n private createContextVersion(): string {\n return `ctx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n private warn(message: string, error?: unknown): void {\n if (error === undefined) {\n console.warn(AgentIframeManager.WARN_PREFIX, message);\n return;\n }\n\n console.warn(AgentIframeManager.WARN_PREFIX, message, error);\n }\n\n private removeIframe(): void {\n if (this.iframe?.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n this.iframe = null;\n }\n\n private createAgentInstance(): AgentSDKInstance {\n return {\n destroy: async () => {\n await this.destroy();\n },\n };\n }\n}\n"],"mappings":"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","names":["MESSAGE_BIZ_ID","PARENT_ORIGIN_QUERY_KEY","IFRAME_ORIGIN","production","staging","boe","development","CHAT_IFRAME_PATH","AGENT_IFRAME_PATH","IFRAME_BASE_URL","AGENT_IFRAME_BASE_URL","isIframeEnv","env","Boolean","resolveDebugIframeEnv","window","undefined","debugIframeEnv","__DEBUG__","ailyWebSdk","iframeEnv","resolveIframeEnv","hostname","location","includes","getIframeBaseURL","getAgentIframeBaseURL","MESSAGE_TIMEOUT","DEFAULT_CHANNEL_TYPE","DEFAULT_ANONYMOUS_CHANNEL_TYPE","ALLOWED_ORIGINS","import_internal_slardar","MOBILE_BREAKPOINT","DeviceDetector","mediaQuery","currentDevice","callback","handleChange","window","matchMedia","innerWidth","getDevice","observe","newDevice","addEventListener","destroy","removeEventListener","MessageBridge","targetOrigin","iframe","requestId","pendingRequests","Map","eventHandlers","URL","origin","handleMessage","bind","attach","window","addEventListener","detach","removeEventListener","forEach","reject","Error","clear","send","type","data","Promise","resolve","contentWindow","id","message","messageBizId","MESSAGE_BIZ_ID","timestamp","Date","now","isRequest","timer","setTimeout","delete","error","slardar","captureException","source","module","messageType","MESSAGE_TIMEOUT","set","postMessage","onEvent","eventName","handler","handlers","get","push","offEvent","index","indexOf","splice","event","ALLOWED_ORIGINS","includes","isResponseMessage","pending","clearTimeout","errorCode","code","isEventMessage","isResponse","IframeManager","root","config","iframe","messageBridge","channelType","deviceDetector","defaultChannel","anonymous","DEFAULT_ANONYMOUS_CHANNEL_TYPE","DEFAULT_CHANNEL_TYPE","common","MessageBridge","getIframeBaseURL","init","initStart","performance","now","device","DeviceDetector","getDevice","document","createElement","src","buildIframeURL","style","width","height","border","allow","appendChild","attach","setupEventHandlers","observe","newDevice","send","waitForReady","reportInitMetrics","createChatPanel","destroy","detach","parentNode","removeChild","baseURL","events","_events","_anonymous","configWithoutEvents","editorConfig","editor","skill","type","builtinType","iframeConfig","resourceType","configBase64","btoa","encodeURIComponent","JSON","stringify","params","URLSearchParams","appKey","toString","Promise","resolve","reject","timeout","setTimeout","error","Error","slardar","captureException","source","module","checkMessage","event","data","messageBizId","MESSAGE_BIZ_ID","eventName","clearTimeout","window","removeEventListener","addEventListener","onReady","onEvent","onError","msg","message","onMessage","onInited","onInitedWithWelcome","onClose","cost","sendEvent","name","metrics","categories","arch","sendMessage","clear","cancelMessage","messageItem","clearAndStop","updateWelcomeMessage","updateConfig","observeSkill","skillId","skillType","setCurrentSkill","AgentIframeManager","root","config","iframe","messageBridge","runtimeCustomContext","contextVersion","initialHandshakeCompleted","handleSubsequentReady","data","sendParentContext","parseReadyEventData","catch","error","warn","resolveRuntimeCustomContext","createContextVersion","MessageBridge","getAgentIframeBaseURL","init","document","createElement","src","buildIframeURL","style","width","height","border","allow","readyPromise","waitForReady","onEvent","attach","appendChild","readyData","createAgentInstance","destroy","offEvent","send","detach","removeIframe","baseURL","params","URLSearchParams","channelToken","PARENT_ORIGIN_QUERY_KEY","window","location","origin","toString","buildParentContext","parentContext","parentOrigin","Promise","resolve","reject","handleReady","clearTimeout","timeout","setTimeout","Error","payload","buildParentContextForReady","response","accepted","iframeSessionId","readySupportsRuntimeContext","protocolVersion","Boolean","needsContext","isRecord","undefined","customParamsToken","trim","customParams","key","entry","Object","entries","value","desc","isValidCustomParamValue","Array","isArray","every","item","Date","now","Math","random","slice","message","console","WARN_PREFIX","parentNode","removeChild","initAilyChat","root","config","manager","IframeManager","init","initAgentChat","AgentIframeManager"]}
package/dist/index.js CHANGED
@@ -587,39 +587,43 @@ var _AgentIframeManager = class _AgentIframeManager {
587
587
  customParamsToken = config.customParamsToken.trim();
588
588
  if (!customParamsToken) {
589
589
  this.warn("customParamsToken cannot be empty. SDK initialization will continue without custom context.");
590
- return null;
591
590
  }
592
591
  }
593
592
  if (config.customParams === void 0) {
594
593
  if (customParamsToken !== void 0) {
595
594
  this.warn("customParamsToken requires customParams for jwt verification. SDK initialization will continue without custom context.");
596
- return null;
595
+ return {
596
+ customParamsToken
597
+ };
597
598
  }
598
599
  return null;
599
600
  }
600
601
  if (!this.isRecord(config.customParams)) {
601
602
  this.warn("customParams must be an object. SDK initialization will continue without custom context.");
602
- return null;
603
+ return {
604
+ customParams: config.customParams,
605
+ ...customParamsToken !== void 0 ? {
606
+ customParamsToken
607
+ } : {}
608
+ };
603
609
  }
604
610
  for (const [key, entry] of Object.entries(config.customParams)) {
605
611
  if (!this.isRecord(entry) || !("value" in entry) || entry.value === void 0) {
606
612
  this.warn(`customParams.${key} must include value. SDK initialization will continue without custom context.`);
607
- return null;
613
+ continue;
608
614
  }
609
615
  if ("desc" in entry && entry.desc !== void 0 && typeof entry.desc !== "string") {
610
616
  this.warn(`customParams.${key}.desc must be a string. SDK initialization will continue without custom context.`);
611
- return null;
612
617
  }
613
- if (!this.isValidCustomParamValue(entry.value)) {
618
+ if ("value" in entry && !this.isValidCustomParamValue(entry.value)) {
614
619
  this.warn(`customParams.${key}.value has invalid type. SDK initialization will continue without custom context.`);
615
- return null;
616
620
  }
617
621
  }
618
- return customParamsToken !== void 0 ? {
622
+ return {
619
623
  customParams: config.customParams,
620
- customParamsToken
621
- } : {
622
- customParams: config.customParams
624
+ ...customParamsToken !== void 0 ? {
625
+ customParamsToken
626
+ } : {}
623
627
  };
624
628
  }
625
629
  isValidCustomParamValue(value) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/iframe-manager.ts","../src/device-detector.ts","../src/message-bridge.ts","../src/agent-iframe-manager.ts","../src/index.ts"],"sourcesContent":["/**\n * Constants for Aily Web SDK\n */\n\n/** Message business ID for postMessage identification */\nexport const MESSAGE_BIZ_ID = 'cui-sdk-message' as const;\nexport const PARENT_ORIGIN_QUERY_KEY = '__parentOrigin' as const;\n\n/** Iframe origins by environment */\nexport const IFRAME_ORIGIN: Record<string, string> = {\n production: 'https://aily.feishu.cn',\n staging: 'https://aily.feishu-pre.cn',\n boe: 'https://aily.feishu-boe.cn',\n development: 'http://localhost:3000',\n};\n\n/** Page paths for iframe apps */\nexport const CHAT_IFRAME_PATH = '/cui' as const;\nexport const AGENT_IFRAME_PATH = '/custom_agent/cui' as const;\n\n/** Chat iframe base URLs by environment */\nexport const IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${CHAT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${CHAT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${CHAT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${CHAT_IFRAME_PATH}`,\n};\n\n/** Agent iframe base URLs by environment */\nexport const AGENT_IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${AGENT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${AGENT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${AGENT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${AGENT_IFRAME_PATH}`,\n};\n\ntype IframeEnv = keyof typeof IFRAME_BASE_URL;\n\ninterface AilyWebSdkDebugConfig {\n iframeEnv?: string;\n}\n\ndeclare global {\n interface Window {\n __DEBUG__?: {\n ailyWebSdk?: AilyWebSdkDebugConfig;\n [key: string]: unknown;\n };\n }\n}\n\nfunction isIframeEnv(env?: string): env is IframeEnv {\n return Boolean(env && env in IFRAME_BASE_URL);\n}\n\nfunction resolveDebugIframeEnv(): IframeEnv | undefined {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n const debugIframeEnv = window.__DEBUG__?.ailyWebSdk?.iframeEnv;\n return isIframeEnv(debugIframeEnv) ? debugIframeEnv : undefined;\n}\n\n/**\n * Get iframe base URL based on environment\n */\nfunction resolveIframeEnv(env?: string): IframeEnv {\n if (isIframeEnv(env)) {\n return env;\n }\n\n const debugIframeEnv = resolveDebugIframeEnv();\n if (debugIframeEnv) {\n return debugIframeEnv;\n }\n\n // Auto-detect based on hostname\n // MiaoDa 宿主域名: miaoda.feishu[-env].cn, *.aiforce[-env][-preview].bytedance.net, *.force-pre.feishuapp.net, *.fsapp.kundou.cn, *.aiforce.run, *.aiforce.cloud\n const hostname =\n typeof window !== 'undefined' ? window.location.hostname : '';\n\n if (hostname.includes('aiforce-boe')) {\n return 'boe';\n }\n if (\n hostname.includes('aiforce-pre') ||\n hostname.includes('force-pre.feishuapp.net') ||\n hostname.includes('fsapp.kundou.cn')\n ) {\n return 'staging';\n }\n\n return 'production';\n}\n\nexport function getIframeBaseURL(env?: string): string {\n return IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/**\n * Get agent iframe base URL based on environment\n */\nexport function getAgentIframeBaseURL(env?: string): string {\n return AGENT_IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/** Timeout for postMessage requests (30 seconds) */\nexport const MESSAGE_TIMEOUT = 30 * 1000;\n\n/** Miaoda 渠道标识默认值(用户可通过 config.common.channelType 覆盖) */\nexport const DEFAULT_CHANNEL_TYPE = 'MIAODA_CUI_SDK';\nexport const DEFAULT_ANONYMOUS_CHANNEL_TYPE = 'MIAODA_ANONYMOUS_CUI_SDK';\n\n/** Allowed origins for postMessage (cui-iframe 的 origin) */\nexport const ALLOWED_ORIGINS = [\n IFRAME_ORIGIN.production,\n IFRAME_ORIGIN.staging,\n IFRAME_ORIGIN.boe,\n 'http://localhost:3000',\n 'http://localhost:5173',\n IFRAME_ORIGIN.development,\n];\n","import {\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetIframeBaseURL,\n\tMESSAGE_BIZ_ID,\n} from \"./constants\";\nimport { slardar } from \"@lark-apaas/internal-slardar\";\nimport { DeviceDetector } from \"./device-detector\";\nimport { MessageBridge } from \"./message-bridge\";\n\nimport type { ChatPanel, WebSDKConfig } from \"./types/config\";\n\n/**\n * IframeManager handles iframe creation and lifecycle\n *\n * iframe 采用自初始化模式:配置通过 URL hash 传入,iframe 加载后自行解析并渲染,\n * 与旧版 copilot iframe 的行为保持一致。宿主通过 postMessage 进行后续操作。\n */\nexport class IframeManager {\n\tprivate iframe: HTMLIFrameElement | null = null;\n\tprivate messageBridge: MessageBridge;\n\tprivate config: WebSDKConfig;\n\tprivate channelType: string;\n\tprivate root: HTMLElement;\n\tprivate deviceDetector: DeviceDetector | null = null;\n\n\tconstructor(root: HTMLElement, config: WebSDKConfig) {\n\t\tthis.root = root;\n\t\tthis.config = config;\n\t\tconst defaultChannel = config.anonymous\n\t\t\t? DEFAULT_ANONYMOUS_CHANNEL_TYPE\n\t\t\t: DEFAULT_CHANNEL_TYPE;\n\t\tthis.channelType = config.common?.channelType || defaultChannel;\n\t\tthis.messageBridge = new MessageBridge(getIframeBaseURL());\n\t}\n\n\t/**\n\t * Initialize the iframe and establish communication\n\t * 配置通过 URL hash 编码传入 iframe,iframe 加载后自行初始化\n\t */\n\tasync init(): Promise<ChatPanel> {\n\t\tconst initStart = performance.now();\n\n\t\t// Auto-detect device if not explicitly provided\n\t\tif (!this.config.device) {\n\t\t\tthis.deviceDetector = new DeviceDetector();\n\t\t\tthis.config.device = this.deviceDetector.getDevice();\n\t\t}\n\n\t\t// Create iframe element\n\t\tthis.iframe = document.createElement(\"iframe\");\n\t\tthis.iframe.src = this.buildIframeURL();\n\t\tthis.iframe.style.width = \"100%\";\n\t\tthis.iframe.style.height = \"100%\";\n\t\tthis.iframe.style.border = \"none\";\n\t\tthis.iframe.allow = \"microphone; clipboard-write\";\n\n\t\t// Attach to DOM\n\t\tthis.root.appendChild(this.iframe);\n\n\t\t// Attach message bridge (开始监听消息)\n\t\tthis.messageBridge.attach(this.iframe);\n\n\t\t// Setup event handlers (在 iframe 初始化完成之前就开始监听,确保不丢失事件)\n\t\tthis.setupEventHandlers();\n\n\t\t// Listen for device changes and push updates to iframe\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.observe((newDevice) => {\n\t\t\t\tthis.messageBridge.send(\"updateConfig\", { device: newDevice });\n\t\t\t});\n\t\t}\n\n\t\t// Wait for iframe to finish initialization (iframe 自行读取 URL 配置并渲染,完成后发送 ready 事件)\n\t\tawait this.waitForReady();\n\n\t\t// 上报 cui_init_total 耗时(iframe 创建 → init 完成)\n\t\tthis.reportInitMetrics(initStart);\n\n\t\t// Return ChatPanel interface\n\t\treturn this.createChatPanel();\n\t}\n\n\t/**\n\t * Destroy the iframe and cleanup\n\t */\n\tasync destroy(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.messageBridge.send(\"destroy\");\n\t\t} catch {\n\t\t\t// Ignore errors during destroy\n\t\t}\n\n\t\tthis.messageBridge.detach();\n\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.destroy();\n\t\t\tthis.deviceDetector = null;\n\t\t}\n\n\t\tif (this.iframe?.parentNode) {\n\t\t\tthis.iframe.parentNode.removeChild(this.iframe);\n\t\t}\n\n\t\tthis.iframe = null;\n\t}\n\n\t/**\n\t * 构建 iframe URL,将配置编码到 hash 中\n\t * 格式: {baseURL}#{params} 其中 config 为 base64(JSON.stringify(configWithoutEvents))\n\t *\n\t * 鉴权说明:SDK 不参与 token 获取/传递。iframe 自行处理飞书登录流程,\n\t * 允许用户在 iframe 中独立登录。匿名渠道跳过登录检查。\n\t */\n\tprivate buildIframeURL(): string {\n\t\tconst baseURL = getIframeBaseURL();\n\n\t\t// 移除 events(函数无法序列化)\n\t\tconst {\n\t\t\tevents: _events,\n\t\t\tanonymous: _anonymous,\n\t\t\t...configWithoutEvents\n\t\t} = this.config;\n\t\t// 注入 channelType/resourceType(SDK 内部控制,不暴露给消费者)\n\t\t// 补全 editor.skill 硬编码字段\n\t\tconst editorConfig = configWithoutEvents.editor?.skill\n\t\t\t? {\n\t\t\t\t\t...configWithoutEvents.editor,\n\t\t\t\t\tskill: {\n\t\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\t\tbuiltinType: \"unspecified\",\n\t\t\t\t\t\t...configWithoutEvents.editor.skill,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: configWithoutEvents.editor;\n\n\t\tconst iframeConfig = {\n\t\t\t...configWithoutEvents,\n\t\t\tcommon: {\n\t\t\t\t...configWithoutEvents.common,\n\t\t\t\tchannelType: this.channelType,\n\t\t\t\tresourceType:\n\t\t\t\t\tconfigWithoutEvents.common?.resourceType || this.channelType,\n\t\t\t},\n\t\t\teditor: editorConfig,\n\t\t};\n\t\tconst configBase64 = btoa(encodeURIComponent(JSON.stringify(iframeConfig)));\n\n\t\tconst params = new URLSearchParams({\n\t\t\tappKey: this.config.appKey,\n\t\t\tconfig: encodeURIComponent(configBase64),\n\t\t});\n\n\t\treturn `${baseURL}#${params.toString()}`;\n\t}\n\n\t/**\n\t * 等待 iframe 自行初始化完成后发送 ready 事件\n\t */\n\tprivate waitForReady(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tconst error = new Error(\"Iframe ready timeout\");\n\t\t\t\tslardar.captureException(error, { source: 'aily-web-sdk', module: 'iframe-ready' });\n\t\t\t\treject(error);\n\t\t\t}, 30000);\n\n\t\t\tconst checkMessage = (event: MessageEvent) => {\n\t\t\t\tif (\n\t\t\t\t\tevent.data?.messageBizId === MESSAGE_BIZ_ID &&\n\t\t\t\t\tevent.data?.type === \"event\" &&\n\t\t\t\t\tevent.data?.eventName === \"ready\"\n\t\t\t\t) {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\twindow.removeEventListener(\"message\", checkMessage);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\twindow.addEventListener(\"message\", checkMessage);\n\t\t});\n\t}\n\n\tprivate setupEventHandlers(): void {\n\t\tconst { events } = this.config;\n\t\tif (!events) return;\n\n\t\tif (events.onReady) {\n\t\t\tthis.messageBridge.onEvent(\"ready\", events.onReady);\n\t\t}\n\n\t\tif (events.onError) {\n\t\t\tthis.messageBridge.onEvent(\"error\", (data: unknown) => {\n\t\t\t\tconst msg = (data as { message?: string })?.message || \"Unknown error\";\n\t\t\t\tevents.onError?.(new Error(msg));\n\t\t\t});\n\t\t}\n\n\t\tif (events.onMessage) {\n\t\t\tthis.messageBridge.onEvent(\"onMessage\", events.onMessage);\n\t\t}\n\n\t\tif (events.onInited) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"inited\",\n\t\t\t\tevents.onInited as (data: unknown) => void,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onInitedWithWelcome) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"initedWithWelcome\",\n\t\t\t\tevents.onInitedWithWelcome,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onClose) {\n\t\t\tthis.messageBridge.onEvent(\"onClose\", events.onClose);\n\t\t}\n\t}\n\n\tprivate reportInitMetrics(initStart: number): void {\n\t\ttry {\n\t\t\tconst cost = performance.now() - initStart;\n\t\t\tslardar.sendEvent({\n\t\t\t\tname: \"cui_init_total\",\n\t\t\t\tmetrics: { cost },\n\t\t\t\tcategories: {\n\t\t\t\t\tarch: \"iframe-static\",\n\t\t\t\t\tappKey: this.config.appKey,\n\t\t\t\t\tchannelType: this.channelType,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch {\n\t\t\t// 性能上报失败不影响功能\n\t\t}\n\t}\n\n\tprivate createChatPanel(): ChatPanel {\n\t\treturn {\n\t\t\tsendMessage: async (data) => {\n\t\t\t\tawait this.messageBridge.send(\"sendMessage\", data);\n\t\t\t},\n\t\t\tclear: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clear\");\n\t\t\t},\n\t\t\tcancelMessage: async (messageItem) => {\n\t\t\t\tawait this.messageBridge.send(\"cancelMessage\", messageItem);\n\t\t\t},\n\t\t\tclearAndStop: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clearAndStop\");\n\t\t\t},\n\t\t\tupdateWelcomeMessage: async () => {\n\t\t\t\tawait this.messageBridge.send(\"updateWelcomeMessage\");\n\t\t\t},\n\t\t\tupdateConfig: async (config) => {\n\t\t\t\tawait this.messageBridge.send(\"updateConfig\", config);\n\t\t\t},\n\t\t\tobserveSkill: async (skillId, name, skillType) => {\n\t\t\t\tawait this.messageBridge.send(\"observeSkill\", {\n\t\t\t\t\tskillId,\n\t\t\t\t\tname,\n\t\t\t\t\tskillType,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetCurrentSkill: async (skill) => {\n\t\t\t\tawait this.messageBridge.send(\"setCurrentSkill\", skill);\n\t\t\t},\n\t\t\tdestroy: async () => {\n\t\t\t\tawait this.destroy();\n\t\t\t},\n\t\t};\n\t}\n}\n","const MOBILE_BREAKPOINT = 768;\n\ntype DeviceType = 'pc' | 'mobile';\ntype DeviceChangeCallback = (device: DeviceType) => void;\n\n/**\n * 设备类型自动检测器\n *\n * 使用 matchMedia + 768px 断点检测设备类型,与 miaoda useIsMobile 逻辑一致。\n * 检测在宿主页面(而非 iframe)中执行,结果通过 postMessage 推送给 iframe。\n */\nexport class DeviceDetector {\n private mediaQuery: MediaQueryList;\n private currentDevice: DeviceType;\n private callback: DeviceChangeCallback | null = null;\n private handleChange: (() => void) | null = null;\n\n constructor() {\n this.mediaQuery = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n this.currentDevice = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n }\n\n getDevice(): DeviceType {\n return this.currentDevice;\n }\n\n observe(callback: DeviceChangeCallback): void {\n this.callback = callback;\n this.handleChange = () => {\n const newDevice: DeviceType = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n if (newDevice !== this.currentDevice) {\n this.currentDevice = newDevice;\n this.callback?.(newDevice);\n }\n };\n this.mediaQuery.addEventListener('change', this.handleChange);\n }\n\n destroy(): void {\n if (this.handleChange) {\n this.mediaQuery.removeEventListener('change', this.handleChange);\n this.handleChange = null;\n }\n this.callback = null;\n }\n}\n","import { MESSAGE_TIMEOUT, ALLOWED_ORIGINS } from './constants';\nimport {\n MESSAGE_BIZ_ID,\n type IframeMessage,\n type IframeRequestMessage,\n type IframeResponseMessage,\n type IframeEventMessage,\n type IframeMessageType,\n} from './types/message';\nimport { slardar } from '@lark-apaas/internal-slardar';\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * MessageBridge handles postMessage communication between parent and iframe\n */\nexport class MessageBridge {\n private iframe: HTMLIFrameElement | null = null;\n private requestId = 0;\n private pendingRequests = new Map<number, PendingRequest>();\n private eventHandlers = new Map<string, ((data: unknown) => void)[]>();\n private targetOrigin: string;\n\n constructor(targetOrigin: string) {\n this.targetOrigin = new URL(targetOrigin).origin;\n this.handleMessage = this.handleMessage.bind(this);\n }\n\n /**\n * Attach to an iframe and start listening for messages\n */\n attach(iframe: HTMLIFrameElement): void {\n this.iframe = iframe;\n window.addEventListener('message', this.handleMessage);\n }\n\n /**\n * Detach from iframe and clean up\n */\n detach(): void {\n window.removeEventListener('message', this.handleMessage);\n this.iframe = null;\n // Clear all pending requests\n this.pendingRequests.forEach(({ reject }) => {\n reject(new Error('MessageBridge detached'));\n });\n this.pendingRequests.clear();\n }\n\n /**\n * Send a message to the iframe and wait for response\n */\n send<T = unknown>(type: IframeMessageType, data?: unknown): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!this.iframe?.contentWindow) {\n reject(new Error('Iframe not attached'));\n return;\n }\n\n this.requestId += 1;\n const id = this.requestId;\n const message: IframeRequestMessage = {\n messageBizId: MESSAGE_BIZ_ID,\n id,\n type,\n data,\n timestamp: Date.now(),\n isRequest: true,\n };\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n const error = new Error(`Message timeout: ${type}`);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', messageType: type });\n reject(error);\n }, MESSAGE_TIMEOUT);\n\n this.pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timer });\n\n this.iframe.contentWindow.postMessage(message, this.targetOrigin);\n });\n }\n\n /**\n * Register an event handler\n */\n onEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n handlers.push(handler);\n this.eventHandlers.set(eventName, handlers);\n }\n\n /**\n * Remove an event handler\n */\n offEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n this.eventHandlers.set(eventName, handlers);\n }\n }\n\n private handleMessage(event: MessageEvent<IframeMessage>): void {\n // Validate origin\n if (!ALLOWED_ORIGINS.includes(event.origin)) {\n return;\n }\n\n const { data } = event;\n\n // Validate message format\n if (data?.messageBizId !== MESSAGE_BIZ_ID) {\n return;\n }\n\n // Handle response messages\n if (this.isResponseMessage(data)) {\n const pending = this.pendingRequests.get(data.id);\n if (pending) {\n clearTimeout(pending.timer);\n this.pendingRequests.delete(data.id);\n\n if (data.error) {\n const error = new Error(data.error.message);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', errorCode: data.error.code });\n pending.reject(error);\n } else {\n pending.resolve(data.data);\n }\n }\n }\n\n // Handle event messages\n if (this.isEventMessage(data)) {\n const handlers = this.eventHandlers.get(data.eventName) || [];\n handlers.forEach((handler) => {\n try {\n handler(data.data);\n } catch {\n // Ignore handler errors\n }\n });\n }\n }\n\n private isResponseMessage(data: IframeMessage): data is IframeResponseMessage {\n return 'isResponse' in data && data.isResponse === true;\n }\n\n private isEventMessage(data: IframeMessage): data is IframeEventMessage {\n return data.type === 'event';\n }\n}\n","import { PARENT_ORIGIN_QUERY_KEY, getAgentIframeBaseURL } from './constants';\nimport { MessageBridge } from './message-bridge';\n\nimport type {\n AgentSDKInitConfig,\n AgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n} from './types/config';\nimport type {\n AgentReadyEventData,\n ParentContextMessageData,\n ParentContextResponseData,\n} from './types/message';\n\n/**\n * AgentIframeManager handles agent iframe creation and lifecycle.\n */\nexport class AgentIframeManager {\n private static readonly WARN_PREFIX = '[aily-web-sdk]';\n private iframe: HTMLIFrameElement | null = null;\n private readonly messageBridge: MessageBridge;\n private readonly config: AgentSDKInitConfig;\n private readonly root: HTMLElement;\n private readonly runtimeCustomContext: AgentSDKRuntimeCustomContext | null;\n private readonly contextVersion: string;\n private initialHandshakeCompleted = false;\n\n constructor(root: HTMLElement, config: AgentSDKInitConfig) {\n this.root = root;\n this.config = config;\n this.runtimeCustomContext = this.resolveRuntimeCustomContext(config);\n this.contextVersion = this.createContextVersion();\n this.messageBridge = new MessageBridge(getAgentIframeBaseURL());\n }\n\n async init(): Promise<AgentSDKInstance> {\n this.iframe = document.createElement('iframe');\n this.iframe.src = this.buildIframeURL();\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.style.border = 'none';\n this.iframe.allow = 'microphone; clipboard-write';\n\n const readyPromise = this.waitForReady();\n this.messageBridge.onEvent('ready', this.handleSubsequentReady);\n this.messageBridge.attach(this.iframe);\n this.root.appendChild(this.iframe);\n\n try {\n const readyData = await readyPromise;\n await this.sendParentContext(readyData);\n } catch (error) {\n this.warn(\n 'Agent SDK initialization encountered a non-blocking error. Initialization will continue without blocking the iframe lifecycle.',\n error\n );\n } finally {\n this.initialHandshakeCompleted = true;\n }\n\n return this.createAgentInstance();\n }\n\n async destroy(): Promise<void> {\n this.messageBridge.offEvent('ready', this.handleSubsequentReady);\n\n try {\n await this.messageBridge.send('destroy');\n } catch {\n // Ignore errors during destroy.\n }\n\n this.messageBridge.detach();\n this.removeIframe();\n this.initialHandshakeCompleted = false;\n }\n\n private buildIframeURL(): string {\n const baseURL = getAgentIframeBaseURL();\n const params = new URLSearchParams({\n channelToken: this.config.channelToken,\n [PARENT_ORIGIN_QUERY_KEY]: window.location.origin,\n });\n\n return `${baseURL}?${params.toString()}`;\n }\n\n private buildParentContext(): ParentContextMessageData {\n const parentContext: ParentContextMessageData = {\n parentOrigin: window.location.origin,\n };\n\n return parentContext;\n }\n\n private waitForReady(): Promise<AgentReadyEventData | undefined> {\n return new Promise((resolve, reject) => {\n const handleReady = (data: unknown) => {\n clearTimeout(timeout);\n this.messageBridge.offEvent('ready', handleReady);\n resolve(this.parseReadyEventData(data));\n };\n\n const timeout = setTimeout(() => {\n this.messageBridge.offEvent('ready', handleReady);\n reject(new Error('Iframe ready timeout'));\n }, 30000);\n\n this.messageBridge.onEvent('ready', handleReady);\n });\n }\n\n private readonly handleSubsequentReady = (data: unknown): void => {\n if (!this.initialHandshakeCompleted) {\n return;\n }\n\n void this.sendParentContext(this.parseReadyEventData(data)).catch(error => {\n this.warn(\n 'Failed to re-send initParentContext after iframe ready event.',\n error\n );\n });\n };\n\n private async sendParentContext(\n readyData?: AgentReadyEventData\n ): Promise<void> {\n const payload = this.buildParentContextForReady(readyData);\n let response: ParentContextResponseData | undefined;\n\n try {\n response = await this.messageBridge.send<ParentContextResponseData>(\n 'initParentContext',\n payload\n );\n } catch (error) {\n this.warn(\n 'Failed to send initParentContext during initialization.',\n error\n );\n return;\n }\n\n if (!this.runtimeCustomContext) {\n return;\n }\n\n if (response?.accepted !== true) {\n this.warn(\n 'Iframe rejected initParentContext custom context. Custom context will be ignored for this initialization.'\n );\n return;\n }\n\n if (\n payload.iframeSessionId &&\n response.iframeSessionId &&\n response.iframeSessionId !== payload.iframeSessionId\n ) {\n this.warn(\n 'Iframe returned mismatched iframeSessionId. Custom context acknowledgement will be ignored.'\n );\n return;\n }\n\n if (\n payload.contextVersion &&\n response.contextVersion &&\n response.contextVersion !== payload.contextVersion\n ) {\n this.warn(\n 'Iframe returned mismatched contextVersion. Custom context acknowledgement will be ignored.'\n );\n }\n }\n\n private buildParentContextForReady(\n readyData?: AgentReadyEventData\n ): ParentContextMessageData {\n const parentContext = this.buildParentContext();\n\n if (!this.runtimeCustomContext) {\n return parentContext;\n }\n\n if (!this.readySupportsRuntimeContext(readyData)) {\n this.warn(\n 'Current iframe version does not support custom context initParentContext protocol. SDK initialization will continue without custom context.'\n );\n return parentContext;\n }\n\n return {\n ...parentContext,\n protocolVersion: 2,\n iframeSessionId: readyData.iframeSessionId,\n contextVersion: this.contextVersion,\n runtimeCustomContext: this.runtimeCustomContext,\n };\n }\n\n private readySupportsRuntimeContext(\n readyData?: AgentReadyEventData\n ): readyData is AgentReadyEventData & {\n protocolVersion: 2;\n iframeSessionId: string;\n needsContext: true;\n } {\n return (\n readyData?.protocolVersion === 2 &&\n Boolean(readyData.iframeSessionId) &&\n readyData.needsContext === true\n );\n }\n\n private parseReadyEventData(data: unknown): AgentReadyEventData | undefined {\n if (!this.isRecord(data)) {\n return undefined;\n }\n\n return data as AgentReadyEventData;\n }\n\n private resolveRuntimeCustomContext(\n config: AgentSDKInitConfig\n ): AgentSDKRuntimeCustomContext | null {\n let customParamsToken: string | undefined;\n if (config.customParamsToken !== undefined) {\n customParamsToken = config.customParamsToken.trim();\n if (!customParamsToken) {\n this.warn(\n 'customParamsToken cannot be empty. SDK initialization will continue without custom context.'\n );\n return null;\n }\n }\n\n if (config.customParams === undefined) {\n if (customParamsToken !== undefined) {\n this.warn(\n 'customParamsToken requires customParams for jwt verification. SDK initialization will continue without custom context.'\n );\n return null;\n }\n\n return null;\n }\n\n if (!this.isRecord(config.customParams)) {\n this.warn(\n 'customParams must be an object. SDK initialization will continue without custom context.'\n );\n return null;\n }\n\n for (const [key, entry] of Object.entries(config.customParams)) {\n if (\n !this.isRecord(entry) ||\n !('value' in entry) ||\n entry.value === undefined\n ) {\n this.warn(\n `customParams.${key} must include value. SDK initialization will continue without custom context.`\n );\n return null;\n }\n\n if (\n 'desc' in entry &&\n entry.desc !== undefined &&\n typeof entry.desc !== 'string'\n ) {\n this.warn(\n `customParams.${key}.desc must be a string. SDK initialization will continue without custom context.`\n );\n return null;\n }\n\n if (!this.isValidCustomParamValue(entry.value)) {\n this.warn(\n `customParams.${key}.value has invalid type. SDK initialization will continue without custom context.`\n );\n return null;\n }\n }\n\n return customParamsToken !== undefined\n ? {\n customParams: config.customParams,\n customParamsToken,\n }\n : {\n customParams: config.customParams,\n };\n }\n\n private isValidCustomParamValue(value: unknown): boolean {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(\n item =>\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean' ||\n this.isRecord(item)\n );\n }\n\n return this.isRecord(value);\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n\n private createContextVersion(): string {\n return `ctx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n private warn(message: string, error?: unknown): void {\n if (error === undefined) {\n console.warn(AgentIframeManager.WARN_PREFIX, message);\n return;\n }\n\n console.warn(AgentIframeManager.WARN_PREFIX, message, error);\n }\n\n private removeIframe(): void {\n if (this.iframe?.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n this.iframe = null;\n }\n\n private createAgentInstance(): AgentSDKInstance {\n return {\n destroy: async () => {\n await this.destroy();\n },\n };\n }\n}\n","/*\n * index.ts\n * Author: perterpon.wang<perterpon.wang@bytedance.com>\n * Create: Tue Feb 10 2026\n */\n\nimport { IframeManager } from \"./iframe-manager\";\nimport { AgentIframeManager } from \"./agent-iframe-manager\";\n\nimport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n\tChatPanel,\n\tWebSDKConfig,\n} from \"./types/config\";\n\n/**\n * Initialize Aily Chat via iframe\n * This is the primary method for initializing the chat panel\n * @param root - Container element for the iframe\n * @param config - Configuration options\n * @returns ChatPanel instance for controlling the chat\n */\nexport async function initAilyChat(\n\troot: HTMLElement,\n\tconfig: WebSDKConfig,\n): Promise<ChatPanel> {\n\tconst manager = new IframeManager(root, config);\n\treturn manager.init();\n}\n\n/**\n * Initialize Agent Chat via iframe\n * @param root - Container element for the iframe\n * @param config - Agent SDK configuration\n * @returns Agent SDK instance for controlling the agent page\n */\nexport async function initAgentChat(\n\troot: HTMLElement,\n\tconfig: AgentSDKInitConfig,\n): Promise<AgentSDKInstance> {\n\tconst manager = new AgentIframeManager(root, config);\n\treturn manager.init();\n}\n\n// Export constants\nexport {\n\tAGENT_IFRAME_BASE_URL,\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetAgentIframeBaseURL,\n\tgetIframeBaseURL,\n\tIFRAME_BASE_URL,\n\tMESSAGE_TIMEOUT,\n} from \"./constants\";\n// Export types\nexport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n\tChatPanel,\n CustomParamEntry,\n CustomParams,\n\tWebSDKCommonConfig,\n\tWebSDKConfig,\n\tWebSDKConversionConfig,\n\tWebSDKEditorConfig,\n\tWebSDKEvents,\n\tWebSDKSkillInfo,\n} from \"./types/config\";\n\n// Export message types\nexport type {\n\tIframeEventMessage,\n\tIframeMessage,\n\tIframeMessageType,\n\tIframeRequestMessage,\n\tIframeResponseMessage,\n} from \"./types/message\";\n"],"mappings":"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","names":["MESSAGE_BIZ_ID","PARENT_ORIGIN_QUERY_KEY","IFRAME_ORIGIN","production","staging","boe","development","CHAT_IFRAME_PATH","AGENT_IFRAME_PATH","IFRAME_BASE_URL","AGENT_IFRAME_BASE_URL","isIframeEnv","env","Boolean","resolveDebugIframeEnv","window","undefined","debugIframeEnv","__DEBUG__","ailyWebSdk","iframeEnv","resolveIframeEnv","hostname","location","includes","getIframeBaseURL","getAgentIframeBaseURL","MESSAGE_TIMEOUT","DEFAULT_CHANNEL_TYPE","DEFAULT_ANONYMOUS_CHANNEL_TYPE","ALLOWED_ORIGINS","slardar","MOBILE_BREAKPOINT","DeviceDetector","mediaQuery","currentDevice","callback","handleChange","window","matchMedia","innerWidth","getDevice","observe","newDevice","addEventListener","destroy","removeEventListener","slardar","MessageBridge","targetOrigin","iframe","requestId","pendingRequests","Map","eventHandlers","URL","origin","handleMessage","bind","attach","window","addEventListener","detach","removeEventListener","forEach","reject","Error","clear","send","type","data","Promise","resolve","contentWindow","id","message","messageBizId","MESSAGE_BIZ_ID","timestamp","Date","now","isRequest","timer","setTimeout","delete","error","slardar","captureException","source","module","messageType","MESSAGE_TIMEOUT","set","postMessage","onEvent","eventName","handler","handlers","get","push","offEvent","index","indexOf","splice","event","ALLOWED_ORIGINS","includes","isResponseMessage","pending","clearTimeout","errorCode","code","isEventMessage","isResponse","IframeManager","root","config","iframe","messageBridge","channelType","deviceDetector","defaultChannel","anonymous","DEFAULT_ANONYMOUS_CHANNEL_TYPE","DEFAULT_CHANNEL_TYPE","common","MessageBridge","getIframeBaseURL","init","initStart","performance","now","device","DeviceDetector","getDevice","document","createElement","src","buildIframeURL","style","width","height","border","allow","appendChild","attach","setupEventHandlers","observe","newDevice","send","waitForReady","reportInitMetrics","createChatPanel","destroy","detach","parentNode","removeChild","baseURL","events","_events","_anonymous","configWithoutEvents","editorConfig","editor","skill","type","builtinType","iframeConfig","resourceType","configBase64","btoa","encodeURIComponent","JSON","stringify","params","URLSearchParams","appKey","toString","Promise","resolve","reject","timeout","setTimeout","error","Error","slardar","captureException","source","module","checkMessage","event","data","messageBizId","MESSAGE_BIZ_ID","eventName","clearTimeout","window","removeEventListener","addEventListener","onReady","onEvent","onError","msg","message","onMessage","onInited","onInitedWithWelcome","onClose","cost","sendEvent","name","metrics","categories","arch","sendMessage","clear","cancelMessage","messageItem","clearAndStop","updateWelcomeMessage","updateConfig","observeSkill","skillId","skillType","setCurrentSkill","AgentIframeManager","root","config","iframe","messageBridge","runtimeCustomContext","contextVersion","initialHandshakeCompleted","handleSubsequentReady","data","sendParentContext","parseReadyEventData","catch","error","warn","resolveRuntimeCustomContext","createContextVersion","MessageBridge","getAgentIframeBaseURL","init","document","createElement","src","buildIframeURL","style","width","height","border","allow","readyPromise","waitForReady","onEvent","attach","appendChild","readyData","createAgentInstance","destroy","offEvent","send","detach","removeIframe","baseURL","params","URLSearchParams","channelToken","PARENT_ORIGIN_QUERY_KEY","window","location","origin","toString","buildParentContext","parentContext","parentOrigin","Promise","resolve","reject","handleReady","clearTimeout","timeout","setTimeout","Error","payload","buildParentContextForReady","response","accepted","iframeSessionId","readySupportsRuntimeContext","protocolVersion","Boolean","needsContext","isRecord","undefined","customParamsToken","trim","customParams","key","entry","Object","entries","value","desc","isValidCustomParamValue","Array","isArray","every","item","Date","now","Math","random","slice","message","console","WARN_PREFIX","parentNode","removeChild","initAilyChat","root","config","manager","IframeManager","init","initAgentChat","AgentIframeManager"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/iframe-manager.ts","../src/device-detector.ts","../src/message-bridge.ts","../src/agent-iframe-manager.ts","../src/index.ts"],"sourcesContent":["/**\n * Constants for Aily Web SDK\n */\n\n/** Message business ID for postMessage identification */\nexport const MESSAGE_BIZ_ID = 'cui-sdk-message' as const;\nexport const PARENT_ORIGIN_QUERY_KEY = '__parentOrigin' as const;\n\n/** Iframe origins by environment */\nexport const IFRAME_ORIGIN: Record<string, string> = {\n production: 'https://aily.feishu.cn',\n staging: 'https://aily.feishu-pre.cn',\n boe: 'https://aily.feishu-boe.cn',\n development: 'http://localhost:3000',\n};\n\n/** Page paths for iframe apps */\nexport const CHAT_IFRAME_PATH = '/cui' as const;\nexport const AGENT_IFRAME_PATH = '/custom_agent/cui' as const;\n\n/** Chat iframe base URLs by environment */\nexport const IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${CHAT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${CHAT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${CHAT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${CHAT_IFRAME_PATH}`,\n};\n\n/** Agent iframe base URLs by environment */\nexport const AGENT_IFRAME_BASE_URL: Record<string, string> = {\n production: `${IFRAME_ORIGIN.production}${AGENT_IFRAME_PATH}`,\n staging: `${IFRAME_ORIGIN.staging}${AGENT_IFRAME_PATH}`,\n boe: `${IFRAME_ORIGIN.boe}${AGENT_IFRAME_PATH}`,\n development: `${IFRAME_ORIGIN.development}${AGENT_IFRAME_PATH}`,\n};\n\ntype IframeEnv = keyof typeof IFRAME_BASE_URL;\n\ninterface AilyWebSdkDebugConfig {\n iframeEnv?: string;\n}\n\ndeclare global {\n interface Window {\n __DEBUG__?: {\n ailyWebSdk?: AilyWebSdkDebugConfig;\n [key: string]: unknown;\n };\n }\n}\n\nfunction isIframeEnv(env?: string): env is IframeEnv {\n return Boolean(env && env in IFRAME_BASE_URL);\n}\n\nfunction resolveDebugIframeEnv(): IframeEnv | undefined {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n const debugIframeEnv = window.__DEBUG__?.ailyWebSdk?.iframeEnv;\n return isIframeEnv(debugIframeEnv) ? debugIframeEnv : undefined;\n}\n\n/**\n * Get iframe base URL based on environment\n */\nfunction resolveIframeEnv(env?: string): IframeEnv {\n if (isIframeEnv(env)) {\n return env;\n }\n\n const debugIframeEnv = resolveDebugIframeEnv();\n if (debugIframeEnv) {\n return debugIframeEnv;\n }\n\n // Auto-detect based on hostname\n // MiaoDa 宿主域名: miaoda.feishu[-env].cn, *.aiforce[-env][-preview].bytedance.net, *.force-pre.feishuapp.net, *.fsapp.kundou.cn, *.aiforce.run, *.aiforce.cloud\n const hostname =\n typeof window !== 'undefined' ? window.location.hostname : '';\n\n if (hostname.includes('aiforce-boe')) {\n return 'boe';\n }\n if (\n hostname.includes('aiforce-pre') ||\n hostname.includes('force-pre.feishuapp.net') ||\n hostname.includes('fsapp.kundou.cn')\n ) {\n return 'staging';\n }\n\n return 'production';\n}\n\nexport function getIframeBaseURL(env?: string): string {\n return IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/**\n * Get agent iframe base URL based on environment\n */\nexport function getAgentIframeBaseURL(env?: string): string {\n return AGENT_IFRAME_BASE_URL[resolveIframeEnv(env)];\n}\n\n/** Timeout for postMessage requests (30 seconds) */\nexport const MESSAGE_TIMEOUT = 30 * 1000;\n\n/** Miaoda 渠道标识默认值(用户可通过 config.common.channelType 覆盖) */\nexport const DEFAULT_CHANNEL_TYPE = 'MIAODA_CUI_SDK';\nexport const DEFAULT_ANONYMOUS_CHANNEL_TYPE = 'MIAODA_ANONYMOUS_CUI_SDK';\n\n/** Allowed origins for postMessage (cui-iframe 的 origin) */\nexport const ALLOWED_ORIGINS = [\n IFRAME_ORIGIN.production,\n IFRAME_ORIGIN.staging,\n IFRAME_ORIGIN.boe,\n 'http://localhost:3000',\n 'http://localhost:5173',\n IFRAME_ORIGIN.development,\n];\n","import {\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetIframeBaseURL,\n\tMESSAGE_BIZ_ID,\n} from \"./constants\";\nimport { slardar } from \"@lark-apaas/internal-slardar\";\nimport { DeviceDetector } from \"./device-detector\";\nimport { MessageBridge } from \"./message-bridge\";\n\nimport type { ChatPanel, WebSDKConfig } from \"./types/config\";\n\n/**\n * IframeManager handles iframe creation and lifecycle\n *\n * iframe 采用自初始化模式:配置通过 URL hash 传入,iframe 加载后自行解析并渲染,\n * 与旧版 copilot iframe 的行为保持一致。宿主通过 postMessage 进行后续操作。\n */\nexport class IframeManager {\n\tprivate iframe: HTMLIFrameElement | null = null;\n\tprivate messageBridge: MessageBridge;\n\tprivate config: WebSDKConfig;\n\tprivate channelType: string;\n\tprivate root: HTMLElement;\n\tprivate deviceDetector: DeviceDetector | null = null;\n\n\tconstructor(root: HTMLElement, config: WebSDKConfig) {\n\t\tthis.root = root;\n\t\tthis.config = config;\n\t\tconst defaultChannel = config.anonymous\n\t\t\t? DEFAULT_ANONYMOUS_CHANNEL_TYPE\n\t\t\t: DEFAULT_CHANNEL_TYPE;\n\t\tthis.channelType = config.common?.channelType || defaultChannel;\n\t\tthis.messageBridge = new MessageBridge(getIframeBaseURL());\n\t}\n\n\t/**\n\t * Initialize the iframe and establish communication\n\t * 配置通过 URL hash 编码传入 iframe,iframe 加载后自行初始化\n\t */\n\tasync init(): Promise<ChatPanel> {\n\t\tconst initStart = performance.now();\n\n\t\t// Auto-detect device if not explicitly provided\n\t\tif (!this.config.device) {\n\t\t\tthis.deviceDetector = new DeviceDetector();\n\t\t\tthis.config.device = this.deviceDetector.getDevice();\n\t\t}\n\n\t\t// Create iframe element\n\t\tthis.iframe = document.createElement(\"iframe\");\n\t\tthis.iframe.src = this.buildIframeURL();\n\t\tthis.iframe.style.width = \"100%\";\n\t\tthis.iframe.style.height = \"100%\";\n\t\tthis.iframe.style.border = \"none\";\n\t\tthis.iframe.allow = \"microphone; clipboard-write\";\n\n\t\t// Attach to DOM\n\t\tthis.root.appendChild(this.iframe);\n\n\t\t// Attach message bridge (开始监听消息)\n\t\tthis.messageBridge.attach(this.iframe);\n\n\t\t// Setup event handlers (在 iframe 初始化完成之前就开始监听,确保不丢失事件)\n\t\tthis.setupEventHandlers();\n\n\t\t// Listen for device changes and push updates to iframe\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.observe((newDevice) => {\n\t\t\t\tthis.messageBridge.send(\"updateConfig\", { device: newDevice });\n\t\t\t});\n\t\t}\n\n\t\t// Wait for iframe to finish initialization (iframe 自行读取 URL 配置并渲染,完成后发送 ready 事件)\n\t\tawait this.waitForReady();\n\n\t\t// 上报 cui_init_total 耗时(iframe 创建 → init 完成)\n\t\tthis.reportInitMetrics(initStart);\n\n\t\t// Return ChatPanel interface\n\t\treturn this.createChatPanel();\n\t}\n\n\t/**\n\t * Destroy the iframe and cleanup\n\t */\n\tasync destroy(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.messageBridge.send(\"destroy\");\n\t\t} catch {\n\t\t\t// Ignore errors during destroy\n\t\t}\n\n\t\tthis.messageBridge.detach();\n\n\t\tif (this.deviceDetector) {\n\t\t\tthis.deviceDetector.destroy();\n\t\t\tthis.deviceDetector = null;\n\t\t}\n\n\t\tif (this.iframe?.parentNode) {\n\t\t\tthis.iframe.parentNode.removeChild(this.iframe);\n\t\t}\n\n\t\tthis.iframe = null;\n\t}\n\n\t/**\n\t * 构建 iframe URL,将配置编码到 hash 中\n\t * 格式: {baseURL}#{params} 其中 config 为 base64(JSON.stringify(configWithoutEvents))\n\t *\n\t * 鉴权说明:SDK 不参与 token 获取/传递。iframe 自行处理飞书登录流程,\n\t * 允许用户在 iframe 中独立登录。匿名渠道跳过登录检查。\n\t */\n\tprivate buildIframeURL(): string {\n\t\tconst baseURL = getIframeBaseURL();\n\n\t\t// 移除 events(函数无法序列化)\n\t\tconst {\n\t\t\tevents: _events,\n\t\t\tanonymous: _anonymous,\n\t\t\t...configWithoutEvents\n\t\t} = this.config;\n\t\t// 注入 channelType/resourceType(SDK 内部控制,不暴露给消费者)\n\t\t// 补全 editor.skill 硬编码字段\n\t\tconst editorConfig = configWithoutEvents.editor?.skill\n\t\t\t? {\n\t\t\t\t\t...configWithoutEvents.editor,\n\t\t\t\t\tskill: {\n\t\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\t\tbuiltinType: \"unspecified\",\n\t\t\t\t\t\t...configWithoutEvents.editor.skill,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: configWithoutEvents.editor;\n\n\t\tconst iframeConfig = {\n\t\t\t...configWithoutEvents,\n\t\t\tcommon: {\n\t\t\t\t...configWithoutEvents.common,\n\t\t\t\tchannelType: this.channelType,\n\t\t\t\tresourceType:\n\t\t\t\t\tconfigWithoutEvents.common?.resourceType || this.channelType,\n\t\t\t},\n\t\t\teditor: editorConfig,\n\t\t};\n\t\tconst configBase64 = btoa(encodeURIComponent(JSON.stringify(iframeConfig)));\n\n\t\tconst params = new URLSearchParams({\n\t\t\tappKey: this.config.appKey,\n\t\t\tconfig: encodeURIComponent(configBase64),\n\t\t});\n\n\t\treturn `${baseURL}#${params.toString()}`;\n\t}\n\n\t/**\n\t * 等待 iframe 自行初始化完成后发送 ready 事件\n\t */\n\tprivate waitForReady(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tconst error = new Error(\"Iframe ready timeout\");\n\t\t\t\tslardar.captureException(error, { source: 'aily-web-sdk', module: 'iframe-ready' });\n\t\t\t\treject(error);\n\t\t\t}, 30000);\n\n\t\t\tconst checkMessage = (event: MessageEvent) => {\n\t\t\t\tif (\n\t\t\t\t\tevent.data?.messageBizId === MESSAGE_BIZ_ID &&\n\t\t\t\t\tevent.data?.type === \"event\" &&\n\t\t\t\t\tevent.data?.eventName === \"ready\"\n\t\t\t\t) {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\twindow.removeEventListener(\"message\", checkMessage);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\twindow.addEventListener(\"message\", checkMessage);\n\t\t});\n\t}\n\n\tprivate setupEventHandlers(): void {\n\t\tconst { events } = this.config;\n\t\tif (!events) return;\n\n\t\tif (events.onReady) {\n\t\t\tthis.messageBridge.onEvent(\"ready\", events.onReady);\n\t\t}\n\n\t\tif (events.onError) {\n\t\t\tthis.messageBridge.onEvent(\"error\", (data: unknown) => {\n\t\t\t\tconst msg = (data as { message?: string })?.message || \"Unknown error\";\n\t\t\t\tevents.onError?.(new Error(msg));\n\t\t\t});\n\t\t}\n\n\t\tif (events.onMessage) {\n\t\t\tthis.messageBridge.onEvent(\"onMessage\", events.onMessage);\n\t\t}\n\n\t\tif (events.onInited) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"inited\",\n\t\t\t\tevents.onInited as (data: unknown) => void,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onInitedWithWelcome) {\n\t\t\tthis.messageBridge.onEvent(\n\t\t\t\t\"initedWithWelcome\",\n\t\t\t\tevents.onInitedWithWelcome,\n\t\t\t);\n\t\t}\n\n\t\tif (events.onClose) {\n\t\t\tthis.messageBridge.onEvent(\"onClose\", events.onClose);\n\t\t}\n\t}\n\n\tprivate reportInitMetrics(initStart: number): void {\n\t\ttry {\n\t\t\tconst cost = performance.now() - initStart;\n\t\t\tslardar.sendEvent({\n\t\t\t\tname: \"cui_init_total\",\n\t\t\t\tmetrics: { cost },\n\t\t\t\tcategories: {\n\t\t\t\t\tarch: \"iframe-static\",\n\t\t\t\t\tappKey: this.config.appKey,\n\t\t\t\t\tchannelType: this.channelType,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch {\n\t\t\t// 性能上报失败不影响功能\n\t\t}\n\t}\n\n\tprivate createChatPanel(): ChatPanel {\n\t\treturn {\n\t\t\tsendMessage: async (data) => {\n\t\t\t\tawait this.messageBridge.send(\"sendMessage\", data);\n\t\t\t},\n\t\t\tclear: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clear\");\n\t\t\t},\n\t\t\tcancelMessage: async (messageItem) => {\n\t\t\t\tawait this.messageBridge.send(\"cancelMessage\", messageItem);\n\t\t\t},\n\t\t\tclearAndStop: async () => {\n\t\t\t\tawait this.messageBridge.send(\"clearAndStop\");\n\t\t\t},\n\t\t\tupdateWelcomeMessage: async () => {\n\t\t\t\tawait this.messageBridge.send(\"updateWelcomeMessage\");\n\t\t\t},\n\t\t\tupdateConfig: async (config) => {\n\t\t\t\tawait this.messageBridge.send(\"updateConfig\", config);\n\t\t\t},\n\t\t\tobserveSkill: async (skillId, name, skillType) => {\n\t\t\t\tawait this.messageBridge.send(\"observeSkill\", {\n\t\t\t\t\tskillId,\n\t\t\t\t\tname,\n\t\t\t\t\tskillType,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetCurrentSkill: async (skill) => {\n\t\t\t\tawait this.messageBridge.send(\"setCurrentSkill\", skill);\n\t\t\t},\n\t\t\tdestroy: async () => {\n\t\t\t\tawait this.destroy();\n\t\t\t},\n\t\t};\n\t}\n}\n","const MOBILE_BREAKPOINT = 768;\n\ntype DeviceType = 'pc' | 'mobile';\ntype DeviceChangeCallback = (device: DeviceType) => void;\n\n/**\n * 设备类型自动检测器\n *\n * 使用 matchMedia + 768px 断点检测设备类型,与 miaoda useIsMobile 逻辑一致。\n * 检测在宿主页面(而非 iframe)中执行,结果通过 postMessage 推送给 iframe。\n */\nexport class DeviceDetector {\n private mediaQuery: MediaQueryList;\n private currentDevice: DeviceType;\n private callback: DeviceChangeCallback | null = null;\n private handleChange: (() => void) | null = null;\n\n constructor() {\n this.mediaQuery = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n this.currentDevice = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n }\n\n getDevice(): DeviceType {\n return this.currentDevice;\n }\n\n observe(callback: DeviceChangeCallback): void {\n this.callback = callback;\n this.handleChange = () => {\n const newDevice: DeviceType = window.innerWidth < MOBILE_BREAKPOINT ? 'mobile' : 'pc';\n if (newDevice !== this.currentDevice) {\n this.currentDevice = newDevice;\n this.callback?.(newDevice);\n }\n };\n this.mediaQuery.addEventListener('change', this.handleChange);\n }\n\n destroy(): void {\n if (this.handleChange) {\n this.mediaQuery.removeEventListener('change', this.handleChange);\n this.handleChange = null;\n }\n this.callback = null;\n }\n}\n","import { MESSAGE_TIMEOUT, ALLOWED_ORIGINS } from './constants';\nimport {\n MESSAGE_BIZ_ID,\n type IframeMessage,\n type IframeRequestMessage,\n type IframeResponseMessage,\n type IframeEventMessage,\n type IframeMessageType,\n} from './types/message';\nimport { slardar } from '@lark-apaas/internal-slardar';\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * MessageBridge handles postMessage communication between parent and iframe\n */\nexport class MessageBridge {\n private iframe: HTMLIFrameElement | null = null;\n private requestId = 0;\n private pendingRequests = new Map<number, PendingRequest>();\n private eventHandlers = new Map<string, ((data: unknown) => void)[]>();\n private targetOrigin: string;\n\n constructor(targetOrigin: string) {\n this.targetOrigin = new URL(targetOrigin).origin;\n this.handleMessage = this.handleMessage.bind(this);\n }\n\n /**\n * Attach to an iframe and start listening for messages\n */\n attach(iframe: HTMLIFrameElement): void {\n this.iframe = iframe;\n window.addEventListener('message', this.handleMessage);\n }\n\n /**\n * Detach from iframe and clean up\n */\n detach(): void {\n window.removeEventListener('message', this.handleMessage);\n this.iframe = null;\n // Clear all pending requests\n this.pendingRequests.forEach(({ reject }) => {\n reject(new Error('MessageBridge detached'));\n });\n this.pendingRequests.clear();\n }\n\n /**\n * Send a message to the iframe and wait for response\n */\n send<T = unknown>(type: IframeMessageType, data?: unknown): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!this.iframe?.contentWindow) {\n reject(new Error('Iframe not attached'));\n return;\n }\n\n this.requestId += 1;\n const id = this.requestId;\n const message: IframeRequestMessage = {\n messageBizId: MESSAGE_BIZ_ID,\n id,\n type,\n data,\n timestamp: Date.now(),\n isRequest: true,\n };\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n const error = new Error(`Message timeout: ${type}`);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', messageType: type });\n reject(error);\n }, MESSAGE_TIMEOUT);\n\n this.pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timer });\n\n this.iframe.contentWindow.postMessage(message, this.targetOrigin);\n });\n }\n\n /**\n * Register an event handler\n */\n onEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n handlers.push(handler);\n this.eventHandlers.set(eventName, handlers);\n }\n\n /**\n * Remove an event handler\n */\n offEvent(eventName: string, handler: (data: unknown) => void): void {\n const handlers = this.eventHandlers.get(eventName) || [];\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n this.eventHandlers.set(eventName, handlers);\n }\n }\n\n private handleMessage(event: MessageEvent<IframeMessage>): void {\n // Validate origin\n if (!ALLOWED_ORIGINS.includes(event.origin)) {\n return;\n }\n\n const { data } = event;\n\n // Validate message format\n if (data?.messageBizId !== MESSAGE_BIZ_ID) {\n return;\n }\n\n // Handle response messages\n if (this.isResponseMessage(data)) {\n const pending = this.pendingRequests.get(data.id);\n if (pending) {\n clearTimeout(pending.timer);\n this.pendingRequests.delete(data.id);\n\n if (data.error) {\n const error = new Error(data.error.message);\n slardar.captureException(error, { source: 'aily-web-sdk', module: 'message-bridge', errorCode: data.error.code });\n pending.reject(error);\n } else {\n pending.resolve(data.data);\n }\n }\n }\n\n // Handle event messages\n if (this.isEventMessage(data)) {\n const handlers = this.eventHandlers.get(data.eventName) || [];\n handlers.forEach((handler) => {\n try {\n handler(data.data);\n } catch {\n // Ignore handler errors\n }\n });\n }\n }\n\n private isResponseMessage(data: IframeMessage): data is IframeResponseMessage {\n return 'isResponse' in data && data.isResponse === true;\n }\n\n private isEventMessage(data: IframeMessage): data is IframeEventMessage {\n return data.type === 'event';\n }\n}\n","import { PARENT_ORIGIN_QUERY_KEY, getAgentIframeBaseURL } from './constants';\nimport { MessageBridge } from './message-bridge';\n\nimport type {\n AgentSDKInitConfig,\n AgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n} from './types/config';\nimport type {\n AgentReadyEventData,\n ParentContextMessageData,\n ParentContextResponseData,\n} from './types/message';\n\ntype RuntimeCustomContextPayload = Partial<AgentSDKRuntimeCustomContext> & {\n customParams?: unknown;\n customParamsToken?: string;\n};\n\n/**\n * AgentIframeManager handles agent iframe creation and lifecycle.\n */\nexport class AgentIframeManager {\n private static readonly WARN_PREFIX = '[aily-web-sdk]';\n private iframe: HTMLIFrameElement | null = null;\n private readonly messageBridge: MessageBridge;\n private readonly config: AgentSDKInitConfig;\n private readonly root: HTMLElement;\n private readonly runtimeCustomContext: RuntimeCustomContextPayload | null;\n private readonly contextVersion: string;\n private initialHandshakeCompleted = false;\n\n constructor(root: HTMLElement, config: AgentSDKInitConfig) {\n this.root = root;\n this.config = config;\n this.runtimeCustomContext = this.resolveRuntimeCustomContext(config);\n this.contextVersion = this.createContextVersion();\n this.messageBridge = new MessageBridge(getAgentIframeBaseURL());\n }\n\n async init(): Promise<AgentSDKInstance> {\n this.iframe = document.createElement('iframe');\n this.iframe.src = this.buildIframeURL();\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.style.border = 'none';\n this.iframe.allow = 'microphone; clipboard-write';\n\n const readyPromise = this.waitForReady();\n this.messageBridge.onEvent('ready', this.handleSubsequentReady);\n this.messageBridge.attach(this.iframe);\n this.root.appendChild(this.iframe);\n\n try {\n const readyData = await readyPromise;\n await this.sendParentContext(readyData);\n } catch (error) {\n this.warn(\n 'Agent SDK initialization encountered a non-blocking error. Initialization will continue without blocking the iframe lifecycle.',\n error\n );\n } finally {\n this.initialHandshakeCompleted = true;\n }\n\n return this.createAgentInstance();\n }\n\n async destroy(): Promise<void> {\n this.messageBridge.offEvent('ready', this.handleSubsequentReady);\n\n try {\n await this.messageBridge.send('destroy');\n } catch {\n // Ignore errors during destroy.\n }\n\n this.messageBridge.detach();\n this.removeIframe();\n this.initialHandshakeCompleted = false;\n }\n\n private buildIframeURL(): string {\n const baseURL = getAgentIframeBaseURL();\n const params = new URLSearchParams({\n channelToken: this.config.channelToken,\n [PARENT_ORIGIN_QUERY_KEY]: window.location.origin,\n });\n\n return `${baseURL}?${params.toString()}`;\n }\n\n private buildParentContext(): ParentContextMessageData {\n const parentContext: ParentContextMessageData = {\n parentOrigin: window.location.origin,\n };\n\n return parentContext;\n }\n\n private waitForReady(): Promise<AgentReadyEventData | undefined> {\n return new Promise((resolve, reject) => {\n const handleReady = (data: unknown) => {\n clearTimeout(timeout);\n this.messageBridge.offEvent('ready', handleReady);\n resolve(this.parseReadyEventData(data));\n };\n\n const timeout = setTimeout(() => {\n this.messageBridge.offEvent('ready', handleReady);\n reject(new Error('Iframe ready timeout'));\n }, 30000);\n\n this.messageBridge.onEvent('ready', handleReady);\n });\n }\n\n private readonly handleSubsequentReady = (data: unknown): void => {\n if (!this.initialHandshakeCompleted) {\n return;\n }\n\n void this.sendParentContext(this.parseReadyEventData(data)).catch(error => {\n this.warn(\n 'Failed to re-send initParentContext after iframe ready event.',\n error\n );\n });\n };\n\n private async sendParentContext(\n readyData?: AgentReadyEventData\n ): Promise<void> {\n const payload = this.buildParentContextForReady(readyData);\n let response: ParentContextResponseData | undefined;\n\n try {\n response = await this.messageBridge.send<ParentContextResponseData>(\n 'initParentContext',\n payload\n );\n } catch (error) {\n this.warn(\n 'Failed to send initParentContext during initialization.',\n error\n );\n return;\n }\n\n if (!this.runtimeCustomContext) {\n return;\n }\n\n if (response?.accepted !== true) {\n this.warn(\n 'Iframe rejected initParentContext custom context. Custom context will be ignored for this initialization.'\n );\n return;\n }\n\n if (\n payload.iframeSessionId &&\n response.iframeSessionId &&\n response.iframeSessionId !== payload.iframeSessionId\n ) {\n this.warn(\n 'Iframe returned mismatched iframeSessionId. Custom context acknowledgement will be ignored.'\n );\n return;\n }\n\n if (\n payload.contextVersion &&\n response.contextVersion &&\n response.contextVersion !== payload.contextVersion\n ) {\n this.warn(\n 'Iframe returned mismatched contextVersion. Custom context acknowledgement will be ignored.'\n );\n }\n }\n\n private buildParentContextForReady(\n readyData?: AgentReadyEventData\n ): ParentContextMessageData {\n const parentContext = this.buildParentContext();\n\n if (!this.runtimeCustomContext) {\n return parentContext;\n }\n\n if (!this.readySupportsRuntimeContext(readyData)) {\n this.warn(\n 'Current iframe version does not support custom context initParentContext protocol. SDK initialization will continue without custom context.'\n );\n return parentContext;\n }\n\n return {\n ...parentContext,\n protocolVersion: 2,\n iframeSessionId: readyData.iframeSessionId,\n contextVersion: this.contextVersion,\n runtimeCustomContext: this.runtimeCustomContext,\n };\n }\n\n private readySupportsRuntimeContext(\n readyData?: AgentReadyEventData\n ): readyData is AgentReadyEventData & {\n protocolVersion: 2;\n iframeSessionId: string;\n needsContext: true;\n } {\n return (\n readyData?.protocolVersion === 2 &&\n Boolean(readyData.iframeSessionId) &&\n readyData.needsContext === true\n );\n }\n\n private parseReadyEventData(data: unknown): AgentReadyEventData | undefined {\n if (!this.isRecord(data)) {\n return undefined;\n }\n\n return data as AgentReadyEventData;\n }\n\n private resolveRuntimeCustomContext(\n config: AgentSDKInitConfig\n ): RuntimeCustomContextPayload | null {\n let customParamsToken: string | undefined;\n if (config.customParamsToken !== undefined) {\n customParamsToken = config.customParamsToken.trim();\n if (!customParamsToken) {\n this.warn(\n 'customParamsToken cannot be empty. SDK initialization will continue without custom context.'\n );\n }\n }\n\n if (config.customParams === undefined) {\n if (customParamsToken !== undefined) {\n this.warn(\n 'customParamsToken requires customParams for jwt verification. SDK initialization will continue without custom context.'\n );\n return {\n customParamsToken,\n };\n }\n\n return null;\n }\n\n if (!this.isRecord(config.customParams)) {\n this.warn(\n 'customParams must be an object. SDK initialization will continue without custom context.'\n );\n return {\n customParams: config.customParams,\n ...(customParamsToken !== undefined ? { customParamsToken } : {}),\n };\n }\n\n for (const [key, entry] of Object.entries(config.customParams)) {\n if (\n !this.isRecord(entry) ||\n !('value' in entry) ||\n entry.value === undefined\n ) {\n this.warn(\n `customParams.${key} must include value. SDK initialization will continue without custom context.`\n );\n continue;\n }\n\n if (\n 'desc' in entry &&\n entry.desc !== undefined &&\n typeof entry.desc !== 'string'\n ) {\n this.warn(\n `customParams.${key}.desc must be a string. SDK initialization will continue without custom context.`\n );\n }\n\n if ('value' in entry && !this.isValidCustomParamValue(entry.value)) {\n this.warn(\n `customParams.${key}.value has invalid type. SDK initialization will continue without custom context.`\n );\n }\n }\n\n return {\n customParams: config.customParams,\n ...(customParamsToken !== undefined ? { customParamsToken } : {}),\n };\n }\n\n private isValidCustomParamValue(value: unknown): boolean {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(\n item =>\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean' ||\n this.isRecord(item)\n );\n }\n\n return this.isRecord(value);\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n\n private createContextVersion(): string {\n return `ctx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n private warn(message: string, error?: unknown): void {\n if (error === undefined) {\n console.warn(AgentIframeManager.WARN_PREFIX, message);\n return;\n }\n\n console.warn(AgentIframeManager.WARN_PREFIX, message, error);\n }\n\n private removeIframe(): void {\n if (this.iframe?.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n this.iframe = null;\n }\n\n private createAgentInstance(): AgentSDKInstance {\n return {\n destroy: async () => {\n await this.destroy();\n },\n };\n }\n}\n","/*\n * index.ts\n * Author: perterpon.wang<perterpon.wang@bytedance.com>\n * Create: Tue Feb 10 2026\n */\n\nimport { IframeManager } from \"./iframe-manager\";\nimport { AgentIframeManager } from \"./agent-iframe-manager\";\n\nimport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n\tChatPanel,\n\tWebSDKConfig,\n} from \"./types/config\";\n\n/**\n * Initialize Aily Chat via iframe\n * This is the primary method for initializing the chat panel\n * @param root - Container element for the iframe\n * @param config - Configuration options\n * @returns ChatPanel instance for controlling the chat\n */\nexport async function initAilyChat(\n\troot: HTMLElement,\n\tconfig: WebSDKConfig,\n): Promise<ChatPanel> {\n\tconst manager = new IframeManager(root, config);\n\treturn manager.init();\n}\n\n/**\n * Initialize Agent Chat via iframe\n * @param root - Container element for the iframe\n * @param config - Agent SDK configuration\n * @returns Agent SDK instance for controlling the agent page\n */\nexport async function initAgentChat(\n\troot: HTMLElement,\n\tconfig: AgentSDKInitConfig,\n): Promise<AgentSDKInstance> {\n\tconst manager = new AgentIframeManager(root, config);\n\treturn manager.init();\n}\n\n// Export constants\nexport {\n\tAGENT_IFRAME_BASE_URL,\n\tDEFAULT_ANONYMOUS_CHANNEL_TYPE,\n\tDEFAULT_CHANNEL_TYPE,\n\tgetAgentIframeBaseURL,\n\tgetIframeBaseURL,\n\tIFRAME_BASE_URL,\n\tMESSAGE_TIMEOUT,\n} from \"./constants\";\n// Export types\nexport type {\n\tAgentSDKInitConfig,\n\tAgentSDKInstance,\n AgentSDKRuntimeCustomContext,\n\tChatPanel,\n CustomParamEntry,\n CustomParams,\n\tWebSDKCommonConfig,\n\tWebSDKConfig,\n\tWebSDKConversionConfig,\n\tWebSDKEditorConfig,\n\tWebSDKEvents,\n\tWebSDKSkillInfo,\n} from \"./types/config\";\n\n// Export message types\nexport type {\n\tIframeEventMessage,\n\tIframeMessage,\n\tIframeMessageType,\n\tIframeRequestMessage,\n\tIframeResponseMessage,\n} from \"./types/message\";\n"],"mappings":"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","names":["MESSAGE_BIZ_ID","PARENT_ORIGIN_QUERY_KEY","IFRAME_ORIGIN","production","staging","boe","development","CHAT_IFRAME_PATH","AGENT_IFRAME_PATH","IFRAME_BASE_URL","AGENT_IFRAME_BASE_URL","isIframeEnv","env","Boolean","resolveDebugIframeEnv","window","undefined","debugIframeEnv","__DEBUG__","ailyWebSdk","iframeEnv","resolveIframeEnv","hostname","location","includes","getIframeBaseURL","getAgentIframeBaseURL","MESSAGE_TIMEOUT","DEFAULT_CHANNEL_TYPE","DEFAULT_ANONYMOUS_CHANNEL_TYPE","ALLOWED_ORIGINS","slardar","MOBILE_BREAKPOINT","DeviceDetector","mediaQuery","currentDevice","callback","handleChange","window","matchMedia","innerWidth","getDevice","observe","newDevice","addEventListener","destroy","removeEventListener","slardar","MessageBridge","targetOrigin","iframe","requestId","pendingRequests","Map","eventHandlers","URL","origin","handleMessage","bind","attach","window","addEventListener","detach","removeEventListener","forEach","reject","Error","clear","send","type","data","Promise","resolve","contentWindow","id","message","messageBizId","MESSAGE_BIZ_ID","timestamp","Date","now","isRequest","timer","setTimeout","delete","error","slardar","captureException","source","module","messageType","MESSAGE_TIMEOUT","set","postMessage","onEvent","eventName","handler","handlers","get","push","offEvent","index","indexOf","splice","event","ALLOWED_ORIGINS","includes","isResponseMessage","pending","clearTimeout","errorCode","code","isEventMessage","isResponse","IframeManager","root","config","iframe","messageBridge","channelType","deviceDetector","defaultChannel","anonymous","DEFAULT_ANONYMOUS_CHANNEL_TYPE","DEFAULT_CHANNEL_TYPE","common","MessageBridge","getIframeBaseURL","init","initStart","performance","now","device","DeviceDetector","getDevice","document","createElement","src","buildIframeURL","style","width","height","border","allow","appendChild","attach","setupEventHandlers","observe","newDevice","send","waitForReady","reportInitMetrics","createChatPanel","destroy","detach","parentNode","removeChild","baseURL","events","_events","_anonymous","configWithoutEvents","editorConfig","editor","skill","type","builtinType","iframeConfig","resourceType","configBase64","btoa","encodeURIComponent","JSON","stringify","params","URLSearchParams","appKey","toString","Promise","resolve","reject","timeout","setTimeout","error","Error","slardar","captureException","source","module","checkMessage","event","data","messageBizId","MESSAGE_BIZ_ID","eventName","clearTimeout","window","removeEventListener","addEventListener","onReady","onEvent","onError","msg","message","onMessage","onInited","onInitedWithWelcome","onClose","cost","sendEvent","name","metrics","categories","arch","sendMessage","clear","cancelMessage","messageItem","clearAndStop","updateWelcomeMessage","updateConfig","observeSkill","skillId","skillType","setCurrentSkill","AgentIframeManager","root","config","iframe","messageBridge","runtimeCustomContext","contextVersion","initialHandshakeCompleted","handleSubsequentReady","data","sendParentContext","parseReadyEventData","catch","error","warn","resolveRuntimeCustomContext","createContextVersion","MessageBridge","getAgentIframeBaseURL","init","document","createElement","src","buildIframeURL","style","width","height","border","allow","readyPromise","waitForReady","onEvent","attach","appendChild","readyData","createAgentInstance","destroy","offEvent","send","detach","removeIframe","baseURL","params","URLSearchParams","channelToken","PARENT_ORIGIN_QUERY_KEY","window","location","origin","toString","buildParentContext","parentContext","parentOrigin","Promise","resolve","reject","handleReady","clearTimeout","timeout","setTimeout","Error","payload","buildParentContextForReady","response","accepted","iframeSessionId","readySupportsRuntimeContext","protocolVersion","Boolean","needsContext","isRecord","undefined","customParamsToken","trim","customParams","key","entry","Object","entries","value","desc","isValidCustomParamValue","Array","isArray","every","item","Date","now","Math","random","slice","message","console","WARN_PREFIX","parentNode","removeChild","initAilyChat","root","config","manager","IframeManager","init","initAgentChat","AgentIframeManager"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/aily-web-sdk",
3
- "version": "0.0.12-alpha.2",
3
+ "version": "0.0.12-alpha.3",
4
4
  "description": "Aily Web SDK - iframe-based chat panel integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",