@runtypelabs/persona 3.10.1 → 3.12.0
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 +46 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +143 -0
- package/dist/index.d.ts +143 -0
- package/dist/index.global.js +68 -68
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +46 -46
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/theme-editor.cjs +328 -26
- package/dist/theme-editor.d.cts +143 -0
- package/dist/theme-editor.d.ts +143 -0
- package/dist/theme-editor.js +328 -26
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.js +1 -1
- package/dist/widget.css +80 -0
- package/package.json +1 -1
- package/src/components/reasoning-bubble.ts +139 -5
- package/src/components/tool-bubble.ts +121 -1
- package/src/defaults.ts +2 -0
- package/src/install.ts +4 -1
- package/src/styles/widget.css +80 -0
- package/src/theme-reference.ts +11 -5
- package/src/tool-call-display-defaults.test.ts +2 -0
- package/src/types.ts +149 -0
- package/src/ui.scroll.test.ts +45 -2
- package/src/ui.ts +48 -2
- package/src/utils/formatting.test.ts +99 -1
- package/src/utils/formatting.ts +145 -0
- package/src/utils/message-fingerprint.test.ts +12 -0
- package/src/utils/message-fingerprint.ts +1 -0
- package/src/utils/morph.test.ts +86 -0
- package/src/utils/morph.ts +17 -3
package/dist/install.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var SiteAgentInstaller=(()=>{var
|
|
1
|
+
"use strict";var SiteAgentInstaller=(()=>{var m=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var _=(s,i,g,t)=>{if(i&&typeof i=="object"||typeof i=="function")for(let a of W(i))!T.call(s,a)&&a!==g&&m(s,a,{get:()=>i[a],enumerable:!(t=j(i,a))||t.enumerable});return s};var F=s=>_(m({},"__esModule",{value:!0}),s);var L={};(function(){"use strict";if(window.__siteAgentInstallerLoaded)return;window.__siteAgentInstallerLoaded=!0;let i=(()=>{let n=document.currentScript;if(!n)return{};let e={},o=n.getAttribute("data-config");if(o)try{let c=o.replace(/[\r\n]+\s*/g,""),d=JSON.parse(c);if(d.config){let{__proto__:M,constructor:$,prototype:J,...P}=d;Object.assign(e,P)}else e.config=d}catch(c){console.error("Failed to parse data-config JSON:",c)}let r=n.getAttribute("data-runtype-token");r&&(e.clientToken=r);let l=n.getAttribute("data-flow-id");l&&(e.flowId=l);let p=n.getAttribute("data-api-url");p&&(e.apiUrl=p);let w=n.getAttribute("data-preview-param");return w&&(e.previewQueryParam=w),e})(),t={...window.siteAgentConfig||{},...i};if(!(()=>{if(!t.previewQueryParam)return!0;let e=new URLSearchParams(window.location.search).get(t.previewQueryParam);return e!==null&&e!==""&&e.toLowerCase()!=="false"&&e!=="0"})())return;let A=t.version||"latest",C=t.cdn||"jsdelivr",h=t.autoInit!==!1,y=()=>{if(t.cssUrl&&t.jsUrl)return{cssUrl:t.cssUrl,jsUrl:t.jsUrl};let e=`/npm/@runtypelabs/persona@${A}/dist`;return C==="unpkg"?{cssUrl:`https://unpkg.com${e}/widget.css`,jsUrl:`https://unpkg.com${e}/index.global.js`}:{cssUrl:`https://cdn.jsdelivr.net${e}/widget.css`,jsUrl:`https://cdn.jsdelivr.net${e}/index.global.js`}},{cssUrl:u,jsUrl:f}=y(),k=()=>!!document.head.querySelector("link[data-persona]")||!!document.head.querySelector('link[href*="widget.css"]'),S=()=>!!window.AgentWidget,U=n=>{let e=!1,o=()=>{e||(e=!0,n())},r=()=>{typeof requestIdleCallback!="undefined"?requestIdleCallback(()=>{requestAnimationFrame(()=>{requestAnimationFrame(o)})},{timeout:3e3}):setTimeout(o,300)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r):r()},b=()=>new Promise((n,e)=>{if(k()){n();return}let o=document.createElement("link");o.rel="stylesheet",o.href=u,o.setAttribute("data-persona","true"),o.onload=()=>n(),o.onerror=()=>e(new Error(`Failed to load CSS from ${u}`)),document.head.appendChild(o)}),I=()=>new Promise((n,e)=>{if(S()){n();return}let o=document.createElement("script");o.src=f,o.async=!0,o.onload=()=>n(),o.onerror=()=>e(new Error(`Failed to load JS from ${f}`)),document.head.appendChild(o)}),v=()=>{var r;if(!window.AgentWidget||!window.AgentWidget.initAgentWidget){console.warn("AgentWidget not available. Make sure the script loaded successfully.");return}let n=t.target||"body",e={...t.config};if(t.apiUrl&&!e.apiUrl&&(e.apiUrl=t.apiUrl),t.clientToken&&!e.clientToken&&(e.clientToken=t.clientToken),t.flowId&&!e.flowId&&(e.flowId=t.flowId),!(!(e.apiUrl||e.clientToken)&&Object.keys(e).length===0)){!e.postprocessMessage&&window.AgentWidget.markdownPostprocessor&&(e.postprocessMessage=({text:l})=>window.AgentWidget.markdownPostprocessor(l));try{window.AgentWidget.initAgentWidget({target:n,config:e,useShadowDom:(r=t.useShadowDom)!=null?r:!1})}catch(l){console.error("Failed to initialize AgentWidget:",l)}}};U(async()=>{try{await b(),await I(),h&&(t.config||t.apiUrl||t.clientToken)&&setTimeout(v,0)}catch(n){console.error("Failed to install AgentWidget:",n)}})})();return F(L);})();
|
|
2
2
|
//# sourceMappingURL=install.global.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/install.ts"],"sourcesContent":["/**\n * Standalone installer script for easy script tag installation\n * This script automatically loads CSS and JS, then initializes the widget\n * if configuration is provided via window.siteAgentConfig\n */\n\nexport {};\n\ninterface SiteAgentInstallConfig {\n version?: string;\n cdn?: \"unpkg\" | \"jsdelivr\";\n cssUrl?: string;\n jsUrl?: string;\n target?: string | HTMLElement;\n config?: any;\n autoInit?: boolean;\n // Client token mode options (can also be set via data attributes)\n clientToken?: string;\n flowId?: string;\n apiUrl?: string;\n // Optional query param key that gates widget installation in preview mode\n previewQueryParam?: string;\n // Shadow DOM option (defaults to false for better CSS compatibility)\n useShadowDom?: boolean;\n}\n\ndeclare global {\n interface Window {\n siteAgentConfig?: SiteAgentInstallConfig;\n AgentWidget?: any;\n }\n}\n\n(function() {\n \"use strict\";\n\n // Prevent double installation\n if ((window as any).__siteAgentInstallerLoaded) {\n return;\n }\n (window as any).__siteAgentInstallerLoaded = true;\n\n /**\n * Read configuration from data attributes on the current script tag.\n * Supports: data-config (JSON), data-runtype-token, data-flow-id, data-api-url\n */\n const getConfigFromScript = (): Partial<SiteAgentInstallConfig> => {\n // Try to get the current script element\n const script = document.currentScript as HTMLScriptElement | null;\n if (!script) return {};\n\n const scriptConfig: Partial<SiteAgentInstallConfig> = {};\n\n // Full config from data-config attribute (JSON string)\n const configJson = script.getAttribute('data-config');\n if (configJson) {\n try {\n const parsedConfig = JSON.parse(configJson);\n // If it has nested 'config' property, use it; otherwise treat as widget config\n if (parsedConfig.config) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { __proto__: _a, constructor: _b, prototype: _c, ...safeConfig } = parsedConfig;\n Object.assign(scriptConfig, safeConfig);\n } else {\n // Treat the entire object as widget config\n scriptConfig.config = parsedConfig;\n }\n } catch (e) {\n console.error(\"Failed to parse data-config JSON:\", e);\n }\n }\n\n // Client token from data attribute (primary method for client token mode)\n const token = script.getAttribute('data-runtype-token');\n if (token) {\n scriptConfig.clientToken = token;\n }\n\n // Optional flow ID\n const flowId = script.getAttribute('data-flow-id');\n if (flowId) {\n scriptConfig.flowId = flowId;\n }\n\n // Optional API URL override\n const apiUrl = script.getAttribute('data-api-url');\n if (apiUrl) {\n scriptConfig.apiUrl = apiUrl;\n }\n\n // Optional preview query param gate\n const previewQueryParam = script.getAttribute('data-preview-param');\n if (previewQueryParam) {\n scriptConfig.previewQueryParam = previewQueryParam;\n }\n\n return scriptConfig;\n };\n\n // Get config from script attributes (must be called synchronously during script execution)\n const scriptConfig = getConfigFromScript();\n\n // Merge script attributes with window config (script attributes take precedence)\n const windowConfig: SiteAgentInstallConfig = window.siteAgentConfig || {};\n const config: SiteAgentInstallConfig = { ...windowConfig, ...scriptConfig };\n\n const isPreviewModeEnabled = (): boolean => {\n if (!config.previewQueryParam) {\n return true;\n }\n\n const params = new URLSearchParams(window.location.search);\n const value = params.get(config.previewQueryParam);\n return value !== null && value !== \"\" && value.toLowerCase() !== \"false\" && value !== \"0\";\n };\n\n if (!isPreviewModeEnabled()) {\n return;\n }\n \n const version = config.version || \"latest\";\n const cdn = config.cdn || \"jsdelivr\";\n const autoInit = config.autoInit !== false; // Default to true\n\n // Determine CDN base URL\n const getCdnBase = () => {\n if (config.cssUrl && config.jsUrl) {\n return { cssUrl: config.cssUrl, jsUrl: config.jsUrl };\n }\n \n const packageName = \"@runtypelabs/persona\";\n const basePath = `/npm/${packageName}@${version}/dist`;\n \n if (cdn === \"unpkg\") {\n return {\n cssUrl: `https://unpkg.com${basePath}/widget.css`,\n jsUrl: `https://unpkg.com${basePath}/index.global.js`\n };\n } else {\n return {\n cssUrl: `https://cdn.jsdelivr.net${basePath}/widget.css`,\n jsUrl: `https://cdn.jsdelivr.net${basePath}/index.global.js`\n };\n }\n };\n\n const { cssUrl, jsUrl } = getCdnBase();\n\n // Check if CSS is already loaded\n const isCssLoaded = () => {\n return !!document.head.querySelector('link[data-persona]') ||\n !!document.head.querySelector(`link[href*=\"widget.css\"]`);\n };\n\n // Check if JS is already loaded\n const isJsLoaded = () => {\n return !!(window as any).AgentWidget;\n };\n\n /**\n * Wait for framework hydration to complete (Next.js, Nuxt, etc.)\n * This prevents the framework from removing dynamically added CSS during reconciliation.\n * Uses requestIdleCallback + double requestAnimationFrame for reliable detection.\n */\n const waitForHydration = (callback: () => void): void => {\n let executed = false;\n \n const execute = () => {\n if (executed) return;\n executed = true;\n callback();\n };\n\n const afterDom = () => {\n // Strategy 1: Use requestIdleCallback if available (best for detecting idle after hydration)\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(() => {\n // Double requestAnimationFrame ensures at least one full paint cycle completed\n requestAnimationFrame(() => {\n requestAnimationFrame(execute);\n });\n }, { timeout: 3000 }); // Max wait 3 seconds, then proceed anyway\n } else {\n // Strategy 2: Fallback for Safari (no requestIdleCallback)\n // 300ms is typically enough for hydration on most pages\n setTimeout(execute, 300);\n }\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', afterDom);\n } else {\n // DOM already ready, but still wait for potential hydration\n afterDom();\n }\n };\n\n // Load CSS\n const loadCSS = (): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (isCssLoaded()) {\n resolve();\n return;\n }\n\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n link.setAttribute(\"data-persona\", \"true\");\n \n link.onload = () => resolve();\n link.onerror = () => reject(new Error(`Failed to load CSS from ${cssUrl}`));\n document.head.appendChild(link);\n });\n };\n\n // Load JS\n const loadJS = (): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (isJsLoaded()) {\n resolve();\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = jsUrl;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`Failed to load JS from ${jsUrl}`));\n document.head.appendChild(script);\n });\n };\n\n // Initialize widget\n const initWidget = () => {\n if (!window.AgentWidget || !window.AgentWidget.initAgentWidget) {\n console.warn(\"AgentWidget not available. Make sure the script loaded successfully.\");\n return;\n }\n\n const target = config.target || \"body\";\n // Merge top-level config options into widget config\n const widgetConfig = { ...config.config };\n \n // Merge apiUrl from top-level config into widget config if present\n if (config.apiUrl && !widgetConfig.apiUrl) {\n widgetConfig.apiUrl = config.apiUrl;\n }\n \n // Merge clientToken from top-level config into widget config if present\n if (config.clientToken && !widgetConfig.clientToken) {\n widgetConfig.clientToken = config.clientToken;\n }\n \n // Merge flowId from top-level config into widget config if present\n if (config.flowId && !widgetConfig.flowId) {\n widgetConfig.flowId = config.flowId;\n }\n\n // Only initialize if we have either apiUrl OR clientToken (or other config)\n const hasApiConfig = widgetConfig.apiUrl || widgetConfig.clientToken;\n if (!hasApiConfig && Object.keys(widgetConfig).length === 0) {\n return;\n }\n\n // Auto-apply markdown postprocessor if not explicitly set and available\n if (!widgetConfig.postprocessMessage && window.AgentWidget.markdownPostprocessor) {\n widgetConfig.postprocessMessage = ({ text }: { text: string }) => \n window.AgentWidget.markdownPostprocessor(text);\n }\n\n try {\n window.AgentWidget.initAgentWidget({\n target,\n config: widgetConfig,\n // Explicitly disable shadow DOM for better CSS compatibility with host page\n useShadowDom: config.useShadowDom ?? false\n });\n } catch (error) {\n console.error(\"Failed to initialize AgentWidget:\", error);\n }\n };\n\n // Main installation flow (called after hydration completes)\n const install = async () => {\n try {\n await loadCSS();\n await loadJS();\n \n // Auto-init if we have config OR apiUrl OR clientToken\n const shouldAutoInit = autoInit && (\n config.config || \n config.apiUrl || \n config.clientToken\n );\n \n if (shouldAutoInit) {\n // Wait a tick to ensure AgentWidget is fully initialized\n setTimeout(initWidget, 0);\n }\n } catch (error) {\n console.error(\"Failed to install AgentWidget:\", error);\n }\n };\n\n // Start installation after hydration completes\n // This prevents Next.js/Nuxt/etc. from removing dynamically added CSS\n waitForHydration(install);\n})();\n\n"],"mappings":"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","names":["install_exports","scriptConfig","script","configJson","parsedConfig","_a","_b","_c","safeConfig","e","token","flowId","apiUrl","previewQueryParam","config","value","version","cdn","autoInit","getCdnBase","basePath","cssUrl","jsUrl","isCssLoaded","isJsLoaded","waitForHydration","callback","executed","execute","afterDom","loadCSS","resolve","reject","link","loadJS","initWidget","target","widgetConfig","text","error"]}
|
|
1
|
+
{"version":3,"sources":["../src/install.ts"],"sourcesContent":["/**\n * Standalone installer script for easy script tag installation\n * This script automatically loads CSS and JS, then initializes the widget\n * if configuration is provided via window.siteAgentConfig\n */\n\nexport {};\n\ninterface SiteAgentInstallConfig {\n version?: string;\n cdn?: \"unpkg\" | \"jsdelivr\";\n cssUrl?: string;\n jsUrl?: string;\n target?: string | HTMLElement;\n config?: any;\n autoInit?: boolean;\n // Client token mode options (can also be set via data attributes)\n clientToken?: string;\n flowId?: string;\n apiUrl?: string;\n // Optional query param key that gates widget installation in preview mode\n previewQueryParam?: string;\n // Shadow DOM option (defaults to false for better CSS compatibility)\n useShadowDom?: boolean;\n}\n\ndeclare global {\n interface Window {\n siteAgentConfig?: SiteAgentInstallConfig;\n AgentWidget?: any;\n }\n}\n\n(function() {\n \"use strict\";\n\n // Prevent double installation\n if ((window as any).__siteAgentInstallerLoaded) {\n return;\n }\n (window as any).__siteAgentInstallerLoaded = true;\n\n /**\n * Read configuration from data attributes on the current script tag.\n * Supports: data-config (JSON), data-runtype-token, data-flow-id, data-api-url\n */\n const getConfigFromScript = (): Partial<SiteAgentInstallConfig> => {\n // Try to get the current script element\n const script = document.currentScript as HTMLScriptElement | null;\n if (!script) return {};\n\n const scriptConfig: Partial<SiteAgentInstallConfig> = {};\n\n // Full config from data-config attribute (JSON string)\n const configJson = script.getAttribute('data-config');\n if (configJson) {\n try {\n // HTML attributes preserve literal newlines/tabs which are invalid\n // control characters inside JSON string literals — strip them.\n const normalizedJson = configJson.replace(/[\\r\\n]+\\s*/g, '');\n const parsedConfig = JSON.parse(normalizedJson);\n // If it has nested 'config' property, use it; otherwise treat as widget config\n if (parsedConfig.config) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { __proto__: _a, constructor: _b, prototype: _c, ...safeConfig } = parsedConfig;\n Object.assign(scriptConfig, safeConfig);\n } else {\n // Treat the entire object as widget config\n scriptConfig.config = parsedConfig;\n }\n } catch (e) {\n console.error(\"Failed to parse data-config JSON:\", e);\n }\n }\n\n // Client token from data attribute (primary method for client token mode)\n const token = script.getAttribute('data-runtype-token');\n if (token) {\n scriptConfig.clientToken = token;\n }\n\n // Optional flow ID\n const flowId = script.getAttribute('data-flow-id');\n if (flowId) {\n scriptConfig.flowId = flowId;\n }\n\n // Optional API URL override\n const apiUrl = script.getAttribute('data-api-url');\n if (apiUrl) {\n scriptConfig.apiUrl = apiUrl;\n }\n\n // Optional preview query param gate\n const previewQueryParam = script.getAttribute('data-preview-param');\n if (previewQueryParam) {\n scriptConfig.previewQueryParam = previewQueryParam;\n }\n\n return scriptConfig;\n };\n\n // Get config from script attributes (must be called synchronously during script execution)\n const scriptConfig = getConfigFromScript();\n\n // Merge script attributes with window config (script attributes take precedence)\n const windowConfig: SiteAgentInstallConfig = window.siteAgentConfig || {};\n const config: SiteAgentInstallConfig = { ...windowConfig, ...scriptConfig };\n\n const isPreviewModeEnabled = (): boolean => {\n if (!config.previewQueryParam) {\n return true;\n }\n\n const params = new URLSearchParams(window.location.search);\n const value = params.get(config.previewQueryParam);\n return value !== null && value !== \"\" && value.toLowerCase() !== \"false\" && value !== \"0\";\n };\n\n if (!isPreviewModeEnabled()) {\n return;\n }\n \n const version = config.version || \"latest\";\n const cdn = config.cdn || \"jsdelivr\";\n const autoInit = config.autoInit !== false; // Default to true\n\n // Determine CDN base URL\n const getCdnBase = () => {\n if (config.cssUrl && config.jsUrl) {\n return { cssUrl: config.cssUrl, jsUrl: config.jsUrl };\n }\n \n const packageName = \"@runtypelabs/persona\";\n const basePath = `/npm/${packageName}@${version}/dist`;\n \n if (cdn === \"unpkg\") {\n return {\n cssUrl: `https://unpkg.com${basePath}/widget.css`,\n jsUrl: `https://unpkg.com${basePath}/index.global.js`\n };\n } else {\n return {\n cssUrl: `https://cdn.jsdelivr.net${basePath}/widget.css`,\n jsUrl: `https://cdn.jsdelivr.net${basePath}/index.global.js`\n };\n }\n };\n\n const { cssUrl, jsUrl } = getCdnBase();\n\n // Check if CSS is already loaded\n const isCssLoaded = () => {\n return !!document.head.querySelector('link[data-persona]') ||\n !!document.head.querySelector(`link[href*=\"widget.css\"]`);\n };\n\n // Check if JS is already loaded\n const isJsLoaded = () => {\n return !!(window as any).AgentWidget;\n };\n\n /**\n * Wait for framework hydration to complete (Next.js, Nuxt, etc.)\n * This prevents the framework from removing dynamically added CSS during reconciliation.\n * Uses requestIdleCallback + double requestAnimationFrame for reliable detection.\n */\n const waitForHydration = (callback: () => void): void => {\n let executed = false;\n \n const execute = () => {\n if (executed) return;\n executed = true;\n callback();\n };\n\n const afterDom = () => {\n // Strategy 1: Use requestIdleCallback if available (best for detecting idle after hydration)\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(() => {\n // Double requestAnimationFrame ensures at least one full paint cycle completed\n requestAnimationFrame(() => {\n requestAnimationFrame(execute);\n });\n }, { timeout: 3000 }); // Max wait 3 seconds, then proceed anyway\n } else {\n // Strategy 2: Fallback for Safari (no requestIdleCallback)\n // 300ms is typically enough for hydration on most pages\n setTimeout(execute, 300);\n }\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', afterDom);\n } else {\n // DOM already ready, but still wait for potential hydration\n afterDom();\n }\n };\n\n // Load CSS\n const loadCSS = (): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (isCssLoaded()) {\n resolve();\n return;\n }\n\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n link.setAttribute(\"data-persona\", \"true\");\n \n link.onload = () => resolve();\n link.onerror = () => reject(new Error(`Failed to load CSS from ${cssUrl}`));\n document.head.appendChild(link);\n });\n };\n\n // Load JS\n const loadJS = (): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (isJsLoaded()) {\n resolve();\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = jsUrl;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`Failed to load JS from ${jsUrl}`));\n document.head.appendChild(script);\n });\n };\n\n // Initialize widget\n const initWidget = () => {\n if (!window.AgentWidget || !window.AgentWidget.initAgentWidget) {\n console.warn(\"AgentWidget not available. Make sure the script loaded successfully.\");\n return;\n }\n\n const target = config.target || \"body\";\n // Merge top-level config options into widget config\n const widgetConfig = { ...config.config };\n \n // Merge apiUrl from top-level config into widget config if present\n if (config.apiUrl && !widgetConfig.apiUrl) {\n widgetConfig.apiUrl = config.apiUrl;\n }\n \n // Merge clientToken from top-level config into widget config if present\n if (config.clientToken && !widgetConfig.clientToken) {\n widgetConfig.clientToken = config.clientToken;\n }\n \n // Merge flowId from top-level config into widget config if present\n if (config.flowId && !widgetConfig.flowId) {\n widgetConfig.flowId = config.flowId;\n }\n\n // Only initialize if we have either apiUrl OR clientToken (or other config)\n const hasApiConfig = widgetConfig.apiUrl || widgetConfig.clientToken;\n if (!hasApiConfig && Object.keys(widgetConfig).length === 0) {\n return;\n }\n\n // Auto-apply markdown postprocessor if not explicitly set and available\n if (!widgetConfig.postprocessMessage && window.AgentWidget.markdownPostprocessor) {\n widgetConfig.postprocessMessage = ({ text }: { text: string }) => \n window.AgentWidget.markdownPostprocessor(text);\n }\n\n try {\n window.AgentWidget.initAgentWidget({\n target,\n config: widgetConfig,\n // Explicitly disable shadow DOM for better CSS compatibility with host page\n useShadowDom: config.useShadowDom ?? false\n });\n } catch (error) {\n console.error(\"Failed to initialize AgentWidget:\", error);\n }\n };\n\n // Main installation flow (called after hydration completes)\n const install = async () => {\n try {\n await loadCSS();\n await loadJS();\n \n // Auto-init if we have config OR apiUrl OR clientToken\n const shouldAutoInit = autoInit && (\n config.config || \n config.apiUrl || \n config.clientToken\n );\n \n if (shouldAutoInit) {\n // Wait a tick to ensure AgentWidget is fully initialized\n setTimeout(initWidget, 0);\n }\n } catch (error) {\n console.error(\"Failed to install AgentWidget:\", error);\n }\n };\n\n // Start installation after hydration completes\n // This prevents Next.js/Nuxt/etc. from removing dynamically added CSS\n waitForHydration(install);\n})();\n\n"],"mappings":"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","names":["install_exports","scriptConfig","script","configJson","normalizedJson","parsedConfig","_a","_b","_c","safeConfig","e","token","flowId","apiUrl","previewQueryParam","config","value","version","cdn","autoInit","getCdnBase","basePath","cssUrl","jsUrl","isCssLoaded","isJsLoaded","waitForHydration","callback","executed","execute","afterDom","loadCSS","resolve","reject","link","loadJS","initWidget","target","widgetConfig","text","error"]}
|
package/dist/theme-editor.cjs
CHANGED
|
@@ -233,12 +233,14 @@ var DEFAULT_WIDGET_CONFIG = {
|
|
|
233
233
|
activePreview: false,
|
|
234
234
|
grouped: false,
|
|
235
235
|
previewMaxLines: 3,
|
|
236
|
-
expandable: true
|
|
236
|
+
expandable: true,
|
|
237
|
+
loadingAnimation: "none"
|
|
237
238
|
},
|
|
238
239
|
reasoningDisplay: {
|
|
239
240
|
activePreview: false,
|
|
240
241
|
previewMaxLines: 3,
|
|
241
|
-
expandable: true
|
|
242
|
+
expandable: true,
|
|
243
|
+
loadingAnimation: "none"
|
|
242
244
|
}
|
|
243
245
|
},
|
|
244
246
|
suggestionChips: [
|
|
@@ -3345,6 +3347,70 @@ var describeToolTitle = (tool) => {
|
|
|
3345
3347
|
}
|
|
3346
3348
|
return "Using tool...";
|
|
3347
3349
|
};
|
|
3350
|
+
var formatElapsedMs = (ms) => {
|
|
3351
|
+
const seconds = ms / 1e3;
|
|
3352
|
+
if (seconds < 0.1) return "<0.1s";
|
|
3353
|
+
if (seconds >= 10) return `${Math.round(seconds)}s`;
|
|
3354
|
+
return `${seconds.toFixed(1).replace(/\.0$/, "")}s`;
|
|
3355
|
+
};
|
|
3356
|
+
var computeToolElapsed = (tool) => {
|
|
3357
|
+
var _a, _b, _c;
|
|
3358
|
+
const durationMs = typeof tool.duration === "number" ? tool.duration : typeof tool.durationMs === "number" ? tool.durationMs : Math.max(
|
|
3359
|
+
0,
|
|
3360
|
+
((_a = tool.completedAt) != null ? _a : Date.now()) - ((_c = (_b = tool.startedAt) != null ? _b : tool.completedAt) != null ? _c : Date.now())
|
|
3361
|
+
);
|
|
3362
|
+
return formatElapsedMs(durationMs);
|
|
3363
|
+
};
|
|
3364
|
+
var computeReasoningElapsed = (reasoning) => {
|
|
3365
|
+
var _a, _b, _c;
|
|
3366
|
+
const durationMs = reasoning.durationMs !== void 0 ? reasoning.durationMs : Math.max(
|
|
3367
|
+
0,
|
|
3368
|
+
((_a = reasoning.completedAt) != null ? _a : Date.now()) - ((_c = (_b = reasoning.startedAt) != null ? _b : reasoning.completedAt) != null ? _c : Date.now())
|
|
3369
|
+
);
|
|
3370
|
+
return formatElapsedMs(durationMs);
|
|
3371
|
+
};
|
|
3372
|
+
var resolveToolHeaderText = (tool, template, fallback) => {
|
|
3373
|
+
var _a;
|
|
3374
|
+
if (!template) return fallback;
|
|
3375
|
+
const toolName = ((_a = tool.name) == null ? void 0 : _a.trim()) || "tool";
|
|
3376
|
+
const duration = computeToolElapsed(tool);
|
|
3377
|
+
return template.replace(/\{toolName\}/g, toolName).replace(/\{duration\}/g, duration);
|
|
3378
|
+
};
|
|
3379
|
+
var parseFormattedTemplate = (template, toolName) => {
|
|
3380
|
+
const resolved = template.replace(/\{toolName\}/g, toolName);
|
|
3381
|
+
const segments = [];
|
|
3382
|
+
const regex = /\*\*(.+?)\*\*|\*(.+?)\*|~(.+?)~/g;
|
|
3383
|
+
let lastIndex = 0;
|
|
3384
|
+
let match;
|
|
3385
|
+
while ((match = regex.exec(resolved)) !== null) {
|
|
3386
|
+
if (match.index > lastIndex) {
|
|
3387
|
+
pushSegments(segments, resolved.slice(lastIndex, match.index), []);
|
|
3388
|
+
}
|
|
3389
|
+
if (match[1] !== void 0) {
|
|
3390
|
+
pushSegments(segments, match[1], ["bold"]);
|
|
3391
|
+
} else if (match[2] !== void 0) {
|
|
3392
|
+
pushSegments(segments, match[2], ["italic"]);
|
|
3393
|
+
} else if (match[3] !== void 0) {
|
|
3394
|
+
pushSegments(segments, match[3], ["dim"]);
|
|
3395
|
+
}
|
|
3396
|
+
lastIndex = match.index + match[0].length;
|
|
3397
|
+
}
|
|
3398
|
+
if (lastIndex < resolved.length) {
|
|
3399
|
+
pushSegments(segments, resolved.slice(lastIndex), []);
|
|
3400
|
+
}
|
|
3401
|
+
return segments;
|
|
3402
|
+
};
|
|
3403
|
+
var pushSegments = (segments, text, styles) => {
|
|
3404
|
+
const parts = text.split("{duration}");
|
|
3405
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3406
|
+
if (parts[i]) {
|
|
3407
|
+
segments.push({ text: parts[i], styles });
|
|
3408
|
+
}
|
|
3409
|
+
if (i < parts.length - 1) {
|
|
3410
|
+
segments.push({ text: "{duration}", styles, isDuration: true });
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3348
3414
|
var createRegexJsonParserInternal = () => {
|
|
3349
3415
|
let extractedText = null;
|
|
3350
3416
|
let processedLength = 0;
|
|
@@ -7962,10 +8028,24 @@ var morphMessages = (container, newContent, options = {}) => {
|
|
|
7962
8028
|
import_idiomorph.Idiomorph.morph(container, newContent.innerHTML, {
|
|
7963
8029
|
morphStyle: "innerHTML",
|
|
7964
8030
|
callbacks: {
|
|
7965
|
-
beforeNodeMorphed(oldNode,
|
|
8031
|
+
beforeNodeMorphed(oldNode, newNode) {
|
|
8032
|
+
var _a, _b;
|
|
7966
8033
|
if (!(oldNode instanceof HTMLElement)) return;
|
|
7967
8034
|
if (preserveTypingAnimation) {
|
|
7968
|
-
if (oldNode.classList.contains("persona-animate-typing")
|
|
8035
|
+
if (oldNode.classList.contains("persona-animate-typing")) {
|
|
8036
|
+
return false;
|
|
8037
|
+
}
|
|
8038
|
+
if (oldNode.hasAttribute("data-preserve-animation")) {
|
|
8039
|
+
if (newNode instanceof HTMLElement && !newNode.hasAttribute("data-preserve-animation")) {
|
|
8040
|
+
return;
|
|
8041
|
+
}
|
|
8042
|
+
if (newNode instanceof HTMLElement && newNode.hasAttribute("data-preserve-animation")) {
|
|
8043
|
+
const oldText = (_a = oldNode.textContent) != null ? _a : "";
|
|
8044
|
+
const newText = (_b = newNode.textContent) != null ? _b : "";
|
|
8045
|
+
if (oldText !== newText) {
|
|
8046
|
+
return;
|
|
8047
|
+
}
|
|
8048
|
+
}
|
|
7969
8049
|
return false;
|
|
7970
8050
|
}
|
|
7971
8051
|
}
|
|
@@ -7976,7 +8056,7 @@ var morphMessages = (container, newContent, options = {}) => {
|
|
|
7976
8056
|
|
|
7977
8057
|
// src/utils/message-fingerprint.ts
|
|
7978
8058
|
function computeMessageFingerprint(message, configVersion) {
|
|
7979
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A;
|
|
8059
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
|
|
7980
8060
|
return [
|
|
7981
8061
|
message.id,
|
|
7982
8062
|
message.role,
|
|
@@ -7988,11 +8068,12 @@ function computeMessageFingerprint(message, configVersion) {
|
|
|
7988
8068
|
(_i = (_h = message.llmContent) == null ? void 0 : _h.length) != null ? _i : 0,
|
|
7989
8069
|
(_k = (_j = message.approval) == null ? void 0 : _j.status) != null ? _k : "",
|
|
7990
8070
|
(_m = (_l = message.toolCall) == null ? void 0 : _l.status) != null ? _m : "",
|
|
7991
|
-
(
|
|
7992
|
-
(
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
(_A = (_z = message.
|
|
8071
|
+
(_o = (_n = message.toolCall) == null ? void 0 : _n.name) != null ? _o : "",
|
|
8072
|
+
(_r = (_q = (_p = message.toolCall) == null ? void 0 : _p.chunks) == null ? void 0 : _q.length) != null ? _r : 0,
|
|
8073
|
+
(_v = (_u = (_t = (_s = message.toolCall) == null ? void 0 : _s.chunks) == null ? void 0 : _t[message.toolCall.chunks.length - 1]) == null ? void 0 : _u.slice(-32)) != null ? _v : "",
|
|
8074
|
+
typeof ((_w = message.toolCall) == null ? void 0 : _w.args) === "string" ? message.toolCall.args.length : ((_x = message.toolCall) == null ? void 0 : _x.args) ? JSON.stringify(message.toolCall.args).length : 0,
|
|
8075
|
+
(_A = (_z = (_y = message.reasoning) == null ? void 0 : _y.chunks) == null ? void 0 : _z.length) != null ? _A : 0,
|
|
8076
|
+
(_C = (_B = message.contentParts) == null ? void 0 : _B.length) != null ? _C : 0,
|
|
7996
8077
|
configVersion
|
|
7997
8078
|
].join("\0");
|
|
7998
8079
|
}
|
|
@@ -10114,7 +10195,7 @@ var updateReasoningBubbleUI = (messageId, bubble) => {
|
|
|
10114
10195
|
}
|
|
10115
10196
|
};
|
|
10116
10197
|
var createReasoningBubble = (message, config) => {
|
|
10117
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
10198
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
10118
10199
|
const reasoning = message.reasoning;
|
|
10119
10200
|
const bubble = createElement(
|
|
10120
10201
|
"div",
|
|
@@ -10157,13 +10238,23 @@ var createReasoningBubble = (message, config) => {
|
|
|
10157
10238
|
const headerContent = createElement("div", "persona-flex persona-flex-col persona-text-left");
|
|
10158
10239
|
const title = createElement("span", "persona-text-xs persona-text-persona-primary");
|
|
10159
10240
|
const defaultSummary = "Thinking...";
|
|
10160
|
-
const
|
|
10241
|
+
const reasoningConfig = (_d = config == null ? void 0 : config.reasoning) != null ? _d : {};
|
|
10242
|
+
const startedAt = String((_e = reasoning.startedAt) != null ? _e : Date.now());
|
|
10243
|
+
const createElapsedSpan = () => {
|
|
10244
|
+
const span = createElement("span", "");
|
|
10245
|
+
span.setAttribute("data-tool-elapsed", startedAt);
|
|
10246
|
+
span.textContent = computeReasoningElapsed(reasoning);
|
|
10247
|
+
return span;
|
|
10248
|
+
};
|
|
10249
|
+
const customSummary = (_f = reasoningConfig.renderCollapsedSummary) == null ? void 0 : _f.call(reasoningConfig, {
|
|
10161
10250
|
message,
|
|
10162
10251
|
reasoning,
|
|
10163
10252
|
defaultSummary,
|
|
10164
10253
|
previewText,
|
|
10165
10254
|
isActive,
|
|
10166
|
-
config: config != null ? config : {}
|
|
10255
|
+
config: config != null ? config : {},
|
|
10256
|
+
elapsed: computeReasoningElapsed(reasoning),
|
|
10257
|
+
createElapsedElement: createElapsedSpan
|
|
10167
10258
|
});
|
|
10168
10259
|
if (typeof customSummary === "string" && customSummary.trim()) {
|
|
10169
10260
|
title.textContent = customSummary;
|
|
@@ -10177,10 +10268,101 @@ var createReasoningBubble = (message, config) => {
|
|
|
10177
10268
|
const status = createElement("span", "persona-text-xs persona-text-persona-primary");
|
|
10178
10269
|
status.textContent = describeReasonStatus(reasoning);
|
|
10179
10270
|
headerContent.appendChild(status);
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
10271
|
+
const loadingAnimation = (_g = reasoningDisplayConfig.loadingAnimation) != null ? _g : "none";
|
|
10272
|
+
const activeTemplate = reasoningConfig.activeTextTemplate;
|
|
10273
|
+
const completeTemplate = reasoningConfig.completeTextTemplate;
|
|
10274
|
+
const currentTemplate = isActive ? activeTemplate : completeTemplate;
|
|
10275
|
+
const skipCustomElement = customSummary instanceof HTMLElement;
|
|
10276
|
+
const appendCharSpans = (container, text2, startIndex) => {
|
|
10277
|
+
let idx = startIndex;
|
|
10278
|
+
for (const char of text2) {
|
|
10279
|
+
const span = createElement("span", "persona-tool-char");
|
|
10280
|
+
span.style.setProperty("--char-index", String(idx));
|
|
10281
|
+
span.textContent = char === " " ? "\xA0" : char;
|
|
10282
|
+
container.appendChild(span);
|
|
10283
|
+
idx++;
|
|
10284
|
+
}
|
|
10285
|
+
return idx;
|
|
10286
|
+
};
|
|
10287
|
+
const renderFormattedTitle = (template, animated) => {
|
|
10288
|
+
title.textContent = "";
|
|
10289
|
+
const segments = parseFormattedTemplate(template, "");
|
|
10290
|
+
let charIndex = 0;
|
|
10291
|
+
for (const seg of segments) {
|
|
10292
|
+
const parent = seg.styles.length > 0 ? (() => {
|
|
10293
|
+
const w = createElement("span", seg.styles.map((s) => `persona-tool-text-${s}`).join(" "));
|
|
10294
|
+
title.appendChild(w);
|
|
10295
|
+
return w;
|
|
10296
|
+
})() : title;
|
|
10297
|
+
if (seg.isDuration && isActive) {
|
|
10298
|
+
parent.appendChild(createElapsedSpan());
|
|
10299
|
+
} else {
|
|
10300
|
+
const text2 = seg.isDuration ? computeReasoningElapsed(reasoning) : seg.text;
|
|
10301
|
+
if (animated) {
|
|
10302
|
+
charIndex = appendCharSpans(parent, text2, charIndex);
|
|
10303
|
+
} else {
|
|
10304
|
+
parent.appendChild(document.createTextNode(text2));
|
|
10305
|
+
}
|
|
10306
|
+
}
|
|
10307
|
+
}
|
|
10308
|
+
};
|
|
10309
|
+
if (!skipCustomElement && currentTemplate) {
|
|
10310
|
+
status.style.display = "none";
|
|
10311
|
+
title.style.display = "";
|
|
10312
|
+
if (isActive && loadingAnimation !== "none") {
|
|
10313
|
+
const animDuration = (_h = reasoningConfig.loadingAnimationDuration) != null ? _h : 2e3;
|
|
10314
|
+
title.setAttribute("data-preserve-animation", "true");
|
|
10315
|
+
if (loadingAnimation === "pulse") {
|
|
10316
|
+
title.classList.add("persona-tool-loading-pulse");
|
|
10317
|
+
title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
|
|
10318
|
+
renderFormattedTitle(currentTemplate, false);
|
|
10319
|
+
} else {
|
|
10320
|
+
title.classList.add(`persona-tool-loading-${loadingAnimation}`);
|
|
10321
|
+
title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
|
|
10322
|
+
if (loadingAnimation === "shimmer-color") {
|
|
10323
|
+
if (reasoningConfig.loadingAnimationColor) {
|
|
10324
|
+
title.style.setProperty("--persona-tool-anim-color", reasoningConfig.loadingAnimationColor);
|
|
10325
|
+
}
|
|
10326
|
+
if (reasoningConfig.loadingAnimationSecondaryColor) {
|
|
10327
|
+
title.style.setProperty("--persona-tool-anim-secondary-color", reasoningConfig.loadingAnimationSecondaryColor);
|
|
10328
|
+
}
|
|
10329
|
+
}
|
|
10330
|
+
renderFormattedTitle(currentTemplate, true);
|
|
10331
|
+
}
|
|
10332
|
+
} else {
|
|
10333
|
+
renderFormattedTitle(currentTemplate, false);
|
|
10334
|
+
}
|
|
10335
|
+
} else if (!skipCustomElement && isActive && loadingAnimation !== "none") {
|
|
10183
10336
|
title.style.display = "";
|
|
10337
|
+
const animDuration = (_i = reasoningConfig.loadingAnimationDuration) != null ? _i : 2e3;
|
|
10338
|
+
title.setAttribute("data-preserve-animation", "true");
|
|
10339
|
+
if (loadingAnimation === "pulse") {
|
|
10340
|
+
title.classList.add("persona-tool-loading-pulse");
|
|
10341
|
+
title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
|
|
10342
|
+
} else {
|
|
10343
|
+
title.classList.add(`persona-tool-loading-${loadingAnimation}`);
|
|
10344
|
+
title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
|
|
10345
|
+
if (loadingAnimation === "shimmer-color") {
|
|
10346
|
+
if (reasoningConfig.loadingAnimationColor) {
|
|
10347
|
+
title.style.setProperty("--persona-tool-anim-color", reasoningConfig.loadingAnimationColor);
|
|
10348
|
+
}
|
|
10349
|
+
if (reasoningConfig.loadingAnimationSecondaryColor) {
|
|
10350
|
+
title.style.setProperty("--persona-tool-anim-secondary-color", reasoningConfig.loadingAnimationSecondaryColor);
|
|
10351
|
+
}
|
|
10352
|
+
}
|
|
10353
|
+
const text2 = title.textContent || defaultSummary;
|
|
10354
|
+
title.textContent = "";
|
|
10355
|
+
appendCharSpans(title, text2, 0);
|
|
10356
|
+
}
|
|
10357
|
+
if (reasoning.status === "complete") {
|
|
10358
|
+
title.style.display = "none";
|
|
10359
|
+
}
|
|
10360
|
+
} else if (!skipCustomElement) {
|
|
10361
|
+
if (reasoning.status === "complete") {
|
|
10362
|
+
title.style.display = "none";
|
|
10363
|
+
} else {
|
|
10364
|
+
title.style.display = "";
|
|
10365
|
+
}
|
|
10184
10366
|
}
|
|
10185
10367
|
let toggleIcon = null;
|
|
10186
10368
|
if (expandable) {
|
|
@@ -10206,7 +10388,7 @@ var createReasoningBubble = (message, config) => {
|
|
|
10206
10388
|
collapsedPreview.style.display = "none";
|
|
10207
10389
|
collapsedPreview.style.whiteSpace = "pre-wrap";
|
|
10208
10390
|
if (!expanded && isActive && reasoningDisplayConfig.activePreview && previewText) {
|
|
10209
|
-
const renderedPreview = (
|
|
10391
|
+
const renderedPreview = (_k = (_j = config == null ? void 0 : config.reasoning) == null ? void 0 : _j.renderCollapsedPreview) == null ? void 0 : _k.call(_j, {
|
|
10210
10392
|
message,
|
|
10211
10393
|
reasoning,
|
|
10212
10394
|
defaultPreview: previewText,
|
|
@@ -10282,7 +10464,7 @@ var getToolPreviewText = (message, maxLines) => {
|
|
|
10282
10464
|
return argsText.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(0, maxLines).join("\n");
|
|
10283
10465
|
};
|
|
10284
10466
|
var getToolSummaryText = (message, config) => {
|
|
10285
|
-
var _a, _b, _c, _d;
|
|
10467
|
+
var _a, _b, _c, _d, _e;
|
|
10286
10468
|
const tool = message.toolCall;
|
|
10287
10469
|
const toolDisplayConfig = (_a = config == null ? void 0 : config.features) == null ? void 0 : _a.toolCallDisplay;
|
|
10288
10470
|
const collapsedMode = (_b = toolDisplayConfig == null ? void 0 : toolDisplayConfig.collapsedMode) != null ? _b : "tool-call";
|
|
@@ -10292,12 +10474,18 @@ var getToolSummaryText = (message, config) => {
|
|
|
10292
10474
|
return { summary: defaultSummary, previewText, isActive: false };
|
|
10293
10475
|
}
|
|
10294
10476
|
const isActive = tool.status !== "complete";
|
|
10477
|
+
const toolCallConfig = (_d = config == null ? void 0 : config.toolCall) != null ? _d : {};
|
|
10295
10478
|
let summary = defaultSummary;
|
|
10296
10479
|
if (collapsedMode === "tool-name") {
|
|
10297
|
-
summary = ((
|
|
10480
|
+
summary = ((_e = tool.name) == null ? void 0 : _e.trim()) || defaultSummary;
|
|
10298
10481
|
} else if (collapsedMode === "tool-preview" && previewText) {
|
|
10299
10482
|
summary = previewText;
|
|
10300
10483
|
}
|
|
10484
|
+
if (isActive && toolCallConfig.activeTextTemplate) {
|
|
10485
|
+
summary = resolveToolHeaderText(tool, toolCallConfig.activeTextTemplate, summary);
|
|
10486
|
+
} else if (!isActive && toolCallConfig.completeTextTemplate) {
|
|
10487
|
+
summary = resolveToolHeaderText(tool, toolCallConfig.completeTextTemplate, summary);
|
|
10488
|
+
}
|
|
10301
10489
|
return { summary, previewText, isActive };
|
|
10302
10490
|
};
|
|
10303
10491
|
var updateToolBubbleUI = (messageId, bubble, config) => {
|
|
@@ -10327,7 +10515,7 @@ var updateToolBubbleUI = (messageId, bubble, config) => {
|
|
|
10327
10515
|
}
|
|
10328
10516
|
};
|
|
10329
10517
|
var createToolBubble = (message, config) => {
|
|
10330
|
-
var _a, _b, _c, _d, _e, _f;
|
|
10518
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
10331
10519
|
const tool = message.toolCall;
|
|
10332
10520
|
const toolCallConfig = (_a = config == null ? void 0 : config.toolCall) != null ? _a : {};
|
|
10333
10521
|
const bubble = createElement(
|
|
@@ -10395,14 +10583,23 @@ var createToolBubble = (message, config) => {
|
|
|
10395
10583
|
if (toolCallConfig.headerTextColor) {
|
|
10396
10584
|
title.style.color = toolCallConfig.headerTextColor;
|
|
10397
10585
|
}
|
|
10398
|
-
const
|
|
10586
|
+
const startedAt = String((_d = tool.startedAt) != null ? _d : Date.now());
|
|
10587
|
+
const createElapsedSpan = () => {
|
|
10588
|
+
const span = createElement("span", "");
|
|
10589
|
+
span.setAttribute("data-tool-elapsed", startedAt);
|
|
10590
|
+
span.textContent = computeToolElapsed(tool);
|
|
10591
|
+
return span;
|
|
10592
|
+
};
|
|
10593
|
+
const customSummary = (_f = toolCallConfig.renderCollapsedSummary) == null ? void 0 : _f.call(toolCallConfig, {
|
|
10399
10594
|
message,
|
|
10400
10595
|
toolCall: tool,
|
|
10401
10596
|
defaultSummary: summary,
|
|
10402
10597
|
previewText,
|
|
10403
|
-
collapsedMode: (
|
|
10598
|
+
collapsedMode: (_e = toolDisplayConfig.collapsedMode) != null ? _e : "tool-call",
|
|
10404
10599
|
isActive,
|
|
10405
|
-
config: config != null ? config : {}
|
|
10600
|
+
config: config != null ? config : {},
|
|
10601
|
+
elapsed: computeToolElapsed(tool),
|
|
10602
|
+
createElapsedElement: createElapsedSpan
|
|
10406
10603
|
});
|
|
10407
10604
|
if (typeof customSummary === "string" && customSummary.trim()) {
|
|
10408
10605
|
title.textContent = customSummary;
|
|
@@ -10413,6 +10610,79 @@ var createToolBubble = (message, config) => {
|
|
|
10413
10610
|
title.textContent = summary;
|
|
10414
10611
|
headerContent.appendChild(title);
|
|
10415
10612
|
}
|
|
10613
|
+
const loadingAnimation = (_g = toolDisplayConfig.loadingAnimation) != null ? _g : "none";
|
|
10614
|
+
const activeTemplate = toolCallConfig.activeTextTemplate;
|
|
10615
|
+
const completeTemplate = toolCallConfig.completeTextTemplate;
|
|
10616
|
+
const currentTemplate = isActive ? activeTemplate : completeTemplate;
|
|
10617
|
+
const skipCustomElement = customSummary instanceof HTMLElement;
|
|
10618
|
+
const appendCharSpans = (container, text, startIndex) => {
|
|
10619
|
+
let idx = startIndex;
|
|
10620
|
+
for (const char of text) {
|
|
10621
|
+
const span = createElement("span", "persona-tool-char");
|
|
10622
|
+
span.style.setProperty("--char-index", String(idx));
|
|
10623
|
+
span.textContent = char === " " ? "\xA0" : char;
|
|
10624
|
+
container.appendChild(span);
|
|
10625
|
+
idx++;
|
|
10626
|
+
}
|
|
10627
|
+
return idx;
|
|
10628
|
+
};
|
|
10629
|
+
const renderFormattedTitle = (template, animated) => {
|
|
10630
|
+
var _a2;
|
|
10631
|
+
title.textContent = "";
|
|
10632
|
+
const toolName = ((_a2 = tool.name) == null ? void 0 : _a2.trim()) || "tool";
|
|
10633
|
+
const segments = parseFormattedTemplate(template, toolName);
|
|
10634
|
+
let charIndex = 0;
|
|
10635
|
+
for (const seg of segments) {
|
|
10636
|
+
const parent = seg.styles.length > 0 ? (() => {
|
|
10637
|
+
const w = createElement("span", seg.styles.map((s) => `persona-tool-text-${s}`).join(" "));
|
|
10638
|
+
title.appendChild(w);
|
|
10639
|
+
return w;
|
|
10640
|
+
})() : title;
|
|
10641
|
+
if (seg.isDuration && isActive) {
|
|
10642
|
+
parent.appendChild(createElapsedSpan());
|
|
10643
|
+
} else {
|
|
10644
|
+
const text = seg.isDuration ? computeToolElapsed(tool) : seg.text;
|
|
10645
|
+
if (animated) {
|
|
10646
|
+
charIndex = appendCharSpans(parent, text, charIndex);
|
|
10647
|
+
} else {
|
|
10648
|
+
parent.appendChild(document.createTextNode(text));
|
|
10649
|
+
}
|
|
10650
|
+
}
|
|
10651
|
+
}
|
|
10652
|
+
};
|
|
10653
|
+
if (!skipCustomElement) {
|
|
10654
|
+
if (isActive && loadingAnimation !== "none") {
|
|
10655
|
+
const animDuration = (_h = toolCallConfig.loadingAnimationDuration) != null ? _h : 2e3;
|
|
10656
|
+
title.setAttribute("data-preserve-animation", "true");
|
|
10657
|
+
if (loadingAnimation === "pulse") {
|
|
10658
|
+
title.classList.add("persona-tool-loading-pulse");
|
|
10659
|
+
title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
|
|
10660
|
+
if (currentTemplate) {
|
|
10661
|
+
renderFormattedTitle(currentTemplate, false);
|
|
10662
|
+
}
|
|
10663
|
+
} else {
|
|
10664
|
+
title.classList.add(`persona-tool-loading-${loadingAnimation}`);
|
|
10665
|
+
title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
|
|
10666
|
+
if (loadingAnimation === "shimmer-color") {
|
|
10667
|
+
if (toolCallConfig.loadingAnimationColor) {
|
|
10668
|
+
title.style.setProperty("--persona-tool-anim-color", toolCallConfig.loadingAnimationColor);
|
|
10669
|
+
}
|
|
10670
|
+
if (toolCallConfig.loadingAnimationSecondaryColor) {
|
|
10671
|
+
title.style.setProperty("--persona-tool-anim-secondary-color", toolCallConfig.loadingAnimationSecondaryColor);
|
|
10672
|
+
}
|
|
10673
|
+
}
|
|
10674
|
+
if (currentTemplate) {
|
|
10675
|
+
renderFormattedTitle(currentTemplate, true);
|
|
10676
|
+
} else {
|
|
10677
|
+
const text = title.textContent || summary;
|
|
10678
|
+
title.textContent = "";
|
|
10679
|
+
appendCharSpans(title, text, 0);
|
|
10680
|
+
}
|
|
10681
|
+
}
|
|
10682
|
+
} else if (currentTemplate) {
|
|
10683
|
+
renderFormattedTitle(currentTemplate, false);
|
|
10684
|
+
}
|
|
10685
|
+
}
|
|
10416
10686
|
let toggleIcon = null;
|
|
10417
10687
|
if (expandable) {
|
|
10418
10688
|
toggleIcon = createElement("div", "persona-flex persona-items-center");
|
|
@@ -10437,7 +10707,7 @@ var createToolBubble = (message, config) => {
|
|
|
10437
10707
|
collapsedPreview.style.display = "none";
|
|
10438
10708
|
collapsedPreview.style.whiteSpace = "pre-wrap";
|
|
10439
10709
|
if (!expanded && isActive && toolDisplayConfig.activePreview && previewText) {
|
|
10440
|
-
const renderedPreview = (
|
|
10710
|
+
const renderedPreview = (_i = toolCallConfig.renderCollapsedPreview) == null ? void 0 : _i.call(toolCallConfig, {
|
|
10441
10711
|
message,
|
|
10442
10712
|
toolCall: tool,
|
|
10443
10713
|
defaultPreview: previewText,
|
|
@@ -14830,8 +15100,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
14830
15100
|
let scrollRAF = null;
|
|
14831
15101
|
let isAutoScrolling = false;
|
|
14832
15102
|
let hasPendingAutoScroll = false;
|
|
14833
|
-
const USER_SCROLL_THRESHOLD =
|
|
14834
|
-
const BOTTOM_THRESHOLD =
|
|
15103
|
+
const USER_SCROLL_THRESHOLD = 4;
|
|
15104
|
+
const BOTTOM_THRESHOLD = 24;
|
|
15105
|
+
const AUTO_SCROLL_SNAP_THRESHOLD = 80;
|
|
14835
15106
|
const messageState = /* @__PURE__ */ new Map();
|
|
14836
15107
|
const voiceState = {
|
|
14837
15108
|
active: false,
|
|
@@ -14972,6 +15243,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
14972
15243
|
lastScrollTop = element.scrollTop;
|
|
14973
15244
|
return;
|
|
14974
15245
|
}
|
|
15246
|
+
if (Math.abs(distance) >= AUTO_SCROLL_SNAP_THRESHOLD) {
|
|
15247
|
+
cancelSmoothScroll();
|
|
15248
|
+
isAutoScrolling = true;
|
|
15249
|
+
element.scrollTop = target;
|
|
15250
|
+
lastScrollTop = element.scrollTop;
|
|
15251
|
+
isAutoScrolling = false;
|
|
15252
|
+
return;
|
|
15253
|
+
}
|
|
14975
15254
|
cancelSmoothScroll();
|
|
14976
15255
|
const startTime = performance.now();
|
|
14977
15256
|
isAutoScrolling = true;
|
|
@@ -15580,9 +15859,28 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
15580
15859
|
}
|
|
15581
15860
|
};
|
|
15582
15861
|
}
|
|
15862
|
+
let toolElapsedTimerId = null;
|
|
15863
|
+
const ensureToolElapsedTimer = () => {
|
|
15864
|
+
if (toolElapsedTimerId != null) return;
|
|
15865
|
+
toolElapsedTimerId = setInterval(() => {
|
|
15866
|
+
const spans = messagesWrapper.querySelectorAll("[data-tool-elapsed]");
|
|
15867
|
+
if (spans.length === 0) {
|
|
15868
|
+
clearInterval(toolElapsedTimerId);
|
|
15869
|
+
toolElapsedTimerId = null;
|
|
15870
|
+
return;
|
|
15871
|
+
}
|
|
15872
|
+
const now = Date.now();
|
|
15873
|
+
spans.forEach((span) => {
|
|
15874
|
+
const startedAt = Number(span.getAttribute("data-tool-elapsed"));
|
|
15875
|
+
if (!startedAt) return;
|
|
15876
|
+
span.textContent = formatElapsedMs(now - startedAt);
|
|
15877
|
+
});
|
|
15878
|
+
}, 100);
|
|
15879
|
+
};
|
|
15583
15880
|
session = new AgentWidgetSession(config, {
|
|
15584
15881
|
onMessagesChanged(messages) {
|
|
15585
15882
|
renderMessagesWithPlugins(messagesWrapper, messages, postprocess);
|
|
15883
|
+
ensureToolElapsedTimer();
|
|
15586
15884
|
if (session) {
|
|
15587
15885
|
const hasUserMessage = messages.some((msg) => msg.role === "user");
|
|
15588
15886
|
if (hasUserMessage) {
|
|
@@ -17745,6 +18043,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
17745
18043
|
return session.submitNPSFeedback(rating, comment);
|
|
17746
18044
|
},
|
|
17747
18045
|
destroy() {
|
|
18046
|
+
if (toolElapsedTimerId != null) {
|
|
18047
|
+
clearInterval(toolElapsedTimerId);
|
|
18048
|
+
toolElapsedTimerId = null;
|
|
18049
|
+
}
|
|
17748
18050
|
destroyCallbacks.forEach((cb) => cb());
|
|
17749
18051
|
wrapper.remove();
|
|
17750
18052
|
launcherButtonInstance == null ? void 0 : launcherButtonInstance.destroy();
|