vanilla-agent 1.23.0 → 1.25.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 +24 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -7
- package/dist/index.d.ts +70 -7
- package/dist/index.global.js +69 -68
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +24 -23
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/widget.css +0 -4
- package/package.json +1 -1
- package/src/components/feedback.ts +2 -0
- package/src/defaults.ts +86 -36
- package/src/index.ts +6 -1
- package/src/install.ts +24 -1
- package/src/styles/widget.css +0 -4
- package/src/types.ts +61 -6
- package/src/ui.ts +32 -1
- package/src/utils/code-generators.ts +514 -414
- package/src/utils/message-id.ts +2 -0
- package/src/utils/theme.ts +86 -6
package/dist/install.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var SiteAgentInstaller=(()=>{(function(){"use strict";if(window.__siteAgentInstallerLoaded)return;window.__siteAgentInstallerLoaded=!0;let
|
|
1
|
+
"use strict";var SiteAgentInstaller=(()=>{(function(){"use strict";if(window.__siteAgentInstallerLoaded)return;window.__siteAgentInstallerLoaded=!0;let g=(()=>{let n=document.currentScript;if(!n)return{};let t={},i=n.getAttribute("data-config");if(i)try{let s=JSON.parse(i);s.config?Object.assign(t,s):t.config=s}catch(s){console.error("Failed to parse data-config JSON:",s)}let o=n.getAttribute("data-travrse-token");o&&(t.clientToken=o);let c=n.getAttribute("data-flow-id");c&&(t.flowId=c);let d=n.getAttribute("data-api-url");return d&&(t.apiUrl=d),t})(),e={...window.siteAgentConfig||{},...g},f=e.version||"latest",u=e.cdn||"jsdelivr",p=e.autoInit!==!1,w=()=>{if(e.cssUrl&&e.jsUrl)return{cssUrl:e.cssUrl,jsUrl:e.jsUrl};let t=`/npm/vanilla-agent@${f}/dist`;return u==="unpkg"?{cssUrl:`https://unpkg.com${t}/widget.css`,jsUrl:`https://unpkg.com${t}/index.global.js`}:{cssUrl:`https://cdn.jsdelivr.net${t}/widget.css`,jsUrl:`https://cdn.jsdelivr.net${t}/index.global.js`}},{cssUrl:r,jsUrl:a}=w(),A=()=>!!document.head.querySelector("link[data-vanilla-agent]")||!!document.head.querySelector('link[href*="widget.css"]'),m=()=>!!window.AgentWidget,C=()=>new Promise((n,t)=>{if(A()){n();return}let i=document.createElement("link");i.rel="stylesheet",i.href=r,i.setAttribute("data-vanilla-agent","true"),i.onload=()=>n(),i.onerror=()=>t(new Error(`Failed to load CSS from ${r}`)),document.head.appendChild(i)}),k=()=>new Promise((n,t)=>{if(m()){n();return}let i=document.createElement("script");i.src=a,i.async=!0,i.onload=()=>n(),i.onerror=()=>t(new Error(`Failed to load JS from ${a}`)),document.head.appendChild(i)}),h=()=>{if(!window.AgentWidget||!window.AgentWidget.initAgentWidget){console.warn("AgentWidget not available. Make sure the script loaded successfully.");return}let n=e.target||"body",t={...e.config};if(e.apiUrl&&!t.apiUrl&&(t.apiUrl=e.apiUrl),e.clientToken&&!t.clientToken&&(t.clientToken=e.clientToken),e.flowId&&!t.flowId&&(t.flowId=e.flowId),!(!(t.apiUrl||t.clientToken)&&Object.keys(t).length===0)){!t.postprocessMessage&&window.AgentWidget.markdownPostprocessor&&(t.postprocessMessage=({text:o})=>window.AgentWidget.markdownPostprocessor(o));try{window.AgentWidget.initAgentWidget({target:n,config:t})}catch(o){console.error("Failed to initialize AgentWidget:",o)}}},l=async()=>{try{await C(),await k(),p&&(e.config||e.apiUrl||e.clientToken)&&setTimeout(h,0)}catch(n){console.error("Failed to install AgentWidget:",n)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",l):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\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}\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-travrse-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 // Client token from data attribute (primary method for client token mode)\n const token = script.getAttribute('data-travrse-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 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 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 = \"vanilla-agent\";\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-vanilla-agent]') ||\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 // 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-vanilla-agent\", \"true\");\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 try {\n window.AgentWidget.initAgentWidget({\n target,\n config: widgetConfig\n });\n } catch (error) {\n console.error(\"Failed to initialize AgentWidget:\", error);\n }\n };\n\n // Main installation flow\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\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", install);\n } else {\n install();\n }\n})();\n\n"],"mappings":"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","names":["scriptConfig","script","token","flowId","apiUrl","config","version","cdn","autoInit","getCdnBase","basePath","cssUrl","jsUrl","isCssLoaded","isJsLoaded","loadCSS","resolve","reject","link","loadJS","initWidget","target","widgetConfig","error","install"]}
|
|
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\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}\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-travrse-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 Object.assign(scriptConfig, parsedConfig);\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-travrse-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 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 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 = \"vanilla-agent\";\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-vanilla-agent]') ||\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 // 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-vanilla-agent\", \"true\");\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 });\n } catch (error) {\n console.error(\"Failed to initialize AgentWidget:\", error);\n }\n };\n\n // Main installation flow\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\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", install);\n } else {\n install();\n }\n})();\n\n"],"mappings":"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","names":["scriptConfig","script","configJson","parsedConfig","e","token","flowId","apiUrl","config","version","cdn","autoInit","getCdnBase","basePath","cssUrl","jsUrl","isCssLoaded","isJsLoaded","loadCSS","resolve","reject","link","loadJS","initWidget","target","widgetConfig","text","error","install"]}
|
package/dist/widget.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vanilla-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "Themeable, plugable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
package/src/defaults.ts
CHANGED
|
@@ -1,4 +1,82 @@
|
|
|
1
|
-
import type { AgentWidgetConfig } from "./types";
|
|
1
|
+
import type { AgentWidgetConfig, AgentWidgetTheme } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default light theme colors
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_LIGHT_THEME: AgentWidgetTheme = {
|
|
7
|
+
primary: "#111827",
|
|
8
|
+
accent: "#1d4ed8",
|
|
9
|
+
surface: "#ffffff",
|
|
10
|
+
muted: "#6b7280",
|
|
11
|
+
container: "#f8fafc",
|
|
12
|
+
border: "#f1f5f9",
|
|
13
|
+
divider: "#f1f5f9",
|
|
14
|
+
messageBorder: "#f1f5f9",
|
|
15
|
+
inputBackground: "#ffffff",
|
|
16
|
+
callToAction: "#000000",
|
|
17
|
+
callToActionBackground: "#ffffff",
|
|
18
|
+
sendButtonBackgroundColor: "#111827",
|
|
19
|
+
sendButtonTextColor: "#ffffff",
|
|
20
|
+
sendButtonBorderColor: "#60a5fa",
|
|
21
|
+
closeButtonColor: "#6b7280",
|
|
22
|
+
closeButtonBackgroundColor: "transparent",
|
|
23
|
+
closeButtonBorderColor: "",
|
|
24
|
+
clearChatIconColor: "#6b7280",
|
|
25
|
+
clearChatBackgroundColor: "transparent",
|
|
26
|
+
clearChatBorderColor: "transparent",
|
|
27
|
+
micIconColor: "#111827",
|
|
28
|
+
micBackgroundColor: "transparent",
|
|
29
|
+
micBorderColor: "transparent",
|
|
30
|
+
recordingIconColor: "#ffffff",
|
|
31
|
+
recordingBackgroundColor: "#ef4444",
|
|
32
|
+
recordingBorderColor: "transparent",
|
|
33
|
+
inputFontFamily: "sans-serif",
|
|
34
|
+
inputFontWeight: "400",
|
|
35
|
+
radiusSm: "0.75rem",
|
|
36
|
+
radiusMd: "1rem",
|
|
37
|
+
radiusLg: "1.5rem",
|
|
38
|
+
launcherRadius: "9999px",
|
|
39
|
+
buttonRadius: "9999px",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Default dark theme colors
|
|
44
|
+
*/
|
|
45
|
+
export const DEFAULT_DARK_THEME: AgentWidgetTheme = {
|
|
46
|
+
primary: "#f9fafb",
|
|
47
|
+
accent: "#3b82f6",
|
|
48
|
+
surface: "#1f2937",
|
|
49
|
+
muted: "#9ca3af",
|
|
50
|
+
container: "#111827",
|
|
51
|
+
border: "#374151",
|
|
52
|
+
divider: "#374151",
|
|
53
|
+
messageBorder: "#374151",
|
|
54
|
+
inputBackground: "#111827",
|
|
55
|
+
callToAction: "#ffffff",
|
|
56
|
+
callToActionBackground: "#374151",
|
|
57
|
+
sendButtonBackgroundColor: "#3b82f6",
|
|
58
|
+
sendButtonTextColor: "#ffffff",
|
|
59
|
+
sendButtonBorderColor: "#60a5fa",
|
|
60
|
+
closeButtonColor: "#9ca3af",
|
|
61
|
+
closeButtonBackgroundColor: "transparent",
|
|
62
|
+
closeButtonBorderColor: "",
|
|
63
|
+
clearChatIconColor: "#9ca3af",
|
|
64
|
+
clearChatBackgroundColor: "transparent",
|
|
65
|
+
clearChatBorderColor: "transparent",
|
|
66
|
+
micIconColor: "#f9fafb",
|
|
67
|
+
micBackgroundColor: "transparent",
|
|
68
|
+
micBorderColor: "transparent",
|
|
69
|
+
recordingIconColor: "#ffffff",
|
|
70
|
+
recordingBackgroundColor: "#ef4444",
|
|
71
|
+
recordingBorderColor: "transparent",
|
|
72
|
+
inputFontFamily: "sans-serif",
|
|
73
|
+
inputFontWeight: "400",
|
|
74
|
+
radiusSm: "0.75rem",
|
|
75
|
+
radiusMd: "1rem",
|
|
76
|
+
radiusLg: "1.5rem",
|
|
77
|
+
launcherRadius: "9999px",
|
|
78
|
+
buttonRadius: "9999px",
|
|
79
|
+
};
|
|
2
80
|
|
|
3
81
|
/**
|
|
4
82
|
* Default widget configuration
|
|
@@ -8,41 +86,9 @@ export const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {
|
|
|
8
86
|
apiUrl: "http://localhost:43111/api/chat/dispatch",
|
|
9
87
|
// Client token mode defaults (optional, only used when clientToken is set)
|
|
10
88
|
clientToken: undefined,
|
|
11
|
-
theme:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
surface: "#ffffff",
|
|
15
|
-
muted: "#6b7280",
|
|
16
|
-
container: "#f8fafc",
|
|
17
|
-
border: "#f1f5f9",
|
|
18
|
-
divider: "#f1f5f9",
|
|
19
|
-
messageBorder: "#f1f5f9",
|
|
20
|
-
inputBackground: "#ffffff",
|
|
21
|
-
callToAction: "#000000",
|
|
22
|
-
callToActionBackground: "#ffffff",
|
|
23
|
-
sendButtonBackgroundColor: "#111827",
|
|
24
|
-
sendButtonTextColor: "#ffffff",
|
|
25
|
-
sendButtonBorderColor: "#60a5fa",
|
|
26
|
-
closeButtonColor: "#6b7280",
|
|
27
|
-
closeButtonBackgroundColor: "transparent",
|
|
28
|
-
closeButtonBorderColor: "",
|
|
29
|
-
clearChatIconColor: "#6b7280",
|
|
30
|
-
clearChatBackgroundColor: "transparent",
|
|
31
|
-
clearChatBorderColor: "transparent",
|
|
32
|
-
micIconColor: "#111827",
|
|
33
|
-
micBackgroundColor: "transparent",
|
|
34
|
-
micBorderColor: "transparent",
|
|
35
|
-
recordingIconColor: "#ffffff",
|
|
36
|
-
recordingBackgroundColor: "#ef4444",
|
|
37
|
-
recordingBorderColor: "transparent",
|
|
38
|
-
inputFontFamily: "sans-serif",
|
|
39
|
-
inputFontWeight: "400",
|
|
40
|
-
radiusSm: "0.75rem",
|
|
41
|
-
radiusMd: "1rem",
|
|
42
|
-
radiusLg: "1.5rem",
|
|
43
|
-
launcherRadius: "9999px",
|
|
44
|
-
buttonRadius: "9999px",
|
|
45
|
-
},
|
|
89
|
+
theme: DEFAULT_LIGHT_THEME,
|
|
90
|
+
darkTheme: DEFAULT_DARK_THEME,
|
|
91
|
+
colorScheme: "light",
|
|
46
92
|
launcher: {
|
|
47
93
|
enabled: true,
|
|
48
94
|
title: "Chat Assistant",
|
|
@@ -198,6 +244,10 @@ export function mergeWithDefaults(
|
|
|
198
244
|
...DEFAULT_WIDGET_CONFIG.theme,
|
|
199
245
|
...config.theme,
|
|
200
246
|
},
|
|
247
|
+
darkTheme: {
|
|
248
|
+
...DEFAULT_WIDGET_CONFIG.darkTheme,
|
|
249
|
+
...config.darkTheme,
|
|
250
|
+
},
|
|
201
251
|
launcher: {
|
|
202
252
|
...DEFAULT_WIDGET_CONFIG.launcher,
|
|
203
253
|
...config.launcher,
|
package/src/index.ts
CHANGED
|
@@ -105,7 +105,12 @@ export {
|
|
|
105
105
|
} from "./utils/component-middleware";
|
|
106
106
|
|
|
107
107
|
// Default configuration exports
|
|
108
|
-
export {
|
|
108
|
+
export {
|
|
109
|
+
DEFAULT_WIDGET_CONFIG,
|
|
110
|
+
DEFAULT_LIGHT_THEME,
|
|
111
|
+
DEFAULT_DARK_THEME,
|
|
112
|
+
mergeWithDefaults
|
|
113
|
+
} from "./defaults";
|
|
109
114
|
|
|
110
115
|
// Layout system exports
|
|
111
116
|
export {
|
package/src/install.ts
CHANGED
|
@@ -36,7 +36,7 @@ declare global {
|
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Read configuration from data attributes on the current script tag.
|
|
39
|
-
* Supports: data-travrse-token, data-flow-id, data-api-url
|
|
39
|
+
* Supports: data-config (JSON), data-travrse-token, data-flow-id, data-api-url
|
|
40
40
|
*/
|
|
41
41
|
const getConfigFromScript = (): Partial<SiteAgentInstallConfig> => {
|
|
42
42
|
// Try to get the current script element
|
|
@@ -45,6 +45,23 @@ declare global {
|
|
|
45
45
|
|
|
46
46
|
const scriptConfig: Partial<SiteAgentInstallConfig> = {};
|
|
47
47
|
|
|
48
|
+
// Full config from data-config attribute (JSON string)
|
|
49
|
+
const configJson = script.getAttribute('data-config');
|
|
50
|
+
if (configJson) {
|
|
51
|
+
try {
|
|
52
|
+
const parsedConfig = JSON.parse(configJson);
|
|
53
|
+
// If it has nested 'config' property, use it; otherwise treat as widget config
|
|
54
|
+
if (parsedConfig.config) {
|
|
55
|
+
Object.assign(scriptConfig, parsedConfig);
|
|
56
|
+
} else {
|
|
57
|
+
// Treat the entire object as widget config
|
|
58
|
+
scriptConfig.config = parsedConfig;
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.error("Failed to parse data-config JSON:", e);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
// Client token from data attribute (primary method for client token mode)
|
|
49
66
|
const token = script.getAttribute('data-travrse-token');
|
|
50
67
|
if (token) {
|
|
@@ -179,6 +196,12 @@ declare global {
|
|
|
179
196
|
return;
|
|
180
197
|
}
|
|
181
198
|
|
|
199
|
+
// Auto-apply markdown postprocessor if not explicitly set and available
|
|
200
|
+
if (!widgetConfig.postprocessMessage && window.AgentWidget.markdownPostprocessor) {
|
|
201
|
+
widgetConfig.postprocessMessage = ({ text }: { text: string }) =>
|
|
202
|
+
window.AgentWidget.markdownPostprocessor(text);
|
|
203
|
+
}
|
|
204
|
+
|
|
182
205
|
try {
|
|
183
206
|
window.AgentWidget.initAgentWidget({
|
|
184
207
|
target,
|
package/src/styles/widget.css
CHANGED
package/src/types.ts
CHANGED
|
@@ -105,6 +105,23 @@ export type AgentWidgetMessageFeedback = {
|
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Configuration for message action buttons (copy, upvote, downvote)
|
|
108
|
+
*
|
|
109
|
+
* **Client Token Mode**: When using `clientToken`, feedback is automatically
|
|
110
|
+
* sent to your Travrse backend. Just enable the buttons and you're done!
|
|
111
|
+
* The `onFeedback` and `onCopy` callbacks are optional for additional local handling.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* // With clientToken - feedback is automatic!
|
|
116
|
+
* config: {
|
|
117
|
+
* clientToken: 'ct_live_...',
|
|
118
|
+
* messageActions: {
|
|
119
|
+
* showUpvote: true,
|
|
120
|
+
* showDownvote: true,
|
|
121
|
+
* // No onFeedback needed - sent to backend automatically
|
|
122
|
+
* }
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
108
125
|
*/
|
|
109
126
|
export type AgentWidgetMessageActionsConfig = {
|
|
110
127
|
/**
|
|
@@ -118,13 +135,15 @@ export type AgentWidgetMessageActionsConfig = {
|
|
|
118
135
|
*/
|
|
119
136
|
showCopy?: boolean;
|
|
120
137
|
/**
|
|
121
|
-
* Show upvote button
|
|
122
|
-
*
|
|
138
|
+
* Show upvote button.
|
|
139
|
+
* When using `clientToken`, feedback is sent to the backend automatically.
|
|
140
|
+
* @default false
|
|
123
141
|
*/
|
|
124
142
|
showUpvote?: boolean;
|
|
125
143
|
/**
|
|
126
|
-
* Show downvote button
|
|
127
|
-
*
|
|
144
|
+
* Show downvote button.
|
|
145
|
+
* When using `clientToken`, feedback is sent to the backend automatically.
|
|
146
|
+
* @default false
|
|
128
147
|
*/
|
|
129
148
|
showDownvote?: boolean;
|
|
130
149
|
/**
|
|
@@ -145,11 +164,19 @@ export type AgentWidgetMessageActionsConfig = {
|
|
|
145
164
|
*/
|
|
146
165
|
layout?: "pill-inside" | "row-inside";
|
|
147
166
|
/**
|
|
148
|
-
* Callback when user submits feedback (upvote/downvote)
|
|
167
|
+
* Callback when user submits feedback (upvote/downvote).
|
|
168
|
+
*
|
|
169
|
+
* **Note**: When using `clientToken`, feedback is AUTOMATICALLY sent to your
|
|
170
|
+
* backend via `/v1/client/feedback`. This callback is called IN ADDITION to
|
|
171
|
+
* the automatic submission, useful for updating local UI or analytics.
|
|
149
172
|
*/
|
|
150
173
|
onFeedback?: (feedback: AgentWidgetMessageFeedback) => void;
|
|
151
174
|
/**
|
|
152
|
-
* Callback when user copies a message
|
|
175
|
+
* Callback when user copies a message.
|
|
176
|
+
*
|
|
177
|
+
* **Note**: When using `clientToken`, copy events are AUTOMATICALLY tracked
|
|
178
|
+
* via `/v1/client/feedback`. This callback is called IN ADDITION to the
|
|
179
|
+
* automatic tracking.
|
|
153
180
|
*/
|
|
154
181
|
onCopy?: (message: AgentWidgetMessage) => void;
|
|
155
182
|
};
|
|
@@ -1097,6 +1124,34 @@ export type AgentWidgetConfig = {
|
|
|
1097
1124
|
sendButtonLabel?: string;
|
|
1098
1125
|
};
|
|
1099
1126
|
theme?: AgentWidgetTheme;
|
|
1127
|
+
/**
|
|
1128
|
+
* Theme colors for dark mode. Applied when dark mode is detected
|
|
1129
|
+
* (when colorScheme is 'dark' or 'auto' with dark mode active).
|
|
1130
|
+
* If not provided, falls back to `theme` colors.
|
|
1131
|
+
*
|
|
1132
|
+
* @example
|
|
1133
|
+
* ```typescript
|
|
1134
|
+
* config: {
|
|
1135
|
+
* theme: { primary: '#111827', surface: '#ffffff' },
|
|
1136
|
+
* darkTheme: { primary: '#f9fafb', surface: '#1f2937' },
|
|
1137
|
+
* colorScheme: 'auto'
|
|
1138
|
+
* }
|
|
1139
|
+
* ```
|
|
1140
|
+
*/
|
|
1141
|
+
darkTheme?: AgentWidgetTheme;
|
|
1142
|
+
/**
|
|
1143
|
+
* Color scheme mode for the widget.
|
|
1144
|
+
* - 'light': Always use light theme (default)
|
|
1145
|
+
* - 'dark': Always use dark theme
|
|
1146
|
+
* - 'auto': Automatically detect from page (HTML class or prefers-color-scheme)
|
|
1147
|
+
*
|
|
1148
|
+
* When 'auto', detection order:
|
|
1149
|
+
* 1. Check if `<html>` has 'dark' class
|
|
1150
|
+
* 2. Fall back to `prefers-color-scheme: dark` media query
|
|
1151
|
+
*
|
|
1152
|
+
* @default 'light'
|
|
1153
|
+
*/
|
|
1154
|
+
colorScheme?: 'auto' | 'light' | 'dark';
|
|
1100
1155
|
features?: AgentWidgetFeatureFlags;
|
|
1101
1156
|
launcher?: AgentWidgetLauncherConfig;
|
|
1102
1157
|
initialMessages?: AgentWidgetMessage[];
|
package/src/ui.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
SlotRenderer,
|
|
15
15
|
AgentWidgetMessageFeedback
|
|
16
16
|
} from "./types";
|
|
17
|
-
import { applyThemeVariables } from "./utils/theme";
|
|
17
|
+
import { applyThemeVariables, createThemeObserver } from "./utils/theme";
|
|
18
18
|
import { renderLucideIcon } from "./utils/icons";
|
|
19
19
|
import { createElement } from "./utils/dom";
|
|
20
20
|
import { statusCopy } from "./utils/constants";
|
|
@@ -642,6 +642,31 @@ export const createAgentExperience = (
|
|
|
642
642
|
applyThemeVariables(mount, config);
|
|
643
643
|
|
|
644
644
|
const destroyCallbacks: Array<() => void> = [];
|
|
645
|
+
|
|
646
|
+
// Set up theme observer for auto color scheme detection
|
|
647
|
+
let cleanupThemeObserver: (() => void) | null = null;
|
|
648
|
+
const setupThemeObserver = () => {
|
|
649
|
+
// Clean up existing observer if any
|
|
650
|
+
if (cleanupThemeObserver) {
|
|
651
|
+
cleanupThemeObserver();
|
|
652
|
+
cleanupThemeObserver = null;
|
|
653
|
+
}
|
|
654
|
+
// Set up new observer if colorScheme is 'auto'
|
|
655
|
+
if (config.colorScheme === 'auto') {
|
|
656
|
+
cleanupThemeObserver = createThemeObserver(() => {
|
|
657
|
+
// Re-apply theme when color scheme changes
|
|
658
|
+
applyThemeVariables(mount, config);
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
setupThemeObserver();
|
|
663
|
+
destroyCallbacks.push(() => {
|
|
664
|
+
if (cleanupThemeObserver) {
|
|
665
|
+
cleanupThemeObserver();
|
|
666
|
+
cleanupThemeObserver = null;
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
|
|
645
670
|
const suggestionsManager = createSuggestions(suggestions);
|
|
646
671
|
let closeHandler: (() => void) | null = null;
|
|
647
672
|
let session: AgentWidgetSession;
|
|
@@ -1811,11 +1836,17 @@ export const createAgentExperience = (
|
|
|
1811
1836
|
const controller: Controller = {
|
|
1812
1837
|
update(nextConfig: AgentWidgetConfig) {
|
|
1813
1838
|
const previousToolCallConfig = config.toolCall;
|
|
1839
|
+
const previousColorScheme = config.colorScheme;
|
|
1814
1840
|
config = { ...config, ...nextConfig };
|
|
1815
1841
|
// applyFullHeightStyles resets mount.style.cssText, so call it before applyThemeVariables
|
|
1816
1842
|
applyFullHeightStyles();
|
|
1817
1843
|
applyThemeVariables(mount, config);
|
|
1818
1844
|
|
|
1845
|
+
// Re-setup theme observer if colorScheme changed
|
|
1846
|
+
if (config.colorScheme !== previousColorScheme) {
|
|
1847
|
+
setupThemeObserver();
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1819
1850
|
// Update plugins
|
|
1820
1851
|
const newPlugins = pluginRegistry.getForInstance(config.plugins);
|
|
1821
1852
|
plugins.length = 0;
|