@webless/agent 0.7.0 → 0.7.2

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/embed.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/embed/mount.tsx","../src/embed/preview-build.ts","../src/embed/AgentWidget.tsx","../src/embed/manifest.ts","../src/embed/iife-bootstrap.ts"],"sourcesContent":["import { createRoot, type Root } from \"react-dom/client\";\nimport { closeAgentPanel, openAgentPanel } from \"./controller\";\nimport { AgentWidget } from \"./AgentWidget\";\nimport {\n normalizeAgentTagManifest,\n type AgentTagManifest,\n type NormalizedAgentTagManifest,\n} from \"./manifest\";\n\nexport type AgentRuntimeHandle = {\n customerId: string;\n manifest: NormalizedAgentTagManifest;\n host: HTMLElement;\n root: Root;\n open: () => void;\n close: () => void;\n unmount: () => void;\n};\n\nconst mountedHandles = new Map<string, AgentRuntimeHandle>();\nlet latestCustomerId: string | null = null;\n\nfunction resolveMountHost(manifest: NormalizedAgentTagManifest, script?: HTMLScriptElement | null) {\n const strategy = manifest.mount.strategy ?? \"body\";\n\n if (strategy === \"script-parent\" && script?.parentElement instanceof HTMLElement) {\n return script.parentElement;\n }\n\n if (strategy === \"selector\" && manifest.mount.selector) {\n const target = document.querySelector(manifest.mount.selector);\n if (target instanceof HTMLElement) return target;\n }\n\n return document.body;\n}\n\nfunction createHost(customerId: string) {\n const host = document.createElement(\"div\");\n host.dataset.weblessAgentCustomerId = customerId;\n host.setAttribute(\"data-webless-agent\", customerId);\n return host;\n}\n\nexport function mountAgent(input: {\n manifest: AgentTagManifest;\n script?: HTMLScriptElement | null;\n}): AgentRuntimeHandle {\n const manifest = normalizeAgentTagManifest(input.manifest);\n const existing = mountedHandles.get(manifest.customerId);\n if (existing) {\n return existing;\n }\n\n const mountTarget = resolveMountHost(manifest, input.script ?? null);\n const host = createHost(manifest.customerId);\n mountTarget.append(host);\n\n const root = createRoot(host);\n root.render(<AgentWidget manifest={manifest} />);\n\n const handle: AgentRuntimeHandle = {\n customerId: manifest.customerId,\n manifest,\n host,\n root,\n open: () => {\n openAgentPanel(manifest.customerId);\n },\n close: () => {\n closeAgentPanel(manifest.customerId);\n },\n unmount: () => {\n root.unmount();\n host.remove();\n mountedHandles.delete(manifest.customerId);\n if (latestCustomerId === manifest.customerId) {\n latestCustomerId = null;\n }\n },\n };\n\n mountedHandles.set(manifest.customerId, handle);\n latestCustomerId = manifest.customerId;\n return handle;\n}\n\nexport function unmountAgent(customerId?: string) {\n const id = customerId ?? latestCustomerId;\n if (!id) return false;\n const handle = mountedHandles.get(id);\n if (!handle) return false;\n handle.unmount();\n return true;\n}\n\nexport function getMountedAgent(customerId?: string) {\n if (customerId) return mountedHandles.get(customerId) ?? null;\n if (latestCustomerId) return mountedHandles.get(latestCustomerId) ?? null;\n return mountedHandles.values().next().value ?? null;\n}\n\nexport function bootstrapAgent(manifest: AgentTagManifest, script?: HTMLScriptElement | null) {\n return mountAgent({ manifest, script });\n}\n","const PREVIEW_BUILD_ID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;\n\nexport function readUnpublishedPreviewBuildId(href?: string) {\n const source =\n href ?? (typeof window === \"undefined\" ? undefined : window.location.href);\n if (!source) return undefined;\n\n try {\n const buildId = new URL(source).searchParams.get(\"v\")?.trim();\n return buildId && PREVIEW_BUILD_ID_PATTERN.test(buildId)\n ? buildId\n : undefined;\n } catch {\n return undefined;\n }\n}\n","import { AgentWidget as WeblessAgentWidget } from \"../react/components/AgentWidget\";\nimport type { NormalizedAgentTagManifest } from \"./manifest\";\nimport { readUnpublishedPreviewBuildId } from \"./preview-build\";\n\nexport function AgentWidget({\n manifest,\n}: {\n manifest: NormalizedAgentTagManifest;\n}) {\n const defaultCollapsed = manifest.version !== \"unpublished\";\n return (\n <WeblessAgentWidget\n indexId={manifest.indexId}\n customerId={manifest.customerId}\n version={manifest.version}\n runtimeOrigin={manifest.runtimeOrigin}\n previewBuildId={\n manifest.version === \"unpublished\"\n ? readUnpublishedPreviewBuildId()\n : undefined\n }\n placement={manifest.placement}\n pageShift={manifest.pageShift}\n colorScheme={manifest.colorScheme}\n branding={manifest.branding}\n analytics={manifest.analytics}\n defaultCollapsed={defaultCollapsed}\n registerPanelController\n />\n );\n}\n","import {\n DEFAULT_RUNTIME_ORIGIN,\n resolveAgentRuntimeConfig,\n} from \"../runtime/config\";\nimport type { AgentIndexVersion } from \"../runtime/types\";\nimport {\n DEFAULT_AGENT_PLACEMENT,\n normalizeAgentPlacement,\n type AgentPlacementConfig,\n} from \"../react/placement\";\nimport type { AgentColorScheme } from \"../react/types/conversation\";\n\nexport type { AgentPlacementConfig };\nexport type AgentMountStrategy = \"body\" | \"selector\" | \"script-parent\";\n\nexport type AgentTabVariant = AgentPlacementConfig[\"variant\"];\nexport type AgentTabSide = AgentPlacementConfig[\"side\"];\n\nexport type AgentBrandingConfig = {\n agentName?: string;\n tabLabel?: string;\n tabIconUrl?: string;\n logoUrl?: string;\n greeting?: string;\n composerPlaceholder?: string;\n poweredByLabel?: string;\n disclaimer?: string | null;\n answerReceipt?: boolean;\n readAloud?: boolean;\n fontFamily?: string;\n colors?: {\n primary?: string;\n primarySoft?: string;\n primaryForeground?: string;\n surface?: string;\n surfaceMuted?: string;\n text?: string;\n textMuted?: string;\n border?: string;\n };\n};\n\nexport type AgentAnalyticsConfig = {\n companyIndex: string;\n eventUrl: string;\n trackingConsent: boolean;\n};\n\nexport type AgentTagManifest = {\n customerId: string;\n indexId: string;\n runtimeOrigin?: string;\n version?: AgentIndexVersion;\n mount?: {\n selector?: string;\n strategy?: AgentMountStrategy;\n };\n placement?: Partial<AgentPlacementConfig>;\n pageShift?: boolean;\n colorScheme?: AgentColorScheme;\n branding?: AgentBrandingConfig;\n analytics?: AgentAnalyticsConfig;\n};\n\nexport { DEFAULT_AGENT_PLACEMENT, normalizeAgentPlacement };\n\nexport function normalizeAgentTagManifest(manifest: AgentTagManifest) {\n const indexId = manifest.indexId.trim();\n if (!indexId) {\n throw new Error(\"Agent manifest requires indexId.\");\n }\n\n const customerId = manifest.customerId.trim();\n if (!customerId) {\n throw new Error(\"Agent manifest requires customerId.\");\n }\n\n const version = manifest.version ?? \"published\";\n if (version !== \"published\" && version !== \"unpublished\") {\n throw new Error(\"Agent manifest version must be published or unpublished.\");\n }\n\n const colorScheme = manifest.colorScheme ?? \"auto\";\n if (\n colorScheme !== \"auto\" &&\n colorScheme !== \"light\" &&\n colorScheme !== \"dark\"\n ) {\n throw new Error(\"Agent manifest colorScheme must be auto, light, or dark.\");\n }\n\n const runtime = resolveAgentRuntimeConfig({\n indexId,\n version,\n runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN,\n });\n const branding = normalizeAgentBranding(manifest.branding);\n const analytics = normalizeAgentAnalytics(manifest.analytics);\n\n return {\n customerId,\n indexId,\n runtimeOrigin: runtime.origin,\n version,\n mount: {\n selector: manifest.mount?.selector?.trim(),\n strategy: manifest.mount?.strategy ?? \"body\",\n },\n placement: normalizeAgentPlacement(manifest.placement),\n pageShift: manifest.pageShift ?? true,\n colorScheme,\n ...(branding ? { branding } : {}),\n ...(analytics ? { analytics } : {}),\n };\n}\n\nfunction normalizeAgentAnalytics(\n analytics: AgentAnalyticsConfig | undefined\n): AgentAnalyticsConfig | undefined {\n if (!analytics) return undefined;\n const companyIndex = analytics.companyIndex?.trim() ?? \"\";\n const eventUrl = analytics.eventUrl?.trim() ?? \"\";\n if (!companyIndex || !eventUrl) return undefined;\n try {\n const parsed = new URL(eventUrl);\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n return undefined;\n }\n } catch {\n return undefined;\n }\n return {\n companyIndex,\n eventUrl,\n trackingConsent: analytics.trackingConsent === true,\n };\n}\n\nfunction normalizeOptionalValue(value: string | undefined) {\n const normalized = value?.trim();\n return normalized || undefined;\n}\n\nfunction normalizeAgentBranding(\n branding: AgentBrandingConfig | undefined\n): AgentBrandingConfig | undefined {\n if (!branding) return undefined;\n\n const colors = branding.colors\n ? Object.fromEntries(\n Object.entries(branding.colors).flatMap(([key, value]) => {\n const normalized = normalizeOptionalValue(value);\n return normalized ? [[key, normalized]] : [];\n })\n )\n : undefined;\n const normalized = {\n agentName: normalizeOptionalValue(branding.agentName),\n tabLabel: normalizeOptionalValue(branding.tabLabel),\n tabIconUrl: normalizeOptionalValue(branding.tabIconUrl),\n logoUrl: normalizeOptionalValue(branding.logoUrl),\n greeting: normalizeOptionalValue(branding.greeting),\n composerPlaceholder: normalizeOptionalValue(branding.composerPlaceholder),\n poweredByLabel: normalizeOptionalValue(branding.poweredByLabel),\n disclaimer:\n branding.disclaimer === null\n ? null\n : normalizeOptionalValue(branding.disclaimer),\n answerReceipt: branding.answerReceipt === true ? true : undefined,\n readAloud: branding.readAloud === true ? true : undefined,\n fontFamily: normalizeOptionalValue(branding.fontFamily),\n colors:\n colors && Object.keys(colors).length > 0\n ? (colors as NonNullable<AgentBrandingConfig[\"colors\"]>)\n : undefined,\n };\n\n return Object.values(normalized).some((value) => value !== undefined)\n ? normalized\n : undefined;\n}\n\nexport type NormalizedAgentTagManifest = ReturnType<\n typeof normalizeAgentTagManifest\n>;\n","import {\n getMountedAgent,\n mountAgent,\n unmountAgent,\n} from \"./mount\";\nimport type { AgentTagManifest } from \"./manifest\";\n\ndeclare global {\n interface Window {\n WeblessAgent?: WeblessAgentPublicApi;\n }\n}\n\nexport type WeblessAgentPublicApi = {\n mount: (options?: Partial<AgentTagManifest>) => ReturnType<typeof mountAgent>;\n unmount: (customerId?: string) => boolean;\n open: (customerId?: string) => void;\n close: (customerId?: string) => void;\n get: (customerId?: string) => ReturnType<typeof getMountedAgent>;\n};\n\nexport function createWeblessAgentPublicApi(manifest: AgentTagManifest): WeblessAgentPublicApi {\n const script = document.currentScript instanceof HTMLScriptElement ? document.currentScript : null;\n\n function mount(options: Partial<AgentTagManifest> = {}) {\n return mountAgent({\n manifest: {\n ...manifest,\n ...options,\n customerId: manifest.customerId,\n },\n script,\n });\n }\n\n function unmount(customerId?: string) {\n return unmountAgent(customerId ?? manifest.customerId);\n }\n\n function open(customerId?: string) {\n getMountedAgent(customerId ?? manifest.customerId)?.open();\n }\n\n function close(customerId?: string) {\n getMountedAgent(customerId ?? manifest.customerId)?.close();\n }\n\n function get(customerId?: string) {\n return getMountedAgent(customerId ?? manifest.customerId);\n }\n\n const api: WeblessAgentPublicApi = {\n mount,\n unmount,\n open,\n close,\n get,\n };\n\n window.WeblessAgent = api;\n\n void (async () => {\n try {\n mount();\n } catch (error) {\n console.error(\"[Webless] Agent mount failed\", error);\n }\n })();\n\n return api;\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,kBAA6B;;;ACAtC,IAAM,2BACJ;AAEK,SAAS,8BAA8B,MAAe;AAC3D,QAAM,SACJ,SAAS,OAAO,WAAW,cAAc,SAAY,OAAO,SAAS;AACvE,MAAI,CAAC,OAAQ,QAAO;AAEpB,MAAI;AACF,UAAM,UAAU,IAAI,IAAI,MAAM,EAAE,aAAa,IAAI,GAAG,GAAG,KAAK;AAC5D,WAAO,WAAW,yBAAyB,KAAK,OAAO,IACnD,UACA;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACLI;AAPG,SAASA,aAAY;AAAA,EAC1B;AACF,GAEG;AACD,QAAM,mBAAmB,SAAS,YAAY;AAC9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,SAAS;AAAA,MAClB,YAAY,SAAS;AAAA,MACrB,SAAS,SAAS;AAAA,MAClB,eAAe,SAAS;AAAA,MACxB,gBACE,SAAS,YAAY,gBACjB,8BAA8B,IAC9B;AAAA,MAEN,WAAW,SAAS;AAAA,MACpB,WAAW,SAAS;AAAA,MACpB,aAAa,SAAS;AAAA,MACtB,UAAU,SAAS;AAAA,MACnB,WAAW,SAAS;AAAA,MACpB;AAAA,MACA,yBAAuB;AAAA;AAAA,EACzB;AAEJ;;;ACoCO,SAAS,0BAA0B,UAA4B;AACpE,QAAM,UAAU,SAAS,QAAQ,KAAK;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,QAAM,aAAa,SAAS,WAAW,KAAK;AAC5C,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AAEA,QAAM,UAAU,SAAS,WAAW;AACpC,MAAI,YAAY,eAAe,YAAY,eAAe;AACxD,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,QAAM,cAAc,SAAS,eAAe;AAC5C,MACE,gBAAgB,UAChB,gBAAgB,WAChB,gBAAgB,QAChB;AACA,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,QAAM,UAAU,0BAA0B;AAAA,IACxC;AAAA,IACA;AAAA,IACA,eAAe,SAAS,eAAe,KAAK,KAAK;AAAA,EACnD,CAAC;AACD,QAAM,WAAW,uBAAuB,SAAS,QAAQ;AACzD,QAAM,YAAY,wBAAwB,SAAS,SAAS;AAE5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAe,QAAQ;AAAA,IACvB;AAAA,IACA,OAAO;AAAA,MACL,UAAU,SAAS,OAAO,UAAU,KAAK;AAAA,MACzC,UAAU,SAAS,OAAO,YAAY;AAAA,IACxC;AAAA,IACA,WAAW,wBAAwB,SAAS,SAAS;AAAA,IACrD,WAAW,SAAS,aAAa;AAAA,IACjC;AAAA,IACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,EACnC;AACF;AAEA,SAAS,wBACP,WACkC;AAClC,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,eAAe,UAAU,cAAc,KAAK,KAAK;AACvD,QAAM,WAAW,UAAU,UAAU,KAAK,KAAK;AAC/C,MAAI,CAAC,gBAAgB,CAAC,SAAU,QAAO;AACvC,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,QAAI,OAAO,aAAa,YAAY,OAAO,aAAa,SAAS;AAC/D,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,iBAAiB,UAAU,oBAAoB;AAAA,EACjD;AACF;AAEA,SAAS,uBAAuB,OAA2B;AACzD,QAAM,aAAa,OAAO,KAAK;AAC/B,SAAO,cAAc;AACvB;AAEA,SAAS,uBACP,UACiC;AACjC,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,SAAS,SAAS,SACpB,OAAO;AAAA,IACL,OAAO,QAAQ,SAAS,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACxD,YAAMC,cAAa,uBAAuB,KAAK;AAC/C,aAAOA,cAAa,CAAC,CAAC,KAAKA,WAAU,CAAC,IAAI,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH,IACA;AACJ,QAAM,aAAa;AAAA,IACjB,WAAW,uBAAuB,SAAS,SAAS;AAAA,IACpD,UAAU,uBAAuB,SAAS,QAAQ;AAAA,IAClD,YAAY,uBAAuB,SAAS,UAAU;AAAA,IACtD,SAAS,uBAAuB,SAAS,OAAO;AAAA,IAChD,UAAU,uBAAuB,SAAS,QAAQ;AAAA,IAClD,qBAAqB,uBAAuB,SAAS,mBAAmB;AAAA,IACxE,gBAAgB,uBAAuB,SAAS,cAAc;AAAA,IAC9D,YACE,SAAS,eAAe,OACpB,OACA,uBAAuB,SAAS,UAAU;AAAA,IAChD,eAAe,SAAS,kBAAkB,OAAO,OAAO;AAAA,IACxD,WAAW,SAAS,cAAc,OAAO,OAAO;AAAA,IAChD,YAAY,uBAAuB,SAAS,UAAU;AAAA,IACtD,QACE,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,IAClC,SACD;AAAA,EACR;AAEA,SAAO,OAAO,OAAO,UAAU,EAAE,KAAK,CAAC,UAAU,UAAU,MAAS,IAChE,aACA;AACN;;;AHzHc,gBAAAC,YAAA;AAxCd,IAAM,iBAAiB,oBAAI,IAAgC;AAC3D,IAAI,mBAAkC;AAEtC,SAAS,iBAAiB,UAAsC,QAAmC;AACjG,QAAM,WAAW,SAAS,MAAM,YAAY;AAE5C,MAAI,aAAa,mBAAmB,QAAQ,yBAAyB,aAAa;AAChF,WAAO,OAAO;AAAA,EAChB;AAEA,MAAI,aAAa,cAAc,SAAS,MAAM,UAAU;AACtD,UAAM,SAAS,SAAS,cAAc,SAAS,MAAM,QAAQ;AAC7D,QAAI,kBAAkB,YAAa,QAAO;AAAA,EAC5C;AAEA,SAAO,SAAS;AAClB;AAEA,SAAS,WAAW,YAAoB;AACtC,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,QAAQ,yBAAyB;AACtC,OAAK,aAAa,sBAAsB,UAAU;AAClD,SAAO;AACT;AAEO,SAAS,WAAW,OAGJ;AACrB,QAAM,WAAW,0BAA0B,MAAM,QAAQ;AACzD,QAAM,WAAW,eAAe,IAAI,SAAS,UAAU;AACvD,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,iBAAiB,UAAU,MAAM,UAAU,IAAI;AACnE,QAAM,OAAO,WAAW,SAAS,UAAU;AAC3C,cAAY,OAAO,IAAI;AAEvB,QAAM,OAAO,WAAW,IAAI;AAC5B,OAAK,OAAO,gBAAAA,KAACC,cAAA,EAAY,UAAoB,CAAE;AAE/C,QAAM,SAA6B;AAAA,IACjC,YAAY,SAAS;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,MAAM;AACV,qBAAe,SAAS,UAAU;AAAA,IACpC;AAAA,IACA,OAAO,MAAM;AACX,sBAAgB,SAAS,UAAU;AAAA,IACrC;AAAA,IACA,SAAS,MAAM;AACb,WAAK,QAAQ;AACb,WAAK,OAAO;AACZ,qBAAe,OAAO,SAAS,UAAU;AACzC,UAAI,qBAAqB,SAAS,YAAY;AAC5C,2BAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,IAAI,SAAS,YAAY,MAAM;AAC9C,qBAAmB,SAAS;AAC5B,SAAO;AACT;AAEO,SAAS,aAAa,YAAqB;AAChD,QAAM,KAAK,cAAc;AACzB,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,SAAS,eAAe,IAAI,EAAE;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,QAAQ;AACf,SAAO;AACT;AAEO,SAAS,gBAAgB,YAAqB;AACnD,MAAI,WAAY,QAAO,eAAe,IAAI,UAAU,KAAK;AACzD,MAAI,iBAAkB,QAAO,eAAe,IAAI,gBAAgB,KAAK;AACrE,SAAO,eAAe,OAAO,EAAE,KAAK,EAAE,SAAS;AACjD;AAEO,SAAS,eAAe,UAA4B,QAAmC;AAC5F,SAAO,WAAW,EAAE,UAAU,OAAO,CAAC;AACxC;;;AInFO,SAAS,4BAA4B,UAAmD;AAC7F,QAAM,SAAS,SAAS,yBAAyB,oBAAoB,SAAS,gBAAgB;AAE9F,WAAS,MAAM,UAAqC,CAAC,GAAG;AACtD,WAAO,WAAW;AAAA,MAChB,UAAU;AAAA,QACR,GAAG;AAAA,QACH,GAAG;AAAA,QACH,YAAY,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,QAAQ,YAAqB;AACpC,WAAO,aAAa,cAAc,SAAS,UAAU;AAAA,EACvD;AAEA,WAAS,KAAK,YAAqB;AACjC,oBAAgB,cAAc,SAAS,UAAU,GAAG,KAAK;AAAA,EAC3D;AAEA,WAAS,MAAM,YAAqB;AAClC,oBAAgB,cAAc,SAAS,UAAU,GAAG,MAAM;AAAA,EAC5D;AAEA,WAAS,IAAI,YAAqB;AAChC,WAAO,gBAAgB,cAAc,SAAS,UAAU;AAAA,EAC1D;AAEA,QAAM,MAA6B;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,eAAe;AAEtB,QAAM,YAAY;AAChB,QAAI;AACF,YAAM;AAAA,IACR,SAAS,OAAO;AACd,cAAQ,MAAM,gCAAgC,KAAK;AAAA,IACrD;AAAA,EACF,GAAG;AAEH,SAAO;AACT;","names":["AgentWidget","normalized","jsx","AgentWidget"]}
1
+ {"version":3,"sources":["../src/embed/mount.tsx","../src/embed/preview-build.ts","../src/embed/AgentWidget.tsx","../src/embed/manifest.ts","../src/embed/iife-bootstrap.ts"],"sourcesContent":["import { createRoot, type Root } from \"react-dom/client\";\nimport { closeAgentPanel, openAgentPanel } from \"./controller\";\nimport { AgentWidget } from \"./AgentWidget\";\nimport {\n normalizeAgentTagManifest,\n type AgentTagManifest,\n type NormalizedAgentTagManifest,\n} from \"./manifest\";\n\nexport type AgentRuntimeHandle = {\n customerId: string;\n manifest: NormalizedAgentTagManifest;\n host: HTMLElement;\n root: Root;\n open: () => void;\n close: () => void;\n unmount: () => void;\n};\n\nconst mountedHandles = new Map<string, AgentRuntimeHandle>();\nlet latestCustomerId: string | null = null;\n\nfunction resolveMountHost(manifest: NormalizedAgentTagManifest, script?: HTMLScriptElement | null) {\n const strategy = manifest.mount.strategy ?? \"body\";\n\n if (strategy === \"script-parent\" && script?.parentElement instanceof HTMLElement) {\n return script.parentElement;\n }\n\n if (strategy === \"selector\" && manifest.mount.selector) {\n const target = document.querySelector(manifest.mount.selector);\n if (target instanceof HTMLElement) return target;\n }\n\n return document.body;\n}\n\nfunction createHost(customerId: string) {\n const host = document.createElement(\"div\");\n host.dataset.weblessAgentCustomerId = customerId;\n host.setAttribute(\"data-webless-agent\", customerId);\n return host;\n}\n\nexport function mountAgent(input: {\n manifest: AgentTagManifest;\n script?: HTMLScriptElement | null;\n}): AgentRuntimeHandle {\n const manifest = normalizeAgentTagManifest(input.manifest);\n const existing = mountedHandles.get(manifest.customerId);\n if (existing) {\n return existing;\n }\n\n const mountTarget = resolveMountHost(manifest, input.script ?? null);\n const host = createHost(manifest.customerId);\n mountTarget.append(host);\n\n const root = createRoot(host);\n root.render(<AgentWidget manifest={manifest} />);\n\n const handle: AgentRuntimeHandle = {\n customerId: manifest.customerId,\n manifest,\n host,\n root,\n open: () => {\n openAgentPanel(manifest.customerId);\n },\n close: () => {\n closeAgentPanel(manifest.customerId);\n },\n unmount: () => {\n root.unmount();\n host.remove();\n mountedHandles.delete(manifest.customerId);\n if (latestCustomerId === manifest.customerId) {\n latestCustomerId = null;\n }\n },\n };\n\n mountedHandles.set(manifest.customerId, handle);\n latestCustomerId = manifest.customerId;\n return handle;\n}\n\nexport function unmountAgent(customerId?: string) {\n const id = customerId ?? latestCustomerId;\n if (!id) return false;\n const handle = mountedHandles.get(id);\n if (!handle) return false;\n handle.unmount();\n return true;\n}\n\nexport function getMountedAgent(customerId?: string) {\n if (customerId) return mountedHandles.get(customerId) ?? null;\n if (latestCustomerId) return mountedHandles.get(latestCustomerId) ?? null;\n return mountedHandles.values().next().value ?? null;\n}\n\nexport function bootstrapAgent(manifest: AgentTagManifest, script?: HTMLScriptElement | null) {\n return mountAgent({ manifest, script });\n}\n","const PREVIEW_BUILD_ID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;\n\nexport function readUnpublishedPreviewBuildId(href?: string) {\n const source =\n href ?? (typeof window === \"undefined\" ? undefined : window.location.href);\n if (!source) return undefined;\n\n try {\n const buildId = new URL(source).searchParams.get(\"v\")?.trim();\n return buildId && PREVIEW_BUILD_ID_PATTERN.test(buildId)\n ? buildId\n : undefined;\n } catch {\n return undefined;\n }\n}\n","import { AgentWidget as WeblessAgentWidget } from \"../react/components/AgentWidget\";\nimport type { NormalizedAgentTagManifest } from \"./manifest\";\nimport { readUnpublishedPreviewBuildId } from \"./preview-build\";\n\nexport function AgentWidget({\n manifest,\n}: {\n manifest: NormalizedAgentTagManifest;\n}) {\n const defaultCollapsed = manifest.version !== \"unpublished\";\n return (\n <WeblessAgentWidget\n indexId={manifest.indexId}\n customerId={manifest.customerId}\n version={manifest.version}\n runtimeOrigin={manifest.runtimeOrigin}\n previewBuildId={\n manifest.version === \"unpublished\"\n ? readUnpublishedPreviewBuildId()\n : undefined\n }\n placement={manifest.placement}\n pageShift={manifest.pageShift}\n colorScheme={manifest.colorScheme}\n branding={manifest.branding}\n analytics={manifest.analytics}\n defaultCollapsed={defaultCollapsed}\n registerPanelController\n />\n );\n}\n","import {\n DEFAULT_RUNTIME_ORIGIN,\n resolveAgentRuntimeConfig,\n} from \"../runtime/config\";\nimport type { AgentIndexVersion } from \"../runtime/types\";\nimport {\n DEFAULT_AGENT_PLACEMENT,\n normalizeAgentPlacement,\n type AgentPlacementConfig,\n} from \"../react/placement\";\nimport type { AgentColorScheme } from \"../react/types/conversation\";\n\nexport type { AgentPlacementConfig };\nexport type AgentMountStrategy = \"body\" | \"selector\" | \"script-parent\";\n\nexport type AgentTabVariant = AgentPlacementConfig[\"variant\"];\nexport type AgentTabSide = AgentPlacementConfig[\"side\"];\n\nexport type AgentBrandingConfig = {\n agentName?: string;\n tabLabel?: string;\n tabIconUrl?: string;\n logoUrl?: string;\n greeting?: string;\n composerPlaceholder?: string;\n poweredByLabel?: string;\n disclaimer?: string | null;\n disclaimerLink?: string | null;\n answerReceipt?: boolean;\n readAloud?: boolean;\n fontFamily?: string;\n colors?: {\n primary?: string;\n primarySoft?: string;\n primaryForeground?: string;\n surface?: string;\n surfaceMuted?: string;\n text?: string;\n textMuted?: string;\n border?: string;\n };\n};\n\nexport type AgentAnalyticsConfig = {\n companyIndex: string;\n eventUrl: string;\n trackingConsent: boolean;\n};\n\nexport type AgentTagManifest = {\n customerId: string;\n indexId: string;\n runtimeOrigin?: string;\n version?: AgentIndexVersion;\n mount?: {\n selector?: string;\n strategy?: AgentMountStrategy;\n };\n placement?: Partial<AgentPlacementConfig>;\n pageShift?: boolean;\n colorScheme?: AgentColorScheme;\n branding?: AgentBrandingConfig;\n analytics?: AgentAnalyticsConfig;\n};\n\nexport { DEFAULT_AGENT_PLACEMENT, normalizeAgentPlacement };\n\nexport function normalizeAgentTagManifest(manifest: AgentTagManifest) {\n const indexId = manifest.indexId.trim();\n if (!indexId) {\n throw new Error(\"Agent manifest requires indexId.\");\n }\n\n const customerId = manifest.customerId.trim();\n if (!customerId) {\n throw new Error(\"Agent manifest requires customerId.\");\n }\n\n const version = manifest.version ?? \"published\";\n if (version !== \"published\" && version !== \"unpublished\") {\n throw new Error(\"Agent manifest version must be published or unpublished.\");\n }\n\n const colorScheme = manifest.colorScheme ?? \"auto\";\n if (\n colorScheme !== \"auto\" &&\n colorScheme !== \"light\" &&\n colorScheme !== \"dark\"\n ) {\n throw new Error(\"Agent manifest colorScheme must be auto, light, or dark.\");\n }\n\n const runtime = resolveAgentRuntimeConfig({\n indexId,\n version,\n runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN,\n });\n const branding = normalizeAgentBranding(manifest.branding);\n const analytics = normalizeAgentAnalytics(manifest.analytics);\n\n return {\n customerId,\n indexId,\n runtimeOrigin: runtime.origin,\n version,\n mount: {\n selector: manifest.mount?.selector?.trim(),\n strategy: manifest.mount?.strategy ?? \"body\",\n },\n placement: normalizeAgentPlacement(manifest.placement),\n pageShift: manifest.pageShift ?? true,\n colorScheme,\n ...(branding ? { branding } : {}),\n ...(analytics ? { analytics } : {}),\n };\n}\n\nfunction normalizeAgentAnalytics(\n analytics: AgentAnalyticsConfig | undefined\n): AgentAnalyticsConfig | undefined {\n if (!analytics) return undefined;\n const companyIndex = analytics.companyIndex?.trim() ?? \"\";\n const eventUrl = analytics.eventUrl?.trim() ?? \"\";\n if (!companyIndex || !eventUrl) return undefined;\n try {\n const parsed = new URL(eventUrl);\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n return undefined;\n }\n } catch {\n return undefined;\n }\n return {\n companyIndex,\n eventUrl,\n trackingConsent: analytics.trackingConsent === true,\n };\n}\n\nfunction normalizeOptionalValue(value: string | undefined) {\n const normalized = value?.trim();\n return normalized || undefined;\n}\n\nfunction normalizeOptionalHttpUrl(value: string | null | undefined) {\n if (value === null) return null;\n const normalized = value?.trim();\n if (!normalized) return undefined;\n try {\n const url = new URL(normalized);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return undefined;\n }\n return normalized;\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeAgentBranding(\n branding: AgentBrandingConfig | undefined\n): AgentBrandingConfig | undefined {\n if (!branding) return undefined;\n\n const colors = branding.colors\n ? Object.fromEntries(\n Object.entries(branding.colors).flatMap(([key, value]) => {\n const normalized = normalizeOptionalValue(value);\n return normalized ? [[key, normalized]] : [];\n })\n )\n : undefined;\n const normalized = {\n agentName: normalizeOptionalValue(branding.agentName),\n tabLabel: normalizeOptionalValue(branding.tabLabel),\n tabIconUrl: normalizeOptionalValue(branding.tabIconUrl),\n logoUrl: normalizeOptionalValue(branding.logoUrl),\n greeting: normalizeOptionalValue(branding.greeting),\n composerPlaceholder: normalizeOptionalValue(branding.composerPlaceholder),\n poweredByLabel: normalizeOptionalValue(branding.poweredByLabel),\n disclaimer:\n branding.disclaimer === null\n ? null\n : normalizeOptionalValue(branding.disclaimer),\n disclaimerLink: normalizeOptionalHttpUrl(branding.disclaimerLink),\n answerReceipt: branding.answerReceipt === true ? true : undefined,\n readAloud: branding.readAloud === true ? true : undefined,\n fontFamily: normalizeOptionalValue(branding.fontFamily),\n colors:\n colors && Object.keys(colors).length > 0\n ? (colors as NonNullable<AgentBrandingConfig[\"colors\"]>)\n : undefined,\n };\n\n return Object.values(normalized).some((value) => value !== undefined)\n ? normalized\n : undefined;\n}\n\nexport type NormalizedAgentTagManifest = ReturnType<\n typeof normalizeAgentTagManifest\n>;\n","import {\n getMountedAgent,\n mountAgent,\n unmountAgent,\n} from \"./mount\";\nimport type { AgentTagManifest } from \"./manifest\";\n\ndeclare global {\n interface Window {\n WeblessAgent?: WeblessAgentPublicApi;\n }\n}\n\nexport type WeblessAgentPublicApi = {\n mount: (options?: Partial<AgentTagManifest>) => ReturnType<typeof mountAgent>;\n unmount: (customerId?: string) => boolean;\n open: (customerId?: string) => void;\n close: (customerId?: string) => void;\n get: (customerId?: string) => ReturnType<typeof getMountedAgent>;\n};\n\nexport function createWeblessAgentPublicApi(manifest: AgentTagManifest): WeblessAgentPublicApi {\n const script = document.currentScript instanceof HTMLScriptElement ? document.currentScript : null;\n\n function mount(options: Partial<AgentTagManifest> = {}) {\n return mountAgent({\n manifest: {\n ...manifest,\n ...options,\n customerId: manifest.customerId,\n },\n script,\n });\n }\n\n function unmount(customerId?: string) {\n return unmountAgent(customerId ?? manifest.customerId);\n }\n\n function open(customerId?: string) {\n getMountedAgent(customerId ?? manifest.customerId)?.open();\n }\n\n function close(customerId?: string) {\n getMountedAgent(customerId ?? manifest.customerId)?.close();\n }\n\n function get(customerId?: string) {\n return getMountedAgent(customerId ?? manifest.customerId);\n }\n\n const api: WeblessAgentPublicApi = {\n mount,\n unmount,\n open,\n close,\n get,\n };\n\n window.WeblessAgent = api;\n\n void (async () => {\n try {\n mount();\n } catch (error) {\n console.error(\"[Webless] Agent mount failed\", error);\n }\n })();\n\n return api;\n}\n"],"mappings":"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","names":["AgentWidget","normalized","jsx","AgentWidget"]}
@@ -359,6 +359,7 @@ type AgentBrandingConfig = {
359
359
  composerPlaceholder?: string;
360
360
  poweredByLabel?: string;
361
361
  disclaimer?: string | null;
362
+ disclaimerLink?: string | null;
362
363
  answerReceipt?: boolean;
363
364
  readAloud?: boolean;
364
365
  fontFamily?: string;
@@ -359,6 +359,7 @@ type AgentBrandingConfig = {
359
359
  composerPlaceholder?: string;
360
360
  poweredByLabel?: string;
361
361
  disclaimer?: string | null;
362
+ disclaimerLink?: string | null;
362
363
  answerReceipt?: boolean;
363
364
  readAloud?: boolean;
364
365
  fontFamily?: string;
package/dist/react.cjs CHANGED
@@ -4514,6 +4514,126 @@ function toSpeechText(text) {
4514
4514
  function isSpeechSupported() {
4515
4515
  return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
4516
4516
  }
4517
+ function stopSpeech() {
4518
+ if (!isSpeechSupported()) return;
4519
+ window.speechSynthesis.cancel();
4520
+ }
4521
+ var speechInterruptListeners = /* @__PURE__ */ new Set();
4522
+ var pageListenersAttached = false;
4523
+ var lastPathname = "";
4524
+ var originalPushState = null;
4525
+ var originalReplaceState = null;
4526
+ var patchedPushState = null;
4527
+ var patchedReplaceState = null;
4528
+ function currentPathname() {
4529
+ return window.location.pathname;
4530
+ }
4531
+ function notifySpeechInterrupts() {
4532
+ if (speechInterruptListeners.size === 0) return;
4533
+ stopSpeech();
4534
+ for (const listener of speechInterruptListeners) {
4535
+ listener();
4536
+ }
4537
+ }
4538
+ function interruptIfPathChanged(nextPath) {
4539
+ if (nextPath === lastPathname) return;
4540
+ lastPathname = nextPath;
4541
+ notifySpeechInterrupts();
4542
+ }
4543
+ function patchHistoryMethod(original) {
4544
+ return function patched(data, unused, url) {
4545
+ const result = original.call(this, data, unused, url);
4546
+ interruptIfPathChanged(currentPathname());
4547
+ return result;
4548
+ };
4549
+ }
4550
+ function historyMethodState(name) {
4551
+ return name === "pushState" ? {
4552
+ original: originalPushState,
4553
+ patched: patchedPushState,
4554
+ set(original, patched) {
4555
+ originalPushState = original;
4556
+ patchedPushState = patched;
4557
+ }
4558
+ } : {
4559
+ original: originalReplaceState,
4560
+ patched: patchedReplaceState,
4561
+ set(original, patched) {
4562
+ originalReplaceState = original;
4563
+ patchedReplaceState = patched;
4564
+ }
4565
+ };
4566
+ }
4567
+ function patchHistoryNamed(name) {
4568
+ const state = historyMethodState(name);
4569
+ const current = history[name];
4570
+ if (state.patched && current === state.patched) return;
4571
+ const patched = patchHistoryMethod(current);
4572
+ state.set(current, patched);
4573
+ history[name] = patched;
4574
+ }
4575
+ function restoreHistoryMethod(name) {
4576
+ const state = historyMethodState(name);
4577
+ if (!state.patched || !state.original || typeof history === "undefined") {
4578
+ return false;
4579
+ }
4580
+ if (history[name] !== state.patched) return false;
4581
+ history[name] = state.original;
4582
+ state.set(null, null);
4583
+ return true;
4584
+ }
4585
+ function handlePageHide() {
4586
+ notifySpeechInterrupts();
4587
+ }
4588
+ function handlePopState() {
4589
+ interruptIfPathChanged(currentPathname());
4590
+ }
4591
+ function handleVisibilityChange() {
4592
+ if (document.visibilityState === "hidden") {
4593
+ notifySpeechInterrupts();
4594
+ }
4595
+ }
4596
+ function attachPageListeners() {
4597
+ if (pageListenersAttached || typeof window === "undefined") return;
4598
+ pageListenersAttached = true;
4599
+ window.addEventListener("pagehide", handlePageHide);
4600
+ window.addEventListener("popstate", handlePopState);
4601
+ document.addEventListener("visibilitychange", handleVisibilityChange);
4602
+ }
4603
+ function detachPageListeners() {
4604
+ if (!pageListenersAttached || typeof window === "undefined") return;
4605
+ window.removeEventListener("pagehide", handlePageHide);
4606
+ window.removeEventListener("popstate", handlePopState);
4607
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
4608
+ pageListenersAttached = false;
4609
+ }
4610
+ function ensureSpeechInterruptsPatched() {
4611
+ if (typeof window === "undefined") return;
4612
+ lastPathname = currentPathname();
4613
+ patchHistoryNamed("pushState");
4614
+ patchHistoryNamed("replaceState");
4615
+ attachPageListeners();
4616
+ }
4617
+ function teardownSpeechInterrupts() {
4618
+ detachPageListeners();
4619
+ restoreHistoryMethod("pushState");
4620
+ restoreHistoryMethod("replaceState");
4621
+ if (!patchedPushState && !patchedReplaceState) {
4622
+ lastPathname = "";
4623
+ }
4624
+ }
4625
+ function subscribeSpeechInterrupts(onInterrupt) {
4626
+ if (typeof window === "undefined") return () => {
4627
+ };
4628
+ ensureSpeechInterruptsPatched();
4629
+ speechInterruptListeners.add(onInterrupt);
4630
+ return () => {
4631
+ speechInterruptListeners.delete(onInterrupt);
4632
+ if (speechInterruptListeners.size === 0) {
4633
+ teardownSpeechInterrupts();
4634
+ }
4635
+ };
4636
+ }
4517
4637
 
4518
4638
  // src/react/components/MessageActions/MessageActions.tsx
4519
4639
  var import_jsx_runtime7 = require("react/jsx-runtime");
@@ -4769,15 +4889,20 @@ function MessageActions({
4769
4889
  const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
4770
4890
  const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
4771
4891
  const [speaking, setSpeaking] = (0, import_react11.useState)(false);
4892
+ const [speechSupported, setSpeechSupported] = (0, import_react11.useState)(null);
4772
4893
  const copyTimerRef = (0, import_react11.useRef)(null);
4773
4894
  const menuRef = (0, import_react11.useRef)(null);
4774
4895
  const portaledMenuRef = (0, import_react11.useRef)(null);
4775
4896
  const moreButtonRef = (0, import_react11.useRef)(null);
4776
4897
  const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
4777
4898
  const resolvedSpeechText = speechText ?? toSpeechText(copyText);
4778
- const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
4779
- const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
4780
4899
  const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
4900
+ const readAloudEligible = Boolean(readAloud && resolvedSpeechText);
4901
+ const canReadAloud = readAloudEligible && speechSupported === true;
4902
+ const showMenu = canOpenReceipt || (speechSupported === null ? readAloudEligible : canReadAloud);
4903
+ (0, import_react11.useLayoutEffect)(() => {
4904
+ setSpeechSupported(isSpeechSupported());
4905
+ }, []);
4781
4906
  (0, import_react11.useLayoutEffect)(() => {
4782
4907
  if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
4783
4908
  setMenuPosition(null);
@@ -4795,17 +4920,16 @@ function MessageActions({
4795
4920
  })
4796
4921
  );
4797
4922
  }, [menuOpen, menuPortalRoot]);
4798
- (0, import_react11.useEffect)(
4799
- () => () => {
4923
+ (0, import_react11.useEffect)(() => {
4924
+ const unsubscribe = subscribeSpeechInterrupts(() => setSpeaking(false));
4925
+ return () => {
4926
+ unsubscribe();
4800
4927
  if (copyTimerRef.current !== null) {
4801
4928
  window.clearTimeout(copyTimerRef.current);
4802
4929
  }
4803
- if (speaking) window.speechSynthesis.cancel();
4804
- },
4805
- // Cancel speech only when this answer's actions unmount.
4806
- // eslint-disable-next-line react-hooks/exhaustive-deps
4807
- []
4808
- );
4930
+ stopSpeech();
4931
+ };
4932
+ }, []);
4809
4933
  (0, import_react11.useEffect)(() => {
4810
4934
  if (!menuOpen) return;
4811
4935
  const handlePointerDown = (event) => {
@@ -4844,14 +4968,14 @@ function MessageActions({
4844
4968
  if (!canReadAloud) return;
4845
4969
  setMenuOpen(false);
4846
4970
  if (speaking) {
4847
- window.speechSynthesis.cancel();
4971
+ stopSpeech();
4848
4972
  setSpeaking(false);
4849
4973
  return;
4850
4974
  }
4851
4975
  const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
4852
4976
  utterance.onend = () => setSpeaking(false);
4853
4977
  utterance.onerror = () => setSpeaking(false);
4854
- window.speechSynthesis.cancel();
4978
+ stopSpeech();
4855
4979
  window.speechSynthesis.speak(utterance);
4856
4980
  setSpeaking(true);
4857
4981
  }
@@ -5749,8 +5873,9 @@ function AgentRail({
5749
5873
  colorScheme = "auto",
5750
5874
  brandLabel = "",
5751
5875
  brandLogoUrl,
5752
- poweredByLabel = "Powered by Webless",
5876
+ poweredByLabel,
5753
5877
  disclaimerLabel,
5878
+ disclaimerLink,
5754
5879
  answerReceipt = false,
5755
5880
  readAloud = false,
5756
5881
  composerPlaceholder = "Ask anything\u2026",
@@ -6185,7 +6310,15 @@ function AgentRail({
6185
6310
  onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6186
6311
  ] }) : null
6187
6312
  ] }) }),
6188
- showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: resolvedDisclaimerLabel }) }) : null,
6313
+ showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: disclaimerLink ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6314
+ "a",
6315
+ {
6316
+ href: disclaimerLink,
6317
+ rel: "noopener noreferrer",
6318
+ target: "_blank",
6319
+ children: resolvedDisclaimerLabel
6320
+ }
6321
+ ) : resolvedDisclaimerLabel }) }) : null,
6189
6322
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
6190
6323
  showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6191
6324
  "button",
@@ -6650,8 +6783,9 @@ function AgentWidget({
6650
6783
  brandLabel: agentName,
6651
6784
  brandLogoUrl: branding?.logoUrl,
6652
6785
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
6653
- poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6786
+ poweredByLabel: branding?.poweredByLabel,
6654
6787
  disclaimerLabel: branding?.disclaimer,
6788
+ disclaimerLink: branding?.disclaimerLink,
6655
6789
  answerReceipt: branding?.answerReceipt,
6656
6790
  readAloud: branding?.readAloud,
6657
6791
  state,