vanilla-agent 1.29.0 → 1.30.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 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +46 -46
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +24 -24
- package/dist/index.js.map +1 -1
- package/dist/widget.css +6 -2
- package/package.json +2 -1
- package/src/@types/idiomorph.d.ts +37 -0
- package/src/components/message-bubble.ts +6 -0
- package/src/components/reasoning-bubble.ts +3 -0
- package/src/components/tool-bubble.ts +3 -0
- package/src/styles/widget.css +6 -2
- package/src/ui.ts +137 -26
- package/src/utils/morph.ts +36 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/postprocessors.ts","../src/utils/formatting.ts","../src/client.ts","../src/utils/message-id.ts","../src/session.ts","../src/utils/theme.ts","../src/utils/icons.ts","../src/utils/dom.ts","../src/utils/constants.ts","../src/utils/positioning.ts","../src/components/launcher.ts","../src/components/header-builder.ts","../src/components/header-layouts.ts","../src/components/composer-builder.ts","../src/components/panel.ts","../src/components/message-bubble.ts","../src/components/reasoning-bubble.ts","../src/components/tool-bubble.ts","../src/components/suggestions.ts","../src/components/forms.ts","../src/plugins/registry.ts","../src/defaults.ts","../src/utils/events.ts","../src/utils/actions.ts","../src/utils/storage.ts","../src/components/registry.ts","../src/utils/component-parser.ts","../src/utils/component-middleware.ts","../src/components/feedback.ts","../src/ui.ts","../src/runtime/init.ts","../src/utils/code-generators.ts"],"sourcesContent":["import {\n initAgentWidget as initAgentWidgetFn,\n type AgentWidgetInitHandle\n} from \"./runtime/init\";\n\nexport type {\n AgentWidgetConfig,\n AgentWidgetTheme,\n AgentWidgetFeatureFlags,\n AgentWidgetInitOptions,\n AgentWidgetMessage,\n AgentWidgetLauncherConfig,\n AgentWidgetEvent,\n AgentWidgetStreamParser,\n AgentWidgetStreamParserResult,\n AgentWidgetRequestPayload,\n AgentWidgetCustomFetch,\n AgentWidgetSSEEventParser,\n AgentWidgetSSEEventResult,\n AgentWidgetHeadersFunction,\n // Layout types\n AgentWidgetLayoutConfig,\n AgentWidgetHeaderLayoutConfig,\n AgentWidgetMessageLayoutConfig,\n AgentWidgetAvatarConfig,\n AgentWidgetTimestampConfig,\n WidgetLayoutSlot,\n SlotRenderer,\n SlotRenderContext,\n HeaderRenderContext,\n MessageRenderContext,\n // Markdown types\n AgentWidgetMarkdownConfig,\n AgentWidgetMarkdownOptions,\n AgentWidgetMarkdownRendererOverrides,\n // Message actions types\n AgentWidgetMessageActionsConfig,\n AgentWidgetMessageFeedback,\n // Client token types\n ClientSession,\n ClientInitResponse,\n ClientChatRequest,\n ClientFeedbackRequest,\n ClientFeedbackType\n} from \"./types\";\n\nexport { initAgentWidgetFn as initAgentWidget };\nexport {\n createAgentExperience,\n type AgentWidgetController\n} from \"./ui\";\nexport {\n AgentWidgetSession,\n type AgentWidgetSessionStatus\n} from \"./session\";\nexport { AgentWidgetClient } from \"./client\";\nexport { createLocalStorageAdapter } from \"./utils/storage\";\nexport {\n createActionManager,\n defaultActionHandlers,\n defaultJsonActionParser\n} from \"./utils/actions\";\nexport {\n markdownPostprocessor,\n escapeHtml,\n directivePostprocessor,\n createMarkdownProcessor,\n createMarkdownProcessorFromConfig,\n createDirectivePostprocessor\n} from \"./postprocessors\";\nexport type { MarkdownProcessorOptions } from \"./postprocessors\";\nexport {\n createPlainTextParser,\n createJsonStreamParser,\n createFlexibleJsonStreamParser,\n createRegexJsonParser,\n createXmlParser\n} from \"./utils/formatting\";\nexport {\n generateMessageId,\n generateUserMessageId,\n generateAssistantMessageId\n} from \"./utils/message-id\";\nexport { generateCodeSnippet } from \"./utils/code-generators\";\nexport type { CodeFormat } from \"./utils/code-generators\";\nexport type { AgentWidgetInitHandle };\n\n// Plugin system exports\nexport type { AgentWidgetPlugin } from \"./plugins/types\";\nexport { pluginRegistry } from \"./plugins/registry\";\n\n// Component system exports\nexport { componentRegistry } from \"./components/registry\";\nexport type { ComponentRenderer, ComponentContext } from \"./components/registry\";\nexport {\n createComponentStreamParser,\n isComponentDirectiveType\n} from \"./utils/component-parser\";\nexport type { ComponentDirective } from \"./utils/component-parser\";\nexport {\n renderComponentDirective,\n createComponentMiddleware,\n hasComponentDirective,\n extractComponentDirectiveFromMessage\n} from \"./utils/component-middleware\";\n\n// Default configuration exports\nexport {\n DEFAULT_WIDGET_CONFIG,\n DEFAULT_LIGHT_THEME,\n DEFAULT_DARK_THEME,\n mergeWithDefaults\n} from \"./defaults\";\n\n// Layout system exports\nexport {\n buildHeader,\n buildComposer,\n attachHeaderToContainer\n} from \"./components/panel\";\nexport type {\n HeaderElements,\n HeaderBuildContext,\n ComposerElements,\n ComposerBuildContext\n} from \"./components/panel\";\nexport {\n headerLayouts,\n getHeaderLayout,\n buildHeaderWithLayout,\n buildDefaultHeader,\n buildMinimalHeader,\n buildExpandedHeader\n} from \"./components/header-layouts\";\nexport type {\n HeaderLayoutContext,\n HeaderLayoutRenderer\n} from \"./components/header-layouts\";\nexport {\n createStandardBubble,\n createBubbleWithLayout,\n createTypingIndicator,\n createMessageActions\n} from \"./components/message-bubble\";\nexport type { MessageTransform, MessageActionCallbacks } from \"./components/message-bubble\";\nexport {\n createCSATFeedback,\n createNPSFeedback\n} from \"./components/feedback\";\nexport type { CSATFeedbackOptions, NPSFeedbackOptions } from \"./components/feedback\";\n\nexport default initAgentWidgetFn;\n","import { Marked, type RendererObject } from \"marked\";\nimport type { AgentWidgetMarkdownConfig, AgentWidgetMarkdownRendererOverrides, AgentWidgetMarkdownOptions } from \"./types\";\n\n/**\n * Options for creating a markdown processor\n */\nexport type MarkdownProcessorOptions = {\n /** Marked parsing options */\n markedOptions?: AgentWidgetMarkdownOptions;\n /** Custom renderer overrides */\n renderer?: AgentWidgetMarkdownRendererOverrides;\n};\n\n/**\n * Converts AgentWidgetMarkdownRendererOverrides to marked's RendererObject format\n */\nconst convertRendererOverrides = (\n overrides?: AgentWidgetMarkdownRendererOverrides\n): Partial<RendererObject> | undefined => {\n if (!overrides) return undefined;\n \n // The token-based API in marked v12+ matches our type definitions\n // We can pass through the overrides directly\n return overrides as Partial<RendererObject>;\n};\n\n/**\n * Creates a configured markdown processor with custom options and renderers.\n * \n * @param options - Configuration options for the markdown processor\n * @returns A function that converts markdown text to HTML\n * \n * @example\n * ```typescript\n * // Basic usage with defaults\n * const processor = createMarkdownProcessor();\n * const html = processor(\"# Hello World\");\n * \n * // With custom options\n * const processor = createMarkdownProcessor({\n * markedOptions: { gfm: true, breaks: true },\n * renderer: {\n * link(token) {\n * return `<a href=\"${token.href}\" target=\"_blank\">${token.text}</a>`;\n * }\n * }\n * });\n * ```\n */\nexport const createMarkdownProcessor = (options?: MarkdownProcessorOptions) => {\n const opts = options?.markedOptions;\n const markedInstance = new Marked({\n gfm: opts?.gfm ?? true,\n breaks: opts?.breaks ?? true,\n pedantic: opts?.pedantic,\n silent: opts?.silent,\n });\n \n const rendererOverrides = convertRendererOverrides(options?.renderer);\n if (rendererOverrides) {\n markedInstance.use({ renderer: rendererOverrides });\n }\n \n return (text: string): string => {\n return markedInstance.parse(text) as string;\n };\n};\n\n/**\n * Creates a markdown processor from AgentWidgetMarkdownConfig.\n * This is a convenience function that maps the widget config to processor options.\n * \n * @param config - The markdown configuration from widget config\n * @returns A function that converts markdown text to HTML\n */\nexport const createMarkdownProcessorFromConfig = (config?: AgentWidgetMarkdownConfig) => {\n if (!config) {\n return createMarkdownProcessor();\n }\n \n return createMarkdownProcessor({\n markedOptions: config.options,\n renderer: config.renderer,\n });\n};\n\n// Create default markdown processor instance\nconst defaultMarkdownProcessor = createMarkdownProcessor();\n\n/**\n * Basic markdown renderer using default settings.\n * Remember to sanitize the returned HTML if you render untrusted content in your host page.\n * \n * For custom configuration, use `createMarkdownProcessor()` or `createMarkdownProcessorFromConfig()`.\n */\nexport const markdownPostprocessor = (text: string): string => {\n return defaultMarkdownProcessor(text);\n};\n\n/**\n * Escapes HTML entities. Used as the default safe renderer.\n */\nexport const escapeHtml = (text: string): string =>\n text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n\nconst escapeAttribute = (value: string) =>\n value.replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n\nconst makeToken = (idx: number) => `%%FORM_PLACEHOLDER_${idx}%%`;\n\nconst directiveReplacer = (source: string, placeholders: Array<{ token: string; type: string }>) => {\n let working = source;\n\n // JSON directive pattern e.g. <Directive>{\"component\":\"form\",\"type\":\"init\"}</Directive>\n working = working.replace(/<Directive>([\\s\\S]*?)<\\/Directive>/gi, (match, jsonText) => {\n try {\n const parsed = JSON.parse(jsonText.trim());\n if (parsed && typeof parsed === \"object\" && parsed.component === \"form\" && parsed.type) {\n const token = makeToken(placeholders.length);\n placeholders.push({ token, type: String(parsed.type) });\n return token;\n }\n } catch (error) {\n return match;\n }\n return match;\n });\n\n // XML-style directive e.g. <Form type=\"init\" />\n working = working.replace(/<Form\\s+type=\"([^\"]+)\"\\s*\\/>/gi, (_, type) => {\n const token = makeToken(placeholders.length);\n placeholders.push({ token, type });\n return token;\n });\n\n return working;\n};\n\n/**\n * Creates a directive postprocessor with custom markdown configuration.\n * Converts special directives (either `<Form type=\"init\" />` or\n * `<Directive>{\"component\":\"form\",\"type\":\"init\"}</Directive>`) into placeholder\n * elements that the widget upgrades after render. Remaining text is rendered as\n * Markdown with the provided configuration.\n * \n * @param markdownConfig - Optional markdown configuration\n * @returns A function that processes text with directives and markdown\n */\nexport const createDirectivePostprocessor = (markdownConfig?: AgentWidgetMarkdownConfig) => {\n const processor = createMarkdownProcessorFromConfig(markdownConfig);\n \n return (text: string): string => {\n const placeholders: Array<{ token: string; type: string }> = [];\n const withTokens = directiveReplacer(text, placeholders);\n let html = processor(withTokens);\n\n placeholders.forEach(({ token, type }) => {\n const tokenRegex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), \"g\");\n const safeType = escapeAttribute(type);\n const replacement = `<div class=\"tvw-form-directive\" data-tv-form=\"${safeType}\"></div>`;\n html = html.replace(tokenRegex, replacement);\n });\n\n return html;\n };\n};\n\n/**\n * Converts special directives (either `<Form type=\"init\" />` or\n * `<Directive>{\"component\":\"form\",\"type\":\"init\"}</Directive>`) into placeholder\n * elements that the widget upgrades after render. Remaining text is rendered as\n * Markdown using default settings.\n * \n * For custom markdown configuration, use `createDirectivePostprocessor()`.\n */\nexport const directivePostprocessor = (text: string): string => {\n const placeholders: Array<{ token: string; type: string }> = [];\n const withTokens = directiveReplacer(text, placeholders);\n let html = markdownPostprocessor(withTokens);\n\n placeholders.forEach(({ token, type }) => {\n const tokenRegex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), \"g\");\n const safeType = escapeAttribute(type);\n const replacement = `<div class=\"tvw-form-directive\" data-tv-form=\"${safeType}\"></div>`;\n html = html.replace(tokenRegex, replacement);\n });\n\n return html;\n};\n","import { AgentWidgetReasoning, AgentWidgetToolCall, AgentWidgetStreamParser, AgentWidgetStreamParserResult } from \"../types\";\nimport { parse as parsePartialJson, STR, OBJ } from \"partial-json\";\n\n/**\n * Unescapes JSON string escape sequences that LLMs often double-escape.\n * Converts literal \\n, \\r, \\t sequences to actual control characters.\n */\nconst unescapeJsonString = (str: string): string => {\n return str\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n};\n\nexport const formatUnknownValue = (value: unknown): string => {\n if (value === null) return \"null\";\n if (value === undefined) return \"\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch (error) {\n return String(value);\n }\n};\n\nexport const formatReasoningDuration = (reasoning: AgentWidgetReasoning) => {\n const end = reasoning.completedAt ?? Date.now();\n const start = reasoning.startedAt ?? end;\n const durationMs =\n reasoning.durationMs !== undefined\n ? reasoning.durationMs\n : Math.max(0, end - start);\n const seconds = durationMs / 1000;\n if (seconds < 0.1) {\n return \"Thought for <0.1 seconds\";\n }\n const formatted =\n seconds >= 10\n ? Math.round(seconds).toString()\n : seconds.toFixed(1).replace(/\\.0$/, \"\");\n return `Thought for ${formatted} seconds`;\n};\n\nexport const describeReasonStatus = (reasoning: AgentWidgetReasoning) => {\n if (reasoning.status === \"complete\") return formatReasoningDuration(reasoning);\n if (reasoning.status === \"pending\") return \"Waiting\";\n return \"\";\n};\n\nexport const formatToolDuration = (tool: AgentWidgetToolCall) => {\n const durationMs =\n typeof tool.duration === \"number\"\n ? tool.duration\n : typeof tool.durationMs === \"number\"\n ? tool.durationMs\n : Math.max(\n 0,\n (tool.completedAt ?? Date.now()) -\n (tool.startedAt ?? tool.completedAt ?? Date.now())\n );\n const seconds = durationMs / 1000;\n if (seconds < 0.1) {\n return \"Used tool for <0.1 seconds\";\n }\n const formatted =\n seconds >= 10\n ? Math.round(seconds).toString()\n : seconds.toFixed(1).replace(/\\.0$/, \"\");\n return `Used tool for ${formatted} seconds`;\n};\n\nexport const describeToolStatus = (status: AgentWidgetToolCall[\"status\"]) => {\n if (status === \"complete\") return \"\";\n if (status === \"pending\") return \"Starting\";\n return \"Running\";\n};\n\nexport const describeToolTitle = (tool: AgentWidgetToolCall) => {\n if (tool.status === \"complete\") {\n return formatToolDuration(tool);\n }\n return \"Using tool...\";\n};\n\n/**\n * Creates a regex-based parser for extracting text from JSON streams.\n * This is a simpler alternative to schema-stream that uses regex to extract\n * the 'text' field incrementally as JSON streams in.\n * \n * This can be used as an alternative parser option.\n */\nconst createRegexJsonParserInternal = (): {\n processChunk(accumulatedContent: string): Promise<AgentWidgetStreamParserResult | string | null>;\n getExtractedText(): string | null;\n close?(): Promise<void>;\n} => {\n let extractedText: string | null = null;\n let processedLength = 0;\n \n // Regex-based extraction for incremental JSON parsing\n const extractTextFromIncompleteJson = (jsonString: string): string | null => {\n // Look for \"text\": \"value\" pattern, handling incomplete strings\n // Match: \"text\": \" followed by any characters (including incomplete)\n const textFieldRegex = /\"text\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.|\")*?)\"/;\n const match = jsonString.match(textFieldRegex);\n \n if (match && match[1]) {\n // Unescape the string value\n try {\n // Replace escaped characters\n let unescaped = match[1]\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n return unescaped;\n } catch {\n return match[1];\n }\n }\n \n // Also try to match incomplete text field (text field that hasn't closed yet)\n // Look for \"text\": \" followed by content that may not be closed\n const incompleteTextFieldRegex = /\"text\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)/;\n const incompleteMatch = jsonString.match(incompleteTextFieldRegex);\n \n if (incompleteMatch && incompleteMatch[1]) {\n // Unescape the partial string value\n try {\n let unescaped = incompleteMatch[1]\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n return unescaped;\n } catch {\n return incompleteMatch[1];\n }\n }\n \n return null;\n };\n \n return {\n getExtractedText: () => extractedText,\n processChunk: async (accumulatedContent: string): Promise<AgentWidgetStreamParserResult | string | null> => {\n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedText !== null\n ? { text: extractedText, raw: accumulatedContent }\n : null;\n }\n \n // Validate that the accumulated content looks like valid JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n \n // Try to extract text field using regex\n const extracted = extractTextFromIncompleteJson(accumulatedContent);\n if (extracted !== null) {\n extractedText = extracted;\n }\n \n // Update processed length\n processedLength = accumulatedContent.length;\n \n // Return both the extracted text and raw JSON\n if (extractedText !== null) {\n return {\n text: extractedText,\n raw: accumulatedContent\n };\n }\n\n return null;\n },\n close: async () => {\n // No cleanup needed for regex-based parser\n }\n };\n};\n\n/**\n * Extracts the text field from JSON (works with partial JSON during streaming).\n * For complete JSON, uses fast path. For incomplete JSON, returns null (use stateful parser in client.ts).\n * \n * @param jsonString - The JSON string (can be partial/incomplete during streaming)\n * @returns The extracted text value, or null if not found or invalid\n */\nexport const extractTextFromJson = (jsonString: string): string | null => {\n try {\n // Try to parse complete JSON first (fast path)\n const parsed = JSON.parse(jsonString);\n if (parsed && typeof parsed === \"object\" && typeof parsed.text === \"string\") {\n return parsed.text;\n }\n } catch {\n // For incomplete JSON, return null - use stateful parser in client.ts\n return null;\n }\n return null;\n};\n\n/**\n * Plain text parser - passes through text as-is without any parsing.\n * This is the default parser.\n */\nexport const createPlainTextParser = (): AgentWidgetStreamParser => {\n const parser: AgentWidgetStreamParser = {\n processChunk: (accumulatedContent: string): string | null => {\n // Always return null to indicate this isn't a structured format\n // Content will be displayed as plain text\n return null;\n },\n getExtractedText: (): string | null => {\n return null;\n }\n };\n // Mark this as a plain text parser\n (parser as any).__isPlainTextParser = true;\n return parser;\n};\n\n/**\n * JSON parser using regex-based extraction.\n * Extracts the 'text' field from JSON responses using regex patterns.\n * This is a simpler regex-based alternative to createJsonStreamParser.\n * Less robust for complex/malformed JSON but has no external dependencies.\n */\nexport const createRegexJsonParser = (): AgentWidgetStreamParser => {\n const regexParser = createRegexJsonParserInternal();\n \n return {\n processChunk: async (accumulatedContent: string): Promise<AgentWidgetStreamParserResult | string | null> => {\n // Only process if it looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n return regexParser.processChunk(accumulatedContent);\n },\n getExtractedText: regexParser.getExtractedText.bind(regexParser),\n close: regexParser.close?.bind(regexParser)\n };\n};\n\n/**\n * JSON stream parser using partial-json library.\n * Extracts the 'text' field from JSON responses using the partial-json library,\n * which is specifically designed for parsing incomplete JSON from LLMs.\n * This is the recommended parser as it's more robust than regex.\n * \n * Library: https://github.com/promplate/partial-json-parser-js\n */\nexport const createJsonStreamParser = (): AgentWidgetStreamParser => {\n let extractedText: string | null = null;\n let processedLength = 0;\n \n return {\n getExtractedText: () => extractedText,\n processChunk: (accumulatedContent: string): AgentWidgetStreamParserResult | string | null => {\n // Validate that the accumulated content looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n \n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedText !== null || extractedText === \"\"\n ? { text: extractedText || \"\", raw: accumulatedContent }\n : null;\n }\n \n try {\n // Parse partial JSON - allow partial strings and objects\n // STR | OBJ allows incomplete strings and objects during streaming\n const parsed = parsePartialJson(accumulatedContent, STR | OBJ);\n \n if (parsed && typeof parsed === \"object\") {\n // Check for component directives - extract text if present for combined text+component\n if (parsed.component && typeof parsed.component === \"string\") {\n // For component directives, extract text if present, otherwise empty\n extractedText = typeof parsed.text === \"string\" ? unescapeJsonString(parsed.text) : \"\";\n }\n // Check for form directives - these also don't have text fields\n else if (parsed.type === \"init\" && parsed.form) {\n // For form directives, return empty - they're handled by form postprocessor\n extractedText = \"\";\n }\n // Extract text field if available\n else if (typeof parsed.text === \"string\") {\n extractedText = unescapeJsonString(parsed.text);\n }\n }\n } catch (error) {\n // If parsing fails completely, keep the last extracted text\n // This can happen with very malformed JSON\n }\n \n // Update processed length\n processedLength = accumulatedContent.length;\n \n // Always return raw JSON for component/form directive detection\n // Return empty string for text if it's a component/form directive\n if (extractedText !== null) {\n return {\n text: extractedText,\n raw: accumulatedContent\n };\n }\n\n return null;\n },\n close: () => {\n // No cleanup needed\n }\n };\n};\n\n/**\n * Flexible JSON stream parser that can extract text from various field names.\n * This parser looks for display text in multiple possible fields, making it\n * compatible with different JSON response formats.\n * \n * @param textExtractor Optional function to extract display text from parsed JSON.\n * If not provided, looks for common text fields.\n */\nexport const createFlexibleJsonStreamParser = (\n textExtractor?: (parsed: any) => string | null\n): AgentWidgetStreamParser => {\n let extractedText: string | null = null;\n let processedLength = 0;\n \n // Default text extractor that handles common patterns\n const defaultExtractor = (parsed: any): string | null => {\n if (!parsed || typeof parsed !== \"object\") return null;\n\n // Helper to safely extract and unescape text\n const getText = (value: any): string | null => {\n return typeof value === \"string\" ? unescapeJsonString(value) : null;\n };\n\n // Check for component directives - extract text if present for combined text+component\n if (parsed.component && typeof parsed.component === \"string\") {\n // For component directives, extract text if present, otherwise empty\n return typeof parsed.text === \"string\" ? unescapeJsonString(parsed.text) : \"\";\n }\n \n // Check for form directives - these also don't have text fields\n if (parsed.type === \"init\" && parsed.form) {\n // For form directives, return empty - they're handled by form postprocessor\n return \"\";\n }\n \n // Check for action-based text fields\n if (parsed.action) {\n switch (parsed.action) {\n case 'nav_then_click':\n return getText(parsed.on_load_text) || getText(parsed.text) || null;\n case 'message':\n case 'message_and_click':\n case 'checkout':\n return getText(parsed.text) || null;\n default:\n return getText(parsed.text) || getText(parsed.display_text) || getText(parsed.message) || null;\n }\n }\n \n // Fallback to common text field names\n return getText(parsed.text) || getText(parsed.display_text) || getText(parsed.message) || getText(parsed.content) || null;\n };\n \n const extractText = textExtractor || defaultExtractor;\n \n return {\n getExtractedText: () => extractedText,\n processChunk: (accumulatedContent: string): AgentWidgetStreamParserResult | string | null => {\n // Validate that the accumulated content looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n \n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedText !== null\n ? { text: extractedText, raw: accumulatedContent }\n : null;\n }\n \n try {\n // Parse partial JSON - allow partial strings and objects\n // STR | OBJ allows incomplete strings and objects during streaming\n const parsed = parsePartialJson(accumulatedContent, STR | OBJ);\n \n // Extract text using the provided or default extractor\n const newText = extractText(parsed);\n if (newText !== null) {\n extractedText = newText;\n }\n } catch (error) {\n // If parsing fails completely, keep the last extracted text\n // This can happen with very malformed JSON\n }\n \n // Update processed length\n processedLength = accumulatedContent.length;\n \n // Always return the raw JSON for action parsing and component detection\n // Text may be null or empty for component/form directives, that's ok\n return {\n text: extractedText || \"\",\n raw: accumulatedContent\n };\n },\n close: () => {\n // No cleanup needed\n }\n };\n};\n\n/**\n * XML stream parser.\n * Extracts text from <text>...</text> tags in XML responses.\n */\nexport const createXmlParser = (): AgentWidgetStreamParser => {\n let extractedText: string | null = null;\n \n return {\n processChunk: (accumulatedContent: string): AgentWidgetStreamParserResult | string | null => {\n // Return null if not XML format\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('<')) {\n return null;\n }\n \n // Extract text from <text>...</text> tags\n // Handle both <text>content</text> and <text attr=\"value\">content</text>\n const match = accumulatedContent.match(/<text[^>]*>([\\s\\S]*?)<\\/text>/);\n if (match && match[1]) {\n extractedText = match[1];\n // For XML, we typically don't need the raw content for middleware\n // but we can include it for consistency\n return { text: extractedText, raw: accumulatedContent };\n }\n \n return null;\n },\n getExtractedText: (): string | null => {\n return extractedText;\n }\n };\n};\n\n\n\n\n\n\n\n","import {\n AgentWidgetConfig,\n AgentWidgetMessage,\n AgentWidgetEvent,\n AgentWidgetStreamParser,\n AgentWidgetContextProvider,\n AgentWidgetRequestMiddleware,\n AgentWidgetRequestPayload,\n AgentWidgetCustomFetch,\n AgentWidgetSSEEventParser,\n AgentWidgetHeadersFunction,\n AgentWidgetSSEEventResult,\n ClientSession,\n ClientInitResponse,\n ClientChatRequest,\n ClientFeedbackRequest,\n ClientFeedbackType\n} from \"./types\";\nimport { \n extractTextFromJson, \n createPlainTextParser,\n createJsonStreamParser,\n createRegexJsonParser,\n createXmlParser\n} from \"./utils/formatting\";\n\ntype DispatchOptions = {\n messages: AgentWidgetMessage[];\n signal?: AbortSignal;\n /** Pre-generated ID for the expected assistant response (for feedback tracking) */\n assistantMessageId?: string;\n};\n\ntype SSEHandler = (event: AgentWidgetEvent) => void;\n\nconst DEFAULT_ENDPOINT = \"https://api.travrse.ai/v1/dispatch\";\nconst DEFAULT_CLIENT_API_BASE = \"https://api.travrse.ai\";\n\n/**\n * Maps parserType string to the corresponding parser factory function\n */\nfunction getParserFromType(parserType?: \"plain\" | \"json\" | \"regex-json\" | \"xml\"): () => AgentWidgetStreamParser {\n switch (parserType) {\n case \"json\":\n return createJsonStreamParser;\n case \"regex-json\":\n return createRegexJsonParser;\n case \"xml\":\n return createXmlParser;\n case \"plain\":\n default:\n return createPlainTextParser;\n }\n}\n\nexport class AgentWidgetClient {\n private readonly apiUrl: string;\n private readonly headers: Record<string, string>;\n private readonly debug: boolean;\n private readonly createStreamParser: () => AgentWidgetStreamParser;\n private readonly contextProviders: AgentWidgetContextProvider[];\n private readonly requestMiddleware?: AgentWidgetRequestMiddleware;\n private readonly customFetch?: AgentWidgetCustomFetch;\n private readonly parseSSEEvent?: AgentWidgetSSEEventParser;\n private readonly getHeaders?: AgentWidgetHeadersFunction;\n \n // Client token mode properties\n private clientSession: ClientSession | null = null;\n private sessionInitPromise: Promise<ClientSession> | null = null;\n\n constructor(private config: AgentWidgetConfig = {}) {\n this.apiUrl = config.apiUrl ?? DEFAULT_ENDPOINT;\n this.headers = {\n \"Content-Type\": \"application/json\",\n ...config.headers\n };\n this.debug = Boolean(config.debug);\n // Use custom stream parser if provided, otherwise use parserType, or fall back to plain text parser\n this.createStreamParser = config.streamParser ?? getParserFromType(config.parserType);\n this.contextProviders = config.contextProviders ?? [];\n this.requestMiddleware = config.requestMiddleware;\n this.customFetch = config.customFetch;\n this.parseSSEEvent = config.parseSSEEvent;\n this.getHeaders = config.getHeaders;\n }\n\n /**\n * Check if running in client token mode\n */\n public isClientTokenMode(): boolean {\n return !!this.config.clientToken;\n }\n\n /**\n * Get the appropriate API URL based on mode\n */\n private getClientApiUrl(endpoint: 'init' | 'chat'): string {\n const baseUrl = this.config.apiUrl?.replace(/\\/+$/, '').replace(/\\/v1\\/dispatch$/, '') || DEFAULT_CLIENT_API_BASE;\n return endpoint === 'init'\n ? `${baseUrl}/v1/client/init`\n : `${baseUrl}/v1/client/chat`;\n }\n\n /**\n * Get the current client session (if any)\n */\n public getClientSession(): ClientSession | null {\n return this.clientSession;\n }\n\n /**\n * Initialize session for client token mode.\n * Called automatically on first message if not already initialized.\n */\n public async initSession(): Promise<ClientSession> {\n if (!this.isClientTokenMode()) {\n throw new Error('initSession() only available in client token mode');\n }\n\n // Return existing session if valid\n if (this.clientSession && new Date() < this.clientSession.expiresAt) {\n return this.clientSession;\n }\n\n // Deduplicate concurrent init calls\n if (this.sessionInitPromise) {\n return this.sessionInitPromise;\n }\n\n this.sessionInitPromise = this._doInitSession();\n try {\n const session = await this.sessionInitPromise;\n this.clientSession = session;\n this.config.onSessionInit?.(session);\n return session;\n } finally {\n this.sessionInitPromise = null;\n }\n }\n\n private async _doInitSession(): Promise<ClientSession> {\n const response = await fetch(this.getClientApiUrl('init'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n token: this.config.clientToken,\n flow_id: this.config.flowId,\n }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Session initialization failed' }));\n if (response.status === 401) {\n throw new Error(`Invalid client token: ${error.hint || error.error}`);\n }\n if (response.status === 403) {\n throw new Error(`Origin not allowed: ${error.hint || error.error}`);\n }\n throw new Error(error.error || 'Failed to initialize session');\n }\n\n const data: ClientInitResponse = await response.json();\n return {\n sessionId: data.session_id,\n expiresAt: new Date(data.expires_at),\n flow: data.flow,\n config: {\n welcomeMessage: data.config.welcome_message,\n placeholder: data.config.placeholder,\n theme: data.config.theme,\n },\n };\n }\n\n /**\n * Clear the current client session\n */\n public clearClientSession(): void {\n this.clientSession = null;\n this.sessionInitPromise = null;\n }\n\n /**\n * Get the feedback API URL\n */\n private getFeedbackApiUrl(): string {\n const baseUrl = this.config.apiUrl?.replace(/\\/+$/, '').replace(/\\/v1\\/dispatch$/, '') || DEFAULT_CLIENT_API_BASE;\n return `${baseUrl}/v1/client/feedback`;\n }\n\n /**\n * Send feedback for a message (client token mode only).\n * Supports upvote, downvote, copy, csat, and nps feedback types.\n * \n * @param feedback - The feedback request payload\n * @returns Promise that resolves when feedback is sent successfully\n * @throws Error if not in client token mode or if session is invalid\n * \n * @example\n * ```typescript\n * // Message feedback (upvote/downvote/copy)\n * await client.sendFeedback({\n * session_id: sessionId,\n * message_id: messageId,\n * type: 'upvote'\n * });\n * \n * // CSAT feedback (1-5 rating)\n * await client.sendFeedback({\n * session_id: sessionId,\n * type: 'csat',\n * rating: 5,\n * comment: 'Great experience!'\n * });\n * \n * // NPS feedback (0-10 rating)\n * await client.sendFeedback({\n * session_id: sessionId,\n * type: 'nps',\n * rating: 9\n * });\n * ```\n */\n public async sendFeedback(feedback: ClientFeedbackRequest): Promise<void> {\n if (!this.isClientTokenMode()) {\n throw new Error('sendFeedback() only available in client token mode');\n }\n\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n // Validate message_id is provided for message-level feedback types\n const messageFeedbackTypes: ClientFeedbackType[] = ['upvote', 'downvote', 'copy'];\n if (messageFeedbackTypes.includes(feedback.type) && !feedback.message_id) {\n throw new Error(`message_id is required for ${feedback.type} feedback type`);\n }\n\n // Validate rating is provided for csat/nps feedback types\n if (feedback.type === 'csat') {\n if (feedback.rating === undefined || feedback.rating < 1 || feedback.rating > 5) {\n throw new Error('CSAT rating must be between 1 and 5');\n }\n }\n if (feedback.type === 'nps') {\n if (feedback.rating === undefined || feedback.rating < 0 || feedback.rating > 10) {\n throw new Error('NPS rating must be between 0 and 10');\n }\n }\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] sending feedback\", feedback);\n }\n\n const response = await fetch(this.getFeedbackApiUrl(), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(feedback),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Feedback submission failed' }));\n \n if (response.status === 401) {\n this.clientSession = null;\n this.config.onSessionExpired?.();\n throw new Error('Session expired. Please refresh to continue.');\n }\n \n throw new Error(errorData.error || 'Failed to submit feedback');\n }\n }\n\n /**\n * Submit message feedback (upvote, downvote, or copy).\n * Convenience method for sendFeedback with message-level feedback.\n * \n * @param messageId - The ID of the message to provide feedback for\n * @param type - The feedback type: 'upvote', 'downvote', or 'copy'\n */\n public async submitMessageFeedback(\n messageId: string, \n type: 'upvote' | 'downvote' | 'copy'\n ): Promise<void> {\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n return this.sendFeedback({\n session_id: session.sessionId,\n message_id: messageId,\n type,\n });\n }\n\n /**\n * Submit CSAT (Customer Satisfaction) feedback.\n * Convenience method for sendFeedback with CSAT feedback.\n * \n * @param rating - Rating from 1 to 5\n * @param comment - Optional comment\n */\n public async submitCSATFeedback(rating: number, comment?: string): Promise<void> {\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n return this.sendFeedback({\n session_id: session.sessionId,\n type: 'csat',\n rating,\n comment,\n });\n }\n\n /**\n * Submit NPS (Net Promoter Score) feedback.\n * Convenience method for sendFeedback with NPS feedback.\n * \n * @param rating - Rating from 0 to 10\n * @param comment - Optional comment\n */\n public async submitNPSFeedback(rating: number, comment?: string): Promise<void> {\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n return this.sendFeedback({\n session_id: session.sessionId,\n type: 'nps',\n rating,\n comment,\n });\n }\n\n /**\n * Send a message - handles both proxy and client token modes\n */\n public async dispatch(options: DispatchOptions, onEvent: SSEHandler) {\n if (this.isClientTokenMode()) {\n return this.dispatchClientToken(options, onEvent);\n }\n return this.dispatchProxy(options, onEvent);\n }\n\n /**\n * Client token mode dispatch\n */\n private async dispatchClientToken(options: DispatchOptions, onEvent: SSEHandler) {\n const controller = new AbortController();\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => controller.abort());\n }\n\n onEvent({ type: \"status\", status: \"connecting\" });\n\n try {\n // Ensure session is initialized\n const session = await this.initSession();\n\n // Check if session is about to expire (within 1 minute)\n if (new Date() >= new Date(session.expiresAt.getTime() - 60000)) {\n // Session expired or expiring soon\n this.clientSession = null;\n this.config.onSessionExpired?.();\n const error = new Error('Session expired. Please refresh to continue.');\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n // Build the standard payload to get context/metadata from middleware\n const basePayload = await this.buildPayload(options.messages);\n\n // Build the chat request payload with message IDs for feedback tracking\n const chatRequest: ClientChatRequest = {\n session_id: session.sessionId,\n messages: options.messages.map(m => ({\n id: m.id, // Include message ID for tracking\n role: m.role,\n content: m.rawContent || m.content,\n })),\n // Include pre-generated assistant message ID if provided\n ...(options.assistantMessageId && { assistant_message_id: options.assistantMessageId }),\n // Include metadata/context from middleware if present\n ...(basePayload.metadata && { metadata: basePayload.metadata }),\n ...(basePayload.context && { context: basePayload.context }),\n };\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] client token dispatch\", chatRequest);\n }\n\n const response = await fetch(this.getClientApiUrl('chat'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(chatRequest),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Chat request failed' }));\n \n if (response.status === 401) {\n // Session expired\n this.clientSession = null;\n this.config.onSessionExpired?.();\n const error = new Error('Session expired. Please refresh to continue.');\n onEvent({ type: \"error\", error });\n throw error;\n }\n \n if (response.status === 429) {\n const error = new Error(errorData.hint || 'Message limit reached for this session.');\n onEvent({ type: \"error\", error });\n throw error;\n }\n \n const error = new Error(errorData.error || 'Failed to send message');\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n if (!response.body) {\n const error = new Error('No response body received');\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n onEvent({ type: \"status\", status: \"connected\" });\n \n // Stream the response (same SSE handling as proxy mode)\n try {\n await this.streamResponse(response.body, onEvent, options.assistantMessageId);\n } finally {\n onEvent({ type: \"status\", status: \"idle\" });\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n // Only emit error if it wasn't already emitted\n if (!err.message.includes('Session expired') && !err.message.includes('Message limit')) {\n onEvent({ type: \"error\", error: err });\n }\n throw err;\n }\n }\n\n /**\n * Proxy mode dispatch (original implementation)\n */\n private async dispatchProxy(options: DispatchOptions, onEvent: SSEHandler) {\n const controller = new AbortController();\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => controller.abort());\n }\n\n onEvent({ type: \"status\", status: \"connecting\" });\n\n const payload = await this.buildPayload(options.messages);\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] dispatch payload\", payload);\n }\n\n // Build headers - merge static headers with dynamic headers if provided\n let headers = { ...this.headers };\n if (this.getHeaders) {\n try {\n const dynamicHeaders = await this.getHeaders();\n headers = { ...headers, ...dynamicHeaders };\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] getHeaders error:\", error);\n }\n }\n }\n\n // Use customFetch if provided, otherwise use default fetch\n let response: Response;\n if (this.customFetch) {\n try {\n response = await this.customFetch(\n this.apiUrl,\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n signal: controller.signal\n },\n payload\n );\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n onEvent({ type: \"error\", error: err });\n throw err;\n }\n } else {\n response = await fetch(this.apiUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n signal: controller.signal\n });\n }\n\n if (!response.ok || !response.body) {\n const error = new Error(\n `Chat backend request failed: ${response.status} ${response.statusText}`\n );\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n onEvent({ type: \"status\", status: \"connected\" });\n try {\n await this.streamResponse(response.body, onEvent);\n } finally {\n onEvent({ type: \"status\", status: \"idle\" });\n }\n }\n\n private async buildPayload(\n messages: AgentWidgetMessage[]\n ): Promise<AgentWidgetRequestPayload> {\n const normalizedMessages = messages\n .slice()\n .sort((a, b) => {\n const timeA = new Date(a.createdAt).getTime();\n const timeB = new Date(b.createdAt).getTime();\n return timeA - timeB;\n })\n .map((message) => ({\n role: message.role,\n content: message.rawContent || message.content,\n createdAt: message.createdAt\n }));\n\n const payload: AgentWidgetRequestPayload = {\n messages: normalizedMessages,\n ...(this.config.flowId && { flowId: this.config.flowId })\n };\n\n if (this.contextProviders.length) {\n const contextAggregate: Record<string, unknown> = {};\n await Promise.all(\n this.contextProviders.map(async (provider) => {\n try {\n const result = await provider({\n messages,\n config: this.config\n });\n if (result && typeof result === \"object\") {\n Object.assign(contextAggregate, result);\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.warn(\"[AgentWidget] Context provider failed:\", error);\n }\n }\n })\n );\n\n if (Object.keys(contextAggregate).length) {\n payload.context = contextAggregate;\n }\n }\n\n if (this.requestMiddleware) {\n try {\n const result = await this.requestMiddleware({\n payload: { ...payload },\n config: this.config\n });\n if (result && typeof result === \"object\") {\n return result as AgentWidgetRequestPayload;\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Request middleware error:\", error);\n }\n }\n }\n\n return payload;\n }\n\n /**\n * Handle custom SSE event parsing via parseSSEEvent callback\n * Returns true if event was handled, false otherwise\n */\n private async handleCustomSSEEvent(\n payload: unknown,\n onEvent: SSEHandler,\n assistantMessageRef: { current: AgentWidgetMessage | null },\n emitMessage: (msg: AgentWidgetMessage) => void,\n nextSequence: () => number\n ): Promise<boolean> {\n if (!this.parseSSEEvent) return false;\n\n try {\n const result = await this.parseSSEEvent(payload);\n if (result === null) return false; // Event should be ignored\n\n const ensureAssistant = () => {\n if (assistantMessageRef.current) return assistantMessageRef.current;\n const msg: AgentWidgetMessage = {\n id: `assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n variant: \"assistant\",\n sequence: nextSequence()\n };\n assistantMessageRef.current = msg;\n emitMessage(msg);\n return msg;\n };\n\n if (result.text !== undefined) {\n const assistant = ensureAssistant();\n assistant.content += result.text;\n emitMessage(assistant);\n }\n\n if (result.done) {\n if (assistantMessageRef.current) {\n assistantMessageRef.current.streaming = false;\n emitMessage(assistantMessageRef.current);\n }\n onEvent({ type: \"status\", status: \"idle\" });\n }\n\n if (result.error) {\n onEvent({\n type: \"error\",\n error: new Error(result.error)\n });\n }\n\n return true; // Event was handled\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] parseSSEEvent error:\", error);\n }\n return false;\n }\n }\n\n private async streamResponse(\n body: ReadableStream<Uint8Array>,\n onEvent: SSEHandler,\n assistantMessageId?: string\n ) {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n const baseSequence = Date.now();\n let sequenceCounter = 0;\n const nextSequence = () => baseSequence + sequenceCounter++;\n\n const cloneMessage = (msg: AgentWidgetMessage): AgentWidgetMessage => {\n const reasoning = msg.reasoning\n ? {\n ...msg.reasoning,\n chunks: [...msg.reasoning.chunks]\n }\n : undefined;\n const toolCall = msg.toolCall\n ? {\n ...msg.toolCall,\n chunks: msg.toolCall.chunks ? [...msg.toolCall.chunks] : undefined\n }\n : undefined;\n const tools = msg.tools\n ? msg.tools.map((tool) => ({\n ...tool,\n chunks: tool.chunks ? [...tool.chunks] : undefined\n }))\n : undefined;\n\n return {\n ...msg,\n reasoning,\n toolCall,\n tools\n };\n };\n\n const emitMessage = (msg: AgentWidgetMessage) => {\n onEvent({\n type: \"message\",\n message: cloneMessage(msg)\n });\n };\n\n let assistantMessage: AgentWidgetMessage | null = null;\n // Reference to track assistant message for custom event handler\n const assistantMessageRef = { current: null as AgentWidgetMessage | null };\n const reasoningMessages = new Map<string, AgentWidgetMessage>();\n const toolMessages = new Map<string, AgentWidgetMessage>();\n const reasoningContext = {\n lastId: null as string | null,\n byStep: new Map<string, string>()\n };\n const toolContext = {\n lastId: null as string | null,\n byCall: new Map<string, string>()\n };\n\n const normalizeKey = (value: unknown): string | null => {\n if (value === null || value === undefined) return null;\n try {\n return String(value);\n } catch (error) {\n return null;\n }\n };\n\n const getStepKey = (payload: Record<string, any>) =>\n normalizeKey(\n payload.stepId ??\n payload.step_id ??\n payload.step ??\n payload.parentId ??\n payload.flowStepId ??\n payload.flow_step_id\n );\n\n const getToolCallKey = (payload: Record<string, any>) =>\n normalizeKey(\n payload.callId ??\n payload.call_id ??\n payload.requestId ??\n payload.request_id ??\n payload.toolCallId ??\n payload.tool_call_id ??\n payload.stepId ??\n payload.step_id\n );\n\n const ensureAssistantMessage = () => {\n if (assistantMessage) return assistantMessage;\n assistantMessage = {\n // Use pre-generated ID if provided, otherwise generate one\n id: assistantMessageId ?? `assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n sequence: nextSequence()\n };\n emitMessage(assistantMessage);\n return assistantMessage;\n };\n\n const trackReasoningId = (stepKey: string | null, id: string) => {\n reasoningContext.lastId = id;\n if (stepKey) {\n reasoningContext.byStep.set(stepKey, id);\n }\n };\n\n const resolveReasoningId = (\n payload: Record<string, any>,\n allowCreate: boolean\n ): string | null => {\n const rawId = payload.reasoningId ?? payload.id;\n const stepKey = getStepKey(payload);\n if (rawId) {\n const resolved = String(rawId);\n trackReasoningId(stepKey, resolved);\n return resolved;\n }\n if (stepKey) {\n const existing = reasoningContext.byStep.get(stepKey);\n if (existing) {\n reasoningContext.lastId = existing;\n return existing;\n }\n }\n if (reasoningContext.lastId && !allowCreate) {\n return reasoningContext.lastId;\n }\n if (!allowCreate) {\n return null;\n }\n const generated = `reason-${nextSequence()}`;\n trackReasoningId(stepKey, generated);\n return generated;\n };\n\n const ensureReasoningMessage = (reasoningId: string) => {\n const existing = reasoningMessages.get(reasoningId);\n if (existing) {\n return existing;\n }\n\n const message: AgentWidgetMessage = {\n id: `reason-${reasoningId}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n variant: \"reasoning\",\n sequence: nextSequence(),\n reasoning: {\n id: reasoningId,\n status: \"streaming\",\n chunks: []\n }\n };\n\n reasoningMessages.set(reasoningId, message);\n emitMessage(message);\n return message;\n };\n\n const trackToolId = (callKey: string | null, id: string) => {\n toolContext.lastId = id;\n if (callKey) {\n toolContext.byCall.set(callKey, id);\n }\n };\n\n const resolveToolId = (\n payload: Record<string, any>,\n allowCreate: boolean\n ): string | null => {\n const rawId = payload.toolId ?? payload.id;\n const callKey = getToolCallKey(payload);\n if (rawId) {\n const resolved = String(rawId);\n trackToolId(callKey, resolved);\n return resolved;\n }\n if (callKey) {\n const existing = toolContext.byCall.get(callKey);\n if (existing) {\n toolContext.lastId = existing;\n return existing;\n }\n }\n if (toolContext.lastId && !allowCreate) {\n return toolContext.lastId;\n }\n if (!allowCreate) {\n return null;\n }\n const generated = `tool-${nextSequence()}`;\n trackToolId(callKey, generated);\n return generated;\n };\n\n const ensureToolMessage = (toolId: string) => {\n const existing = toolMessages.get(toolId);\n if (existing) {\n return existing;\n }\n\n const message: AgentWidgetMessage = {\n id: `tool-${toolId}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n variant: \"tool\",\n sequence: nextSequence(),\n toolCall: {\n id: toolId,\n status: \"pending\"\n }\n };\n\n toolMessages.set(toolId, message);\n emitMessage(message);\n return message;\n };\n\n const resolveTimestamp = (value: unknown) => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number(value);\n if (!Number.isNaN(parsed) && Number.isFinite(parsed)) {\n return parsed;\n }\n const dateParsed = Date.parse(value);\n if (!Number.isNaN(dateParsed)) {\n return dateParsed;\n }\n }\n return Date.now();\n };\n\n const ensureStringContent = (value: unknown): string => {\n if (typeof value === \"string\") {\n return value;\n }\n if (value === null || value === undefined) {\n return \"\";\n }\n // Convert objects/arrays to JSON string\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n };\n\n // Maintain stateful stream parsers per message for incremental parsing\n const streamParsers = new Map<string, AgentWidgetStreamParser>();\n // Track accumulated raw content for structured formats (JSON, XML, etc.)\n const rawContentBuffers = new Map<string, string>();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const events = buffer.split(\"\\n\\n\");\n buffer = events.pop() ?? \"\";\n\n for (const event of events) {\n const lines = event.split(\"\\n\");\n let eventType = \"message\";\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"event:\")) {\n eventType = line.replace(\"event:\", \"\").trim();\n } else if (line.startsWith(\"data:\")) {\n data += line.replace(\"data:\", \"\").trim();\n }\n }\n\n if (!data) continue;\n let payload: any;\n try {\n payload = JSON.parse(data);\n } catch (error) {\n onEvent({\n type: \"error\",\n error:\n error instanceof Error\n ? error\n : new Error(\"Failed to parse chat stream payload\")\n });\n continue;\n }\n\n const payloadType =\n eventType !== \"message\" ? eventType : payload.type ?? \"message\";\n\n // If custom SSE event parser is provided, try it first\n if (this.parseSSEEvent) {\n // Keep assistant message ref in sync\n assistantMessageRef.current = assistantMessage;\n const handled = await this.handleCustomSSEEvent(\n payload,\n onEvent,\n assistantMessageRef,\n emitMessage,\n nextSequence\n );\n // Update assistantMessage from ref (in case it was created)\n if (assistantMessageRef.current && !assistantMessage) {\n assistantMessage = assistantMessageRef.current;\n }\n if (handled) continue; // Skip default handling if custom handler processed it\n }\n\n if (payloadType === \"reason_start\") {\n const reasoningId =\n resolveReasoningId(payload, true) ?? `reason-${nextSequence()}`;\n const reasoningMessage = ensureReasoningMessage(reasoningId);\n reasoningMessage.reasoning = reasoningMessage.reasoning ?? {\n id: reasoningId,\n status: \"streaming\",\n chunks: []\n };\n reasoningMessage.reasoning.startedAt =\n reasoningMessage.reasoning.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n reasoningMessage.reasoning.completedAt = undefined;\n reasoningMessage.reasoning.durationMs = undefined;\n reasoningMessage.streaming = true;\n reasoningMessage.reasoning.status = \"streaming\";\n emitMessage(reasoningMessage);\n } else if (payloadType === \"reason_chunk\") {\n const reasoningId =\n resolveReasoningId(payload, false) ??\n resolveReasoningId(payload, true) ??\n `reason-${nextSequence()}`;\n const reasoningMessage = ensureReasoningMessage(reasoningId);\n reasoningMessage.reasoning = reasoningMessage.reasoning ?? {\n id: reasoningId,\n status: \"streaming\",\n chunks: []\n };\n reasoningMessage.reasoning.startedAt =\n reasoningMessage.reasoning.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n const chunk =\n payload.reasoningText ??\n payload.text ??\n payload.delta ??\n \"\";\n if (chunk && payload.hidden !== true) {\n reasoningMessage.reasoning.chunks.push(String(chunk));\n }\n reasoningMessage.reasoning.status = payload.done ? \"complete\" : \"streaming\";\n if (payload.done) {\n reasoningMessage.reasoning.completedAt = resolveTimestamp(\n payload.completedAt ?? payload.timestamp\n );\n const start = reasoningMessage.reasoning.startedAt ?? Date.now();\n reasoningMessage.reasoning.durationMs = Math.max(\n 0,\n (reasoningMessage.reasoning.completedAt ?? Date.now()) - start\n );\n }\n reasoningMessage.streaming = reasoningMessage.reasoning.status !== \"complete\";\n emitMessage(reasoningMessage);\n } else if (payloadType === \"reason_complete\") {\n const reasoningId =\n resolveReasoningId(payload, false) ??\n resolveReasoningId(payload, true) ??\n `reason-${nextSequence()}`;\n const reasoningMessage = reasoningMessages.get(reasoningId);\n if (reasoningMessage?.reasoning) {\n reasoningMessage.reasoning.status = \"complete\";\n reasoningMessage.reasoning.completedAt = resolveTimestamp(\n payload.completedAt ?? payload.timestamp\n );\n const start = reasoningMessage.reasoning.startedAt ?? Date.now();\n reasoningMessage.reasoning.durationMs = Math.max(\n 0,\n (reasoningMessage.reasoning.completedAt ?? Date.now()) - start\n );\n reasoningMessage.streaming = false;\n emitMessage(reasoningMessage);\n }\n const stepKey = getStepKey(payload);\n if (stepKey) {\n reasoningContext.byStep.delete(stepKey);\n }\n } else if (payloadType === \"tool_start\") {\n const toolId =\n resolveToolId(payload, true) ?? `tool-${nextSequence()}`;\n const toolMessage = ensureToolMessage(toolId);\n const tool = toolMessage.toolCall ?? {\n id: toolId,\n status: \"pending\"\n };\n tool.name = payload.toolName ?? tool.name;\n tool.status = \"running\";\n if (payload.args !== undefined) {\n tool.args = payload.args;\n }\n tool.startedAt =\n tool.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n tool.completedAt = undefined;\n tool.durationMs = undefined;\n toolMessage.toolCall = tool;\n toolMessage.streaming = true;\n emitMessage(toolMessage);\n } else if (payloadType === \"tool_chunk\") {\n const toolId =\n resolveToolId(payload, false) ??\n resolveToolId(payload, true) ??\n `tool-${nextSequence()}`;\n const toolMessage = ensureToolMessage(toolId);\n const tool = toolMessage.toolCall ?? {\n id: toolId,\n status: \"running\"\n };\n tool.startedAt =\n tool.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n const chunkText =\n payload.text ?? payload.delta ?? payload.message ?? \"\";\n if (chunkText) {\n tool.chunks = tool.chunks ?? [];\n tool.chunks.push(String(chunkText));\n }\n tool.status = \"running\";\n toolMessage.toolCall = tool;\n toolMessage.streaming = true;\n emitMessage(toolMessage);\n } else if (payloadType === \"tool_complete\") {\n const toolId =\n resolveToolId(payload, false) ??\n resolveToolId(payload, true) ??\n `tool-${nextSequence()}`;\n const toolMessage = ensureToolMessage(toolId);\n const tool = toolMessage.toolCall ?? {\n id: toolId,\n status: \"running\"\n };\n tool.status = \"complete\";\n if (payload.result !== undefined) {\n tool.result = payload.result;\n }\n if (typeof payload.duration === \"number\") {\n tool.duration = payload.duration;\n }\n tool.completedAt = resolveTimestamp(\n payload.completedAt ?? payload.timestamp\n );\n if (typeof payload.duration === \"number\") {\n tool.durationMs = payload.duration;\n } else {\n const start = tool.startedAt ?? Date.now();\n tool.durationMs = Math.max(\n 0,\n (tool.completedAt ?? Date.now()) - start\n );\n }\n toolMessage.toolCall = tool;\n toolMessage.streaming = false;\n emitMessage(toolMessage);\n const callKey = getToolCallKey(payload);\n if (callKey) {\n toolContext.byCall.delete(callKey);\n }\n } else if (payloadType === \"step_chunk\") {\n // Only process chunks for prompt steps, not tool/context steps\n const stepType = (payload as any).stepType;\n const executionType = (payload as any).executionType;\n if (stepType === \"tool\" || executionType === \"context\") {\n // Skip tool-related chunks - they're handled by tool_start/tool_complete\n continue;\n }\n const assistant = ensureAssistantMessage();\n // Support various field names: text, delta, content, chunk (Travrse uses 'chunk')\n const chunk = payload.text ?? payload.delta ?? payload.content ?? payload.chunk ?? \"\";\n if (chunk) {\n // Accumulate raw content for structured format parsing\n const rawBuffer = rawContentBuffers.get(assistant.id) ?? \"\";\n const accumulatedRaw = rawBuffer + chunk;\n // Store raw content for action parsing, but NEVER set assistant.content to raw JSON\n assistant.rawContent = accumulatedRaw;\n \n // Use stream parser to parse\n if (!streamParsers.has(assistant.id)) {\n streamParsers.set(assistant.id, this.createStreamParser());\n }\n const parser = streamParsers.get(assistant.id)!;\n \n // Check if content looks like JSON\n const looksLikeJson = accumulatedRaw.trim().startsWith('{') || accumulatedRaw.trim().startsWith('[');\n \n // Store raw buffer before processing (needed for step_complete handler)\n if (looksLikeJson) {\n rawContentBuffers.set(assistant.id, accumulatedRaw);\n }\n \n // Check if this is a plain text parser (marked with __isPlainTextParser)\n const isPlainTextParser = (parser as any).__isPlainTextParser === true;\n \n // If plain text parser, just append the chunk directly\n if (isPlainTextParser) {\n assistant.content += chunk;\n // Clear any raw buffer/parser since we're in plain text mode\n rawContentBuffers.delete(assistant.id);\n streamParsers.delete(assistant.id);\n assistant.rawContent = undefined;\n emitMessage(assistant);\n continue;\n }\n \n // Try to parse with the parser (for structured parsers)\n const parsedResult = parser.processChunk(accumulatedRaw);\n \n // Handle async parser result\n if (parsedResult instanceof Promise) {\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n // Parser successfully extracted text\n // Update the message content with extracted text\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n emitMessage(currentAssistant);\n }\n } else if (!looksLikeJson && !accumulatedRaw.trim().startsWith('<')) {\n // Not a structured format - show as plain text\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content += chunk;\n rawContentBuffers.delete(currentAssistant.id);\n streamParsers.delete(currentAssistant.id);\n currentAssistant.rawContent = undefined;\n emitMessage(currentAssistant);\n }\n }\n // Otherwise wait for more chunks (incomplete structured format)\n // Don't emit message if parser hasn't extracted text yet\n }).catch(() => {\n // On error, treat as plain text\n assistant.content += chunk;\n rawContentBuffers.delete(assistant.id);\n streamParsers.delete(assistant.id);\n assistant.rawContent = undefined;\n emitMessage(assistant);\n });\n } else {\n // Synchronous parser result\n // Extract text from result (could be string, null, or object)\n const text = typeof parsedResult === 'string' ? parsedResult : parsedResult?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n // Parser successfully extracted text\n // Buffer is already set above\n assistant.content = text;\n emitMessage(assistant);\n } else if (!looksLikeJson && !accumulatedRaw.trim().startsWith('<')) {\n // Not a structured format - show as plain text\n assistant.content += chunk;\n // Clear any raw buffer/parser if we were in structured format mode\n rawContentBuffers.delete(assistant.id);\n streamParsers.delete(assistant.id);\n assistant.rawContent = undefined;\n emitMessage(assistant);\n }\n // Otherwise wait for more chunks (incomplete structured format)\n // Don't emit message if parser hasn't extracted text yet\n }\n \n // IMPORTANT: Don't call getExtractedText() and emit messages here\n // This was causing raw JSON to be displayed because getExtractedText() \n // wasn't extracting the \"text\" field correctly during streaming\n }\n if (payload.isComplete) {\n const finalContent = payload.result?.response ?? assistant.content;\n if (finalContent) {\n // Check if we have raw content buffer that needs final processing\n const rawBuffer = rawContentBuffers.get(assistant.id);\n const contentToProcess = rawBuffer ?? ensureStringContent(finalContent);\n assistant.rawContent = contentToProcess;\n \n // Try to extract text from final structured content\n const parser = streamParsers.get(assistant.id);\n let extractedText: string | null = null;\n let asyncPending = false;\n \n if (parser) {\n // First check if parser already has extracted text\n extractedText = parser.getExtractedText();\n \n if (extractedText === null) {\n // Try extracting with regex\n extractedText = extractTextFromJson(contentToProcess);\n }\n \n if (extractedText === null) {\n // Try parser.processChunk as last resort\n const parsedResult = parser.processChunk(contentToProcess);\n if (parsedResult instanceof Promise) {\n asyncPending = true;\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n if (text !== null) {\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n currentAssistant.streaming = false;\n // Clean up\n streamParsers.delete(currentAssistant.id);\n rawContentBuffers.delete(currentAssistant.id);\n emitMessage(currentAssistant);\n }\n }\n });\n } else {\n // Extract text from synchronous result\n extractedText = typeof parsedResult === 'string' ? parsedResult : parsedResult?.text ?? null;\n }\n }\n }\n \n // Skip sync emit if we're waiting on async parser\n if (!asyncPending) {\n // Set content: use extracted text if available, otherwise use raw content\n if (extractedText !== null && extractedText.trim() !== \"\") {\n assistant.content = extractedText;\n } else if (!rawContentBuffers.has(assistant.id)) {\n // Only use raw final content if we didn't accumulate chunks\n assistant.content = ensureStringContent(finalContent);\n }\n \n // Clean up parser and buffer\n const parserToClose = streamParsers.get(assistant.id);\n if (parserToClose) {\n const closeResult = parserToClose.close?.();\n if (closeResult instanceof Promise) {\n closeResult.catch(() => {});\n }\n streamParsers.delete(assistant.id);\n }\n rawContentBuffers.delete(assistant.id);\n assistant.streaming = false;\n emitMessage(assistant);\n }\n }\n }\n } else if (payloadType === \"step_complete\") {\n // Only process completions for prompt steps, not tool/context steps\n const stepType = (payload as any).stepType;\n const executionType = (payload as any).executionType;\n if (stepType === \"tool\" || executionType === \"context\") {\n // Skip tool-related completions - they're handled by tool_complete\n continue;\n }\n const finalContent = payload.result?.response;\n const assistant = ensureAssistantMessage();\n if (finalContent !== undefined && finalContent !== null) {\n // Check if we already have extracted text from streaming\n const parser = streamParsers.get(assistant.id);\n let hasExtractedText = false;\n let asyncPending = false;\n \n if (parser) {\n // First check if parser already extracted text during streaming\n const currentExtractedText = parser.getExtractedText();\n const rawBuffer = rawContentBuffers.get(assistant.id);\n const contentToProcess = rawBuffer ?? ensureStringContent(finalContent);\n \n // Always set rawContent so action parsers can access the raw JSON\n assistant.rawContent = contentToProcess;\n \n if (currentExtractedText !== null && currentExtractedText.trim() !== \"\") {\n // We already have extracted text from streaming - use it\n assistant.content = currentExtractedText;\n hasExtractedText = true;\n } else {\n // No extracted text yet - try to extract from final content\n \n // Try fast path first\n const extractedText = extractTextFromJson(contentToProcess);\n if (extractedText !== null) {\n assistant.content = extractedText;\n hasExtractedText = true;\n } else {\n // Try parser\n const parsedResult = parser.processChunk(contentToProcess);\n if (parsedResult instanceof Promise) {\n asyncPending = true;\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n currentAssistant.streaming = false;\n // Clean up\n streamParsers.delete(currentAssistant.id);\n rawContentBuffers.delete(currentAssistant.id);\n emitMessage(currentAssistant);\n }\n } else {\n // No extracted text - check if we should show raw content\n const finalExtractedText = parser.getExtractedText();\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n if (finalExtractedText !== null && finalExtractedText.trim() !== \"\") {\n currentAssistant.content = finalExtractedText;\n } else if (!rawContentBuffers.has(currentAssistant.id)) {\n // Only show raw content if we never had any extracted text\n currentAssistant.content = ensureStringContent(finalContent);\n }\n currentAssistant.streaming = false;\n // Clean up\n streamParsers.delete(currentAssistant.id);\n rawContentBuffers.delete(currentAssistant.id);\n emitMessage(currentAssistant);\n }\n }\n });\n } else {\n // Extract text from synchronous result\n const text = typeof parsedResult === 'string' ? parsedResult : parsedResult?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n assistant.content = text;\n hasExtractedText = true;\n } else {\n // Check stub one more time\n const finalExtractedText = parser.getExtractedText();\n if (finalExtractedText !== null && finalExtractedText.trim() !== \"\") {\n assistant.content = finalExtractedText;\n hasExtractedText = true;\n }\n }\n }\n }\n }\n }\n \n // Skip sync emit if we're waiting on async parser\n if (!asyncPending) {\n // Ensure rawContent is set even if there's no parser (for action parsing)\n if (!assistant.rawContent) {\n const rawBuffer = rawContentBuffers.get(assistant.id);\n assistant.rawContent = rawBuffer ?? ensureStringContent(finalContent);\n }\n \n // Only show raw content if we never extracted any text and no buffer was used\n if (!hasExtractedText && !rawContentBuffers.has(assistant.id)) {\n // No extracted text and no streaming happened - show raw content\n assistant.content = ensureStringContent(finalContent);\n }\n \n // Clean up parser and buffer\n if (parser) {\n const closeResult = parser.close?.();\n if (closeResult instanceof Promise) {\n closeResult.catch(() => {});\n }\n }\n streamParsers.delete(assistant.id);\n rawContentBuffers.delete(assistant.id);\n assistant.streaming = false;\n emitMessage(assistant);\n }\n } else {\n // No final content, just mark as complete and clean up\n streamParsers.delete(assistant.id);\n rawContentBuffers.delete(assistant.id);\n assistant.streaming = false;\n emitMessage(assistant);\n }\n } else if (payloadType === \"flow_complete\") {\n const finalContent = payload.result?.response;\n if (finalContent !== undefined && finalContent !== null) {\n const assistant = ensureAssistantMessage();\n // Check if we have raw content buffer that needs final processing\n const rawBuffer = rawContentBuffers.get(assistant.id);\n const stringContent = rawBuffer ?? ensureStringContent(finalContent);\n assistant.rawContent = stringContent;\n // Try to extract text from structured content\n let displayContent = ensureStringContent(finalContent);\n const parser = streamParsers.get(assistant.id);\n if (parser) {\n const extractedText = extractTextFromJson(stringContent);\n if (extractedText !== null) {\n displayContent = extractedText;\n } else {\n // Try parser if it exists\n const parsedResult = parser.processChunk(stringContent);\n if (parsedResult instanceof Promise) {\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n if (text !== null) {\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n currentAssistant.streaming = false;\n emitMessage(currentAssistant);\n }\n }\n });\n }\n const currentText = parser.getExtractedText();\n if (currentText !== null) {\n displayContent = currentText;\n }\n }\n }\n // Clean up parser and buffer\n streamParsers.delete(assistant.id);\n rawContentBuffers.delete(assistant.id);\n \n // Only emit if something actually changed to avoid flicker\n const contentChanged = displayContent !== assistant.content;\n const streamingChanged = assistant.streaming !== false;\n \n if (contentChanged) {\n assistant.content = displayContent;\n }\n assistant.streaming = false;\n \n // Only emit if content or streaming state changed\n if (contentChanged || streamingChanged) {\n emitMessage(assistant);\n }\n } else {\n // No final content, just mark as complete and clean up\n if (assistantMessage !== null) {\n // Clean up any remaining parsers/buffers\n // TypeScript narrowing issue - assistantMessage is checked for null above\n const msg: AgentWidgetMessage = assistantMessage;\n streamParsers.delete(msg.id);\n rawContentBuffers.delete(msg.id);\n \n // Only emit if streaming state changed\n if (msg.streaming !== false) {\n msg.streaming = false;\n emitMessage(msg);\n }\n }\n }\n onEvent({ type: \"status\", status: \"idle\" });\n } else if (payloadType === \"error\" && payload.error) {\n onEvent({\n type: \"error\",\n error:\n payload.error instanceof Error\n ? payload.error\n : new Error(String(payload.error))\n });\n }\n }\n }\n }\n}\n","/**\n * Message ID utilities for client-side message tracking\n * Used for feedback integration with the Travrse API\n */\n\n/**\n * Generate a unique message ID for tracking\n * Format: msg_{timestamp_base36}_{random_8chars}\n */\nexport function generateMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `msg_${timestamp}_${random}`;\n}\n\n/**\n * Generate a unique user message ID\n * Format: usr_{timestamp_base36}_{random_8chars}\n */\nexport function generateUserMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `usr_${timestamp}_${random}`;\n}\n\n/**\n * Generate a unique assistant message ID\n * Format: ast_{timestamp_base36}_{random_8chars}\n */\nexport function generateAssistantMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `ast_${timestamp}_${random}`;\n}\n\n\n\n","import { AgentWidgetClient } from \"./client\";\nimport {\n AgentWidgetConfig,\n AgentWidgetEvent,\n AgentWidgetMessage,\n ClientSession\n} from \"./types\";\nimport {\n generateUserMessageId,\n generateAssistantMessageId\n} from \"./utils/message-id\";\n\nexport type AgentWidgetSessionStatus =\n | \"idle\"\n | \"connecting\"\n | \"connected\"\n | \"error\";\n\ntype SessionCallbacks = {\n onMessagesChanged: (messages: AgentWidgetMessage[]) => void;\n onStatusChanged: (status: AgentWidgetSessionStatus) => void;\n onStreamingChanged: (streaming: boolean) => void;\n onError?: (error: Error) => void;\n};\n\nexport class AgentWidgetSession {\n private client: AgentWidgetClient;\n private messages: AgentWidgetMessage[];\n private status: AgentWidgetSessionStatus = \"idle\";\n private streaming = false;\n private abortController: AbortController | null = null;\n private sequenceCounter = Date.now();\n \n // Client token session management\n private clientSession: ClientSession | null = null;\n\n constructor(\n private config: AgentWidgetConfig = {},\n private callbacks: SessionCallbacks\n ) {\n this.messages = [...(config.initialMessages ?? [])].map((message) => ({\n ...message,\n sequence: message.sequence ?? this.nextSequence()\n }));\n this.messages = this.sortMessages(this.messages);\n this.client = new AgentWidgetClient(config);\n\n if (this.messages.length) {\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n this.callbacks.onStatusChanged(this.status);\n }\n\n /**\n * Check if running in client token mode\n */\n public isClientTokenMode(): boolean {\n return this.client.isClientTokenMode();\n }\n\n /**\n * Initialize the client session (for client token mode).\n * This is called automatically on first message, but can be called\n * explicitly to pre-initialize the session and get config from server.\n */\n public async initClientSession(): Promise<ClientSession | null> {\n if (!this.isClientTokenMode()) {\n return null;\n }\n \n try {\n const session = await this.client.initSession();\n this.setClientSession(session);\n return session;\n } catch (error) {\n this.callbacks.onError?.(\n error instanceof Error ? error : new Error(String(error))\n );\n return null;\n }\n }\n\n /**\n * Set the client session after initialization\n */\n public setClientSession(session: ClientSession): void {\n this.clientSession = session;\n \n // Optionally add welcome message from session config\n if (session.config.welcomeMessage && this.messages.length === 0) {\n const welcomeMessage: AgentWidgetMessage = {\n id: `welcome-${Date.now()}`,\n role: \"assistant\",\n content: session.config.welcomeMessage,\n createdAt: new Date().toISOString(),\n sequence: this.nextSequence()\n };\n this.appendMessage(welcomeMessage);\n }\n }\n\n /**\n * Get current client session\n */\n public getClientSession(): ClientSession | null {\n return this.clientSession ?? this.client.getClientSession();\n }\n\n /**\n * Check if session is valid and not expired\n */\n public isSessionValid(): boolean {\n const session = this.getClientSession();\n if (!session) return false;\n return new Date() < session.expiresAt;\n }\n\n /**\n * Clear session (on expiry or error)\n */\n public clearClientSession(): void {\n this.clientSession = null;\n this.client.clearClientSession();\n }\n\n /**\n * Get the underlying client instance (for advanced use cases like feedback)\n */\n public getClient(): AgentWidgetClient {\n return this.client;\n }\n\n /**\n * Submit message feedback (upvote, downvote, or copy) to the API.\n * Only available in client token mode.\n * \n * @param messageId - The ID of the message to provide feedback for\n * @param type - The feedback type: 'upvote', 'downvote', or 'copy'\n */\n public async submitMessageFeedback(\n messageId: string,\n type: 'upvote' | 'downvote' | 'copy'\n ): Promise<void> {\n return this.client.submitMessageFeedback(messageId, type);\n }\n\n /**\n * Submit CSAT (Customer Satisfaction) feedback to the API.\n * Only available in client token mode.\n * \n * @param rating - Rating from 1 to 5\n * @param comment - Optional comment\n */\n public async submitCSATFeedback(rating: number, comment?: string): Promise<void> {\n return this.client.submitCSATFeedback(rating, comment);\n }\n\n /**\n * Submit NPS (Net Promoter Score) feedback to the API.\n * Only available in client token mode.\n * \n * @param rating - Rating from 0 to 10\n * @param comment - Optional comment\n */\n public async submitNPSFeedback(rating: number, comment?: string): Promise<void> {\n return this.client.submitNPSFeedback(rating, comment);\n }\n\n public updateConfig(next: AgentWidgetConfig) {\n this.config = { ...this.config, ...next };\n this.client = new AgentWidgetClient(this.config);\n }\n\n public getMessages() {\n return [...this.messages];\n }\n\n public getStatus() {\n return this.status;\n }\n\n public isStreaming() {\n return this.streaming;\n }\n\n public injectTestEvent(event: AgentWidgetEvent) {\n this.handleEvent(event);\n }\n\n public async sendMessage(rawInput: string, options?: { viaVoice?: boolean }) {\n const input = rawInput.trim();\n if (!input) return;\n\n this.abortController?.abort();\n\n // Generate IDs for both user message and expected assistant response\n const userMessageId = generateUserMessageId();\n const assistantMessageId = generateAssistantMessageId();\n\n const userMessage: AgentWidgetMessage = {\n id: userMessageId,\n role: \"user\",\n content: input,\n createdAt: new Date().toISOString(),\n sequence: this.nextSequence(),\n viaVoice: options?.viaVoice || false\n };\n\n this.appendMessage(userMessage);\n this.setStreaming(true);\n\n const controller = new AbortController();\n this.abortController = controller;\n\n const snapshot = [...this.messages];\n\n try {\n await this.client.dispatch(\n {\n messages: snapshot,\n signal: controller.signal,\n assistantMessageId // Pass expected assistant message ID for tracking\n },\n this.handleEvent\n );\n } catch (error) {\n const fallback: AgentWidgetMessage = {\n id: assistantMessageId, // Use the pre-generated ID for fallback too\n role: \"assistant\",\n createdAt: new Date().toISOString(),\n content:\n \"It looks like the proxy isn't returning a real response yet. Here's a sample message so you can continue testing locally.\",\n sequence: this.nextSequence()\n };\n\n this.appendMessage(fallback);\n this.setStatus(\"idle\");\n this.setStreaming(false);\n this.abortController = null;\n if (error instanceof Error) {\n this.callbacks.onError?.(error);\n } else {\n this.callbacks.onError?.(new Error(String(error)));\n }\n }\n }\n\n public cancel() {\n this.abortController?.abort();\n this.abortController = null;\n this.setStreaming(false);\n this.setStatus(\"idle\");\n }\n\n public clearMessages() {\n this.abortController?.abort();\n this.abortController = null;\n this.messages = [];\n this.setStreaming(false);\n this.setStatus(\"idle\");\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n public hydrateMessages(messages: AgentWidgetMessage[]) {\n this.abortController?.abort();\n this.abortController = null;\n this.messages = this.sortMessages(\n messages.map((message) => ({\n ...message,\n streaming: false,\n sequence: message.sequence ?? this.nextSequence()\n }))\n );\n this.setStreaming(false);\n this.setStatus(\"idle\");\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n private handleEvent = (event: AgentWidgetEvent) => {\n if (event.type === \"message\") {\n this.upsertMessage(event.message);\n } else if (event.type === \"status\") {\n this.setStatus(event.status);\n if (event.status === \"connecting\") {\n this.setStreaming(true);\n } else if (event.status === \"idle\" || event.status === \"error\") {\n this.setStreaming(false);\n this.abortController = null;\n }\n } else if (event.type === \"error\") {\n this.setStatus(\"error\");\n this.setStreaming(false);\n this.abortController = null;\n this.callbacks.onError?.(event.error);\n }\n };\n\n private setStatus(status: AgentWidgetSessionStatus) {\n if (this.status === status) return;\n this.status = status;\n this.callbacks.onStatusChanged(status);\n }\n\n private setStreaming(streaming: boolean) {\n if (this.streaming === streaming) return;\n this.streaming = streaming;\n this.callbacks.onStreamingChanged(streaming);\n }\n\n private appendMessage(message: AgentWidgetMessage) {\n const withSequence = this.ensureSequence(message);\n this.messages = this.sortMessages([...this.messages, withSequence]);\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n private upsertMessage(message: AgentWidgetMessage) {\n const withSequence = this.ensureSequence(message);\n const index = this.messages.findIndex((m) => m.id === withSequence.id);\n if (index === -1) {\n this.appendMessage(withSequence);\n return;\n }\n\n this.messages = this.messages.map((existing, idx) =>\n idx === index ? { ...existing, ...withSequence } : existing\n );\n this.messages = this.sortMessages(this.messages);\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n private ensureSequence(message: AgentWidgetMessage): AgentWidgetMessage {\n if (message.sequence !== undefined) {\n return { ...message };\n }\n return {\n ...message,\n sequence: this.nextSequence()\n };\n }\n\n private nextSequence() {\n return this.sequenceCounter++;\n }\n\n private sortMessages(messages: AgentWidgetMessage[]) {\n return [...messages].sort((a, b) => {\n // Sort by createdAt timestamp first (chronological order)\n const timeA = new Date(a.createdAt).getTime();\n const timeB = new Date(b.createdAt).getTime();\n if (!Number.isNaN(timeA) && !Number.isNaN(timeB) && timeA !== timeB) {\n return timeA - timeB;\n }\n\n // Fall back to sequence if timestamps are equal or invalid\n const seqA = a.sequence ?? 0;\n const seqB = b.sequence ?? 0;\n if (seqA !== seqB) return seqA - seqB;\n\n // Final fallback to ID\n return a.id.localeCompare(b.id);\n });\n }\n}\n","import { AgentWidgetConfig, AgentWidgetTheme } from \"../types\";\n\n/**\n * Detects the current color scheme from the page.\n * 1. Checks if <html> element has 'dark' class\n * 2. Falls back to prefers-color-scheme media query\n */\nexport const detectColorScheme = (): 'light' | 'dark' => {\n // Check for 'dark' class on <html> element\n if (typeof document !== 'undefined' && document.documentElement.classList.contains('dark')) {\n return 'dark';\n }\n \n // Fall back to media query\n if (typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches) {\n return 'dark';\n }\n \n return 'light';\n};\n\n/**\n * Gets the active theme based on colorScheme setting and current detection.\n */\nexport const getActiveTheme = (config?: AgentWidgetConfig): AgentWidgetTheme => {\n const colorScheme = config?.colorScheme ?? 'light';\n const lightTheme = config?.theme ?? {};\n const darkTheme = config?.darkTheme ?? lightTheme;\n \n if (colorScheme === 'light') {\n return lightTheme;\n }\n \n if (colorScheme === 'dark') {\n return darkTheme;\n }\n \n // colorScheme === 'auto'\n const detectedScheme = detectColorScheme();\n return detectedScheme === 'dark' ? darkTheme : lightTheme;\n};\n\n/**\n * Creates observers for theme changes (HTML class and media query).\n * Returns a cleanup function.\n */\nexport const createThemeObserver = (\n callback: (scheme: 'light' | 'dark') => void\n): (() => void) => {\n const cleanupFns: Array<() => void> = [];\n \n // Observe HTML class changes\n if (typeof document !== 'undefined' && typeof MutationObserver !== 'undefined') {\n const observer = new MutationObserver(() => {\n callback(detectColorScheme());\n });\n \n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class']\n });\n \n cleanupFns.push(() => observer.disconnect());\n }\n \n // Observe media query changes\n if (typeof window !== 'undefined' && window.matchMedia) {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => callback(detectColorScheme());\n \n // Use addEventListener if available (modern browsers), otherwise addListener\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n cleanupFns.push(() => mediaQuery.removeEventListener('change', handleChange));\n } else if (mediaQuery.addListener) {\n // Legacy Safari\n mediaQuery.addListener(handleChange);\n cleanupFns.push(() => mediaQuery.removeListener(handleChange));\n }\n }\n \n return () => {\n cleanupFns.forEach(fn => fn());\n };\n};\n\nexport const applyThemeVariables = (\n element: HTMLElement,\n config?: AgentWidgetConfig\n) => {\n const theme = getActiveTheme(config);\n Object.entries(theme).forEach(([key, value]) => {\n // Skip undefined or empty values\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n // Convert camelCase to kebab-case (e.g., radiusSm → radius-sm)\n const kebabKey = key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);\n element.style.setProperty(`--cw-${kebabKey}`, String(value));\n });\n};\n\n\n\n\n","import * as icons from \"lucide\";\nimport type { IconNode } from \"lucide\";\n\n/**\n * Renders a Lucide icon as an inline SVG element\n * This approach requires no CSS and works on any page\n * \n * @param iconName - The Lucide icon name in kebab-case (e.g., \"arrow-up\")\n * @param size - The size of the icon (default: 24)\n * @param color - The stroke color (default: \"currentColor\")\n * @param strokeWidth - The stroke width (default: 2)\n * @returns SVGElement or null if icon not found\n */\nexport const renderLucideIcon = (\n iconName: string,\n size: number | string = 24,\n color: string = \"currentColor\",\n strokeWidth: number = 2\n): SVGElement | null => {\n try {\n // Convert kebab-case to PascalCase (e.g., \"arrow-up\" -> \"ArrowUp\")\n const pascalName = iconName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n \n // Lucide's icons object contains IconNode data directly, not functions\n const iconData = (icons as Record<string, IconNode>)[pascalName] as IconNode;\n \n if (!iconData) {\n console.warn(`Lucide icon \"${iconName}\" not found (tried \"${pascalName}\"). Available icons: https://lucide.dev/icons`);\n return null;\n }\n\n return createSvgFromIconData(iconData, size, color, strokeWidth);\n } catch (error) {\n console.warn(`Failed to render Lucide icon \"${iconName}\":`, error);\n return null;\n }\n};\n\n/**\n * Helper function to create SVG from IconNode data\n */\nfunction createSvgFromIconData(\n iconData: IconNode,\n size: number | string,\n color: string,\n strokeWidth: number\n): SVGElement | null {\n if (!iconData || !Array.isArray(iconData)) {\n return null;\n }\n\n // Create SVG element\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"width\", String(size));\n svg.setAttribute(\"height\", String(size));\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"fill\", \"none\");\n svg.setAttribute(\"stroke\", color);\n svg.setAttribute(\"stroke-width\", String(strokeWidth));\n svg.setAttribute(\"stroke-linecap\", \"round\");\n svg.setAttribute(\"stroke-linejoin\", \"round\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n \n // Render elements from icon data\n // IconNode format: [[\"path\", {\"d\": \"...\"}], [\"rect\", {\"x\": \"...\", \"y\": \"...\"}], ...]\n iconData.forEach((elementData) => {\n if (Array.isArray(elementData) && elementData.length >= 2) {\n const tagName = elementData[0] as string;\n const attrs = elementData[1] as Record<string, string>;\n \n if (attrs) {\n // Create the appropriate SVG element (path, rect, circle, ellipse, line, etc.)\n const element = document.createElementNS(\"http://www.w3.org/2000/svg\", tagName);\n \n // Apply all attributes, but skip 'stroke' (we want to use the parent SVG's stroke for consistent coloring)\n Object.entries(attrs).forEach(([key, value]) => {\n if (key !== \"stroke\") {\n element.setAttribute(key, String(value));\n }\n });\n \n svg.appendChild(element);\n }\n }\n });\n \n return svg;\n}\n\n","/**\n * DOM utility functions\n */\nexport const createElement = <K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string\n): HTMLElementTagNameMap[K] => {\n const element = document.createElement(tag);\n if (className) {\n element.className = className;\n }\n return element;\n};\n\nexport const createFragment = (): DocumentFragment => {\n return document.createDocumentFragment();\n};\n\n\n\n\n\n\n\n\n","import { AgentWidgetSessionStatus } from \"../session\";\n\nexport const statusCopy: Record<AgentWidgetSessionStatus, string> = {\n idle: \"Online\",\n connecting: \"Connecting…\",\n connected: \"Streaming…\",\n error: \"Offline\"\n};\n\n\n\n\n\n\n\n\n","export const positionMap: Record<\n \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\",\n string\n> = {\n \"bottom-right\": \"tvw-bottom-6 tvw-right-6\",\n \"bottom-left\": \"tvw-bottom-6 tvw-left-6\",\n \"top-right\": \"tvw-top-6 tvw-right-6\",\n \"top-left\": \"tvw-top-6 tvw-left-6\"\n};\n\n\n\n\n\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetConfig } from \"../types\";\nimport { positionMap } from \"../utils/positioning\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\nexport interface LauncherButton {\n element: HTMLButtonElement;\n update: (config: AgentWidgetConfig) => void;\n destroy: () => void;\n}\n\nexport const createLauncherButton = (\n config: AgentWidgetConfig | undefined,\n onToggle: () => void\n): LauncherButton => {\n const button = createElement(\"button\") as HTMLButtonElement;\n button.type = \"button\";\n button.innerHTML = `\n <span class=\"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-bg-cw-primary tvw-text-white\" data-role=\"launcher-icon\">💬</span>\n <img data-role=\"launcher-image\" class=\"tvw-rounded-full tvw-object-cover\" alt=\"\" style=\"display:none\" />\n <span class=\"tvw-flex tvw-flex-col tvw-items-start tvw-text-left\">\n <span class=\"tvw-text-sm tvw-font-semibold tvw-text-cw-primary\" data-role=\"launcher-title\"></span>\n <span class=\"tvw-text-xs tvw-text-cw-muted\" data-role=\"launcher-subtitle\"></span>\n </span>\n <span class=\"tvw-ml-2 tvw-grid tvw-place-items-center tvw-rounded-full tvw-bg-cw-primary tvw-text-cw-call-to-action\" data-role=\"launcher-call-to-action-icon\">↗</span>\n `;\n button.addEventListener(\"click\", onToggle);\n\n const update = (newConfig: AgentWidgetConfig) => {\n const launcher = newConfig.launcher ?? {};\n\n const titleEl = button.querySelector(\"[data-role='launcher-title']\");\n if (titleEl) {\n titleEl.textContent = launcher.title ?? \"Chat Assistant\";\n }\n\n const subtitleEl = button.querySelector(\"[data-role='launcher-subtitle']\");\n if (subtitleEl) {\n subtitleEl.textContent = launcher.subtitle ?? \"Get answers fast\";\n }\n\n // Hide/show text container\n const textContainer = button.querySelector(\".tvw-flex-col\");\n if (textContainer) {\n if (launcher.textHidden) {\n (textContainer as HTMLElement).style.display = \"none\";\n } else {\n (textContainer as HTMLElement).style.display = \"\";\n }\n }\n\n const icon = button.querySelector<HTMLSpanElement>(\"[data-role='launcher-icon']\");\n if (icon) {\n if (launcher.agentIconHidden) {\n icon.style.display = \"none\";\n } else {\n const iconSize = launcher.agentIconSize ?? \"40px\";\n icon.style.height = iconSize;\n icon.style.width = iconSize;\n \n // Clear existing content\n icon.innerHTML = \"\";\n \n // Render icon based on priority: Lucide icon > iconUrl > agentIconText\n if (launcher.agentIconName) {\n // Use Lucide icon\n const iconSizeNum = parseFloat(iconSize) || 24;\n const iconSvg = renderLucideIcon(launcher.agentIconName, iconSizeNum * 0.6, \"#ffffff\", 2);\n if (iconSvg) {\n icon.appendChild(iconSvg);\n icon.style.display = \"\";\n } else {\n // Fallback to agentIconText if Lucide icon fails\n icon.textContent = launcher.agentIconText ?? \"💬\";\n icon.style.display = \"\";\n }\n } else if (launcher.iconUrl) {\n // Use image URL - hide icon span and show img\n icon.style.display = \"none\";\n } else {\n // Use text/emoji\n icon.textContent = launcher.agentIconText ?? \"💬\";\n icon.style.display = \"\";\n }\n }\n }\n\n const img = button.querySelector<HTMLImageElement>(\"[data-role='launcher-image']\");\n if (img) {\n const iconSize = launcher.agentIconSize ?? \"40px\";\n img.style.height = iconSize;\n img.style.width = iconSize;\n if (launcher.iconUrl && !launcher.agentIconName && !launcher.agentIconHidden) {\n // Only show image if not using Lucide icon and not hidden\n img.src = launcher.iconUrl;\n img.style.display = \"block\";\n } else {\n img.style.display = \"none\";\n }\n }\n\n const callToActionIconEl = button.querySelector<HTMLSpanElement>(\"[data-role='launcher-call-to-action-icon']\");\n if (callToActionIconEl) {\n const callToActionIconSize = launcher.callToActionIconSize ?? \"32px\";\n callToActionIconEl.style.height = callToActionIconSize;\n callToActionIconEl.style.width = callToActionIconSize;\n \n // Apply background color if configured\n if (launcher.callToActionIconBackgroundColor) {\n callToActionIconEl.style.backgroundColor = launcher.callToActionIconBackgroundColor;\n callToActionIconEl.classList.remove(\"tvw-bg-cw-primary\");\n } else {\n callToActionIconEl.style.backgroundColor = \"\";\n callToActionIconEl.classList.add(\"tvw-bg-cw-primary\");\n }\n \n // Calculate padding to adjust icon size\n let paddingTotal = 0;\n if (launcher.callToActionIconPadding) {\n callToActionIconEl.style.boxSizing = \"border-box\";\n callToActionIconEl.style.padding = launcher.callToActionIconPadding;\n // Parse padding value to calculate total padding (padding applies to both sides)\n const paddingValue = parseFloat(launcher.callToActionIconPadding) || 0;\n paddingTotal = paddingValue * 2; // padding on both sides\n } else {\n callToActionIconEl.style.boxSizing = \"\";\n callToActionIconEl.style.padding = \"\";\n }\n \n if (launcher.callToActionIconHidden) {\n callToActionIconEl.style.display = \"none\";\n } else {\n callToActionIconEl.style.display = \"\";\n \n // Clear existing content\n callToActionIconEl.innerHTML = \"\";\n \n // Use Lucide icon if provided, otherwise fall back to text\n if (launcher.callToActionIconName) {\n // Calculate actual icon size by subtracting padding\n const containerSize = parseFloat(callToActionIconSize) || 24;\n const iconSize = Math.max(containerSize - paddingTotal, 8); // Ensure minimum size of 8px\n const iconSvg = renderLucideIcon(launcher.callToActionIconName, iconSize, \"currentColor\", 2);\n if (iconSvg) {\n callToActionIconEl.appendChild(iconSvg);\n } else {\n // Fallback to text if icon fails to render\n callToActionIconEl.textContent = launcher.callToActionIconText ?? \"↗\";\n }\n } else {\n callToActionIconEl.textContent = launcher.callToActionIconText ?? \"↗\";\n }\n }\n }\n\n const positionClass =\n launcher.position && positionMap[launcher.position]\n ? positionMap[launcher.position]\n : positionMap[\"bottom-right\"];\n\n // Removed hardcoded border/shadow classes (tvw-shadow-lg, tvw-border, tvw-border-gray-200)\n // These are now applied via inline styles from config\n const base =\n \"tvw-fixed tvw-flex tvw-items-center tvw-gap-3 tvw-rounded-launcher tvw-bg-cw-surface tvw-py-2.5 tvw-pl-3 tvw-pr-3 tvw-transition hover:tvw-translate-y-[-2px] tvw-cursor-pointer tvw-z-50\";\n\n button.className = `${base} ${positionClass}`;\n \n // Apply launcher border and shadow from config (with defaults matching previous Tailwind classes)\n const defaultBorder = \"1px solid #e5e7eb\";\n const defaultShadow = \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)\";\n \n button.style.border = launcher.border ?? defaultBorder;\n button.style.boxShadow = launcher.shadow ?? defaultShadow;\n };\n\n const destroy = () => {\n button.removeEventListener(\"click\", onToggle);\n button.remove();\n };\n\n // Initial update\n if (config) {\n update(config);\n }\n\n return {\n element: button,\n update,\n destroy\n };\n};\n\n\n","import { createElement } from \"../utils/dom\";\nimport { renderLucideIcon } from \"../utils/icons\";\nimport { AgentWidgetConfig } from \"../types\";\n\nexport interface HeaderElements {\n header: HTMLElement;\n iconHolder: HTMLElement;\n headerTitle: HTMLElement;\n headerSubtitle: HTMLElement;\n closeButton: HTMLButtonElement;\n closeButtonWrapper: HTMLElement;\n clearChatButton: HTMLButtonElement | null;\n clearChatButtonWrapper: HTMLElement | null;\n}\n\nexport interface HeaderBuildContext {\n config?: AgentWidgetConfig;\n showClose?: boolean;\n onClose?: () => void;\n onClearChat?: () => void;\n}\n\n/**\n * Build the header section of the panel.\n * Extracted for reuse and plugin override support.\n */\nexport const buildHeader = (context: HeaderBuildContext): HeaderElements => {\n const { config, showClose = true } = context;\n\n const header = createElement(\n \"div\",\n \"tvw-widget-header tvw-flex tvw-items-center tvw-gap-3 tvw-bg-cw-surface tvw-px-6 tvw-py-5 tvw-border-b-cw-divider\"\n );\n\n const launcher = config?.launcher ?? {};\n const headerIconSize = launcher.headerIconSize ?? \"48px\";\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonPlacement = launcher.closeButtonPlacement ?? \"inline\";\n const headerIconHidden = launcher.headerIconHidden ?? false;\n const headerIconName = launcher.headerIconName;\n\n const iconHolder = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-center tvw-rounded-xl tvw-bg-cw-primary tvw-text-white tvw-text-xl\"\n );\n iconHolder.style.height = headerIconSize;\n iconHolder.style.width = headerIconSize;\n\n // Render icon based on priority: Lucide icon > iconUrl > agentIconText\n if (!headerIconHidden) {\n if (headerIconName) {\n // Use Lucide icon\n const iconSize = parseFloat(headerIconSize) || 24;\n const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.6, \"#ffffff\", 2);\n if (iconSvg) {\n iconHolder.replaceChildren(iconSvg);\n } else {\n // Fallback to agentIconText if Lucide icon fails\n iconHolder.textContent = config?.launcher?.agentIconText ?? \"💬\";\n }\n } else if (config?.launcher?.iconUrl) {\n // Use image URL\n const img = createElement(\"img\") as HTMLImageElement;\n img.src = config.launcher.iconUrl;\n img.alt = \"\";\n img.className = \"tvw-rounded-xl tvw-object-cover\";\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n iconHolder.replaceChildren(img);\n } else {\n // Use text/emoji\n iconHolder.textContent = config?.launcher?.agentIconText ?? \"💬\";\n }\n }\n\n const headerCopy = createElement(\"div\", \"tvw-flex tvw-flex-col\");\n const title = createElement(\"span\", \"tvw-text-base tvw-font-semibold\");\n title.textContent = config?.launcher?.title ?? \"Chat Assistant\";\n const subtitle = createElement(\"span\", \"tvw-text-xs tvw-text-cw-muted\");\n subtitle.textContent =\n config?.launcher?.subtitle ?? \"Here to help you get answers fast\";\n\n headerCopy.append(title, subtitle);\n\n // Only append iconHolder if not hidden\n if (!headerIconHidden) {\n header.append(iconHolder, headerCopy);\n } else {\n header.append(headerCopy);\n }\n\n // Create clear chat button if enabled\n const clearChatConfig = launcher.clearChat ?? {};\n const clearChatEnabled = clearChatConfig.enabled ?? true;\n const clearChatPlacement = clearChatConfig.placement ?? \"inline\";\n let clearChatButton: HTMLButtonElement | null = null;\n let clearChatButtonWrapper: HTMLElement | null = null;\n\n if (clearChatEnabled) {\n const clearChatSize = clearChatConfig.size ?? \"32px\";\n const clearChatIconName = clearChatConfig.iconName ?? \"refresh-cw\";\n const clearChatIconColor = clearChatConfig.iconColor ?? \"\";\n const clearChatBgColor = clearChatConfig.backgroundColor ?? \"\";\n const clearChatBorderWidth = clearChatConfig.borderWidth ?? \"\";\n const clearChatBorderColor = clearChatConfig.borderColor ?? \"\";\n const clearChatBorderRadius = clearChatConfig.borderRadius ?? \"\";\n const clearChatPaddingX = clearChatConfig.paddingX ?? \"\";\n const clearChatPaddingY = clearChatConfig.paddingY ?? \"\";\n const clearChatTooltipText = clearChatConfig.tooltipText ?? \"Clear chat\";\n const clearChatShowTooltip = clearChatConfig.showTooltip ?? true;\n\n // Create button wrapper for tooltip - positioned based on placement\n // Note: Don't use tvw-clear-chat-button-wrapper class for top-right mode as its\n // display: inline-flex causes alignment issues with the close button\n clearChatButtonWrapper = createElement(\n \"div\",\n clearChatPlacement === \"top-right\"\n ? \"tvw-absolute tvw-top-4 tvw-z-50\"\n : \"tvw-relative tvw-ml-auto tvw-clear-chat-button-wrapper\"\n );\n\n // Position to the left of the close button (which is at right: 1rem/16px)\n // Close button is ~32px wide, plus small gap = 48px from right\n if (clearChatPlacement === \"top-right\") {\n clearChatButtonWrapper.style.right = \"48px\";\n }\n\n clearChatButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n\n clearChatButton.style.height = clearChatSize;\n clearChatButton.style.width = clearChatSize;\n clearChatButton.type = \"button\";\n clearChatButton.setAttribute(\"aria-label\", clearChatTooltipText);\n\n // Add icon\n const iconSvg = renderLucideIcon(\n clearChatIconName,\n \"20px\",\n clearChatIconColor || \"\",\n 2\n );\n if (iconSvg) {\n clearChatButton.appendChild(iconSvg);\n }\n\n // Apply styling from config\n if (clearChatIconColor) {\n clearChatButton.style.color = clearChatIconColor;\n clearChatButton.classList.remove(\"tvw-text-cw-muted\");\n }\n\n if (clearChatBgColor) {\n clearChatButton.style.backgroundColor = clearChatBgColor;\n clearChatButton.classList.remove(\"hover:tvw-bg-gray-100\");\n }\n\n if (clearChatBorderWidth || clearChatBorderColor) {\n const borderWidth = clearChatBorderWidth || \"0px\";\n const borderColor = clearChatBorderColor || \"transparent\";\n clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;\n clearChatButton.classList.remove(\"tvw-border-none\");\n }\n\n if (clearChatBorderRadius) {\n clearChatButton.style.borderRadius = clearChatBorderRadius;\n clearChatButton.classList.remove(\"tvw-rounded-full\");\n }\n\n // Apply padding styling\n if (clearChatPaddingX) {\n clearChatButton.style.paddingLeft = clearChatPaddingX;\n clearChatButton.style.paddingRight = clearChatPaddingX;\n } else {\n clearChatButton.style.paddingLeft = \"\";\n clearChatButton.style.paddingRight = \"\";\n }\n if (clearChatPaddingY) {\n clearChatButton.style.paddingTop = clearChatPaddingY;\n clearChatButton.style.paddingBottom = clearChatPaddingY;\n } else {\n clearChatButton.style.paddingTop = \"\";\n clearChatButton.style.paddingBottom = \"\";\n }\n\n clearChatButtonWrapper.appendChild(clearChatButton);\n\n // Add tooltip with portaling to document.body to escape overflow clipping\n if (\n clearChatShowTooltip &&\n clearChatTooltipText &&\n clearChatButton &&\n clearChatButtonWrapper\n ) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip || !clearChatButton) return; // Already showing or button doesn't exist\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = clearChatTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = clearChatButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n clearChatButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n clearChatButton.addEventListener(\"focus\", showTooltip);\n clearChatButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the button for later use\n (clearChatButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n }\n if (clearChatButton) {\n clearChatButton.removeEventListener(\"focus\", showTooltip);\n clearChatButton.removeEventListener(\"blur\", hideTooltip);\n }\n };\n }\n\n // Only append to header if inline placement\n if (clearChatPlacement === \"inline\") {\n header.appendChild(clearChatButtonWrapper);\n }\n }\n\n // Create close button wrapper for tooltip positioning\n // Only needs ml-auto if clear chat is disabled or top-right positioned\n const closeButtonWrapper = createElement(\n \"div\",\n closeButtonPlacement === \"top-right\"\n ? \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50\"\n : clearChatEnabled && clearChatPlacement === \"inline\"\n ? \"\"\n : \"tvw-ml-auto\"\n );\n\n // Create close button with base classes\n const closeButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n closeButton.type = \"button\";\n\n // Get tooltip config\n const closeButtonTooltipText = launcher.closeButtonTooltipText ?? \"Close chat\";\n const closeButtonShowTooltip = launcher.closeButtonShowTooltip ?? true;\n\n closeButton.setAttribute(\"aria-label\", closeButtonTooltipText);\n closeButton.style.display = showClose ? \"\" : \"none\";\n\n // Add icon or fallback text\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeButtonIconText = launcher.closeButtonIconText ?? \"×\";\n\n // Try to render Lucide icon, fallback to text if not provided or fails\n const closeIconSvg = renderLucideIcon(\n closeButtonIconName,\n \"20px\",\n launcher.closeButtonColor || \"\",\n 2\n );\n if (closeIconSvg) {\n closeButton.appendChild(closeIconSvg);\n } else {\n closeButton.textContent = closeButtonIconText;\n }\n\n // Apply close button styling from config\n if (launcher.closeButtonColor) {\n closeButton.style.color = launcher.closeButtonColor;\n closeButton.classList.remove(\"tvw-text-cw-muted\");\n } else {\n closeButton.style.color = \"\";\n closeButton.classList.add(\"tvw-text-cw-muted\");\n }\n\n if (launcher.closeButtonBackgroundColor) {\n closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;\n closeButton.classList.remove(\"hover:tvw-bg-gray-100\");\n } else {\n closeButton.style.backgroundColor = \"\";\n closeButton.classList.add(\"hover:tvw-bg-gray-100\");\n }\n\n // Apply border if width and/or color are provided\n if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {\n const borderWidth = launcher.closeButtonBorderWidth || \"0px\";\n const borderColor = launcher.closeButtonBorderColor || \"transparent\";\n closeButton.style.border = `${borderWidth} solid ${borderColor}`;\n closeButton.classList.remove(\"tvw-border-none\");\n } else {\n closeButton.style.border = \"\";\n closeButton.classList.add(\"tvw-border-none\");\n }\n\n if (launcher.closeButtonBorderRadius) {\n closeButton.style.borderRadius = launcher.closeButtonBorderRadius;\n closeButton.classList.remove(\"tvw-rounded-full\");\n } else {\n closeButton.style.borderRadius = \"\";\n closeButton.classList.add(\"tvw-rounded-full\");\n }\n\n // Apply padding styling\n if (launcher.closeButtonPaddingX) {\n closeButton.style.paddingLeft = launcher.closeButtonPaddingX;\n closeButton.style.paddingRight = launcher.closeButtonPaddingX;\n } else {\n closeButton.style.paddingLeft = \"\";\n closeButton.style.paddingRight = \"\";\n }\n if (launcher.closeButtonPaddingY) {\n closeButton.style.paddingTop = launcher.closeButtonPaddingY;\n closeButton.style.paddingBottom = launcher.closeButtonPaddingY;\n } else {\n closeButton.style.paddingTop = \"\";\n closeButton.style.paddingBottom = \"\";\n }\n\n closeButtonWrapper.appendChild(closeButton);\n\n // Add tooltip with portaling to document.body to escape overflow clipping\n if (closeButtonShowTooltip && closeButtonTooltipText) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip) return; // Already showing\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = closeButtonTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = closeButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n closeButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n closeButton.addEventListener(\"focus\", showTooltip);\n closeButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the wrapper for later use\n (closeButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n closeButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n closeButton.removeEventListener(\"focus\", showTooltip);\n closeButton.removeEventListener(\"blur\", hideTooltip);\n };\n }\n\n // Inline placement: append close button to header\n if (closeButtonPlacement !== \"top-right\") {\n header.appendChild(closeButtonWrapper);\n }\n\n return {\n header,\n iconHolder,\n headerTitle: title,\n headerSubtitle: subtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton,\n clearChatButtonWrapper\n };\n};\n\n/**\n * Attach header elements to the container, handling placement modes.\n */\nexport const attachHeaderToContainer = (\n container: HTMLElement,\n headerElements: HeaderElements,\n config?: AgentWidgetConfig\n): void => {\n const launcher = config?.launcher ?? {};\n const closeButtonPlacement = launcher.closeButtonPlacement ?? \"inline\";\n const clearChatPlacement = launcher.clearChat?.placement ?? \"inline\";\n\n // Add header to container\n container.appendChild(headerElements.header);\n\n // Position close button wrapper if top-right placement\n if (closeButtonPlacement === \"top-right\") {\n container.style.position = \"relative\";\n container.appendChild(headerElements.closeButtonWrapper);\n }\n\n // Position clear chat button wrapper if top-right placement\n if (\n headerElements.clearChatButtonWrapper &&\n clearChatPlacement === \"top-right\"\n ) {\n container.style.position = \"relative\";\n container.appendChild(headerElements.clearChatButtonWrapper);\n }\n};\n\n\n","import { createElement } from \"../utils/dom\";\nimport { renderLucideIcon } from \"../utils/icons\";\nimport { AgentWidgetConfig, AgentWidgetHeaderLayoutConfig } from \"../types\";\nimport { buildHeader, HeaderElements, attachHeaderToContainer } from \"./header-builder\";\n\nexport interface HeaderLayoutContext {\n config: AgentWidgetConfig;\n showClose?: boolean;\n onClose?: () => void;\n onClearChat?: () => void;\n}\n\nexport type HeaderLayoutRenderer = (context: HeaderLayoutContext) => HeaderElements;\n\n/**\n * Build default header layout\n * Full header with icon, title, subtitle, clear chat, and close button\n */\nexport const buildDefaultHeader: HeaderLayoutRenderer = (context) => {\n return buildHeader({\n config: context.config,\n showClose: context.showClose,\n onClose: context.onClose,\n onClearChat: context.onClearChat\n });\n};\n\n/**\n * Build minimal header layout\n * Simplified layout with just title and close button\n */\nexport const buildMinimalHeader: HeaderLayoutRenderer = (context) => {\n const { config, showClose = true, onClose } = context;\n const launcher = config?.launcher ?? {};\n\n const header = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-between tvw-bg-cw-surface tvw-px-6 tvw-py-4 tvw-border-b-cw-divider\"\n );\n\n // Title only (no icon, no subtitle)\n const title = createElement(\"span\", \"tvw-text-base tvw-font-semibold\");\n title.textContent = launcher.title ?? \"Chat Assistant\";\n\n header.appendChild(title);\n\n // Close button\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonWrapper = createElement(\"div\", \"\");\n\n const closeButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n closeButton.type = \"button\";\n closeButton.setAttribute(\"aria-label\", \"Close chat\");\n closeButton.style.display = showClose ? \"\" : \"none\";\n\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeIconSvg = renderLucideIcon(\n closeButtonIconName,\n \"20px\",\n launcher.closeButtonColor || \"\",\n 2\n );\n if (closeIconSvg) {\n closeButton.appendChild(closeIconSvg);\n } else {\n closeButton.textContent = \"×\";\n }\n\n if (onClose) {\n closeButton.addEventListener(\"click\", onClose);\n }\n\n closeButtonWrapper.appendChild(closeButton);\n header.appendChild(closeButtonWrapper);\n\n // Create placeholder elements for compatibility\n const iconHolder = createElement(\"div\");\n iconHolder.style.display = \"none\";\n const headerSubtitle = createElement(\"span\");\n headerSubtitle.style.display = \"none\";\n\n return {\n header,\n iconHolder,\n headerTitle: title,\n headerSubtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton: null,\n clearChatButtonWrapper: null\n };\n};\n\n/**\n * Build expanded header layout\n * Full branding area with additional space for custom content\n */\nexport const buildExpandedHeader: HeaderLayoutRenderer = (context) => {\n const { config, showClose = true, onClose, onClearChat } = context;\n const launcher = config?.launcher ?? {};\n\n const header = createElement(\n \"div\",\n \"tvw-flex tvw-flex-col tvw-bg-cw-surface tvw-px-6 tvw-py-5 tvw-border-b-cw-divider\"\n );\n\n // Top row: icon + text + buttons\n const topRow = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-gap-3\"\n );\n\n // Icon\n const headerIconSize = launcher.headerIconSize ?? \"56px\";\n const iconHolder = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-center tvw-rounded-xl tvw-bg-cw-primary tvw-text-white tvw-text-2xl\"\n );\n iconHolder.style.height = headerIconSize;\n iconHolder.style.width = headerIconSize;\n\n const headerIconName = launcher.headerIconName;\n if (headerIconName) {\n const iconSize = parseFloat(headerIconSize) || 24;\n const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.5, \"#ffffff\", 2);\n if (iconSvg) {\n iconHolder.replaceChildren(iconSvg);\n } else {\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n } else if (launcher.iconUrl) {\n const img = createElement(\"img\") as HTMLImageElement;\n img.src = launcher.iconUrl;\n img.alt = \"\";\n img.className = \"tvw-rounded-xl tvw-object-cover\";\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n iconHolder.replaceChildren(img);\n } else {\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n\n // Title and subtitle\n const headerCopy = createElement(\"div\", \"tvw-flex tvw-flex-col tvw-flex-1\");\n const title = createElement(\"span\", \"tvw-text-lg tvw-font-semibold\");\n title.textContent = launcher.title ?? \"Chat Assistant\";\n const subtitle = createElement(\"span\", \"tvw-text-sm tvw-text-cw-muted\");\n subtitle.textContent = launcher.subtitle ?? \"Here to help you get answers fast\";\n headerCopy.append(title, subtitle);\n\n topRow.append(iconHolder, headerCopy);\n\n // Close button\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonWrapper = createElement(\"div\", \"\");\n\n const closeButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n closeButton.type = \"button\";\n closeButton.setAttribute(\"aria-label\", \"Close chat\");\n closeButton.style.display = showClose ? \"\" : \"none\";\n\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeIconSvg = renderLucideIcon(\n closeButtonIconName,\n \"20px\",\n launcher.closeButtonColor || \"\",\n 2\n );\n if (closeIconSvg) {\n closeButton.appendChild(closeIconSvg);\n } else {\n closeButton.textContent = \"×\";\n }\n\n if (onClose) {\n closeButton.addEventListener(\"click\", onClose);\n }\n\n closeButtonWrapper.appendChild(closeButton);\n topRow.appendChild(closeButtonWrapper);\n\n header.appendChild(topRow);\n\n // Bottom row: additional space for status or branding\n const bottomRow = createElement(\n \"div\",\n \"tvw-mt-3 tvw-pt-3 tvw-border-t tvw-border-gray-100 tvw-text-xs tvw-text-cw-muted\"\n );\n bottomRow.textContent = \"Online and ready to help\";\n header.appendChild(bottomRow);\n\n return {\n header,\n iconHolder,\n headerTitle: title,\n headerSubtitle: subtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton: null,\n clearChatButtonWrapper: null\n };\n};\n\n/**\n * Header layout registry\n * Maps layout names to their renderer functions\n */\nexport const headerLayouts: Record<string, HeaderLayoutRenderer> = {\n default: buildDefaultHeader,\n minimal: buildMinimalHeader,\n expanded: buildExpandedHeader\n};\n\n/**\n * Get header layout renderer by name\n */\nexport const getHeaderLayout = (layoutName: string): HeaderLayoutRenderer => {\n return headerLayouts[layoutName] ?? headerLayouts.default;\n};\n\n/**\n * Build header based on layout configuration\n * Applies layout config settings to determine which layout to use\n */\nexport const buildHeaderWithLayout = (\n config: AgentWidgetConfig,\n layoutConfig?: AgentWidgetHeaderLayoutConfig,\n context?: Partial<HeaderLayoutContext>\n): HeaderElements => {\n // If custom render is provided, use it\n if (layoutConfig?.render) {\n const customHeader = layoutConfig.render({\n config,\n onClose: context?.onClose,\n onClearChat: context?.onClearChat\n });\n \n // Wrap in HeaderElements structure\n const iconHolder = createElement(\"div\");\n iconHolder.style.display = \"none\";\n const headerTitle = createElement(\"span\");\n const headerSubtitle = createElement(\"span\");\n const closeButton = createElement(\"button\") as HTMLButtonElement;\n closeButton.style.display = \"none\";\n const closeButtonWrapper = createElement(\"div\");\n closeButtonWrapper.style.display = \"none\";\n \n return {\n header: customHeader,\n iconHolder,\n headerTitle,\n headerSubtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton: null,\n clearChatButtonWrapper: null\n };\n }\n\n // Get layout renderer\n const layoutName = layoutConfig?.layout ?? \"default\";\n const layoutRenderer = getHeaderLayout(layoutName);\n\n // Build header with layout\n const headerElements = layoutRenderer({\n config,\n showClose: layoutConfig?.showCloseButton ?? context?.showClose ?? true,\n onClose: context?.onClose,\n onClearChat: context?.onClearChat\n });\n\n // Apply visibility settings from layout config\n if (layoutConfig) {\n if (layoutConfig.showIcon === false) {\n headerElements.iconHolder.style.display = \"none\";\n }\n if (layoutConfig.showTitle === false) {\n headerElements.headerTitle.style.display = \"none\";\n }\n if (layoutConfig.showSubtitle === false) {\n headerElements.headerSubtitle.style.display = \"none\";\n }\n if (layoutConfig.showCloseButton === false) {\n headerElements.closeButton.style.display = \"none\";\n }\n if (layoutConfig.showClearChat === false && headerElements.clearChatButtonWrapper) {\n headerElements.clearChatButtonWrapper.style.display = \"none\";\n }\n }\n\n return headerElements;\n};\n\n","import { createElement } from \"../utils/dom\";\nimport { renderLucideIcon } from \"../utils/icons\";\nimport { AgentWidgetConfig } from \"../types\";\n\nexport interface ComposerElements {\n footer: HTMLElement;\n suggestions: HTMLElement;\n composerForm: HTMLFormElement;\n textarea: HTMLTextAreaElement;\n sendButton: HTMLButtonElement;\n sendButtonWrapper: HTMLElement;\n micButton: HTMLButtonElement | null;\n micButtonWrapper: HTMLElement | null;\n statusText: HTMLElement;\n}\n\nexport interface ComposerBuildContext {\n config?: AgentWidgetConfig;\n onSubmit?: (text: string) => void;\n disabled?: boolean;\n}\n\n/**\n * Helper to get font family CSS value from config preset\n */\nconst getFontFamilyValue = (\n family: \"sans-serif\" | \"serif\" | \"mono\"\n): string => {\n switch (family) {\n case \"serif\":\n return 'Georgia, \"Times New Roman\", Times, serif';\n case \"mono\":\n return '\"Courier New\", Courier, \"Lucida Console\", Monaco, monospace';\n case \"sans-serif\":\n default:\n return '-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif';\n }\n};\n\n/**\n * Build the composer/footer section of the panel.\n * Extracted for reuse and plugin override support.\n */\nexport const buildComposer = (context: ComposerBuildContext): ComposerElements => {\n const { config } = context;\n\n const footer = createElement(\n \"div\",\n \"tvw-widget-footer tvw-border-t-cw-divider tvw-bg-cw-surface tvw-px-6 tvw-py-4\"\n );\n\n const suggestions = createElement(\n \"div\",\n \"tvw-mb-3 tvw-flex tvw-flex-wrap tvw-gap-2\"\n );\n\n // Determine gap based on voice recognition\n const voiceRecognitionEnabledForGap =\n config?.voiceRecognition?.enabled === true;\n const hasSpeechRecognitionForGap =\n typeof window !== \"undefined\" &&\n (typeof (window as any).webkitSpeechRecognition !== \"undefined\" ||\n typeof (window as any).SpeechRecognition !== \"undefined\");\n const shouldUseSmallGap =\n voiceRecognitionEnabledForGap && hasSpeechRecognitionForGap;\n const gapClass = shouldUseSmallGap ? \"tvw-gap-1\" : \"tvw-gap-3\";\n\n const composerForm = createElement(\n \"form\",\n `tvw-widget-composer tvw-flex tvw-items-end ${gapClass} tvw-rounded-2xl tvw-border tvw-border-gray-200 tvw-bg-cw-input-background tvw-px-4 tvw-py-3`\n ) as HTMLFormElement;\n // Prevent form from getting focus styles\n composerForm.style.outline = \"none\";\n\n const textarea = createElement(\"textarea\") as HTMLTextAreaElement;\n textarea.placeholder = config?.copy?.inputPlaceholder ?? \"Type your message…\";\n textarea.className =\n \"tvw-min-h-[48px] tvw-flex-1 tvw-resize-none tvw-border-none tvw-bg-transparent tvw-text-sm tvw-text-cw-primary focus:tvw-outline-none focus:tvw-border-none\";\n textarea.rows = 1;\n\n // Apply font family and weight from config\n const fontFamily = config?.theme?.inputFontFamily ?? \"sans-serif\";\n const fontWeight = config?.theme?.inputFontWeight ?? \"400\";\n\n textarea.style.fontFamily = getFontFamilyValue(fontFamily);\n textarea.style.fontWeight = fontWeight;\n\n // Explicitly remove border and outline on focus to prevent browser defaults\n textarea.style.border = \"none\";\n textarea.style.outline = \"none\";\n textarea.style.borderWidth = \"0\";\n textarea.style.borderStyle = \"none\";\n textarea.style.borderColor = \"transparent\";\n textarea.addEventListener(\"focus\", () => {\n textarea.style.border = \"none\";\n textarea.style.outline = \"none\";\n textarea.style.borderWidth = \"0\";\n textarea.style.borderStyle = \"none\";\n textarea.style.borderColor = \"transparent\";\n textarea.style.boxShadow = \"none\";\n });\n textarea.addEventListener(\"blur\", () => {\n textarea.style.border = \"none\";\n textarea.style.outline = \"none\";\n });\n\n // Send button configuration\n const sendButtonConfig = config?.sendButton ?? {};\n const useIcon = sendButtonConfig.useIcon ?? false;\n const iconText = sendButtonConfig.iconText ?? \"↑\";\n const iconName = sendButtonConfig.iconName;\n const tooltipText = sendButtonConfig.tooltipText ?? \"Send message\";\n const showTooltip = sendButtonConfig.showTooltip ?? false;\n const buttonSize = sendButtonConfig.size ?? \"40px\";\n const backgroundColor = sendButtonConfig.backgroundColor;\n const textColor = sendButtonConfig.textColor;\n\n // Create wrapper for tooltip positioning\n const sendButtonWrapper = createElement(\"div\", \"tvw-send-button-wrapper\");\n\n const sendButton = createElement(\n \"button\",\n useIcon\n ? \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\"\n : \"tvw-rounded-button tvw-bg-cw-accent tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold disabled:tvw-opacity-50 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n\n sendButton.type = \"submit\";\n\n if (useIcon) {\n // Icon mode: circular button\n sendButton.style.width = buttonSize;\n sendButton.style.height = buttonSize;\n sendButton.style.minWidth = buttonSize;\n sendButton.style.minHeight = buttonSize;\n sendButton.style.fontSize = \"18px\";\n sendButton.style.lineHeight = \"1\";\n\n // Clear any existing content\n sendButton.innerHTML = \"\";\n\n // Use Lucide icon if iconName is provided, otherwise fall back to iconText\n if (iconName) {\n const iconSize = parseFloat(buttonSize) || 24;\n const iconColor =\n textColor && typeof textColor === \"string\" && textColor.trim()\n ? textColor.trim()\n : \"currentColor\";\n const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);\n if (iconSvg) {\n sendButton.appendChild(iconSvg);\n sendButton.style.color = iconColor;\n } else {\n // Fallback to text if icon fails to render\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n } else {\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n\n if (backgroundColor) {\n sendButton.style.backgroundColor = backgroundColor;\n } else {\n sendButton.classList.add(\"tvw-bg-cw-primary\");\n }\n } else {\n // Text mode: existing behavior\n sendButton.textContent = config?.copy?.sendButtonLabel ?? \"Send\";\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n\n // Apply existing styling from config\n if (sendButtonConfig.borderWidth) {\n sendButton.style.borderWidth = sendButtonConfig.borderWidth;\n sendButton.style.borderStyle = \"solid\";\n }\n if (sendButtonConfig.borderColor) {\n sendButton.style.borderColor = sendButtonConfig.borderColor;\n }\n\n // Apply padding styling (works in both icon and text mode)\n if (sendButtonConfig.paddingX) {\n sendButton.style.paddingLeft = sendButtonConfig.paddingX;\n sendButton.style.paddingRight = sendButtonConfig.paddingX;\n } else {\n sendButton.style.paddingLeft = \"\";\n sendButton.style.paddingRight = \"\";\n }\n if (sendButtonConfig.paddingY) {\n sendButton.style.paddingTop = sendButtonConfig.paddingY;\n sendButton.style.paddingBottom = sendButtonConfig.paddingY;\n } else {\n sendButton.style.paddingTop = \"\";\n sendButton.style.paddingBottom = \"\";\n }\n\n // Add tooltip if enabled\n if (showTooltip && tooltipText) {\n const tooltip = createElement(\"div\", \"tvw-send-button-tooltip\");\n tooltip.textContent = tooltipText;\n sendButtonWrapper.appendChild(tooltip);\n }\n\n sendButtonWrapper.appendChild(sendButton);\n\n // Voice recognition mic button\n const voiceRecognitionConfig = config?.voiceRecognition ?? {};\n const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;\n let micButton: HTMLButtonElement | null = null;\n let micButtonWrapper: HTMLElement | null = null;\n\n // Check browser support for speech recognition\n const hasSpeechRecognition =\n typeof window !== \"undefined\" &&\n (typeof (window as any).webkitSpeechRecognition !== \"undefined\" ||\n typeof (window as any).SpeechRecognition !== \"undefined\");\n\n if (voiceRecognitionEnabled && hasSpeechRecognition) {\n micButtonWrapper = createElement(\"div\", \"tvw-send-button-wrapper\");\n micButton = createElement(\n \"button\",\n \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n\n micButton.type = \"button\";\n micButton.setAttribute(\"aria-label\", \"Start voice recognition\");\n\n const micIconName = voiceRecognitionConfig.iconName ?? \"mic\";\n const micIconSize = voiceRecognitionConfig.iconSize ?? buttonSize;\n const micIconSizeNum = parseFloat(micIconSize) || 24;\n\n // Use dedicated colors from voice recognition config, fallback to send button colors\n const micBackgroundColor =\n voiceRecognitionConfig.backgroundColor ?? backgroundColor;\n const micIconColor = voiceRecognitionConfig.iconColor ?? textColor;\n\n micButton.style.width = micIconSize;\n micButton.style.height = micIconSize;\n micButton.style.minWidth = micIconSize;\n micButton.style.minHeight = micIconSize;\n micButton.style.fontSize = \"18px\";\n micButton.style.lineHeight = \"1\";\n\n // Use Lucide mic icon with configured color (stroke width 1.5 for minimalist outline style)\n const iconColorValue = micIconColor || \"currentColor\";\n const micIconSvg = renderLucideIcon(\n micIconName,\n micIconSizeNum,\n iconColorValue,\n 1.5\n );\n if (micIconSvg) {\n micButton.appendChild(micIconSvg);\n micButton.style.color = iconColorValue;\n } else {\n // Fallback to text if icon fails\n micButton.textContent = \"🎤\";\n micButton.style.color = iconColorValue;\n }\n\n // Apply background color\n if (micBackgroundColor) {\n micButton.style.backgroundColor = micBackgroundColor;\n } else {\n micButton.classList.add(\"tvw-bg-cw-primary\");\n }\n\n // Apply icon/text color\n if (micIconColor) {\n micButton.style.color = micIconColor;\n } else if (!micIconColor && !textColor) {\n micButton.classList.add(\"tvw-text-white\");\n }\n\n // Apply border styling\n if (voiceRecognitionConfig.borderWidth) {\n micButton.style.borderWidth = voiceRecognitionConfig.borderWidth;\n micButton.style.borderStyle = \"solid\";\n }\n if (voiceRecognitionConfig.borderColor) {\n micButton.style.borderColor = voiceRecognitionConfig.borderColor;\n }\n\n // Apply padding styling\n if (voiceRecognitionConfig.paddingX) {\n micButton.style.paddingLeft = voiceRecognitionConfig.paddingX;\n micButton.style.paddingRight = voiceRecognitionConfig.paddingX;\n }\n if (voiceRecognitionConfig.paddingY) {\n micButton.style.paddingTop = voiceRecognitionConfig.paddingY;\n micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;\n }\n\n micButtonWrapper.appendChild(micButton);\n\n // Add tooltip if enabled\n const micTooltipText =\n voiceRecognitionConfig.tooltipText ?? \"Start voice recognition\";\n const showMicTooltip = voiceRecognitionConfig.showTooltip ?? false;\n if (showMicTooltip && micTooltipText) {\n const tooltip = createElement(\"div\", \"tvw-send-button-tooltip\");\n tooltip.textContent = micTooltipText;\n micButtonWrapper.appendChild(tooltip);\n }\n }\n\n // Focus textarea when composer form container is clicked\n composerForm.addEventListener(\"click\", (e) => {\n // Don't focus if clicking on the send button, mic button, or their wrappers\n if (\n e.target !== sendButton &&\n e.target !== sendButtonWrapper &&\n e.target !== micButton &&\n e.target !== micButtonWrapper\n ) {\n textarea.focus();\n }\n });\n\n // Append elements: textarea, mic button (if exists), send button\n composerForm.append(textarea);\n if (micButtonWrapper) {\n composerForm.append(micButtonWrapper);\n }\n composerForm.append(sendButtonWrapper);\n\n const statusText = createElement(\n \"div\",\n \"tvw-mt-2 tvw-text-right tvw-text-xs tvw-text-cw-muted\"\n );\n\n // Apply status indicator config\n const statusConfig = config?.statusIndicator ?? {};\n const isVisible = statusConfig.visible ?? true;\n statusText.style.display = isVisible ? \"\" : \"none\";\n statusText.textContent = statusConfig.idleText ?? \"Online\";\n\n footer.append(suggestions, composerForm, statusText);\n\n return {\n footer,\n suggestions,\n composerForm,\n textarea,\n sendButton,\n sendButtonWrapper,\n micButton,\n micButtonWrapper,\n statusText\n };\n};\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetConfig } from \"../types\";\nimport { positionMap } from \"../utils/positioning\";\nimport { buildHeader, attachHeaderToContainer, HeaderElements } from \"./header-builder\";\nimport { buildHeaderWithLayout } from \"./header-layouts\";\nimport { buildComposer, ComposerElements } from \"./composer-builder\";\n\nexport interface PanelWrapper {\n wrapper: HTMLElement;\n panel: HTMLElement;\n}\n\nexport const createWrapper = (config?: AgentWidgetConfig): PanelWrapper => {\n const launcherEnabled = config?.launcher?.enabled ?? true;\n\n if (!launcherEnabled) {\n // For inline embed mode, use flex layout to ensure the widget fills its container\n // and only the chat messages area scrolls\n const wrapper = createElement(\n \"div\",\n \"tvw-relative tvw-h-full tvw-flex tvw-flex-col tvw-flex-1 tvw-min-h-0\"\n );\n const panel = createElement(\n \"div\",\n \"tvw-relative tvw-flex-1 tvw-flex tvw-flex-col tvw-min-h-0\"\n );\n \n // Apply width from config, defaulting to 100% for inline embed mode\n const inlineWidth = config?.launcher?.width ?? \"100%\";\n wrapper.style.width = inlineWidth;\n panel.style.width = \"100%\";\n \n wrapper.appendChild(panel);\n return { wrapper, panel };\n }\n\n const launcher = config?.launcher ?? {};\n const position =\n launcher.position && positionMap[launcher.position]\n ? positionMap[launcher.position]\n : positionMap[\"bottom-right\"];\n\n const wrapper = createElement(\n \"div\",\n `tvw-widget-wrapper tvw-fixed ${position} tvw-z-50 tvw-transition`\n );\n\n const panel = createElement(\n \"div\",\n \"tvw-widget-panel tvw-relative tvw-min-h-[320px]\"\n );\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(400px, calc(100vw - 24px))\";\n panel.style.width = width;\n panel.style.maxWidth = width;\n\n wrapper.appendChild(panel);\n return { wrapper, panel };\n};\n\nexport interface PanelElements {\n container: HTMLElement;\n body: HTMLElement;\n messagesWrapper: HTMLElement;\n suggestions: HTMLElement;\n textarea: HTMLTextAreaElement;\n sendButton: HTMLButtonElement;\n sendButtonWrapper: HTMLElement;\n micButton: HTMLButtonElement | null;\n micButtonWrapper: HTMLElement | null;\n composerForm: HTMLFormElement;\n statusText: HTMLElement;\n introTitle: HTMLElement;\n introSubtitle: HTMLElement;\n closeButton: HTMLButtonElement;\n closeButtonWrapper: HTMLElement;\n clearChatButton: HTMLButtonElement | null;\n clearChatButtonWrapper: HTMLElement | null;\n iconHolder: HTMLElement;\n headerTitle: HTMLElement;\n headerSubtitle: HTMLElement;\n // Exposed for potential header replacement\n header: HTMLElement;\n footer: HTMLElement;\n}\n\nexport const buildPanel = (config?: AgentWidgetConfig, showClose = true): PanelElements => {\n // Use flex-1 and min-h-0 to ensure the container fills its parent and allows\n // the body (chat messages area) to scroll while header/footer stay fixed\n const container = createElement(\n \"div\",\n \"tvw-widget-container tvw-flex tvw-h-full tvw-w-full tvw-flex-1 tvw-min-h-0 tvw-flex-col tvw-bg-cw-surface tvw-text-cw-primary tvw-rounded-2xl tvw-overflow-hidden tvw-border tvw-border-cw-border\"\n );\n\n // Build header using layout config if available, otherwise use standard builder\n const headerLayoutConfig = config?.layout?.header;\n const headerElements: HeaderElements = headerLayoutConfig\n ? buildHeaderWithLayout(config!, headerLayoutConfig, { showClose })\n : buildHeader({ config, showClose });\n\n // Build body with intro card and messages wrapper\n const body = createElement(\n \"div\",\n \"tvw-widget-body tvw-flex tvw-flex-1 tvw-min-h-0 tvw-flex-col tvw-gap-6 tvw-overflow-y-auto tvw-bg-cw-container tvw-px-6 tvw-py-6\"\n );\n body.id = \"vanilla-agent-scroll-container\";\n \n const introCard = createElement(\n \"div\",\n \"tvw-rounded-2xl tvw-bg-cw-surface tvw-p-6 tvw-shadow-sm\"\n );\n const introTitle = createElement(\n \"h2\",\n \"tvw-text-lg tvw-font-semibold tvw-text-cw-primary\"\n );\n introTitle.textContent = config?.copy?.welcomeTitle ?? \"Hello 👋\";\n const introSubtitle = createElement(\n \"p\",\n \"tvw-mt-2 tvw-text-sm tvw-text-cw-muted\"\n );\n introSubtitle.textContent =\n config?.copy?.welcomeSubtitle ??\n \"Ask anything about your account or products.\";\n introCard.append(introTitle, introSubtitle);\n\n const messagesWrapper = createElement(\n \"div\",\n \"tvw-flex tvw-flex-col tvw-gap-3\"\n );\n\n body.append(introCard, messagesWrapper);\n\n // Build composer/footer using extracted builder\n const composerElements: ComposerElements = buildComposer({ config });\n\n // Assemble container with header, body, and footer\n attachHeaderToContainer(container, headerElements, config);\n container.append(body, composerElements.footer);\n\n return {\n container,\n body,\n messagesWrapper,\n suggestions: composerElements.suggestions,\n textarea: composerElements.textarea,\n sendButton: composerElements.sendButton,\n sendButtonWrapper: composerElements.sendButtonWrapper,\n micButton: composerElements.micButton,\n micButtonWrapper: composerElements.micButtonWrapper,\n composerForm: composerElements.composerForm,\n statusText: composerElements.statusText,\n introTitle,\n introSubtitle,\n closeButton: headerElements.closeButton,\n closeButtonWrapper: headerElements.closeButtonWrapper,\n clearChatButton: headerElements.clearChatButton,\n clearChatButtonWrapper: headerElements.clearChatButtonWrapper,\n iconHolder: headerElements.iconHolder,\n headerTitle: headerElements.headerTitle,\n headerSubtitle: headerElements.headerSubtitle,\n header: headerElements.header,\n footer: composerElements.footer\n };\n};\n\n// Re-export builder types and functions for plugin use\nexport { buildHeader, buildComposer, attachHeaderToContainer };\nexport type { HeaderElements, HeaderBuildContext } from \"./header-builder\";\nexport type { ComposerElements, ComposerBuildContext } from \"./composer-builder\";\n","import { createElement } from \"../utils/dom\";\nimport { \n AgentWidgetMessage, \n AgentWidgetMessageLayoutConfig,\n AgentWidgetAvatarConfig,\n AgentWidgetTimestampConfig,\n AgentWidgetMessageActionsConfig,\n AgentWidgetMessageFeedback\n} from \"../types\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\nexport type MessageTransform = (context: {\n text: string;\n message: AgentWidgetMessage;\n streaming: boolean;\n raw?: string;\n}) => string;\n\nexport type MessageActionCallbacks = {\n onCopy?: (message: AgentWidgetMessage) => void;\n onFeedback?: (feedback: AgentWidgetMessageFeedback) => void;\n};\n\n// Create typing indicator element\nexport const createTypingIndicator = (): HTMLElement => {\n const container = document.createElement(\"div\");\n container.className = \"tvw-flex tvw-items-center tvw-space-x-1 tvw-h-5 tvw-mt-2\";\n\n const dot1 = document.createElement(\"div\");\n dot1.className = \"tvw-bg-cw-primary tvw-animate-typing tvw-rounded-full tvw-h-1.5 tvw-w-1.5\";\n dot1.style.animationDelay = \"0ms\";\n\n const dot2 = document.createElement(\"div\");\n dot2.className = \"tvw-bg-cw-primary tvw-animate-typing tvw-rounded-full tvw-h-1.5 tvw-w-1.5\";\n dot2.style.animationDelay = \"250ms\";\n\n const dot3 = document.createElement(\"div\");\n dot3.className = \"tvw-bg-cw-primary tvw-animate-typing tvw-rounded-full tvw-h-1.5 tvw-w-1.5\";\n dot3.style.animationDelay = \"500ms\";\n\n const srOnly = document.createElement(\"span\");\n srOnly.className = \"tvw-sr-only\";\n srOnly.textContent = \"Loading\";\n\n container.appendChild(dot1);\n container.appendChild(dot2);\n container.appendChild(dot3);\n container.appendChild(srOnly);\n\n return container;\n};\n\n/**\n * Create an avatar element\n */\nconst createAvatar = (\n avatarConfig: AgentWidgetAvatarConfig,\n role: \"user\" | \"assistant\"\n): HTMLElement => {\n const avatar = createElement(\n \"div\",\n \"tvw-flex-shrink-0 tvw-w-8 tvw-h-8 tvw-rounded-full tvw-flex tvw-items-center tvw-justify-center tvw-text-sm\"\n );\n\n const avatarContent = role === \"user\" \n ? avatarConfig.userAvatar \n : avatarConfig.assistantAvatar;\n\n if (avatarContent) {\n // Check if it's a URL or emoji/text\n if (avatarContent.startsWith(\"http\") || avatarContent.startsWith(\"/\") || avatarContent.startsWith(\"data:\")) {\n const img = createElement(\"img\") as HTMLImageElement;\n img.src = avatarContent;\n img.alt = role === \"user\" ? \"User\" : \"Assistant\";\n img.className = \"tvw-w-full tvw-h-full tvw-rounded-full tvw-object-cover\";\n avatar.appendChild(img);\n } else {\n // Emoji or text\n avatar.textContent = avatarContent;\n avatar.classList.add(\n role === \"user\" ? \"tvw-bg-cw-accent\" : \"tvw-bg-cw-primary\",\n \"tvw-text-white\"\n );\n }\n } else {\n // Default avatar\n avatar.textContent = role === \"user\" ? \"U\" : \"A\";\n avatar.classList.add(\n role === \"user\" ? \"tvw-bg-cw-accent\" : \"tvw-bg-cw-primary\",\n \"tvw-text-white\"\n );\n }\n\n return avatar;\n};\n\n/**\n * Create a timestamp element\n */\nconst createTimestamp = (\n message: AgentWidgetMessage,\n timestampConfig: AgentWidgetTimestampConfig\n): HTMLElement => {\n const timestamp = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n\n const date = new Date(message.createdAt);\n \n if (timestampConfig.format) {\n timestamp.textContent = timestampConfig.format(date);\n } else {\n // Default format: HH:MM\n timestamp.textContent = date.toLocaleTimeString([], { \n hour: \"2-digit\", \n minute: \"2-digit\" \n });\n }\n\n return timestamp;\n};\n\n/**\n * Get bubble classes based on layout preset\n */\nconst getBubbleClasses = (\n role: \"user\" | \"assistant\" | \"system\",\n layout: AgentWidgetMessageLayoutConfig[\"layout\"] = \"bubble\"\n): string[] => {\n const baseClasses = [\"vanilla-message-bubble\", \"tvw-max-w-[85%]\"];\n\n switch (layout) {\n case \"flat\":\n // Flat layout: no bubble styling, just text\n if (role === \"user\") {\n baseClasses.push(\n \"vanilla-message-user-bubble\",\n \"tvw-ml-auto\",\n \"tvw-text-cw-primary\",\n \"tvw-py-2\"\n );\n } else {\n baseClasses.push(\n \"vanilla-message-assistant-bubble\",\n \"tvw-text-cw-primary\",\n \"tvw-py-2\"\n );\n }\n break;\n\n case \"minimal\":\n // Minimal layout: reduced padding and styling\n baseClasses.push(\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\"\n );\n if (role === \"user\") {\n baseClasses.push(\n \"vanilla-message-user-bubble\",\n \"tvw-ml-auto\",\n \"tvw-bg-cw-accent\",\n \"tvw-text-white\",\n \"tvw-px-3\",\n \"tvw-py-2\",\n \"tvw-rounded-lg\"\n );\n } else {\n baseClasses.push(\n \"vanilla-message-assistant-bubble\",\n \"tvw-bg-cw-surface\",\n \"tvw-text-cw-primary\",\n \"tvw-px-3\",\n \"tvw-py-2\",\n \"tvw-rounded-lg\"\n );\n }\n break;\n\n case \"bubble\":\n default:\n // Default bubble layout\n baseClasses.push(\n \"tvw-rounded-2xl\",\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\",\n \"tvw-shadow-sm\"\n );\n if (role === \"user\") {\n baseClasses.push(\n \"vanilla-message-user-bubble\",\n \"tvw-ml-auto\",\n \"tvw-bg-cw-accent\",\n \"tvw-text-white\",\n \"tvw-px-5\",\n \"tvw-py-3\"\n );\n } else {\n baseClasses.push(\n \"vanilla-message-assistant-bubble\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-px-5\",\n \"tvw-py-3\"\n );\n }\n break;\n }\n\n return baseClasses;\n};\n\n/**\n * Create message action buttons (copy, upvote, downvote)\n */\nexport const createMessageActions = (\n message: AgentWidgetMessage,\n actionsConfig: AgentWidgetMessageActionsConfig,\n callbacks?: MessageActionCallbacks\n): HTMLElement => {\n const showCopy = actionsConfig.showCopy ?? true;\n const showUpvote = actionsConfig.showUpvote ?? true;\n const showDownvote = actionsConfig.showDownvote ?? true;\n const visibility = actionsConfig.visibility ?? \"hover\";\n const align = actionsConfig.align ?? \"right\";\n const layout = actionsConfig.layout ?? \"pill-inside\";\n\n // Map alignment to CSS class\n const alignClass = {\n left: \"tvw-message-actions-left\",\n center: \"tvw-message-actions-center\",\n right: \"tvw-message-actions-right\",\n }[align];\n\n // Map layout to CSS class\n const layoutClass = {\n \"pill-inside\": \"tvw-message-actions-pill\",\n \"row-inside\": \"tvw-message-actions-row\",\n }[layout];\n\n const container = createElement(\n \"div\",\n `tvw-message-actions tvw-flex tvw-items-center tvw-gap-1 tvw-mt-2 ${alignClass} ${layoutClass} ${\n visibility === \"hover\" ? \"tvw-message-actions-hover\" : \"\"\n }`\n );\n\n // Track vote state for this message\n let currentVote: \"upvote\" | \"downvote\" | null = null;\n\n const createActionButton = (\n iconName: string,\n label: string,\n onClick: () => void,\n dataAction?: string\n ): HTMLButtonElement => {\n const button = document.createElement(\"button\");\n button.className = \"tvw-message-action-btn\";\n button.setAttribute(\"aria-label\", label);\n button.setAttribute(\"title\", label);\n if (dataAction) {\n button.setAttribute(\"data-action\", dataAction);\n }\n\n const icon = renderLucideIcon(iconName, 14, \"currentColor\", 2);\n if (icon) {\n button.appendChild(icon);\n }\n\n button.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n onClick();\n });\n\n return button;\n };\n\n // Copy button\n if (showCopy) {\n const copyButton = createActionButton(\"copy\", \"Copy message\", () => {\n // Copy to clipboard\n const textToCopy = message.content || \"\";\n navigator.clipboard.writeText(textToCopy).then(() => {\n // Show success feedback - swap icon temporarily\n copyButton.classList.add(\"tvw-message-action-success\");\n const checkIcon = renderLucideIcon(\"check\", 14, \"currentColor\", 2);\n if (checkIcon) {\n copyButton.innerHTML = \"\";\n copyButton.appendChild(checkIcon);\n }\n \n // Restore original icon after 2 seconds\n setTimeout(() => {\n copyButton.classList.remove(\"tvw-message-action-success\");\n const originalIcon = renderLucideIcon(\"copy\", 14, \"currentColor\", 2);\n if (originalIcon) {\n copyButton.innerHTML = \"\";\n copyButton.appendChild(originalIcon);\n }\n }, 2000);\n }).catch((err) => {\n if (typeof console !== \"undefined\") {\n console.error(\"[AgentWidget] Failed to copy message:\", err);\n }\n });\n\n // Trigger callback\n if (callbacks?.onCopy) {\n callbacks.onCopy(message);\n }\n if (actionsConfig.onCopy) {\n actionsConfig.onCopy(message);\n }\n }, \"copy\");\n container.appendChild(copyButton);\n }\n\n // Upvote button\n if (showUpvote) {\n const upvoteButton = createActionButton(\"thumbs-up\", \"Upvote\", () => {\n const wasActive = currentVote === \"upvote\";\n \n // Toggle state\n if (wasActive) {\n currentVote = null;\n upvoteButton.classList.remove(\"tvw-message-action-active\");\n } else {\n // Remove downvote if active\n const downvoteBtn = container.querySelector('[data-action=\"downvote\"]');\n if (downvoteBtn) {\n downvoteBtn.classList.remove(\"tvw-message-action-active\");\n }\n currentVote = \"upvote\";\n upvoteButton.classList.add(\"tvw-message-action-active\");\n \n // Trigger feedback\n const feedback: AgentWidgetMessageFeedback = {\n type: \"upvote\",\n messageId: message.id,\n message\n };\n if (callbacks?.onFeedback) {\n callbacks.onFeedback(feedback);\n }\n if (actionsConfig.onFeedback) {\n actionsConfig.onFeedback(feedback);\n }\n }\n }, \"upvote\");\n container.appendChild(upvoteButton);\n }\n\n // Downvote button\n if (showDownvote) {\n const downvoteButton = createActionButton(\"thumbs-down\", \"Downvote\", () => {\n const wasActive = currentVote === \"downvote\";\n \n // Toggle state\n if (wasActive) {\n currentVote = null;\n downvoteButton.classList.remove(\"tvw-message-action-active\");\n } else {\n // Remove upvote if active\n const upvoteBtn = container.querySelector('[data-action=\"upvote\"]');\n if (upvoteBtn) {\n upvoteBtn.classList.remove(\"tvw-message-action-active\");\n }\n currentVote = \"downvote\";\n downvoteButton.classList.add(\"tvw-message-action-active\");\n \n // Trigger feedback\n const feedback: AgentWidgetMessageFeedback = {\n type: \"downvote\",\n messageId: message.id,\n message\n };\n if (callbacks?.onFeedback) {\n callbacks.onFeedback(feedback);\n }\n if (actionsConfig.onFeedback) {\n actionsConfig.onFeedback(feedback);\n }\n }\n }, \"downvote\");\n container.appendChild(downvoteButton);\n }\n\n return container;\n};\n\n/**\n * Create standard message bubble\n * Supports layout configuration for avatars, timestamps, and visual presets\n */\nexport const createStandardBubble = (\n message: AgentWidgetMessage,\n transform: MessageTransform,\n layoutConfig?: AgentWidgetMessageLayoutConfig,\n actionsConfig?: AgentWidgetMessageActionsConfig,\n actionCallbacks?: MessageActionCallbacks\n): HTMLElement => {\n const config = layoutConfig ?? {};\n const layout = config.layout ?? \"bubble\";\n const avatarConfig = config.avatar;\n const timestampConfig = config.timestamp;\n const showAvatar = avatarConfig?.show ?? false;\n const showTimestamp = timestampConfig?.show ?? false;\n const avatarPosition = avatarConfig?.position ?? \"left\";\n const timestampPosition = timestampConfig?.position ?? \"below\";\n\n // Create the bubble element\n const classes = getBubbleClasses(message.role, layout);\n const bubble = createElement(\"div\", classes.join(\" \"));\n\n // Add message content\n const contentDiv = document.createElement(\"div\");\n contentDiv.innerHTML = transform({\n text: message.content,\n message,\n streaming: Boolean(message.streaming),\n raw: message.rawContent\n });\n\n // Add inline timestamp if configured\n if (showTimestamp && timestampPosition === \"inline\" && message.createdAt) {\n const timestamp = createTimestamp(message, timestampConfig!);\n timestamp.classList.add(\"tvw-ml-2\", \"tvw-inline\");\n contentDiv.appendChild(timestamp);\n }\n\n bubble.appendChild(contentDiv);\n\n // Add timestamp below if configured\n if (showTimestamp && timestampPosition === \"below\" && message.createdAt) {\n const timestamp = createTimestamp(message, timestampConfig!);\n timestamp.classList.add(\"tvw-mt-1\");\n bubble.appendChild(timestamp);\n }\n\n // Add typing indicator if this is a streaming assistant message\n if (message.streaming && message.role === \"assistant\") {\n if (!message.content || !message.content.trim()) {\n const typingIndicator = createTypingIndicator();\n bubble.appendChild(typingIndicator);\n }\n }\n\n // Add message actions for assistant messages (only when not streaming and has content)\n const shouldShowActions = \n message.role === \"assistant\" && \n !message.streaming && \n message.content && \n message.content.trim() &&\n actionsConfig?.enabled !== false;\n\n if (shouldShowActions && actionsConfig) {\n const actions = createMessageActions(message, actionsConfig, actionCallbacks);\n bubble.appendChild(actions);\n }\n\n // If no avatar needed, return bubble directly\n if (!showAvatar || message.role === \"system\") {\n return bubble;\n }\n\n // Create wrapper with avatar\n const wrapper = createElement(\n \"div\",\n `tvw-flex tvw-gap-2 ${message.role === \"user\" ? \"tvw-flex-row-reverse\" : \"\"}`\n );\n\n const avatar = createAvatar(avatarConfig!, message.role);\n\n if (avatarPosition === \"right\" || (avatarPosition === \"left\" && message.role === \"user\")) {\n wrapper.append(bubble, avatar);\n } else {\n wrapper.append(avatar, bubble);\n }\n\n // Adjust bubble max-width when avatar is present\n bubble.classList.remove(\"tvw-max-w-[85%]\");\n bubble.classList.add(\"tvw-max-w-[calc(85%-2.5rem)]\");\n\n return wrapper;\n};\n\n/**\n * Create bubble with custom renderer support\n * Uses custom renderer if provided in layout config, otherwise falls back to standard bubble\n */\nexport const createBubbleWithLayout = (\n message: AgentWidgetMessage,\n transform: MessageTransform,\n layoutConfig?: AgentWidgetMessageLayoutConfig,\n actionsConfig?: AgentWidgetMessageActionsConfig,\n actionCallbacks?: MessageActionCallbacks\n): HTMLElement => {\n const config = layoutConfig ?? {};\n\n // Check for custom renderers\n if (message.role === \"user\" && config.renderUserMessage) {\n return config.renderUserMessage({\n message,\n config: {} as any, // Will be populated by caller\n streaming: Boolean(message.streaming)\n });\n }\n\n if (message.role === \"assistant\" && config.renderAssistantMessage) {\n return config.renderAssistantMessage({\n message,\n config: {} as any, // Will be populated by caller\n streaming: Boolean(message.streaming)\n });\n }\n\n // Fall back to standard bubble\n return createStandardBubble(message, transform, layoutConfig, actionsConfig, actionCallbacks);\n};\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage } from \"../types\";\nimport { describeReasonStatus } from \"../utils/formatting\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\n// Expansion state per widget instance\nconst reasoningExpansionState = new Set<string>();\n\nexport const createReasoningBubble = (message: AgentWidgetMessage): HTMLElement => {\n const reasoning = message.reasoning;\n const bubble = createElement(\n \"div\",\n [\n \"vanilla-message-bubble\",\n \"vanilla-reasoning-bubble\",\n \"tvw-w-full\",\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-shadow-sm\",\n \"tvw-overflow-hidden\",\n \"tvw-px-0\",\n \"tvw-py-0\"\n ].join(\" \")\n );\n\n if (!reasoning) {\n return bubble;\n }\n\n let expanded = reasoningExpansionState.has(message.id);\n const header = createElement(\n \"button\",\n \"tvw-flex tvw-w-full tvw-items-center tvw-justify-between tvw-gap-3 tvw-bg-transparent tvw-px-4 tvw-py-3 tvw-text-left tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n header.type = \"button\";\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n\n const headerContent = createElement(\"div\", \"tvw-flex tvw-flex-col tvw-text-left\");\n const title = createElement(\"span\", \"tvw-text-xs tvw-text-cw-primary\");\n title.textContent = \"Thinking...\";\n headerContent.appendChild(title);\n\n const status = createElement(\"span\", \"tvw-text-xs tvw-text-cw-primary\");\n status.textContent = describeReasonStatus(reasoning);\n headerContent.appendChild(status);\n\n if (reasoning.status === \"complete\") {\n title.style.display = \"none\";\n } else {\n title.style.display = \"\";\n }\n\n const toggleIcon = createElement(\"div\", \"tvw-flex tvw-items-center\");\n const iconColor = \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n\n const headerMeta = createElement(\"div\", \"tvw-flex tvw-items-center tvw-ml-auto\");\n headerMeta.append(toggleIcon);\n\n header.append(headerContent, headerMeta);\n\n const content = createElement(\n \"div\",\n \"tvw-border-t tvw-border-gray-200 tvw-bg-gray-50 tvw-px-4 tvw-py-3\"\n );\n content.style.display = expanded ? \"\" : \"none\";\n\n const text = reasoning.chunks.join(\"\");\n const body = createElement(\n \"div\",\n \"tvw-whitespace-pre-wrap tvw-text-xs tvw-leading-snug tvw-text-cw-muted\"\n );\n body.textContent =\n text ||\n (reasoning.status === \"complete\"\n ? \"No additional context was shared.\"\n : \"Waiting for details…\");\n content.appendChild(body);\n\n const applyExpansionState = () => {\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n // Update chevron icon\n toggleIcon.innerHTML = \"\";\n const iconColor = \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n content.style.display = expanded ? \"\" : \"none\";\n };\n\n const toggleExpansion = () => {\n expanded = !expanded;\n if (expanded) {\n reasoningExpansionState.add(message.id);\n } else {\n reasoningExpansionState.delete(message.id);\n }\n applyExpansionState();\n };\n\n header.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n toggleExpansion();\n });\n\n header.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n toggleExpansion();\n }\n });\n\n applyExpansionState();\n\n bubble.append(header, content);\n return bubble;\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage, AgentWidgetConfig } from \"../types\";\nimport { formatUnknownValue, describeToolTitle } from \"../utils/formatting\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\n// Expansion state per widget instance\nconst toolExpansionState = new Set<string>();\n\nexport const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidgetConfig): HTMLElement => {\n const tool = message.toolCall;\n const toolCallConfig = config?.toolCall ?? {};\n \n const bubble = createElement(\n \"div\",\n [\n \"vanilla-message-bubble\",\n \"vanilla-tool-bubble\",\n \"tvw-w-full\",\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-shadow-sm\",\n \"tvw-overflow-hidden\",\n \"tvw-px-0\",\n \"tvw-py-0\"\n ].join(\" \")\n );\n\n // Apply bubble-level styles\n if (toolCallConfig.backgroundColor) {\n bubble.style.backgroundColor = toolCallConfig.backgroundColor;\n }\n if (toolCallConfig.borderColor) {\n bubble.style.borderColor = toolCallConfig.borderColor;\n }\n if (toolCallConfig.borderWidth) {\n bubble.style.borderWidth = toolCallConfig.borderWidth;\n }\n if (toolCallConfig.borderRadius) {\n bubble.style.borderRadius = toolCallConfig.borderRadius;\n }\n\n if (!tool) {\n return bubble;\n }\n\n let expanded = toolExpansionState.has(message.id);\n const header = createElement(\n \"button\",\n \"tvw-flex tvw-w-full tvw-items-center tvw-justify-between tvw-gap-3 tvw-bg-transparent tvw-px-4 tvw-py-3 tvw-text-left tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n header.type = \"button\";\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n\n // Apply header styles\n if (toolCallConfig.headerBackgroundColor) {\n header.style.backgroundColor = toolCallConfig.headerBackgroundColor;\n }\n if (toolCallConfig.headerPaddingX) {\n header.style.paddingLeft = toolCallConfig.headerPaddingX;\n header.style.paddingRight = toolCallConfig.headerPaddingX;\n }\n if (toolCallConfig.headerPaddingY) {\n header.style.paddingTop = toolCallConfig.headerPaddingY;\n header.style.paddingBottom = toolCallConfig.headerPaddingY;\n }\n\n const headerContent = createElement(\"div\", \"tvw-flex tvw-flex-col tvw-text-left\");\n const title = createElement(\"span\", \"tvw-text-xs tvw-text-cw-primary\");\n if (toolCallConfig.headerTextColor) {\n title.style.color = toolCallConfig.headerTextColor;\n }\n title.textContent = describeToolTitle(tool);\n headerContent.appendChild(title);\n\n const toggleIcon = createElement(\"div\", \"tvw-flex tvw-items-center\");\n const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n\n const headerMeta = createElement(\"div\", \"tvw-flex tvw-items-center tvw-gap-2 tvw-ml-auto\");\n headerMeta.append(toggleIcon);\n\n header.append(headerContent, headerMeta);\n\n const content = createElement(\n \"div\",\n \"tvw-border-t tvw-border-gray-200 tvw-bg-gray-50 tvw-space-y-3 tvw-px-4 tvw-py-3\"\n );\n content.style.display = expanded ? \"\" : \"none\";\n\n // Apply content styles\n if (toolCallConfig.contentBackgroundColor) {\n content.style.backgroundColor = toolCallConfig.contentBackgroundColor;\n }\n if (toolCallConfig.contentTextColor) {\n content.style.color = toolCallConfig.contentTextColor;\n }\n if (toolCallConfig.contentPaddingX) {\n content.style.paddingLeft = toolCallConfig.contentPaddingX;\n content.style.paddingRight = toolCallConfig.contentPaddingX;\n }\n if (toolCallConfig.contentPaddingY) {\n content.style.paddingTop = toolCallConfig.contentPaddingY;\n content.style.paddingBottom = toolCallConfig.contentPaddingY;\n }\n\n // Add tool name at the top of content\n if (tool.name) {\n const toolName = createElement(\"div\", \"tvw-text-xs tvw-text-cw-muted tvw-italic\");\n if (toolCallConfig.contentTextColor) {\n toolName.style.color = toolCallConfig.contentTextColor;\n } else if (toolCallConfig.headerTextColor) {\n toolName.style.color = toolCallConfig.headerTextColor;\n }\n toolName.textContent = tool.name;\n content.appendChild(toolName);\n }\n\n if (tool.args !== undefined) {\n const argsBlock = createElement(\"div\", \"tvw-space-y-1\");\n const argsLabel = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.labelTextColor) {\n argsLabel.style.color = toolCallConfig.labelTextColor;\n }\n argsLabel.textContent = \"Arguments\";\n const argsPre = createElement(\n \"pre\",\n \"tvw-max-h-48 tvw-overflow-auto tvw-whitespace-pre-wrap tvw-rounded-lg tvw-border tvw-border-gray-100 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-xs tvw-text-cw-primary\"\n );\n // Ensure font size matches header text (0.75rem / 12px)\n argsPre.style.fontSize = \"0.75rem\";\n argsPre.style.lineHeight = \"1rem\";\n if (toolCallConfig.codeBlockBackgroundColor) {\n argsPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;\n }\n if (toolCallConfig.codeBlockBorderColor) {\n argsPre.style.borderColor = toolCallConfig.codeBlockBorderColor;\n }\n if (toolCallConfig.codeBlockTextColor) {\n argsPre.style.color = toolCallConfig.codeBlockTextColor;\n }\n argsPre.textContent = formatUnknownValue(tool.args);\n argsBlock.append(argsLabel, argsPre);\n content.appendChild(argsBlock);\n }\n\n if (tool.chunks && tool.chunks.length) {\n const logsBlock = createElement(\"div\", \"tvw-space-y-1\");\n const logsLabel = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.labelTextColor) {\n logsLabel.style.color = toolCallConfig.labelTextColor;\n }\n logsLabel.textContent = \"Activity\";\n const logsPre = createElement(\n \"pre\",\n \"tvw-max-h-48 tvw-overflow-auto tvw-whitespace-pre-wrap tvw-rounded-lg tvw-border tvw-border-gray-100 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-xs tvw-text-cw-primary\"\n );\n // Ensure font size matches header text (0.75rem / 12px)\n logsPre.style.fontSize = \"0.75rem\";\n logsPre.style.lineHeight = \"1rem\";\n if (toolCallConfig.codeBlockBackgroundColor) {\n logsPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;\n }\n if (toolCallConfig.codeBlockBorderColor) {\n logsPre.style.borderColor = toolCallConfig.codeBlockBorderColor;\n }\n if (toolCallConfig.codeBlockTextColor) {\n logsPre.style.color = toolCallConfig.codeBlockTextColor;\n }\n logsPre.textContent = tool.chunks.join(\"\\n\");\n logsBlock.append(logsLabel, logsPre);\n content.appendChild(logsBlock);\n }\n\n if (tool.status === \"complete\" && tool.result !== undefined) {\n const resultBlock = createElement(\"div\", \"tvw-space-y-1\");\n const resultLabel = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.labelTextColor) {\n resultLabel.style.color = toolCallConfig.labelTextColor;\n }\n resultLabel.textContent = \"Result\";\n const resultPre = createElement(\n \"pre\",\n \"tvw-max-h-48 tvw-overflow-auto tvw-whitespace-pre-wrap tvw-rounded-lg tvw-border tvw-border-gray-100 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-xs tvw-text-cw-primary\"\n );\n // Ensure font size matches header text (0.75rem / 12px)\n resultPre.style.fontSize = \"0.75rem\";\n resultPre.style.lineHeight = \"1rem\";\n if (toolCallConfig.codeBlockBackgroundColor) {\n resultPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;\n }\n if (toolCallConfig.codeBlockBorderColor) {\n resultPre.style.borderColor = toolCallConfig.codeBlockBorderColor;\n }\n if (toolCallConfig.codeBlockTextColor) {\n resultPre.style.color = toolCallConfig.codeBlockTextColor;\n }\n resultPre.textContent = formatUnknownValue(tool.result);\n resultBlock.append(resultLabel, resultPre);\n content.appendChild(resultBlock);\n }\n\n if (tool.status === \"complete\" && typeof tool.duration === \"number\") {\n const duration = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.contentTextColor) {\n duration.style.color = toolCallConfig.contentTextColor;\n }\n duration.textContent = `Duration: ${tool.duration}ms`;\n content.appendChild(duration);\n }\n\n const applyToolExpansion = () => {\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n // Update chevron icon\n toggleIcon.innerHTML = \"\";\n const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n content.style.display = expanded ? \"\" : \"none\";\n };\n\n const toggleToolExpansion = () => {\n expanded = !expanded;\n if (expanded) {\n toolExpansionState.add(message.id);\n } else {\n toolExpansionState.delete(message.id);\n }\n applyToolExpansion();\n };\n\n header.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n toggleToolExpansion();\n });\n\n header.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n toggleToolExpansion();\n }\n });\n\n applyToolExpansion();\n\n bubble.append(header, content);\n return bubble;\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetSession } from \"../session\";\nimport { AgentWidgetMessage, AgentWidgetSuggestionChipsConfig } from \"../types\";\n\nexport interface SuggestionButtons {\n buttons: HTMLButtonElement[];\n render: (\n chips: string[] | undefined,\n session: AgentWidgetSession,\n textarea: HTMLTextAreaElement,\n messages?: AgentWidgetMessage[],\n config?: AgentWidgetSuggestionChipsConfig\n ) => void;\n}\n\nexport const createSuggestions = (container: HTMLElement): SuggestionButtons => {\n const suggestionButtons: HTMLButtonElement[] = [];\n\n const render = (\n chips: string[] | undefined,\n session: AgentWidgetSession,\n textarea: HTMLTextAreaElement,\n messages?: AgentWidgetMessage[],\n chipsConfig?: AgentWidgetSuggestionChipsConfig\n ) => {\n container.innerHTML = \"\";\n suggestionButtons.length = 0;\n if (!chips || !chips.length) return;\n\n // Hide suggestions after the first user message is sent\n // Use provided messages or get from session\n const messagesToCheck = messages ?? (session ? session.getMessages() : []);\n const hasUserMessage = messagesToCheck.some((msg) => msg.role === \"user\");\n if (hasUserMessage) return;\n\n const fragment = document.createDocumentFragment();\n const streaming = session ? session.isStreaming() : false;\n\n // Get font family mapping function\n const getFontFamilyValue = (family: \"sans-serif\" | \"serif\" | \"mono\"): string => {\n switch (family) {\n case \"serif\":\n return 'Georgia, \"Times New Roman\", Times, serif';\n case \"mono\":\n return '\"Courier New\", Courier, \"Lucida Console\", Monaco, monospace';\n case \"sans-serif\":\n default:\n return '-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif';\n }\n };\n\n chips.forEach((chip) => {\n const btn = createElement(\n \"button\",\n \"tvw-rounded-button tvw-bg-cw-surface tvw-px-3 tvw-py-1.5 tvw-text-xs tvw-font-medium tvw-text-cw-muted hover:tvw-opacity-90 tvw-cursor-pointer tvw-border tvw-border-gray-200\"\n ) as HTMLButtonElement;\n btn.type = \"button\";\n btn.textContent = chip;\n btn.disabled = streaming;\n\n // Apply typography settings\n if (chipsConfig?.fontFamily) {\n btn.style.fontFamily = getFontFamilyValue(chipsConfig.fontFamily);\n }\n if (chipsConfig?.fontWeight) {\n btn.style.fontWeight = chipsConfig.fontWeight;\n }\n\n // Apply padding settings\n if (chipsConfig?.paddingX) {\n btn.style.paddingLeft = chipsConfig.paddingX;\n btn.style.paddingRight = chipsConfig.paddingX;\n }\n if (chipsConfig?.paddingY) {\n btn.style.paddingTop = chipsConfig.paddingY;\n btn.style.paddingBottom = chipsConfig.paddingY;\n }\n\n btn.addEventListener(\"click\", () => {\n if (!session || session.isStreaming()) return;\n textarea.value = \"\";\n session.sendMessage(chip);\n });\n fragment.appendChild(btn);\n suggestionButtons.push(btn);\n });\n container.appendChild(fragment);\n };\n\n return {\n buttons: suggestionButtons,\n render\n };\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage, AgentWidgetConfig } from \"../types\";\nimport { AgentWidgetSession } from \"../session\";\n\nexport const formDefinitions: Record<\n string,\n {\n title: string;\n description?: string;\n fields: Array<{\n name: string;\n label: string;\n placeholder?: string;\n type?: \"text\" | \"email\" | \"textarea\";\n required?: boolean;\n }>;\n submitLabel?: string;\n }\n> = {\n init: {\n title: \"Schedule a Demo\",\n description: \"Share the basics and we'll follow up with a confirmation.\",\n fields: [\n { name: \"name\", label: \"Full name\", placeholder: \"Jane Doe\", required: true },\n { name: \"email\", label: \"Work email\", placeholder: \"jane@example.com\", type: \"email\", required: true },\n { name: \"notes\", label: \"What would you like to cover?\", type: \"textarea\" }\n ],\n submitLabel: \"Submit details\"\n },\n followup: {\n title: \"Additional Information\",\n description: \"Provide any extra details to tailor the next steps.\",\n fields: [\n { name: \"company\", label: \"Company\", placeholder: \"Acme Inc.\" },\n { name: \"context\", label: \"Context\", type: \"textarea\", placeholder: \"Share more about your use case\" }\n ],\n submitLabel: \"Send\"\n }\n};\n\nexport const enhanceWithForms = (\n bubble: HTMLElement,\n message: AgentWidgetMessage,\n config: AgentWidgetConfig,\n session: AgentWidgetSession\n) => {\n const placeholders = bubble.querySelectorAll<HTMLElement>(\"[data-tv-form]\");\n if (placeholders.length) {\n placeholders.forEach((placeholder) => {\n if (placeholder.dataset.enhanced === \"true\") return;\n const type = placeholder.dataset.tvForm ?? \"init\";\n placeholder.dataset.enhanced = \"true\";\n\n const definition = formDefinitions[type] ?? formDefinitions.init;\n placeholder.classList.add(\"tvw-form-card\", \"tvw-space-y-4\");\n\n const heading = createElement(\"div\", \"tvw-space-y-1\");\n const title = createElement(\n \"h3\",\n \"tvw-text-base tvw-font-semibold tvw-text-cw-primary\"\n );\n title.textContent = definition.title;\n heading.appendChild(title);\n if (definition.description) {\n const desc = createElement(\n \"p\",\n \"tvw-text-sm tvw-text-cw-muted\"\n );\n desc.textContent = definition.description;\n heading.appendChild(desc);\n }\n\n const form = document.createElement(\"form\");\n form.className = \"tvw-form-grid tvw-space-y-3\";\n\n definition.fields.forEach((field) => {\n const group = createElement(\"label\", \"tvw-form-field tvw-flex tvw-flex-col tvw-gap-1\");\n group.htmlFor = `${message.id}-${type}-${field.name}`;\n const label = createElement(\"span\", \"tvw-text-xs tvw-font-medium tvw-text-cw-muted\");\n label.textContent = field.label;\n group.appendChild(label);\n\n const inputType = field.type ?? \"text\";\n let control: HTMLInputElement | HTMLTextAreaElement;\n if (inputType === \"textarea\") {\n control = document.createElement(\"textarea\");\n control.rows = 3;\n } else {\n control = document.createElement(\"input\");\n control.type = inputType;\n }\n control.className =\n \"tvw-rounded-xl tvw-border tvw-border-gray-200 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-sm tvw-text-cw-primary focus:tvw-outline-none focus:tvw-border-cw-primary\";\n control.id = `${message.id}-${type}-${field.name}`;\n control.name = field.name;\n control.placeholder = field.placeholder ?? \"\";\n if (field.required) {\n control.required = true;\n }\n group.appendChild(control);\n form.appendChild(group);\n });\n\n const actions = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-between tvw-gap-2\"\n );\n const status = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted tvw-min-h-[1.5rem]\"\n );\n const submit = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-rounded-full tvw-bg-cw-primary tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold tvw-text-white disabled:tvw-opacity-60 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n submit.type = \"submit\";\n submit.textContent = definition.submitLabel ?? \"Submit\";\n actions.appendChild(status);\n actions.appendChild(submit);\n form.appendChild(actions);\n\n placeholder.replaceChildren(heading, form);\n\n form.addEventListener(\"submit\", async (event) => {\n event.preventDefault();\n const formEndpoint = config.formEndpoint ?? \"/form\";\n const formData = new FormData(form as HTMLFormElement);\n const payload: Record<string, unknown> = {};\n formData.forEach((value, key) => {\n payload[key] = value;\n });\n payload[\"type\"] = type;\n\n submit.disabled = true;\n status.textContent = \"Submitting…\";\n\n try {\n const response = await fetch(formEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(payload)\n });\n if (!response.ok) {\n throw new Error(`Form submission failed (${response.status})`);\n }\n const data = await response.json();\n status.textContent = data.message ?? \"Thanks! We'll be in touch soon.\";\n if (data.success && data.nextPrompt) {\n await session.sendMessage(String(data.nextPrompt));\n }\n } catch (error) {\n status.textContent =\n error instanceof Error ? error.message : \"Something went wrong. Please try again.\";\n } finally {\n submit.disabled = false;\n }\n });\n });\n }\n};\n\n\n\n\n\n\n\n\n","import { AgentWidgetPlugin } from \"./types\";\n\nclass PluginRegistry {\n private plugins: Map<string, AgentWidgetPlugin> = new Map();\n\n /**\n * Register a plugin\n */\n register(plugin: AgentWidgetPlugin): void {\n if (this.plugins.has(plugin.id)) {\n console.warn(`Plugin \"${plugin.id}\" is already registered. Overwriting.`);\n }\n\n this.plugins.set(plugin.id, plugin);\n plugin.onRegister?.();\n }\n\n /**\n * Unregister a plugin\n */\n unregister(pluginId: string): void {\n const plugin = this.plugins.get(pluginId);\n if (plugin) {\n plugin.onUnregister?.();\n this.plugins.delete(pluginId);\n }\n }\n\n /**\n * Get all plugins sorted by priority\n */\n getAll(): AgentWidgetPlugin[] {\n return Array.from(this.plugins.values()).sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n );\n }\n\n /**\n * Get plugins for a specific instance (from config)\n * Merges instance plugins with globally registered plugins\n */\n getForInstance(instancePlugins?: AgentWidgetPlugin[]): AgentWidgetPlugin[] {\n const allPlugins = this.getAll();\n\n if (!instancePlugins || instancePlugins.length === 0) {\n return allPlugins;\n }\n\n // Merge instance plugins with global plugins\n // Instance plugins override global plugins with the same ID\n const instanceIds = new Set(instancePlugins.map(p => p.id));\n const merged = [\n ...allPlugins.filter(p => !instanceIds.has(p.id)),\n ...instancePlugins\n ];\n\n return merged.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }\n\n /**\n * Clear all plugins\n */\n clear(): void {\n this.plugins.forEach(plugin => plugin.onUnregister?.());\n this.plugins.clear();\n }\n}\n\nexport const pluginRegistry = new PluginRegistry();\n\n\n\n\n\n\n\n\n","import type { AgentWidgetConfig, AgentWidgetTheme } from \"./types\";\n\n/**\n * Default light theme colors\n */\nexport const DEFAULT_LIGHT_THEME: AgentWidgetTheme = {\n primary: \"#111827\",\n accent: \"#1d4ed8\",\n surface: \"#ffffff\",\n muted: \"#6b7280\",\n container: \"#f8fafc\",\n border: \"#f1f5f9\",\n divider: \"#f1f5f9\",\n messageBorder: \"#f1f5f9\",\n inputBackground: \"#ffffff\",\n callToAction: \"#000000\",\n callToActionBackground: \"#ffffff\",\n sendButtonBackgroundColor: \"#111827\",\n sendButtonTextColor: \"#ffffff\",\n sendButtonBorderColor: \"#60a5fa\",\n closeButtonColor: \"#6b7280\",\n closeButtonBackgroundColor: \"transparent\",\n closeButtonBorderColor: \"\",\n clearChatIconColor: \"#6b7280\",\n clearChatBackgroundColor: \"transparent\",\n clearChatBorderColor: \"transparent\",\n micIconColor: \"#111827\",\n micBackgroundColor: \"transparent\",\n micBorderColor: \"transparent\",\n recordingIconColor: \"#ffffff\",\n recordingBackgroundColor: \"#ef4444\",\n recordingBorderColor: \"transparent\",\n inputFontFamily: \"sans-serif\",\n inputFontWeight: \"400\",\n radiusSm: \"0.75rem\",\n radiusMd: \"1rem\",\n radiusLg: \"1.5rem\",\n launcherRadius: \"9999px\",\n buttonRadius: \"9999px\",\n};\n\n/**\n * Default dark theme colors\n */\nexport const DEFAULT_DARK_THEME: AgentWidgetTheme = {\n primary: \"#f9fafb\",\n accent: \"#3b82f6\",\n surface: \"#1f2937\",\n muted: \"#9ca3af\",\n container: \"#111827\",\n border: \"#374151\",\n divider: \"#374151\",\n messageBorder: \"#374151\",\n inputBackground: \"#111827\",\n callToAction: \"#ffffff\",\n callToActionBackground: \"#374151\",\n sendButtonBackgroundColor: \"#3b82f6\",\n sendButtonTextColor: \"#ffffff\",\n sendButtonBorderColor: \"#60a5fa\",\n closeButtonColor: \"#9ca3af\",\n closeButtonBackgroundColor: \"transparent\",\n closeButtonBorderColor: \"\",\n clearChatIconColor: \"#9ca3af\",\n clearChatBackgroundColor: \"transparent\",\n clearChatBorderColor: \"transparent\",\n micIconColor: \"#f9fafb\",\n micBackgroundColor: \"transparent\",\n micBorderColor: \"transparent\",\n recordingIconColor: \"#ffffff\",\n recordingBackgroundColor: \"#ef4444\",\n recordingBorderColor: \"transparent\",\n inputFontFamily: \"sans-serif\",\n inputFontWeight: \"400\",\n radiusSm: \"0.75rem\",\n radiusMd: \"1rem\",\n radiusLg: \"1.5rem\",\n launcherRadius: \"9999px\",\n buttonRadius: \"9999px\",\n};\n\n/**\n * Default widget configuration\n * Single source of truth for all default values\n */\nexport const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {\n apiUrl: \"http://localhost:43111/api/chat/dispatch\",\n // Client token mode defaults (optional, only used when clientToken is set)\n clientToken: undefined,\n theme: DEFAULT_LIGHT_THEME,\n darkTheme: DEFAULT_DARK_THEME,\n colorScheme: \"light\",\n launcher: {\n enabled: true,\n title: \"Chat Assistant\",\n subtitle: \"Here to help you get answers fast\",\n agentIconText: \"💬\",\n position: \"bottom-right\",\n width: \"min(400px, calc(100vw - 24px))\",\n heightOffset: 0,\n autoExpand: false,\n callToActionIconHidden: false,\n agentIconSize: \"40px\",\n headerIconSize: \"40px\",\n closeButtonSize: \"32px\",\n callToActionIconName: \"arrow-up-right\",\n callToActionIconText: \"\",\n callToActionIconSize: \"32px\",\n callToActionIconPadding: \"5px\",\n callToActionIconColor: \"#000000\",\n callToActionIconBackgroundColor: \"#ffffff\",\n closeButtonColor: \"#6b7280\",\n closeButtonBackgroundColor: \"transparent\",\n clearChat: {\n iconColor: \"#6b7280\",\n backgroundColor: \"transparent\",\n borderColor: \"transparent\",\n enabled: true,\n placement: \"inline\",\n iconName: \"refresh-cw\",\n size: \"32px\",\n showTooltip: true,\n tooltipText: \"Clear chat\",\n paddingX: \"0px\",\n paddingY: \"0px\",\n },\n headerIconHidden: false,\n border: \"1px solid #e5e7eb\",\n shadow: \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)\",\n },\n copy: {\n welcomeTitle: \"Hello 👋\",\n welcomeSubtitle: \"Ask anything about your account or products.\",\n inputPlaceholder: \"How can I help...\",\n sendButtonLabel: \"Send\",\n },\n sendButton: {\n borderWidth: \"0px\",\n paddingX: \"12px\",\n paddingY: \"10px\",\n backgroundColor: \"#111827\",\n textColor: \"#ffffff\",\n borderColor: \"#60a5fa\",\n useIcon: true,\n iconText: \"↑\",\n size: \"40px\",\n showTooltip: true,\n tooltipText: \"Send message\",\n iconName: \"send\",\n },\n statusIndicator: {\n visible: true,\n idleText: \"Online\",\n connectingText: \"Connecting…\",\n connectedText: \"Streaming…\",\n errorText: \"Offline\",\n },\n voiceRecognition: {\n enabled: true,\n pauseDuration: 2000,\n iconName: \"mic\",\n iconSize: \"39px\",\n borderWidth: \"0px\",\n paddingX: \"9px\",\n paddingY: \"14px\",\n iconColor: \"#111827\",\n backgroundColor: \"transparent\",\n borderColor: \"transparent\",\n recordingIconColor: \"#ffffff\",\n recordingBackgroundColor: \"#ef4444\",\n recordingBorderColor: \"transparent\",\n showTooltip: true,\n tooltipText: \"Start voice recognition\",\n },\n features: {\n showReasoning: true,\n showToolCalls: true,\n },\n suggestionChips: [\n \"What can you help me with?\",\n \"Tell me about your features\",\n \"How does this work?\",\n ],\n suggestionChipsConfig: {\n fontFamily: \"sans-serif\",\n fontWeight: \"500\",\n paddingX: \"12px\",\n paddingY: \"6px\",\n },\n layout: {\n header: {\n layout: \"default\",\n showIcon: true,\n showTitle: true,\n showSubtitle: true,\n showCloseButton: true,\n showClearChat: true,\n },\n messages: {\n layout: \"bubble\",\n avatar: {\n show: false,\n position: \"left\",\n },\n timestamp: {\n show: false,\n position: \"below\",\n },\n groupConsecutive: false,\n },\n slots: {},\n },\n markdown: {\n options: {\n gfm: true,\n breaks: true,\n },\n disableDefaultStyles: false,\n },\n messageActions: {\n enabled: true,\n showCopy: true,\n showUpvote: false, // Requires backend - disabled by default\n showDownvote: false, // Requires backend - disabled by default\n visibility: \"hover\",\n align: \"right\",\n layout: \"pill-inside\",\n },\n debug: false,\n};\n\n/**\n * Helper to deep merge user config with defaults\n * This ensures all default values are present while allowing selective overrides\n */\nexport function mergeWithDefaults(\n config?: Partial<AgentWidgetConfig>\n): Partial<AgentWidgetConfig> {\n if (!config) return DEFAULT_WIDGET_CONFIG;\n\n return {\n ...DEFAULT_WIDGET_CONFIG,\n ...config,\n theme: {\n ...DEFAULT_WIDGET_CONFIG.theme,\n ...config.theme,\n },\n darkTheme: {\n ...DEFAULT_WIDGET_CONFIG.darkTheme,\n ...config.darkTheme,\n },\n launcher: {\n ...DEFAULT_WIDGET_CONFIG.launcher,\n ...config.launcher,\n clearChat: {\n ...DEFAULT_WIDGET_CONFIG.launcher?.clearChat,\n ...config.launcher?.clearChat,\n },\n },\n copy: {\n ...DEFAULT_WIDGET_CONFIG.copy,\n ...config.copy,\n },\n sendButton: {\n ...DEFAULT_WIDGET_CONFIG.sendButton,\n ...config.sendButton,\n },\n statusIndicator: {\n ...DEFAULT_WIDGET_CONFIG.statusIndicator,\n ...config.statusIndicator,\n },\n voiceRecognition: {\n ...DEFAULT_WIDGET_CONFIG.voiceRecognition,\n ...config.voiceRecognition,\n },\n features: {\n ...DEFAULT_WIDGET_CONFIG.features,\n ...config.features,\n },\n suggestionChips: config.suggestionChips ?? DEFAULT_WIDGET_CONFIG.suggestionChips,\n suggestionChipsConfig: {\n ...DEFAULT_WIDGET_CONFIG.suggestionChipsConfig,\n ...config.suggestionChipsConfig,\n },\n layout: {\n ...DEFAULT_WIDGET_CONFIG.layout,\n ...config.layout,\n header: {\n ...DEFAULT_WIDGET_CONFIG.layout?.header,\n ...config.layout?.header,\n },\n messages: {\n ...DEFAULT_WIDGET_CONFIG.layout?.messages,\n ...config.layout?.messages,\n avatar: {\n ...DEFAULT_WIDGET_CONFIG.layout?.messages?.avatar,\n ...config.layout?.messages?.avatar,\n },\n timestamp: {\n ...DEFAULT_WIDGET_CONFIG.layout?.messages?.timestamp,\n ...config.layout?.messages?.timestamp,\n },\n },\n slots: {\n ...DEFAULT_WIDGET_CONFIG.layout?.slots,\n ...config.layout?.slots,\n },\n },\n markdown: {\n ...DEFAULT_WIDGET_CONFIG.markdown,\n ...config.markdown,\n options: {\n ...DEFAULT_WIDGET_CONFIG.markdown?.options,\n ...config.markdown?.options,\n },\n },\n messageActions: {\n ...DEFAULT_WIDGET_CONFIG.messageActions,\n ...config.messageActions,\n },\n };\n}\n","type Handler<T> = (payload: T) => void;\n\nexport type EventUnsubscribe = () => void;\n\nexport const createEventBus = <EventMap extends Record<string, any>>() => {\n const listeners = new Map<keyof EventMap, Set<Handler<any>>>();\n\n const on = <K extends keyof EventMap>(\n event: K,\n handler: Handler<EventMap[K]>\n ): EventUnsubscribe => {\n if (!listeners.has(event)) {\n listeners.set(event, new Set());\n }\n listeners.get(event)!.add(handler as Handler<any>);\n return () => off(event, handler);\n };\n\n const off = <K extends keyof EventMap>(\n event: K,\n handler: Handler<EventMap[K]>\n ) => {\n listeners.get(event)?.delete(handler as Handler<any>);\n };\n\n const emit = <K extends keyof EventMap>(event: K, payload: EventMap[K]) => {\n listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Event handler error:\", error);\n }\n }\n });\n };\n\n return { on, off, emit };\n};\n\n","import type {\n AgentWidgetActionContext,\n AgentWidgetActionEventPayload,\n AgentWidgetActionHandler,\n AgentWidgetActionHandlerResult,\n AgentWidgetActionParser,\n AgentWidgetParsedAction,\n AgentWidgetControllerEventMap,\n AgentWidgetMessage\n} from \"../types\";\n\ntype ActionManagerProcessContext = {\n text: string;\n message: AgentWidgetMessage;\n streaming: boolean;\n raw?: string;\n};\n\ntype ActionManagerOptions = {\n parsers: AgentWidgetActionParser[];\n handlers: AgentWidgetActionHandler[];\n getMetadata: () => Record<string, unknown>;\n updateMetadata: (\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) => void;\n emit: <K extends keyof AgentWidgetControllerEventMap>(\n event: K,\n payload: AgentWidgetControllerEventMap[K]\n ) => void;\n documentRef: Document | null;\n};\n\nconst stripCodeFence = (value: string) => {\n const match = value.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n return match ? match[1] : value;\n};\n\nconst extractJsonObject = (value: string) => {\n const trimmed = value.trim();\n const start = trimmed.indexOf(\"{\");\n if (start === -1) return null;\n\n let depth = 0;\n for (let i = start; i < trimmed.length; i += 1) {\n const char = trimmed[i];\n if (char === \"{\") depth += 1;\n if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return trimmed.slice(start, i + 1);\n }\n }\n }\n return null;\n};\n\nexport const defaultJsonActionParser: AgentWidgetActionParser = ({ text }) => {\n if (!text) return null;\n if (!text.includes(\"{\")) return null;\n\n try {\n const withoutFence = stripCodeFence(text);\n const jsonBody = extractJsonObject(withoutFence);\n if (!jsonBody) return null;\n const parsed = JSON.parse(jsonBody);\n if (!parsed || typeof parsed !== \"object\" || !parsed.action) {\n return null;\n }\n const { action, ...payload } = parsed;\n return {\n type: String(action),\n payload,\n raw: parsed\n };\n } catch {\n return null;\n }\n};\n\nconst asString = (value: unknown) =>\n typeof value === \"string\" ? value : value == null ? \"\" : String(value);\n\nexport const defaultActionHandlers: Record<\n string,\n AgentWidgetActionHandler\n> = {\n message: (action) => {\n if (action.type !== \"message\") return;\n const text = asString((action.payload as Record<string, unknown>).text);\n return {\n handled: true,\n displayText: text\n };\n },\n messageAndClick: (action, context) => {\n if (action.type !== \"message_and_click\") return;\n const payload = action.payload as Record<string, unknown>;\n const selector = asString(payload.element);\n if (selector && context.document?.querySelector) {\n const element = context.document.querySelector<HTMLElement>(selector);\n if (element) {\n setTimeout(() => {\n element.click();\n }, 400);\n } else if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.warn(\"[AgentWidget] Element not found for selector:\", selector);\n }\n }\n return {\n handled: true,\n displayText: asString(payload.text)\n };\n }\n};\n\nconst ensureArrayOfStrings = (value: unknown): string[] => {\n if (Array.isArray(value)) {\n return value.map((entry) => String(entry));\n }\n return [];\n};\n\nexport const createActionManager = (options: ActionManagerOptions) => {\n let processedIds = new Set(\n ensureArrayOfStrings(options.getMetadata().processedActionMessageIds)\n );\n\n const syncFromMetadata = () => {\n processedIds = new Set(\n ensureArrayOfStrings(options.getMetadata().processedActionMessageIds)\n );\n };\n\n const persistProcessedIds = () => {\n const latestIds = Array.from(processedIds);\n options.updateMetadata((prev) => ({\n ...prev,\n processedActionMessageIds: latestIds\n }));\n };\n\n const process = (context: ActionManagerProcessContext): { text: string; persist: boolean } | null => {\n if (\n context.streaming ||\n context.message.role !== \"assistant\" ||\n !context.text ||\n processedIds.has(context.message.id)\n ) {\n return null;\n }\n\n const parseSource =\n (typeof context.raw === \"string\" && context.raw) ||\n (typeof context.message.rawContent === \"string\" &&\n context.message.rawContent) ||\n (typeof context.text === \"string\" && context.text) ||\n null;\n\n if (\n !parseSource &&\n typeof context.text === \"string\" &&\n context.text.trim().startsWith(\"{\") &&\n typeof console !== \"undefined\"\n ) {\n // eslint-disable-next-line no-console\n console.warn(\n \"[AgentWidget] Structured response detected but no raw payload was provided. Ensure your stream parser returns { text, raw }.\"\n );\n }\n\n const action = parseSource\n ? options.parsers.reduce<AgentWidgetParsedAction | null>(\n (acc, parser) =>\n acc || parser?.({ text: parseSource, message: context.message }) || null,\n null\n )\n : null;\n\n if (!action) {\n return null;\n }\n\n processedIds.add(context.message.id);\n persistProcessedIds();\n\n const eventPayload: AgentWidgetActionEventPayload = {\n action,\n message: context.message\n };\n options.emit(\"action:detected\", eventPayload);\n\n for (const handler of options.handlers) {\n if (!handler) continue;\n try {\n const handlerResult = handler(action, {\n message: context.message,\n metadata: options.getMetadata(),\n updateMetadata: options.updateMetadata,\n document: options.documentRef\n } as AgentWidgetActionContext) as AgentWidgetActionHandlerResult | void;\n\n if (!handlerResult) continue;\n\n if (handlerResult.handled) {\n // persistMessage defaults to true if not specified\n const persist = handlerResult.persistMessage !== false;\n const displayText = handlerResult.displayText !== undefined ? handlerResult.displayText : \"\";\n return { text: displayText, persist };\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Action handler error:\", error);\n }\n }\n }\n\n return { text: \"\", persist: true };\n };\n\n return {\n process,\n syncFromMetadata\n };\n};\n\n","import type {\n AgentWidgetMessage,\n AgentWidgetStorageAdapter,\n AgentWidgetStoredState\n} from \"../types\";\n\nconst safeJsonParse = (value: string | null) => {\n if (!value) return null;\n try {\n return JSON.parse(value);\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to parse stored state:\", error);\n }\n return null;\n }\n};\n\nconst sanitizeMessages = (messages: AgentWidgetMessage[]) =>\n messages.map((message) => ({\n ...message,\n streaming: false\n }));\n\nexport const createLocalStorageAdapter = (\n key = \"vanilla-agent-state\"\n): AgentWidgetStorageAdapter => {\n const getStorage = () => {\n if (typeof window === \"undefined\" || !window.localStorage) {\n return null;\n }\n return window.localStorage;\n };\n\n return {\n load: () => {\n const storage = getStorage();\n if (!storage) return null;\n return safeJsonParse(storage.getItem(key));\n },\n save: (state: AgentWidgetStoredState) => {\n const storage = getStorage();\n if (!storage) return;\n try {\n const payload: AgentWidgetStoredState = {\n ...state,\n messages: state.messages ? sanitizeMessages(state.messages) : undefined\n };\n storage.setItem(key, JSON.stringify(payload));\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to persist state:\", error);\n }\n }\n },\n clear: () => {\n const storage = getStorage();\n if (!storage) return;\n try {\n storage.removeItem(key);\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear stored state:\", error);\n }\n }\n }\n };\n};\n\n","import { AgentWidgetConfig, AgentWidgetMessage } from \"../types\";\n\n/**\n * Context provided to component renderers\n */\nexport interface ComponentContext {\n message: AgentWidgetMessage;\n config: AgentWidgetConfig;\n /**\n * Update component props during streaming\n */\n updateProps: (newProps: Record<string, unknown>) => void;\n}\n\n/**\n * Component renderer function signature\n */\nexport type ComponentRenderer = (\n props: Record<string, unknown>,\n context: ComponentContext\n) => HTMLElement;\n\n/**\n * Component registry for managing custom components\n */\nclass ComponentRegistry {\n private components: Map<string, ComponentRenderer> = new Map();\n\n /**\n * Register a custom component\n */\n register(name: string, renderer: ComponentRenderer): void {\n if (this.components.has(name)) {\n console.warn(`[ComponentRegistry] Component \"${name}\" is already registered. Overwriting.`);\n }\n this.components.set(name, renderer);\n }\n\n /**\n * Unregister a component\n */\n unregister(name: string): void {\n this.components.delete(name);\n }\n\n /**\n * Get a component renderer by name\n */\n get(name: string): ComponentRenderer | undefined {\n return this.components.get(name);\n }\n\n /**\n * Check if a component is registered\n */\n has(name: string): boolean {\n return this.components.has(name);\n }\n\n /**\n * Get all registered component names\n */\n getAllNames(): string[] {\n return Array.from(this.components.keys());\n }\n\n /**\n * Clear all registered components\n */\n clear(): void {\n this.components.clear();\n }\n\n /**\n * Register multiple components at once\n */\n registerAll(components: Record<string, ComponentRenderer>): void {\n Object.entries(components).forEach(([name, renderer]) => {\n this.register(name, renderer);\n });\n }\n}\n\n/**\n * Global component registry instance\n */\nexport const componentRegistry = new ComponentRegistry();\n","import { parse as parsePartialJson, STR, OBJ } from \"partial-json\";\n\n/**\n * Represents a component directive extracted from JSON\n */\nexport interface ComponentDirective {\n component: string;\n props: Record<string, unknown>;\n raw: string;\n}\n\n/**\n * Checks if a parsed object is a component directive\n */\nfunction isComponentDirective(obj: unknown): obj is { component: string; props?: unknown } {\n if (!obj || typeof obj !== \"object\") return false;\n if (!(\"component\" in obj)) return false;\n const component = (obj as { component: unknown }).component;\n return typeof component === \"string\" && component.length > 0;\n}\n\n/**\n * Extracts component directive from parsed JSON object\n */\nfunction extractComponentDirective(\n parsed: unknown,\n rawJson: string\n): ComponentDirective | null {\n if (!isComponentDirective(parsed)) {\n return null;\n }\n\n const props = parsed.props && typeof parsed.props === \"object\" && parsed.props !== null\n ? (parsed.props as Record<string, unknown>)\n : {};\n\n return {\n component: parsed.component,\n props,\n raw: rawJson\n };\n}\n\n/**\n * Creates a parser that extracts component directives from JSON streams\n * This parser looks for objects with a \"component\" field and extracts\n * the component name and props incrementally as they stream in.\n */\nexport function createComponentStreamParser() {\n let extractedDirective: ComponentDirective | null = null;\n let processedLength = 0;\n\n return {\n /**\n * Get the currently extracted component directive\n */\n getExtractedDirective: (): ComponentDirective | null => {\n return extractedDirective;\n },\n\n /**\n * Process a chunk of JSON and extract component directive if present\n */\n processChunk: (accumulatedContent: string): ComponentDirective | null => {\n // Validate that the accumulated content looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return null;\n }\n\n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedDirective;\n }\n\n try {\n // Parse partial JSON - allow partial strings and objects during streaming\n // STR | OBJ allows incomplete strings and objects during streaming\n const parsed = parsePartialJson(accumulatedContent, STR | OBJ);\n\n // Try to extract component directive\n const directive = extractComponentDirective(parsed, accumulatedContent);\n if (directive) {\n extractedDirective = directive;\n }\n } catch (error) {\n // If parsing fails completely, keep the last extracted directive\n // This can happen with very malformed JSON during streaming\n }\n\n // Update processed length\n processedLength = accumulatedContent.length;\n\n return extractedDirective;\n },\n\n /**\n * Reset the parser state\n */\n reset: () => {\n extractedDirective = null;\n processedLength = 0;\n }\n };\n}\n\n/**\n * Type guard to check if an object is a component directive\n */\nexport function isComponentDirectiveType(obj: unknown): obj is ComponentDirective {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"component\" in obj &&\n typeof (obj as { component: unknown }).component === \"string\" &&\n \"props\" in obj &&\n typeof (obj as { props: unknown }).props === \"object\"\n );\n}\n","import { AgentWidgetMessage, AgentWidgetConfig } from \"../types\";\nimport { componentRegistry, ComponentContext } from \"../components/registry\";\nimport { ComponentDirective, createComponentStreamParser } from \"./component-parser\";\nimport { createStandardBubble, MessageTransform } from \"../components/message-bubble\";\n\n/**\n * Options for component middleware\n */\nexport interface ComponentMiddlewareOptions {\n config: AgentWidgetConfig;\n message: AgentWidgetMessage;\n transform: MessageTransform;\n onPropsUpdate?: (props: Record<string, unknown>) => void;\n}\n\n/**\n * Renders a component directive into an HTMLElement\n */\nexport function renderComponentDirective(\n directive: ComponentDirective,\n options: ComponentMiddlewareOptions\n): HTMLElement | null {\n const { config, message, onPropsUpdate } = options;\n\n // Get component renderer from registry\n const renderer = componentRegistry.get(directive.component);\n if (!renderer) {\n // Component not found, fall back to default rendering\n console.warn(\n `[ComponentMiddleware] Component \"${directive.component}\" not found in registry. Falling back to default rendering.`\n );\n return null;\n }\n\n // Create component context\n const context: ComponentContext = {\n message,\n config,\n updateProps: (newProps: Record<string, unknown>) => {\n if (onPropsUpdate) {\n onPropsUpdate(newProps);\n }\n }\n };\n\n try {\n // Render the component\n const element = renderer(directive.props, context);\n return element;\n } catch (error) {\n console.error(\n `[ComponentMiddleware] Error rendering component \"${directive.component}\":`,\n error\n );\n return null;\n }\n}\n\n/**\n * Creates middleware that processes component directives from streamed JSON\n */\nexport function createComponentMiddleware() {\n const parser = createComponentStreamParser();\n\n return {\n /**\n * Process accumulated content and extract component directive\n */\n processChunk: (accumulatedContent: string): ComponentDirective | null => {\n return parser.processChunk(accumulatedContent);\n },\n\n /**\n * Get the currently extracted directive\n */\n getDirective: (): ComponentDirective | null => {\n return parser.getExtractedDirective();\n },\n\n /**\n * Reset the parser state\n */\n reset: () => {\n parser.reset();\n }\n };\n}\n\n/**\n * Checks if a message contains a component directive in its raw content\n */\nexport function hasComponentDirective(message: AgentWidgetMessage): boolean {\n if (!message.rawContent) return false;\n \n try {\n const parsed = JSON.parse(message.rawContent);\n return (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"component\" in parsed &&\n typeof parsed.component === \"string\"\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Extracts component directive from a complete message\n */\nexport function extractComponentDirectiveFromMessage(\n message: AgentWidgetMessage\n): ComponentDirective | null {\n if (!message.rawContent) return null;\n\n try {\n const parsed = JSON.parse(message.rawContent);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"component\" in parsed &&\n typeof parsed.component === \"string\"\n ) {\n return {\n component: parsed.component,\n props: (parsed.props && typeof parsed.props === \"object\" && parsed.props !== null\n ? parsed.props\n : {}) as Record<string, unknown>,\n raw: message.rawContent\n };\n }\n } catch {\n // Not valid JSON or not a component directive\n }\n\n return null;\n}\n","/**\n * Feedback UI components for CSAT and NPS collection\n */\n\nexport type CSATFeedbackOptions = {\n /** Callback when user submits CSAT feedback */\n onSubmit: (rating: number, comment?: string) => void | Promise<void>;\n /** Callback when user dismisses the feedback form */\n onDismiss?: () => void;\n /** Title text */\n title?: string;\n /** Subtitle/question text */\n subtitle?: string;\n /** Placeholder for optional comment field */\n commentPlaceholder?: string;\n /** Submit button text */\n submitText?: string;\n /** Skip button text */\n skipText?: string;\n /** Show comment field */\n showComment?: boolean;\n /** Rating labels (5 items for ratings 1-5) */\n ratingLabels?: [string, string, string, string, string];\n};\n\nexport type NPSFeedbackOptions = {\n /** Callback when user submits NPS feedback */\n onSubmit: (rating: number, comment?: string) => void | Promise<void>;\n /** Callback when user dismisses the feedback form */\n onDismiss?: () => void;\n /** Title text */\n title?: string;\n /** Subtitle/question text */\n subtitle?: string;\n /** Placeholder for optional comment field */\n commentPlaceholder?: string;\n /** Submit button text */\n submitText?: string;\n /** Skip button text */\n skipText?: string;\n /** Show comment field */\n showComment?: boolean;\n /** Low label (left side) */\n lowLabel?: string;\n /** High label (right side) */\n highLabel?: string;\n};\n\nconst defaultCSATLabels: [string, string, string, string, string] = [\n 'Very dissatisfied',\n 'Dissatisfied',\n 'Neutral',\n 'Satisfied',\n 'Very satisfied'\n];\n\n/**\n * Create a CSAT (Customer Satisfaction) feedback form\n * Rating scale: 1-5\n */\nexport function createCSATFeedback(options: CSATFeedbackOptions): HTMLElement {\n const {\n onSubmit,\n onDismiss,\n title = 'How satisfied are you?',\n subtitle = 'Please rate your experience',\n commentPlaceholder = 'Share your thoughts (optional)...',\n submitText = 'Submit',\n skipText = 'Skip',\n showComment = true,\n ratingLabels = defaultCSATLabels,\n } = options;\n\n const container = document.createElement('div');\n container.className = 'tvw-feedback-container tvw-feedback-csat';\n container.setAttribute('role', 'dialog');\n container.setAttribute('aria-label', 'Customer satisfaction feedback');\n\n let selectedRating: number | null = null;\n\n // Create inner content\n const content = document.createElement('div');\n content.className = 'tvw-feedback-content';\n\n // Header\n const header = document.createElement('div');\n header.className = 'tvw-feedback-header';\n \n const titleEl = document.createElement('h3');\n titleEl.className = 'tvw-feedback-title';\n titleEl.textContent = title;\n header.appendChild(titleEl);\n\n const subtitleEl = document.createElement('p');\n subtitleEl.className = 'tvw-feedback-subtitle';\n subtitleEl.textContent = subtitle;\n header.appendChild(subtitleEl);\n\n content.appendChild(header);\n\n // Rating buttons (1-5 stars or numbers)\n const ratingContainer = document.createElement('div');\n ratingContainer.className = 'tvw-feedback-rating tvw-feedback-rating-csat';\n ratingContainer.setAttribute('role', 'radiogroup');\n ratingContainer.setAttribute('aria-label', 'Satisfaction rating from 1 to 5');\n\n const ratingButtons: HTMLButtonElement[] = [];\n\n for (let i = 1; i <= 5; i++) {\n const ratingButton = document.createElement('button');\n ratingButton.type = 'button';\n ratingButton.className = 'tvw-feedback-rating-btn tvw-feedback-star-btn';\n ratingButton.setAttribute('role', 'radio');\n ratingButton.setAttribute('aria-checked', 'false');\n ratingButton.setAttribute('aria-label', `${i} star${i > 1 ? 's' : ''}: ${ratingLabels[i - 1]}`);\n ratingButton.title = ratingLabels[i - 1];\n ratingButton.dataset.rating = String(i);\n\n // Star icon (filled when selected)\n ratingButton.innerHTML = `\n <svg class=\"tvw-feedback-star\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"></polygon>\n </svg>\n `;\n\n ratingButton.addEventListener('click', () => {\n selectedRating = i;\n ratingButtons.forEach((btn, index) => {\n const isSelected = index < i;\n btn.classList.toggle('selected', isSelected);\n btn.setAttribute('aria-checked', index === i - 1 ? 'true' : 'false');\n });\n });\n\n ratingButtons.push(ratingButton);\n ratingContainer.appendChild(ratingButton);\n }\n\n content.appendChild(ratingContainer);\n\n // Comment field\n let commentTextarea: HTMLTextAreaElement | null = null;\n if (showComment) {\n const commentContainer = document.createElement('div');\n commentContainer.className = 'tvw-feedback-comment-container';\n \n commentTextarea = document.createElement('textarea');\n commentTextarea.className = 'tvw-feedback-comment';\n commentTextarea.placeholder = commentPlaceholder;\n commentTextarea.rows = 3;\n commentTextarea.setAttribute('aria-label', 'Additional comments');\n \n commentContainer.appendChild(commentTextarea);\n content.appendChild(commentContainer);\n }\n\n // Action buttons\n const actions = document.createElement('div');\n actions.className = 'tvw-feedback-actions';\n\n const skipButton = document.createElement('button');\n skipButton.type = 'button';\n skipButton.className = 'tvw-feedback-btn tvw-feedback-btn-skip';\n skipButton.textContent = skipText;\n skipButton.addEventListener('click', () => {\n onDismiss?.();\n container.remove();\n });\n\n const submitButton = document.createElement('button');\n submitButton.type = 'button';\n submitButton.className = 'tvw-feedback-btn tvw-feedback-btn-submit';\n submitButton.textContent = submitText;\n submitButton.addEventListener('click', async () => {\n if (selectedRating === null) {\n // Shake the rating container to indicate selection required\n ratingContainer.classList.add('tvw-feedback-shake');\n setTimeout(() => ratingContainer.classList.remove('tvw-feedback-shake'), 500);\n return;\n }\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n const comment = commentTextarea?.value.trim() || undefined;\n await onSubmit(selectedRating, comment);\n container.remove();\n } catch (error) {\n submitButton.disabled = false;\n submitButton.textContent = submitText;\n // eslint-disable-next-line no-console\n console.error('[CSAT Feedback] Failed to submit:', error);\n }\n });\n\n actions.appendChild(skipButton);\n actions.appendChild(submitButton);\n content.appendChild(actions);\n\n container.appendChild(content);\n\n return container;\n}\n\n/**\n * Create an NPS (Net Promoter Score) feedback form\n * Rating scale: 0-10\n */\nexport function createNPSFeedback(options: NPSFeedbackOptions): HTMLElement {\n const {\n onSubmit,\n onDismiss,\n title = 'How likely are you to recommend us?',\n subtitle = 'On a scale of 0 to 10',\n commentPlaceholder = 'What could we do better? (optional)...',\n submitText = 'Submit',\n skipText = 'Skip',\n showComment = true,\n lowLabel = 'Not likely',\n highLabel = 'Very likely',\n } = options;\n\n const container = document.createElement('div');\n container.className = 'tvw-feedback-container tvw-feedback-nps';\n container.setAttribute('role', 'dialog');\n container.setAttribute('aria-label', 'Net Promoter Score feedback');\n\n let selectedRating: number | null = null;\n\n // Create inner content\n const content = document.createElement('div');\n content.className = 'tvw-feedback-content';\n\n // Header\n const header = document.createElement('div');\n header.className = 'tvw-feedback-header';\n \n const titleEl = document.createElement('h3');\n titleEl.className = 'tvw-feedback-title';\n titleEl.textContent = title;\n header.appendChild(titleEl);\n\n const subtitleEl = document.createElement('p');\n subtitleEl.className = 'tvw-feedback-subtitle';\n subtitleEl.textContent = subtitle;\n header.appendChild(subtitleEl);\n\n content.appendChild(header);\n\n // Rating buttons (0-10)\n const ratingContainer = document.createElement('div');\n ratingContainer.className = 'tvw-feedback-rating tvw-feedback-rating-nps';\n ratingContainer.setAttribute('role', 'radiogroup');\n ratingContainer.setAttribute('aria-label', 'Likelihood rating from 0 to 10');\n\n // Labels row\n const labelsRow = document.createElement('div');\n labelsRow.className = 'tvw-feedback-labels';\n \n const lowLabelEl = document.createElement('span');\n lowLabelEl.className = 'tvw-feedback-label-low';\n lowLabelEl.textContent = lowLabel;\n \n const highLabelEl = document.createElement('span');\n highLabelEl.className = 'tvw-feedback-label-high';\n highLabelEl.textContent = highLabel;\n \n labelsRow.appendChild(lowLabelEl);\n labelsRow.appendChild(highLabelEl);\n \n // Numbers row\n const numbersRow = document.createElement('div');\n numbersRow.className = 'tvw-feedback-numbers';\n\n const ratingButtons: HTMLButtonElement[] = [];\n\n for (let i = 0; i <= 10; i++) {\n const ratingButton = document.createElement('button');\n ratingButton.type = 'button';\n ratingButton.className = 'tvw-feedback-rating-btn tvw-feedback-number-btn';\n ratingButton.setAttribute('role', 'radio');\n ratingButton.setAttribute('aria-checked', 'false');\n ratingButton.setAttribute('aria-label', `Rating ${i} out of 10`);\n ratingButton.textContent = String(i);\n ratingButton.dataset.rating = String(i);\n\n // Color coding: detractors (0-6), passives (7-8), promoters (9-10)\n if (i <= 6) {\n ratingButton.classList.add('tvw-feedback-detractor');\n } else if (i <= 8) {\n ratingButton.classList.add('tvw-feedback-passive');\n } else {\n ratingButton.classList.add('tvw-feedback-promoter');\n }\n\n ratingButton.addEventListener('click', () => {\n selectedRating = i;\n ratingButtons.forEach((btn, index) => {\n btn.classList.toggle('selected', index === i);\n btn.setAttribute('aria-checked', index === i ? 'true' : 'false');\n });\n });\n\n ratingButtons.push(ratingButton);\n numbersRow.appendChild(ratingButton);\n }\n\n ratingContainer.appendChild(labelsRow);\n ratingContainer.appendChild(numbersRow);\n content.appendChild(ratingContainer);\n\n // Comment field\n let commentTextarea: HTMLTextAreaElement | null = null;\n if (showComment) {\n const commentContainer = document.createElement('div');\n commentContainer.className = 'tvw-feedback-comment-container';\n \n commentTextarea = document.createElement('textarea');\n commentTextarea.className = 'tvw-feedback-comment';\n commentTextarea.placeholder = commentPlaceholder;\n commentTextarea.rows = 3;\n commentTextarea.setAttribute('aria-label', 'Additional comments');\n \n commentContainer.appendChild(commentTextarea);\n content.appendChild(commentContainer);\n }\n\n // Action buttons\n const actions = document.createElement('div');\n actions.className = 'tvw-feedback-actions';\n\n const skipButton = document.createElement('button');\n skipButton.type = 'button';\n skipButton.className = 'tvw-feedback-btn tvw-feedback-btn-skip';\n skipButton.textContent = skipText;\n skipButton.addEventListener('click', () => {\n onDismiss?.();\n container.remove();\n });\n\n const submitButton = document.createElement('button');\n submitButton.type = 'button';\n submitButton.className = 'tvw-feedback-btn tvw-feedback-btn-submit';\n submitButton.textContent = submitText;\n submitButton.addEventListener('click', async () => {\n if (selectedRating === null) {\n // Shake the rating container to indicate selection required\n numbersRow.classList.add('tvw-feedback-shake');\n setTimeout(() => numbersRow.classList.remove('tvw-feedback-shake'), 500);\n return;\n }\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n const comment = commentTextarea?.value.trim() || undefined;\n await onSubmit(selectedRating, comment);\n container.remove();\n } catch (error) {\n submitButton.disabled = false;\n submitButton.textContent = submitText;\n // eslint-disable-next-line no-console\n console.error('[NPS Feedback] Failed to submit:', error);\n }\n });\n\n actions.appendChild(skipButton);\n actions.appendChild(submitButton);\n content.appendChild(actions);\n\n container.appendChild(content);\n\n return container;\n}\n\n\n\n","import { escapeHtml, createMarkdownProcessorFromConfig } from \"./postprocessors\";\nimport { AgentWidgetSession, AgentWidgetSessionStatus } from \"./session\";\nimport {\n AgentWidgetConfig,\n AgentWidgetMessage,\n AgentWidgetEvent,\n AgentWidgetStorageAdapter,\n AgentWidgetStoredState,\n AgentWidgetControllerEventMap,\n AgentWidgetVoiceStateEvent,\n AgentWidgetStateEvent,\n AgentWidgetStateSnapshot,\n WidgetLayoutSlot,\n SlotRenderer,\n AgentWidgetMessageFeedback\n} from \"./types\";\nimport { applyThemeVariables, createThemeObserver } from \"./utils/theme\";\nimport { renderLucideIcon } from \"./utils/icons\";\nimport { createElement } from \"./utils/dom\";\nimport { statusCopy } from \"./utils/constants\";\nimport { createLauncherButton } from \"./components/launcher\";\nimport { createWrapper, buildPanel, buildHeader, buildComposer, attachHeaderToContainer } from \"./components/panel\";\nimport { positionMap } from \"./utils/positioning\";\nimport type { HeaderElements, ComposerElements } from \"./components/panel\";\nimport { MessageTransform, MessageActionCallbacks } from \"./components/message-bubble\";\nimport { createStandardBubble, createTypingIndicator } from \"./components/message-bubble\";\nimport { createReasoningBubble } from \"./components/reasoning-bubble\";\nimport { createToolBubble } from \"./components/tool-bubble\";\nimport { createSuggestions } from \"./components/suggestions\";\nimport { enhanceWithForms } from \"./components/forms\";\nimport { pluginRegistry } from \"./plugins/registry\";\nimport { mergeWithDefaults } from \"./defaults\";\nimport { createEventBus } from \"./utils/events\";\nimport {\n createActionManager,\n defaultActionHandlers,\n defaultJsonActionParser\n} from \"./utils/actions\";\nimport { createLocalStorageAdapter } from \"./utils/storage\";\nimport { componentRegistry } from \"./components/registry\";\nimport {\n renderComponentDirective,\n extractComponentDirectiveFromMessage,\n hasComponentDirective\n} from \"./utils/component-middleware\";\nimport {\n createCSATFeedback,\n createNPSFeedback,\n type CSATFeedbackOptions,\n type NPSFeedbackOptions\n} from \"./components/feedback\";\n\n// Default localStorage key for chat history (automatically cleared on clear chat)\nconst DEFAULT_CHAT_HISTORY_STORAGE_KEY = \"vanilla-agent-chat-history\";\nconst VOICE_STATE_RESTORE_WINDOW = 30 * 1000;\n\nconst ensureRecord = (value: unknown): Record<string, unknown> => {\n if (!value || typeof value !== \"object\") {\n return {};\n }\n return { ...(value as Record<string, unknown>) };\n};\n\nconst stripStreamingFromMessages = (messages: AgentWidgetMessage[]) =>\n messages.map((message) => ({\n ...message,\n streaming: false\n }));\n\ntype Controller = {\n update: (config: AgentWidgetConfig) => void;\n destroy: () => void;\n open: () => void;\n close: () => void;\n toggle: () => void;\n clearChat: () => void;\n setMessage: (message: string) => boolean;\n submitMessage: (message?: string) => boolean;\n startVoiceRecognition: () => boolean;\n stopVoiceRecognition: () => boolean;\n injectTestMessage: (event: AgentWidgetEvent) => void;\n getMessages: () => AgentWidgetMessage[];\n getStatus: () => AgentWidgetSessionStatus;\n getPersistentMetadata: () => Record<string, unknown>;\n updatePersistentMetadata: (\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) => void;\n on: <K extends keyof AgentWidgetControllerEventMap>(\n event: K,\n handler: (payload: AgentWidgetControllerEventMap[K]) => void\n ) => () => void;\n off: <K extends keyof AgentWidgetControllerEventMap>(\n event: K,\n handler: (payload: AgentWidgetControllerEventMap[K]) => void\n ) => void;\n // State query methods\n isOpen: () => boolean;\n isVoiceActive: () => boolean;\n getState: () => AgentWidgetStateSnapshot;\n // Feedback methods (CSAT/NPS)\n showCSATFeedback: (options?: Partial<CSATFeedbackOptions>) => void;\n showNPSFeedback: (options?: Partial<NPSFeedbackOptions>) => void;\n submitCSATFeedback: (rating: number, comment?: string) => Promise<void>;\n submitNPSFeedback: (rating: number, comment?: string) => Promise<void>;\n};\n\nconst buildPostprocessor = (\n cfg: AgentWidgetConfig | undefined,\n actionManager?: ReturnType<typeof createActionManager>\n): MessageTransform => {\n // Create markdown processor from config if markdown config is provided\n // This allows users to enable markdown rendering via config.markdown\n const markdownProcessor = cfg?.markdown \n ? createMarkdownProcessorFromConfig(cfg.markdown)\n : null;\n\n return (context) => {\n let nextText = context.text ?? \"\";\n const rawPayload = context.message.rawContent ?? null;\n\n if (actionManager) {\n const actionResult = actionManager.process({\n text: nextText,\n raw: rawPayload ?? nextText,\n message: context.message,\n streaming: context.streaming\n });\n if (actionResult !== null) {\n nextText = actionResult.text;\n // Mark message as non-persistable if persist is false\n if (!actionResult.persist) {\n (context.message as any).__skipPersist = true;\n }\n }\n }\n\n // Priority: postprocessMessage > markdown config > escapeHtml\n if (cfg?.postprocessMessage) {\n return cfg.postprocessMessage({\n ...context,\n text: nextText,\n raw: rawPayload ?? context.text ?? \"\"\n });\n }\n\n // Use markdown processor if markdown config is provided\n if (markdownProcessor) {\n return markdownProcessor(nextText);\n }\n\n return escapeHtml(nextText);\n };\n};\n\nexport const createAgentExperience = (\n mount: HTMLElement,\n initialConfig?: AgentWidgetConfig,\n runtimeOptions?: { debugTools?: boolean }\n): Controller => {\n // Tailwind config uses important: \"#vanilla-agent-root\", so ensure mount has this ID\n if (!mount.id || mount.id !== \"vanilla-agent-root\") {\n mount.id = \"vanilla-agent-root\";\n }\n\n let config = mergeWithDefaults(initialConfig) as AgentWidgetConfig;\n // Note: applyThemeVariables is called after applyFullHeightStyles() below\n // because applyFullHeightStyles resets mount.style.cssText\n\n // Get plugins for this instance\n const plugins = pluginRegistry.getForInstance(config.plugins);\n \n // Register components from config\n if (config.components) {\n componentRegistry.registerAll(config.components);\n }\n const eventBus = createEventBus<AgentWidgetControllerEventMap>();\n\n const storageAdapter: AgentWidgetStorageAdapter =\n config.storageAdapter ?? createLocalStorageAdapter();\n let persistentMetadata: Record<string, unknown> = {};\n let pendingStoredState: Promise<AgentWidgetStoredState | null> | null = null;\n\n if (storageAdapter?.load) {\n try {\n const storedState = storageAdapter.load();\n if (storedState && typeof (storedState as Promise<any>).then === \"function\") {\n pendingStoredState = storedState as Promise<AgentWidgetStoredState | null>;\n } else if (storedState) {\n const immediateState = storedState as AgentWidgetStoredState;\n if (immediateState.metadata) {\n persistentMetadata = ensureRecord(immediateState.metadata);\n }\n if (immediateState.messages?.length) {\n config = { ...config, initialMessages: immediateState.messages };\n }\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to load stored state:\", error);\n }\n }\n }\n\n const getMetadata = () => persistentMetadata;\n const updateMetadata = (\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) => {\n const next = updater({ ...persistentMetadata }) ?? {};\n persistentMetadata = next;\n persistState();\n };\n\n const resolvedActionParsers =\n config.actionParsers && config.actionParsers.length\n ? config.actionParsers\n : [defaultJsonActionParser];\n\n const resolvedActionHandlers =\n config.actionHandlers && config.actionHandlers.length\n ? config.actionHandlers\n : [defaultActionHandlers.message, defaultActionHandlers.messageAndClick];\n\n let actionManager = createActionManager({\n parsers: resolvedActionParsers,\n handlers: resolvedActionHandlers,\n getMetadata,\n updateMetadata,\n emit: eventBus.emit,\n documentRef: typeof document !== \"undefined\" ? document : null\n });\n actionManager.syncFromMetadata();\n\n let launcherEnabled = config.launcher?.enabled ?? true;\n let autoExpand = config.launcher?.autoExpand ?? false;\n let prevAutoExpand = autoExpand;\n let prevLauncherEnabled = launcherEnabled;\n let open = launcherEnabled ? autoExpand : true;\n let postprocess = buildPostprocessor(config, actionManager);\n let showReasoning = config.features?.showReasoning ?? true;\n let showToolCalls = config.features?.showToolCalls ?? true;\n \n // Create message action callbacks that emit events and optionally send to API\n const messageActionCallbacks: MessageActionCallbacks = {\n onCopy: (message: AgentWidgetMessage) => {\n eventBus.emit(\"message:copy\", message);\n // Send copy feedback to API if in client token mode\n if (session?.isClientTokenMode()) {\n session.submitMessageFeedback(message.id, 'copy').catch((error) => {\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to submit copy feedback:\", error);\n }\n });\n }\n // Call user-provided callback\n config.messageActions?.onCopy?.(message);\n },\n onFeedback: (feedback: AgentWidgetMessageFeedback) => {\n eventBus.emit(\"message:feedback\", feedback);\n // Send feedback to API if in client token mode\n if (session?.isClientTokenMode()) {\n session.submitMessageFeedback(feedback.messageId, feedback.type).catch((error) => {\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to submit feedback:\", error);\n }\n });\n }\n // Call user-provided callback\n config.messageActions?.onFeedback?.(feedback);\n }\n };\n \n // Get status indicator config\n const statusConfig = config.statusIndicator ?? {};\n const getStatusText = (status: AgentWidgetSessionStatus): string => {\n if (status === \"idle\") return statusConfig.idleText ?? statusCopy.idle;\n if (status === \"connecting\") return statusConfig.connectingText ?? statusCopy.connecting;\n if (status === \"connected\") return statusConfig.connectedText ?? statusCopy.connected;\n if (status === \"error\") return statusConfig.errorText ?? statusCopy.error;\n return statusCopy[status];\n };\n\n const { wrapper, panel } = createWrapper(config);\n const panelElements = buildPanel(config, launcherEnabled);\n let {\n container,\n body,\n messagesWrapper,\n suggestions,\n textarea,\n sendButton,\n sendButtonWrapper,\n composerForm,\n statusText,\n introTitle,\n introSubtitle,\n closeButton,\n iconHolder,\n headerTitle,\n headerSubtitle,\n header,\n footer\n } = panelElements;\n \n // Use mutable references for mic button so we can update them dynamically\n let micButton: HTMLButtonElement | null = panelElements.micButton;\n let micButtonWrapper: HTMLElement | null = panelElements.micButtonWrapper;\n\n // Plugin hook: renderHeader - allow plugins to provide custom header\n const headerPlugin = plugins.find(p => p.renderHeader);\n if (headerPlugin?.renderHeader) {\n const customHeader = headerPlugin.renderHeader({\n config,\n defaultRenderer: () => {\n const headerElements = buildHeader({ config, showClose: launcherEnabled });\n attachHeaderToContainer(container, headerElements, config);\n return headerElements.header;\n },\n onClose: () => setOpenState(false, \"user\")\n });\n if (customHeader) {\n // Replace the default header with custom header\n const existingHeader = container.querySelector('.tvw-border-b-cw-divider');\n if (existingHeader) {\n existingHeader.replaceWith(customHeader);\n header = customHeader;\n }\n }\n }\n\n // Plugin hook: renderComposer - allow plugins to provide custom composer\n const composerPlugin = plugins.find(p => p.renderComposer);\n if (composerPlugin?.renderComposer) {\n const customComposer = composerPlugin.renderComposer({\n config,\n defaultRenderer: () => {\n const composerElements = buildComposer({ config });\n return composerElements.footer;\n },\n onSubmit: (text: string) => {\n if (session && !session.isStreaming()) {\n session.sendMessage(text);\n }\n },\n disabled: false\n });\n if (customComposer) {\n // Replace the default footer with custom composer\n footer.replaceWith(customComposer);\n footer = customComposer;\n // Note: When using custom composer, textarea/sendButton/etc may not exist\n // The plugin is responsible for providing its own submit handling\n }\n }\n\n // Slot system: allow custom content injection into specific regions\n const renderSlots = () => {\n const slots = config.layout?.slots ?? {};\n \n // Helper to get default slot content\n const getDefaultSlotContent = (slot: WidgetLayoutSlot): HTMLElement | null => {\n switch (slot) {\n case \"body-top\":\n // Default: the intro card\n return container.querySelector(\".tvw-rounded-2xl.tvw-bg-cw-surface.tvw-p-6\") as HTMLElement || null;\n case \"messages\":\n return messagesWrapper;\n case \"footer-top\":\n return suggestions;\n case \"composer\":\n return composerForm;\n case \"footer-bottom\":\n return statusText;\n default:\n return null;\n }\n };\n\n // Helper to insert content into slot region\n const insertSlotContent = (slot: WidgetLayoutSlot, element: HTMLElement) => {\n switch (slot) {\n case \"header-left\":\n case \"header-center\":\n case \"header-right\":\n // Header slots - prepend/append to header\n if (slot === \"header-left\") {\n header.insertBefore(element, header.firstChild);\n } else if (slot === \"header-right\") {\n header.appendChild(element);\n } else {\n // header-center: insert after icon/title\n const titleSection = header.querySelector(\".tvw-flex-col\");\n if (titleSection) {\n titleSection.parentNode?.insertBefore(element, titleSection.nextSibling);\n } else {\n header.appendChild(element);\n }\n }\n break;\n case \"body-top\":\n // Replace or prepend to body\n const introCard = body.querySelector(\".tvw-rounded-2xl.tvw-bg-cw-surface.tvw-p-6\");\n if (introCard) {\n introCard.replaceWith(element);\n } else {\n body.insertBefore(element, body.firstChild);\n }\n break;\n case \"body-bottom\":\n // Append after messages wrapper\n body.appendChild(element);\n break;\n case \"footer-top\":\n // Replace suggestions area\n suggestions.replaceWith(element);\n break;\n case \"footer-bottom\":\n // Replace or append after status text\n statusText.replaceWith(element);\n break;\n default:\n // For other slots, just append to appropriate container\n break;\n }\n };\n\n // Process each configured slot\n for (const [slotName, renderer] of Object.entries(slots) as [WidgetLayoutSlot, SlotRenderer][]) {\n if (renderer) {\n try {\n const slotElement = renderer({\n config,\n defaultContent: () => getDefaultSlotContent(slotName)\n });\n if (slotElement) {\n insertSlotContent(slotName, slotElement);\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(`[AgentWidget] Error rendering slot \"${slotName}\":`, error);\n }\n }\n }\n }\n };\n\n // Render custom slots\n renderSlots();\n\n panel.appendChild(container);\n mount.appendChild(wrapper);\n\n // Apply full-height and sidebar styles if enabled\n // This ensures the widget fills its container height with proper flex layout\n const applyFullHeightStyles = () => {\n const sidebarMode = config.launcher?.sidebarMode ?? false;\n const fullHeight = sidebarMode || (config.launcher?.fullHeight ?? false);\n const theme = config.theme ?? {};\n \n // Determine panel styling based on mode, with theme overrides\n const position = config.launcher?.position ?? 'bottom-left';\n const isLeftSidebar = position === 'bottom-left' || position === 'top-left';\n \n // Default values based on mode\n const defaultPanelBorder = sidebarMode ? 'none' : '1px solid var(--tvw-cw-border)';\n const defaultPanelShadow = sidebarMode \n ? (isLeftSidebar ? '2px 0 12px rgba(0, 0, 0, 0.08)' : '-2px 0 12px rgba(0, 0, 0, 0.08)')\n : '0 25px 50px -12px rgba(0, 0, 0, 0.25)';\n const defaultPanelBorderRadius = sidebarMode ? '0' : '16px';\n \n // Apply theme overrides or defaults\n const panelBorder = theme.panelBorder ?? defaultPanelBorder;\n const panelShadow = theme.panelShadow ?? defaultPanelShadow;\n const panelBorderRadius = theme.panelBorderRadius ?? defaultPanelBorderRadius;\n \n // Reset all inline styles first to handle mode toggling\n // This ensures styles don't persist when switching between modes\n mount.style.cssText = '';\n wrapper.style.cssText = '';\n panel.style.cssText = '';\n container.style.cssText = '';\n body.style.cssText = '';\n footer.style.cssText = '';\n \n // Re-apply panel width/maxWidth from initial setup\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(400px, calc(100vw - 24px))\";\n if (!sidebarMode) {\n panel.style.width = width;\n panel.style.maxWidth = width;\n }\n \n // Apply panel styling\n // Box-shadow is applied to panel (parent) instead of container to avoid\n // rendering artifacts when container has overflow:hidden + border-radius\n // Panel also gets border-radius to make the shadow follow the rounded corners\n panel.style.boxShadow = panelShadow;\n panel.style.borderRadius = panelBorderRadius;\n container.style.border = panelBorder;\n container.style.borderRadius = panelBorderRadius;\n \n // Check if this is inline embed mode (launcher disabled) vs launcher mode\n const isInlineEmbed = config.launcher?.enabled === false;\n \n if (fullHeight) {\n // Mount container\n mount.style.display = 'flex';\n mount.style.flexDirection = 'column';\n mount.style.height = '100%';\n mount.style.minHeight = '0';\n \n // Wrapper\n // - Inline embed: needs overflow:hidden to contain the flex layout\n // - Launcher mode: no overflow:hidden to allow panel's box-shadow to render fully\n wrapper.style.display = 'flex';\n wrapper.style.flexDirection = 'column';\n wrapper.style.flex = '1 1 0%';\n wrapper.style.minHeight = '0';\n wrapper.style.maxHeight = '100%';\n wrapper.style.height = '100%';\n if (isInlineEmbed) {\n wrapper.style.overflow = 'hidden';\n }\n \n // Panel\n panel.style.display = 'flex';\n panel.style.flexDirection = 'column';\n panel.style.flex = '1 1 0%';\n panel.style.minHeight = '0';\n panel.style.maxHeight = '100%';\n panel.style.height = '100%';\n panel.style.overflow = 'hidden';\n \n // Main container\n container.style.display = 'flex';\n container.style.flexDirection = 'column';\n container.style.flex = '1 1 0%';\n container.style.minHeight = '0';\n container.style.maxHeight = '100%';\n container.style.overflow = 'hidden';\n \n // Body (scrollable messages area)\n body.style.flex = '1 1 0%';\n body.style.minHeight = '0';\n body.style.overflowY = 'auto';\n \n // Footer (composer) - should not shrink\n footer.style.flexShrink = '0';\n }\n \n // Handle positioning classes based on mode\n // First remove all position classes to reset state\n wrapper.classList.remove(\n 'tvw-bottom-6', 'tvw-right-6', 'tvw-left-6', 'tvw-top-6',\n 'tvw-bottom-4', 'tvw-right-4', 'tvw-left-4', 'tvw-top-4'\n );\n \n if (!sidebarMode && !isInlineEmbed) {\n // Restore positioning classes when not in sidebar mode (launcher mode only)\n const positionClasses = positionMap[position as keyof typeof positionMap] ?? positionMap['bottom-right'];\n positionClasses.split(' ').forEach(cls => wrapper.classList.add(cls));\n }\n \n // Apply sidebar-specific styles\n if (sidebarMode) {\n const sidebarWidth = config.launcher?.sidebarWidth ?? '420px';\n \n // Wrapper - fixed position, flush with edges\n wrapper.style.cssText = `\n position: fixed !important;\n top: 0 !important;\n bottom: 0 !important;\n width: ${sidebarWidth} !important;\n height: 100vh !important;\n max-height: 100vh !important;\n margin: 0 !important;\n padding: 0 !important;\n display: flex !important;\n flex-direction: column !important;\n ${isLeftSidebar ? 'left: 0 !important; right: auto !important;' : 'left: auto !important; right: 0 !important;'}\n `;\n \n // Panel - fill wrapper (override inline width/max-width from panel.ts)\n // Box-shadow is on panel to avoid rendering artifacts with container's overflow:hidden\n // Border-radius on panel ensures shadow follows rounded corners\n panel.style.cssText = `\n position: relative !important;\n display: flex !important;\n flex-direction: column !important;\n flex: 1 1 0% !important;\n width: 100% !important;\n max-width: 100% !important;\n height: 100% !important;\n min-height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n box-shadow: ${panelShadow} !important;\n border-radius: ${panelBorderRadius} !important;\n `;\n // Force override any inline width/maxWidth that may be set elsewhere\n panel.style.setProperty('width', '100%', 'important');\n panel.style.setProperty('max-width', '100%', 'important');\n \n // Container - apply configurable styles with sidebar layout\n // Note: box-shadow is on panel, not container\n container.style.cssText = `\n display: flex !important;\n flex-direction: column !important;\n flex: 1 1 0% !important;\n width: 100% !important;\n height: 100% !important;\n min-height: 0 !important;\n max-height: 100% !important;\n overflow: hidden !important;\n border-radius: ${panelBorderRadius} !important;\n border: ${panelBorder} !important;\n `;\n \n // Remove footer border in sidebar mode\n footer.style.cssText = `\n flex-shrink: 0 !important;\n border-top: none !important;\n padding: 8px 16px 12px 16px !important;\n `;\n }\n \n // Apply max-height constraints to wrapper to prevent expanding past viewport top\n // Use both -moz-available (Firefox) and stretch (standard) for cross-browser support\n // Append to cssText to allow multiple fallback values for the same property\n // Only apply to launcher mode (not sidebar or inline embed)\n if (!isInlineEmbed) {\n const maxHeightStyles = 'max-height: -moz-available !important; max-height: stretch !important;';\n const paddingStyles = sidebarMode ? '' : 'padding-top: 1.25em !important;';\n wrapper.style.cssText += maxHeightStyles + paddingStyles;\n }\n };\n applyFullHeightStyles();\n // Apply theme variables after applyFullHeightStyles since it resets mount.style.cssText\n applyThemeVariables(mount, config);\n\n const destroyCallbacks: Array<() => void> = [];\n\n // Set up theme observer for auto color scheme detection\n let cleanupThemeObserver: (() => void) | null = null;\n const setupThemeObserver = () => {\n // Clean up existing observer if any\n if (cleanupThemeObserver) {\n cleanupThemeObserver();\n cleanupThemeObserver = null;\n }\n // Set up new observer if colorScheme is 'auto'\n if (config.colorScheme === 'auto') {\n cleanupThemeObserver = createThemeObserver(() => {\n // Re-apply theme when color scheme changes\n applyThemeVariables(mount, config);\n });\n }\n };\n setupThemeObserver();\n destroyCallbacks.push(() => {\n if (cleanupThemeObserver) {\n cleanupThemeObserver();\n cleanupThemeObserver = null;\n }\n });\n\n const suggestionsManager = createSuggestions(suggestions);\n let closeHandler: (() => void) | null = null;\n let session: AgentWidgetSession;\n let isStreaming = false;\n let shouldAutoScroll = true;\n let lastScrollTop = 0;\n let lastAutoScrollTime = 0;\n let scrollRAF: number | null = null;\n let isAutoScrollBlocked = false;\n let blockUntilTime = 0;\n let isAutoScrolling = false;\n\n const AUTO_SCROLL_THROTTLE = 125;\n const AUTO_SCROLL_BLOCK_TIME = 2000;\n const USER_SCROLL_THRESHOLD = 5;\n const BOTTOM_THRESHOLD = 50;\n const messageState = new Map<\n string,\n { streaming?: boolean; role: AgentWidgetMessage[\"role\"] }\n >();\n const voiceState = {\n active: false,\n manuallyDeactivated: false,\n lastUserMessageWasVoice: false\n };\n const voiceAutoResumeMode = config.voiceRecognition?.autoResume ?? false;\n const emitVoiceState = (source: AgentWidgetVoiceStateEvent[\"source\"]) => {\n eventBus.emit(\"voice:state\", {\n active: voiceState.active,\n source,\n timestamp: Date.now()\n });\n };\n const persistVoiceMetadata = () => {\n updateMetadata((prev) => ({\n ...prev,\n voiceState: {\n active: voiceState.active,\n timestamp: Date.now(),\n manuallyDeactivated: voiceState.manuallyDeactivated\n }\n }));\n };\n const maybeRestoreVoiceFromMetadata = () => {\n if (config.voiceRecognition?.enabled === false) return;\n const rawVoiceState = ensureRecord((persistentMetadata as any).voiceState);\n const wasActive = Boolean(rawVoiceState.active);\n const timestamp = Number(rawVoiceState.timestamp ?? 0);\n voiceState.manuallyDeactivated = Boolean(rawVoiceState.manuallyDeactivated);\n if (wasActive && Date.now() - timestamp < VOICE_STATE_RESTORE_WINDOW) {\n setTimeout(() => {\n if (!voiceState.active) {\n voiceState.manuallyDeactivated = false;\n startVoiceRecognition(\"restore\");\n }\n }, 1000);\n }\n };\n\n const getMessagesForPersistence = () =>\n session \n ? stripStreamingFromMessages(session.getMessages()).filter(msg => !(msg as any).__skipPersist)\n : [];\n\n function persistState(messagesOverride?: AgentWidgetMessage[]) {\n if (!storageAdapter?.save) return;\n\n // Allow saving even if session doesn't exist yet (for metadata during init)\n const messages = messagesOverride\n ? stripStreamingFromMessages(messagesOverride)\n : session\n ? getMessagesForPersistence()\n : [];\n\n const payload = {\n messages,\n metadata: persistentMetadata\n };\n try {\n const result = storageAdapter.save(payload);\n if (result instanceof Promise) {\n result.catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to persist state:\", error);\n }\n });\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to persist state:\", error);\n }\n }\n }\n\n const scheduleAutoScroll = (force = false) => {\n if (!shouldAutoScroll) return;\n\n const now = Date.now();\n\n if (isAutoScrollBlocked && now < blockUntilTime) {\n if (!force) return;\n }\n\n if (isAutoScrollBlocked && now >= blockUntilTime) {\n isAutoScrollBlocked = false;\n }\n\n if (!force && !isStreaming) return;\n\n if (now - lastAutoScrollTime < AUTO_SCROLL_THROTTLE) return;\n lastAutoScrollTime = now;\n\n if (scrollRAF) {\n cancelAnimationFrame(scrollRAF);\n }\n\n scrollRAF = requestAnimationFrame(() => {\n if (isAutoScrollBlocked || !shouldAutoScroll) return;\n isAutoScrolling = true;\n body.scrollTop = body.scrollHeight;\n lastScrollTop = body.scrollTop;\n requestAnimationFrame(() => {\n isAutoScrolling = false;\n });\n scrollRAF = null;\n });\n };\n\n // Track ongoing smooth scroll animation\n let smoothScrollRAF: number | null = null;\n\n // Get the scrollable container using its unique ID\n const getScrollableContainer = (): HTMLElement => {\n // Use the unique ID for reliable selection\n const scrollable = wrapper.querySelector('#vanilla-agent-scroll-container') as HTMLElement;\n // Fallback to body if ID not found (shouldn't happen, but safe fallback)\n return scrollable || body;\n };\n\n // Custom smooth scroll animation with easing\n const smoothScrollToBottom = (element: HTMLElement, duration = 500) => {\n const start = element.scrollTop;\n const clientHeight = element.clientHeight;\n // Recalculate target dynamically to handle layout changes\n let target = element.scrollHeight;\n let distance = target - start;\n\n // Check if already at bottom: scrollTop + clientHeight should be >= scrollHeight\n // Add a small threshold (2px) to account for rounding/subpixel differences\n const isAtBottom = start + clientHeight >= target - 2;\n \n // If already at bottom or very close, skip animation to prevent glitch\n if (isAtBottom || Math.abs(distance) < 5) {\n return;\n }\n\n // Cancel any ongoing smooth scroll animation\n if (smoothScrollRAF !== null) {\n cancelAnimationFrame(smoothScrollRAF);\n smoothScrollRAF = null;\n }\n\n const startTime = performance.now();\n\n // Easing function: ease-out cubic for smooth deceleration\n const easeOutCubic = (t: number): number => {\n return 1 - Math.pow(1 - t, 3);\n };\n\n const animate = (currentTime: number) => {\n // Recalculate target each frame in case scrollHeight changed\n const currentTarget = element.scrollHeight;\n if (currentTarget !== target) {\n target = currentTarget;\n distance = target - start;\n }\n\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / duration, 1);\n const eased = easeOutCubic(progress);\n \n const currentScroll = start + distance * eased;\n element.scrollTop = currentScroll;\n\n if (progress < 1) {\n smoothScrollRAF = requestAnimationFrame(animate);\n } else {\n // Ensure we end exactly at the target\n element.scrollTop = element.scrollHeight;\n smoothScrollRAF = null;\n }\n };\n\n smoothScrollRAF = requestAnimationFrame(animate);\n };\n\n const trackMessages = (messages: AgentWidgetMessage[]) => {\n const nextState = new Map<\n string,\n { streaming?: boolean; role: AgentWidgetMessage[\"role\"] }\n >();\n\n messages.forEach((message) => {\n const previous = messageState.get(message.id);\n nextState.set(message.id, {\n streaming: message.streaming,\n role: message.role\n });\n\n if (!previous && message.role === \"assistant\") {\n eventBus.emit(\"assistant:message\", message);\n }\n\n if (\n message.role === \"assistant\" &&\n previous?.streaming &&\n message.streaming === false\n ) {\n eventBus.emit(\"assistant:complete\", message);\n }\n });\n\n messageState.clear();\n nextState.forEach((value, key) => {\n messageState.set(key, value);\n });\n };\n\n\n // Message rendering with plugin support (implementation)\n const renderMessagesWithPluginsImpl = (\n container: HTMLElement,\n messages: AgentWidgetMessage[],\n transform: MessageTransform\n ) => {\n container.innerHTML = \"\";\n const fragment = document.createDocumentFragment();\n\n messages.forEach((message) => {\n let bubble: HTMLElement | null = null;\n\n // Try plugins first\n const matchingPlugin = plugins.find((p) => {\n if (message.variant === \"reasoning\" && p.renderReasoning) {\n return true;\n }\n if (message.variant === \"tool\" && p.renderToolCall) {\n return true;\n }\n if (!message.variant && p.renderMessage) {\n return true;\n }\n return false;\n });\n\n // Get message layout config\n const messageLayoutConfig = config.layout?.messages;\n\n if (matchingPlugin) {\n if (message.variant === \"reasoning\" && message.reasoning && matchingPlugin.renderReasoning) {\n if (!showReasoning) return;\n bubble = matchingPlugin.renderReasoning({\n message,\n defaultRenderer: () => createReasoningBubble(message),\n config\n });\n } else if (message.variant === \"tool\" && message.toolCall && matchingPlugin.renderToolCall) {\n if (!showToolCalls) return;\n bubble = matchingPlugin.renderToolCall({\n message,\n defaultRenderer: () => createToolBubble(message, config),\n config\n });\n } else if (matchingPlugin.renderMessage) {\n bubble = matchingPlugin.renderMessage({\n message,\n defaultRenderer: () => {\n const b = createStandardBubble(\n message, \n transform, \n messageLayoutConfig, \n config.messageActions, \n messageActionCallbacks\n );\n if (message.role !== \"user\") {\n enhanceWithForms(b, message, config, session);\n }\n return b;\n },\n config\n });\n }\n }\n\n // Check for component directive if no plugin handled it\n if (!bubble && message.role === \"assistant\" && !message.variant) {\n const enableComponentStreaming = config.enableComponentStreaming !== false; // Default to true\n if (enableComponentStreaming && hasComponentDirective(message)) {\n const directive = extractComponentDirectiveFromMessage(message);\n if (directive) {\n const componentBubble = renderComponentDirective(directive, {\n config,\n message,\n transform\n });\n if (componentBubble) {\n // Wrap component in standard bubble styling\n const wrapper = document.createElement(\"div\");\n wrapper.className = [\n \"vanilla-message-bubble\",\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-p-4\"\n ].join(\" \");\n wrapper.setAttribute(\"data-message-id\", message.id);\n\n // Add text content above component if present (combined text+component response)\n if (message.content && message.content.trim()) {\n const textDiv = document.createElement(\"div\");\n textDiv.className = \"tvw-mb-3 tvw-text-sm tvw-leading-relaxed\";\n textDiv.innerHTML = transform({\n text: message.content,\n message,\n streaming: Boolean(message.streaming),\n raw: message.rawContent\n });\n wrapper.appendChild(textDiv);\n }\n\n wrapper.appendChild(componentBubble);\n bubble = wrapper;\n }\n }\n }\n }\n\n // Fallback to default rendering if plugin returned null or no plugin matched\n if (!bubble) {\n if (message.variant === \"reasoning\" && message.reasoning) {\n if (!showReasoning) return;\n bubble = createReasoningBubble(message);\n } else if (message.variant === \"tool\" && message.toolCall) {\n if (!showToolCalls) return;\n bubble = createToolBubble(message, config);\n } else {\n // Check for custom message renderers in layout config\n const messageLayoutConfig = config.layout?.messages;\n if (messageLayoutConfig?.renderUserMessage && message.role === \"user\") {\n bubble = messageLayoutConfig.renderUserMessage({\n message,\n config,\n streaming: Boolean(message.streaming)\n });\n } else if (messageLayoutConfig?.renderAssistantMessage && message.role === \"assistant\") {\n bubble = messageLayoutConfig.renderAssistantMessage({\n message,\n config,\n streaming: Boolean(message.streaming)\n });\n } else {\n bubble = createStandardBubble(\n message, \n transform, \n messageLayoutConfig, \n config.messageActions, \n messageActionCallbacks\n );\n }\n if (message.role !== \"user\" && bubble) {\n enhanceWithForms(bubble, message, config, session);\n }\n }\n }\n\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"tvw-flex\";\n if (message.role === \"user\") {\n wrapper.classList.add(\"tvw-justify-end\");\n }\n wrapper.appendChild(bubble);\n fragment.appendChild(wrapper);\n });\n\n // Add standalone typing indicator only if streaming but no assistant message is streaming yet\n // (This shows while waiting for the stream to start)\n // Check for ANY streaming assistant message, even if empty (to avoid duplicate bubbles)\n const hasStreamingAssistantMessage = messages.some(\n (msg) => msg.role === \"assistant\" && msg.streaming\n );\n \n // Also check if there's a recently completed assistant message (streaming just ended)\n // This prevents flicker when the message completes but isStreaming hasn't updated yet\n const lastMessage = messages[messages.length - 1];\n const hasRecentAssistantResponse = lastMessage?.role === \"assistant\" && !lastMessage.streaming;\n\n if (isStreaming && messages.some((msg) => msg.role === \"user\") && !hasStreamingAssistantMessage && !hasRecentAssistantResponse) {\n const typingIndicator = createTypingIndicator();\n\n // Create a bubble wrapper for the typing indicator (similar to assistant messages)\n const typingBubble = document.createElement(\"div\");\n typingBubble.className = [\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\",\n \"tvw-shadow-sm\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-px-5\",\n \"tvw-py-3\"\n ].join(\" \");\n\n typingBubble.appendChild(typingIndicator);\n\n const typingWrapper = document.createElement(\"div\");\n typingWrapper.className = \"tvw-flex\";\n typingWrapper.appendChild(typingBubble);\n fragment.appendChild(typingWrapper);\n }\n\n container.appendChild(fragment);\n // Defer scroll to next frame for smoother animation and to prevent jolt\n // This allows the browser to update layout (e.g., typing indicator removal) before scrolling\n // Use double RAF to ensure layout has fully settled before starting scroll animation\n // Get the scrollable container using its unique ID (#vanilla-agent-scroll-container)\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const scrollableContainer = getScrollableContainer();\n smoothScrollToBottom(scrollableContainer);\n });\n });\n };\n\n // Alias for clarity - the implementation handles flicker prevention via typing indicator logic\n const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;\n\n const updateOpenState = () => {\n if (!launcherEnabled) return;\n if (open) {\n wrapper.classList.remove(\"tvw-pointer-events-none\", \"tvw-opacity-0\");\n panel.classList.remove(\"tvw-scale-95\", \"tvw-opacity-0\");\n panel.classList.add(\"tvw-scale-100\", \"tvw-opacity-100\");\n // Hide launcher button when widget is open\n if (launcherButtonInstance) {\n launcherButtonInstance.element.style.display = \"none\";\n } else if (customLauncherElement) {\n customLauncherElement.style.display = \"none\";\n }\n } else {\n wrapper.classList.add(\"tvw-pointer-events-none\", \"tvw-opacity-0\");\n panel.classList.remove(\"tvw-scale-100\", \"tvw-opacity-100\");\n panel.classList.add(\"tvw-scale-95\", \"tvw-opacity-0\");\n // Show launcher button when widget is closed\n if (launcherButtonInstance) {\n launcherButtonInstance.element.style.display = \"\";\n } else if (customLauncherElement) {\n customLauncherElement.style.display = \"\";\n }\n }\n };\n\n const setOpenState = (nextOpen: boolean, source: \"user\" | \"auto\" | \"api\" | \"system\" = \"user\") => {\n if (!launcherEnabled) return;\n if (open === nextOpen) return;\n \n const prevOpen = open;\n open = nextOpen;\n updateOpenState();\n \n if (open) {\n recalcPanelHeight();\n scheduleAutoScroll(true);\n }\n \n // Emit widget state events\n const stateEvent: AgentWidgetStateEvent = {\n open,\n source,\n timestamp: Date.now()\n };\n \n if (open && !prevOpen) {\n eventBus.emit(\"widget:opened\", stateEvent);\n } else if (!open && prevOpen) {\n eventBus.emit(\"widget:closed\", stateEvent);\n }\n \n // Emit general state snapshot\n eventBus.emit(\"widget:state\", {\n open,\n launcherEnabled,\n voiceActive: voiceState.active,\n streaming: session.isStreaming()\n });\n };\n\n const setComposerDisabled = (disabled: boolean) => {\n // Keep textarea always enabled so users can type while streaming\n // Only disable submit controls to prevent sending during streaming\n sendButton.disabled = disabled;\n if (micButton) {\n micButton.disabled = disabled;\n }\n suggestionsManager.buttons.forEach((btn) => {\n btn.disabled = disabled;\n });\n };\n\n const updateCopy = () => {\n introTitle.textContent = config.copy?.welcomeTitle ?? \"Hello 👋\";\n introSubtitle.textContent =\n config.copy?.welcomeSubtitle ??\n \"Ask anything about your account or products.\";\n textarea.placeholder = config.copy?.inputPlaceholder ?? \"How can I help...\";\n\n // Only update send button text if NOT using icon mode\n const useIcon = config.sendButton?.useIcon ?? false;\n if (!useIcon) {\n sendButton.textContent = config.copy?.sendButtonLabel ?? \"Send\";\n }\n\n // Update textarea font family and weight\n const fontFamily = config.theme?.inputFontFamily ?? \"sans-serif\";\n const fontWeight = config.theme?.inputFontWeight ?? \"400\";\n \n const getFontFamilyValue = (family: \"sans-serif\" | \"serif\" | \"mono\"): string => {\n switch (family) {\n case \"serif\":\n return 'Georgia, \"Times New Roman\", Times, serif';\n case \"mono\":\n return '\"Courier New\", Courier, \"Lucida Console\", Monaco, monospace';\n case \"sans-serif\":\n default:\n return '-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif';\n }\n };\n \n textarea.style.fontFamily = getFontFamilyValue(fontFamily);\n textarea.style.fontWeight = fontWeight;\n };\n\n session = new AgentWidgetSession(config, {\n onMessagesChanged(messages) {\n renderMessagesWithPlugins(messagesWrapper, messages, postprocess);\n // Re-render suggestions to hide them after first user message\n // Pass messages directly to avoid calling session.getMessages() during construction\n if (session) {\n const hasUserMessage = messages.some((msg) => msg.role === \"user\");\n if (hasUserMessage) {\n // Hide suggestions if user message exists\n suggestionsManager.render([], session, textarea, messages);\n } else {\n // Show suggestions if no user message yet\n suggestionsManager.render(config.suggestionChips, session, textarea, messages, config.suggestionChipsConfig);\n }\n }\n scheduleAutoScroll(!isStreaming);\n trackMessages(messages);\n\n const lastUserMessage = [...messages]\n .reverse()\n .find((msg) => msg.role === \"user\");\n voiceState.lastUserMessageWasVoice = Boolean(lastUserMessage?.viaVoice);\n persistState(messages);\n },\n onStatusChanged(status) {\n const currentStatusConfig = config.statusIndicator ?? {};\n const getCurrentStatusText = (status: AgentWidgetSessionStatus): string => {\n if (status === \"idle\") return currentStatusConfig.idleText ?? statusCopy.idle;\n if (status === \"connecting\") return currentStatusConfig.connectingText ?? statusCopy.connecting;\n if (status === \"connected\") return currentStatusConfig.connectedText ?? statusCopy.connected;\n if (status === \"error\") return currentStatusConfig.errorText ?? statusCopy.error;\n return statusCopy[status];\n };\n statusText.textContent = getCurrentStatusText(status);\n },\n onStreamingChanged(streaming) {\n isStreaming = streaming;\n setComposerDisabled(streaming);\n // Re-render messages to show/hide typing indicator\n if (session) {\n renderMessagesWithPlugins(messagesWrapper, session.getMessages(), postprocess);\n }\n if (!streaming) {\n scheduleAutoScroll(true);\n }\n }\n });\n\n if (pendingStoredState) {\n pendingStoredState\n .then((state) => {\n if (!state) return;\n if (state.metadata) {\n persistentMetadata = ensureRecord(state.metadata);\n actionManager.syncFromMetadata();\n }\n if (state.messages?.length) {\n session.hydrateMessages(state.messages);\n }\n })\n .catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to hydrate stored state:\", error);\n }\n });\n }\n\n const handleSubmit = (event: Event) => {\n event.preventDefault();\n const value = textarea.value.trim();\n if (!value) return;\n textarea.value = \"\";\n session.sendMessage(value);\n };\n\n const handleInputEnter = (event: KeyboardEvent) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n sendButton.click();\n }\n };\n\n // Voice recognition state and logic\n let speechRecognition: any = null;\n let isRecording = false;\n let pauseTimer: number | null = null;\n let originalMicStyles: {\n backgroundColor: string;\n color: string;\n borderColor: string;\n } | null = null;\n\n const getSpeechRecognitionClass = (): any => {\n if (typeof window === 'undefined') return null;\n return (window as any).webkitSpeechRecognition || (window as any).SpeechRecognition || null;\n };\n\n const startVoiceRecognition = (\n source: AgentWidgetVoiceStateEvent[\"source\"] = \"user\"\n ) => {\n if (isRecording || session.isStreaming()) return;\n\n const SpeechRecognitionClass = getSpeechRecognitionClass();\n if (!SpeechRecognitionClass) return;\n\n speechRecognition = new SpeechRecognitionClass();\n const voiceConfig = config.voiceRecognition ?? {};\n const pauseDuration = voiceConfig.pauseDuration ?? 2000;\n\n speechRecognition.continuous = true;\n speechRecognition.interimResults = true;\n speechRecognition.lang = 'en-US';\n\n // Store the initial text that was in the textarea\n const initialText = textarea.value;\n\n speechRecognition.onresult = (event: any) => {\n // Build the complete transcript from all results\n let fullTranscript = \"\";\n let interimTranscript = \"\";\n \n // Process all results from the beginning\n for (let i = 0; i < event.results.length; i++) {\n const result = event.results[i];\n const transcript = result[0].transcript;\n \n if (result.isFinal) {\n fullTranscript += transcript + \" \";\n } else {\n // Only take the last interim result\n interimTranscript = transcript;\n }\n }\n \n // Update textarea with initial text + full transcript + interim\n const newValue = initialText + fullTranscript + interimTranscript;\n textarea.value = newValue;\n\n // Reset pause timer on each result\n if (pauseTimer) {\n clearTimeout(pauseTimer);\n }\n\n // Set timer to auto-submit after pause when we have any speech\n if (fullTranscript || interimTranscript) {\n pauseTimer = window.setTimeout(() => {\n const finalValue = textarea.value.trim();\n if (finalValue && speechRecognition && isRecording) {\n stopVoiceRecognition();\n textarea.value = \"\";\n session.sendMessage(finalValue, { viaVoice: true });\n }\n }, pauseDuration);\n }\n };\n\n speechRecognition.onerror = (event: any) => {\n // Don't stop on \"no-speech\" error, just ignore it\n if (event.error !== 'no-speech') {\n stopVoiceRecognition();\n }\n };\n\n speechRecognition.onend = () => {\n // If recognition ended naturally (not manually stopped), submit if there's text\n if (isRecording) {\n const finalValue = textarea.value.trim();\n if (finalValue && finalValue !== initialText.trim()) {\n textarea.value = \"\";\n session.sendMessage(finalValue, { viaVoice: true });\n }\n stopVoiceRecognition();\n }\n };\n\n try {\n speechRecognition.start();\n isRecording = true;\n voiceState.active = true;\n if (source !== \"system\") {\n voiceState.manuallyDeactivated = false;\n }\n emitVoiceState(source);\n persistVoiceMetadata();\n if (micButton) {\n // Store original styles\n originalMicStyles = {\n backgroundColor: micButton.style.backgroundColor,\n color: micButton.style.color,\n borderColor: micButton.style.borderColor\n };\n \n // Apply recording state styles from config\n const voiceConfig = config.voiceRecognition ?? {};\n const recordingBackgroundColor = voiceConfig.recordingBackgroundColor ?? \"#ef4444\";\n const recordingIconColor = voiceConfig.recordingIconColor;\n const recordingBorderColor = voiceConfig.recordingBorderColor;\n \n micButton.classList.add(\"tvw-voice-recording\");\n micButton.style.backgroundColor = recordingBackgroundColor;\n \n if (recordingIconColor) {\n micButton.style.color = recordingIconColor;\n // Update SVG stroke color if present\n const svg = micButton.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"stroke\", recordingIconColor);\n }\n }\n \n if (recordingBorderColor) {\n micButton.style.borderColor = recordingBorderColor;\n }\n \n micButton.setAttribute(\"aria-label\", \"Stop voice recognition\");\n }\n } catch (error) {\n stopVoiceRecognition(\"system\");\n }\n };\n\n const stopVoiceRecognition = (\n source: AgentWidgetVoiceStateEvent[\"source\"] = \"user\"\n ) => {\n if (!isRecording) return;\n\n isRecording = false;\n if (pauseTimer) {\n clearTimeout(pauseTimer);\n pauseTimer = null;\n }\n\n if (speechRecognition) {\n try {\n speechRecognition.stop();\n } catch (error) {\n // Ignore errors when stopping\n }\n speechRecognition = null;\n }\n\n voiceState.active = false;\n emitVoiceState(source);\n persistVoiceMetadata();\n\n if (micButton) {\n micButton.classList.remove(\"tvw-voice-recording\");\n \n // Restore original styles\n if (originalMicStyles) {\n micButton.style.backgroundColor = originalMicStyles.backgroundColor;\n micButton.style.color = originalMicStyles.color;\n micButton.style.borderColor = originalMicStyles.borderColor;\n \n // Restore SVG stroke color if present\n const svg = micButton.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"stroke\", originalMicStyles.color || \"currentColor\");\n }\n \n originalMicStyles = null;\n }\n \n micButton.setAttribute(\"aria-label\", \"Start voice recognition\");\n }\n };\n\n // Function to create mic button dynamically\n const createMicButton = (voiceConfig: AgentWidgetConfig['voiceRecognition'], sendButtonConfig: AgentWidgetConfig['sendButton']): { micButton: HTMLButtonElement; micButtonWrapper: HTMLElement } | null => {\n const hasSpeechRecognition = \n typeof window !== 'undefined' && \n (typeof (window as any).webkitSpeechRecognition !== 'undefined' || \n typeof (window as any).SpeechRecognition !== 'undefined');\n \n if (!hasSpeechRecognition) return null;\n\n const micButtonWrapper = createElement(\"div\", \"tvw-send-button-wrapper\");\n const micButton = createElement(\n \"button\",\n \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n \n micButton.type = \"button\";\n micButton.setAttribute(\"aria-label\", \"Start voice recognition\");\n \n const micIconName = voiceConfig?.iconName ?? \"mic\";\n const buttonSize = sendButtonConfig?.size ?? \"40px\";\n const micIconSize = voiceConfig?.iconSize ?? buttonSize;\n const micIconSizeNum = parseFloat(micIconSize) || 24;\n \n // Use dedicated colors from voice recognition config, fallback to send button colors\n const backgroundColor = voiceConfig?.backgroundColor ?? sendButtonConfig?.backgroundColor;\n const iconColor = voiceConfig?.iconColor ?? sendButtonConfig?.textColor;\n \n micButton.style.width = micIconSize;\n micButton.style.height = micIconSize;\n micButton.style.minWidth = micIconSize;\n micButton.style.minHeight = micIconSize;\n micButton.style.fontSize = \"18px\";\n micButton.style.lineHeight = \"1\";\n \n // Use Lucide mic icon with configured color (stroke width 1.5 for minimalist outline style)\n const iconColorValue = iconColor || \"currentColor\";\n const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColorValue, 1.5);\n if (micIconSvg) {\n micButton.appendChild(micIconSvg);\n micButton.style.color = iconColorValue;\n } else {\n // Fallback to text if icon fails\n micButton.textContent = \"🎤\";\n micButton.style.color = iconColorValue;\n }\n \n // Apply background color\n if (backgroundColor) {\n micButton.style.backgroundColor = backgroundColor;\n } else {\n micButton.classList.add(\"tvw-bg-cw-primary\");\n }\n \n // Apply icon/text color\n if (iconColor) {\n micButton.style.color = iconColor;\n } else if (!iconColor && !sendButtonConfig?.textColor) {\n micButton.classList.add(\"tvw-text-white\");\n }\n \n // Apply border styling\n if (voiceConfig?.borderWidth) {\n micButton.style.borderWidth = voiceConfig.borderWidth;\n micButton.style.borderStyle = \"solid\";\n }\n if (voiceConfig?.borderColor) {\n micButton.style.borderColor = voiceConfig.borderColor;\n }\n \n // Apply padding styling\n if (voiceConfig?.paddingX) {\n micButton.style.paddingLeft = voiceConfig.paddingX;\n micButton.style.paddingRight = voiceConfig.paddingX;\n }\n if (voiceConfig?.paddingY) {\n micButton.style.paddingTop = voiceConfig.paddingY;\n micButton.style.paddingBottom = voiceConfig.paddingY;\n }\n \n micButtonWrapper.appendChild(micButton);\n \n // Add tooltip if enabled\n const tooltipText = voiceConfig?.tooltipText ?? \"Start voice recognition\";\n const showTooltip = voiceConfig?.showTooltip ?? false;\n if (showTooltip && tooltipText) {\n const tooltip = createElement(\"div\", \"tvw-send-button-tooltip\");\n tooltip.textContent = tooltipText;\n micButtonWrapper.appendChild(tooltip);\n }\n \n return { micButton, micButtonWrapper };\n };\n\n // Wire up mic button click handler\n const handleMicButtonClick = () => {\n if (isRecording) {\n // Stop recording and submit\n const finalValue = textarea.value.trim();\n voiceState.manuallyDeactivated = true;\n persistVoiceMetadata();\n stopVoiceRecognition(\"user\");\n if (finalValue) {\n textarea.value = \"\";\n session.sendMessage(finalValue);\n }\n } else {\n // Start recording\n voiceState.manuallyDeactivated = false;\n persistVoiceMetadata();\n startVoiceRecognition(\"user\");\n }\n };\n\n if (micButton) {\n micButton.addEventListener(\"click\", handleMicButtonClick);\n\n destroyCallbacks.push(() => {\n stopVoiceRecognition(\"system\");\n if (micButton) {\n micButton.removeEventListener(\"click\", handleMicButtonClick);\n }\n });\n }\n\n const autoResumeUnsub = eventBus.on(\"assistant:complete\", () => {\n if (!voiceAutoResumeMode) return;\n if (voiceState.active || voiceState.manuallyDeactivated) return;\n if (voiceAutoResumeMode === \"assistant\" && !voiceState.lastUserMessageWasVoice) {\n return;\n }\n setTimeout(() => {\n if (!voiceState.active && !voiceState.manuallyDeactivated) {\n startVoiceRecognition(\"auto\");\n }\n }, 600);\n });\n destroyCallbacks.push(autoResumeUnsub);\n\n const toggleOpen = () => {\n setOpenState(!open, \"user\");\n };\n\n // Plugin hook: renderLauncher - allow plugins to provide custom launcher\n let launcherButtonInstance: ReturnType<typeof createLauncherButton> | null = null;\n let customLauncherElement: HTMLElement | null = null;\n \n if (launcherEnabled) {\n const launcherPlugin = plugins.find(p => p.renderLauncher);\n if (launcherPlugin?.renderLauncher) {\n const customLauncher = launcherPlugin.renderLauncher({\n config,\n defaultRenderer: () => {\n const btn = createLauncherButton(config, toggleOpen);\n return btn.element;\n },\n onToggle: toggleOpen\n });\n if (customLauncher) {\n customLauncherElement = customLauncher;\n }\n }\n \n // Use custom launcher if provided, otherwise use default\n if (!customLauncherElement) {\n launcherButtonInstance = createLauncherButton(config, toggleOpen);\n }\n }\n\n if (launcherButtonInstance) {\n mount.appendChild(launcherButtonInstance.element);\n } else if (customLauncherElement) {\n mount.appendChild(customLauncherElement);\n }\n updateOpenState();\n suggestionsManager.render(config.suggestionChips, session, textarea, undefined, config.suggestionChipsConfig);\n updateCopy();\n setComposerDisabled(session.isStreaming());\n scheduleAutoScroll(true);\n maybeRestoreVoiceFromMetadata();\n\n const recalcPanelHeight = () => {\n const sidebarMode = config.launcher?.sidebarMode ?? false;\n const fullHeight = sidebarMode || (config.launcher?.fullHeight ?? false);\n \n if (!launcherEnabled) {\n panel.style.height = \"\";\n panel.style.width = \"\";\n return;\n }\n \n // In sidebar/fullHeight mode, don't override the width - it's handled by applyFullHeightStyles\n if (!sidebarMode) {\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(400px, calc(100vw - 24px))\";\n panel.style.width = width;\n panel.style.maxWidth = width;\n }\n \n // In fullHeight mode, don't set a fixed height\n if (!fullHeight) {\n const viewportHeight = window.innerHeight;\n const verticalMargin = 64; // leave space for launcher's offset\n const heightOffset = config.launcher?.heightOffset ?? 0;\n const available = Math.max(200, viewportHeight - verticalMargin);\n const clamped = Math.min(640, available);\n const finalHeight = Math.max(200, clamped - heightOffset);\n panel.style.height = `${finalHeight}px`;\n }\n };\n\n recalcPanelHeight();\n window.addEventListener(\"resize\", recalcPanelHeight);\n destroyCallbacks.push(() => window.removeEventListener(\"resize\", recalcPanelHeight));\n\n lastScrollTop = body.scrollTop;\n\n const handleScroll = () => {\n const scrollTop = body.scrollTop;\n const scrollHeight = body.scrollHeight;\n const clientHeight = body.clientHeight;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n const delta = Math.abs(scrollTop - lastScrollTop);\n lastScrollTop = scrollTop;\n\n if (isAutoScrolling) return;\n if (delta <= USER_SCROLL_THRESHOLD) return;\n\n if (!shouldAutoScroll && distanceFromBottom < BOTTOM_THRESHOLD) {\n isAutoScrollBlocked = false;\n shouldAutoScroll = true;\n return;\n }\n\n if (shouldAutoScroll && distanceFromBottom > BOTTOM_THRESHOLD) {\n isAutoScrollBlocked = true;\n blockUntilTime = Date.now() + AUTO_SCROLL_BLOCK_TIME;\n shouldAutoScroll = false;\n }\n };\n\n body.addEventListener(\"scroll\", handleScroll, { passive: true });\n destroyCallbacks.push(() => body.removeEventListener(\"scroll\", handleScroll));\n destroyCallbacks.push(() => {\n if (scrollRAF) cancelAnimationFrame(scrollRAF);\n });\n\n const refreshCloseButton = () => {\n if (!closeButton) return;\n if (closeHandler) {\n closeButton.removeEventListener(\"click\", closeHandler);\n closeHandler = null;\n }\n if (launcherEnabled) {\n closeButton.style.display = \"\";\n closeHandler = () => {\n open = false;\n updateOpenState();\n };\n closeButton.addEventListener(\"click\", closeHandler);\n } else {\n closeButton.style.display = \"none\";\n }\n };\n\n refreshCloseButton();\n\n // Setup clear chat button click handler\n const setupClearChatButton = () => {\n const { clearChatButton } = panelElements;\n if (!clearChatButton) return;\n\n clearChatButton.addEventListener(\"click\", () => {\n // Clear messages in session (this will trigger onMessagesChanged which re-renders)\n session.clearMessages();\n\n // Always clear the default localStorage key\n try {\n localStorage.removeItem(DEFAULT_CHAT_HISTORY_STORAGE_KEY);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared default localStorage key: ${DEFAULT_CHAT_HISTORY_STORAGE_KEY}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear default localStorage:\", error);\n }\n\n // Also clear custom localStorage key if configured\n if (config.clearChatHistoryStorageKey && config.clearChatHistoryStorageKey !== DEFAULT_CHAT_HISTORY_STORAGE_KEY) {\n try {\n localStorage.removeItem(config.clearChatHistoryStorageKey);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared custom localStorage key: ${config.clearChatHistoryStorageKey}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear custom localStorage:\", error);\n }\n }\n\n // Dispatch custom event for external handlers (e.g., localStorage clearing in examples)\n const clearEvent = new CustomEvent(\"vanilla-agent:clear-chat\", {\n detail: { timestamp: new Date().toISOString() }\n });\n window.dispatchEvent(clearEvent);\n\n if (storageAdapter?.clear) {\n try {\n const result = storageAdapter.clear();\n if (result instanceof Promise) {\n result.catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n });\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n }\n }\n persistentMetadata = {};\n actionManager.syncFromMetadata();\n });\n };\n\n setupClearChatButton();\n\n composerForm.addEventListener(\"submit\", handleSubmit);\n textarea.addEventListener(\"keydown\", handleInputEnter);\n\n destroyCallbacks.push(() => {\n composerForm.removeEventListener(\"submit\", handleSubmit);\n textarea.removeEventListener(\"keydown\", handleInputEnter);\n });\n\n destroyCallbacks.push(() => {\n session.cancel();\n });\n\n if (launcherButtonInstance) {\n destroyCallbacks.push(() => {\n launcherButtonInstance?.destroy();\n });\n } else if (customLauncherElement) {\n destroyCallbacks.push(() => {\n customLauncherElement?.remove();\n });\n }\n\n const controller: Controller = {\n update(nextConfig: AgentWidgetConfig) {\n const previousToolCallConfig = config.toolCall;\n const previousColorScheme = config.colorScheme;\n config = { ...config, ...nextConfig };\n // applyFullHeightStyles resets mount.style.cssText, so call it before applyThemeVariables\n applyFullHeightStyles();\n applyThemeVariables(mount, config);\n\n // Re-setup theme observer if colorScheme changed\n if (config.colorScheme !== previousColorScheme) {\n setupThemeObserver();\n }\n\n // Update plugins\n const newPlugins = pluginRegistry.getForInstance(config.plugins);\n plugins.length = 0;\n plugins.push(...newPlugins);\n\n launcherEnabled = config.launcher?.enabled ?? true;\n autoExpand = config.launcher?.autoExpand ?? false;\n showReasoning = config.features?.showReasoning ?? true;\n showToolCalls = config.features?.showToolCalls ?? true;\n\n if (config.launcher?.enabled === false && launcherButtonInstance) {\n launcherButtonInstance.destroy();\n launcherButtonInstance = null;\n }\n if (config.launcher?.enabled === false && customLauncherElement) {\n customLauncherElement.remove();\n customLauncherElement = null;\n }\n\n if (config.launcher?.enabled !== false && !launcherButtonInstance && !customLauncherElement) {\n // Check for launcher plugin when re-enabling\n const launcherPlugin = plugins.find(p => p.renderLauncher);\n if (launcherPlugin?.renderLauncher) {\n const customLauncher = launcherPlugin.renderLauncher({\n config,\n defaultRenderer: () => {\n const btn = createLauncherButton(config, toggleOpen);\n return btn.element;\n },\n onToggle: toggleOpen\n });\n if (customLauncher) {\n customLauncherElement = customLauncher;\n mount.appendChild(customLauncherElement);\n }\n }\n if (!customLauncherElement) {\n launcherButtonInstance = createLauncherButton(config, toggleOpen);\n mount.appendChild(launcherButtonInstance.element);\n }\n }\n\n if (launcherButtonInstance) {\n launcherButtonInstance.update(config);\n }\n // Note: Custom launcher updates are handled by the plugin's own logic\n\n // Update panel header title and subtitle\n if (headerTitle && config.launcher?.title !== undefined) {\n headerTitle.textContent = config.launcher.title;\n }\n if (headerSubtitle && config.launcher?.subtitle !== undefined) {\n headerSubtitle.textContent = config.launcher.subtitle;\n }\n\n // Only update open state if launcher enabled state changed or autoExpand value changed\n const launcherEnabledChanged = launcherEnabled !== prevLauncherEnabled;\n const autoExpandChanged = autoExpand !== prevAutoExpand;\n\n if (launcherEnabledChanged) {\n // Launcher was enabled/disabled - update state accordingly\n if (!launcherEnabled) {\n // When launcher is disabled, always keep panel open\n open = true;\n updateOpenState();\n } else {\n // Launcher was just enabled - respect autoExpand setting\n setOpenState(autoExpand, \"auto\");\n }\n } else if (autoExpandChanged) {\n // autoExpand value changed - update state to match\n setOpenState(autoExpand, \"auto\");\n }\n // Otherwise, preserve current open state (user may have manually opened/closed)\n\n // Update previous values for next comparison\n prevAutoExpand = autoExpand;\n prevLauncherEnabled = launcherEnabled;\n recalcPanelHeight();\n refreshCloseButton();\n\n // Re-render messages if toolCall config changed (to apply new styles)\n const toolCallConfigChanged = JSON.stringify(nextConfig.toolCall) !== JSON.stringify(previousToolCallConfig);\n if (toolCallConfigChanged && session) {\n renderMessagesWithPlugins(messagesWrapper, session.getMessages(), postprocess);\n }\n\n // Update panel icon sizes\n const launcher = config.launcher ?? {};\n const headerIconHidden = launcher.headerIconHidden ?? false;\n const headerIconName = launcher.headerIconName;\n const headerIconSize = launcher.headerIconSize ?? \"48px\";\n \n if (iconHolder) {\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n const headerCopy = header?.querySelector(\".tvw-flex-col\");\n \n // Handle hide/show\n if (headerIconHidden) {\n // Hide iconHolder\n iconHolder.style.display = \"none\";\n // Ensure headerCopy is still in header\n if (header && headerCopy && !header.contains(headerCopy)) {\n header.insertBefore(headerCopy, header.firstChild);\n }\n } else {\n // Show iconHolder\n iconHolder.style.display = \"\";\n iconHolder.style.height = headerIconSize;\n iconHolder.style.width = headerIconSize;\n \n // Ensure iconHolder is before headerCopy in header\n if (header && headerCopy) {\n if (!header.contains(iconHolder)) {\n header.insertBefore(iconHolder, headerCopy);\n } else if (iconHolder.nextSibling !== headerCopy) {\n // Reorder if needed\n iconHolder.remove();\n header.insertBefore(iconHolder, headerCopy);\n }\n }\n \n // Update icon content based on priority: Lucide icon > iconUrl > agentIconText\n if (headerIconName) {\n // Use Lucide icon\n const iconSize = parseFloat(headerIconSize) || 24;\n const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.6, \"#ffffff\", 2);\n if (iconSvg) {\n iconHolder.replaceChildren(iconSvg);\n } else {\n // Fallback to agentIconText if Lucide icon fails\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n } else if (launcher.iconUrl) {\n // Use image URL\n const img = iconHolder.querySelector(\"img\");\n if (img) {\n img.src = launcher.iconUrl;\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n } else {\n // Create new img if it doesn't exist\n const newImg = document.createElement(\"img\");\n newImg.src = launcher.iconUrl;\n newImg.alt = \"\";\n newImg.className = \"tvw-rounded-xl tvw-object-cover\";\n newImg.style.height = headerIconSize;\n newImg.style.width = headerIconSize;\n iconHolder.replaceChildren(newImg);\n }\n } else {\n // Use text/emoji - clear any SVG or img first\n const existingSvg = iconHolder.querySelector(\"svg\");\n const existingImg = iconHolder.querySelector(\"img\");\n if (existingSvg || existingImg) {\n iconHolder.replaceChildren();\n }\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n \n // Update image size if present\n const img = iconHolder.querySelector(\"img\");\n if (img) {\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n }\n }\n }\n if (closeButton) {\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonPlacement = launcher.closeButtonPlacement ?? \"inline\";\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n \n // Update placement if changed - move the wrapper (not just the button) to preserve tooltip\n const { closeButtonWrapper } = panelElements;\n const isTopRight = closeButtonPlacement === \"top-right\";\n const currentlyTopRight = closeButtonWrapper?.classList.contains(\"tvw-absolute\");\n \n if (closeButtonWrapper && isTopRight !== currentlyTopRight) {\n // Placement changed - need to move wrapper and update classes\n closeButtonWrapper.remove();\n \n // Update wrapper classes\n if (isTopRight) {\n closeButtonWrapper.className = \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50\";\n container.style.position = \"relative\";\n container.appendChild(closeButtonWrapper);\n } else {\n // Check if clear chat is inline to determine if we need ml-auto\n const clearChatPlacement = launcher.clearChat?.placement ?? \"inline\";\n const clearChatEnabled = launcher.clearChat?.enabled ?? true;\n closeButtonWrapper.className = (clearChatEnabled && clearChatPlacement === \"inline\") ? \"\" : \"tvw-ml-auto\";\n // Find header element\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n if (header) {\n header.appendChild(closeButtonWrapper);\n }\n }\n }\n \n // Apply close button styling from config\n if (launcher.closeButtonColor) {\n closeButton.style.color = launcher.closeButtonColor;\n closeButton.classList.remove(\"tvw-text-cw-muted\");\n } else {\n closeButton.style.color = \"\";\n closeButton.classList.add(\"tvw-text-cw-muted\");\n }\n \n if (launcher.closeButtonBackgroundColor) {\n closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;\n closeButton.classList.remove(\"hover:tvw-bg-gray-100\");\n } else {\n closeButton.style.backgroundColor = \"\";\n closeButton.classList.add(\"hover:tvw-bg-gray-100\");\n }\n \n // Apply border if width and/or color are provided\n if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {\n const borderWidth = launcher.closeButtonBorderWidth || \"0px\";\n const borderColor = launcher.closeButtonBorderColor || \"transparent\";\n closeButton.style.border = `${borderWidth} solid ${borderColor}`;\n closeButton.classList.remove(\"tvw-border-none\");\n } else {\n closeButton.style.border = \"\";\n closeButton.classList.add(\"tvw-border-none\");\n }\n \n if (launcher.closeButtonBorderRadius) {\n closeButton.style.borderRadius = launcher.closeButtonBorderRadius;\n closeButton.classList.remove(\"tvw-rounded-full\");\n } else {\n closeButton.style.borderRadius = \"\";\n closeButton.classList.add(\"tvw-rounded-full\");\n }\n\n // Update padding\n if (launcher.closeButtonPaddingX) {\n closeButton.style.paddingLeft = launcher.closeButtonPaddingX;\n closeButton.style.paddingRight = launcher.closeButtonPaddingX;\n } else {\n closeButton.style.paddingLeft = \"\";\n closeButton.style.paddingRight = \"\";\n }\n if (launcher.closeButtonPaddingY) {\n closeButton.style.paddingTop = launcher.closeButtonPaddingY;\n closeButton.style.paddingBottom = launcher.closeButtonPaddingY;\n } else {\n closeButton.style.paddingTop = \"\";\n closeButton.style.paddingBottom = \"\";\n }\n\n // Update icon\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeButtonIconText = launcher.closeButtonIconText ?? \"×\";\n\n // Clear existing content and render new icon\n closeButton.innerHTML = \"\";\n const iconSvg = renderLucideIcon(closeButtonIconName, \"20px\", launcher.closeButtonColor || \"\", 2);\n if (iconSvg) {\n closeButton.appendChild(iconSvg);\n } else {\n closeButton.textContent = closeButtonIconText;\n }\n\n // Update tooltip\n const closeButtonTooltipText = launcher.closeButtonTooltipText ?? \"Close chat\";\n const closeButtonShowTooltip = launcher.closeButtonShowTooltip ?? true;\n\n closeButton.setAttribute(\"aria-label\", closeButtonTooltipText);\n\n if (closeButtonWrapper) {\n // Clean up old tooltip event listeners if they exist\n if ((closeButtonWrapper as any)._cleanupTooltip) {\n (closeButtonWrapper as any)._cleanupTooltip();\n delete (closeButtonWrapper as any)._cleanupTooltip;\n }\n\n // Set up new portaled tooltip with event listeners\n if (closeButtonShowTooltip && closeButtonTooltipText) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip || !closeButton) return; // Already showing or button doesn't exist\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = closeButtonTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = closeButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n closeButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n closeButton.addEventListener(\"focus\", showTooltip);\n closeButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the wrapper for later use\n (closeButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n if (closeButtonWrapper) {\n closeButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n }\n if (closeButton) {\n closeButton.removeEventListener(\"focus\", showTooltip);\n closeButton.removeEventListener(\"blur\", hideTooltip);\n }\n };\n }\n }\n }\n\n // Update clear chat button styling from config\n const { clearChatButton, clearChatButtonWrapper } = panelElements;\n if (clearChatButton) {\n const clearChatConfig = launcher.clearChat ?? {};\n const clearChatEnabled = clearChatConfig.enabled ?? true;\n const clearChatPlacement = clearChatConfig.placement ?? \"inline\";\n\n // Show/hide button based on enabled state\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.style.display = clearChatEnabled ? \"\" : \"none\";\n\n // Update placement if changed\n const isTopRight = clearChatPlacement === \"top-right\";\n const currentlyTopRight = clearChatButtonWrapper.classList.contains(\"tvw-absolute\");\n\n if (isTopRight !== currentlyTopRight && clearChatEnabled) {\n clearChatButtonWrapper.remove();\n\n if (isTopRight) {\n // Don't use tvw-clear-chat-button-wrapper class for top-right mode as its\n // display: inline-flex causes alignment issues with the close button\n clearChatButtonWrapper.className = \"tvw-absolute tvw-top-4 tvw-z-50\";\n // Position to the left of the close button (which is at right: 1rem/16px)\n // Close button is ~32px wide, plus small gap = 48px from right\n clearChatButtonWrapper.style.right = \"48px\";\n container.style.position = \"relative\";\n container.appendChild(clearChatButtonWrapper);\n } else {\n clearChatButtonWrapper.className = \"tvw-relative tvw-ml-auto tvw-clear-chat-button-wrapper\";\n // Clear the inline right style when switching back to inline mode\n clearChatButtonWrapper.style.right = \"\";\n // Find header and insert before close button\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n const closeButtonWrapperEl = panelElements.closeButtonWrapper;\n if (header && closeButtonWrapperEl && closeButtonWrapperEl.parentElement === header) {\n header.insertBefore(clearChatButtonWrapper, closeButtonWrapperEl);\n } else if (header) {\n header.appendChild(clearChatButtonWrapper);\n }\n }\n\n // Also update close button's ml-auto class based on clear chat position\n const closeButtonWrapperEl = panelElements.closeButtonWrapper;\n if (closeButtonWrapperEl && !closeButtonWrapperEl.classList.contains(\"tvw-absolute\")) {\n if (isTopRight) {\n // Clear chat moved to top-right, close needs ml-auto\n closeButtonWrapperEl.classList.add(\"tvw-ml-auto\");\n } else {\n // Clear chat is inline, close doesn't need ml-auto\n closeButtonWrapperEl.classList.remove(\"tvw-ml-auto\");\n }\n }\n }\n }\n\n if (clearChatEnabled) {\n // Update size\n const clearChatSize = clearChatConfig.size ?? \"32px\";\n clearChatButton.style.height = clearChatSize;\n clearChatButton.style.width = clearChatSize;\n\n // Update icon\n const clearChatIconName = clearChatConfig.iconName ?? \"refresh-cw\";\n const clearChatIconColor = clearChatConfig.iconColor ?? \"\";\n\n // Clear existing icon and render new one\n clearChatButton.innerHTML = \"\";\n const iconSvg = renderLucideIcon(clearChatIconName, \"20px\", clearChatIconColor || \"\", 2);\n if (iconSvg) {\n clearChatButton.appendChild(iconSvg);\n }\n\n // Update icon color\n if (clearChatIconColor) {\n clearChatButton.style.color = clearChatIconColor;\n clearChatButton.classList.remove(\"tvw-text-cw-muted\");\n } else {\n clearChatButton.style.color = \"\";\n clearChatButton.classList.add(\"tvw-text-cw-muted\");\n }\n\n // Update background color\n if (clearChatConfig.backgroundColor) {\n clearChatButton.style.backgroundColor = clearChatConfig.backgroundColor;\n clearChatButton.classList.remove(\"hover:tvw-bg-gray-100\");\n } else {\n clearChatButton.style.backgroundColor = \"\";\n clearChatButton.classList.add(\"hover:tvw-bg-gray-100\");\n }\n\n // Update border\n if (clearChatConfig.borderWidth || clearChatConfig.borderColor) {\n const borderWidth = clearChatConfig.borderWidth || \"0px\";\n const borderColor = clearChatConfig.borderColor || \"transparent\";\n clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;\n clearChatButton.classList.remove(\"tvw-border-none\");\n } else {\n clearChatButton.style.border = \"\";\n clearChatButton.classList.add(\"tvw-border-none\");\n }\n\n // Update border radius\n if (clearChatConfig.borderRadius) {\n clearChatButton.style.borderRadius = clearChatConfig.borderRadius;\n clearChatButton.classList.remove(\"tvw-rounded-full\");\n } else {\n clearChatButton.style.borderRadius = \"\";\n clearChatButton.classList.add(\"tvw-rounded-full\");\n }\n\n // Update padding\n if (clearChatConfig.paddingX) {\n clearChatButton.style.paddingLeft = clearChatConfig.paddingX;\n clearChatButton.style.paddingRight = clearChatConfig.paddingX;\n } else {\n clearChatButton.style.paddingLeft = \"\";\n clearChatButton.style.paddingRight = \"\";\n }\n if (clearChatConfig.paddingY) {\n clearChatButton.style.paddingTop = clearChatConfig.paddingY;\n clearChatButton.style.paddingBottom = clearChatConfig.paddingY;\n } else {\n clearChatButton.style.paddingTop = \"\";\n clearChatButton.style.paddingBottom = \"\";\n }\n\n const clearChatTooltipText = clearChatConfig.tooltipText ?? \"Clear chat\";\n const clearChatShowTooltip = clearChatConfig.showTooltip ?? true;\n\n clearChatButton.setAttribute(\"aria-label\", clearChatTooltipText);\n\n if (clearChatButtonWrapper) {\n // Clean up old tooltip event listeners if they exist\n if ((clearChatButtonWrapper as any)._cleanupTooltip) {\n (clearChatButtonWrapper as any)._cleanupTooltip();\n delete (clearChatButtonWrapper as any)._cleanupTooltip;\n }\n\n // Set up new portaled tooltip with event listeners\n if (clearChatShowTooltip && clearChatTooltipText) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip || !clearChatButton) return; // Already showing or button doesn't exist\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = clearChatTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = clearChatButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n clearChatButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n clearChatButton.addEventListener(\"focus\", showTooltip);\n clearChatButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the button for later use\n (clearChatButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n }\n if (clearChatButton) {\n clearChatButton.removeEventListener(\"focus\", showTooltip);\n clearChatButton.removeEventListener(\"blur\", hideTooltip);\n }\n };\n }\n }\n }\n }\n\n const nextParsers =\n config.actionParsers && config.actionParsers.length\n ? config.actionParsers\n : [defaultJsonActionParser];\n const nextHandlers =\n config.actionHandlers && config.actionHandlers.length\n ? config.actionHandlers\n : [defaultActionHandlers.message, defaultActionHandlers.messageAndClick];\n\n actionManager = createActionManager({\n parsers: nextParsers,\n handlers: nextHandlers,\n getMetadata,\n updateMetadata,\n emit: eventBus.emit,\n documentRef: typeof document !== \"undefined\" ? document : null\n });\n\n postprocess = buildPostprocessor(config, actionManager);\n session.updateConfig(config);\n renderMessagesWithPlugins(\n messagesWrapper,\n session.getMessages(),\n postprocess\n );\n suggestionsManager.render(config.suggestionChips, session, textarea, undefined, config.suggestionChipsConfig);\n updateCopy();\n setComposerDisabled(session.isStreaming());\n \n // Update voice recognition mic button visibility\n const voiceRecognitionEnabled = config.voiceRecognition?.enabled === true;\n const hasSpeechRecognition = \n typeof window !== 'undefined' && \n (typeof (window as any).webkitSpeechRecognition !== 'undefined' || \n typeof (window as any).SpeechRecognition !== 'undefined');\n \n // Update composer form gap based on voice recognition\n const shouldUseSmallGap = voiceRecognitionEnabled && hasSpeechRecognition;\n composerForm.classList.remove(\"tvw-gap-1\", \"tvw-gap-3\");\n composerForm.classList.add(shouldUseSmallGap ? \"tvw-gap-1\" : \"tvw-gap-3\");\n \n if (voiceRecognitionEnabled && hasSpeechRecognition) {\n // Create or update mic button\n if (!micButton || !micButtonWrapper) {\n // Create new mic button\n const micButtonResult = createMicButton(config.voiceRecognition, config.sendButton);\n if (micButtonResult) {\n // Update the mutable references\n micButton = micButtonResult.micButton;\n micButtonWrapper = micButtonResult.micButtonWrapper;\n \n // Insert before send button wrapper\n composerForm.insertBefore(micButtonWrapper, sendButtonWrapper);\n \n // Wire up click handler\n micButton.addEventListener(\"click\", handleMicButtonClick);\n \n // Set disabled state\n micButton.disabled = session.isStreaming();\n }\n } else {\n // Update existing mic button with new config\n const voiceConfig = config.voiceRecognition ?? {};\n const sendButtonConfig = config.sendButton ?? {};\n \n // Update icon name and size\n const micIconName = voiceConfig.iconName ?? \"mic\";\n const buttonSize = sendButtonConfig.size ?? \"40px\";\n const micIconSize = voiceConfig.iconSize ?? buttonSize;\n const micIconSizeNum = parseFloat(micIconSize) || 24;\n \n micButton.style.width = micIconSize;\n micButton.style.height = micIconSize;\n micButton.style.minWidth = micIconSize;\n micButton.style.minHeight = micIconSize;\n \n // Update icon\n const iconColor = voiceConfig.iconColor ?? sendButtonConfig.textColor ?? \"currentColor\";\n micButton.innerHTML = \"\";\n const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColor, 2);\n if (micIconSvg) {\n micButton.appendChild(micIconSvg);\n } else {\n micButton.textContent = \"🎤\";\n }\n \n // Update colors\n const backgroundColor = voiceConfig.backgroundColor ?? sendButtonConfig.backgroundColor;\n if (backgroundColor) {\n micButton.style.backgroundColor = backgroundColor;\n micButton.classList.remove(\"tvw-bg-cw-primary\");\n } else {\n micButton.style.backgroundColor = \"\";\n micButton.classList.add(\"tvw-bg-cw-primary\");\n }\n \n if (iconColor) {\n micButton.style.color = iconColor;\n micButton.classList.remove(\"tvw-text-white\");\n } else if (!iconColor && !sendButtonConfig.textColor) {\n micButton.style.color = \"\";\n micButton.classList.add(\"tvw-text-white\");\n }\n \n // Update border styling\n if (voiceConfig.borderWidth) {\n micButton.style.borderWidth = voiceConfig.borderWidth;\n micButton.style.borderStyle = \"solid\";\n } else {\n micButton.style.borderWidth = \"\";\n micButton.style.borderStyle = \"\";\n }\n if (voiceConfig.borderColor) {\n micButton.style.borderColor = voiceConfig.borderColor;\n } else {\n micButton.style.borderColor = \"\";\n }\n \n // Update padding styling\n if (voiceConfig.paddingX) {\n micButton.style.paddingLeft = voiceConfig.paddingX;\n micButton.style.paddingRight = voiceConfig.paddingX;\n } else {\n micButton.style.paddingLeft = \"\";\n micButton.style.paddingRight = \"\";\n }\n if (voiceConfig.paddingY) {\n micButton.style.paddingTop = voiceConfig.paddingY;\n micButton.style.paddingBottom = voiceConfig.paddingY;\n } else {\n micButton.style.paddingTop = \"\";\n micButton.style.paddingBottom = \"\";\n }\n \n // Update tooltip\n const tooltip = micButtonWrapper?.querySelector(\".tvw-send-button-tooltip\") as HTMLElement | null;\n const tooltipText = voiceConfig.tooltipText ?? \"Start voice recognition\";\n const showTooltip = voiceConfig.showTooltip ?? false;\n if (showTooltip && tooltipText) {\n if (!tooltip) {\n // Create tooltip if it doesn't exist\n const newTooltip = document.createElement(\"div\");\n newTooltip.className = \"tvw-send-button-tooltip\";\n newTooltip.textContent = tooltipText;\n micButtonWrapper?.insertBefore(newTooltip, micButton);\n } else {\n tooltip.textContent = tooltipText;\n tooltip.style.display = \"\";\n }\n } else if (tooltip) {\n // Hide tooltip if disabled\n tooltip.style.display = \"none\";\n }\n \n // Show and update disabled state\n micButtonWrapper.style.display = \"\";\n micButton.disabled = session.isStreaming();\n }\n } else {\n // Hide mic button\n if (micButton && micButtonWrapper) {\n micButtonWrapper.style.display = \"none\";\n // Stop any active recording if disabling\n if (isRecording) {\n stopVoiceRecognition();\n }\n }\n }\n \n // Update send button styling\n const sendButtonConfig = config.sendButton ?? {};\n const useIcon = sendButtonConfig.useIcon ?? false;\n const iconText = sendButtonConfig.iconText ?? \"↑\";\n const iconName = sendButtonConfig.iconName;\n const tooltipText = sendButtonConfig.tooltipText ?? \"Send message\";\n const showTooltip = sendButtonConfig.showTooltip ?? false;\n const buttonSize = sendButtonConfig.size ?? \"40px\";\n const backgroundColor = sendButtonConfig.backgroundColor;\n const textColor = sendButtonConfig.textColor;\n\n // Update button content and styling based on mode\n if (useIcon) {\n // Icon mode: circular button\n sendButton.style.width = buttonSize;\n sendButton.style.height = buttonSize;\n sendButton.style.minWidth = buttonSize;\n sendButton.style.minHeight = buttonSize;\n sendButton.style.fontSize = \"18px\";\n sendButton.style.lineHeight = \"1\";\n \n // Clear existing content\n sendButton.innerHTML = \"\";\n \n // Use Lucide icon if iconName is provided, otherwise fall back to iconText\n if (iconName) {\n const iconSize = parseFloat(buttonSize) || 24;\n const iconColor = textColor && typeof textColor === 'string' && textColor.trim() ? textColor.trim() : \"currentColor\";\n const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);\n if (iconSvg) {\n sendButton.appendChild(iconSvg);\n sendButton.style.color = iconColor;\n } else {\n // Fallback to text if icon fails to render\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n } else {\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n \n // Update classes\n sendButton.className = \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\";\n \n if (backgroundColor) {\n sendButton.style.backgroundColor = backgroundColor;\n sendButton.classList.remove(\"tvw-bg-cw-primary\");\n } else {\n sendButton.classList.add(\"tvw-bg-cw-primary\");\n }\n } else {\n // Text mode: existing behavior\n sendButton.textContent = config.copy?.sendButtonLabel ?? \"Send\";\n sendButton.style.width = \"\";\n sendButton.style.height = \"\";\n sendButton.style.minWidth = \"\";\n sendButton.style.minHeight = \"\";\n sendButton.style.fontSize = \"\";\n sendButton.style.lineHeight = \"\";\n \n // Update classes\n sendButton.className = \"tvw-rounded-button tvw-bg-cw-accent tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold tvw-text-white disabled:tvw-opacity-50 tvw-cursor-pointer\";\n \n if (backgroundColor) {\n sendButton.style.backgroundColor = backgroundColor;\n sendButton.classList.remove(\"tvw-bg-cw-accent\");\n } else {\n sendButton.classList.add(\"tvw-bg-cw-accent\");\n }\n \n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n\n // Apply border styling\n if (sendButtonConfig.borderWidth) {\n sendButton.style.borderWidth = sendButtonConfig.borderWidth;\n sendButton.style.borderStyle = \"solid\";\n } else {\n sendButton.style.borderWidth = \"\";\n sendButton.style.borderStyle = \"\";\n }\n if (sendButtonConfig.borderColor) {\n sendButton.style.borderColor = sendButtonConfig.borderColor;\n } else {\n sendButton.style.borderColor = \"\";\n }\n\n // Apply padding styling (works in both icon and text mode)\n if (sendButtonConfig.paddingX) {\n sendButton.style.paddingLeft = sendButtonConfig.paddingX;\n sendButton.style.paddingRight = sendButtonConfig.paddingX;\n } else {\n sendButton.style.paddingLeft = \"\";\n sendButton.style.paddingRight = \"\";\n }\n if (sendButtonConfig.paddingY) {\n sendButton.style.paddingTop = sendButtonConfig.paddingY;\n sendButton.style.paddingBottom = sendButtonConfig.paddingY;\n } else {\n sendButton.style.paddingTop = \"\";\n sendButton.style.paddingBottom = \"\";\n }\n\n // Update tooltip\n const tooltip = sendButtonWrapper?.querySelector(\".tvw-send-button-tooltip\") as HTMLElement | null;\n if (showTooltip && tooltipText) {\n if (!tooltip) {\n // Create tooltip if it doesn't exist\n const newTooltip = document.createElement(\"div\");\n newTooltip.className = \"tvw-send-button-tooltip\";\n newTooltip.textContent = tooltipText;\n sendButtonWrapper?.insertBefore(newTooltip, sendButton);\n } else {\n tooltip.textContent = tooltipText;\n tooltip.style.display = \"\";\n }\n } else if (tooltip) {\n tooltip.style.display = \"none\";\n }\n \n // Update status indicator visibility and text\n const statusIndicatorConfig = config.statusIndicator ?? {};\n const isVisible = statusIndicatorConfig.visible ?? true;\n statusText.style.display = isVisible ? \"\" : \"none\";\n \n // Update status text if status is currently set\n if (session) {\n const currentStatus = session.getStatus();\n const getCurrentStatusText = (status: AgentWidgetSessionStatus): string => {\n if (status === \"idle\") return statusIndicatorConfig.idleText ?? statusCopy.idle;\n if (status === \"connecting\") return statusIndicatorConfig.connectingText ?? statusCopy.connecting;\n if (status === \"connected\") return statusIndicatorConfig.connectedText ?? statusCopy.connected;\n if (status === \"error\") return statusIndicatorConfig.errorText ?? statusCopy.error;\n return statusCopy[status];\n };\n statusText.textContent = getCurrentStatusText(currentStatus);\n }\n },\n open() {\n if (!launcherEnabled) return;\n setOpenState(true, \"api\");\n },\n close() {\n if (!launcherEnabled) return;\n setOpenState(false, \"api\");\n },\n toggle() {\n if (!launcherEnabled) return;\n setOpenState(!open, \"api\");\n },\n clearChat() {\n // Clear messages in session (this will trigger onMessagesChanged which re-renders)\n session.clearMessages();\n\n // Always clear the default localStorage key\n try {\n localStorage.removeItem(DEFAULT_CHAT_HISTORY_STORAGE_KEY);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared default localStorage key: ${DEFAULT_CHAT_HISTORY_STORAGE_KEY}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear default localStorage:\", error);\n }\n\n // Also clear custom localStorage key if configured\n if (config.clearChatHistoryStorageKey && config.clearChatHistoryStorageKey !== DEFAULT_CHAT_HISTORY_STORAGE_KEY) {\n try {\n localStorage.removeItem(config.clearChatHistoryStorageKey);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared custom localStorage key: ${config.clearChatHistoryStorageKey}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear custom localStorage:\", error);\n }\n }\n\n // Dispatch custom event for external handlers (e.g., localStorage clearing in examples)\n const clearEvent = new CustomEvent(\"vanilla-agent:clear-chat\", {\n detail: { timestamp: new Date().toISOString() }\n });\n window.dispatchEvent(clearEvent);\n\n if (storageAdapter?.clear) {\n try {\n const result = storageAdapter.clear();\n if (result instanceof Promise) {\n result.catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n });\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n }\n }\n persistentMetadata = {};\n actionManager.syncFromMetadata();\n },\n setMessage(message: string): boolean {\n if (!textarea) return false;\n if (session.isStreaming()) return false;\n \n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n textarea.value = message;\n // Trigger input event for any listeners\n textarea.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n },\n submitMessage(message?: string): boolean {\n if (session.isStreaming()) return false;\n \n const valueToSubmit = message?.trim() || textarea.value.trim();\n if (!valueToSubmit) return false;\n \n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n textarea.value = \"\";\n session.sendMessage(valueToSubmit);\n return true;\n },\n startVoiceRecognition(): boolean {\n if (isRecording || session.isStreaming()) return false;\n \n const SpeechRecognitionClass = getSpeechRecognitionClass();\n if (!SpeechRecognitionClass) return false;\n \n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n voiceState.manuallyDeactivated = false;\n persistVoiceMetadata();\n startVoiceRecognition(\"user\");\n return true;\n },\n stopVoiceRecognition(): boolean {\n if (!isRecording) return false;\n \n voiceState.manuallyDeactivated = true;\n persistVoiceMetadata();\n stopVoiceRecognition(\"user\");\n return true;\n },\n injectTestMessage(event: AgentWidgetEvent) {\n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n session.injectTestEvent(event);\n },\n getMessages() {\n return session.getMessages();\n },\n getStatus() {\n return session.getStatus();\n },\n getPersistentMetadata() {\n return { ...persistentMetadata };\n },\n updatePersistentMetadata(\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) {\n updateMetadata(updater);\n },\n on(event, handler) {\n return eventBus.on(event, handler);\n },\n off(event, handler) {\n eventBus.off(event, handler);\n },\n // State query methods\n isOpen(): boolean {\n return launcherEnabled && open;\n },\n isVoiceActive(): boolean {\n return voiceState.active;\n },\n getState(): AgentWidgetStateSnapshot {\n return {\n open: launcherEnabled && open,\n launcherEnabled,\n voiceActive: voiceState.active,\n streaming: session.isStreaming()\n };\n },\n // Feedback methods (CSAT/NPS)\n showCSATFeedback(options?: Partial<CSATFeedbackOptions>) {\n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n // Remove any existing feedback forms\n const existingFeedback = messagesWrapper.querySelector('.tvw-feedback-container');\n if (existingFeedback) {\n existingFeedback.remove();\n }\n \n const feedbackEl = createCSATFeedback({\n onSubmit: async (rating, comment) => {\n if (session.isClientTokenMode()) {\n await session.submitCSATFeedback(rating, comment);\n }\n options?.onSubmit?.(rating, comment);\n },\n onDismiss: options?.onDismiss,\n ...options,\n });\n \n // Append to messages area at the bottom\n messagesWrapper.appendChild(feedbackEl);\n feedbackEl.scrollIntoView({ behavior: 'smooth', block: 'end' });\n },\n showNPSFeedback(options?: Partial<NPSFeedbackOptions>) {\n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n // Remove any existing feedback forms\n const existingFeedback = messagesWrapper.querySelector('.tvw-feedback-container');\n if (existingFeedback) {\n existingFeedback.remove();\n }\n \n const feedbackEl = createNPSFeedback({\n onSubmit: async (rating, comment) => {\n if (session.isClientTokenMode()) {\n await session.submitNPSFeedback(rating, comment);\n }\n options?.onSubmit?.(rating, comment);\n },\n onDismiss: options?.onDismiss,\n ...options,\n });\n \n // Append to messages area at the bottom\n messagesWrapper.appendChild(feedbackEl);\n feedbackEl.scrollIntoView({ behavior: 'smooth', block: 'end' });\n },\n async submitCSATFeedback(rating: number, comment?: string): Promise<void> {\n return session.submitCSATFeedback(rating, comment);\n },\n async submitNPSFeedback(rating: number, comment?: string): Promise<void> {\n return session.submitNPSFeedback(rating, comment);\n },\n destroy() {\n destroyCallbacks.forEach((cb) => cb());\n wrapper.remove();\n launcherButtonInstance?.destroy();\n customLauncherElement?.remove();\n if (closeHandler) {\n closeButton.removeEventListener(\"click\", closeHandler);\n }\n }\n };\n\n const shouldExposeDebugApi =\n (runtimeOptions?.debugTools ?? false) || Boolean(config.debug);\n\n if (shouldExposeDebugApi && typeof window !== \"undefined\") {\n const previousDebug = (window as any).AgentWidgetBrowser;\n const debugApi = {\n controller,\n getMessages: controller.getMessages,\n getStatus: controller.getStatus,\n getMetadata: controller.getPersistentMetadata,\n updateMetadata: controller.updatePersistentMetadata,\n clearHistory: () => controller.clearChat(),\n setVoiceActive: (active: boolean) =>\n active\n ? controller.startVoiceRecognition()\n : controller.stopVoiceRecognition()\n };\n (window as any).AgentWidgetBrowser = debugApi;\n destroyCallbacks.push(() => {\n if ((window as any).AgentWidgetBrowser === debugApi) {\n (window as any).AgentWidgetBrowser = previousDebug;\n }\n });\n }\n\n return controller;\n};\n\nexport type AgentWidgetController = Controller;\n","import { createAgentExperience, AgentWidgetController } from \"../ui\";\nimport { AgentWidgetConfig, AgentWidgetInitOptions, AgentWidgetEvent } from \"../types\";\n\nconst ensureTarget = (target: string | HTMLElement): HTMLElement => {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new Error(\"Chat widget can only be mounted in a browser environment\");\n }\n\n if (typeof target === \"string\") {\n const element = document.querySelector<HTMLElement>(target);\n if (!element) {\n throw new Error(`Chat widget target \"${target}\" was not found`);\n }\n return element;\n }\n\n return target;\n};\n\nconst widgetCssHref = (): string | null => {\n try {\n // This works in ESM builds but not in IIFE builds\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n return new URL(\"../widget.css\", import.meta.url).href;\n }\n } catch {\n // Fallback for IIFE builds where CSS should be loaded separately\n }\n return null;\n};\n\nconst mountStyles = (root: ShadowRoot | HTMLElement) => {\n const href = widgetCssHref();\n\n const adoptExistingStylesheet = () => {\n if (!(root instanceof ShadowRoot)) {\n return;\n }\n\n if (root.querySelector('link[data-vanilla-agent]')) {\n return;\n }\n\n const globalLink = document.head.querySelector<HTMLLinkElement>(\n 'link[data-vanilla-agent]'\n );\n if (!globalLink) {\n return;\n }\n\n const clonedLink = globalLink.cloneNode(true) as HTMLLinkElement;\n root.insertBefore(clonedLink, root.firstChild);\n };\n\n if (root instanceof ShadowRoot) {\n // For shadow DOM, we need to load CSS into the shadow root\n if (href) {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.setAttribute(\"data-vanilla-agent\", \"true\");\n root.insertBefore(link, root.firstChild);\n } else {\n adoptExistingStylesheet();\n }\n // If href is null (IIFE build), CSS should already be loaded globally\n } else {\n // For non-shadow DOM, check if CSS is already loaded\n const existing = document.head.querySelector<HTMLLinkElement>(\n \"link[data-vanilla-agent]\"\n );\n if (!existing) {\n if (href) {\n // ESM build - load CSS dynamically\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.setAttribute(\"data-vanilla-agent\", \"true\");\n document.head.appendChild(link);\n }\n // IIFE build - CSS should be loaded via <link> tag before script\n // If not found, we'll assume it's loaded globally or warn in dev\n }\n }\n};\n\nexport type AgentWidgetInitHandle = AgentWidgetController & { host: HTMLElement };\n\nexport const initAgentWidget = (\n options: AgentWidgetInitOptions\n): AgentWidgetInitHandle => {\n const target = ensureTarget(options.target);\n const host = document.createElement(\"div\");\n host.className = \"vanilla-agent-host\";\n \n // When launcher is disabled (inline embed mode), ensure the host fills its container\n const launcherEnabled = options.config?.launcher?.enabled ?? true;\n if (!launcherEnabled) {\n host.style.height = \"100%\";\n }\n \n target.appendChild(host);\n\n const useShadow = options.useShadowDom === true;\n let mount: HTMLElement;\n let root: ShadowRoot | HTMLElement;\n\n if (useShadow) {\n const shadowRoot = host.attachShadow({ mode: \"open\" });\n root = shadowRoot;\n mount = document.createElement(\"div\");\n mount.id = \"vanilla-agent-root\";\n // When launcher is disabled, ensure mount fills the host\n if (!launcherEnabled) {\n mount.style.height = \"100%\";\n mount.style.display = \"flex\";\n mount.style.flexDirection = \"column\";\n mount.style.flex = \"1\";\n mount.style.minHeight = \"0\";\n }\n shadowRoot.appendChild(mount);\n mountStyles(shadowRoot);\n } else {\n root = host;\n mount = document.createElement(\"div\");\n mount.id = \"vanilla-agent-root\";\n // When launcher is disabled, ensure mount fills the host\n if (!launcherEnabled) {\n mount.style.height = \"100%\";\n mount.style.display = \"flex\";\n mount.style.flexDirection = \"column\";\n mount.style.flex = \"1\";\n mount.style.minHeight = \"0\";\n }\n host.appendChild(mount);\n mountStyles(host);\n }\n\n let controller = createAgentExperience(mount, options.config, {\n debugTools: options.debugTools\n });\n options.onReady?.();\n\n const handle: AgentWidgetInitHandle = {\n ...controller,\n host,\n destroy() {\n controller.destroy();\n host.remove();\n if (options.windowKey && typeof window !== \"undefined\") {\n delete (window as any)[options.windowKey];\n }\n }\n };\n\n // Store on window if windowKey is provided\n if (options.windowKey && typeof window !== 'undefined') {\n (window as any)[options.windowKey] = handle;\n }\n\n return handle;\n};\n","import type { AgentWidgetConfig } from \"../types\";\n\ntype ParserType = \"plain\" | \"json\" | \"regex-json\" | \"xml\";\nexport type CodeFormat = \"esm\" | \"script-installer\" | \"script-manual\" | \"script-advanced\" | \"react-component\" | \"react-advanced\";\n\nfunction detectParserTypeFromStreamParser(streamParser: any): ParserType | null {\n if (!streamParser) return null;\n const fnString = streamParser.toString();\n if (fnString.includes(\"createJsonStreamParser\") || fnString.includes(\"partial-json\")) {\n return \"json\";\n }\n if (fnString.includes(\"createRegexJsonParser\") || fnString.includes(\"regex\")) {\n return \"regex-json\";\n }\n if (fnString.includes(\"createXmlParser\") || fnString.includes(\"<text>\")) {\n return \"xml\";\n }\n return null;\n}\n\nfunction getParserTypeFromConfig(config: AgentWidgetConfig): ParserType {\n return config.parserType ?? detectParserTypeFromStreamParser(config.streamParser) ?? \"plain\";\n}\n\n// Helper to generate toolCall config\nfunction generateToolCallConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.toolCall) {\n lines.push(`${indent}toolCall: {`);\n Object.entries(config.toolCall).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n }\n });\n lines.push(`${indent}},`);\n }\n return lines;\n}\n\n// Helper to generate messageActions config (excluding callbacks)\nfunction generateMessageActionsConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.messageActions) {\n const hasSerializableProps = Object.entries(config.messageActions).some(\n ([key, value]) => key !== \"onFeedback\" && key !== \"onCopy\" && value !== undefined\n );\n if (hasSerializableProps) {\n lines.push(`${indent}messageActions: {`);\n Object.entries(config.messageActions).forEach(([key, value]) => {\n // Skip function callbacks\n if (key === \"onFeedback\" || key === \"onCopy\") return;\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent}},`);\n }\n }\n return lines;\n}\n\n// Helper to generate markdown config (excluding renderer functions)\nfunction generateMarkdownConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.markdown) {\n const hasOptions = config.markdown.options && Object.keys(config.markdown.options).length > 0;\n const hasDisableDefaultStyles = config.markdown.disableDefaultStyles !== undefined;\n \n if (hasOptions || hasDisableDefaultStyles) {\n lines.push(`${indent}markdown: {`);\n \n if (hasOptions) {\n lines.push(`${indent} options: {`);\n Object.entries(config.markdown.options).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent} },`);\n }\n \n if (hasDisableDefaultStyles) {\n lines.push(`${indent} disableDefaultStyles: ${config.markdown.disableDefaultStyles},`);\n }\n \n lines.push(`${indent}},`);\n }\n }\n return lines;\n}\n\n// Helper to generate layout config (excluding render functions and slots)\nfunction generateLayoutConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.layout) {\n const hasHeader = config.layout.header && Object.keys(config.layout.header).some(\n (key: string) => key !== \"render\"\n );\n const hasMessages = config.layout.messages && Object.keys(config.layout.messages).some(\n (key: string) => key !== \"renderUserMessage\" && key !== \"renderAssistantMessage\"\n );\n \n if (hasHeader || hasMessages) {\n lines.push(`${indent}layout: {`);\n \n // Header config (excluding render function)\n if (hasHeader) {\n lines.push(`${indent} header: {`);\n Object.entries(config.layout.header).forEach(([key, value]) => {\n if (key === \"render\") return; // Skip render function\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent} },`);\n }\n \n // Messages config (excluding render functions)\n if (hasMessages) {\n lines.push(`${indent} messages: {`);\n Object.entries(config.layout.messages).forEach(([key, value]) => {\n // Skip render functions\n if (key === \"renderUserMessage\" || key === \"renderAssistantMessage\") return;\n \n if (key === \"avatar\" && typeof value === \"object\" && value !== null) {\n lines.push(`${indent} avatar: {`);\n Object.entries(value as Record<string, unknown>).forEach(([avatarKey, avatarValue]) => {\n if (typeof avatarValue === \"string\") {\n lines.push(`${indent} ${avatarKey}: \"${avatarValue}\",`);\n } else if (typeof avatarValue === \"boolean\") {\n lines.push(`${indent} ${avatarKey}: ${avatarValue},`);\n }\n });\n lines.push(`${indent} },`);\n } else if (key === \"timestamp\" && typeof value === \"object\" && value !== null) {\n // Only emit serializable timestamp properties (skip format function)\n const hasSerializableTimestamp = Object.entries(value as Record<string, unknown>).some(\n ([k]) => k !== \"format\"\n );\n if (hasSerializableTimestamp) {\n lines.push(`${indent} timestamp: {`);\n Object.entries(value as Record<string, unknown>).forEach(([tsKey, tsValue]) => {\n if (tsKey === \"format\") return; // Skip format function\n if (typeof tsValue === \"string\") {\n lines.push(`${indent} ${tsKey}: \"${tsValue}\",`);\n } else if (typeof tsValue === \"boolean\") {\n lines.push(`${indent} ${tsKey}: ${tsValue},`);\n }\n });\n lines.push(`${indent} },`);\n }\n } else if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent} },`);\n }\n \n lines.push(`${indent}},`);\n }\n }\n return lines;\n}\n\nexport function generateCodeSnippet(config: any, format: CodeFormat = \"esm\"): string {\n // Remove non-serializable properties\n const cleanConfig = { ...config };\n delete cleanConfig.postprocessMessage;\n delete cleanConfig.initialMessages;\n\n if (format === \"esm\") {\n return generateESMCode(cleanConfig);\n } else if (format === \"script-installer\") {\n return generateScriptInstallerCode(cleanConfig);\n } else if (format === \"script-advanced\") {\n return generateScriptAdvancedCode(cleanConfig);\n } else if (format === \"react-component\") {\n return generateReactComponentCode(cleanConfig);\n } else if (format === \"react-advanced\") {\n return generateReactAdvancedCode(cleanConfig);\n } else {\n return generateScriptManualCode(cleanConfig);\n }\n}\n\nfunction generateESMCode(config: any): string {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n \n const lines: string[] = [\n \"import 'vanilla-agent/widget.css';\",\n \"import { initAgentWidget, markdownPostprocessor } from 'vanilla-agent';\",\n \"\",\n \"initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n if (shouldEmitParserType) lines.push(` parserType: \"${parserType}\",`);\n\n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" postprocessMessage: ({ text }) => markdownPostprocessor(text)\");\n lines.push(\" }\");\n lines.push(\"});\");\n\n return lines.join(\"\\n\");\n}\n\nfunction generateReactComponentCode(config: any): string {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n \n const lines: string[] = [\n \"// ChatWidget.tsx\",\n \"'use client'; // Required for Next.js - remove for Vite/CRA\",\n \"\",\n \"import { useEffect } from 'react';\",\n \"import 'vanilla-agent/widget.css';\",\n \"import { initAgentWidget, markdownPostprocessor } from 'vanilla-agent';\",\n \"import type { AgentWidgetInitHandle } from 'vanilla-agent';\",\n \"\",\n \"export function ChatWidget() {\",\n \" useEffect(() => {\",\n \" let handle: AgentWidgetInitHandle | null = null;\",\n \"\",\n \" handle = initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n if (shouldEmitParserType) lines.push(` parserType: \"${parserType}\",`);\n\n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" postprocessMessage: ({ text }) => markdownPostprocessor(text)\");\n lines.push(\" }\");\n lines.push(\" });\");\n lines.push(\"\");\n lines.push(\" // Cleanup on unmount\");\n lines.push(\" return () => {\");\n lines.push(\" if (handle) {\");\n lines.push(\" handle.destroy();\");\n lines.push(\" }\");\n lines.push(\" };\");\n lines.push(\" }, []);\");\n lines.push(\"\");\n lines.push(\" return null; // Widget injects itself into the DOM\");\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"// Usage in your app:\");\n lines.push(\"// import { ChatWidget } from './components/ChatWidget';\");\n lines.push(\"//\");\n lines.push(\"// export default function App() {\");\n lines.push(\"// return (\");\n lines.push(\"// <div>\");\n lines.push(\"// {/* Your app content */}\");\n lines.push(\"// <ChatWidget />\");\n lines.push(\"// </div>\");\n lines.push(\"// );\");\n lines.push(\"// }\");\n\n return lines.join(\"\\n\");\n}\n\nfunction generateReactAdvancedCode(config: any): string {\n const lines: string[] = [\n \"// ChatWidgetAdvanced.tsx\",\n \"'use client'; // Required for Next.js - remove for Vite/CRA\",\n \"\",\n \"import { useEffect } from 'react';\",\n \"import 'vanilla-agent/widget.css';\",\n \"import {\",\n \" initAgentWidget,\",\n \" createFlexibleJsonStreamParser,\",\n \" defaultJsonActionParser,\",\n \" defaultActionHandlers,\",\n \" markdownPostprocessor\",\n \"} from 'vanilla-agent';\",\n \"import type { AgentWidgetInitHandle } from 'vanilla-agent';\",\n \"\",\n \"const STORAGE_KEY = 'chat-widget-state';\",\n \"const PROCESSED_ACTIONS_KEY = 'chat-widget-processed-actions';\",\n \"\",\n \"// Types for DOM elements\",\n \"interface PageElement {\",\n \" type: string;\",\n \" tagName: string;\",\n \" selector: string;\",\n \" innerText: string;\",\n \" href?: string;\",\n \"}\",\n \"\",\n \"interface DOMContext {\",\n \" page_elements: PageElement[];\",\n \" page_element_count: number;\",\n \" element_types: Record<string, number>;\",\n \" page_url: string;\",\n \" page_title: string;\",\n \" timestamp: string;\",\n \"}\",\n \"\",\n \"// DOM context provider - extracts page elements for AI context\",\n \"const collectDOMContext = (): DOMContext => {\",\n \" const selectors = {\",\n \" products: '[data-product-id], .product-card, .product-item, [role=\\\"article\\\"]',\",\n \" buttons: 'button, [role=\\\"button\\\"], .btn',\",\n \" links: 'a[href]',\",\n \" inputs: 'input, textarea, select'\",\n \" };\",\n \"\",\n \" const elements: PageElement[] = [];\",\n \" Object.entries(selectors).forEach(([type, selector]) => {\",\n \" document.querySelectorAll(selector).forEach((element) => {\",\n \" if (!(element instanceof HTMLElement)) return;\",\n \" \",\n \" // Exclude elements within the widget\",\n \" const widgetHost = element.closest('.vanilla-agent-host');\",\n \" if (widgetHost) return;\",\n \" \",\n \" const text = element.innerText?.trim();\",\n \" if (!text) return;\",\n \"\",\n \" const selectorString =\",\n \" element.id ? `#${element.id}` :\",\n \" element.getAttribute('data-testid') ? `[data-testid=\\\"${element.getAttribute('data-testid')}\\\"]` :\",\n \" element.getAttribute('data-product-id') ? `[data-product-id=\\\"${element.getAttribute('data-product-id')}\\\"]` :\",\n \" element.tagName.toLowerCase();\",\n \"\",\n \" const elementData: PageElement = {\",\n \" type,\",\n \" tagName: element.tagName.toLowerCase(),\",\n \" selector: selectorString,\",\n \" innerText: text.substring(0, 200)\",\n \" };\",\n \"\",\n \" if (type === 'links' && element instanceof HTMLAnchorElement && element.href) {\",\n \" elementData.href = element.href;\",\n \" }\",\n \"\",\n \" elements.push(elementData);\",\n \" });\",\n \" });\",\n \"\",\n \" const counts = elements.reduce((acc, el) => {\",\n \" acc[el.type] = (acc[el.type] || 0) + 1;\",\n \" return acc;\",\n \" }, {} as Record<string, number>);\",\n \"\",\n \" return {\",\n \" page_elements: elements.slice(0, 50),\",\n \" page_element_count: elements.length,\",\n \" element_types: counts,\",\n \" page_url: window.location.href,\",\n \" page_title: document.title,\",\n \" timestamp: new Date().toISOString()\",\n \" };\",\n \"};\",\n \"\",\n \"export function ChatWidgetAdvanced() {\",\n \" useEffect(() => {\",\n \" let handle: AgentWidgetInitHandle | null = null;\",\n \"\",\n \" // Load saved state\",\n \" const loadSavedMessages = () => {\",\n \" const savedState = localStorage.getItem(STORAGE_KEY);\",\n \" if (savedState) {\",\n \" try {\",\n \" const { messages } = JSON.parse(savedState);\",\n \" return messages || [];\",\n \" } catch (e) {\",\n \" console.error('Failed to load saved state:', e);\",\n \" }\",\n \" }\",\n \" return [];\",\n \" };\",\n \"\",\n \" handle = initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n \n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" initialMessages: loadSavedMessages(),\");\n lines.push(\" // Flexible JSON stream parser for handling structured actions\");\n lines.push(\" streamParser: () => createFlexibleJsonStreamParser((parsed: any) => {\");\n lines.push(\" if (!parsed || typeof parsed !== 'object') return null;\");\n lines.push(\" // Extract display text based on action type\");\n lines.push(\" if (parsed.action === 'nav_then_click') return 'Navigating...';\");\n lines.push(\" if (parsed.action === 'message') return parsed.text || '';\");\n lines.push(\" if (parsed.action === 'message_and_click') return parsed.text || 'Processing...';\");\n lines.push(\" return parsed.text || null;\");\n lines.push(\" }),\");\n lines.push(\" // Action parsers to detect JSON actions in responses\");\n lines.push(\" actionParsers: [\");\n lines.push(\" defaultJsonActionParser,\");\n lines.push(\" // Custom parser for markdown-wrapped JSON\");\n lines.push(\" ({ text, message }: any) => {\");\n lines.push(\" const jsonSource = (message as any).rawContent || text || message.content;\");\n lines.push(\" if (!jsonSource || typeof jsonSource !== 'string') return null;\");\n lines.push(\" // Strip markdown code fences\");\n lines.push(\" let cleanJson = jsonSource\");\n lines.push(\" .replace(/^```(?:json)?\\\\s*\\\\n?/, '')\");\n lines.push(\" .replace(/\\\\n?```\\\\s*$/, '')\");\n lines.push(\" .trim();\");\n lines.push(\" if (!cleanJson.startsWith('{') || !cleanJson.endsWith('}')) return null;\");\n lines.push(\" try {\");\n lines.push(\" const parsed = JSON.parse(cleanJson);\");\n lines.push(\" if (parsed.action) return { type: parsed.action, payload: parsed };\");\n lines.push(\" } catch (e) { return null; }\");\n lines.push(\" return null;\");\n lines.push(\" }\");\n lines.push(\" ],\");\n lines.push(\" // Action handlers for navigation and other actions\");\n lines.push(\" actionHandlers: [\");\n lines.push(\" defaultActionHandlers.message,\");\n lines.push(\" defaultActionHandlers.messageAndClick,\");\n lines.push(\" // Handler for nav_then_click action\");\n lines.push(\" (action: any, context: any) => {\");\n lines.push(\" if (action.type !== 'nav_then_click') return;\");\n lines.push(\" const payload = action.payload || action.raw || {};\");\n lines.push(\" const url = payload?.page;\");\n lines.push(\" const text = payload?.on_load_text || 'Navigating...';\");\n lines.push(\" if (!url) return { handled: true, displayText: text };\");\n lines.push(\" // Check if already processed\");\n lines.push(\" const messageId = context.message?.id;\");\n lines.push(\" const processedActions = JSON.parse(localStorage.getItem(PROCESSED_ACTIONS_KEY) || '[]');\");\n lines.push(\" const actionKey = `nav_${messageId}_${url}`;\");\n lines.push(\" if (processedActions.includes(actionKey)) {\");\n lines.push(\" return { handled: true, displayText: text };\");\n lines.push(\" }\");\n lines.push(\" processedActions.push(actionKey);\");\n lines.push(\" localStorage.setItem(PROCESSED_ACTIONS_KEY, JSON.stringify(processedActions));\");\n lines.push(\" const targetUrl = url.startsWith('http') ? url : new URL(url, window.location.origin).toString();\");\n lines.push(\" window.location.href = targetUrl;\");\n lines.push(\" return { handled: true, displayText: text };\");\n lines.push(\" }\");\n lines.push(\" ],\");\n lines.push(\" postprocessMessage: ({ text }) => markdownPostprocessor(text),\");\n lines.push(\" requestMiddleware: ({ payload }) => {\");\n lines.push(\" return {\");\n lines.push(\" ...payload,\");\n lines.push(\" metadata: collectDOMContext()\");\n lines.push(\" };\");\n lines.push(\" }\");\n lines.push(\" }\");\n lines.push(\" });\");\n lines.push(\"\");\n lines.push(\" // Save state on message events\");\n lines.push(\" const handleMessage = () => {\");\n lines.push(\" const session = handle?.getSession?.();\");\n lines.push(\" if (session) {\");\n lines.push(\" localStorage.setItem(STORAGE_KEY, JSON.stringify({\");\n lines.push(\" messages: session.messages,\");\n lines.push(\" timestamp: new Date().toISOString()\");\n lines.push(\" }));\");\n lines.push(\" }\");\n lines.push(\" };\");\n lines.push(\"\");\n lines.push(\" // Clear state on clear chat\");\n lines.push(\" const handleClearChat = () => {\");\n lines.push(\" localStorage.removeItem(STORAGE_KEY);\");\n lines.push(\" localStorage.removeItem(PROCESSED_ACTIONS_KEY);\");\n lines.push(\" };\");\n lines.push(\"\");\n lines.push(\" window.addEventListener('vanilla-agent:message', handleMessage);\");\n lines.push(\" window.addEventListener('vanilla-agent:clear-chat', handleClearChat);\");\n lines.push(\"\");\n lines.push(\" // Cleanup on unmount\");\n lines.push(\" return () => {\");\n lines.push(\" window.removeEventListener('vanilla-agent:message', handleMessage);\");\n lines.push(\" window.removeEventListener('vanilla-agent:clear-chat', handleClearChat);\");\n lines.push(\" if (handle) {\");\n lines.push(\" handle.destroy();\");\n lines.push(\" }\");\n lines.push(\" };\");\n lines.push(\" }, []);\");\n lines.push(\"\");\n lines.push(\" return null; // Widget injects itself into the DOM\");\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"// Usage: Collects DOM context for AI-powered navigation\");\n lines.push(\"// Features:\");\n lines.push(\"// - Extracts page elements (products, buttons, links)\");\n lines.push(\"// - Persists chat history across page loads\");\n lines.push(\"// - Handles navigation actions (nav_then_click)\");\n lines.push(\"// - Processes structured JSON actions from AI\");\n lines.push(\"//\");\n lines.push(\"// Example usage in Next.js:\");\n lines.push(\"// import { ChatWidgetAdvanced } from './components/ChatWidgetAdvanced';\");\n lines.push(\"//\");\n lines.push(\"// export default function RootLayout({ children }) {\");\n lines.push(\"// return (\");\n lines.push(\"// <html lang=\\\"en\\\">\");\n lines.push(\"// <body>\");\n lines.push(\"// {children}\");\n lines.push(\"// <ChatWidgetAdvanced />\");\n lines.push(\"// </body>\");\n lines.push(\"// </html>\");\n lines.push(\"// );\");\n lines.push(\"// }\");\n\n return lines.join(\"\\n\");\n}\n\n// Helper to build a serializable config object for JSON export\nfunction buildSerializableConfig(config: any): Record<string, any> {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n \n const serializableConfig: Record<string, any> = {};\n \n if (config.apiUrl) serializableConfig.apiUrl = config.apiUrl;\n if (config.flowId) serializableConfig.flowId = config.flowId;\n if (shouldEmitParserType) serializableConfig.parserType = parserType;\n if (config.theme) serializableConfig.theme = config.theme;\n if (config.launcher) serializableConfig.launcher = config.launcher;\n if (config.copy) serializableConfig.copy = config.copy;\n if (config.sendButton) serializableConfig.sendButton = config.sendButton;\n if (config.voiceRecognition) serializableConfig.voiceRecognition = config.voiceRecognition;\n if (config.statusIndicator) serializableConfig.statusIndicator = config.statusIndicator;\n if (config.features) serializableConfig.features = config.features;\n if (config.suggestionChips?.length > 0) serializableConfig.suggestionChips = config.suggestionChips;\n if (config.suggestionChipsConfig) serializableConfig.suggestionChipsConfig = config.suggestionChipsConfig;\n if (config.debug) serializableConfig.debug = config.debug;\n \n // Add toolCall config (only serializable parts)\n if (config.toolCall) {\n const toolCallConfig: Record<string, any> = {};\n Object.entries(config.toolCall).forEach(([key, value]) => {\n if (typeof value === \"string\") toolCallConfig[key] = value;\n });\n if (Object.keys(toolCallConfig).length > 0) {\n serializableConfig.toolCall = toolCallConfig;\n }\n }\n \n // Add messageActions config (excluding callbacks)\n if (config.messageActions) {\n const messageActionsConfig: Record<string, any> = {};\n Object.entries(config.messageActions).forEach(([key, value]) => {\n if (key !== \"onFeedback\" && key !== \"onCopy\" && value !== undefined) {\n if (typeof value === \"string\" || typeof value === \"boolean\") {\n messageActionsConfig[key] = value;\n }\n }\n });\n if (Object.keys(messageActionsConfig).length > 0) {\n serializableConfig.messageActions = messageActionsConfig;\n }\n }\n \n // Add markdown config (excluding renderer functions)\n if (config.markdown) {\n const markdownConfig: Record<string, any> = {};\n if (config.markdown.options) markdownConfig.options = config.markdown.options;\n if (config.markdown.disableDefaultStyles !== undefined) {\n markdownConfig.disableDefaultStyles = config.markdown.disableDefaultStyles;\n }\n if (Object.keys(markdownConfig).length > 0) {\n serializableConfig.markdown = markdownConfig;\n }\n }\n \n // Add layout config (excluding render functions)\n if (config.layout) {\n const layoutConfig: Record<string, any> = {};\n \n if (config.layout.header) {\n const headerConfig: Record<string, any> = {};\n Object.entries(config.layout.header).forEach(([key, value]) => {\n if (key !== \"render\" && (typeof value === \"string\" || typeof value === \"boolean\")) {\n headerConfig[key] = value;\n }\n });\n if (Object.keys(headerConfig).length > 0) {\n layoutConfig.header = headerConfig;\n }\n }\n \n if (config.layout.messages) {\n const messagesConfig: Record<string, any> = {};\n Object.entries(config.layout.messages).forEach(([key, value]) => {\n if (key !== \"renderUserMessage\" && key !== \"renderAssistantMessage\") {\n if (key === \"avatar\" && typeof value === \"object\" && value !== null) {\n messagesConfig.avatar = value;\n } else if (key === \"timestamp\" && typeof value === \"object\" && value !== null) {\n // Exclude format function\n const tsConfig: Record<string, any> = {};\n Object.entries(value as Record<string, unknown>).forEach(([tsKey, tsValue]) => {\n if (tsKey !== \"format\" && (typeof tsValue === \"string\" || typeof tsValue === \"boolean\")) {\n tsConfig[tsKey] = tsValue;\n }\n });\n if (Object.keys(tsConfig).length > 0) {\n messagesConfig.timestamp = tsConfig;\n }\n } else if (typeof value === \"string\" || typeof value === \"boolean\") {\n messagesConfig[key] = value;\n }\n }\n });\n if (Object.keys(messagesConfig).length > 0) {\n layoutConfig.messages = messagesConfig;\n }\n }\n \n if (Object.keys(layoutConfig).length > 0) {\n serializableConfig.layout = layoutConfig;\n }\n }\n \n return serializableConfig;\n}\n\nfunction generateScriptInstallerCode(config: any): string {\n const serializableConfig = buildSerializableConfig(config);\n \n // Escape single quotes in JSON for HTML attribute\n const configJson = JSON.stringify(serializableConfig, null, 0).replace(/'/g, \"'\");\n \n return `<script src=\"https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist/install.global.js\" data-config='${configJson}'></script>`;\n}\n\nfunction generateScriptManualCode(config: any): string {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n\n const lines: string[] = [\n \"<!-- Load CSS -->\",\n \"<link rel=\\\"stylesheet\\\" href=\\\"https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist/widget.css\\\" />\",\n \"\",\n \"<!-- Load JavaScript -->\",\n \"<script src=\\\"https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist/index.global.js\\\"></script>\",\n \"\",\n \"<!-- Initialize widget -->\",\n \"<script>\",\n \" window.AgentWidget.initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n if (shouldEmitParserType) lines.push(` parserType: \"${parserType}\",`);\n\n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" postprocessMessage: ({ text }) => window.AgentWidget.markdownPostprocessor(text)\");\n lines.push(\" }\");\n lines.push(\" });\");\n lines.push(\"</script>\");\n\n return lines.join(\"\\n\");\n}\n\nfunction generateScriptAdvancedCode(config: any): string {\n const serializableConfig = buildSerializableConfig(config);\n const configJson = JSON.stringify(serializableConfig, null, 2);\n \n const lines: string[] = [\n \"<script>\",\n \"(function() {\",\n \" 'use strict';\",\n \"\",\n \" // Configuration\",\n ` var CONFIG = ${configJson.split('\\n').map((line, i) => i === 0 ? line : ' ' + line).join('\\n')};`,\n \"\",\n \" // Constants\",\n \" var CDN_BASE = 'https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist';\",\n \" var STORAGE_KEY = 'chat-widget-state';\",\n \" var PROCESSED_ACTIONS_KEY = 'chat-widget-processed-actions';\",\n \"\",\n \" // DOM context provider - extracts page elements for AI context\",\n \" var domContextProvider = function() {\",\n \" var selectors = {\",\n \" products: '[data-product-id], .product-card, .product-item, [role=\\\"article\\\"]',\",\n \" buttons: 'button, [role=\\\"button\\\"], .btn',\",\n \" links: 'a[href]',\",\n \" inputs: 'input, textarea, select'\",\n \" };\",\n \"\",\n \" var elements = [];\",\n \" Object.entries(selectors).forEach(function(entry) {\",\n \" var type = entry[0], selector = entry[1];\",\n \" document.querySelectorAll(selector).forEach(function(element) {\",\n \" if (!(element instanceof HTMLElement)) return;\",\n \" var widgetHost = element.closest('.vanilla-agent-host');\",\n \" if (widgetHost) return;\",\n \" var text = element.innerText ? element.innerText.trim() : '';\",\n \" if (!text) return;\",\n \"\",\n \" var selectorString = element.id ? '#' + element.id :\",\n \" element.getAttribute('data-testid') ? '[data-testid=\\\"' + element.getAttribute('data-testid') + '\\\"]' :\",\n \" element.getAttribute('data-product-id') ? '[data-product-id=\\\"' + element.getAttribute('data-product-id') + '\\\"]' :\",\n \" element.tagName.toLowerCase();\",\n \"\",\n \" var elementData = {\",\n \" type: type,\",\n \" tagName: element.tagName.toLowerCase(),\",\n \" selector: selectorString,\",\n \" innerText: text.substring(0, 200)\",\n \" };\",\n \"\",\n \" if (type === 'links' && element instanceof HTMLAnchorElement && element.href) {\",\n \" elementData.href = element.href;\",\n \" }\",\n \" elements.push(elementData);\",\n \" });\",\n \" });\",\n \"\",\n \" var counts = elements.reduce(function(acc, el) {\",\n \" acc[el.type] = (acc[el.type] || 0) + 1;\",\n \" return acc;\",\n \" }, {});\",\n \"\",\n \" return {\",\n \" page_elements: elements.slice(0, 50),\",\n \" page_element_count: elements.length,\",\n \" element_types: counts,\",\n \" page_url: window.location.href,\",\n \" page_title: document.title,\",\n \" timestamp: new Date().toISOString()\",\n \" };\",\n \" };\",\n \"\",\n \" // Load CSS dynamically\",\n \" var loadCSS = function() {\",\n \" if (document.querySelector('link[data-vanilla-agent]')) return;\",\n \" var link = document.createElement('link');\",\n \" link.rel = 'stylesheet';\",\n \" link.href = CDN_BASE + '/widget.css';\",\n \" link.setAttribute('data-vanilla-agent', 'true');\",\n \" document.head.appendChild(link);\",\n \" };\",\n \"\",\n \" // Load JS dynamically\",\n \" var loadJS = function(callback) {\",\n \" if (window.AgentWidget) { callback(); return; }\",\n \" var script = document.createElement('script');\",\n \" script.src = CDN_BASE + '/index.global.js';\",\n \" script.onload = callback;\",\n \" script.onerror = function() { console.error('Failed to load AgentWidget'); };\",\n \" document.head.appendChild(script);\",\n \" };\",\n \"\",\n \" // Create widget config with advanced features\",\n \" var createWidgetConfig = function(agentWidget) {\",\n \" var widgetConfig = Object.assign({}, CONFIG);\",\n \"\",\n \" // Flexible JSON stream parser for handling structured actions\",\n \" widgetConfig.streamParser = function() {\",\n \" return agentWidget.createFlexibleJsonStreamParser(function(parsed) {\",\n \" if (!parsed || typeof parsed !== 'object') return null;\",\n \" if (parsed.action === 'nav_then_click') return 'Navigating...';\",\n \" if (parsed.action === 'message') return parsed.text || '';\",\n \" if (parsed.action === 'message_and_click') return parsed.text || 'Processing...';\",\n \" return parsed.text || null;\",\n \" });\",\n \" };\",\n \"\",\n \" // Action parsers to detect JSON actions in responses\",\n \" widgetConfig.actionParsers = [\",\n \" agentWidget.defaultJsonActionParser,\",\n \" function(ctx) {\",\n \" var jsonSource = ctx.message.rawContent || ctx.text || ctx.message.content;\",\n \" if (!jsonSource || typeof jsonSource !== 'string') return null;\",\n \" var cleanJson = jsonSource\",\n \" .replace(/^```(?:json)?\\\\s*\\\\n?/, '')\",\n \" .replace(/\\\\n?```\\\\s*$/, '')\",\n \" .trim();\",\n \" if (!cleanJson.startsWith('{') || !cleanJson.endsWith('}')) return null;\",\n \" try {\",\n \" var parsed = JSON.parse(cleanJson);\",\n \" if (parsed.action) return { type: parsed.action, payload: parsed };\",\n \" } catch (e) { return null; }\",\n \" return null;\",\n \" }\",\n \" ];\",\n \"\",\n \" // Action handlers for navigation and other actions\",\n \" widgetConfig.actionHandlers = [\",\n \" agentWidget.defaultActionHandlers.message,\",\n \" agentWidget.defaultActionHandlers.messageAndClick,\",\n \" function(action, context) {\",\n \" if (action.type !== 'nav_then_click') return;\",\n \" var payload = action.payload || action.raw || {};\",\n \" var url = payload.page;\",\n \" var text = payload.on_load_text || 'Navigating...';\",\n \" if (!url) return { handled: true, displayText: text };\",\n \" var messageId = context.message ? context.message.id : null;\",\n \" var processedActions = JSON.parse(localStorage.getItem(PROCESSED_ACTIONS_KEY) || '[]');\",\n \" var actionKey = 'nav_' + messageId + '_' + url;\",\n \" if (processedActions.includes(actionKey)) {\",\n \" return { handled: true, displayText: text };\",\n \" }\",\n \" processedActions.push(actionKey);\",\n \" localStorage.setItem(PROCESSED_ACTIONS_KEY, JSON.stringify(processedActions));\",\n \" var targetUrl = url.startsWith('http') ? url : new URL(url, window.location.origin).toString();\",\n \" window.location.href = targetUrl;\",\n \" return { handled: true, displayText: text };\",\n \" }\",\n \" ];\",\n \"\",\n \" // Send DOM context with each request\",\n \" widgetConfig.requestMiddleware = function(ctx) {\",\n \" return Object.assign({}, ctx.payload, { metadata: domContextProvider() });\",\n \" };\",\n \"\",\n \" // Markdown postprocessor\",\n \" widgetConfig.postprocessMessage = function(ctx) {\",\n \" return agentWidget.markdownPostprocessor(ctx.text);\",\n \" };\",\n \"\",\n \" return widgetConfig;\",\n \" };\",\n \"\",\n \" // Initialize widget\",\n \" var init = function() {\",\n \" var agentWidget = window.AgentWidget;\",\n \" if (!agentWidget) {\",\n \" console.error('AgentWidget not loaded');\",\n \" return;\",\n \" }\",\n \"\",\n \" var widgetConfig = createWidgetConfig(agentWidget);\",\n \"\",\n \" // Load saved state\",\n \" var savedState = localStorage.getItem(STORAGE_KEY);\",\n \" if (savedState) {\",\n \" try {\",\n \" var parsed = JSON.parse(savedState);\",\n \" widgetConfig.initialMessages = parsed.messages || [];\",\n \" } catch (e) {\",\n \" console.error('Failed to load saved state:', e);\",\n \" }\",\n \" }\",\n \"\",\n \" // Initialize widget\",\n \" var handle = agentWidget.initAgentWidget({\",\n \" target: 'body',\",\n \" useShadowDom: false,\",\n \" config: widgetConfig\",\n \" });\",\n \"\",\n \" // Save state on message events\",\n \" window.addEventListener('vanilla-agent:message', function() {\",\n \" var session = handle.getSession ? handle.getSession() : null;\",\n \" if (session) {\",\n \" localStorage.setItem(STORAGE_KEY, JSON.stringify({\",\n \" messages: session.messages,\",\n \" timestamp: new Date().toISOString()\",\n \" }));\",\n \" }\",\n \" });\",\n \"\",\n \" // Clear state on clear chat\",\n \" window.addEventListener('vanilla-agent:clear-chat', function() {\",\n \" localStorage.removeItem(STORAGE_KEY);\",\n \" localStorage.removeItem(PROCESSED_ACTIONS_KEY);\",\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 \" var waitForHydration = function(callback) {\",\n \" var executed = false;\",\n \" \",\n \" var execute = function() {\",\n \" if (executed) return;\",\n \" executed = true;\",\n \" callback();\",\n \" };\",\n \"\",\n \" var afterDom = function() {\",\n \" // Strategy 1: Use requestIdleCallback if available (best for detecting idle after hydration)\",\n \" if (typeof requestIdleCallback !== 'undefined') {\",\n \" requestIdleCallback(function() {\",\n \" // Double requestAnimationFrame ensures at least one full paint cycle completed\",\n \" requestAnimationFrame(function() {\",\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 \" // Boot sequence: wait for hydration, then load CSS and JS, then initialize\",\n \" // This prevents Next.js/Nuxt/etc. from removing dynamically added CSS during reconciliation\",\n \" waitForHydration(function() {\",\n \" loadCSS();\",\n \" loadJS(function() {\",\n \" init();\",\n \" });\",\n \" });\",\n \"})();\",\n \"</script>\"\n ];\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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AK,oCAAoC,EAC/CA,EAAM,KAAK,eAAe,EAC1BA,EAAM,KAAK,cAAc,EACzBA,EAAM,KAAK,mCAAmC,EAC9CA,EAAM,KAAK,yBAAyB,EACpCA,EAAM,KAAK,eAAe,EAC1BA,EAAM,KAAK,SAAS,EACpBA,EAAM,KAAK,MAAM,EAEVA,EAAM,KAAK;AAAA,CAAI,CACxB,CAEA,SAASsB,GAA0B3B,EAAqB,CACtD,IAAMK,EAAkB,CACtB,4BACA,8DACA,GACA,qCACA,qCACA,WACA,qBACA,oCACA,6BACA,2BACA,0BACA,0BACA,8DACA,GACA,2CACA,iEACA,GACA,4BACA,0BACA,kBACA,qBACA,sBACA,uBACA,mBACA,IACA,GACA,yBACA,kCACA,gCACA,2CACA,sBACA,wBACA,uBACA,IACA,GACA,kEACA,gDACA,wBACA,qFACA,gDACA,wBACA,wCACA,OACA,GACA,wCACA,8DACA,iEACA,uDACA,SACA,8CACA,mEACA,gCACA,SACA,gDACA,2BACA,GACA,+BACA,0CACA,6GACA,yHACA,yCACA,GACA,2CACA,gBACA,kDACA,oCACA,4CACA,WACA,GACA,wFACA,2CACA,UACA,GACA,oCACA,UACA,QACA,GACA,kDACA,8CACA,kBACA,sCACA,GACA,aACA,4CACA,2CACA,6BACA,sCACA,kCACA,0CACA,OACA,KACA,GACA,yCACA,sBACA,uDACA,GACA,0BACA,wCACA,8DACA,0BACA,gBACA,yDACA,mCACA,wBACA,6DACA,YACA,UACA,mBACA,SACA,GACA,iCACA,wBACA,iBACF,EAEA,OAAIL,EAAO,QAAQK,EAAM,KAAK,oBAAoBL,EAAO,MAAM,IAAI,EAC/DA,EAAO,QAAQK,EAAM,KAAK,oBAAoBL,EAAO,MAAM,IAAI,EAE/DA,EAAO,QACTK,EAAM,KAAK,kBAAkB,EAC7B,OAAO,QAAQL,EAAO,KAAK,EAAE,QAAQ,CAAC,CAACM,EAAKC,CAAK,IAAM,CACrDF,EAAM,KAAK,aAAaC,CAAG,MAAMC,CAAK,IAAI,CAC5C,CAAC,EACDF,EAAM,KAAK,YAAY,GAGrBL,EAAO,WACTK,EAAM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FACA,yCACA,OACA,GACA,mDACA,qDACA,oDACA,GACA,qEACA,+CACA,6EACA,kEACA,0EACA,qEACA,4FACA,sCACA,YACA,SACA,GACA,4DACA,qCACA,6CACA,wBACA,sFACA,0EACA,qCACA,kDACA,yCACA,qBACA,mFACA,gBACA,gDACA,gFACA,uCACA,uBACA,UACA,SACA,GACA,0DACA,sCACA,mDACA,2DACA,oCACA,wDACA,4DACA,kCACA,8DACA,iEACA,uEACA,kGACA,0DACA,sDACA,yDACA,YACA,4CACA,yFACA,0GACA,4CACA,uDACA,UACA,SACA,GACA,4CACA,uDACA,mFACA,SACA,GACA,gCACA,wDACA,4DACA,SACA,GACA,2BACA,OACA,GACA,yBACA,4BACA,4CACA,0BACA,iDACA,gBACA,QACA,GACA,0DACA,GACA,0BACA,0DACA,wBACA,cACA,+CACA,gEACA,sBACA,2DACA,UACA,QACA,GACA,2BACA,iDACA,wBACA,6BACA,6BACA,UACA,GACA,sCACA,oEACA,sEACA,uBACA,6DACA,wCACA,gDACA,eACA,UACA,UACA,GACA,mCACA,uEACA,8CACA,wDACA,UACA,OACA,GACA,sEACA,6FACA,gDACA,4BACA,OACA,iCACA,8BACA,yBACA,oBACA,SACA,GACA,kCACA,sGACA,0DACA,2CACA,4FACA,+CACA,8CACA,gBACA,4EACA,iBACA,sEACA,mEACA,oCACA,UACA,SACA,GACA,+CACA,iEACA,eACA,qEACA,oBACA,QACA,OACA,GACA,gFACA,iGACA,kCACA,iBACA,0BACA,gBACA,UACA,QACA,QACA,WACF,EAEa,KAAK;AAAA,CAAI,CACxB,ChC5sCA,IAAOE,GAAQC","names":["index_exports","__export","AgentWidgetClient","AgentWidgetSession","DEFAULT_DARK_THEME","DEFAULT_LIGHT_THEME","DEFAULT_WIDGET_CONFIG","attachHeaderToContainer","buildComposer","buildDefaultHeader","buildExpandedHeader","buildHeader","buildHeaderWithLayout","buildMinimalHeader","componentRegistry","createActionManager","createAgentExperience","createBubbleWithLayout","createCSATFeedback","createComponentMiddleware","createComponentStreamParser","createDirectivePostprocessor","createFlexibleJsonStreamParser","createJsonStreamParser","createLocalStorageAdapter","createMarkdownProcessor","createMarkdownProcessorFromConfig","createMessageActions","createNPSFeedback","createPlainTextParser","createRegexJsonParser","createStandardBubble","createTypingIndicator","createXmlParser","index_default","defaultActionHandlers","defaultJsonActionParser","directivePostprocessor","escapeHtml","extractComponentDirectiveFromMessage","generateAssistantMessageId","generateCodeSnippet","generateMessageId","generateUserMessageId","getHeaderLayout","hasComponentDirective","headerLayouts","initAgentWidget","isComponentDirectiveType","markdownPostprocessor","mergeWithDefaults","pluginRegistry","renderComponentDirective","__toCommonJS","import_marked","convertRendererOverrides","overrides","createMarkdownProcessor","options","_a","_b","opts","markedInstance","rendererOverrides","text","createMarkdownProcessorFromConfig","config","defaultMarkdownProcessor","markdownPostprocessor","escapeHtml","escapeAttribute","value","makeToken","idx","directiveReplacer","source","placeholders","working","match","jsonText","parsed","token","_","type","createDirectivePostprocessor","markdownConfig","processor","withTokens","html","tokenRegex","replacement","directivePostprocessor","import_partial_json","unescapeJsonString","str","formatUnknownValue","value","formatReasoningDuration","reasoning","_a","_b","end","start","seconds","describeReasonStatus","formatToolDuration","tool","_c","describeToolTitle","tool","formatToolDuration","createRegexJsonParserInternal","extractedText","processedLength","extractTextFromIncompleteJson","jsonString","textFieldRegex","match","incompleteTextFieldRegex","incompleteMatch","accumulatedContent","trimmed","extracted","extractTextFromJson","parsed","createPlainTextParser","parser","createRegexJsonParser","_a","regexParser","createJsonStreamParser","parsePartialJson","unescapeJsonString","createFlexibleJsonStreamParser","textExtractor","extractText","getText","value","newText","createXmlParser","DEFAULT_ENDPOINT","DEFAULT_CLIENT_API_BASE","getParserFromType","parserType","createJsonStreamParser","createRegexJsonParser","createXmlParser","createPlainTextParser","AgentWidgetClient","config","_a","_b","_c","endpoint","baseUrl","session","response","error","data","feedback","errorData","messageId","type","rating","comment","options","onEvent","_d","controller","basePayload","chatRequest","m","err","payload","headers","dynamicHeaders","messages","a","b","timeA","timeB","message","contextAggregate","provider","result","assistantMessageRef","emitMessage","nextSequence","ensureAssistant","msg","assistant","body","assistantMessageId","_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","_D","_E","_F","_G","_H","_I","_J","_K","_L","_M","_N","_O","_P","_Q","_R","_S","_T","_U","_V","_W","_X","_Y","_Z","__","_$","_aa","_ba","reader","decoder","buffer","baseSequence","sequenceCounter","cloneMessage","reasoning","toolCall","tools","tool","assistantMessage","reasoningMessages","toolMessages","reasoningContext","toolContext","normalizeKey","value","getStepKey","getToolCallKey","ensureAssistantMessage","trackReasoningId","stepKey","id","resolveReasoningId","allowCreate","rawId","resolved","existing","generated","ensureReasoningMessage","reasoningId","trackToolId","callKey","resolveToolId","ensureToolMessage","toolId","resolveTimestamp","parsed","dateParsed","ensureStringContent","streamParsers","rawContentBuffers","done","events","event","lines","eventType","line","payloadType","handled","reasoningMessage","chunk","start","toolMessage","chunkText","stepType","executionType","accumulatedRaw","parser","looksLikeJson","parsedResult","text","currentAssistant","finalContent","rawBuffer","contentToProcess","extractedText","asyncPending","extractTextFromJson","parserToClose","closeResult","hasExtractedText","currentExtractedText","finalExtractedText","stringContent","displayContent","currentText","contentChanged","streamingChanged","generateMessageId","timestamp","random","generateUserMessageId","generateAssistantMessageId","AgentWidgetSession","config","callbacks","event","_a","_b","message","AgentWidgetClient","session","error","welcomeMessage","messageId","type","rating","comment","next","rawInput","options","_c","_d","_e","input","userMessageId","generateUserMessageId","assistantMessageId","generateAssistantMessageId","userMessage","controller","snapshot","fallback","messages","status","streaming","withSequence","index","m","existing","idx","a","b","timeA","timeB","seqA","seqB","detectColorScheme","_a","getActiveTheme","config","_b","_c","colorScheme","lightTheme","darkTheme","createThemeObserver","callback","cleanupFns","observer","mediaQuery","handleChange","fn","applyThemeVariables","element","theme","key","value","kebabKey","letter","icons","renderLucideIcon","iconName","size","color","strokeWidth","pascalName","word","iconData","createSvgFromIconData","error","svg","elementData","tagName","attrs","element","key","value","createElement","tag","className","element","statusCopy","positionMap","createLauncherButton","config","onToggle","button","createElement","update","newConfig","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","launcher","titleEl","subtitleEl","textContainer","icon","iconSize","iconSizeNum","iconSvg","renderLucideIcon","img","callToActionIconEl","callToActionIconSize","paddingTotal","containerSize","positionClass","positionMap","base","defaultBorder","defaultShadow","destroy","buildHeader","context","_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","_D","_E","_F","config","showClose","header","createElement","launcher","headerIconSize","closeButtonSize","closeButtonPlacement","headerIconHidden","headerIconName","iconHolder","iconSize","iconSvg","renderLucideIcon","img","headerCopy","title","subtitle","clearChatConfig","clearChatEnabled","clearChatPlacement","clearChatButton","clearChatButtonWrapper","clearChatSize","clearChatIconName","clearChatIconColor","clearChatBgColor","clearChatBorderWidth","clearChatBorderColor","clearChatBorderRadius","clearChatPaddingX","clearChatPaddingY","clearChatTooltipText","clearChatShowTooltip","borderWidth","borderColor","portaledTooltip","showTooltip","arrow","buttonRect","hideTooltip","closeButtonWrapper","closeButton","closeButtonTooltipText","closeButtonShowTooltip","closeButtonIconName","closeButtonIconText","closeIconSvg","attachHeaderToContainer","container","headerElements","buildDefaultHeader","context","buildHeader","buildMinimalHeader","_a","_b","_c","_d","config","showClose","onClose","launcher","header","createElement","title","closeButtonSize","closeButtonWrapper","closeButton","closeButtonIconName","closeIconSvg","renderLucideIcon","iconHolder","headerSubtitle","buildExpandedHeader","_e","_f","_g","_h","onClearChat","topRow","headerIconSize","headerIconName","iconSize","iconSvg","img","headerCopy","subtitle","bottomRow","headerLayouts","getHeaderLayout","layoutName","buildHeaderWithLayout","layoutConfig","customHeader","headerTitle","headerElements","getFontFamilyValue","family","buildComposer","context","_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","config","footer","createElement","suggestions","voiceRecognitionEnabledForGap","hasSpeechRecognitionForGap","composerForm","textarea","fontFamily","fontWeight","sendButtonConfig","useIcon","iconText","iconName","tooltipText","showTooltip","buttonSize","backgroundColor","textColor","sendButtonWrapper","sendButton","iconSize","iconColor","iconSvg","renderLucideIcon","tooltip","voiceRecognitionConfig","voiceRecognitionEnabled","micButton","micButtonWrapper","hasSpeechRecognition","micIconName","micIconSize","micIconSizeNum","micBackgroundColor","micIconColor","iconColorValue","micIconSvg","micTooltipText","e","statusText","statusConfig","isVisible","createWrapper","config","_a","_b","_c","_d","_e","_f","_g","wrapper","createElement","panel","inlineWidth","launcher","position","positionMap","launcherWidth","width","buildPanel","showClose","container","headerLayoutConfig","headerElements","buildHeaderWithLayout","buildHeader","body","introCard","introTitle","introSubtitle","messagesWrapper","composerElements","buildComposer","attachHeaderToContainer","createTypingIndicator","container","dot1","dot2","dot3","srOnly","createAvatar","avatarConfig","role","avatar","createElement","avatarContent","img","createTimestamp","message","timestampConfig","timestamp","date","getBubbleClasses","layout","baseClasses","createMessageActions","actionsConfig","callbacks","_a","_b","_c","_d","_e","_f","showCopy","showUpvote","showDownvote","visibility","align","alignClass","layoutClass","currentVote","createActionButton","iconName","label","onClick","dataAction","button","icon","renderLucideIcon","e","copyButton","textToCopy","checkIcon","originalIcon","err","upvoteButton","downvoteBtn","feedback","downvoteButton","upvoteBtn","createStandardBubble","transform","layoutConfig","actionCallbacks","config","showAvatar","showTimestamp","avatarPosition","timestampPosition","classes","bubble","contentDiv","typingIndicator","actions","wrapper","createBubbleWithLayout","reasoningExpansionState","createReasoningBubble","message","reasoning","bubble","createElement","expanded","header","headerContent","title","status","describeReasonStatus","toggleIcon","chevronIcon","renderLucideIcon","headerMeta","content","text","body","applyExpansionState","toggleExpansion","event","toolExpansionState","createToolBubble","message","config","_a","tool","toolCallConfig","bubble","createElement","expanded","header","headerContent","title","describeToolTitle","toggleIcon","iconColor","chevronIcon","renderLucideIcon","headerMeta","content","toolName","argsBlock","argsLabel","argsPre","formatUnknownValue","logsBlock","logsLabel","logsPre","resultBlock","resultLabel","resultPre","duration","applyToolExpansion","toggleToolExpansion","event","createSuggestions","container","suggestionButtons","chips","session","textarea","messages","chipsConfig","msg","fragment","streaming","getFontFamilyValue","family","chip","btn","createElement","formDefinitions","enhanceWithForms","bubble","message","config","session","placeholders","placeholder","_a","_b","_c","type","definition","heading","createElement","title","desc","form","field","group","label","inputType","control","actions","status","submit","event","formEndpoint","formData","payload","value","key","response","data","error","PluginRegistry","plugin","_a","pluginId","a","b","_b","instancePlugins","allPlugins","instanceIds","p","pluginRegistry","DEFAULT_LIGHT_THEME","DEFAULT_DARK_THEME","DEFAULT_WIDGET_CONFIG","mergeWithDefaults","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","createEventBus","listeners","on","event","handler","off","_a","payload","error","stripCodeFence","value","match","extractJsonObject","trimmed","start","depth","i","char","defaultJsonActionParser","text","withoutFence","jsonBody","parsed","action","payload","asString","defaultActionHandlers","context","_a","selector","element","ensureArrayOfStrings","entry","createActionManager","options","processedIds","syncFromMetadata","persistProcessedIds","latestIds","prev","parseSource","acc","parser","eventPayload","handler","handlerResult","persist","error","safeJsonParse","value","error","sanitizeMessages","messages","message","createLocalStorageAdapter","key","getStorage","storage","state","payload","ComponentRegistry","name","renderer","components","componentRegistry","import_partial_json","isComponentDirective","obj","component","extractComponentDirective","parsed","rawJson","props","createComponentStreamParser","extractedDirective","processedLength","accumulatedContent","trimmed","parsePartialJson","directive","isComponentDirectiveType","renderComponentDirective","directive","options","config","message","onPropsUpdate","renderer","componentRegistry","context","newProps","error","createComponentMiddleware","parser","createComponentStreamParser","accumulatedContent","hasComponentDirective","parsed","extractComponentDirectiveFromMessage","defaultCSATLabels","createCSATFeedback","options","onSubmit","onDismiss","title","subtitle","commentPlaceholder","submitText","skipText","showComment","ratingLabels","container","selectedRating","content","header","titleEl","subtitleEl","ratingContainer","ratingButtons","i","ratingButton","btn","index","isSelected","commentTextarea","commentContainer","actions","skipButton","submitButton","comment","error","createNPSFeedback","lowLabel","highLabel","labelsRow","lowLabelEl","highLabelEl","numbersRow","DEFAULT_CHAT_HISTORY_STORAGE_KEY","VOICE_STATE_RESTORE_WINDOW","ensureRecord","value","stripStreamingFromMessages","messages","message","buildPostprocessor","cfg","actionManager","markdownProcessor","createMarkdownProcessorFromConfig","context","_a","_b","_c","nextText","rawPayload","actionResult","escapeHtml","createAgentExperience","mount","initialConfig","runtimeOptions","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","config","mergeWithDefaults","plugins","pluginRegistry","componentRegistry","eventBus","createEventBus","storageAdapter","createLocalStorageAdapter","persistentMetadata","pendingStoredState","storedState","immediateState","error","getMetadata","updateMetadata","updater","persistState","resolvedActionParsers","defaultJsonActionParser","resolvedActionHandlers","defaultActionHandlers","createActionManager","launcherEnabled","autoExpand","prevAutoExpand","prevLauncherEnabled","open","postprocess","showReasoning","showToolCalls","messageActionCallbacks","session","feedback","statusConfig","getStatusText","status","statusCopy","wrapper","panel","createWrapper","panelElements","buildPanel","container","body","messagesWrapper","suggestions","textarea","sendButton","sendButtonWrapper","composerForm","statusText","introTitle","introSubtitle","closeButton","iconHolder","headerTitle","headerSubtitle","header","footer","micButton","micButtonWrapper","headerPlugin","p","customHeader","headerElements","buildHeader","attachHeaderToContainer","setOpenState","existingHeader","composerPlugin","customComposer","buildComposer","text","slots","getDefaultSlotContent","slot","insertSlotContent","element","titleSection","introCard","slotName","renderer","slotElement","applyFullHeightStyles","_o","_p","sidebarMode","fullHeight","theme","position","isLeftSidebar","defaultPanelBorder","defaultPanelShadow","defaultPanelBorderRadius","panelBorder","panelShadow","panelBorderRadius","launcherWidth","width","isInlineEmbed","positionMap","cls","sidebarWidth","maxHeightStyles","paddingStyles","applyThemeVariables","destroyCallbacks","cleanupThemeObserver","setupThemeObserver","createThemeObserver","suggestionsManager","createSuggestions","closeHandler","isStreaming","shouldAutoScroll","lastScrollTop","lastAutoScrollTime","scrollRAF","isAutoScrollBlocked","blockUntilTime","isAutoScrolling","AUTO_SCROLL_THROTTLE","AUTO_SCROLL_BLOCK_TIME","USER_SCROLL_THRESHOLD","BOTTOM_THRESHOLD","messageState","voiceState","voiceAutoResumeMode","emitVoiceState","source","persistVoiceMetadata","prev","maybeRestoreVoiceFromMetadata","rawVoiceState","wasActive","timestamp","startVoiceRecognition","getMessagesForPersistence","msg","messagesOverride","payload","result","scheduleAutoScroll","force","now","smoothScrollRAF","getScrollableContainer","smoothScrollToBottom","duration","start","clientHeight","target","distance","startTime","easeOutCubic","t","animate","currentTime","currentTarget","elapsed","progress","eased","currentScroll","trackMessages","nextState","previous","key","renderMessagesWithPlugins","transform","fragment","bubble","matchingPlugin","messageLayoutConfig","createReasoningBubble","createToolBubble","b","createStandardBubble","enhanceWithForms","hasComponentDirective","directive","extractComponentDirectiveFromMessage","componentBubble","renderComponentDirective","textDiv","hasStreamingAssistantMessage","lastMessage","hasRecentAssistantResponse","typingIndicator","createTypingIndicator","typingBubble","typingWrapper","scrollableContainer","updateOpenState","launcherButtonInstance","customLauncherElement","nextOpen","prevOpen","recalcPanelHeight","stateEvent","setComposerDisabled","disabled","btn","updateCopy","fontFamily","fontWeight","getFontFamilyValue","family","AgentWidgetSession","lastUserMessage","currentStatusConfig","getCurrentStatusText","streaming","state","handleSubmit","event","handleInputEnter","speechRecognition","isRecording","pauseTimer","originalMicStyles","getSpeechRecognitionClass","SpeechRecognitionClass","pauseDuration","initialText","fullTranscript","interimTranscript","i","transcript","newValue","finalValue","stopVoiceRecognition","voiceConfig","recordingBackgroundColor","recordingIconColor","recordingBorderColor","svg","createMicButton","sendButtonConfig","createElement","micIconName","buttonSize","micIconSize","micIconSizeNum","backgroundColor","iconColor","iconColorValue","micIconSvg","renderLucideIcon","tooltipText","tooltip","handleMicButtonClick","autoResumeUnsub","toggleOpen","launcherPlugin","customLauncher","createLauncherButton","viewportHeight","verticalMargin","heightOffset","available","clamped","finalHeight","handleScroll","scrollTop","scrollHeight","distanceFromBottom","delta","refreshCloseButton","clearChatButton","clearEvent","controller","nextConfig","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z","_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","__","_$","_aa","_ba","_ca","previousToolCallConfig","previousColorScheme","newPlugins","launcher","headerIconHidden","headerIconName","headerIconSize","headerCopy","iconSize","iconSvg","img","newImg","existingSvg","existingImg","closeButtonSize","closeButtonPlacement","closeButtonWrapper","isTopRight","currentlyTopRight","clearChatPlacement","clearChatEnabled","borderWidth","borderColor","closeButtonIconName","closeButtonIconText","closeButtonTooltipText","closeButtonShowTooltip","portaledTooltip","showTooltip","arrow","buttonRect","hideTooltip","clearChatButtonWrapper","clearChatConfig","closeButtonWrapperEl","clearChatSize","clearChatIconName","clearChatIconColor","clearChatTooltipText","clearChatShowTooltip","nextParsers","nextHandlers","voiceRecognitionEnabled","hasSpeechRecognition","shouldUseSmallGap","micButtonResult","newTooltip","useIcon","iconText","iconName","textColor","statusIndicatorConfig","isVisible","currentStatus","valueToSubmit","handler","options","existingFeedback","feedbackEl","createCSATFeedback","rating","comment","createNPSFeedback","cb","previousDebug","debugApi","active","import_meta","ensureTarget","target","element","widgetCssHref","mountStyles","root","href","adoptExistingStylesheet","globalLink","clonedLink","link","initAgentWidget","options","_a","_b","_c","_d","host","launcherEnabled","useShadow","mount","shadowRoot","controller","createAgentExperience","handle","detectParserTypeFromStreamParser","streamParser","fnString","getParserTypeFromConfig","config","_a","_b","generateToolCallConfig","indent","lines","key","value","generateMessageActionsConfig","generateMarkdownConfig","hasOptions","hasDisableDefaultStyles","generateLayoutConfig","hasHeader","hasMessages","avatarKey","avatarValue","k","tsKey","tsValue","generateCodeSnippet","format","cleanConfig","generateESMCode","generateScriptInstallerCode","generateScriptAdvancedCode","generateReactComponentCode","generateReactAdvancedCode","generateScriptManualCode","parserType","shouldEmitParserType","chip","buildSerializableConfig","serializableConfig","toolCallConfig","messageActionsConfig","markdownConfig","layoutConfig","headerConfig","messagesConfig","tsConfig","line","i","index_default","initAgentWidget"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/postprocessors.ts","../src/utils/formatting.ts","../src/client.ts","../src/utils/message-id.ts","../src/session.ts","../src/utils/theme.ts","../src/utils/icons.ts","../src/utils/dom.ts","../src/utils/morph.ts","../src/utils/constants.ts","../src/utils/positioning.ts","../src/components/launcher.ts","../src/components/header-builder.ts","../src/components/header-layouts.ts","../src/components/composer-builder.ts","../src/components/panel.ts","../src/components/message-bubble.ts","../src/components/reasoning-bubble.ts","../src/components/tool-bubble.ts","../src/components/suggestions.ts","../src/components/forms.ts","../src/plugins/registry.ts","../src/defaults.ts","../src/utils/events.ts","../src/utils/actions.ts","../src/utils/storage.ts","../src/components/registry.ts","../src/utils/component-parser.ts","../src/utils/component-middleware.ts","../src/components/feedback.ts","../src/ui.ts","../src/runtime/init.ts","../src/utils/code-generators.ts"],"sourcesContent":["import {\n initAgentWidget as initAgentWidgetFn,\n type AgentWidgetInitHandle\n} from \"./runtime/init\";\n\nexport type {\n AgentWidgetConfig,\n AgentWidgetTheme,\n AgentWidgetFeatureFlags,\n AgentWidgetInitOptions,\n AgentWidgetMessage,\n AgentWidgetLauncherConfig,\n AgentWidgetEvent,\n AgentWidgetStreamParser,\n AgentWidgetStreamParserResult,\n AgentWidgetRequestPayload,\n AgentWidgetCustomFetch,\n AgentWidgetSSEEventParser,\n AgentWidgetSSEEventResult,\n AgentWidgetHeadersFunction,\n // Layout types\n AgentWidgetLayoutConfig,\n AgentWidgetHeaderLayoutConfig,\n AgentWidgetMessageLayoutConfig,\n AgentWidgetAvatarConfig,\n AgentWidgetTimestampConfig,\n WidgetLayoutSlot,\n SlotRenderer,\n SlotRenderContext,\n HeaderRenderContext,\n MessageRenderContext,\n // Markdown types\n AgentWidgetMarkdownConfig,\n AgentWidgetMarkdownOptions,\n AgentWidgetMarkdownRendererOverrides,\n // Message actions types\n AgentWidgetMessageActionsConfig,\n AgentWidgetMessageFeedback,\n // Client token types\n ClientSession,\n ClientInitResponse,\n ClientChatRequest,\n ClientFeedbackRequest,\n ClientFeedbackType\n} from \"./types\";\n\nexport { initAgentWidgetFn as initAgentWidget };\nexport {\n createAgentExperience,\n type AgentWidgetController\n} from \"./ui\";\nexport {\n AgentWidgetSession,\n type AgentWidgetSessionStatus\n} from \"./session\";\nexport { AgentWidgetClient } from \"./client\";\nexport { createLocalStorageAdapter } from \"./utils/storage\";\nexport {\n createActionManager,\n defaultActionHandlers,\n defaultJsonActionParser\n} from \"./utils/actions\";\nexport {\n markdownPostprocessor,\n escapeHtml,\n directivePostprocessor,\n createMarkdownProcessor,\n createMarkdownProcessorFromConfig,\n createDirectivePostprocessor\n} from \"./postprocessors\";\nexport type { MarkdownProcessorOptions } from \"./postprocessors\";\nexport {\n createPlainTextParser,\n createJsonStreamParser,\n createFlexibleJsonStreamParser,\n createRegexJsonParser,\n createXmlParser\n} from \"./utils/formatting\";\nexport {\n generateMessageId,\n generateUserMessageId,\n generateAssistantMessageId\n} from \"./utils/message-id\";\nexport { generateCodeSnippet } from \"./utils/code-generators\";\nexport type { CodeFormat } from \"./utils/code-generators\";\nexport type { AgentWidgetInitHandle };\n\n// Plugin system exports\nexport type { AgentWidgetPlugin } from \"./plugins/types\";\nexport { pluginRegistry } from \"./plugins/registry\";\n\n// Component system exports\nexport { componentRegistry } from \"./components/registry\";\nexport type { ComponentRenderer, ComponentContext } from \"./components/registry\";\nexport {\n createComponentStreamParser,\n isComponentDirectiveType\n} from \"./utils/component-parser\";\nexport type { ComponentDirective } from \"./utils/component-parser\";\nexport {\n renderComponentDirective,\n createComponentMiddleware,\n hasComponentDirective,\n extractComponentDirectiveFromMessage\n} from \"./utils/component-middleware\";\n\n// Default configuration exports\nexport {\n DEFAULT_WIDGET_CONFIG,\n DEFAULT_LIGHT_THEME,\n DEFAULT_DARK_THEME,\n mergeWithDefaults\n} from \"./defaults\";\n\n// Layout system exports\nexport {\n buildHeader,\n buildComposer,\n attachHeaderToContainer\n} from \"./components/panel\";\nexport type {\n HeaderElements,\n HeaderBuildContext,\n ComposerElements,\n ComposerBuildContext\n} from \"./components/panel\";\nexport {\n headerLayouts,\n getHeaderLayout,\n buildHeaderWithLayout,\n buildDefaultHeader,\n buildMinimalHeader,\n buildExpandedHeader\n} from \"./components/header-layouts\";\nexport type {\n HeaderLayoutContext,\n HeaderLayoutRenderer\n} from \"./components/header-layouts\";\nexport {\n createStandardBubble,\n createBubbleWithLayout,\n createTypingIndicator,\n createMessageActions\n} from \"./components/message-bubble\";\nexport type { MessageTransform, MessageActionCallbacks } from \"./components/message-bubble\";\nexport {\n createCSATFeedback,\n createNPSFeedback\n} from \"./components/feedback\";\nexport type { CSATFeedbackOptions, NPSFeedbackOptions } from \"./components/feedback\";\n\nexport default initAgentWidgetFn;\n","import { Marked, type RendererObject } from \"marked\";\nimport type { AgentWidgetMarkdownConfig, AgentWidgetMarkdownRendererOverrides, AgentWidgetMarkdownOptions } from \"./types\";\n\n/**\n * Options for creating a markdown processor\n */\nexport type MarkdownProcessorOptions = {\n /** Marked parsing options */\n markedOptions?: AgentWidgetMarkdownOptions;\n /** Custom renderer overrides */\n renderer?: AgentWidgetMarkdownRendererOverrides;\n};\n\n/**\n * Converts AgentWidgetMarkdownRendererOverrides to marked's RendererObject format\n */\nconst convertRendererOverrides = (\n overrides?: AgentWidgetMarkdownRendererOverrides\n): Partial<RendererObject> | undefined => {\n if (!overrides) return undefined;\n \n // The token-based API in marked v12+ matches our type definitions\n // We can pass through the overrides directly\n return overrides as Partial<RendererObject>;\n};\n\n/**\n * Creates a configured markdown processor with custom options and renderers.\n * \n * @param options - Configuration options for the markdown processor\n * @returns A function that converts markdown text to HTML\n * \n * @example\n * ```typescript\n * // Basic usage with defaults\n * const processor = createMarkdownProcessor();\n * const html = processor(\"# Hello World\");\n * \n * // With custom options\n * const processor = createMarkdownProcessor({\n * markedOptions: { gfm: true, breaks: true },\n * renderer: {\n * link(token) {\n * return `<a href=\"${token.href}\" target=\"_blank\">${token.text}</a>`;\n * }\n * }\n * });\n * ```\n */\nexport const createMarkdownProcessor = (options?: MarkdownProcessorOptions) => {\n const opts = options?.markedOptions;\n const markedInstance = new Marked({\n gfm: opts?.gfm ?? true,\n breaks: opts?.breaks ?? true,\n pedantic: opts?.pedantic,\n silent: opts?.silent,\n });\n \n const rendererOverrides = convertRendererOverrides(options?.renderer);\n if (rendererOverrides) {\n markedInstance.use({ renderer: rendererOverrides });\n }\n \n return (text: string): string => {\n return markedInstance.parse(text) as string;\n };\n};\n\n/**\n * Creates a markdown processor from AgentWidgetMarkdownConfig.\n * This is a convenience function that maps the widget config to processor options.\n * \n * @param config - The markdown configuration from widget config\n * @returns A function that converts markdown text to HTML\n */\nexport const createMarkdownProcessorFromConfig = (config?: AgentWidgetMarkdownConfig) => {\n if (!config) {\n return createMarkdownProcessor();\n }\n \n return createMarkdownProcessor({\n markedOptions: config.options,\n renderer: config.renderer,\n });\n};\n\n// Create default markdown processor instance\nconst defaultMarkdownProcessor = createMarkdownProcessor();\n\n/**\n * Basic markdown renderer using default settings.\n * Remember to sanitize the returned HTML if you render untrusted content in your host page.\n * \n * For custom configuration, use `createMarkdownProcessor()` or `createMarkdownProcessorFromConfig()`.\n */\nexport const markdownPostprocessor = (text: string): string => {\n return defaultMarkdownProcessor(text);\n};\n\n/**\n * Escapes HTML entities. Used as the default safe renderer.\n */\nexport const escapeHtml = (text: string): string =>\n text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n\nconst escapeAttribute = (value: string) =>\n value.replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n\nconst makeToken = (idx: number) => `%%FORM_PLACEHOLDER_${idx}%%`;\n\nconst directiveReplacer = (source: string, placeholders: Array<{ token: string; type: string }>) => {\n let working = source;\n\n // JSON directive pattern e.g. <Directive>{\"component\":\"form\",\"type\":\"init\"}</Directive>\n working = working.replace(/<Directive>([\\s\\S]*?)<\\/Directive>/gi, (match, jsonText) => {\n try {\n const parsed = JSON.parse(jsonText.trim());\n if (parsed && typeof parsed === \"object\" && parsed.component === \"form\" && parsed.type) {\n const token = makeToken(placeholders.length);\n placeholders.push({ token, type: String(parsed.type) });\n return token;\n }\n } catch (error) {\n return match;\n }\n return match;\n });\n\n // XML-style directive e.g. <Form type=\"init\" />\n working = working.replace(/<Form\\s+type=\"([^\"]+)\"\\s*\\/>/gi, (_, type) => {\n const token = makeToken(placeholders.length);\n placeholders.push({ token, type });\n return token;\n });\n\n return working;\n};\n\n/**\n * Creates a directive postprocessor with custom markdown configuration.\n * Converts special directives (either `<Form type=\"init\" />` or\n * `<Directive>{\"component\":\"form\",\"type\":\"init\"}</Directive>`) into placeholder\n * elements that the widget upgrades after render. Remaining text is rendered as\n * Markdown with the provided configuration.\n * \n * @param markdownConfig - Optional markdown configuration\n * @returns A function that processes text with directives and markdown\n */\nexport const createDirectivePostprocessor = (markdownConfig?: AgentWidgetMarkdownConfig) => {\n const processor = createMarkdownProcessorFromConfig(markdownConfig);\n \n return (text: string): string => {\n const placeholders: Array<{ token: string; type: string }> = [];\n const withTokens = directiveReplacer(text, placeholders);\n let html = processor(withTokens);\n\n placeholders.forEach(({ token, type }) => {\n const tokenRegex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), \"g\");\n const safeType = escapeAttribute(type);\n const replacement = `<div class=\"tvw-form-directive\" data-tv-form=\"${safeType}\"></div>`;\n html = html.replace(tokenRegex, replacement);\n });\n\n return html;\n };\n};\n\n/**\n * Converts special directives (either `<Form type=\"init\" />` or\n * `<Directive>{\"component\":\"form\",\"type\":\"init\"}</Directive>`) into placeholder\n * elements that the widget upgrades after render. Remaining text is rendered as\n * Markdown using default settings.\n * \n * For custom markdown configuration, use `createDirectivePostprocessor()`.\n */\nexport const directivePostprocessor = (text: string): string => {\n const placeholders: Array<{ token: string; type: string }> = [];\n const withTokens = directiveReplacer(text, placeholders);\n let html = markdownPostprocessor(withTokens);\n\n placeholders.forEach(({ token, type }) => {\n const tokenRegex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), \"g\");\n const safeType = escapeAttribute(type);\n const replacement = `<div class=\"tvw-form-directive\" data-tv-form=\"${safeType}\"></div>`;\n html = html.replace(tokenRegex, replacement);\n });\n\n return html;\n};\n","import { AgentWidgetReasoning, AgentWidgetToolCall, AgentWidgetStreamParser, AgentWidgetStreamParserResult } from \"../types\";\nimport { parse as parsePartialJson, STR, OBJ } from \"partial-json\";\n\n/**\n * Unescapes JSON string escape sequences that LLMs often double-escape.\n * Converts literal \\n, \\r, \\t sequences to actual control characters.\n */\nconst unescapeJsonString = (str: string): string => {\n return str\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n};\n\nexport const formatUnknownValue = (value: unknown): string => {\n if (value === null) return \"null\";\n if (value === undefined) return \"\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch (error) {\n return String(value);\n }\n};\n\nexport const formatReasoningDuration = (reasoning: AgentWidgetReasoning) => {\n const end = reasoning.completedAt ?? Date.now();\n const start = reasoning.startedAt ?? end;\n const durationMs =\n reasoning.durationMs !== undefined\n ? reasoning.durationMs\n : Math.max(0, end - start);\n const seconds = durationMs / 1000;\n if (seconds < 0.1) {\n return \"Thought for <0.1 seconds\";\n }\n const formatted =\n seconds >= 10\n ? Math.round(seconds).toString()\n : seconds.toFixed(1).replace(/\\.0$/, \"\");\n return `Thought for ${formatted} seconds`;\n};\n\nexport const describeReasonStatus = (reasoning: AgentWidgetReasoning) => {\n if (reasoning.status === \"complete\") return formatReasoningDuration(reasoning);\n if (reasoning.status === \"pending\") return \"Waiting\";\n return \"\";\n};\n\nexport const formatToolDuration = (tool: AgentWidgetToolCall) => {\n const durationMs =\n typeof tool.duration === \"number\"\n ? tool.duration\n : typeof tool.durationMs === \"number\"\n ? tool.durationMs\n : Math.max(\n 0,\n (tool.completedAt ?? Date.now()) -\n (tool.startedAt ?? tool.completedAt ?? Date.now())\n );\n const seconds = durationMs / 1000;\n if (seconds < 0.1) {\n return \"Used tool for <0.1 seconds\";\n }\n const formatted =\n seconds >= 10\n ? Math.round(seconds).toString()\n : seconds.toFixed(1).replace(/\\.0$/, \"\");\n return `Used tool for ${formatted} seconds`;\n};\n\nexport const describeToolStatus = (status: AgentWidgetToolCall[\"status\"]) => {\n if (status === \"complete\") return \"\";\n if (status === \"pending\") return \"Starting\";\n return \"Running\";\n};\n\nexport const describeToolTitle = (tool: AgentWidgetToolCall) => {\n if (tool.status === \"complete\") {\n return formatToolDuration(tool);\n }\n return \"Using tool...\";\n};\n\n/**\n * Creates a regex-based parser for extracting text from JSON streams.\n * This is a simpler alternative to schema-stream that uses regex to extract\n * the 'text' field incrementally as JSON streams in.\n * \n * This can be used as an alternative parser option.\n */\nconst createRegexJsonParserInternal = (): {\n processChunk(accumulatedContent: string): Promise<AgentWidgetStreamParserResult | string | null>;\n getExtractedText(): string | null;\n close?(): Promise<void>;\n} => {\n let extractedText: string | null = null;\n let processedLength = 0;\n \n // Regex-based extraction for incremental JSON parsing\n const extractTextFromIncompleteJson = (jsonString: string): string | null => {\n // Look for \"text\": \"value\" pattern, handling incomplete strings\n // Match: \"text\": \" followed by any characters (including incomplete)\n const textFieldRegex = /\"text\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.|\")*?)\"/;\n const match = jsonString.match(textFieldRegex);\n \n if (match && match[1]) {\n // Unescape the string value\n try {\n // Replace escaped characters\n let unescaped = match[1]\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n return unescaped;\n } catch {\n return match[1];\n }\n }\n \n // Also try to match incomplete text field (text field that hasn't closed yet)\n // Look for \"text\": \" followed by content that may not be closed\n const incompleteTextFieldRegex = /\"text\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)/;\n const incompleteMatch = jsonString.match(incompleteTextFieldRegex);\n \n if (incompleteMatch && incompleteMatch[1]) {\n // Unescape the partial string value\n try {\n let unescaped = incompleteMatch[1]\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n return unescaped;\n } catch {\n return incompleteMatch[1];\n }\n }\n \n return null;\n };\n \n return {\n getExtractedText: () => extractedText,\n processChunk: async (accumulatedContent: string): Promise<AgentWidgetStreamParserResult | string | null> => {\n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedText !== null\n ? { text: extractedText, raw: accumulatedContent }\n : null;\n }\n \n // Validate that the accumulated content looks like valid JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n \n // Try to extract text field using regex\n const extracted = extractTextFromIncompleteJson(accumulatedContent);\n if (extracted !== null) {\n extractedText = extracted;\n }\n \n // Update processed length\n processedLength = accumulatedContent.length;\n \n // Return both the extracted text and raw JSON\n if (extractedText !== null) {\n return {\n text: extractedText,\n raw: accumulatedContent\n };\n }\n\n return null;\n },\n close: async () => {\n // No cleanup needed for regex-based parser\n }\n };\n};\n\n/**\n * Extracts the text field from JSON (works with partial JSON during streaming).\n * For complete JSON, uses fast path. For incomplete JSON, returns null (use stateful parser in client.ts).\n * \n * @param jsonString - The JSON string (can be partial/incomplete during streaming)\n * @returns The extracted text value, or null if not found or invalid\n */\nexport const extractTextFromJson = (jsonString: string): string | null => {\n try {\n // Try to parse complete JSON first (fast path)\n const parsed = JSON.parse(jsonString);\n if (parsed && typeof parsed === \"object\" && typeof parsed.text === \"string\") {\n return parsed.text;\n }\n } catch {\n // For incomplete JSON, return null - use stateful parser in client.ts\n return null;\n }\n return null;\n};\n\n/**\n * Plain text parser - passes through text as-is without any parsing.\n * This is the default parser.\n */\nexport const createPlainTextParser = (): AgentWidgetStreamParser => {\n const parser: AgentWidgetStreamParser = {\n processChunk: (accumulatedContent: string): string | null => {\n // Always return null to indicate this isn't a structured format\n // Content will be displayed as plain text\n return null;\n },\n getExtractedText: (): string | null => {\n return null;\n }\n };\n // Mark this as a plain text parser\n (parser as any).__isPlainTextParser = true;\n return parser;\n};\n\n/**\n * JSON parser using regex-based extraction.\n * Extracts the 'text' field from JSON responses using regex patterns.\n * This is a simpler regex-based alternative to createJsonStreamParser.\n * Less robust for complex/malformed JSON but has no external dependencies.\n */\nexport const createRegexJsonParser = (): AgentWidgetStreamParser => {\n const regexParser = createRegexJsonParserInternal();\n \n return {\n processChunk: async (accumulatedContent: string): Promise<AgentWidgetStreamParserResult | string | null> => {\n // Only process if it looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n return regexParser.processChunk(accumulatedContent);\n },\n getExtractedText: regexParser.getExtractedText.bind(regexParser),\n close: regexParser.close?.bind(regexParser)\n };\n};\n\n/**\n * JSON stream parser using partial-json library.\n * Extracts the 'text' field from JSON responses using the partial-json library,\n * which is specifically designed for parsing incomplete JSON from LLMs.\n * This is the recommended parser as it's more robust than regex.\n * \n * Library: https://github.com/promplate/partial-json-parser-js\n */\nexport const createJsonStreamParser = (): AgentWidgetStreamParser => {\n let extractedText: string | null = null;\n let processedLength = 0;\n \n return {\n getExtractedText: () => extractedText,\n processChunk: (accumulatedContent: string): AgentWidgetStreamParserResult | string | null => {\n // Validate that the accumulated content looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n \n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedText !== null || extractedText === \"\"\n ? { text: extractedText || \"\", raw: accumulatedContent }\n : null;\n }\n \n try {\n // Parse partial JSON - allow partial strings and objects\n // STR | OBJ allows incomplete strings and objects during streaming\n const parsed = parsePartialJson(accumulatedContent, STR | OBJ);\n \n if (parsed && typeof parsed === \"object\") {\n // Check for component directives - extract text if present for combined text+component\n if (parsed.component && typeof parsed.component === \"string\") {\n // For component directives, extract text if present, otherwise empty\n extractedText = typeof parsed.text === \"string\" ? unescapeJsonString(parsed.text) : \"\";\n }\n // Check for form directives - these also don't have text fields\n else if (parsed.type === \"init\" && parsed.form) {\n // For form directives, return empty - they're handled by form postprocessor\n extractedText = \"\";\n }\n // Extract text field if available\n else if (typeof parsed.text === \"string\") {\n extractedText = unescapeJsonString(parsed.text);\n }\n }\n } catch (error) {\n // If parsing fails completely, keep the last extracted text\n // This can happen with very malformed JSON\n }\n \n // Update processed length\n processedLength = accumulatedContent.length;\n \n // Always return raw JSON for component/form directive detection\n // Return empty string for text if it's a component/form directive\n if (extractedText !== null) {\n return {\n text: extractedText,\n raw: accumulatedContent\n };\n }\n\n return null;\n },\n close: () => {\n // No cleanup needed\n }\n };\n};\n\n/**\n * Flexible JSON stream parser that can extract text from various field names.\n * This parser looks for display text in multiple possible fields, making it\n * compatible with different JSON response formats.\n * \n * @param textExtractor Optional function to extract display text from parsed JSON.\n * If not provided, looks for common text fields.\n */\nexport const createFlexibleJsonStreamParser = (\n textExtractor?: (parsed: any) => string | null\n): AgentWidgetStreamParser => {\n let extractedText: string | null = null;\n let processedLength = 0;\n \n // Default text extractor that handles common patterns\n const defaultExtractor = (parsed: any): string | null => {\n if (!parsed || typeof parsed !== \"object\") return null;\n\n // Helper to safely extract and unescape text\n const getText = (value: any): string | null => {\n return typeof value === \"string\" ? unescapeJsonString(value) : null;\n };\n\n // Check for component directives - extract text if present for combined text+component\n if (parsed.component && typeof parsed.component === \"string\") {\n // For component directives, extract text if present, otherwise empty\n return typeof parsed.text === \"string\" ? unescapeJsonString(parsed.text) : \"\";\n }\n \n // Check for form directives - these also don't have text fields\n if (parsed.type === \"init\" && parsed.form) {\n // For form directives, return empty - they're handled by form postprocessor\n return \"\";\n }\n \n // Check for action-based text fields\n if (parsed.action) {\n switch (parsed.action) {\n case 'nav_then_click':\n return getText(parsed.on_load_text) || getText(parsed.text) || null;\n case 'message':\n case 'message_and_click':\n case 'checkout':\n return getText(parsed.text) || null;\n default:\n return getText(parsed.text) || getText(parsed.display_text) || getText(parsed.message) || null;\n }\n }\n \n // Fallback to common text field names\n return getText(parsed.text) || getText(parsed.display_text) || getText(parsed.message) || getText(parsed.content) || null;\n };\n \n const extractText = textExtractor || defaultExtractor;\n \n return {\n getExtractedText: () => extractedText,\n processChunk: (accumulatedContent: string): AgentWidgetStreamParserResult | string | null => {\n // Validate that the accumulated content looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return null;\n }\n \n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedText !== null\n ? { text: extractedText, raw: accumulatedContent }\n : null;\n }\n \n try {\n // Parse partial JSON - allow partial strings and objects\n // STR | OBJ allows incomplete strings and objects during streaming\n const parsed = parsePartialJson(accumulatedContent, STR | OBJ);\n \n // Extract text using the provided or default extractor\n const newText = extractText(parsed);\n if (newText !== null) {\n extractedText = newText;\n }\n } catch (error) {\n // If parsing fails completely, keep the last extracted text\n // This can happen with very malformed JSON\n }\n \n // Update processed length\n processedLength = accumulatedContent.length;\n \n // Always return the raw JSON for action parsing and component detection\n // Text may be null or empty for component/form directives, that's ok\n return {\n text: extractedText || \"\",\n raw: accumulatedContent\n };\n },\n close: () => {\n // No cleanup needed\n }\n };\n};\n\n/**\n * XML stream parser.\n * Extracts text from <text>...</text> tags in XML responses.\n */\nexport const createXmlParser = (): AgentWidgetStreamParser => {\n let extractedText: string | null = null;\n \n return {\n processChunk: (accumulatedContent: string): AgentWidgetStreamParserResult | string | null => {\n // Return null if not XML format\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith('<')) {\n return null;\n }\n \n // Extract text from <text>...</text> tags\n // Handle both <text>content</text> and <text attr=\"value\">content</text>\n const match = accumulatedContent.match(/<text[^>]*>([\\s\\S]*?)<\\/text>/);\n if (match && match[1]) {\n extractedText = match[1];\n // For XML, we typically don't need the raw content for middleware\n // but we can include it for consistency\n return { text: extractedText, raw: accumulatedContent };\n }\n \n return null;\n },\n getExtractedText: (): string | null => {\n return extractedText;\n }\n };\n};\n\n\n\n\n\n\n\n","import {\n AgentWidgetConfig,\n AgentWidgetMessage,\n AgentWidgetEvent,\n AgentWidgetStreamParser,\n AgentWidgetContextProvider,\n AgentWidgetRequestMiddleware,\n AgentWidgetRequestPayload,\n AgentWidgetCustomFetch,\n AgentWidgetSSEEventParser,\n AgentWidgetHeadersFunction,\n AgentWidgetSSEEventResult,\n ClientSession,\n ClientInitResponse,\n ClientChatRequest,\n ClientFeedbackRequest,\n ClientFeedbackType\n} from \"./types\";\nimport { \n extractTextFromJson, \n createPlainTextParser,\n createJsonStreamParser,\n createRegexJsonParser,\n createXmlParser\n} from \"./utils/formatting\";\n\ntype DispatchOptions = {\n messages: AgentWidgetMessage[];\n signal?: AbortSignal;\n /** Pre-generated ID for the expected assistant response (for feedback tracking) */\n assistantMessageId?: string;\n};\n\ntype SSEHandler = (event: AgentWidgetEvent) => void;\n\nconst DEFAULT_ENDPOINT = \"https://api.travrse.ai/v1/dispatch\";\nconst DEFAULT_CLIENT_API_BASE = \"https://api.travrse.ai\";\n\n/**\n * Maps parserType string to the corresponding parser factory function\n */\nfunction getParserFromType(parserType?: \"plain\" | \"json\" | \"regex-json\" | \"xml\"): () => AgentWidgetStreamParser {\n switch (parserType) {\n case \"json\":\n return createJsonStreamParser;\n case \"regex-json\":\n return createRegexJsonParser;\n case \"xml\":\n return createXmlParser;\n case \"plain\":\n default:\n return createPlainTextParser;\n }\n}\n\nexport class AgentWidgetClient {\n private readonly apiUrl: string;\n private readonly headers: Record<string, string>;\n private readonly debug: boolean;\n private readonly createStreamParser: () => AgentWidgetStreamParser;\n private readonly contextProviders: AgentWidgetContextProvider[];\n private readonly requestMiddleware?: AgentWidgetRequestMiddleware;\n private readonly customFetch?: AgentWidgetCustomFetch;\n private readonly parseSSEEvent?: AgentWidgetSSEEventParser;\n private readonly getHeaders?: AgentWidgetHeadersFunction;\n \n // Client token mode properties\n private clientSession: ClientSession | null = null;\n private sessionInitPromise: Promise<ClientSession> | null = null;\n\n constructor(private config: AgentWidgetConfig = {}) {\n this.apiUrl = config.apiUrl ?? DEFAULT_ENDPOINT;\n this.headers = {\n \"Content-Type\": \"application/json\",\n ...config.headers\n };\n this.debug = Boolean(config.debug);\n // Use custom stream parser if provided, otherwise use parserType, or fall back to plain text parser\n this.createStreamParser = config.streamParser ?? getParserFromType(config.parserType);\n this.contextProviders = config.contextProviders ?? [];\n this.requestMiddleware = config.requestMiddleware;\n this.customFetch = config.customFetch;\n this.parseSSEEvent = config.parseSSEEvent;\n this.getHeaders = config.getHeaders;\n }\n\n /**\n * Check if running in client token mode\n */\n public isClientTokenMode(): boolean {\n return !!this.config.clientToken;\n }\n\n /**\n * Get the appropriate API URL based on mode\n */\n private getClientApiUrl(endpoint: 'init' | 'chat'): string {\n const baseUrl = this.config.apiUrl?.replace(/\\/+$/, '').replace(/\\/v1\\/dispatch$/, '') || DEFAULT_CLIENT_API_BASE;\n return endpoint === 'init'\n ? `${baseUrl}/v1/client/init`\n : `${baseUrl}/v1/client/chat`;\n }\n\n /**\n * Get the current client session (if any)\n */\n public getClientSession(): ClientSession | null {\n return this.clientSession;\n }\n\n /**\n * Initialize session for client token mode.\n * Called automatically on first message if not already initialized.\n */\n public async initSession(): Promise<ClientSession> {\n if (!this.isClientTokenMode()) {\n throw new Error('initSession() only available in client token mode');\n }\n\n // Return existing session if valid\n if (this.clientSession && new Date() < this.clientSession.expiresAt) {\n return this.clientSession;\n }\n\n // Deduplicate concurrent init calls\n if (this.sessionInitPromise) {\n return this.sessionInitPromise;\n }\n\n this.sessionInitPromise = this._doInitSession();\n try {\n const session = await this.sessionInitPromise;\n this.clientSession = session;\n this.config.onSessionInit?.(session);\n return session;\n } finally {\n this.sessionInitPromise = null;\n }\n }\n\n private async _doInitSession(): Promise<ClientSession> {\n const response = await fetch(this.getClientApiUrl('init'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n token: this.config.clientToken,\n flow_id: this.config.flowId,\n }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Session initialization failed' }));\n if (response.status === 401) {\n throw new Error(`Invalid client token: ${error.hint || error.error}`);\n }\n if (response.status === 403) {\n throw new Error(`Origin not allowed: ${error.hint || error.error}`);\n }\n throw new Error(error.error || 'Failed to initialize session');\n }\n\n const data: ClientInitResponse = await response.json();\n return {\n sessionId: data.session_id,\n expiresAt: new Date(data.expires_at),\n flow: data.flow,\n config: {\n welcomeMessage: data.config.welcome_message,\n placeholder: data.config.placeholder,\n theme: data.config.theme,\n },\n };\n }\n\n /**\n * Clear the current client session\n */\n public clearClientSession(): void {\n this.clientSession = null;\n this.sessionInitPromise = null;\n }\n\n /**\n * Get the feedback API URL\n */\n private getFeedbackApiUrl(): string {\n const baseUrl = this.config.apiUrl?.replace(/\\/+$/, '').replace(/\\/v1\\/dispatch$/, '') || DEFAULT_CLIENT_API_BASE;\n return `${baseUrl}/v1/client/feedback`;\n }\n\n /**\n * Send feedback for a message (client token mode only).\n * Supports upvote, downvote, copy, csat, and nps feedback types.\n * \n * @param feedback - The feedback request payload\n * @returns Promise that resolves when feedback is sent successfully\n * @throws Error if not in client token mode or if session is invalid\n * \n * @example\n * ```typescript\n * // Message feedback (upvote/downvote/copy)\n * await client.sendFeedback({\n * session_id: sessionId,\n * message_id: messageId,\n * type: 'upvote'\n * });\n * \n * // CSAT feedback (1-5 rating)\n * await client.sendFeedback({\n * session_id: sessionId,\n * type: 'csat',\n * rating: 5,\n * comment: 'Great experience!'\n * });\n * \n * // NPS feedback (0-10 rating)\n * await client.sendFeedback({\n * session_id: sessionId,\n * type: 'nps',\n * rating: 9\n * });\n * ```\n */\n public async sendFeedback(feedback: ClientFeedbackRequest): Promise<void> {\n if (!this.isClientTokenMode()) {\n throw new Error('sendFeedback() only available in client token mode');\n }\n\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n // Validate message_id is provided for message-level feedback types\n const messageFeedbackTypes: ClientFeedbackType[] = ['upvote', 'downvote', 'copy'];\n if (messageFeedbackTypes.includes(feedback.type) && !feedback.message_id) {\n throw new Error(`message_id is required for ${feedback.type} feedback type`);\n }\n\n // Validate rating is provided for csat/nps feedback types\n if (feedback.type === 'csat') {\n if (feedback.rating === undefined || feedback.rating < 1 || feedback.rating > 5) {\n throw new Error('CSAT rating must be between 1 and 5');\n }\n }\n if (feedback.type === 'nps') {\n if (feedback.rating === undefined || feedback.rating < 0 || feedback.rating > 10) {\n throw new Error('NPS rating must be between 0 and 10');\n }\n }\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] sending feedback\", feedback);\n }\n\n const response = await fetch(this.getFeedbackApiUrl(), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(feedback),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Feedback submission failed' }));\n \n if (response.status === 401) {\n this.clientSession = null;\n this.config.onSessionExpired?.();\n throw new Error('Session expired. Please refresh to continue.');\n }\n \n throw new Error(errorData.error || 'Failed to submit feedback');\n }\n }\n\n /**\n * Submit message feedback (upvote, downvote, or copy).\n * Convenience method for sendFeedback with message-level feedback.\n * \n * @param messageId - The ID of the message to provide feedback for\n * @param type - The feedback type: 'upvote', 'downvote', or 'copy'\n */\n public async submitMessageFeedback(\n messageId: string, \n type: 'upvote' | 'downvote' | 'copy'\n ): Promise<void> {\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n return this.sendFeedback({\n session_id: session.sessionId,\n message_id: messageId,\n type,\n });\n }\n\n /**\n * Submit CSAT (Customer Satisfaction) feedback.\n * Convenience method for sendFeedback with CSAT feedback.\n * \n * @param rating - Rating from 1 to 5\n * @param comment - Optional comment\n */\n public async submitCSATFeedback(rating: number, comment?: string): Promise<void> {\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n return this.sendFeedback({\n session_id: session.sessionId,\n type: 'csat',\n rating,\n comment,\n });\n }\n\n /**\n * Submit NPS (Net Promoter Score) feedback.\n * Convenience method for sendFeedback with NPS feedback.\n * \n * @param rating - Rating from 0 to 10\n * @param comment - Optional comment\n */\n public async submitNPSFeedback(rating: number, comment?: string): Promise<void> {\n const session = this.getClientSession();\n if (!session) {\n throw new Error('No active session. Please initialize session first.');\n }\n\n return this.sendFeedback({\n session_id: session.sessionId,\n type: 'nps',\n rating,\n comment,\n });\n }\n\n /**\n * Send a message - handles both proxy and client token modes\n */\n public async dispatch(options: DispatchOptions, onEvent: SSEHandler) {\n if (this.isClientTokenMode()) {\n return this.dispatchClientToken(options, onEvent);\n }\n return this.dispatchProxy(options, onEvent);\n }\n\n /**\n * Client token mode dispatch\n */\n private async dispatchClientToken(options: DispatchOptions, onEvent: SSEHandler) {\n const controller = new AbortController();\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => controller.abort());\n }\n\n onEvent({ type: \"status\", status: \"connecting\" });\n\n try {\n // Ensure session is initialized\n const session = await this.initSession();\n\n // Check if session is about to expire (within 1 minute)\n if (new Date() >= new Date(session.expiresAt.getTime() - 60000)) {\n // Session expired or expiring soon\n this.clientSession = null;\n this.config.onSessionExpired?.();\n const error = new Error('Session expired. Please refresh to continue.');\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n // Build the standard payload to get context/metadata from middleware\n const basePayload = await this.buildPayload(options.messages);\n\n // Build the chat request payload with message IDs for feedback tracking\n const chatRequest: ClientChatRequest = {\n session_id: session.sessionId,\n messages: options.messages.map(m => ({\n id: m.id, // Include message ID for tracking\n role: m.role,\n content: m.rawContent || m.content,\n })),\n // Include pre-generated assistant message ID if provided\n ...(options.assistantMessageId && { assistant_message_id: options.assistantMessageId }),\n // Include metadata/context from middleware if present\n ...(basePayload.metadata && { metadata: basePayload.metadata }),\n ...(basePayload.context && { context: basePayload.context }),\n };\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] client token dispatch\", chatRequest);\n }\n\n const response = await fetch(this.getClientApiUrl('chat'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(chatRequest),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Chat request failed' }));\n \n if (response.status === 401) {\n // Session expired\n this.clientSession = null;\n this.config.onSessionExpired?.();\n const error = new Error('Session expired. Please refresh to continue.');\n onEvent({ type: \"error\", error });\n throw error;\n }\n \n if (response.status === 429) {\n const error = new Error(errorData.hint || 'Message limit reached for this session.');\n onEvent({ type: \"error\", error });\n throw error;\n }\n \n const error = new Error(errorData.error || 'Failed to send message');\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n if (!response.body) {\n const error = new Error('No response body received');\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n onEvent({ type: \"status\", status: \"connected\" });\n \n // Stream the response (same SSE handling as proxy mode)\n try {\n await this.streamResponse(response.body, onEvent, options.assistantMessageId);\n } finally {\n onEvent({ type: \"status\", status: \"idle\" });\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n // Only emit error if it wasn't already emitted\n if (!err.message.includes('Session expired') && !err.message.includes('Message limit')) {\n onEvent({ type: \"error\", error: err });\n }\n throw err;\n }\n }\n\n /**\n * Proxy mode dispatch (original implementation)\n */\n private async dispatchProxy(options: DispatchOptions, onEvent: SSEHandler) {\n const controller = new AbortController();\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => controller.abort());\n }\n\n onEvent({ type: \"status\", status: \"connecting\" });\n\n const payload = await this.buildPayload(options.messages);\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] dispatch payload\", payload);\n }\n\n // Build headers - merge static headers with dynamic headers if provided\n let headers = { ...this.headers };\n if (this.getHeaders) {\n try {\n const dynamicHeaders = await this.getHeaders();\n headers = { ...headers, ...dynamicHeaders };\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] getHeaders error:\", error);\n }\n }\n }\n\n // Use customFetch if provided, otherwise use default fetch\n let response: Response;\n if (this.customFetch) {\n try {\n response = await this.customFetch(\n this.apiUrl,\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n signal: controller.signal\n },\n payload\n );\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n onEvent({ type: \"error\", error: err });\n throw err;\n }\n } else {\n response = await fetch(this.apiUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n signal: controller.signal\n });\n }\n\n if (!response.ok || !response.body) {\n const error = new Error(\n `Chat backend request failed: ${response.status} ${response.statusText}`\n );\n onEvent({ type: \"error\", error });\n throw error;\n }\n\n onEvent({ type: \"status\", status: \"connected\" });\n try {\n await this.streamResponse(response.body, onEvent);\n } finally {\n onEvent({ type: \"status\", status: \"idle\" });\n }\n }\n\n private async buildPayload(\n messages: AgentWidgetMessage[]\n ): Promise<AgentWidgetRequestPayload> {\n const normalizedMessages = messages\n .slice()\n .sort((a, b) => {\n const timeA = new Date(a.createdAt).getTime();\n const timeB = new Date(b.createdAt).getTime();\n return timeA - timeB;\n })\n .map((message) => ({\n role: message.role,\n content: message.rawContent || message.content,\n createdAt: message.createdAt\n }));\n\n const payload: AgentWidgetRequestPayload = {\n messages: normalizedMessages,\n ...(this.config.flowId && { flowId: this.config.flowId })\n };\n\n if (this.contextProviders.length) {\n const contextAggregate: Record<string, unknown> = {};\n await Promise.all(\n this.contextProviders.map(async (provider) => {\n try {\n const result = await provider({\n messages,\n config: this.config\n });\n if (result && typeof result === \"object\") {\n Object.assign(contextAggregate, result);\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.warn(\"[AgentWidget] Context provider failed:\", error);\n }\n }\n })\n );\n\n if (Object.keys(contextAggregate).length) {\n payload.context = contextAggregate;\n }\n }\n\n if (this.requestMiddleware) {\n try {\n const result = await this.requestMiddleware({\n payload: { ...payload },\n config: this.config\n });\n if (result && typeof result === \"object\") {\n return result as AgentWidgetRequestPayload;\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Request middleware error:\", error);\n }\n }\n }\n\n return payload;\n }\n\n /**\n * Handle custom SSE event parsing via parseSSEEvent callback\n * Returns true if event was handled, false otherwise\n */\n private async handleCustomSSEEvent(\n payload: unknown,\n onEvent: SSEHandler,\n assistantMessageRef: { current: AgentWidgetMessage | null },\n emitMessage: (msg: AgentWidgetMessage) => void,\n nextSequence: () => number\n ): Promise<boolean> {\n if (!this.parseSSEEvent) return false;\n\n try {\n const result = await this.parseSSEEvent(payload);\n if (result === null) return false; // Event should be ignored\n\n const ensureAssistant = () => {\n if (assistantMessageRef.current) return assistantMessageRef.current;\n const msg: AgentWidgetMessage = {\n id: `assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n variant: \"assistant\",\n sequence: nextSequence()\n };\n assistantMessageRef.current = msg;\n emitMessage(msg);\n return msg;\n };\n\n if (result.text !== undefined) {\n const assistant = ensureAssistant();\n assistant.content += result.text;\n emitMessage(assistant);\n }\n\n if (result.done) {\n if (assistantMessageRef.current) {\n assistantMessageRef.current.streaming = false;\n emitMessage(assistantMessageRef.current);\n }\n onEvent({ type: \"status\", status: \"idle\" });\n }\n\n if (result.error) {\n onEvent({\n type: \"error\",\n error: new Error(result.error)\n });\n }\n\n return true; // Event was handled\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] parseSSEEvent error:\", error);\n }\n return false;\n }\n }\n\n private async streamResponse(\n body: ReadableStream<Uint8Array>,\n onEvent: SSEHandler,\n assistantMessageId?: string\n ) {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n const baseSequence = Date.now();\n let sequenceCounter = 0;\n const nextSequence = () => baseSequence + sequenceCounter++;\n\n const cloneMessage = (msg: AgentWidgetMessage): AgentWidgetMessage => {\n const reasoning = msg.reasoning\n ? {\n ...msg.reasoning,\n chunks: [...msg.reasoning.chunks]\n }\n : undefined;\n const toolCall = msg.toolCall\n ? {\n ...msg.toolCall,\n chunks: msg.toolCall.chunks ? [...msg.toolCall.chunks] : undefined\n }\n : undefined;\n const tools = msg.tools\n ? msg.tools.map((tool) => ({\n ...tool,\n chunks: tool.chunks ? [...tool.chunks] : undefined\n }))\n : undefined;\n\n return {\n ...msg,\n reasoning,\n toolCall,\n tools\n };\n };\n\n const emitMessage = (msg: AgentWidgetMessage) => {\n onEvent({\n type: \"message\",\n message: cloneMessage(msg)\n });\n };\n\n let assistantMessage: AgentWidgetMessage | null = null;\n // Reference to track assistant message for custom event handler\n const assistantMessageRef = { current: null as AgentWidgetMessage | null };\n const reasoningMessages = new Map<string, AgentWidgetMessage>();\n const toolMessages = new Map<string, AgentWidgetMessage>();\n const reasoningContext = {\n lastId: null as string | null,\n byStep: new Map<string, string>()\n };\n const toolContext = {\n lastId: null as string | null,\n byCall: new Map<string, string>()\n };\n\n const normalizeKey = (value: unknown): string | null => {\n if (value === null || value === undefined) return null;\n try {\n return String(value);\n } catch (error) {\n return null;\n }\n };\n\n const getStepKey = (payload: Record<string, any>) =>\n normalizeKey(\n payload.stepId ??\n payload.step_id ??\n payload.step ??\n payload.parentId ??\n payload.flowStepId ??\n payload.flow_step_id\n );\n\n const getToolCallKey = (payload: Record<string, any>) =>\n normalizeKey(\n payload.callId ??\n payload.call_id ??\n payload.requestId ??\n payload.request_id ??\n payload.toolCallId ??\n payload.tool_call_id ??\n payload.stepId ??\n payload.step_id\n );\n\n const ensureAssistantMessage = () => {\n if (assistantMessage) return assistantMessage;\n assistantMessage = {\n // Use pre-generated ID if provided, otherwise generate one\n id: assistantMessageId ?? `assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n sequence: nextSequence()\n };\n emitMessage(assistantMessage);\n return assistantMessage;\n };\n\n const trackReasoningId = (stepKey: string | null, id: string) => {\n reasoningContext.lastId = id;\n if (stepKey) {\n reasoningContext.byStep.set(stepKey, id);\n }\n };\n\n const resolveReasoningId = (\n payload: Record<string, any>,\n allowCreate: boolean\n ): string | null => {\n const rawId = payload.reasoningId ?? payload.id;\n const stepKey = getStepKey(payload);\n if (rawId) {\n const resolved = String(rawId);\n trackReasoningId(stepKey, resolved);\n return resolved;\n }\n if (stepKey) {\n const existing = reasoningContext.byStep.get(stepKey);\n if (existing) {\n reasoningContext.lastId = existing;\n return existing;\n }\n }\n if (reasoningContext.lastId && !allowCreate) {\n return reasoningContext.lastId;\n }\n if (!allowCreate) {\n return null;\n }\n const generated = `reason-${nextSequence()}`;\n trackReasoningId(stepKey, generated);\n return generated;\n };\n\n const ensureReasoningMessage = (reasoningId: string) => {\n const existing = reasoningMessages.get(reasoningId);\n if (existing) {\n return existing;\n }\n\n const message: AgentWidgetMessage = {\n id: `reason-${reasoningId}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n variant: \"reasoning\",\n sequence: nextSequence(),\n reasoning: {\n id: reasoningId,\n status: \"streaming\",\n chunks: []\n }\n };\n\n reasoningMessages.set(reasoningId, message);\n emitMessage(message);\n return message;\n };\n\n const trackToolId = (callKey: string | null, id: string) => {\n toolContext.lastId = id;\n if (callKey) {\n toolContext.byCall.set(callKey, id);\n }\n };\n\n const resolveToolId = (\n payload: Record<string, any>,\n allowCreate: boolean\n ): string | null => {\n const rawId = payload.toolId ?? payload.id;\n const callKey = getToolCallKey(payload);\n if (rawId) {\n const resolved = String(rawId);\n trackToolId(callKey, resolved);\n return resolved;\n }\n if (callKey) {\n const existing = toolContext.byCall.get(callKey);\n if (existing) {\n toolContext.lastId = existing;\n return existing;\n }\n }\n if (toolContext.lastId && !allowCreate) {\n return toolContext.lastId;\n }\n if (!allowCreate) {\n return null;\n }\n const generated = `tool-${nextSequence()}`;\n trackToolId(callKey, generated);\n return generated;\n };\n\n const ensureToolMessage = (toolId: string) => {\n const existing = toolMessages.get(toolId);\n if (existing) {\n return existing;\n }\n\n const message: AgentWidgetMessage = {\n id: `tool-${toolId}`,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date().toISOString(),\n streaming: true,\n variant: \"tool\",\n sequence: nextSequence(),\n toolCall: {\n id: toolId,\n status: \"pending\"\n }\n };\n\n toolMessages.set(toolId, message);\n emitMessage(message);\n return message;\n };\n\n const resolveTimestamp = (value: unknown) => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number(value);\n if (!Number.isNaN(parsed) && Number.isFinite(parsed)) {\n return parsed;\n }\n const dateParsed = Date.parse(value);\n if (!Number.isNaN(dateParsed)) {\n return dateParsed;\n }\n }\n return Date.now();\n };\n\n const ensureStringContent = (value: unknown): string => {\n if (typeof value === \"string\") {\n return value;\n }\n if (value === null || value === undefined) {\n return \"\";\n }\n // Convert objects/arrays to JSON string\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n };\n\n // Maintain stateful stream parsers per message for incremental parsing\n const streamParsers = new Map<string, AgentWidgetStreamParser>();\n // Track accumulated raw content for structured formats (JSON, XML, etc.)\n const rawContentBuffers = new Map<string, string>();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const events = buffer.split(\"\\n\\n\");\n buffer = events.pop() ?? \"\";\n\n for (const event of events) {\n const lines = event.split(\"\\n\");\n let eventType = \"message\";\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"event:\")) {\n eventType = line.replace(\"event:\", \"\").trim();\n } else if (line.startsWith(\"data:\")) {\n data += line.replace(\"data:\", \"\").trim();\n }\n }\n\n if (!data) continue;\n let payload: any;\n try {\n payload = JSON.parse(data);\n } catch (error) {\n onEvent({\n type: \"error\",\n error:\n error instanceof Error\n ? error\n : new Error(\"Failed to parse chat stream payload\")\n });\n continue;\n }\n\n const payloadType =\n eventType !== \"message\" ? eventType : payload.type ?? \"message\";\n\n // If custom SSE event parser is provided, try it first\n if (this.parseSSEEvent) {\n // Keep assistant message ref in sync\n assistantMessageRef.current = assistantMessage;\n const handled = await this.handleCustomSSEEvent(\n payload,\n onEvent,\n assistantMessageRef,\n emitMessage,\n nextSequence\n );\n // Update assistantMessage from ref (in case it was created)\n if (assistantMessageRef.current && !assistantMessage) {\n assistantMessage = assistantMessageRef.current;\n }\n if (handled) continue; // Skip default handling if custom handler processed it\n }\n\n if (payloadType === \"reason_start\") {\n const reasoningId =\n resolveReasoningId(payload, true) ?? `reason-${nextSequence()}`;\n const reasoningMessage = ensureReasoningMessage(reasoningId);\n reasoningMessage.reasoning = reasoningMessage.reasoning ?? {\n id: reasoningId,\n status: \"streaming\",\n chunks: []\n };\n reasoningMessage.reasoning.startedAt =\n reasoningMessage.reasoning.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n reasoningMessage.reasoning.completedAt = undefined;\n reasoningMessage.reasoning.durationMs = undefined;\n reasoningMessage.streaming = true;\n reasoningMessage.reasoning.status = \"streaming\";\n emitMessage(reasoningMessage);\n } else if (payloadType === \"reason_chunk\") {\n const reasoningId =\n resolveReasoningId(payload, false) ??\n resolveReasoningId(payload, true) ??\n `reason-${nextSequence()}`;\n const reasoningMessage = ensureReasoningMessage(reasoningId);\n reasoningMessage.reasoning = reasoningMessage.reasoning ?? {\n id: reasoningId,\n status: \"streaming\",\n chunks: []\n };\n reasoningMessage.reasoning.startedAt =\n reasoningMessage.reasoning.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n const chunk =\n payload.reasoningText ??\n payload.text ??\n payload.delta ??\n \"\";\n if (chunk && payload.hidden !== true) {\n reasoningMessage.reasoning.chunks.push(String(chunk));\n }\n reasoningMessage.reasoning.status = payload.done ? \"complete\" : \"streaming\";\n if (payload.done) {\n reasoningMessage.reasoning.completedAt = resolveTimestamp(\n payload.completedAt ?? payload.timestamp\n );\n const start = reasoningMessage.reasoning.startedAt ?? Date.now();\n reasoningMessage.reasoning.durationMs = Math.max(\n 0,\n (reasoningMessage.reasoning.completedAt ?? Date.now()) - start\n );\n }\n reasoningMessage.streaming = reasoningMessage.reasoning.status !== \"complete\";\n emitMessage(reasoningMessage);\n } else if (payloadType === \"reason_complete\") {\n const reasoningId =\n resolveReasoningId(payload, false) ??\n resolveReasoningId(payload, true) ??\n `reason-${nextSequence()}`;\n const reasoningMessage = reasoningMessages.get(reasoningId);\n if (reasoningMessage?.reasoning) {\n reasoningMessage.reasoning.status = \"complete\";\n reasoningMessage.reasoning.completedAt = resolveTimestamp(\n payload.completedAt ?? payload.timestamp\n );\n const start = reasoningMessage.reasoning.startedAt ?? Date.now();\n reasoningMessage.reasoning.durationMs = Math.max(\n 0,\n (reasoningMessage.reasoning.completedAt ?? Date.now()) - start\n );\n reasoningMessage.streaming = false;\n emitMessage(reasoningMessage);\n }\n const stepKey = getStepKey(payload);\n if (stepKey) {\n reasoningContext.byStep.delete(stepKey);\n }\n } else if (payloadType === \"tool_start\") {\n const toolId =\n resolveToolId(payload, true) ?? `tool-${nextSequence()}`;\n const toolMessage = ensureToolMessage(toolId);\n const tool = toolMessage.toolCall ?? {\n id: toolId,\n status: \"pending\"\n };\n tool.name = payload.toolName ?? tool.name;\n tool.status = \"running\";\n if (payload.args !== undefined) {\n tool.args = payload.args;\n }\n tool.startedAt =\n tool.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n tool.completedAt = undefined;\n tool.durationMs = undefined;\n toolMessage.toolCall = tool;\n toolMessage.streaming = true;\n emitMessage(toolMessage);\n } else if (payloadType === \"tool_chunk\") {\n const toolId =\n resolveToolId(payload, false) ??\n resolveToolId(payload, true) ??\n `tool-${nextSequence()}`;\n const toolMessage = ensureToolMessage(toolId);\n const tool = toolMessage.toolCall ?? {\n id: toolId,\n status: \"running\"\n };\n tool.startedAt =\n tool.startedAt ??\n resolveTimestamp(payload.startedAt ?? payload.timestamp);\n const chunkText =\n payload.text ?? payload.delta ?? payload.message ?? \"\";\n if (chunkText) {\n tool.chunks = tool.chunks ?? [];\n tool.chunks.push(String(chunkText));\n }\n tool.status = \"running\";\n toolMessage.toolCall = tool;\n toolMessage.streaming = true;\n emitMessage(toolMessage);\n } else if (payloadType === \"tool_complete\") {\n const toolId =\n resolveToolId(payload, false) ??\n resolveToolId(payload, true) ??\n `tool-${nextSequence()}`;\n const toolMessage = ensureToolMessage(toolId);\n const tool = toolMessage.toolCall ?? {\n id: toolId,\n status: \"running\"\n };\n tool.status = \"complete\";\n if (payload.result !== undefined) {\n tool.result = payload.result;\n }\n if (typeof payload.duration === \"number\") {\n tool.duration = payload.duration;\n }\n tool.completedAt = resolveTimestamp(\n payload.completedAt ?? payload.timestamp\n );\n if (typeof payload.duration === \"number\") {\n tool.durationMs = payload.duration;\n } else {\n const start = tool.startedAt ?? Date.now();\n tool.durationMs = Math.max(\n 0,\n (tool.completedAt ?? Date.now()) - start\n );\n }\n toolMessage.toolCall = tool;\n toolMessage.streaming = false;\n emitMessage(toolMessage);\n const callKey = getToolCallKey(payload);\n if (callKey) {\n toolContext.byCall.delete(callKey);\n }\n } else if (payloadType === \"step_chunk\") {\n // Only process chunks for prompt steps, not tool/context steps\n const stepType = (payload as any).stepType;\n const executionType = (payload as any).executionType;\n if (stepType === \"tool\" || executionType === \"context\") {\n // Skip tool-related chunks - they're handled by tool_start/tool_complete\n continue;\n }\n const assistant = ensureAssistantMessage();\n // Support various field names: text, delta, content, chunk (Travrse uses 'chunk')\n const chunk = payload.text ?? payload.delta ?? payload.content ?? payload.chunk ?? \"\";\n if (chunk) {\n // Accumulate raw content for structured format parsing\n const rawBuffer = rawContentBuffers.get(assistant.id) ?? \"\";\n const accumulatedRaw = rawBuffer + chunk;\n // Store raw content for action parsing, but NEVER set assistant.content to raw JSON\n assistant.rawContent = accumulatedRaw;\n \n // Use stream parser to parse\n if (!streamParsers.has(assistant.id)) {\n streamParsers.set(assistant.id, this.createStreamParser());\n }\n const parser = streamParsers.get(assistant.id)!;\n \n // Check if content looks like JSON\n const looksLikeJson = accumulatedRaw.trim().startsWith('{') || accumulatedRaw.trim().startsWith('[');\n \n // Store raw buffer before processing (needed for step_complete handler)\n if (looksLikeJson) {\n rawContentBuffers.set(assistant.id, accumulatedRaw);\n }\n \n // Check if this is a plain text parser (marked with __isPlainTextParser)\n const isPlainTextParser = (parser as any).__isPlainTextParser === true;\n \n // If plain text parser, just append the chunk directly\n if (isPlainTextParser) {\n assistant.content += chunk;\n // Clear any raw buffer/parser since we're in plain text mode\n rawContentBuffers.delete(assistant.id);\n streamParsers.delete(assistant.id);\n assistant.rawContent = undefined;\n emitMessage(assistant);\n continue;\n }\n \n // Try to parse with the parser (for structured parsers)\n const parsedResult = parser.processChunk(accumulatedRaw);\n \n // Handle async parser result\n if (parsedResult instanceof Promise) {\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n // Parser successfully extracted text\n // Update the message content with extracted text\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n emitMessage(currentAssistant);\n }\n } else if (!looksLikeJson && !accumulatedRaw.trim().startsWith('<')) {\n // Not a structured format - show as plain text\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content += chunk;\n rawContentBuffers.delete(currentAssistant.id);\n streamParsers.delete(currentAssistant.id);\n currentAssistant.rawContent = undefined;\n emitMessage(currentAssistant);\n }\n }\n // Otherwise wait for more chunks (incomplete structured format)\n // Don't emit message if parser hasn't extracted text yet\n }).catch(() => {\n // On error, treat as plain text\n assistant.content += chunk;\n rawContentBuffers.delete(assistant.id);\n streamParsers.delete(assistant.id);\n assistant.rawContent = undefined;\n emitMessage(assistant);\n });\n } else {\n // Synchronous parser result\n // Extract text from result (could be string, null, or object)\n const text = typeof parsedResult === 'string' ? parsedResult : parsedResult?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n // Parser successfully extracted text\n // Buffer is already set above\n assistant.content = text;\n emitMessage(assistant);\n } else if (!looksLikeJson && !accumulatedRaw.trim().startsWith('<')) {\n // Not a structured format - show as plain text\n assistant.content += chunk;\n // Clear any raw buffer/parser if we were in structured format mode\n rawContentBuffers.delete(assistant.id);\n streamParsers.delete(assistant.id);\n assistant.rawContent = undefined;\n emitMessage(assistant);\n }\n // Otherwise wait for more chunks (incomplete structured format)\n // Don't emit message if parser hasn't extracted text yet\n }\n \n // IMPORTANT: Don't call getExtractedText() and emit messages here\n // This was causing raw JSON to be displayed because getExtractedText() \n // wasn't extracting the \"text\" field correctly during streaming\n }\n if (payload.isComplete) {\n const finalContent = payload.result?.response ?? assistant.content;\n if (finalContent) {\n // Check if we have raw content buffer that needs final processing\n const rawBuffer = rawContentBuffers.get(assistant.id);\n const contentToProcess = rawBuffer ?? ensureStringContent(finalContent);\n assistant.rawContent = contentToProcess;\n \n // Try to extract text from final structured content\n const parser = streamParsers.get(assistant.id);\n let extractedText: string | null = null;\n let asyncPending = false;\n \n if (parser) {\n // First check if parser already has extracted text\n extractedText = parser.getExtractedText();\n \n if (extractedText === null) {\n // Try extracting with regex\n extractedText = extractTextFromJson(contentToProcess);\n }\n \n if (extractedText === null) {\n // Try parser.processChunk as last resort\n const parsedResult = parser.processChunk(contentToProcess);\n if (parsedResult instanceof Promise) {\n asyncPending = true;\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n if (text !== null) {\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n currentAssistant.streaming = false;\n // Clean up\n streamParsers.delete(currentAssistant.id);\n rawContentBuffers.delete(currentAssistant.id);\n emitMessage(currentAssistant);\n }\n }\n });\n } else {\n // Extract text from synchronous result\n extractedText = typeof parsedResult === 'string' ? parsedResult : parsedResult?.text ?? null;\n }\n }\n }\n \n // Skip sync emit if we're waiting on async parser\n if (!asyncPending) {\n // Set content: use extracted text if available, otherwise use raw content\n if (extractedText !== null && extractedText.trim() !== \"\") {\n assistant.content = extractedText;\n } else if (!rawContentBuffers.has(assistant.id)) {\n // Only use raw final content if we didn't accumulate chunks\n assistant.content = ensureStringContent(finalContent);\n }\n \n // Clean up parser and buffer\n const parserToClose = streamParsers.get(assistant.id);\n if (parserToClose) {\n const closeResult = parserToClose.close?.();\n if (closeResult instanceof Promise) {\n closeResult.catch(() => {});\n }\n streamParsers.delete(assistant.id);\n }\n rawContentBuffers.delete(assistant.id);\n assistant.streaming = false;\n emitMessage(assistant);\n }\n }\n }\n } else if (payloadType === \"step_complete\") {\n // Only process completions for prompt steps, not tool/context steps\n const stepType = (payload as any).stepType;\n const executionType = (payload as any).executionType;\n if (stepType === \"tool\" || executionType === \"context\") {\n // Skip tool-related completions - they're handled by tool_complete\n continue;\n }\n const finalContent = payload.result?.response;\n const assistant = ensureAssistantMessage();\n if (finalContent !== undefined && finalContent !== null) {\n // Check if we already have extracted text from streaming\n const parser = streamParsers.get(assistant.id);\n let hasExtractedText = false;\n let asyncPending = false;\n \n if (parser) {\n // First check if parser already extracted text during streaming\n const currentExtractedText = parser.getExtractedText();\n const rawBuffer = rawContentBuffers.get(assistant.id);\n const contentToProcess = rawBuffer ?? ensureStringContent(finalContent);\n \n // Always set rawContent so action parsers can access the raw JSON\n assistant.rawContent = contentToProcess;\n \n if (currentExtractedText !== null && currentExtractedText.trim() !== \"\") {\n // We already have extracted text from streaming - use it\n assistant.content = currentExtractedText;\n hasExtractedText = true;\n } else {\n // No extracted text yet - try to extract from final content\n \n // Try fast path first\n const extractedText = extractTextFromJson(contentToProcess);\n if (extractedText !== null) {\n assistant.content = extractedText;\n hasExtractedText = true;\n } else {\n // Try parser\n const parsedResult = parser.processChunk(contentToProcess);\n if (parsedResult instanceof Promise) {\n asyncPending = true;\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n currentAssistant.streaming = false;\n // Clean up\n streamParsers.delete(currentAssistant.id);\n rawContentBuffers.delete(currentAssistant.id);\n emitMessage(currentAssistant);\n }\n } else {\n // No extracted text - check if we should show raw content\n const finalExtractedText = parser.getExtractedText();\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n if (finalExtractedText !== null && finalExtractedText.trim() !== \"\") {\n currentAssistant.content = finalExtractedText;\n } else if (!rawContentBuffers.has(currentAssistant.id)) {\n // Only show raw content if we never had any extracted text\n currentAssistant.content = ensureStringContent(finalContent);\n }\n currentAssistant.streaming = false;\n // Clean up\n streamParsers.delete(currentAssistant.id);\n rawContentBuffers.delete(currentAssistant.id);\n emitMessage(currentAssistant);\n }\n }\n });\n } else {\n // Extract text from synchronous result\n const text = typeof parsedResult === 'string' ? parsedResult : parsedResult?.text ?? null;\n \n if (text !== null && text.trim() !== \"\") {\n assistant.content = text;\n hasExtractedText = true;\n } else {\n // Check stub one more time\n const finalExtractedText = parser.getExtractedText();\n if (finalExtractedText !== null && finalExtractedText.trim() !== \"\") {\n assistant.content = finalExtractedText;\n hasExtractedText = true;\n }\n }\n }\n }\n }\n }\n \n // Skip sync emit if we're waiting on async parser\n if (!asyncPending) {\n // Ensure rawContent is set even if there's no parser (for action parsing)\n if (!assistant.rawContent) {\n const rawBuffer = rawContentBuffers.get(assistant.id);\n assistant.rawContent = rawBuffer ?? ensureStringContent(finalContent);\n }\n \n // Only show raw content if we never extracted any text and no buffer was used\n if (!hasExtractedText && !rawContentBuffers.has(assistant.id)) {\n // No extracted text and no streaming happened - show raw content\n assistant.content = ensureStringContent(finalContent);\n }\n \n // Clean up parser and buffer\n if (parser) {\n const closeResult = parser.close?.();\n if (closeResult instanceof Promise) {\n closeResult.catch(() => {});\n }\n }\n streamParsers.delete(assistant.id);\n rawContentBuffers.delete(assistant.id);\n assistant.streaming = false;\n emitMessage(assistant);\n }\n } else {\n // No final content, just mark as complete and clean up\n streamParsers.delete(assistant.id);\n rawContentBuffers.delete(assistant.id);\n assistant.streaming = false;\n emitMessage(assistant);\n }\n } else if (payloadType === \"flow_complete\") {\n const finalContent = payload.result?.response;\n if (finalContent !== undefined && finalContent !== null) {\n const assistant = ensureAssistantMessage();\n // Check if we have raw content buffer that needs final processing\n const rawBuffer = rawContentBuffers.get(assistant.id);\n const stringContent = rawBuffer ?? ensureStringContent(finalContent);\n assistant.rawContent = stringContent;\n // Try to extract text from structured content\n let displayContent = ensureStringContent(finalContent);\n const parser = streamParsers.get(assistant.id);\n if (parser) {\n const extractedText = extractTextFromJson(stringContent);\n if (extractedText !== null) {\n displayContent = extractedText;\n } else {\n // Try parser if it exists\n const parsedResult = parser.processChunk(stringContent);\n if (parsedResult instanceof Promise) {\n parsedResult.then((result) => {\n // Extract text from result (could be string or object)\n const text = typeof result === 'string' ? result : result?.text ?? null;\n if (text !== null) {\n const currentAssistant = assistantMessage;\n if (currentAssistant && currentAssistant.id === assistant.id) {\n currentAssistant.content = text;\n currentAssistant.streaming = false;\n emitMessage(currentAssistant);\n }\n }\n });\n }\n const currentText = parser.getExtractedText();\n if (currentText !== null) {\n displayContent = currentText;\n }\n }\n }\n // Clean up parser and buffer\n streamParsers.delete(assistant.id);\n rawContentBuffers.delete(assistant.id);\n \n // Only emit if something actually changed to avoid flicker\n const contentChanged = displayContent !== assistant.content;\n const streamingChanged = assistant.streaming !== false;\n \n if (contentChanged) {\n assistant.content = displayContent;\n }\n assistant.streaming = false;\n \n // Only emit if content or streaming state changed\n if (contentChanged || streamingChanged) {\n emitMessage(assistant);\n }\n } else {\n // No final content, just mark as complete and clean up\n if (assistantMessage !== null) {\n // Clean up any remaining parsers/buffers\n // TypeScript narrowing issue - assistantMessage is checked for null above\n const msg: AgentWidgetMessage = assistantMessage;\n streamParsers.delete(msg.id);\n rawContentBuffers.delete(msg.id);\n \n // Only emit if streaming state changed\n if (msg.streaming !== false) {\n msg.streaming = false;\n emitMessage(msg);\n }\n }\n }\n onEvent({ type: \"status\", status: \"idle\" });\n } else if (payloadType === \"error\" && payload.error) {\n onEvent({\n type: \"error\",\n error:\n payload.error instanceof Error\n ? payload.error\n : new Error(String(payload.error))\n });\n }\n }\n }\n }\n}\n","/**\n * Message ID utilities for client-side message tracking\n * Used for feedback integration with the Travrse API\n */\n\n/**\n * Generate a unique message ID for tracking\n * Format: msg_{timestamp_base36}_{random_8chars}\n */\nexport function generateMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `msg_${timestamp}_${random}`;\n}\n\n/**\n * Generate a unique user message ID\n * Format: usr_{timestamp_base36}_{random_8chars}\n */\nexport function generateUserMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `usr_${timestamp}_${random}`;\n}\n\n/**\n * Generate a unique assistant message ID\n * Format: ast_{timestamp_base36}_{random_8chars}\n */\nexport function generateAssistantMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `ast_${timestamp}_${random}`;\n}\n\n\n\n","import { AgentWidgetClient } from \"./client\";\nimport {\n AgentWidgetConfig,\n AgentWidgetEvent,\n AgentWidgetMessage,\n ClientSession\n} from \"./types\";\nimport {\n generateUserMessageId,\n generateAssistantMessageId\n} from \"./utils/message-id\";\n\nexport type AgentWidgetSessionStatus =\n | \"idle\"\n | \"connecting\"\n | \"connected\"\n | \"error\";\n\ntype SessionCallbacks = {\n onMessagesChanged: (messages: AgentWidgetMessage[]) => void;\n onStatusChanged: (status: AgentWidgetSessionStatus) => void;\n onStreamingChanged: (streaming: boolean) => void;\n onError?: (error: Error) => void;\n};\n\nexport class AgentWidgetSession {\n private client: AgentWidgetClient;\n private messages: AgentWidgetMessage[];\n private status: AgentWidgetSessionStatus = \"idle\";\n private streaming = false;\n private abortController: AbortController | null = null;\n private sequenceCounter = Date.now();\n \n // Client token session management\n private clientSession: ClientSession | null = null;\n\n constructor(\n private config: AgentWidgetConfig = {},\n private callbacks: SessionCallbacks\n ) {\n this.messages = [...(config.initialMessages ?? [])].map((message) => ({\n ...message,\n sequence: message.sequence ?? this.nextSequence()\n }));\n this.messages = this.sortMessages(this.messages);\n this.client = new AgentWidgetClient(config);\n\n if (this.messages.length) {\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n this.callbacks.onStatusChanged(this.status);\n }\n\n /**\n * Check if running in client token mode\n */\n public isClientTokenMode(): boolean {\n return this.client.isClientTokenMode();\n }\n\n /**\n * Initialize the client session (for client token mode).\n * This is called automatically on first message, but can be called\n * explicitly to pre-initialize the session and get config from server.\n */\n public async initClientSession(): Promise<ClientSession | null> {\n if (!this.isClientTokenMode()) {\n return null;\n }\n \n try {\n const session = await this.client.initSession();\n this.setClientSession(session);\n return session;\n } catch (error) {\n this.callbacks.onError?.(\n error instanceof Error ? error : new Error(String(error))\n );\n return null;\n }\n }\n\n /**\n * Set the client session after initialization\n */\n public setClientSession(session: ClientSession): void {\n this.clientSession = session;\n \n // Optionally add welcome message from session config\n if (session.config.welcomeMessage && this.messages.length === 0) {\n const welcomeMessage: AgentWidgetMessage = {\n id: `welcome-${Date.now()}`,\n role: \"assistant\",\n content: session.config.welcomeMessage,\n createdAt: new Date().toISOString(),\n sequence: this.nextSequence()\n };\n this.appendMessage(welcomeMessage);\n }\n }\n\n /**\n * Get current client session\n */\n public getClientSession(): ClientSession | null {\n return this.clientSession ?? this.client.getClientSession();\n }\n\n /**\n * Check if session is valid and not expired\n */\n public isSessionValid(): boolean {\n const session = this.getClientSession();\n if (!session) return false;\n return new Date() < session.expiresAt;\n }\n\n /**\n * Clear session (on expiry or error)\n */\n public clearClientSession(): void {\n this.clientSession = null;\n this.client.clearClientSession();\n }\n\n /**\n * Get the underlying client instance (for advanced use cases like feedback)\n */\n public getClient(): AgentWidgetClient {\n return this.client;\n }\n\n /**\n * Submit message feedback (upvote, downvote, or copy) to the API.\n * Only available in client token mode.\n * \n * @param messageId - The ID of the message to provide feedback for\n * @param type - The feedback type: 'upvote', 'downvote', or 'copy'\n */\n public async submitMessageFeedback(\n messageId: string,\n type: 'upvote' | 'downvote' | 'copy'\n ): Promise<void> {\n return this.client.submitMessageFeedback(messageId, type);\n }\n\n /**\n * Submit CSAT (Customer Satisfaction) feedback to the API.\n * Only available in client token mode.\n * \n * @param rating - Rating from 1 to 5\n * @param comment - Optional comment\n */\n public async submitCSATFeedback(rating: number, comment?: string): Promise<void> {\n return this.client.submitCSATFeedback(rating, comment);\n }\n\n /**\n * Submit NPS (Net Promoter Score) feedback to the API.\n * Only available in client token mode.\n * \n * @param rating - Rating from 0 to 10\n * @param comment - Optional comment\n */\n public async submitNPSFeedback(rating: number, comment?: string): Promise<void> {\n return this.client.submitNPSFeedback(rating, comment);\n }\n\n public updateConfig(next: AgentWidgetConfig) {\n this.config = { ...this.config, ...next };\n this.client = new AgentWidgetClient(this.config);\n }\n\n public getMessages() {\n return [...this.messages];\n }\n\n public getStatus() {\n return this.status;\n }\n\n public isStreaming() {\n return this.streaming;\n }\n\n public injectTestEvent(event: AgentWidgetEvent) {\n this.handleEvent(event);\n }\n\n public async sendMessage(rawInput: string, options?: { viaVoice?: boolean }) {\n const input = rawInput.trim();\n if (!input) return;\n\n this.abortController?.abort();\n\n // Generate IDs for both user message and expected assistant response\n const userMessageId = generateUserMessageId();\n const assistantMessageId = generateAssistantMessageId();\n\n const userMessage: AgentWidgetMessage = {\n id: userMessageId,\n role: \"user\",\n content: input,\n createdAt: new Date().toISOString(),\n sequence: this.nextSequence(),\n viaVoice: options?.viaVoice || false\n };\n\n this.appendMessage(userMessage);\n this.setStreaming(true);\n\n const controller = new AbortController();\n this.abortController = controller;\n\n const snapshot = [...this.messages];\n\n try {\n await this.client.dispatch(\n {\n messages: snapshot,\n signal: controller.signal,\n assistantMessageId // Pass expected assistant message ID for tracking\n },\n this.handleEvent\n );\n } catch (error) {\n const fallback: AgentWidgetMessage = {\n id: assistantMessageId, // Use the pre-generated ID for fallback too\n role: \"assistant\",\n createdAt: new Date().toISOString(),\n content:\n \"It looks like the proxy isn't returning a real response yet. Here's a sample message so you can continue testing locally.\",\n sequence: this.nextSequence()\n };\n\n this.appendMessage(fallback);\n this.setStatus(\"idle\");\n this.setStreaming(false);\n this.abortController = null;\n if (error instanceof Error) {\n this.callbacks.onError?.(error);\n } else {\n this.callbacks.onError?.(new Error(String(error)));\n }\n }\n }\n\n public cancel() {\n this.abortController?.abort();\n this.abortController = null;\n this.setStreaming(false);\n this.setStatus(\"idle\");\n }\n\n public clearMessages() {\n this.abortController?.abort();\n this.abortController = null;\n this.messages = [];\n this.setStreaming(false);\n this.setStatus(\"idle\");\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n public hydrateMessages(messages: AgentWidgetMessage[]) {\n this.abortController?.abort();\n this.abortController = null;\n this.messages = this.sortMessages(\n messages.map((message) => ({\n ...message,\n streaming: false,\n sequence: message.sequence ?? this.nextSequence()\n }))\n );\n this.setStreaming(false);\n this.setStatus(\"idle\");\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n private handleEvent = (event: AgentWidgetEvent) => {\n if (event.type === \"message\") {\n this.upsertMessage(event.message);\n } else if (event.type === \"status\") {\n this.setStatus(event.status);\n if (event.status === \"connecting\") {\n this.setStreaming(true);\n } else if (event.status === \"idle\" || event.status === \"error\") {\n this.setStreaming(false);\n this.abortController = null;\n }\n } else if (event.type === \"error\") {\n this.setStatus(\"error\");\n this.setStreaming(false);\n this.abortController = null;\n this.callbacks.onError?.(event.error);\n }\n };\n\n private setStatus(status: AgentWidgetSessionStatus) {\n if (this.status === status) return;\n this.status = status;\n this.callbacks.onStatusChanged(status);\n }\n\n private setStreaming(streaming: boolean) {\n if (this.streaming === streaming) return;\n this.streaming = streaming;\n this.callbacks.onStreamingChanged(streaming);\n }\n\n private appendMessage(message: AgentWidgetMessage) {\n const withSequence = this.ensureSequence(message);\n this.messages = this.sortMessages([...this.messages, withSequence]);\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n private upsertMessage(message: AgentWidgetMessage) {\n const withSequence = this.ensureSequence(message);\n const index = this.messages.findIndex((m) => m.id === withSequence.id);\n if (index === -1) {\n this.appendMessage(withSequence);\n return;\n }\n\n this.messages = this.messages.map((existing, idx) =>\n idx === index ? { ...existing, ...withSequence } : existing\n );\n this.messages = this.sortMessages(this.messages);\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n\n private ensureSequence(message: AgentWidgetMessage): AgentWidgetMessage {\n if (message.sequence !== undefined) {\n return { ...message };\n }\n return {\n ...message,\n sequence: this.nextSequence()\n };\n }\n\n private nextSequence() {\n return this.sequenceCounter++;\n }\n\n private sortMessages(messages: AgentWidgetMessage[]) {\n return [...messages].sort((a, b) => {\n // Sort by createdAt timestamp first (chronological order)\n const timeA = new Date(a.createdAt).getTime();\n const timeB = new Date(b.createdAt).getTime();\n if (!Number.isNaN(timeA) && !Number.isNaN(timeB) && timeA !== timeB) {\n return timeA - timeB;\n }\n\n // Fall back to sequence if timestamps are equal or invalid\n const seqA = a.sequence ?? 0;\n const seqB = b.sequence ?? 0;\n if (seqA !== seqB) return seqA - seqB;\n\n // Final fallback to ID\n return a.id.localeCompare(b.id);\n });\n }\n}\n","import { AgentWidgetConfig, AgentWidgetTheme } from \"../types\";\n\n/**\n * Detects the current color scheme from the page.\n * 1. Checks if <html> element has 'dark' class\n * 2. Falls back to prefers-color-scheme media query\n */\nexport const detectColorScheme = (): 'light' | 'dark' => {\n // Check for 'dark' class on <html> element\n if (typeof document !== 'undefined' && document.documentElement.classList.contains('dark')) {\n return 'dark';\n }\n \n // Fall back to media query\n if (typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches) {\n return 'dark';\n }\n \n return 'light';\n};\n\n/**\n * Gets the active theme based on colorScheme setting and current detection.\n */\nexport const getActiveTheme = (config?: AgentWidgetConfig): AgentWidgetTheme => {\n const colorScheme = config?.colorScheme ?? 'light';\n const lightTheme = config?.theme ?? {};\n const darkTheme = config?.darkTheme ?? lightTheme;\n \n if (colorScheme === 'light') {\n return lightTheme;\n }\n \n if (colorScheme === 'dark') {\n return darkTheme;\n }\n \n // colorScheme === 'auto'\n const detectedScheme = detectColorScheme();\n return detectedScheme === 'dark' ? darkTheme : lightTheme;\n};\n\n/**\n * Creates observers for theme changes (HTML class and media query).\n * Returns a cleanup function.\n */\nexport const createThemeObserver = (\n callback: (scheme: 'light' | 'dark') => void\n): (() => void) => {\n const cleanupFns: Array<() => void> = [];\n \n // Observe HTML class changes\n if (typeof document !== 'undefined' && typeof MutationObserver !== 'undefined') {\n const observer = new MutationObserver(() => {\n callback(detectColorScheme());\n });\n \n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class']\n });\n \n cleanupFns.push(() => observer.disconnect());\n }\n \n // Observe media query changes\n if (typeof window !== 'undefined' && window.matchMedia) {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => callback(detectColorScheme());\n \n // Use addEventListener if available (modern browsers), otherwise addListener\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n cleanupFns.push(() => mediaQuery.removeEventListener('change', handleChange));\n } else if (mediaQuery.addListener) {\n // Legacy Safari\n mediaQuery.addListener(handleChange);\n cleanupFns.push(() => mediaQuery.removeListener(handleChange));\n }\n }\n \n return () => {\n cleanupFns.forEach(fn => fn());\n };\n};\n\nexport const applyThemeVariables = (\n element: HTMLElement,\n config?: AgentWidgetConfig\n) => {\n const theme = getActiveTheme(config);\n Object.entries(theme).forEach(([key, value]) => {\n // Skip undefined or empty values\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n // Convert camelCase to kebab-case (e.g., radiusSm → radius-sm)\n const kebabKey = key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);\n element.style.setProperty(`--cw-${kebabKey}`, String(value));\n });\n};\n\n\n\n\n","import * as icons from \"lucide\";\nimport type { IconNode } from \"lucide\";\n\n/**\n * Renders a Lucide icon as an inline SVG element\n * This approach requires no CSS and works on any page\n * \n * @param iconName - The Lucide icon name in kebab-case (e.g., \"arrow-up\")\n * @param size - The size of the icon (default: 24)\n * @param color - The stroke color (default: \"currentColor\")\n * @param strokeWidth - The stroke width (default: 2)\n * @returns SVGElement or null if icon not found\n */\nexport const renderLucideIcon = (\n iconName: string,\n size: number | string = 24,\n color: string = \"currentColor\",\n strokeWidth: number = 2\n): SVGElement | null => {\n try {\n // Convert kebab-case to PascalCase (e.g., \"arrow-up\" -> \"ArrowUp\")\n const pascalName = iconName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n \n // Lucide's icons object contains IconNode data directly, not functions\n const iconData = (icons as Record<string, IconNode>)[pascalName] as IconNode;\n \n if (!iconData) {\n console.warn(`Lucide icon \"${iconName}\" not found (tried \"${pascalName}\"). Available icons: https://lucide.dev/icons`);\n return null;\n }\n\n return createSvgFromIconData(iconData, size, color, strokeWidth);\n } catch (error) {\n console.warn(`Failed to render Lucide icon \"${iconName}\":`, error);\n return null;\n }\n};\n\n/**\n * Helper function to create SVG from IconNode data\n */\nfunction createSvgFromIconData(\n iconData: IconNode,\n size: number | string,\n color: string,\n strokeWidth: number\n): SVGElement | null {\n if (!iconData || !Array.isArray(iconData)) {\n return null;\n }\n\n // Create SVG element\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"width\", String(size));\n svg.setAttribute(\"height\", String(size));\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"fill\", \"none\");\n svg.setAttribute(\"stroke\", color);\n svg.setAttribute(\"stroke-width\", String(strokeWidth));\n svg.setAttribute(\"stroke-linecap\", \"round\");\n svg.setAttribute(\"stroke-linejoin\", \"round\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n \n // Render elements from icon data\n // IconNode format: [[\"path\", {\"d\": \"...\"}], [\"rect\", {\"x\": \"...\", \"y\": \"...\"}], ...]\n iconData.forEach((elementData) => {\n if (Array.isArray(elementData) && elementData.length >= 2) {\n const tagName = elementData[0] as string;\n const attrs = elementData[1] as Record<string, string>;\n \n if (attrs) {\n // Create the appropriate SVG element (path, rect, circle, ellipse, line, etc.)\n const element = document.createElementNS(\"http://www.w3.org/2000/svg\", tagName);\n \n // Apply all attributes, but skip 'stroke' (we want to use the parent SVG's stroke for consistent coloring)\n Object.entries(attrs).forEach(([key, value]) => {\n if (key !== \"stroke\") {\n element.setAttribute(key, String(value));\n }\n });\n \n svg.appendChild(element);\n }\n }\n });\n \n return svg;\n}\n\n","/**\n * DOM utility functions\n */\nexport const createElement = <K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string\n): HTMLElementTagNameMap[K] => {\n const element = document.createElement(tag);\n if (className) {\n element.className = className;\n }\n return element;\n};\n\nexport const createFragment = (): DocumentFragment => {\n return document.createDocumentFragment();\n};\n\n\n\n\n\n\n\n\n","import { Idiomorph } from \"idiomorph\";\n\nexport type MorphOptions = {\n preserveTypingAnimation?: boolean;\n};\n\n/**\n * Morph a container's contents using idiomorph with chat-widget-specific\n * preservation rules for typing indicators.\n *\n * Action buttons are matched by their `id` attribute (set to `actions-{messageId}`)\n * so idiomorph updates them in place rather than recreating them.\n */\nexport const morphMessages = (\n container: HTMLElement,\n newContent: HTMLElement,\n options: MorphOptions = {}\n): void => {\n const { preserveTypingAnimation = true } = options;\n\n Idiomorph.morph(container, newContent.innerHTML, {\n morphStyle: \"innerHTML\",\n callbacks: {\n beforeNodeMorphed(oldNode: Node, newNode: Node): boolean | void {\n if (!(oldNode instanceof HTMLElement)) return;\n\n // Preserve typing indicator dots to maintain animation continuity\n if (preserveTypingAnimation) {\n if (oldNode.classList.contains(\"tvw-animate-typing\")) {\n return false;\n }\n }\n },\n },\n });\n};\n","import { AgentWidgetSessionStatus } from \"../session\";\n\nexport const statusCopy: Record<AgentWidgetSessionStatus, string> = {\n idle: \"Online\",\n connecting: \"Connecting…\",\n connected: \"Streaming…\",\n error: \"Offline\"\n};\n\n\n\n\n\n\n\n\n","export const positionMap: Record<\n \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\",\n string\n> = {\n \"bottom-right\": \"tvw-bottom-6 tvw-right-6\",\n \"bottom-left\": \"tvw-bottom-6 tvw-left-6\",\n \"top-right\": \"tvw-top-6 tvw-right-6\",\n \"top-left\": \"tvw-top-6 tvw-left-6\"\n};\n\n\n\n\n\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetConfig } from \"../types\";\nimport { positionMap } from \"../utils/positioning\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\nexport interface LauncherButton {\n element: HTMLButtonElement;\n update: (config: AgentWidgetConfig) => void;\n destroy: () => void;\n}\n\nexport const createLauncherButton = (\n config: AgentWidgetConfig | undefined,\n onToggle: () => void\n): LauncherButton => {\n const button = createElement(\"button\") as HTMLButtonElement;\n button.type = \"button\";\n button.innerHTML = `\n <span class=\"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-bg-cw-primary tvw-text-white\" data-role=\"launcher-icon\">💬</span>\n <img data-role=\"launcher-image\" class=\"tvw-rounded-full tvw-object-cover\" alt=\"\" style=\"display:none\" />\n <span class=\"tvw-flex tvw-flex-col tvw-items-start tvw-text-left\">\n <span class=\"tvw-text-sm tvw-font-semibold tvw-text-cw-primary\" data-role=\"launcher-title\"></span>\n <span class=\"tvw-text-xs tvw-text-cw-muted\" data-role=\"launcher-subtitle\"></span>\n </span>\n <span class=\"tvw-ml-2 tvw-grid tvw-place-items-center tvw-rounded-full tvw-bg-cw-primary tvw-text-cw-call-to-action\" data-role=\"launcher-call-to-action-icon\">↗</span>\n `;\n button.addEventListener(\"click\", onToggle);\n\n const update = (newConfig: AgentWidgetConfig) => {\n const launcher = newConfig.launcher ?? {};\n\n const titleEl = button.querySelector(\"[data-role='launcher-title']\");\n if (titleEl) {\n titleEl.textContent = launcher.title ?? \"Chat Assistant\";\n }\n\n const subtitleEl = button.querySelector(\"[data-role='launcher-subtitle']\");\n if (subtitleEl) {\n subtitleEl.textContent = launcher.subtitle ?? \"Get answers fast\";\n }\n\n // Hide/show text container\n const textContainer = button.querySelector(\".tvw-flex-col\");\n if (textContainer) {\n if (launcher.textHidden) {\n (textContainer as HTMLElement).style.display = \"none\";\n } else {\n (textContainer as HTMLElement).style.display = \"\";\n }\n }\n\n const icon = button.querySelector<HTMLSpanElement>(\"[data-role='launcher-icon']\");\n if (icon) {\n if (launcher.agentIconHidden) {\n icon.style.display = \"none\";\n } else {\n const iconSize = launcher.agentIconSize ?? \"40px\";\n icon.style.height = iconSize;\n icon.style.width = iconSize;\n \n // Clear existing content\n icon.innerHTML = \"\";\n \n // Render icon based on priority: Lucide icon > iconUrl > agentIconText\n if (launcher.agentIconName) {\n // Use Lucide icon\n const iconSizeNum = parseFloat(iconSize) || 24;\n const iconSvg = renderLucideIcon(launcher.agentIconName, iconSizeNum * 0.6, \"#ffffff\", 2);\n if (iconSvg) {\n icon.appendChild(iconSvg);\n icon.style.display = \"\";\n } else {\n // Fallback to agentIconText if Lucide icon fails\n icon.textContent = launcher.agentIconText ?? \"💬\";\n icon.style.display = \"\";\n }\n } else if (launcher.iconUrl) {\n // Use image URL - hide icon span and show img\n icon.style.display = \"none\";\n } else {\n // Use text/emoji\n icon.textContent = launcher.agentIconText ?? \"💬\";\n icon.style.display = \"\";\n }\n }\n }\n\n const img = button.querySelector<HTMLImageElement>(\"[data-role='launcher-image']\");\n if (img) {\n const iconSize = launcher.agentIconSize ?? \"40px\";\n img.style.height = iconSize;\n img.style.width = iconSize;\n if (launcher.iconUrl && !launcher.agentIconName && !launcher.agentIconHidden) {\n // Only show image if not using Lucide icon and not hidden\n img.src = launcher.iconUrl;\n img.style.display = \"block\";\n } else {\n img.style.display = \"none\";\n }\n }\n\n const callToActionIconEl = button.querySelector<HTMLSpanElement>(\"[data-role='launcher-call-to-action-icon']\");\n if (callToActionIconEl) {\n const callToActionIconSize = launcher.callToActionIconSize ?? \"32px\";\n callToActionIconEl.style.height = callToActionIconSize;\n callToActionIconEl.style.width = callToActionIconSize;\n \n // Apply background color if configured\n if (launcher.callToActionIconBackgroundColor) {\n callToActionIconEl.style.backgroundColor = launcher.callToActionIconBackgroundColor;\n callToActionIconEl.classList.remove(\"tvw-bg-cw-primary\");\n } else {\n callToActionIconEl.style.backgroundColor = \"\";\n callToActionIconEl.classList.add(\"tvw-bg-cw-primary\");\n }\n \n // Calculate padding to adjust icon size\n let paddingTotal = 0;\n if (launcher.callToActionIconPadding) {\n callToActionIconEl.style.boxSizing = \"border-box\";\n callToActionIconEl.style.padding = launcher.callToActionIconPadding;\n // Parse padding value to calculate total padding (padding applies to both sides)\n const paddingValue = parseFloat(launcher.callToActionIconPadding) || 0;\n paddingTotal = paddingValue * 2; // padding on both sides\n } else {\n callToActionIconEl.style.boxSizing = \"\";\n callToActionIconEl.style.padding = \"\";\n }\n \n if (launcher.callToActionIconHidden) {\n callToActionIconEl.style.display = \"none\";\n } else {\n callToActionIconEl.style.display = \"\";\n \n // Clear existing content\n callToActionIconEl.innerHTML = \"\";\n \n // Use Lucide icon if provided, otherwise fall back to text\n if (launcher.callToActionIconName) {\n // Calculate actual icon size by subtracting padding\n const containerSize = parseFloat(callToActionIconSize) || 24;\n const iconSize = Math.max(containerSize - paddingTotal, 8); // Ensure minimum size of 8px\n const iconSvg = renderLucideIcon(launcher.callToActionIconName, iconSize, \"currentColor\", 2);\n if (iconSvg) {\n callToActionIconEl.appendChild(iconSvg);\n } else {\n // Fallback to text if icon fails to render\n callToActionIconEl.textContent = launcher.callToActionIconText ?? \"↗\";\n }\n } else {\n callToActionIconEl.textContent = launcher.callToActionIconText ?? \"↗\";\n }\n }\n }\n\n const positionClass =\n launcher.position && positionMap[launcher.position]\n ? positionMap[launcher.position]\n : positionMap[\"bottom-right\"];\n\n // Removed hardcoded border/shadow classes (tvw-shadow-lg, tvw-border, tvw-border-gray-200)\n // These are now applied via inline styles from config\n const base =\n \"tvw-fixed tvw-flex tvw-items-center tvw-gap-3 tvw-rounded-launcher tvw-bg-cw-surface tvw-py-2.5 tvw-pl-3 tvw-pr-3 tvw-transition hover:tvw-translate-y-[-2px] tvw-cursor-pointer tvw-z-50\";\n\n button.className = `${base} ${positionClass}`;\n \n // Apply launcher border and shadow from config (with defaults matching previous Tailwind classes)\n const defaultBorder = \"1px solid #e5e7eb\";\n const defaultShadow = \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)\";\n \n button.style.border = launcher.border ?? defaultBorder;\n button.style.boxShadow = launcher.shadow ?? defaultShadow;\n };\n\n const destroy = () => {\n button.removeEventListener(\"click\", onToggle);\n button.remove();\n };\n\n // Initial update\n if (config) {\n update(config);\n }\n\n return {\n element: button,\n update,\n destroy\n };\n};\n\n\n","import { createElement } from \"../utils/dom\";\nimport { renderLucideIcon } from \"../utils/icons\";\nimport { AgentWidgetConfig } from \"../types\";\n\nexport interface HeaderElements {\n header: HTMLElement;\n iconHolder: HTMLElement;\n headerTitle: HTMLElement;\n headerSubtitle: HTMLElement;\n closeButton: HTMLButtonElement;\n closeButtonWrapper: HTMLElement;\n clearChatButton: HTMLButtonElement | null;\n clearChatButtonWrapper: HTMLElement | null;\n}\n\nexport interface HeaderBuildContext {\n config?: AgentWidgetConfig;\n showClose?: boolean;\n onClose?: () => void;\n onClearChat?: () => void;\n}\n\n/**\n * Build the header section of the panel.\n * Extracted for reuse and plugin override support.\n */\nexport const buildHeader = (context: HeaderBuildContext): HeaderElements => {\n const { config, showClose = true } = context;\n\n const header = createElement(\n \"div\",\n \"tvw-widget-header tvw-flex tvw-items-center tvw-gap-3 tvw-bg-cw-surface tvw-px-6 tvw-py-5 tvw-border-b-cw-divider\"\n );\n\n const launcher = config?.launcher ?? {};\n const headerIconSize = launcher.headerIconSize ?? \"48px\";\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonPlacement = launcher.closeButtonPlacement ?? \"inline\";\n const headerIconHidden = launcher.headerIconHidden ?? false;\n const headerIconName = launcher.headerIconName;\n\n const iconHolder = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-center tvw-rounded-xl tvw-bg-cw-primary tvw-text-white tvw-text-xl\"\n );\n iconHolder.style.height = headerIconSize;\n iconHolder.style.width = headerIconSize;\n\n // Render icon based on priority: Lucide icon > iconUrl > agentIconText\n if (!headerIconHidden) {\n if (headerIconName) {\n // Use Lucide icon\n const iconSize = parseFloat(headerIconSize) || 24;\n const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.6, \"#ffffff\", 2);\n if (iconSvg) {\n iconHolder.replaceChildren(iconSvg);\n } else {\n // Fallback to agentIconText if Lucide icon fails\n iconHolder.textContent = config?.launcher?.agentIconText ?? \"💬\";\n }\n } else if (config?.launcher?.iconUrl) {\n // Use image URL\n const img = createElement(\"img\") as HTMLImageElement;\n img.src = config.launcher.iconUrl;\n img.alt = \"\";\n img.className = \"tvw-rounded-xl tvw-object-cover\";\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n iconHolder.replaceChildren(img);\n } else {\n // Use text/emoji\n iconHolder.textContent = config?.launcher?.agentIconText ?? \"💬\";\n }\n }\n\n const headerCopy = createElement(\"div\", \"tvw-flex tvw-flex-col\");\n const title = createElement(\"span\", \"tvw-text-base tvw-font-semibold\");\n title.textContent = config?.launcher?.title ?? \"Chat Assistant\";\n const subtitle = createElement(\"span\", \"tvw-text-xs tvw-text-cw-muted\");\n subtitle.textContent =\n config?.launcher?.subtitle ?? \"Here to help you get answers fast\";\n\n headerCopy.append(title, subtitle);\n\n // Only append iconHolder if not hidden\n if (!headerIconHidden) {\n header.append(iconHolder, headerCopy);\n } else {\n header.append(headerCopy);\n }\n\n // Create clear chat button if enabled\n const clearChatConfig = launcher.clearChat ?? {};\n const clearChatEnabled = clearChatConfig.enabled ?? true;\n const clearChatPlacement = clearChatConfig.placement ?? \"inline\";\n let clearChatButton: HTMLButtonElement | null = null;\n let clearChatButtonWrapper: HTMLElement | null = null;\n\n if (clearChatEnabled) {\n const clearChatSize = clearChatConfig.size ?? \"32px\";\n const clearChatIconName = clearChatConfig.iconName ?? \"refresh-cw\";\n const clearChatIconColor = clearChatConfig.iconColor ?? \"\";\n const clearChatBgColor = clearChatConfig.backgroundColor ?? \"\";\n const clearChatBorderWidth = clearChatConfig.borderWidth ?? \"\";\n const clearChatBorderColor = clearChatConfig.borderColor ?? \"\";\n const clearChatBorderRadius = clearChatConfig.borderRadius ?? \"\";\n const clearChatPaddingX = clearChatConfig.paddingX ?? \"\";\n const clearChatPaddingY = clearChatConfig.paddingY ?? \"\";\n const clearChatTooltipText = clearChatConfig.tooltipText ?? \"Clear chat\";\n const clearChatShowTooltip = clearChatConfig.showTooltip ?? true;\n\n // Create button wrapper for tooltip - positioned based on placement\n // Note: Don't use tvw-clear-chat-button-wrapper class for top-right mode as its\n // display: inline-flex causes alignment issues with the close button\n clearChatButtonWrapper = createElement(\n \"div\",\n clearChatPlacement === \"top-right\"\n ? \"tvw-absolute tvw-top-4 tvw-z-50\"\n : \"tvw-relative tvw-ml-auto tvw-clear-chat-button-wrapper\"\n );\n\n // Position to the left of the close button (which is at right: 1rem/16px)\n // Close button is ~32px wide, plus small gap = 48px from right\n if (clearChatPlacement === \"top-right\") {\n clearChatButtonWrapper.style.right = \"48px\";\n }\n\n clearChatButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n\n clearChatButton.style.height = clearChatSize;\n clearChatButton.style.width = clearChatSize;\n clearChatButton.type = \"button\";\n clearChatButton.setAttribute(\"aria-label\", clearChatTooltipText);\n\n // Add icon\n const iconSvg = renderLucideIcon(\n clearChatIconName,\n \"20px\",\n clearChatIconColor || \"\",\n 2\n );\n if (iconSvg) {\n clearChatButton.appendChild(iconSvg);\n }\n\n // Apply styling from config\n if (clearChatIconColor) {\n clearChatButton.style.color = clearChatIconColor;\n clearChatButton.classList.remove(\"tvw-text-cw-muted\");\n }\n\n if (clearChatBgColor) {\n clearChatButton.style.backgroundColor = clearChatBgColor;\n clearChatButton.classList.remove(\"hover:tvw-bg-gray-100\");\n }\n\n if (clearChatBorderWidth || clearChatBorderColor) {\n const borderWidth = clearChatBorderWidth || \"0px\";\n const borderColor = clearChatBorderColor || \"transparent\";\n clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;\n clearChatButton.classList.remove(\"tvw-border-none\");\n }\n\n if (clearChatBorderRadius) {\n clearChatButton.style.borderRadius = clearChatBorderRadius;\n clearChatButton.classList.remove(\"tvw-rounded-full\");\n }\n\n // Apply padding styling\n if (clearChatPaddingX) {\n clearChatButton.style.paddingLeft = clearChatPaddingX;\n clearChatButton.style.paddingRight = clearChatPaddingX;\n } else {\n clearChatButton.style.paddingLeft = \"\";\n clearChatButton.style.paddingRight = \"\";\n }\n if (clearChatPaddingY) {\n clearChatButton.style.paddingTop = clearChatPaddingY;\n clearChatButton.style.paddingBottom = clearChatPaddingY;\n } else {\n clearChatButton.style.paddingTop = \"\";\n clearChatButton.style.paddingBottom = \"\";\n }\n\n clearChatButtonWrapper.appendChild(clearChatButton);\n\n // Add tooltip with portaling to document.body to escape overflow clipping\n if (\n clearChatShowTooltip &&\n clearChatTooltipText &&\n clearChatButton &&\n clearChatButtonWrapper\n ) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip || !clearChatButton) return; // Already showing or button doesn't exist\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = clearChatTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = clearChatButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n clearChatButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n clearChatButton.addEventListener(\"focus\", showTooltip);\n clearChatButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the button for later use\n (clearChatButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n }\n if (clearChatButton) {\n clearChatButton.removeEventListener(\"focus\", showTooltip);\n clearChatButton.removeEventListener(\"blur\", hideTooltip);\n }\n };\n }\n\n // Only append to header if inline placement\n if (clearChatPlacement === \"inline\") {\n header.appendChild(clearChatButtonWrapper);\n }\n }\n\n // Create close button wrapper for tooltip positioning\n // Only needs ml-auto if clear chat is disabled or top-right positioned\n const closeButtonWrapper = createElement(\n \"div\",\n closeButtonPlacement === \"top-right\"\n ? \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50\"\n : clearChatEnabled && clearChatPlacement === \"inline\"\n ? \"\"\n : \"tvw-ml-auto\"\n );\n\n // Create close button with base classes\n const closeButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n closeButton.type = \"button\";\n\n // Get tooltip config\n const closeButtonTooltipText = launcher.closeButtonTooltipText ?? \"Close chat\";\n const closeButtonShowTooltip = launcher.closeButtonShowTooltip ?? true;\n\n closeButton.setAttribute(\"aria-label\", closeButtonTooltipText);\n closeButton.style.display = showClose ? \"\" : \"none\";\n\n // Add icon or fallback text\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeButtonIconText = launcher.closeButtonIconText ?? \"×\";\n\n // Try to render Lucide icon, fallback to text if not provided or fails\n const closeIconSvg = renderLucideIcon(\n closeButtonIconName,\n \"20px\",\n launcher.closeButtonColor || \"\",\n 2\n );\n if (closeIconSvg) {\n closeButton.appendChild(closeIconSvg);\n } else {\n closeButton.textContent = closeButtonIconText;\n }\n\n // Apply close button styling from config\n if (launcher.closeButtonColor) {\n closeButton.style.color = launcher.closeButtonColor;\n closeButton.classList.remove(\"tvw-text-cw-muted\");\n } else {\n closeButton.style.color = \"\";\n closeButton.classList.add(\"tvw-text-cw-muted\");\n }\n\n if (launcher.closeButtonBackgroundColor) {\n closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;\n closeButton.classList.remove(\"hover:tvw-bg-gray-100\");\n } else {\n closeButton.style.backgroundColor = \"\";\n closeButton.classList.add(\"hover:tvw-bg-gray-100\");\n }\n\n // Apply border if width and/or color are provided\n if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {\n const borderWidth = launcher.closeButtonBorderWidth || \"0px\";\n const borderColor = launcher.closeButtonBorderColor || \"transparent\";\n closeButton.style.border = `${borderWidth} solid ${borderColor}`;\n closeButton.classList.remove(\"tvw-border-none\");\n } else {\n closeButton.style.border = \"\";\n closeButton.classList.add(\"tvw-border-none\");\n }\n\n if (launcher.closeButtonBorderRadius) {\n closeButton.style.borderRadius = launcher.closeButtonBorderRadius;\n closeButton.classList.remove(\"tvw-rounded-full\");\n } else {\n closeButton.style.borderRadius = \"\";\n closeButton.classList.add(\"tvw-rounded-full\");\n }\n\n // Apply padding styling\n if (launcher.closeButtonPaddingX) {\n closeButton.style.paddingLeft = launcher.closeButtonPaddingX;\n closeButton.style.paddingRight = launcher.closeButtonPaddingX;\n } else {\n closeButton.style.paddingLeft = \"\";\n closeButton.style.paddingRight = \"\";\n }\n if (launcher.closeButtonPaddingY) {\n closeButton.style.paddingTop = launcher.closeButtonPaddingY;\n closeButton.style.paddingBottom = launcher.closeButtonPaddingY;\n } else {\n closeButton.style.paddingTop = \"\";\n closeButton.style.paddingBottom = \"\";\n }\n\n closeButtonWrapper.appendChild(closeButton);\n\n // Add tooltip with portaling to document.body to escape overflow clipping\n if (closeButtonShowTooltip && closeButtonTooltipText) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip) return; // Already showing\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = closeButtonTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = closeButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n closeButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n closeButton.addEventListener(\"focus\", showTooltip);\n closeButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the wrapper for later use\n (closeButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n closeButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n closeButton.removeEventListener(\"focus\", showTooltip);\n closeButton.removeEventListener(\"blur\", hideTooltip);\n };\n }\n\n // Inline placement: append close button to header\n if (closeButtonPlacement !== \"top-right\") {\n header.appendChild(closeButtonWrapper);\n }\n\n return {\n header,\n iconHolder,\n headerTitle: title,\n headerSubtitle: subtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton,\n clearChatButtonWrapper\n };\n};\n\n/**\n * Attach header elements to the container, handling placement modes.\n */\nexport const attachHeaderToContainer = (\n container: HTMLElement,\n headerElements: HeaderElements,\n config?: AgentWidgetConfig\n): void => {\n const launcher = config?.launcher ?? {};\n const closeButtonPlacement = launcher.closeButtonPlacement ?? \"inline\";\n const clearChatPlacement = launcher.clearChat?.placement ?? \"inline\";\n\n // Add header to container\n container.appendChild(headerElements.header);\n\n // Position close button wrapper if top-right placement\n if (closeButtonPlacement === \"top-right\") {\n container.style.position = \"relative\";\n container.appendChild(headerElements.closeButtonWrapper);\n }\n\n // Position clear chat button wrapper if top-right placement\n if (\n headerElements.clearChatButtonWrapper &&\n clearChatPlacement === \"top-right\"\n ) {\n container.style.position = \"relative\";\n container.appendChild(headerElements.clearChatButtonWrapper);\n }\n};\n\n\n","import { createElement } from \"../utils/dom\";\nimport { renderLucideIcon } from \"../utils/icons\";\nimport { AgentWidgetConfig, AgentWidgetHeaderLayoutConfig } from \"../types\";\nimport { buildHeader, HeaderElements, attachHeaderToContainer } from \"./header-builder\";\n\nexport interface HeaderLayoutContext {\n config: AgentWidgetConfig;\n showClose?: boolean;\n onClose?: () => void;\n onClearChat?: () => void;\n}\n\nexport type HeaderLayoutRenderer = (context: HeaderLayoutContext) => HeaderElements;\n\n/**\n * Build default header layout\n * Full header with icon, title, subtitle, clear chat, and close button\n */\nexport const buildDefaultHeader: HeaderLayoutRenderer = (context) => {\n return buildHeader({\n config: context.config,\n showClose: context.showClose,\n onClose: context.onClose,\n onClearChat: context.onClearChat\n });\n};\n\n/**\n * Build minimal header layout\n * Simplified layout with just title and close button\n */\nexport const buildMinimalHeader: HeaderLayoutRenderer = (context) => {\n const { config, showClose = true, onClose } = context;\n const launcher = config?.launcher ?? {};\n\n const header = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-between tvw-bg-cw-surface tvw-px-6 tvw-py-4 tvw-border-b-cw-divider\"\n );\n\n // Title only (no icon, no subtitle)\n const title = createElement(\"span\", \"tvw-text-base tvw-font-semibold\");\n title.textContent = launcher.title ?? \"Chat Assistant\";\n\n header.appendChild(title);\n\n // Close button\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonWrapper = createElement(\"div\", \"\");\n\n const closeButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n closeButton.type = \"button\";\n closeButton.setAttribute(\"aria-label\", \"Close chat\");\n closeButton.style.display = showClose ? \"\" : \"none\";\n\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeIconSvg = renderLucideIcon(\n closeButtonIconName,\n \"20px\",\n launcher.closeButtonColor || \"\",\n 2\n );\n if (closeIconSvg) {\n closeButton.appendChild(closeIconSvg);\n } else {\n closeButton.textContent = \"×\";\n }\n\n if (onClose) {\n closeButton.addEventListener(\"click\", onClose);\n }\n\n closeButtonWrapper.appendChild(closeButton);\n header.appendChild(closeButtonWrapper);\n\n // Create placeholder elements for compatibility\n const iconHolder = createElement(\"div\");\n iconHolder.style.display = \"none\";\n const headerSubtitle = createElement(\"span\");\n headerSubtitle.style.display = \"none\";\n\n return {\n header,\n iconHolder,\n headerTitle: title,\n headerSubtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton: null,\n clearChatButtonWrapper: null\n };\n};\n\n/**\n * Build expanded header layout\n * Full branding area with additional space for custom content\n */\nexport const buildExpandedHeader: HeaderLayoutRenderer = (context) => {\n const { config, showClose = true, onClose, onClearChat } = context;\n const launcher = config?.launcher ?? {};\n\n const header = createElement(\n \"div\",\n \"tvw-flex tvw-flex-col tvw-bg-cw-surface tvw-px-6 tvw-py-5 tvw-border-b-cw-divider\"\n );\n\n // Top row: icon + text + buttons\n const topRow = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-gap-3\"\n );\n\n // Icon\n const headerIconSize = launcher.headerIconSize ?? \"56px\";\n const iconHolder = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-center tvw-rounded-xl tvw-bg-cw-primary tvw-text-white tvw-text-2xl\"\n );\n iconHolder.style.height = headerIconSize;\n iconHolder.style.width = headerIconSize;\n\n const headerIconName = launcher.headerIconName;\n if (headerIconName) {\n const iconSize = parseFloat(headerIconSize) || 24;\n const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.5, \"#ffffff\", 2);\n if (iconSvg) {\n iconHolder.replaceChildren(iconSvg);\n } else {\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n } else if (launcher.iconUrl) {\n const img = createElement(\"img\") as HTMLImageElement;\n img.src = launcher.iconUrl;\n img.alt = \"\";\n img.className = \"tvw-rounded-xl tvw-object-cover\";\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n iconHolder.replaceChildren(img);\n } else {\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n\n // Title and subtitle\n const headerCopy = createElement(\"div\", \"tvw-flex tvw-flex-col tvw-flex-1\");\n const title = createElement(\"span\", \"tvw-text-lg tvw-font-semibold\");\n title.textContent = launcher.title ?? \"Chat Assistant\";\n const subtitle = createElement(\"span\", \"tvw-text-sm tvw-text-cw-muted\");\n subtitle.textContent = launcher.subtitle ?? \"Here to help you get answers fast\";\n headerCopy.append(title, subtitle);\n\n topRow.append(iconHolder, headerCopy);\n\n // Close button\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonWrapper = createElement(\"div\", \"\");\n\n const closeButton = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n closeButton.type = \"button\";\n closeButton.setAttribute(\"aria-label\", \"Close chat\");\n closeButton.style.display = showClose ? \"\" : \"none\";\n\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeIconSvg = renderLucideIcon(\n closeButtonIconName,\n \"20px\",\n launcher.closeButtonColor || \"\",\n 2\n );\n if (closeIconSvg) {\n closeButton.appendChild(closeIconSvg);\n } else {\n closeButton.textContent = \"×\";\n }\n\n if (onClose) {\n closeButton.addEventListener(\"click\", onClose);\n }\n\n closeButtonWrapper.appendChild(closeButton);\n topRow.appendChild(closeButtonWrapper);\n\n header.appendChild(topRow);\n\n // Bottom row: additional space for status or branding\n const bottomRow = createElement(\n \"div\",\n \"tvw-mt-3 tvw-pt-3 tvw-border-t tvw-border-gray-100 tvw-text-xs tvw-text-cw-muted\"\n );\n bottomRow.textContent = \"Online and ready to help\";\n header.appendChild(bottomRow);\n\n return {\n header,\n iconHolder,\n headerTitle: title,\n headerSubtitle: subtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton: null,\n clearChatButtonWrapper: null\n };\n};\n\n/**\n * Header layout registry\n * Maps layout names to their renderer functions\n */\nexport const headerLayouts: Record<string, HeaderLayoutRenderer> = {\n default: buildDefaultHeader,\n minimal: buildMinimalHeader,\n expanded: buildExpandedHeader\n};\n\n/**\n * Get header layout renderer by name\n */\nexport const getHeaderLayout = (layoutName: string): HeaderLayoutRenderer => {\n return headerLayouts[layoutName] ?? headerLayouts.default;\n};\n\n/**\n * Build header based on layout configuration\n * Applies layout config settings to determine which layout to use\n */\nexport const buildHeaderWithLayout = (\n config: AgentWidgetConfig,\n layoutConfig?: AgentWidgetHeaderLayoutConfig,\n context?: Partial<HeaderLayoutContext>\n): HeaderElements => {\n // If custom render is provided, use it\n if (layoutConfig?.render) {\n const customHeader = layoutConfig.render({\n config,\n onClose: context?.onClose,\n onClearChat: context?.onClearChat\n });\n \n // Wrap in HeaderElements structure\n const iconHolder = createElement(\"div\");\n iconHolder.style.display = \"none\";\n const headerTitle = createElement(\"span\");\n const headerSubtitle = createElement(\"span\");\n const closeButton = createElement(\"button\") as HTMLButtonElement;\n closeButton.style.display = \"none\";\n const closeButtonWrapper = createElement(\"div\");\n closeButtonWrapper.style.display = \"none\";\n \n return {\n header: customHeader,\n iconHolder,\n headerTitle,\n headerSubtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton: null,\n clearChatButtonWrapper: null\n };\n }\n\n // Get layout renderer\n const layoutName = layoutConfig?.layout ?? \"default\";\n const layoutRenderer = getHeaderLayout(layoutName);\n\n // Build header with layout\n const headerElements = layoutRenderer({\n config,\n showClose: layoutConfig?.showCloseButton ?? context?.showClose ?? true,\n onClose: context?.onClose,\n onClearChat: context?.onClearChat\n });\n\n // Apply visibility settings from layout config\n if (layoutConfig) {\n if (layoutConfig.showIcon === false) {\n headerElements.iconHolder.style.display = \"none\";\n }\n if (layoutConfig.showTitle === false) {\n headerElements.headerTitle.style.display = \"none\";\n }\n if (layoutConfig.showSubtitle === false) {\n headerElements.headerSubtitle.style.display = \"none\";\n }\n if (layoutConfig.showCloseButton === false) {\n headerElements.closeButton.style.display = \"none\";\n }\n if (layoutConfig.showClearChat === false && headerElements.clearChatButtonWrapper) {\n headerElements.clearChatButtonWrapper.style.display = \"none\";\n }\n }\n\n return headerElements;\n};\n\n","import { createElement } from \"../utils/dom\";\nimport { renderLucideIcon } from \"../utils/icons\";\nimport { AgentWidgetConfig } from \"../types\";\n\nexport interface ComposerElements {\n footer: HTMLElement;\n suggestions: HTMLElement;\n composerForm: HTMLFormElement;\n textarea: HTMLTextAreaElement;\n sendButton: HTMLButtonElement;\n sendButtonWrapper: HTMLElement;\n micButton: HTMLButtonElement | null;\n micButtonWrapper: HTMLElement | null;\n statusText: HTMLElement;\n}\n\nexport interface ComposerBuildContext {\n config?: AgentWidgetConfig;\n onSubmit?: (text: string) => void;\n disabled?: boolean;\n}\n\n/**\n * Helper to get font family CSS value from config preset\n */\nconst getFontFamilyValue = (\n family: \"sans-serif\" | \"serif\" | \"mono\"\n): string => {\n switch (family) {\n case \"serif\":\n return 'Georgia, \"Times New Roman\", Times, serif';\n case \"mono\":\n return '\"Courier New\", Courier, \"Lucida Console\", Monaco, monospace';\n case \"sans-serif\":\n default:\n return '-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif';\n }\n};\n\n/**\n * Build the composer/footer section of the panel.\n * Extracted for reuse and plugin override support.\n */\nexport const buildComposer = (context: ComposerBuildContext): ComposerElements => {\n const { config } = context;\n\n const footer = createElement(\n \"div\",\n \"tvw-widget-footer tvw-border-t-cw-divider tvw-bg-cw-surface tvw-px-6 tvw-py-4\"\n );\n\n const suggestions = createElement(\n \"div\",\n \"tvw-mb-3 tvw-flex tvw-flex-wrap tvw-gap-2\"\n );\n\n // Determine gap based on voice recognition\n const voiceRecognitionEnabledForGap =\n config?.voiceRecognition?.enabled === true;\n const hasSpeechRecognitionForGap =\n typeof window !== \"undefined\" &&\n (typeof (window as any).webkitSpeechRecognition !== \"undefined\" ||\n typeof (window as any).SpeechRecognition !== \"undefined\");\n const shouldUseSmallGap =\n voiceRecognitionEnabledForGap && hasSpeechRecognitionForGap;\n const gapClass = shouldUseSmallGap ? \"tvw-gap-1\" : \"tvw-gap-3\";\n\n const composerForm = createElement(\n \"form\",\n `tvw-widget-composer tvw-flex tvw-items-end ${gapClass} tvw-rounded-2xl tvw-border tvw-border-gray-200 tvw-bg-cw-input-background tvw-px-4 tvw-py-3`\n ) as HTMLFormElement;\n // Prevent form from getting focus styles\n composerForm.style.outline = \"none\";\n\n const textarea = createElement(\"textarea\") as HTMLTextAreaElement;\n textarea.placeholder = config?.copy?.inputPlaceholder ?? \"Type your message…\";\n textarea.className =\n \"tvw-min-h-[48px] tvw-flex-1 tvw-resize-none tvw-border-none tvw-bg-transparent tvw-text-sm tvw-text-cw-primary focus:tvw-outline-none focus:tvw-border-none\";\n textarea.rows = 1;\n\n // Apply font family and weight from config\n const fontFamily = config?.theme?.inputFontFamily ?? \"sans-serif\";\n const fontWeight = config?.theme?.inputFontWeight ?? \"400\";\n\n textarea.style.fontFamily = getFontFamilyValue(fontFamily);\n textarea.style.fontWeight = fontWeight;\n\n // Explicitly remove border and outline on focus to prevent browser defaults\n textarea.style.border = \"none\";\n textarea.style.outline = \"none\";\n textarea.style.borderWidth = \"0\";\n textarea.style.borderStyle = \"none\";\n textarea.style.borderColor = \"transparent\";\n textarea.addEventListener(\"focus\", () => {\n textarea.style.border = \"none\";\n textarea.style.outline = \"none\";\n textarea.style.borderWidth = \"0\";\n textarea.style.borderStyle = \"none\";\n textarea.style.borderColor = \"transparent\";\n textarea.style.boxShadow = \"none\";\n });\n textarea.addEventListener(\"blur\", () => {\n textarea.style.border = \"none\";\n textarea.style.outline = \"none\";\n });\n\n // Send button configuration\n const sendButtonConfig = config?.sendButton ?? {};\n const useIcon = sendButtonConfig.useIcon ?? false;\n const iconText = sendButtonConfig.iconText ?? \"↑\";\n const iconName = sendButtonConfig.iconName;\n const tooltipText = sendButtonConfig.tooltipText ?? \"Send message\";\n const showTooltip = sendButtonConfig.showTooltip ?? false;\n const buttonSize = sendButtonConfig.size ?? \"40px\";\n const backgroundColor = sendButtonConfig.backgroundColor;\n const textColor = sendButtonConfig.textColor;\n\n // Create wrapper for tooltip positioning\n const sendButtonWrapper = createElement(\"div\", \"tvw-send-button-wrapper\");\n\n const sendButton = createElement(\n \"button\",\n useIcon\n ? \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\"\n : \"tvw-rounded-button tvw-bg-cw-accent tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold disabled:tvw-opacity-50 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n\n sendButton.type = \"submit\";\n\n if (useIcon) {\n // Icon mode: circular button\n sendButton.style.width = buttonSize;\n sendButton.style.height = buttonSize;\n sendButton.style.minWidth = buttonSize;\n sendButton.style.minHeight = buttonSize;\n sendButton.style.fontSize = \"18px\";\n sendButton.style.lineHeight = \"1\";\n\n // Clear any existing content\n sendButton.innerHTML = \"\";\n\n // Use Lucide icon if iconName is provided, otherwise fall back to iconText\n if (iconName) {\n const iconSize = parseFloat(buttonSize) || 24;\n const iconColor =\n textColor && typeof textColor === \"string\" && textColor.trim()\n ? textColor.trim()\n : \"currentColor\";\n const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);\n if (iconSvg) {\n sendButton.appendChild(iconSvg);\n sendButton.style.color = iconColor;\n } else {\n // Fallback to text if icon fails to render\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n } else {\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n\n if (backgroundColor) {\n sendButton.style.backgroundColor = backgroundColor;\n } else {\n sendButton.classList.add(\"tvw-bg-cw-primary\");\n }\n } else {\n // Text mode: existing behavior\n sendButton.textContent = config?.copy?.sendButtonLabel ?? \"Send\";\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n\n // Apply existing styling from config\n if (sendButtonConfig.borderWidth) {\n sendButton.style.borderWidth = sendButtonConfig.borderWidth;\n sendButton.style.borderStyle = \"solid\";\n }\n if (sendButtonConfig.borderColor) {\n sendButton.style.borderColor = sendButtonConfig.borderColor;\n }\n\n // Apply padding styling (works in both icon and text mode)\n if (sendButtonConfig.paddingX) {\n sendButton.style.paddingLeft = sendButtonConfig.paddingX;\n sendButton.style.paddingRight = sendButtonConfig.paddingX;\n } else {\n sendButton.style.paddingLeft = \"\";\n sendButton.style.paddingRight = \"\";\n }\n if (sendButtonConfig.paddingY) {\n sendButton.style.paddingTop = sendButtonConfig.paddingY;\n sendButton.style.paddingBottom = sendButtonConfig.paddingY;\n } else {\n sendButton.style.paddingTop = \"\";\n sendButton.style.paddingBottom = \"\";\n }\n\n // Add tooltip if enabled\n if (showTooltip && tooltipText) {\n const tooltip = createElement(\"div\", \"tvw-send-button-tooltip\");\n tooltip.textContent = tooltipText;\n sendButtonWrapper.appendChild(tooltip);\n }\n\n sendButtonWrapper.appendChild(sendButton);\n\n // Voice recognition mic button\n const voiceRecognitionConfig = config?.voiceRecognition ?? {};\n const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;\n let micButton: HTMLButtonElement | null = null;\n let micButtonWrapper: HTMLElement | null = null;\n\n // Check browser support for speech recognition\n const hasSpeechRecognition =\n typeof window !== \"undefined\" &&\n (typeof (window as any).webkitSpeechRecognition !== \"undefined\" ||\n typeof (window as any).SpeechRecognition !== \"undefined\");\n\n if (voiceRecognitionEnabled && hasSpeechRecognition) {\n micButtonWrapper = createElement(\"div\", \"tvw-send-button-wrapper\");\n micButton = createElement(\n \"button\",\n \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n\n micButton.type = \"button\";\n micButton.setAttribute(\"aria-label\", \"Start voice recognition\");\n\n const micIconName = voiceRecognitionConfig.iconName ?? \"mic\";\n const micIconSize = voiceRecognitionConfig.iconSize ?? buttonSize;\n const micIconSizeNum = parseFloat(micIconSize) || 24;\n\n // Use dedicated colors from voice recognition config, fallback to send button colors\n const micBackgroundColor =\n voiceRecognitionConfig.backgroundColor ?? backgroundColor;\n const micIconColor = voiceRecognitionConfig.iconColor ?? textColor;\n\n micButton.style.width = micIconSize;\n micButton.style.height = micIconSize;\n micButton.style.minWidth = micIconSize;\n micButton.style.minHeight = micIconSize;\n micButton.style.fontSize = \"18px\";\n micButton.style.lineHeight = \"1\";\n\n // Use Lucide mic icon with configured color (stroke width 1.5 for minimalist outline style)\n const iconColorValue = micIconColor || \"currentColor\";\n const micIconSvg = renderLucideIcon(\n micIconName,\n micIconSizeNum,\n iconColorValue,\n 1.5\n );\n if (micIconSvg) {\n micButton.appendChild(micIconSvg);\n micButton.style.color = iconColorValue;\n } else {\n // Fallback to text if icon fails\n micButton.textContent = \"🎤\";\n micButton.style.color = iconColorValue;\n }\n\n // Apply background color\n if (micBackgroundColor) {\n micButton.style.backgroundColor = micBackgroundColor;\n } else {\n micButton.classList.add(\"tvw-bg-cw-primary\");\n }\n\n // Apply icon/text color\n if (micIconColor) {\n micButton.style.color = micIconColor;\n } else if (!micIconColor && !textColor) {\n micButton.classList.add(\"tvw-text-white\");\n }\n\n // Apply border styling\n if (voiceRecognitionConfig.borderWidth) {\n micButton.style.borderWidth = voiceRecognitionConfig.borderWidth;\n micButton.style.borderStyle = \"solid\";\n }\n if (voiceRecognitionConfig.borderColor) {\n micButton.style.borderColor = voiceRecognitionConfig.borderColor;\n }\n\n // Apply padding styling\n if (voiceRecognitionConfig.paddingX) {\n micButton.style.paddingLeft = voiceRecognitionConfig.paddingX;\n micButton.style.paddingRight = voiceRecognitionConfig.paddingX;\n }\n if (voiceRecognitionConfig.paddingY) {\n micButton.style.paddingTop = voiceRecognitionConfig.paddingY;\n micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;\n }\n\n micButtonWrapper.appendChild(micButton);\n\n // Add tooltip if enabled\n const micTooltipText =\n voiceRecognitionConfig.tooltipText ?? \"Start voice recognition\";\n const showMicTooltip = voiceRecognitionConfig.showTooltip ?? false;\n if (showMicTooltip && micTooltipText) {\n const tooltip = createElement(\"div\", \"tvw-send-button-tooltip\");\n tooltip.textContent = micTooltipText;\n micButtonWrapper.appendChild(tooltip);\n }\n }\n\n // Focus textarea when composer form container is clicked\n composerForm.addEventListener(\"click\", (e) => {\n // Don't focus if clicking on the send button, mic button, or their wrappers\n if (\n e.target !== sendButton &&\n e.target !== sendButtonWrapper &&\n e.target !== micButton &&\n e.target !== micButtonWrapper\n ) {\n textarea.focus();\n }\n });\n\n // Append elements: textarea, mic button (if exists), send button\n composerForm.append(textarea);\n if (micButtonWrapper) {\n composerForm.append(micButtonWrapper);\n }\n composerForm.append(sendButtonWrapper);\n\n const statusText = createElement(\n \"div\",\n \"tvw-mt-2 tvw-text-right tvw-text-xs tvw-text-cw-muted\"\n );\n\n // Apply status indicator config\n const statusConfig = config?.statusIndicator ?? {};\n const isVisible = statusConfig.visible ?? true;\n statusText.style.display = isVisible ? \"\" : \"none\";\n statusText.textContent = statusConfig.idleText ?? \"Online\";\n\n footer.append(suggestions, composerForm, statusText);\n\n return {\n footer,\n suggestions,\n composerForm,\n textarea,\n sendButton,\n sendButtonWrapper,\n micButton,\n micButtonWrapper,\n statusText\n };\n};\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetConfig } from \"../types\";\nimport { positionMap } from \"../utils/positioning\";\nimport { buildHeader, attachHeaderToContainer, HeaderElements } from \"./header-builder\";\nimport { buildHeaderWithLayout } from \"./header-layouts\";\nimport { buildComposer, ComposerElements } from \"./composer-builder\";\n\nexport interface PanelWrapper {\n wrapper: HTMLElement;\n panel: HTMLElement;\n}\n\nexport const createWrapper = (config?: AgentWidgetConfig): PanelWrapper => {\n const launcherEnabled = config?.launcher?.enabled ?? true;\n\n if (!launcherEnabled) {\n // For inline embed mode, use flex layout to ensure the widget fills its container\n // and only the chat messages area scrolls\n const wrapper = createElement(\n \"div\",\n \"tvw-relative tvw-h-full tvw-flex tvw-flex-col tvw-flex-1 tvw-min-h-0\"\n );\n const panel = createElement(\n \"div\",\n \"tvw-relative tvw-flex-1 tvw-flex tvw-flex-col tvw-min-h-0\"\n );\n \n // Apply width from config, defaulting to 100% for inline embed mode\n const inlineWidth = config?.launcher?.width ?? \"100%\";\n wrapper.style.width = inlineWidth;\n panel.style.width = \"100%\";\n \n wrapper.appendChild(panel);\n return { wrapper, panel };\n }\n\n const launcher = config?.launcher ?? {};\n const position =\n launcher.position && positionMap[launcher.position]\n ? positionMap[launcher.position]\n : positionMap[\"bottom-right\"];\n\n const wrapper = createElement(\n \"div\",\n `tvw-widget-wrapper tvw-fixed ${position} tvw-z-50 tvw-transition`\n );\n\n const panel = createElement(\n \"div\",\n \"tvw-widget-panel tvw-relative tvw-min-h-[320px]\"\n );\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(400px, calc(100vw - 24px))\";\n panel.style.width = width;\n panel.style.maxWidth = width;\n\n wrapper.appendChild(panel);\n return { wrapper, panel };\n};\n\nexport interface PanelElements {\n container: HTMLElement;\n body: HTMLElement;\n messagesWrapper: HTMLElement;\n suggestions: HTMLElement;\n textarea: HTMLTextAreaElement;\n sendButton: HTMLButtonElement;\n sendButtonWrapper: HTMLElement;\n micButton: HTMLButtonElement | null;\n micButtonWrapper: HTMLElement | null;\n composerForm: HTMLFormElement;\n statusText: HTMLElement;\n introTitle: HTMLElement;\n introSubtitle: HTMLElement;\n closeButton: HTMLButtonElement;\n closeButtonWrapper: HTMLElement;\n clearChatButton: HTMLButtonElement | null;\n clearChatButtonWrapper: HTMLElement | null;\n iconHolder: HTMLElement;\n headerTitle: HTMLElement;\n headerSubtitle: HTMLElement;\n // Exposed for potential header replacement\n header: HTMLElement;\n footer: HTMLElement;\n}\n\nexport const buildPanel = (config?: AgentWidgetConfig, showClose = true): PanelElements => {\n // Use flex-1 and min-h-0 to ensure the container fills its parent and allows\n // the body (chat messages area) to scroll while header/footer stay fixed\n const container = createElement(\n \"div\",\n \"tvw-widget-container tvw-flex tvw-h-full tvw-w-full tvw-flex-1 tvw-min-h-0 tvw-flex-col tvw-bg-cw-surface tvw-text-cw-primary tvw-rounded-2xl tvw-overflow-hidden tvw-border tvw-border-cw-border\"\n );\n\n // Build header using layout config if available, otherwise use standard builder\n const headerLayoutConfig = config?.layout?.header;\n const headerElements: HeaderElements = headerLayoutConfig\n ? buildHeaderWithLayout(config!, headerLayoutConfig, { showClose })\n : buildHeader({ config, showClose });\n\n // Build body with intro card and messages wrapper\n const body = createElement(\n \"div\",\n \"tvw-widget-body tvw-flex tvw-flex-1 tvw-min-h-0 tvw-flex-col tvw-gap-6 tvw-overflow-y-auto tvw-bg-cw-container tvw-px-6 tvw-py-6\"\n );\n body.id = \"vanilla-agent-scroll-container\";\n \n const introCard = createElement(\n \"div\",\n \"tvw-rounded-2xl tvw-bg-cw-surface tvw-p-6 tvw-shadow-sm\"\n );\n const introTitle = createElement(\n \"h2\",\n \"tvw-text-lg tvw-font-semibold tvw-text-cw-primary\"\n );\n introTitle.textContent = config?.copy?.welcomeTitle ?? \"Hello 👋\";\n const introSubtitle = createElement(\n \"p\",\n \"tvw-mt-2 tvw-text-sm tvw-text-cw-muted\"\n );\n introSubtitle.textContent =\n config?.copy?.welcomeSubtitle ??\n \"Ask anything about your account or products.\";\n introCard.append(introTitle, introSubtitle);\n\n const messagesWrapper = createElement(\n \"div\",\n \"tvw-flex tvw-flex-col tvw-gap-3\"\n );\n\n body.append(introCard, messagesWrapper);\n\n // Build composer/footer using extracted builder\n const composerElements: ComposerElements = buildComposer({ config });\n\n // Assemble container with header, body, and footer\n attachHeaderToContainer(container, headerElements, config);\n container.append(body, composerElements.footer);\n\n return {\n container,\n body,\n messagesWrapper,\n suggestions: composerElements.suggestions,\n textarea: composerElements.textarea,\n sendButton: composerElements.sendButton,\n sendButtonWrapper: composerElements.sendButtonWrapper,\n micButton: composerElements.micButton,\n micButtonWrapper: composerElements.micButtonWrapper,\n composerForm: composerElements.composerForm,\n statusText: composerElements.statusText,\n introTitle,\n introSubtitle,\n closeButton: headerElements.closeButton,\n closeButtonWrapper: headerElements.closeButtonWrapper,\n clearChatButton: headerElements.clearChatButton,\n clearChatButtonWrapper: headerElements.clearChatButtonWrapper,\n iconHolder: headerElements.iconHolder,\n headerTitle: headerElements.headerTitle,\n headerSubtitle: headerElements.headerSubtitle,\n header: headerElements.header,\n footer: composerElements.footer\n };\n};\n\n// Re-export builder types and functions for plugin use\nexport { buildHeader, buildComposer, attachHeaderToContainer };\nexport type { HeaderElements, HeaderBuildContext } from \"./header-builder\";\nexport type { ComposerElements, ComposerBuildContext } from \"./composer-builder\";\n","import { createElement } from \"../utils/dom\";\nimport { \n AgentWidgetMessage, \n AgentWidgetMessageLayoutConfig,\n AgentWidgetAvatarConfig,\n AgentWidgetTimestampConfig,\n AgentWidgetMessageActionsConfig,\n AgentWidgetMessageFeedback\n} from \"../types\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\nexport type MessageTransform = (context: {\n text: string;\n message: AgentWidgetMessage;\n streaming: boolean;\n raw?: string;\n}) => string;\n\nexport type MessageActionCallbacks = {\n onCopy?: (message: AgentWidgetMessage) => void;\n onFeedback?: (feedback: AgentWidgetMessageFeedback) => void;\n};\n\n// Create typing indicator element\nexport const createTypingIndicator = (): HTMLElement => {\n const container = document.createElement(\"div\");\n container.className = \"tvw-flex tvw-items-center tvw-space-x-1 tvw-h-5 tvw-mt-2\";\n\n const dot1 = document.createElement(\"div\");\n dot1.className = \"tvw-bg-cw-primary tvw-animate-typing tvw-rounded-full tvw-h-1.5 tvw-w-1.5\";\n dot1.style.animationDelay = \"0ms\";\n\n const dot2 = document.createElement(\"div\");\n dot2.className = \"tvw-bg-cw-primary tvw-animate-typing tvw-rounded-full tvw-h-1.5 tvw-w-1.5\";\n dot2.style.animationDelay = \"250ms\";\n\n const dot3 = document.createElement(\"div\");\n dot3.className = \"tvw-bg-cw-primary tvw-animate-typing tvw-rounded-full tvw-h-1.5 tvw-w-1.5\";\n dot3.style.animationDelay = \"500ms\";\n\n const srOnly = document.createElement(\"span\");\n srOnly.className = \"tvw-sr-only\";\n srOnly.textContent = \"Loading\";\n\n container.appendChild(dot1);\n container.appendChild(dot2);\n container.appendChild(dot3);\n container.appendChild(srOnly);\n\n return container;\n};\n\n/**\n * Create an avatar element\n */\nconst createAvatar = (\n avatarConfig: AgentWidgetAvatarConfig,\n role: \"user\" | \"assistant\"\n): HTMLElement => {\n const avatar = createElement(\n \"div\",\n \"tvw-flex-shrink-0 tvw-w-8 tvw-h-8 tvw-rounded-full tvw-flex tvw-items-center tvw-justify-center tvw-text-sm\"\n );\n\n const avatarContent = role === \"user\" \n ? avatarConfig.userAvatar \n : avatarConfig.assistantAvatar;\n\n if (avatarContent) {\n // Check if it's a URL or emoji/text\n if (avatarContent.startsWith(\"http\") || avatarContent.startsWith(\"/\") || avatarContent.startsWith(\"data:\")) {\n const img = createElement(\"img\") as HTMLImageElement;\n img.src = avatarContent;\n img.alt = role === \"user\" ? \"User\" : \"Assistant\";\n img.className = \"tvw-w-full tvw-h-full tvw-rounded-full tvw-object-cover\";\n avatar.appendChild(img);\n } else {\n // Emoji or text\n avatar.textContent = avatarContent;\n avatar.classList.add(\n role === \"user\" ? \"tvw-bg-cw-accent\" : \"tvw-bg-cw-primary\",\n \"tvw-text-white\"\n );\n }\n } else {\n // Default avatar\n avatar.textContent = role === \"user\" ? \"U\" : \"A\";\n avatar.classList.add(\n role === \"user\" ? \"tvw-bg-cw-accent\" : \"tvw-bg-cw-primary\",\n \"tvw-text-white\"\n );\n }\n\n return avatar;\n};\n\n/**\n * Create a timestamp element\n */\nconst createTimestamp = (\n message: AgentWidgetMessage,\n timestampConfig: AgentWidgetTimestampConfig\n): HTMLElement => {\n const timestamp = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n\n const date = new Date(message.createdAt);\n \n if (timestampConfig.format) {\n timestamp.textContent = timestampConfig.format(date);\n } else {\n // Default format: HH:MM\n timestamp.textContent = date.toLocaleTimeString([], { \n hour: \"2-digit\", \n minute: \"2-digit\" \n });\n }\n\n return timestamp;\n};\n\n/**\n * Get bubble classes based on layout preset\n */\nconst getBubbleClasses = (\n role: \"user\" | \"assistant\" | \"system\",\n layout: AgentWidgetMessageLayoutConfig[\"layout\"] = \"bubble\"\n): string[] => {\n const baseClasses = [\"vanilla-message-bubble\", \"tvw-max-w-[85%]\"];\n\n switch (layout) {\n case \"flat\":\n // Flat layout: no bubble styling, just text\n if (role === \"user\") {\n baseClasses.push(\n \"vanilla-message-user-bubble\",\n \"tvw-ml-auto\",\n \"tvw-text-cw-primary\",\n \"tvw-py-2\"\n );\n } else {\n baseClasses.push(\n \"vanilla-message-assistant-bubble\",\n \"tvw-text-cw-primary\",\n \"tvw-py-2\"\n );\n }\n break;\n\n case \"minimal\":\n // Minimal layout: reduced padding and styling\n baseClasses.push(\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\"\n );\n if (role === \"user\") {\n baseClasses.push(\n \"vanilla-message-user-bubble\",\n \"tvw-ml-auto\",\n \"tvw-bg-cw-accent\",\n \"tvw-text-white\",\n \"tvw-px-3\",\n \"tvw-py-2\",\n \"tvw-rounded-lg\"\n );\n } else {\n baseClasses.push(\n \"vanilla-message-assistant-bubble\",\n \"tvw-bg-cw-surface\",\n \"tvw-text-cw-primary\",\n \"tvw-px-3\",\n \"tvw-py-2\",\n \"tvw-rounded-lg\"\n );\n }\n break;\n\n case \"bubble\":\n default:\n // Default bubble layout\n baseClasses.push(\n \"tvw-rounded-2xl\",\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\",\n \"tvw-shadow-sm\"\n );\n if (role === \"user\") {\n baseClasses.push(\n \"vanilla-message-user-bubble\",\n \"tvw-ml-auto\",\n \"tvw-bg-cw-accent\",\n \"tvw-text-white\",\n \"tvw-px-5\",\n \"tvw-py-3\"\n );\n } else {\n baseClasses.push(\n \"vanilla-message-assistant-bubble\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-px-5\",\n \"tvw-py-3\"\n );\n }\n break;\n }\n\n return baseClasses;\n};\n\n/**\n * Create message action buttons (copy, upvote, downvote)\n */\nexport const createMessageActions = (\n message: AgentWidgetMessage,\n actionsConfig: AgentWidgetMessageActionsConfig,\n callbacks?: MessageActionCallbacks\n): HTMLElement => {\n const showCopy = actionsConfig.showCopy ?? true;\n const showUpvote = actionsConfig.showUpvote ?? true;\n const showDownvote = actionsConfig.showDownvote ?? true;\n const visibility = actionsConfig.visibility ?? \"hover\";\n const align = actionsConfig.align ?? \"right\";\n const layout = actionsConfig.layout ?? \"pill-inside\";\n\n // Map alignment to CSS class\n const alignClass = {\n left: \"tvw-message-actions-left\",\n center: \"tvw-message-actions-center\",\n right: \"tvw-message-actions-right\",\n }[align];\n\n // Map layout to CSS class\n const layoutClass = {\n \"pill-inside\": \"tvw-message-actions-pill\",\n \"row-inside\": \"tvw-message-actions-row\",\n }[layout];\n\n const container = createElement(\n \"div\",\n `tvw-message-actions tvw-flex tvw-items-center tvw-gap-1 tvw-mt-2 ${alignClass} ${layoutClass} ${\n visibility === \"hover\" ? \"tvw-message-actions-hover\" : \"\"\n }`\n );\n // Set id for idiomorph matching (prevents recreation on morph)\n container.id = `actions-${message.id}`;\n container.setAttribute(\"data-actions-for\", message.id);\n\n // Track vote state for this message\n let currentVote: \"upvote\" | \"downvote\" | null = null;\n\n const createActionButton = (\n iconName: string,\n label: string,\n onClick: () => void,\n dataAction?: string\n ): HTMLButtonElement => {\n const button = document.createElement(\"button\");\n button.className = \"tvw-message-action-btn\";\n button.setAttribute(\"aria-label\", label);\n button.setAttribute(\"title\", label);\n if (dataAction) {\n button.setAttribute(\"data-action\", dataAction);\n }\n\n const icon = renderLucideIcon(iconName, 14, \"currentColor\", 2);\n if (icon) {\n button.appendChild(icon);\n }\n\n button.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n onClick();\n });\n\n return button;\n };\n\n // Copy button\n if (showCopy) {\n const copyButton = createActionButton(\"copy\", \"Copy message\", () => {\n // Copy to clipboard\n const textToCopy = message.content || \"\";\n navigator.clipboard.writeText(textToCopy).then(() => {\n // Show success feedback - swap icon temporarily\n copyButton.classList.add(\"tvw-message-action-success\");\n const checkIcon = renderLucideIcon(\"check\", 14, \"currentColor\", 2);\n if (checkIcon) {\n copyButton.innerHTML = \"\";\n copyButton.appendChild(checkIcon);\n }\n \n // Restore original icon after 2 seconds\n setTimeout(() => {\n copyButton.classList.remove(\"tvw-message-action-success\");\n const originalIcon = renderLucideIcon(\"copy\", 14, \"currentColor\", 2);\n if (originalIcon) {\n copyButton.innerHTML = \"\";\n copyButton.appendChild(originalIcon);\n }\n }, 2000);\n }).catch((err) => {\n if (typeof console !== \"undefined\") {\n console.error(\"[AgentWidget] Failed to copy message:\", err);\n }\n });\n\n // Trigger callback\n if (callbacks?.onCopy) {\n callbacks.onCopy(message);\n }\n if (actionsConfig.onCopy) {\n actionsConfig.onCopy(message);\n }\n }, \"copy\");\n container.appendChild(copyButton);\n }\n\n // Upvote button\n if (showUpvote) {\n const upvoteButton = createActionButton(\"thumbs-up\", \"Upvote\", () => {\n const wasActive = currentVote === \"upvote\";\n \n // Toggle state\n if (wasActive) {\n currentVote = null;\n upvoteButton.classList.remove(\"tvw-message-action-active\");\n } else {\n // Remove downvote if active\n const downvoteBtn = container.querySelector('[data-action=\"downvote\"]');\n if (downvoteBtn) {\n downvoteBtn.classList.remove(\"tvw-message-action-active\");\n }\n currentVote = \"upvote\";\n upvoteButton.classList.add(\"tvw-message-action-active\");\n \n // Trigger feedback\n const feedback: AgentWidgetMessageFeedback = {\n type: \"upvote\",\n messageId: message.id,\n message\n };\n if (callbacks?.onFeedback) {\n callbacks.onFeedback(feedback);\n }\n if (actionsConfig.onFeedback) {\n actionsConfig.onFeedback(feedback);\n }\n }\n }, \"upvote\");\n container.appendChild(upvoteButton);\n }\n\n // Downvote button\n if (showDownvote) {\n const downvoteButton = createActionButton(\"thumbs-down\", \"Downvote\", () => {\n const wasActive = currentVote === \"downvote\";\n \n // Toggle state\n if (wasActive) {\n currentVote = null;\n downvoteButton.classList.remove(\"tvw-message-action-active\");\n } else {\n // Remove upvote if active\n const upvoteBtn = container.querySelector('[data-action=\"upvote\"]');\n if (upvoteBtn) {\n upvoteBtn.classList.remove(\"tvw-message-action-active\");\n }\n currentVote = \"downvote\";\n downvoteButton.classList.add(\"tvw-message-action-active\");\n \n // Trigger feedback\n const feedback: AgentWidgetMessageFeedback = {\n type: \"downvote\",\n messageId: message.id,\n message\n };\n if (callbacks?.onFeedback) {\n callbacks.onFeedback(feedback);\n }\n if (actionsConfig.onFeedback) {\n actionsConfig.onFeedback(feedback);\n }\n }\n }, \"downvote\");\n container.appendChild(downvoteButton);\n }\n\n return container;\n};\n\n/**\n * Create standard message bubble\n * Supports layout configuration for avatars, timestamps, and visual presets\n */\nexport const createStandardBubble = (\n message: AgentWidgetMessage,\n transform: MessageTransform,\n layoutConfig?: AgentWidgetMessageLayoutConfig,\n actionsConfig?: AgentWidgetMessageActionsConfig,\n actionCallbacks?: MessageActionCallbacks\n): HTMLElement => {\n const config = layoutConfig ?? {};\n const layout = config.layout ?? \"bubble\";\n const avatarConfig = config.avatar;\n const timestampConfig = config.timestamp;\n const showAvatar = avatarConfig?.show ?? false;\n const showTimestamp = timestampConfig?.show ?? false;\n const avatarPosition = avatarConfig?.position ?? \"left\";\n const timestampPosition = timestampConfig?.position ?? \"below\";\n\n // Create the bubble element\n const classes = getBubbleClasses(message.role, layout);\n const bubble = createElement(\"div\", classes.join(\" \"));\n // Set id for idiomorph matching\n bubble.id = `bubble-${message.id}`;\n bubble.setAttribute(\"data-message-id\", message.id);\n\n // Add message content\n const contentDiv = document.createElement(\"div\");\n contentDiv.innerHTML = transform({\n text: message.content,\n message,\n streaming: Boolean(message.streaming),\n raw: message.rawContent\n });\n\n // Add inline timestamp if configured\n if (showTimestamp && timestampPosition === \"inline\" && message.createdAt) {\n const timestamp = createTimestamp(message, timestampConfig!);\n timestamp.classList.add(\"tvw-ml-2\", \"tvw-inline\");\n contentDiv.appendChild(timestamp);\n }\n\n bubble.appendChild(contentDiv);\n\n // Add timestamp below if configured\n if (showTimestamp && timestampPosition === \"below\" && message.createdAt) {\n const timestamp = createTimestamp(message, timestampConfig!);\n timestamp.classList.add(\"tvw-mt-1\");\n bubble.appendChild(timestamp);\n }\n\n // Add typing indicator if this is a streaming assistant message\n if (message.streaming && message.role === \"assistant\") {\n if (!message.content || !message.content.trim()) {\n const typingIndicator = createTypingIndicator();\n bubble.appendChild(typingIndicator);\n }\n }\n\n // Add message actions for assistant messages (only when not streaming and has content)\n const shouldShowActions = \n message.role === \"assistant\" && \n !message.streaming && \n message.content && \n message.content.trim() &&\n actionsConfig?.enabled !== false;\n\n if (shouldShowActions && actionsConfig) {\n const actions = createMessageActions(message, actionsConfig, actionCallbacks);\n bubble.appendChild(actions);\n }\n\n // If no avatar needed, return bubble directly\n if (!showAvatar || message.role === \"system\") {\n return bubble;\n }\n\n // Create wrapper with avatar\n const wrapper = createElement(\n \"div\",\n `tvw-flex tvw-gap-2 ${message.role === \"user\" ? \"tvw-flex-row-reverse\" : \"\"}`\n );\n\n const avatar = createAvatar(avatarConfig!, message.role);\n\n if (avatarPosition === \"right\" || (avatarPosition === \"left\" && message.role === \"user\")) {\n wrapper.append(bubble, avatar);\n } else {\n wrapper.append(avatar, bubble);\n }\n\n // Adjust bubble max-width when avatar is present\n bubble.classList.remove(\"tvw-max-w-[85%]\");\n bubble.classList.add(\"tvw-max-w-[calc(85%-2.5rem)]\");\n\n return wrapper;\n};\n\n/**\n * Create bubble with custom renderer support\n * Uses custom renderer if provided in layout config, otherwise falls back to standard bubble\n */\nexport const createBubbleWithLayout = (\n message: AgentWidgetMessage,\n transform: MessageTransform,\n layoutConfig?: AgentWidgetMessageLayoutConfig,\n actionsConfig?: AgentWidgetMessageActionsConfig,\n actionCallbacks?: MessageActionCallbacks\n): HTMLElement => {\n const config = layoutConfig ?? {};\n\n // Check for custom renderers\n if (message.role === \"user\" && config.renderUserMessage) {\n return config.renderUserMessage({\n message,\n config: {} as any, // Will be populated by caller\n streaming: Boolean(message.streaming)\n });\n }\n\n if (message.role === \"assistant\" && config.renderAssistantMessage) {\n return config.renderAssistantMessage({\n message,\n config: {} as any, // Will be populated by caller\n streaming: Boolean(message.streaming)\n });\n }\n\n // Fall back to standard bubble\n return createStandardBubble(message, transform, layoutConfig, actionsConfig, actionCallbacks);\n};\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage } from \"../types\";\nimport { describeReasonStatus } from \"../utils/formatting\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\n// Expansion state per widget instance\nconst reasoningExpansionState = new Set<string>();\n\nexport const createReasoningBubble = (message: AgentWidgetMessage): HTMLElement => {\n const reasoning = message.reasoning;\n const bubble = createElement(\n \"div\",\n [\n \"vanilla-message-bubble\",\n \"vanilla-reasoning-bubble\",\n \"tvw-w-full\",\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-shadow-sm\",\n \"tvw-overflow-hidden\",\n \"tvw-px-0\",\n \"tvw-py-0\"\n ].join(\" \")\n );\n // Set id for idiomorph matching\n bubble.id = `bubble-${message.id}`;\n bubble.setAttribute(\"data-message-id\", message.id);\n\n if (!reasoning) {\n return bubble;\n }\n\n let expanded = reasoningExpansionState.has(message.id);\n const header = createElement(\n \"button\",\n \"tvw-flex tvw-w-full tvw-items-center tvw-justify-between tvw-gap-3 tvw-bg-transparent tvw-px-4 tvw-py-3 tvw-text-left tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n header.type = \"button\";\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n\n const headerContent = createElement(\"div\", \"tvw-flex tvw-flex-col tvw-text-left\");\n const title = createElement(\"span\", \"tvw-text-xs tvw-text-cw-primary\");\n title.textContent = \"Thinking...\";\n headerContent.appendChild(title);\n\n const status = createElement(\"span\", \"tvw-text-xs tvw-text-cw-primary\");\n status.textContent = describeReasonStatus(reasoning);\n headerContent.appendChild(status);\n\n if (reasoning.status === \"complete\") {\n title.style.display = \"none\";\n } else {\n title.style.display = \"\";\n }\n\n const toggleIcon = createElement(\"div\", \"tvw-flex tvw-items-center\");\n const iconColor = \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n\n const headerMeta = createElement(\"div\", \"tvw-flex tvw-items-center tvw-ml-auto\");\n headerMeta.append(toggleIcon);\n\n header.append(headerContent, headerMeta);\n\n const content = createElement(\n \"div\",\n \"tvw-border-t tvw-border-gray-200 tvw-bg-gray-50 tvw-px-4 tvw-py-3\"\n );\n content.style.display = expanded ? \"\" : \"none\";\n\n const text = reasoning.chunks.join(\"\");\n const body = createElement(\n \"div\",\n \"tvw-whitespace-pre-wrap tvw-text-xs tvw-leading-snug tvw-text-cw-muted\"\n );\n body.textContent =\n text ||\n (reasoning.status === \"complete\"\n ? \"No additional context was shared.\"\n : \"Waiting for details…\");\n content.appendChild(body);\n\n const applyExpansionState = () => {\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n // Update chevron icon\n toggleIcon.innerHTML = \"\";\n const iconColor = \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n content.style.display = expanded ? \"\" : \"none\";\n };\n\n const toggleExpansion = () => {\n expanded = !expanded;\n if (expanded) {\n reasoningExpansionState.add(message.id);\n } else {\n reasoningExpansionState.delete(message.id);\n }\n applyExpansionState();\n };\n\n header.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n toggleExpansion();\n });\n\n header.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n toggleExpansion();\n }\n });\n\n applyExpansionState();\n\n bubble.append(header, content);\n return bubble;\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage, AgentWidgetConfig } from \"../types\";\nimport { formatUnknownValue, describeToolTitle } from \"../utils/formatting\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\n// Expansion state per widget instance\nconst toolExpansionState = new Set<string>();\n\nexport const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidgetConfig): HTMLElement => {\n const tool = message.toolCall;\n const toolCallConfig = config?.toolCall ?? {};\n \n const bubble = createElement(\n \"div\",\n [\n \"vanilla-message-bubble\",\n \"vanilla-tool-bubble\",\n \"tvw-w-full\",\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-shadow-sm\",\n \"tvw-overflow-hidden\",\n \"tvw-px-0\",\n \"tvw-py-0\"\n ].join(\" \")\n );\n // Set id for idiomorph matching\n bubble.id = `bubble-${message.id}`;\n bubble.setAttribute(\"data-message-id\", message.id);\n\n // Apply bubble-level styles\n if (toolCallConfig.backgroundColor) {\n bubble.style.backgroundColor = toolCallConfig.backgroundColor;\n }\n if (toolCallConfig.borderColor) {\n bubble.style.borderColor = toolCallConfig.borderColor;\n }\n if (toolCallConfig.borderWidth) {\n bubble.style.borderWidth = toolCallConfig.borderWidth;\n }\n if (toolCallConfig.borderRadius) {\n bubble.style.borderRadius = toolCallConfig.borderRadius;\n }\n\n if (!tool) {\n return bubble;\n }\n\n let expanded = toolExpansionState.has(message.id);\n const header = createElement(\n \"button\",\n \"tvw-flex tvw-w-full tvw-items-center tvw-justify-between tvw-gap-3 tvw-bg-transparent tvw-px-4 tvw-py-3 tvw-text-left tvw-cursor-pointer tvw-border-none\"\n ) as HTMLButtonElement;\n header.type = \"button\";\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n\n // Apply header styles\n if (toolCallConfig.headerBackgroundColor) {\n header.style.backgroundColor = toolCallConfig.headerBackgroundColor;\n }\n if (toolCallConfig.headerPaddingX) {\n header.style.paddingLeft = toolCallConfig.headerPaddingX;\n header.style.paddingRight = toolCallConfig.headerPaddingX;\n }\n if (toolCallConfig.headerPaddingY) {\n header.style.paddingTop = toolCallConfig.headerPaddingY;\n header.style.paddingBottom = toolCallConfig.headerPaddingY;\n }\n\n const headerContent = createElement(\"div\", \"tvw-flex tvw-flex-col tvw-text-left\");\n const title = createElement(\"span\", \"tvw-text-xs tvw-text-cw-primary\");\n if (toolCallConfig.headerTextColor) {\n title.style.color = toolCallConfig.headerTextColor;\n }\n title.textContent = describeToolTitle(tool);\n headerContent.appendChild(title);\n\n const toggleIcon = createElement(\"div\", \"tvw-flex tvw-items-center\");\n const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n\n const headerMeta = createElement(\"div\", \"tvw-flex tvw-items-center tvw-gap-2 tvw-ml-auto\");\n headerMeta.append(toggleIcon);\n\n header.append(headerContent, headerMeta);\n\n const content = createElement(\n \"div\",\n \"tvw-border-t tvw-border-gray-200 tvw-bg-gray-50 tvw-space-y-3 tvw-px-4 tvw-py-3\"\n );\n content.style.display = expanded ? \"\" : \"none\";\n\n // Apply content styles\n if (toolCallConfig.contentBackgroundColor) {\n content.style.backgroundColor = toolCallConfig.contentBackgroundColor;\n }\n if (toolCallConfig.contentTextColor) {\n content.style.color = toolCallConfig.contentTextColor;\n }\n if (toolCallConfig.contentPaddingX) {\n content.style.paddingLeft = toolCallConfig.contentPaddingX;\n content.style.paddingRight = toolCallConfig.contentPaddingX;\n }\n if (toolCallConfig.contentPaddingY) {\n content.style.paddingTop = toolCallConfig.contentPaddingY;\n content.style.paddingBottom = toolCallConfig.contentPaddingY;\n }\n\n // Add tool name at the top of content\n if (tool.name) {\n const toolName = createElement(\"div\", \"tvw-text-xs tvw-text-cw-muted tvw-italic\");\n if (toolCallConfig.contentTextColor) {\n toolName.style.color = toolCallConfig.contentTextColor;\n } else if (toolCallConfig.headerTextColor) {\n toolName.style.color = toolCallConfig.headerTextColor;\n }\n toolName.textContent = tool.name;\n content.appendChild(toolName);\n }\n\n if (tool.args !== undefined) {\n const argsBlock = createElement(\"div\", \"tvw-space-y-1\");\n const argsLabel = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.labelTextColor) {\n argsLabel.style.color = toolCallConfig.labelTextColor;\n }\n argsLabel.textContent = \"Arguments\";\n const argsPre = createElement(\n \"pre\",\n \"tvw-max-h-48 tvw-overflow-auto tvw-whitespace-pre-wrap tvw-rounded-lg tvw-border tvw-border-gray-100 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-xs tvw-text-cw-primary\"\n );\n // Ensure font size matches header text (0.75rem / 12px)\n argsPre.style.fontSize = \"0.75rem\";\n argsPre.style.lineHeight = \"1rem\";\n if (toolCallConfig.codeBlockBackgroundColor) {\n argsPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;\n }\n if (toolCallConfig.codeBlockBorderColor) {\n argsPre.style.borderColor = toolCallConfig.codeBlockBorderColor;\n }\n if (toolCallConfig.codeBlockTextColor) {\n argsPre.style.color = toolCallConfig.codeBlockTextColor;\n }\n argsPre.textContent = formatUnknownValue(tool.args);\n argsBlock.append(argsLabel, argsPre);\n content.appendChild(argsBlock);\n }\n\n if (tool.chunks && tool.chunks.length) {\n const logsBlock = createElement(\"div\", \"tvw-space-y-1\");\n const logsLabel = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.labelTextColor) {\n logsLabel.style.color = toolCallConfig.labelTextColor;\n }\n logsLabel.textContent = \"Activity\";\n const logsPre = createElement(\n \"pre\",\n \"tvw-max-h-48 tvw-overflow-auto tvw-whitespace-pre-wrap tvw-rounded-lg tvw-border tvw-border-gray-100 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-xs tvw-text-cw-primary\"\n );\n // Ensure font size matches header text (0.75rem / 12px)\n logsPre.style.fontSize = \"0.75rem\";\n logsPre.style.lineHeight = \"1rem\";\n if (toolCallConfig.codeBlockBackgroundColor) {\n logsPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;\n }\n if (toolCallConfig.codeBlockBorderColor) {\n logsPre.style.borderColor = toolCallConfig.codeBlockBorderColor;\n }\n if (toolCallConfig.codeBlockTextColor) {\n logsPre.style.color = toolCallConfig.codeBlockTextColor;\n }\n logsPre.textContent = tool.chunks.join(\"\\n\");\n logsBlock.append(logsLabel, logsPre);\n content.appendChild(logsBlock);\n }\n\n if (tool.status === \"complete\" && tool.result !== undefined) {\n const resultBlock = createElement(\"div\", \"tvw-space-y-1\");\n const resultLabel = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.labelTextColor) {\n resultLabel.style.color = toolCallConfig.labelTextColor;\n }\n resultLabel.textContent = \"Result\";\n const resultPre = createElement(\n \"pre\",\n \"tvw-max-h-48 tvw-overflow-auto tvw-whitespace-pre-wrap tvw-rounded-lg tvw-border tvw-border-gray-100 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-xs tvw-text-cw-primary\"\n );\n // Ensure font size matches header text (0.75rem / 12px)\n resultPre.style.fontSize = \"0.75rem\";\n resultPre.style.lineHeight = \"1rem\";\n if (toolCallConfig.codeBlockBackgroundColor) {\n resultPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;\n }\n if (toolCallConfig.codeBlockBorderColor) {\n resultPre.style.borderColor = toolCallConfig.codeBlockBorderColor;\n }\n if (toolCallConfig.codeBlockTextColor) {\n resultPre.style.color = toolCallConfig.codeBlockTextColor;\n }\n resultPre.textContent = formatUnknownValue(tool.result);\n resultBlock.append(resultLabel, resultPre);\n content.appendChild(resultBlock);\n }\n\n if (tool.status === \"complete\" && typeof tool.duration === \"number\") {\n const duration = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\n if (toolCallConfig.contentTextColor) {\n duration.style.color = toolCallConfig.contentTextColor;\n }\n duration.textContent = `Duration: ${tool.duration}ms`;\n content.appendChild(duration);\n }\n\n const applyToolExpansion = () => {\n header.setAttribute(\"aria-expanded\", expanded ? \"true\" : \"false\");\n // Update chevron icon\n toggleIcon.innerHTML = \"\";\n const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || \"currentColor\";\n const chevronIcon = renderLucideIcon(expanded ? \"chevron-up\" : \"chevron-down\", 16, iconColor, 2);\n if (chevronIcon) {\n toggleIcon.appendChild(chevronIcon);\n } else {\n // Fallback to text if icon fails\n toggleIcon.textContent = expanded ? \"Hide\" : \"Show\";\n }\n content.style.display = expanded ? \"\" : \"none\";\n };\n\n const toggleToolExpansion = () => {\n expanded = !expanded;\n if (expanded) {\n toolExpansionState.add(message.id);\n } else {\n toolExpansionState.delete(message.id);\n }\n applyToolExpansion();\n };\n\n header.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n toggleToolExpansion();\n });\n\n header.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n toggleToolExpansion();\n }\n });\n\n applyToolExpansion();\n\n bubble.append(header, content);\n return bubble;\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetSession } from \"../session\";\nimport { AgentWidgetMessage, AgentWidgetSuggestionChipsConfig } from \"../types\";\n\nexport interface SuggestionButtons {\n buttons: HTMLButtonElement[];\n render: (\n chips: string[] | undefined,\n session: AgentWidgetSession,\n textarea: HTMLTextAreaElement,\n messages?: AgentWidgetMessage[],\n config?: AgentWidgetSuggestionChipsConfig\n ) => void;\n}\n\nexport const createSuggestions = (container: HTMLElement): SuggestionButtons => {\n const suggestionButtons: HTMLButtonElement[] = [];\n\n const render = (\n chips: string[] | undefined,\n session: AgentWidgetSession,\n textarea: HTMLTextAreaElement,\n messages?: AgentWidgetMessage[],\n chipsConfig?: AgentWidgetSuggestionChipsConfig\n ) => {\n container.innerHTML = \"\";\n suggestionButtons.length = 0;\n if (!chips || !chips.length) return;\n\n // Hide suggestions after the first user message is sent\n // Use provided messages or get from session\n const messagesToCheck = messages ?? (session ? session.getMessages() : []);\n const hasUserMessage = messagesToCheck.some((msg) => msg.role === \"user\");\n if (hasUserMessage) return;\n\n const fragment = document.createDocumentFragment();\n const streaming = session ? session.isStreaming() : false;\n\n // Get font family mapping function\n const getFontFamilyValue = (family: \"sans-serif\" | \"serif\" | \"mono\"): string => {\n switch (family) {\n case \"serif\":\n return 'Georgia, \"Times New Roman\", Times, serif';\n case \"mono\":\n return '\"Courier New\", Courier, \"Lucida Console\", Monaco, monospace';\n case \"sans-serif\":\n default:\n return '-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif';\n }\n };\n\n chips.forEach((chip) => {\n const btn = createElement(\n \"button\",\n \"tvw-rounded-button tvw-bg-cw-surface tvw-px-3 tvw-py-1.5 tvw-text-xs tvw-font-medium tvw-text-cw-muted hover:tvw-opacity-90 tvw-cursor-pointer tvw-border tvw-border-gray-200\"\n ) as HTMLButtonElement;\n btn.type = \"button\";\n btn.textContent = chip;\n btn.disabled = streaming;\n\n // Apply typography settings\n if (chipsConfig?.fontFamily) {\n btn.style.fontFamily = getFontFamilyValue(chipsConfig.fontFamily);\n }\n if (chipsConfig?.fontWeight) {\n btn.style.fontWeight = chipsConfig.fontWeight;\n }\n\n // Apply padding settings\n if (chipsConfig?.paddingX) {\n btn.style.paddingLeft = chipsConfig.paddingX;\n btn.style.paddingRight = chipsConfig.paddingX;\n }\n if (chipsConfig?.paddingY) {\n btn.style.paddingTop = chipsConfig.paddingY;\n btn.style.paddingBottom = chipsConfig.paddingY;\n }\n\n btn.addEventListener(\"click\", () => {\n if (!session || session.isStreaming()) return;\n textarea.value = \"\";\n session.sendMessage(chip);\n });\n fragment.appendChild(btn);\n suggestionButtons.push(btn);\n });\n container.appendChild(fragment);\n };\n\n return {\n buttons: suggestionButtons,\n render\n };\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage, AgentWidgetConfig } from \"../types\";\nimport { AgentWidgetSession } from \"../session\";\n\nexport const formDefinitions: Record<\n string,\n {\n title: string;\n description?: string;\n fields: Array<{\n name: string;\n label: string;\n placeholder?: string;\n type?: \"text\" | \"email\" | \"textarea\";\n required?: boolean;\n }>;\n submitLabel?: string;\n }\n> = {\n init: {\n title: \"Schedule a Demo\",\n description: \"Share the basics and we'll follow up with a confirmation.\",\n fields: [\n { name: \"name\", label: \"Full name\", placeholder: \"Jane Doe\", required: true },\n { name: \"email\", label: \"Work email\", placeholder: \"jane@example.com\", type: \"email\", required: true },\n { name: \"notes\", label: \"What would you like to cover?\", type: \"textarea\" }\n ],\n submitLabel: \"Submit details\"\n },\n followup: {\n title: \"Additional Information\",\n description: \"Provide any extra details to tailor the next steps.\",\n fields: [\n { name: \"company\", label: \"Company\", placeholder: \"Acme Inc.\" },\n { name: \"context\", label: \"Context\", type: \"textarea\", placeholder: \"Share more about your use case\" }\n ],\n submitLabel: \"Send\"\n }\n};\n\nexport const enhanceWithForms = (\n bubble: HTMLElement,\n message: AgentWidgetMessage,\n config: AgentWidgetConfig,\n session: AgentWidgetSession\n) => {\n const placeholders = bubble.querySelectorAll<HTMLElement>(\"[data-tv-form]\");\n if (placeholders.length) {\n placeholders.forEach((placeholder) => {\n if (placeholder.dataset.enhanced === \"true\") return;\n const type = placeholder.dataset.tvForm ?? \"init\";\n placeholder.dataset.enhanced = \"true\";\n\n const definition = formDefinitions[type] ?? formDefinitions.init;\n placeholder.classList.add(\"tvw-form-card\", \"tvw-space-y-4\");\n\n const heading = createElement(\"div\", \"tvw-space-y-1\");\n const title = createElement(\n \"h3\",\n \"tvw-text-base tvw-font-semibold tvw-text-cw-primary\"\n );\n title.textContent = definition.title;\n heading.appendChild(title);\n if (definition.description) {\n const desc = createElement(\n \"p\",\n \"tvw-text-sm tvw-text-cw-muted\"\n );\n desc.textContent = definition.description;\n heading.appendChild(desc);\n }\n\n const form = document.createElement(\"form\");\n form.className = \"tvw-form-grid tvw-space-y-3\";\n\n definition.fields.forEach((field) => {\n const group = createElement(\"label\", \"tvw-form-field tvw-flex tvw-flex-col tvw-gap-1\");\n group.htmlFor = `${message.id}-${type}-${field.name}`;\n const label = createElement(\"span\", \"tvw-text-xs tvw-font-medium tvw-text-cw-muted\");\n label.textContent = field.label;\n group.appendChild(label);\n\n const inputType = field.type ?? \"text\";\n let control: HTMLInputElement | HTMLTextAreaElement;\n if (inputType === \"textarea\") {\n control = document.createElement(\"textarea\");\n control.rows = 3;\n } else {\n control = document.createElement(\"input\");\n control.type = inputType;\n }\n control.className =\n \"tvw-rounded-xl tvw-border tvw-border-gray-200 tvw-bg-white tvw-px-3 tvw-py-2 tvw-text-sm tvw-text-cw-primary focus:tvw-outline-none focus:tvw-border-cw-primary\";\n control.id = `${message.id}-${type}-${field.name}`;\n control.name = field.name;\n control.placeholder = field.placeholder ?? \"\";\n if (field.required) {\n control.required = true;\n }\n group.appendChild(control);\n form.appendChild(group);\n });\n\n const actions = createElement(\n \"div\",\n \"tvw-flex tvw-items-center tvw-justify-between tvw-gap-2\"\n );\n const status = createElement(\n \"div\",\n \"tvw-text-xs tvw-text-cw-muted tvw-min-h-[1.5rem]\"\n );\n const submit = createElement(\n \"button\",\n \"tvw-inline-flex tvw-items-center tvw-rounded-full tvw-bg-cw-primary tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold tvw-text-white disabled:tvw-opacity-60 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n submit.type = \"submit\";\n submit.textContent = definition.submitLabel ?? \"Submit\";\n actions.appendChild(status);\n actions.appendChild(submit);\n form.appendChild(actions);\n\n placeholder.replaceChildren(heading, form);\n\n form.addEventListener(\"submit\", async (event) => {\n event.preventDefault();\n const formEndpoint = config.formEndpoint ?? \"/form\";\n const formData = new FormData(form as HTMLFormElement);\n const payload: Record<string, unknown> = {};\n formData.forEach((value, key) => {\n payload[key] = value;\n });\n payload[\"type\"] = type;\n\n submit.disabled = true;\n status.textContent = \"Submitting…\";\n\n try {\n const response = await fetch(formEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(payload)\n });\n if (!response.ok) {\n throw new Error(`Form submission failed (${response.status})`);\n }\n const data = await response.json();\n status.textContent = data.message ?? \"Thanks! We'll be in touch soon.\";\n if (data.success && data.nextPrompt) {\n await session.sendMessage(String(data.nextPrompt));\n }\n } catch (error) {\n status.textContent =\n error instanceof Error ? error.message : \"Something went wrong. Please try again.\";\n } finally {\n submit.disabled = false;\n }\n });\n });\n }\n};\n\n\n\n\n\n\n\n\n","import { AgentWidgetPlugin } from \"./types\";\n\nclass PluginRegistry {\n private plugins: Map<string, AgentWidgetPlugin> = new Map();\n\n /**\n * Register a plugin\n */\n register(plugin: AgentWidgetPlugin): void {\n if (this.plugins.has(plugin.id)) {\n console.warn(`Plugin \"${plugin.id}\" is already registered. Overwriting.`);\n }\n\n this.plugins.set(plugin.id, plugin);\n plugin.onRegister?.();\n }\n\n /**\n * Unregister a plugin\n */\n unregister(pluginId: string): void {\n const plugin = this.plugins.get(pluginId);\n if (plugin) {\n plugin.onUnregister?.();\n this.plugins.delete(pluginId);\n }\n }\n\n /**\n * Get all plugins sorted by priority\n */\n getAll(): AgentWidgetPlugin[] {\n return Array.from(this.plugins.values()).sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n );\n }\n\n /**\n * Get plugins for a specific instance (from config)\n * Merges instance plugins with globally registered plugins\n */\n getForInstance(instancePlugins?: AgentWidgetPlugin[]): AgentWidgetPlugin[] {\n const allPlugins = this.getAll();\n\n if (!instancePlugins || instancePlugins.length === 0) {\n return allPlugins;\n }\n\n // Merge instance plugins with global plugins\n // Instance plugins override global plugins with the same ID\n const instanceIds = new Set(instancePlugins.map(p => p.id));\n const merged = [\n ...allPlugins.filter(p => !instanceIds.has(p.id)),\n ...instancePlugins\n ];\n\n return merged.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }\n\n /**\n * Clear all plugins\n */\n clear(): void {\n this.plugins.forEach(plugin => plugin.onUnregister?.());\n this.plugins.clear();\n }\n}\n\nexport const pluginRegistry = new PluginRegistry();\n\n\n\n\n\n\n\n\n","import type { AgentWidgetConfig, AgentWidgetTheme } from \"./types\";\n\n/**\n * Default light theme colors\n */\nexport const DEFAULT_LIGHT_THEME: AgentWidgetTheme = {\n primary: \"#111827\",\n accent: \"#1d4ed8\",\n surface: \"#ffffff\",\n muted: \"#6b7280\",\n container: \"#f8fafc\",\n border: \"#f1f5f9\",\n divider: \"#f1f5f9\",\n messageBorder: \"#f1f5f9\",\n inputBackground: \"#ffffff\",\n callToAction: \"#000000\",\n callToActionBackground: \"#ffffff\",\n sendButtonBackgroundColor: \"#111827\",\n sendButtonTextColor: \"#ffffff\",\n sendButtonBorderColor: \"#60a5fa\",\n closeButtonColor: \"#6b7280\",\n closeButtonBackgroundColor: \"transparent\",\n closeButtonBorderColor: \"\",\n clearChatIconColor: \"#6b7280\",\n clearChatBackgroundColor: \"transparent\",\n clearChatBorderColor: \"transparent\",\n micIconColor: \"#111827\",\n micBackgroundColor: \"transparent\",\n micBorderColor: \"transparent\",\n recordingIconColor: \"#ffffff\",\n recordingBackgroundColor: \"#ef4444\",\n recordingBorderColor: \"transparent\",\n inputFontFamily: \"sans-serif\",\n inputFontWeight: \"400\",\n radiusSm: \"0.75rem\",\n radiusMd: \"1rem\",\n radiusLg: \"1.5rem\",\n launcherRadius: \"9999px\",\n buttonRadius: \"9999px\",\n};\n\n/**\n * Default dark theme colors\n */\nexport const DEFAULT_DARK_THEME: AgentWidgetTheme = {\n primary: \"#f9fafb\",\n accent: \"#3b82f6\",\n surface: \"#1f2937\",\n muted: \"#9ca3af\",\n container: \"#111827\",\n border: \"#374151\",\n divider: \"#374151\",\n messageBorder: \"#374151\",\n inputBackground: \"#111827\",\n callToAction: \"#ffffff\",\n callToActionBackground: \"#374151\",\n sendButtonBackgroundColor: \"#3b82f6\",\n sendButtonTextColor: \"#ffffff\",\n sendButtonBorderColor: \"#60a5fa\",\n closeButtonColor: \"#9ca3af\",\n closeButtonBackgroundColor: \"transparent\",\n closeButtonBorderColor: \"\",\n clearChatIconColor: \"#9ca3af\",\n clearChatBackgroundColor: \"transparent\",\n clearChatBorderColor: \"transparent\",\n micIconColor: \"#f9fafb\",\n micBackgroundColor: \"transparent\",\n micBorderColor: \"transparent\",\n recordingIconColor: \"#ffffff\",\n recordingBackgroundColor: \"#ef4444\",\n recordingBorderColor: \"transparent\",\n inputFontFamily: \"sans-serif\",\n inputFontWeight: \"400\",\n radiusSm: \"0.75rem\",\n radiusMd: \"1rem\",\n radiusLg: \"1.5rem\",\n launcherRadius: \"9999px\",\n buttonRadius: \"9999px\",\n};\n\n/**\n * Default widget configuration\n * Single source of truth for all default values\n */\nexport const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {\n apiUrl: \"http://localhost:43111/api/chat/dispatch\",\n // Client token mode defaults (optional, only used when clientToken is set)\n clientToken: undefined,\n theme: DEFAULT_LIGHT_THEME,\n darkTheme: DEFAULT_DARK_THEME,\n colorScheme: \"light\",\n launcher: {\n enabled: true,\n title: \"Chat Assistant\",\n subtitle: \"Here to help you get answers fast\",\n agentIconText: \"💬\",\n position: \"bottom-right\",\n width: \"min(400px, calc(100vw - 24px))\",\n heightOffset: 0,\n autoExpand: false,\n callToActionIconHidden: false,\n agentIconSize: \"40px\",\n headerIconSize: \"40px\",\n closeButtonSize: \"32px\",\n callToActionIconName: \"arrow-up-right\",\n callToActionIconText: \"\",\n callToActionIconSize: \"32px\",\n callToActionIconPadding: \"5px\",\n callToActionIconColor: \"#000000\",\n callToActionIconBackgroundColor: \"#ffffff\",\n closeButtonColor: \"#6b7280\",\n closeButtonBackgroundColor: \"transparent\",\n clearChat: {\n iconColor: \"#6b7280\",\n backgroundColor: \"transparent\",\n borderColor: \"transparent\",\n enabled: true,\n placement: \"inline\",\n iconName: \"refresh-cw\",\n size: \"32px\",\n showTooltip: true,\n tooltipText: \"Clear chat\",\n paddingX: \"0px\",\n paddingY: \"0px\",\n },\n headerIconHidden: false,\n border: \"1px solid #e5e7eb\",\n shadow: \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)\",\n },\n copy: {\n welcomeTitle: \"Hello 👋\",\n welcomeSubtitle: \"Ask anything about your account or products.\",\n inputPlaceholder: \"How can I help...\",\n sendButtonLabel: \"Send\",\n },\n sendButton: {\n borderWidth: \"0px\",\n paddingX: \"12px\",\n paddingY: \"10px\",\n backgroundColor: \"#111827\",\n textColor: \"#ffffff\",\n borderColor: \"#60a5fa\",\n useIcon: true,\n iconText: \"↑\",\n size: \"40px\",\n showTooltip: true,\n tooltipText: \"Send message\",\n iconName: \"send\",\n },\n statusIndicator: {\n visible: true,\n idleText: \"Online\",\n connectingText: \"Connecting…\",\n connectedText: \"Streaming…\",\n errorText: \"Offline\",\n },\n voiceRecognition: {\n enabled: true,\n pauseDuration: 2000,\n iconName: \"mic\",\n iconSize: \"39px\",\n borderWidth: \"0px\",\n paddingX: \"9px\",\n paddingY: \"14px\",\n iconColor: \"#111827\",\n backgroundColor: \"transparent\",\n borderColor: \"transparent\",\n recordingIconColor: \"#ffffff\",\n recordingBackgroundColor: \"#ef4444\",\n recordingBorderColor: \"transparent\",\n showTooltip: true,\n tooltipText: \"Start voice recognition\",\n },\n features: {\n showReasoning: true,\n showToolCalls: true,\n },\n suggestionChips: [\n \"What can you help me with?\",\n \"Tell me about your features\",\n \"How does this work?\",\n ],\n suggestionChipsConfig: {\n fontFamily: \"sans-serif\",\n fontWeight: \"500\",\n paddingX: \"12px\",\n paddingY: \"6px\",\n },\n layout: {\n header: {\n layout: \"default\",\n showIcon: true,\n showTitle: true,\n showSubtitle: true,\n showCloseButton: true,\n showClearChat: true,\n },\n messages: {\n layout: \"bubble\",\n avatar: {\n show: false,\n position: \"left\",\n },\n timestamp: {\n show: false,\n position: \"below\",\n },\n groupConsecutive: false,\n },\n slots: {},\n },\n markdown: {\n options: {\n gfm: true,\n breaks: true,\n },\n disableDefaultStyles: false,\n },\n messageActions: {\n enabled: true,\n showCopy: true,\n showUpvote: false, // Requires backend - disabled by default\n showDownvote: false, // Requires backend - disabled by default\n visibility: \"hover\",\n align: \"right\",\n layout: \"pill-inside\",\n },\n debug: false,\n};\n\n/**\n * Helper to deep merge user config with defaults\n * This ensures all default values are present while allowing selective overrides\n */\nexport function mergeWithDefaults(\n config?: Partial<AgentWidgetConfig>\n): Partial<AgentWidgetConfig> {\n if (!config) return DEFAULT_WIDGET_CONFIG;\n\n return {\n ...DEFAULT_WIDGET_CONFIG,\n ...config,\n theme: {\n ...DEFAULT_WIDGET_CONFIG.theme,\n ...config.theme,\n },\n darkTheme: {\n ...DEFAULT_WIDGET_CONFIG.darkTheme,\n ...config.darkTheme,\n },\n launcher: {\n ...DEFAULT_WIDGET_CONFIG.launcher,\n ...config.launcher,\n clearChat: {\n ...DEFAULT_WIDGET_CONFIG.launcher?.clearChat,\n ...config.launcher?.clearChat,\n },\n },\n copy: {\n ...DEFAULT_WIDGET_CONFIG.copy,\n ...config.copy,\n },\n sendButton: {\n ...DEFAULT_WIDGET_CONFIG.sendButton,\n ...config.sendButton,\n },\n statusIndicator: {\n ...DEFAULT_WIDGET_CONFIG.statusIndicator,\n ...config.statusIndicator,\n },\n voiceRecognition: {\n ...DEFAULT_WIDGET_CONFIG.voiceRecognition,\n ...config.voiceRecognition,\n },\n features: {\n ...DEFAULT_WIDGET_CONFIG.features,\n ...config.features,\n },\n suggestionChips: config.suggestionChips ?? DEFAULT_WIDGET_CONFIG.suggestionChips,\n suggestionChipsConfig: {\n ...DEFAULT_WIDGET_CONFIG.suggestionChipsConfig,\n ...config.suggestionChipsConfig,\n },\n layout: {\n ...DEFAULT_WIDGET_CONFIG.layout,\n ...config.layout,\n header: {\n ...DEFAULT_WIDGET_CONFIG.layout?.header,\n ...config.layout?.header,\n },\n messages: {\n ...DEFAULT_WIDGET_CONFIG.layout?.messages,\n ...config.layout?.messages,\n avatar: {\n ...DEFAULT_WIDGET_CONFIG.layout?.messages?.avatar,\n ...config.layout?.messages?.avatar,\n },\n timestamp: {\n ...DEFAULT_WIDGET_CONFIG.layout?.messages?.timestamp,\n ...config.layout?.messages?.timestamp,\n },\n },\n slots: {\n ...DEFAULT_WIDGET_CONFIG.layout?.slots,\n ...config.layout?.slots,\n },\n },\n markdown: {\n ...DEFAULT_WIDGET_CONFIG.markdown,\n ...config.markdown,\n options: {\n ...DEFAULT_WIDGET_CONFIG.markdown?.options,\n ...config.markdown?.options,\n },\n },\n messageActions: {\n ...DEFAULT_WIDGET_CONFIG.messageActions,\n ...config.messageActions,\n },\n };\n}\n","type Handler<T> = (payload: T) => void;\n\nexport type EventUnsubscribe = () => void;\n\nexport const createEventBus = <EventMap extends Record<string, any>>() => {\n const listeners = new Map<keyof EventMap, Set<Handler<any>>>();\n\n const on = <K extends keyof EventMap>(\n event: K,\n handler: Handler<EventMap[K]>\n ): EventUnsubscribe => {\n if (!listeners.has(event)) {\n listeners.set(event, new Set());\n }\n listeners.get(event)!.add(handler as Handler<any>);\n return () => off(event, handler);\n };\n\n const off = <K extends keyof EventMap>(\n event: K,\n handler: Handler<EventMap[K]>\n ) => {\n listeners.get(event)?.delete(handler as Handler<any>);\n };\n\n const emit = <K extends keyof EventMap>(event: K, payload: EventMap[K]) => {\n listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Event handler error:\", error);\n }\n }\n });\n };\n\n return { on, off, emit };\n};\n\n","import type {\n AgentWidgetActionContext,\n AgentWidgetActionEventPayload,\n AgentWidgetActionHandler,\n AgentWidgetActionHandlerResult,\n AgentWidgetActionParser,\n AgentWidgetParsedAction,\n AgentWidgetControllerEventMap,\n AgentWidgetMessage\n} from \"../types\";\n\ntype ActionManagerProcessContext = {\n text: string;\n message: AgentWidgetMessage;\n streaming: boolean;\n raw?: string;\n};\n\ntype ActionManagerOptions = {\n parsers: AgentWidgetActionParser[];\n handlers: AgentWidgetActionHandler[];\n getMetadata: () => Record<string, unknown>;\n updateMetadata: (\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) => void;\n emit: <K extends keyof AgentWidgetControllerEventMap>(\n event: K,\n payload: AgentWidgetControllerEventMap[K]\n ) => void;\n documentRef: Document | null;\n};\n\nconst stripCodeFence = (value: string) => {\n const match = value.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n return match ? match[1] : value;\n};\n\nconst extractJsonObject = (value: string) => {\n const trimmed = value.trim();\n const start = trimmed.indexOf(\"{\");\n if (start === -1) return null;\n\n let depth = 0;\n for (let i = start; i < trimmed.length; i += 1) {\n const char = trimmed[i];\n if (char === \"{\") depth += 1;\n if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return trimmed.slice(start, i + 1);\n }\n }\n }\n return null;\n};\n\nexport const defaultJsonActionParser: AgentWidgetActionParser = ({ text }) => {\n if (!text) return null;\n if (!text.includes(\"{\")) return null;\n\n try {\n const withoutFence = stripCodeFence(text);\n const jsonBody = extractJsonObject(withoutFence);\n if (!jsonBody) return null;\n const parsed = JSON.parse(jsonBody);\n if (!parsed || typeof parsed !== \"object\" || !parsed.action) {\n return null;\n }\n const { action, ...payload } = parsed;\n return {\n type: String(action),\n payload,\n raw: parsed\n };\n } catch {\n return null;\n }\n};\n\nconst asString = (value: unknown) =>\n typeof value === \"string\" ? value : value == null ? \"\" : String(value);\n\nexport const defaultActionHandlers: Record<\n string,\n AgentWidgetActionHandler\n> = {\n message: (action) => {\n if (action.type !== \"message\") return;\n const text = asString((action.payload as Record<string, unknown>).text);\n return {\n handled: true,\n displayText: text\n };\n },\n messageAndClick: (action, context) => {\n if (action.type !== \"message_and_click\") return;\n const payload = action.payload as Record<string, unknown>;\n const selector = asString(payload.element);\n if (selector && context.document?.querySelector) {\n const element = context.document.querySelector<HTMLElement>(selector);\n if (element) {\n setTimeout(() => {\n element.click();\n }, 400);\n } else if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.warn(\"[AgentWidget] Element not found for selector:\", selector);\n }\n }\n return {\n handled: true,\n displayText: asString(payload.text)\n };\n }\n};\n\nconst ensureArrayOfStrings = (value: unknown): string[] => {\n if (Array.isArray(value)) {\n return value.map((entry) => String(entry));\n }\n return [];\n};\n\nexport const createActionManager = (options: ActionManagerOptions) => {\n let processedIds = new Set(\n ensureArrayOfStrings(options.getMetadata().processedActionMessageIds)\n );\n\n const syncFromMetadata = () => {\n processedIds = new Set(\n ensureArrayOfStrings(options.getMetadata().processedActionMessageIds)\n );\n };\n\n const persistProcessedIds = () => {\n const latestIds = Array.from(processedIds);\n options.updateMetadata((prev) => ({\n ...prev,\n processedActionMessageIds: latestIds\n }));\n };\n\n const process = (context: ActionManagerProcessContext): { text: string; persist: boolean } | null => {\n if (\n context.streaming ||\n context.message.role !== \"assistant\" ||\n !context.text ||\n processedIds.has(context.message.id)\n ) {\n return null;\n }\n\n const parseSource =\n (typeof context.raw === \"string\" && context.raw) ||\n (typeof context.message.rawContent === \"string\" &&\n context.message.rawContent) ||\n (typeof context.text === \"string\" && context.text) ||\n null;\n\n if (\n !parseSource &&\n typeof context.text === \"string\" &&\n context.text.trim().startsWith(\"{\") &&\n typeof console !== \"undefined\"\n ) {\n // eslint-disable-next-line no-console\n console.warn(\n \"[AgentWidget] Structured response detected but no raw payload was provided. Ensure your stream parser returns { text, raw }.\"\n );\n }\n\n const action = parseSource\n ? options.parsers.reduce<AgentWidgetParsedAction | null>(\n (acc, parser) =>\n acc || parser?.({ text: parseSource, message: context.message }) || null,\n null\n )\n : null;\n\n if (!action) {\n return null;\n }\n\n processedIds.add(context.message.id);\n persistProcessedIds();\n\n const eventPayload: AgentWidgetActionEventPayload = {\n action,\n message: context.message\n };\n options.emit(\"action:detected\", eventPayload);\n\n for (const handler of options.handlers) {\n if (!handler) continue;\n try {\n const handlerResult = handler(action, {\n message: context.message,\n metadata: options.getMetadata(),\n updateMetadata: options.updateMetadata,\n document: options.documentRef\n } as AgentWidgetActionContext) as AgentWidgetActionHandlerResult | void;\n\n if (!handlerResult) continue;\n\n if (handlerResult.handled) {\n // persistMessage defaults to true if not specified\n const persist = handlerResult.persistMessage !== false;\n const displayText = handlerResult.displayText !== undefined ? handlerResult.displayText : \"\";\n return { text: displayText, persist };\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Action handler error:\", error);\n }\n }\n }\n\n return { text: \"\", persist: true };\n };\n\n return {\n process,\n syncFromMetadata\n };\n};\n\n","import type {\n AgentWidgetMessage,\n AgentWidgetStorageAdapter,\n AgentWidgetStoredState\n} from \"../types\";\n\nconst safeJsonParse = (value: string | null) => {\n if (!value) return null;\n try {\n return JSON.parse(value);\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to parse stored state:\", error);\n }\n return null;\n }\n};\n\nconst sanitizeMessages = (messages: AgentWidgetMessage[]) =>\n messages.map((message) => ({\n ...message,\n streaming: false\n }));\n\nexport const createLocalStorageAdapter = (\n key = \"vanilla-agent-state\"\n): AgentWidgetStorageAdapter => {\n const getStorage = () => {\n if (typeof window === \"undefined\" || !window.localStorage) {\n return null;\n }\n return window.localStorage;\n };\n\n return {\n load: () => {\n const storage = getStorage();\n if (!storage) return null;\n return safeJsonParse(storage.getItem(key));\n },\n save: (state: AgentWidgetStoredState) => {\n const storage = getStorage();\n if (!storage) return;\n try {\n const payload: AgentWidgetStoredState = {\n ...state,\n messages: state.messages ? sanitizeMessages(state.messages) : undefined\n };\n storage.setItem(key, JSON.stringify(payload));\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to persist state:\", error);\n }\n }\n },\n clear: () => {\n const storage = getStorage();\n if (!storage) return;\n try {\n storage.removeItem(key);\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear stored state:\", error);\n }\n }\n }\n };\n};\n\n","import { AgentWidgetConfig, AgentWidgetMessage } from \"../types\";\n\n/**\n * Context provided to component renderers\n */\nexport interface ComponentContext {\n message: AgentWidgetMessage;\n config: AgentWidgetConfig;\n /**\n * Update component props during streaming\n */\n updateProps: (newProps: Record<string, unknown>) => void;\n}\n\n/**\n * Component renderer function signature\n */\nexport type ComponentRenderer = (\n props: Record<string, unknown>,\n context: ComponentContext\n) => HTMLElement;\n\n/**\n * Component registry for managing custom components\n */\nclass ComponentRegistry {\n private components: Map<string, ComponentRenderer> = new Map();\n\n /**\n * Register a custom component\n */\n register(name: string, renderer: ComponentRenderer): void {\n if (this.components.has(name)) {\n console.warn(`[ComponentRegistry] Component \"${name}\" is already registered. Overwriting.`);\n }\n this.components.set(name, renderer);\n }\n\n /**\n * Unregister a component\n */\n unregister(name: string): void {\n this.components.delete(name);\n }\n\n /**\n * Get a component renderer by name\n */\n get(name: string): ComponentRenderer | undefined {\n return this.components.get(name);\n }\n\n /**\n * Check if a component is registered\n */\n has(name: string): boolean {\n return this.components.has(name);\n }\n\n /**\n * Get all registered component names\n */\n getAllNames(): string[] {\n return Array.from(this.components.keys());\n }\n\n /**\n * Clear all registered components\n */\n clear(): void {\n this.components.clear();\n }\n\n /**\n * Register multiple components at once\n */\n registerAll(components: Record<string, ComponentRenderer>): void {\n Object.entries(components).forEach(([name, renderer]) => {\n this.register(name, renderer);\n });\n }\n}\n\n/**\n * Global component registry instance\n */\nexport const componentRegistry = new ComponentRegistry();\n","import { parse as parsePartialJson, STR, OBJ } from \"partial-json\";\n\n/**\n * Represents a component directive extracted from JSON\n */\nexport interface ComponentDirective {\n component: string;\n props: Record<string, unknown>;\n raw: string;\n}\n\n/**\n * Checks if a parsed object is a component directive\n */\nfunction isComponentDirective(obj: unknown): obj is { component: string; props?: unknown } {\n if (!obj || typeof obj !== \"object\") return false;\n if (!(\"component\" in obj)) return false;\n const component = (obj as { component: unknown }).component;\n return typeof component === \"string\" && component.length > 0;\n}\n\n/**\n * Extracts component directive from parsed JSON object\n */\nfunction extractComponentDirective(\n parsed: unknown,\n rawJson: string\n): ComponentDirective | null {\n if (!isComponentDirective(parsed)) {\n return null;\n }\n\n const props = parsed.props && typeof parsed.props === \"object\" && parsed.props !== null\n ? (parsed.props as Record<string, unknown>)\n : {};\n\n return {\n component: parsed.component,\n props,\n raw: rawJson\n };\n}\n\n/**\n * Creates a parser that extracts component directives from JSON streams\n * This parser looks for objects with a \"component\" field and extracts\n * the component name and props incrementally as they stream in.\n */\nexport function createComponentStreamParser() {\n let extractedDirective: ComponentDirective | null = null;\n let processedLength = 0;\n\n return {\n /**\n * Get the currently extracted component directive\n */\n getExtractedDirective: (): ComponentDirective | null => {\n return extractedDirective;\n },\n\n /**\n * Process a chunk of JSON and extract component directive if present\n */\n processChunk: (accumulatedContent: string): ComponentDirective | null => {\n // Validate that the accumulated content looks like JSON\n const trimmed = accumulatedContent.trim();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return null;\n }\n\n // Skip if no new content\n if (accumulatedContent.length <= processedLength) {\n return extractedDirective;\n }\n\n try {\n // Parse partial JSON - allow partial strings and objects during streaming\n // STR | OBJ allows incomplete strings and objects during streaming\n const parsed = parsePartialJson(accumulatedContent, STR | OBJ);\n\n // Try to extract component directive\n const directive = extractComponentDirective(parsed, accumulatedContent);\n if (directive) {\n extractedDirective = directive;\n }\n } catch (error) {\n // If parsing fails completely, keep the last extracted directive\n // This can happen with very malformed JSON during streaming\n }\n\n // Update processed length\n processedLength = accumulatedContent.length;\n\n return extractedDirective;\n },\n\n /**\n * Reset the parser state\n */\n reset: () => {\n extractedDirective = null;\n processedLength = 0;\n }\n };\n}\n\n/**\n * Type guard to check if an object is a component directive\n */\nexport function isComponentDirectiveType(obj: unknown): obj is ComponentDirective {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"component\" in obj &&\n typeof (obj as { component: unknown }).component === \"string\" &&\n \"props\" in obj &&\n typeof (obj as { props: unknown }).props === \"object\"\n );\n}\n","import { AgentWidgetMessage, AgentWidgetConfig } from \"../types\";\nimport { componentRegistry, ComponentContext } from \"../components/registry\";\nimport { ComponentDirective, createComponentStreamParser } from \"./component-parser\";\nimport { createStandardBubble, MessageTransform } from \"../components/message-bubble\";\n\n/**\n * Options for component middleware\n */\nexport interface ComponentMiddlewareOptions {\n config: AgentWidgetConfig;\n message: AgentWidgetMessage;\n transform: MessageTransform;\n onPropsUpdate?: (props: Record<string, unknown>) => void;\n}\n\n/**\n * Renders a component directive into an HTMLElement\n */\nexport function renderComponentDirective(\n directive: ComponentDirective,\n options: ComponentMiddlewareOptions\n): HTMLElement | null {\n const { config, message, onPropsUpdate } = options;\n\n // Get component renderer from registry\n const renderer = componentRegistry.get(directive.component);\n if (!renderer) {\n // Component not found, fall back to default rendering\n console.warn(\n `[ComponentMiddleware] Component \"${directive.component}\" not found in registry. Falling back to default rendering.`\n );\n return null;\n }\n\n // Create component context\n const context: ComponentContext = {\n message,\n config,\n updateProps: (newProps: Record<string, unknown>) => {\n if (onPropsUpdate) {\n onPropsUpdate(newProps);\n }\n }\n };\n\n try {\n // Render the component\n const element = renderer(directive.props, context);\n return element;\n } catch (error) {\n console.error(\n `[ComponentMiddleware] Error rendering component \"${directive.component}\":`,\n error\n );\n return null;\n }\n}\n\n/**\n * Creates middleware that processes component directives from streamed JSON\n */\nexport function createComponentMiddleware() {\n const parser = createComponentStreamParser();\n\n return {\n /**\n * Process accumulated content and extract component directive\n */\n processChunk: (accumulatedContent: string): ComponentDirective | null => {\n return parser.processChunk(accumulatedContent);\n },\n\n /**\n * Get the currently extracted directive\n */\n getDirective: (): ComponentDirective | null => {\n return parser.getExtractedDirective();\n },\n\n /**\n * Reset the parser state\n */\n reset: () => {\n parser.reset();\n }\n };\n}\n\n/**\n * Checks if a message contains a component directive in its raw content\n */\nexport function hasComponentDirective(message: AgentWidgetMessage): boolean {\n if (!message.rawContent) return false;\n \n try {\n const parsed = JSON.parse(message.rawContent);\n return (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"component\" in parsed &&\n typeof parsed.component === \"string\"\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Extracts component directive from a complete message\n */\nexport function extractComponentDirectiveFromMessage(\n message: AgentWidgetMessage\n): ComponentDirective | null {\n if (!message.rawContent) return null;\n\n try {\n const parsed = JSON.parse(message.rawContent);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"component\" in parsed &&\n typeof parsed.component === \"string\"\n ) {\n return {\n component: parsed.component,\n props: (parsed.props && typeof parsed.props === \"object\" && parsed.props !== null\n ? parsed.props\n : {}) as Record<string, unknown>,\n raw: message.rawContent\n };\n }\n } catch {\n // Not valid JSON or not a component directive\n }\n\n return null;\n}\n","/**\n * Feedback UI components for CSAT and NPS collection\n */\n\nexport type CSATFeedbackOptions = {\n /** Callback when user submits CSAT feedback */\n onSubmit: (rating: number, comment?: string) => void | Promise<void>;\n /** Callback when user dismisses the feedback form */\n onDismiss?: () => void;\n /** Title text */\n title?: string;\n /** Subtitle/question text */\n subtitle?: string;\n /** Placeholder for optional comment field */\n commentPlaceholder?: string;\n /** Submit button text */\n submitText?: string;\n /** Skip button text */\n skipText?: string;\n /** Show comment field */\n showComment?: boolean;\n /** Rating labels (5 items for ratings 1-5) */\n ratingLabels?: [string, string, string, string, string];\n};\n\nexport type NPSFeedbackOptions = {\n /** Callback when user submits NPS feedback */\n onSubmit: (rating: number, comment?: string) => void | Promise<void>;\n /** Callback when user dismisses the feedback form */\n onDismiss?: () => void;\n /** Title text */\n title?: string;\n /** Subtitle/question text */\n subtitle?: string;\n /** Placeholder for optional comment field */\n commentPlaceholder?: string;\n /** Submit button text */\n submitText?: string;\n /** Skip button text */\n skipText?: string;\n /** Show comment field */\n showComment?: boolean;\n /** Low label (left side) */\n lowLabel?: string;\n /** High label (right side) */\n highLabel?: string;\n};\n\nconst defaultCSATLabels: [string, string, string, string, string] = [\n 'Very dissatisfied',\n 'Dissatisfied',\n 'Neutral',\n 'Satisfied',\n 'Very satisfied'\n];\n\n/**\n * Create a CSAT (Customer Satisfaction) feedback form\n * Rating scale: 1-5\n */\nexport function createCSATFeedback(options: CSATFeedbackOptions): HTMLElement {\n const {\n onSubmit,\n onDismiss,\n title = 'How satisfied are you?',\n subtitle = 'Please rate your experience',\n commentPlaceholder = 'Share your thoughts (optional)...',\n submitText = 'Submit',\n skipText = 'Skip',\n showComment = true,\n ratingLabels = defaultCSATLabels,\n } = options;\n\n const container = document.createElement('div');\n container.className = 'tvw-feedback-container tvw-feedback-csat';\n container.setAttribute('role', 'dialog');\n container.setAttribute('aria-label', 'Customer satisfaction feedback');\n\n let selectedRating: number | null = null;\n\n // Create inner content\n const content = document.createElement('div');\n content.className = 'tvw-feedback-content';\n\n // Header\n const header = document.createElement('div');\n header.className = 'tvw-feedback-header';\n \n const titleEl = document.createElement('h3');\n titleEl.className = 'tvw-feedback-title';\n titleEl.textContent = title;\n header.appendChild(titleEl);\n\n const subtitleEl = document.createElement('p');\n subtitleEl.className = 'tvw-feedback-subtitle';\n subtitleEl.textContent = subtitle;\n header.appendChild(subtitleEl);\n\n content.appendChild(header);\n\n // Rating buttons (1-5 stars or numbers)\n const ratingContainer = document.createElement('div');\n ratingContainer.className = 'tvw-feedback-rating tvw-feedback-rating-csat';\n ratingContainer.setAttribute('role', 'radiogroup');\n ratingContainer.setAttribute('aria-label', 'Satisfaction rating from 1 to 5');\n\n const ratingButtons: HTMLButtonElement[] = [];\n\n for (let i = 1; i <= 5; i++) {\n const ratingButton = document.createElement('button');\n ratingButton.type = 'button';\n ratingButton.className = 'tvw-feedback-rating-btn tvw-feedback-star-btn';\n ratingButton.setAttribute('role', 'radio');\n ratingButton.setAttribute('aria-checked', 'false');\n ratingButton.setAttribute('aria-label', `${i} star${i > 1 ? 's' : ''}: ${ratingLabels[i - 1]}`);\n ratingButton.title = ratingLabels[i - 1];\n ratingButton.dataset.rating = String(i);\n\n // Star icon (filled when selected)\n ratingButton.innerHTML = `\n <svg class=\"tvw-feedback-star\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"></polygon>\n </svg>\n `;\n\n ratingButton.addEventListener('click', () => {\n selectedRating = i;\n ratingButtons.forEach((btn, index) => {\n const isSelected = index < i;\n btn.classList.toggle('selected', isSelected);\n btn.setAttribute('aria-checked', index === i - 1 ? 'true' : 'false');\n });\n });\n\n ratingButtons.push(ratingButton);\n ratingContainer.appendChild(ratingButton);\n }\n\n content.appendChild(ratingContainer);\n\n // Comment field\n let commentTextarea: HTMLTextAreaElement | null = null;\n if (showComment) {\n const commentContainer = document.createElement('div');\n commentContainer.className = 'tvw-feedback-comment-container';\n \n commentTextarea = document.createElement('textarea');\n commentTextarea.className = 'tvw-feedback-comment';\n commentTextarea.placeholder = commentPlaceholder;\n commentTextarea.rows = 3;\n commentTextarea.setAttribute('aria-label', 'Additional comments');\n \n commentContainer.appendChild(commentTextarea);\n content.appendChild(commentContainer);\n }\n\n // Action buttons\n const actions = document.createElement('div');\n actions.className = 'tvw-feedback-actions';\n\n const skipButton = document.createElement('button');\n skipButton.type = 'button';\n skipButton.className = 'tvw-feedback-btn tvw-feedback-btn-skip';\n skipButton.textContent = skipText;\n skipButton.addEventListener('click', () => {\n onDismiss?.();\n container.remove();\n });\n\n const submitButton = document.createElement('button');\n submitButton.type = 'button';\n submitButton.className = 'tvw-feedback-btn tvw-feedback-btn-submit';\n submitButton.textContent = submitText;\n submitButton.addEventListener('click', async () => {\n if (selectedRating === null) {\n // Shake the rating container to indicate selection required\n ratingContainer.classList.add('tvw-feedback-shake');\n setTimeout(() => ratingContainer.classList.remove('tvw-feedback-shake'), 500);\n return;\n }\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n const comment = commentTextarea?.value.trim() || undefined;\n await onSubmit(selectedRating, comment);\n container.remove();\n } catch (error) {\n submitButton.disabled = false;\n submitButton.textContent = submitText;\n // eslint-disable-next-line no-console\n console.error('[CSAT Feedback] Failed to submit:', error);\n }\n });\n\n actions.appendChild(skipButton);\n actions.appendChild(submitButton);\n content.appendChild(actions);\n\n container.appendChild(content);\n\n return container;\n}\n\n/**\n * Create an NPS (Net Promoter Score) feedback form\n * Rating scale: 0-10\n */\nexport function createNPSFeedback(options: NPSFeedbackOptions): HTMLElement {\n const {\n onSubmit,\n onDismiss,\n title = 'How likely are you to recommend us?',\n subtitle = 'On a scale of 0 to 10',\n commentPlaceholder = 'What could we do better? (optional)...',\n submitText = 'Submit',\n skipText = 'Skip',\n showComment = true,\n lowLabel = 'Not likely',\n highLabel = 'Very likely',\n } = options;\n\n const container = document.createElement('div');\n container.className = 'tvw-feedback-container tvw-feedback-nps';\n container.setAttribute('role', 'dialog');\n container.setAttribute('aria-label', 'Net Promoter Score feedback');\n\n let selectedRating: number | null = null;\n\n // Create inner content\n const content = document.createElement('div');\n content.className = 'tvw-feedback-content';\n\n // Header\n const header = document.createElement('div');\n header.className = 'tvw-feedback-header';\n \n const titleEl = document.createElement('h3');\n titleEl.className = 'tvw-feedback-title';\n titleEl.textContent = title;\n header.appendChild(titleEl);\n\n const subtitleEl = document.createElement('p');\n subtitleEl.className = 'tvw-feedback-subtitle';\n subtitleEl.textContent = subtitle;\n header.appendChild(subtitleEl);\n\n content.appendChild(header);\n\n // Rating buttons (0-10)\n const ratingContainer = document.createElement('div');\n ratingContainer.className = 'tvw-feedback-rating tvw-feedback-rating-nps';\n ratingContainer.setAttribute('role', 'radiogroup');\n ratingContainer.setAttribute('aria-label', 'Likelihood rating from 0 to 10');\n\n // Labels row\n const labelsRow = document.createElement('div');\n labelsRow.className = 'tvw-feedback-labels';\n \n const lowLabelEl = document.createElement('span');\n lowLabelEl.className = 'tvw-feedback-label-low';\n lowLabelEl.textContent = lowLabel;\n \n const highLabelEl = document.createElement('span');\n highLabelEl.className = 'tvw-feedback-label-high';\n highLabelEl.textContent = highLabel;\n \n labelsRow.appendChild(lowLabelEl);\n labelsRow.appendChild(highLabelEl);\n \n // Numbers row\n const numbersRow = document.createElement('div');\n numbersRow.className = 'tvw-feedback-numbers';\n\n const ratingButtons: HTMLButtonElement[] = [];\n\n for (let i = 0; i <= 10; i++) {\n const ratingButton = document.createElement('button');\n ratingButton.type = 'button';\n ratingButton.className = 'tvw-feedback-rating-btn tvw-feedback-number-btn';\n ratingButton.setAttribute('role', 'radio');\n ratingButton.setAttribute('aria-checked', 'false');\n ratingButton.setAttribute('aria-label', `Rating ${i} out of 10`);\n ratingButton.textContent = String(i);\n ratingButton.dataset.rating = String(i);\n\n // Color coding: detractors (0-6), passives (7-8), promoters (9-10)\n if (i <= 6) {\n ratingButton.classList.add('tvw-feedback-detractor');\n } else if (i <= 8) {\n ratingButton.classList.add('tvw-feedback-passive');\n } else {\n ratingButton.classList.add('tvw-feedback-promoter');\n }\n\n ratingButton.addEventListener('click', () => {\n selectedRating = i;\n ratingButtons.forEach((btn, index) => {\n btn.classList.toggle('selected', index === i);\n btn.setAttribute('aria-checked', index === i ? 'true' : 'false');\n });\n });\n\n ratingButtons.push(ratingButton);\n numbersRow.appendChild(ratingButton);\n }\n\n ratingContainer.appendChild(labelsRow);\n ratingContainer.appendChild(numbersRow);\n content.appendChild(ratingContainer);\n\n // Comment field\n let commentTextarea: HTMLTextAreaElement | null = null;\n if (showComment) {\n const commentContainer = document.createElement('div');\n commentContainer.className = 'tvw-feedback-comment-container';\n \n commentTextarea = document.createElement('textarea');\n commentTextarea.className = 'tvw-feedback-comment';\n commentTextarea.placeholder = commentPlaceholder;\n commentTextarea.rows = 3;\n commentTextarea.setAttribute('aria-label', 'Additional comments');\n \n commentContainer.appendChild(commentTextarea);\n content.appendChild(commentContainer);\n }\n\n // Action buttons\n const actions = document.createElement('div');\n actions.className = 'tvw-feedback-actions';\n\n const skipButton = document.createElement('button');\n skipButton.type = 'button';\n skipButton.className = 'tvw-feedback-btn tvw-feedback-btn-skip';\n skipButton.textContent = skipText;\n skipButton.addEventListener('click', () => {\n onDismiss?.();\n container.remove();\n });\n\n const submitButton = document.createElement('button');\n submitButton.type = 'button';\n submitButton.className = 'tvw-feedback-btn tvw-feedback-btn-submit';\n submitButton.textContent = submitText;\n submitButton.addEventListener('click', async () => {\n if (selectedRating === null) {\n // Shake the rating container to indicate selection required\n numbersRow.classList.add('tvw-feedback-shake');\n setTimeout(() => numbersRow.classList.remove('tvw-feedback-shake'), 500);\n return;\n }\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n const comment = commentTextarea?.value.trim() || undefined;\n await onSubmit(selectedRating, comment);\n container.remove();\n } catch (error) {\n submitButton.disabled = false;\n submitButton.textContent = submitText;\n // eslint-disable-next-line no-console\n console.error('[NPS Feedback] Failed to submit:', error);\n }\n });\n\n actions.appendChild(skipButton);\n actions.appendChild(submitButton);\n content.appendChild(actions);\n\n container.appendChild(content);\n\n return container;\n}\n\n\n\n","import { escapeHtml, createMarkdownProcessorFromConfig } from \"./postprocessors\";\nimport { AgentWidgetSession, AgentWidgetSessionStatus } from \"./session\";\nimport {\n AgentWidgetConfig,\n AgentWidgetMessage,\n AgentWidgetEvent,\n AgentWidgetStorageAdapter,\n AgentWidgetStoredState,\n AgentWidgetControllerEventMap,\n AgentWidgetVoiceStateEvent,\n AgentWidgetStateEvent,\n AgentWidgetStateSnapshot,\n WidgetLayoutSlot,\n SlotRenderer,\n AgentWidgetMessageFeedback\n} from \"./types\";\nimport { applyThemeVariables, createThemeObserver } from \"./utils/theme\";\nimport { renderLucideIcon } from \"./utils/icons\";\nimport { createElement } from \"./utils/dom\";\nimport { morphMessages } from \"./utils/morph\";\nimport { statusCopy } from \"./utils/constants\";\nimport { createLauncherButton } from \"./components/launcher\";\nimport { createWrapper, buildPanel, buildHeader, buildComposer, attachHeaderToContainer } from \"./components/panel\";\nimport { buildHeaderWithLayout } from \"./components/header-layouts\";\nimport { positionMap } from \"./utils/positioning\";\nimport type { HeaderElements, ComposerElements } from \"./components/panel\";\nimport { MessageTransform, MessageActionCallbacks } from \"./components/message-bubble\";\nimport { createStandardBubble, createTypingIndicator } from \"./components/message-bubble\";\nimport { createReasoningBubble } from \"./components/reasoning-bubble\";\nimport { createToolBubble } from \"./components/tool-bubble\";\nimport { createSuggestions } from \"./components/suggestions\";\nimport { enhanceWithForms } from \"./components/forms\";\nimport { pluginRegistry } from \"./plugins/registry\";\nimport { mergeWithDefaults } from \"./defaults\";\nimport { createEventBus } from \"./utils/events\";\nimport {\n createActionManager,\n defaultActionHandlers,\n defaultJsonActionParser\n} from \"./utils/actions\";\nimport { createLocalStorageAdapter } from \"./utils/storage\";\nimport { componentRegistry } from \"./components/registry\";\nimport {\n renderComponentDirective,\n extractComponentDirectiveFromMessage,\n hasComponentDirective\n} from \"./utils/component-middleware\";\nimport {\n createCSATFeedback,\n createNPSFeedback,\n type CSATFeedbackOptions,\n type NPSFeedbackOptions\n} from \"./components/feedback\";\n\n// Default localStorage key for chat history (automatically cleared on clear chat)\nconst DEFAULT_CHAT_HISTORY_STORAGE_KEY = \"vanilla-agent-chat-history\";\nconst VOICE_STATE_RESTORE_WINDOW = 30 * 1000;\n\nconst ensureRecord = (value: unknown): Record<string, unknown> => {\n if (!value || typeof value !== \"object\") {\n return {};\n }\n return { ...(value as Record<string, unknown>) };\n};\n\nconst stripStreamingFromMessages = (messages: AgentWidgetMessage[]) =>\n messages.map((message) => ({\n ...message,\n streaming: false\n }));\n\ntype Controller = {\n update: (config: AgentWidgetConfig) => void;\n destroy: () => void;\n open: () => void;\n close: () => void;\n toggle: () => void;\n clearChat: () => void;\n setMessage: (message: string) => boolean;\n submitMessage: (message?: string) => boolean;\n startVoiceRecognition: () => boolean;\n stopVoiceRecognition: () => boolean;\n injectTestMessage: (event: AgentWidgetEvent) => void;\n getMessages: () => AgentWidgetMessage[];\n getStatus: () => AgentWidgetSessionStatus;\n getPersistentMetadata: () => Record<string, unknown>;\n updatePersistentMetadata: (\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) => void;\n on: <K extends keyof AgentWidgetControllerEventMap>(\n event: K,\n handler: (payload: AgentWidgetControllerEventMap[K]) => void\n ) => () => void;\n off: <K extends keyof AgentWidgetControllerEventMap>(\n event: K,\n handler: (payload: AgentWidgetControllerEventMap[K]) => void\n ) => void;\n // State query methods\n isOpen: () => boolean;\n isVoiceActive: () => boolean;\n getState: () => AgentWidgetStateSnapshot;\n // Feedback methods (CSAT/NPS)\n showCSATFeedback: (options?: Partial<CSATFeedbackOptions>) => void;\n showNPSFeedback: (options?: Partial<NPSFeedbackOptions>) => void;\n submitCSATFeedback: (rating: number, comment?: string) => Promise<void>;\n submitNPSFeedback: (rating: number, comment?: string) => Promise<void>;\n};\n\nconst buildPostprocessor = (\n cfg: AgentWidgetConfig | undefined,\n actionManager?: ReturnType<typeof createActionManager>\n): MessageTransform => {\n // Create markdown processor from config if markdown config is provided\n // This allows users to enable markdown rendering via config.markdown\n const markdownProcessor = cfg?.markdown \n ? createMarkdownProcessorFromConfig(cfg.markdown)\n : null;\n\n return (context) => {\n let nextText = context.text ?? \"\";\n const rawPayload = context.message.rawContent ?? null;\n\n if (actionManager) {\n const actionResult = actionManager.process({\n text: nextText,\n raw: rawPayload ?? nextText,\n message: context.message,\n streaming: context.streaming\n });\n if (actionResult !== null) {\n nextText = actionResult.text;\n // Mark message as non-persistable if persist is false\n if (!actionResult.persist) {\n (context.message as any).__skipPersist = true;\n }\n }\n }\n\n // Priority: postprocessMessage > markdown config > escapeHtml\n if (cfg?.postprocessMessage) {\n return cfg.postprocessMessage({\n ...context,\n text: nextText,\n raw: rawPayload ?? context.text ?? \"\"\n });\n }\n\n // Use markdown processor if markdown config is provided\n if (markdownProcessor) {\n return markdownProcessor(nextText);\n }\n\n return escapeHtml(nextText);\n };\n};\n\nexport const createAgentExperience = (\n mount: HTMLElement,\n initialConfig?: AgentWidgetConfig,\n runtimeOptions?: { debugTools?: boolean }\n): Controller => {\n // Tailwind config uses important: \"#vanilla-agent-root\", so ensure mount has this ID\n if (!mount.id || mount.id !== \"vanilla-agent-root\") {\n mount.id = \"vanilla-agent-root\";\n }\n\n let config = mergeWithDefaults(initialConfig) as AgentWidgetConfig;\n // Note: applyThemeVariables is called after applyFullHeightStyles() below\n // because applyFullHeightStyles resets mount.style.cssText\n\n // Get plugins for this instance\n const plugins = pluginRegistry.getForInstance(config.plugins);\n \n // Register components from config\n if (config.components) {\n componentRegistry.registerAll(config.components);\n }\n const eventBus = createEventBus<AgentWidgetControllerEventMap>();\n\n const storageAdapter: AgentWidgetStorageAdapter =\n config.storageAdapter ?? createLocalStorageAdapter();\n let persistentMetadata: Record<string, unknown> = {};\n let pendingStoredState: Promise<AgentWidgetStoredState | null> | null = null;\n\n if (storageAdapter?.load) {\n try {\n const storedState = storageAdapter.load();\n if (storedState && typeof (storedState as Promise<any>).then === \"function\") {\n pendingStoredState = storedState as Promise<AgentWidgetStoredState | null>;\n } else if (storedState) {\n const immediateState = storedState as AgentWidgetStoredState;\n if (immediateState.metadata) {\n persistentMetadata = ensureRecord(immediateState.metadata);\n }\n if (immediateState.messages?.length) {\n config = { ...config, initialMessages: immediateState.messages };\n }\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to load stored state:\", error);\n }\n }\n }\n\n const getMetadata = () => persistentMetadata;\n const updateMetadata = (\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) => {\n const next = updater({ ...persistentMetadata }) ?? {};\n persistentMetadata = next;\n persistState();\n };\n\n const resolvedActionParsers =\n config.actionParsers && config.actionParsers.length\n ? config.actionParsers\n : [defaultJsonActionParser];\n\n const resolvedActionHandlers =\n config.actionHandlers && config.actionHandlers.length\n ? config.actionHandlers\n : [defaultActionHandlers.message, defaultActionHandlers.messageAndClick];\n\n let actionManager = createActionManager({\n parsers: resolvedActionParsers,\n handlers: resolvedActionHandlers,\n getMetadata,\n updateMetadata,\n emit: eventBus.emit,\n documentRef: typeof document !== \"undefined\" ? document : null\n });\n actionManager.syncFromMetadata();\n\n let launcherEnabled = config.launcher?.enabled ?? true;\n let autoExpand = config.launcher?.autoExpand ?? false;\n let prevAutoExpand = autoExpand;\n let prevLauncherEnabled = launcherEnabled;\n let prevHeaderLayout = config.layout?.header?.layout;\n let open = launcherEnabled ? autoExpand : true;\n let postprocess = buildPostprocessor(config, actionManager);\n let showReasoning = config.features?.showReasoning ?? true;\n let showToolCalls = config.features?.showToolCalls ?? true;\n \n // Create message action callbacks that emit events and optionally send to API\n const messageActionCallbacks: MessageActionCallbacks = {\n onCopy: (message: AgentWidgetMessage) => {\n eventBus.emit(\"message:copy\", message);\n // Send copy feedback to API if in client token mode\n if (session?.isClientTokenMode()) {\n session.submitMessageFeedback(message.id, 'copy').catch((error) => {\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to submit copy feedback:\", error);\n }\n });\n }\n // Call user-provided callback\n config.messageActions?.onCopy?.(message);\n },\n onFeedback: (feedback: AgentWidgetMessageFeedback) => {\n eventBus.emit(\"message:feedback\", feedback);\n // Send feedback to API if in client token mode\n if (session?.isClientTokenMode()) {\n session.submitMessageFeedback(feedback.messageId, feedback.type).catch((error) => {\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to submit feedback:\", error);\n }\n });\n }\n // Call user-provided callback\n config.messageActions?.onFeedback?.(feedback);\n }\n };\n \n // Get status indicator config\n const statusConfig = config.statusIndicator ?? {};\n const getStatusText = (status: AgentWidgetSessionStatus): string => {\n if (status === \"idle\") return statusConfig.idleText ?? statusCopy.idle;\n if (status === \"connecting\") return statusConfig.connectingText ?? statusCopy.connecting;\n if (status === \"connected\") return statusConfig.connectedText ?? statusCopy.connected;\n if (status === \"error\") return statusConfig.errorText ?? statusCopy.error;\n return statusCopy[status];\n };\n\n const { wrapper, panel } = createWrapper(config);\n const panelElements = buildPanel(config, launcherEnabled);\n let {\n container,\n body,\n messagesWrapper,\n suggestions,\n textarea,\n sendButton,\n sendButtonWrapper,\n composerForm,\n statusText,\n introTitle,\n introSubtitle,\n closeButton,\n iconHolder,\n headerTitle,\n headerSubtitle,\n header,\n footer\n } = panelElements;\n \n // Use mutable references for mic button so we can update them dynamically\n let micButton: HTMLButtonElement | null = panelElements.micButton;\n let micButtonWrapper: HTMLElement | null = panelElements.micButtonWrapper;\n\n // Plugin hook: renderHeader - allow plugins to provide custom header\n const headerPlugin = plugins.find(p => p.renderHeader);\n if (headerPlugin?.renderHeader) {\n const customHeader = headerPlugin.renderHeader({\n config,\n defaultRenderer: () => {\n const headerElements = buildHeader({ config, showClose: launcherEnabled });\n attachHeaderToContainer(container, headerElements, config);\n return headerElements.header;\n },\n onClose: () => setOpenState(false, \"user\")\n });\n if (customHeader) {\n // Replace the default header with custom header\n const existingHeader = container.querySelector('.tvw-border-b-cw-divider');\n if (existingHeader) {\n existingHeader.replaceWith(customHeader);\n header = customHeader;\n }\n }\n }\n\n // Plugin hook: renderComposer - allow plugins to provide custom composer\n const composerPlugin = plugins.find(p => p.renderComposer);\n if (composerPlugin?.renderComposer) {\n const customComposer = composerPlugin.renderComposer({\n config,\n defaultRenderer: () => {\n const composerElements = buildComposer({ config });\n return composerElements.footer;\n },\n onSubmit: (text: string) => {\n if (session && !session.isStreaming()) {\n session.sendMessage(text);\n }\n },\n disabled: false\n });\n if (customComposer) {\n // Replace the default footer with custom composer\n footer.replaceWith(customComposer);\n footer = customComposer;\n // Note: When using custom composer, textarea/sendButton/etc may not exist\n // The plugin is responsible for providing its own submit handling\n }\n }\n\n // Slot system: allow custom content injection into specific regions\n const renderSlots = () => {\n const slots = config.layout?.slots ?? {};\n \n // Helper to get default slot content\n const getDefaultSlotContent = (slot: WidgetLayoutSlot): HTMLElement | null => {\n switch (slot) {\n case \"body-top\":\n // Default: the intro card\n return container.querySelector(\".tvw-rounded-2xl.tvw-bg-cw-surface.tvw-p-6\") as HTMLElement || null;\n case \"messages\":\n return messagesWrapper;\n case \"footer-top\":\n return suggestions;\n case \"composer\":\n return composerForm;\n case \"footer-bottom\":\n return statusText;\n default:\n return null;\n }\n };\n\n // Helper to insert content into slot region\n const insertSlotContent = (slot: WidgetLayoutSlot, element: HTMLElement) => {\n switch (slot) {\n case \"header-left\":\n case \"header-center\":\n case \"header-right\":\n // Header slots - prepend/append to header\n if (slot === \"header-left\") {\n header.insertBefore(element, header.firstChild);\n } else if (slot === \"header-right\") {\n header.appendChild(element);\n } else {\n // header-center: insert after icon/title\n const titleSection = header.querySelector(\".tvw-flex-col\");\n if (titleSection) {\n titleSection.parentNode?.insertBefore(element, titleSection.nextSibling);\n } else {\n header.appendChild(element);\n }\n }\n break;\n case \"body-top\":\n // Replace or prepend to body\n const introCard = body.querySelector(\".tvw-rounded-2xl.tvw-bg-cw-surface.tvw-p-6\");\n if (introCard) {\n introCard.replaceWith(element);\n } else {\n body.insertBefore(element, body.firstChild);\n }\n break;\n case \"body-bottom\":\n // Append after messages wrapper\n body.appendChild(element);\n break;\n case \"footer-top\":\n // Replace suggestions area\n suggestions.replaceWith(element);\n break;\n case \"footer-bottom\":\n // Replace or append after status text\n statusText.replaceWith(element);\n break;\n default:\n // For other slots, just append to appropriate container\n break;\n }\n };\n\n // Process each configured slot\n for (const [slotName, renderer] of Object.entries(slots) as [WidgetLayoutSlot, SlotRenderer][]) {\n if (renderer) {\n try {\n const slotElement = renderer({\n config,\n defaultContent: () => getDefaultSlotContent(slotName)\n });\n if (slotElement) {\n insertSlotContent(slotName, slotElement);\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(`[AgentWidget] Error rendering slot \"${slotName}\":`, error);\n }\n }\n }\n }\n };\n\n // Render custom slots\n renderSlots();\n\n panel.appendChild(container);\n mount.appendChild(wrapper);\n\n // Apply full-height and sidebar styles if enabled\n // This ensures the widget fills its container height with proper flex layout\n const applyFullHeightStyles = () => {\n const sidebarMode = config.launcher?.sidebarMode ?? false;\n const fullHeight = sidebarMode || (config.launcher?.fullHeight ?? false);\n const theme = config.theme ?? {};\n \n // Determine panel styling based on mode, with theme overrides\n const position = config.launcher?.position ?? 'bottom-left';\n const isLeftSidebar = position === 'bottom-left' || position === 'top-left';\n \n // Default values based on mode\n const defaultPanelBorder = sidebarMode ? 'none' : '1px solid var(--tvw-cw-border)';\n const defaultPanelShadow = sidebarMode \n ? (isLeftSidebar ? '2px 0 12px rgba(0, 0, 0, 0.08)' : '-2px 0 12px rgba(0, 0, 0, 0.08)')\n : '0 25px 50px -12px rgba(0, 0, 0, 0.25)';\n const defaultPanelBorderRadius = sidebarMode ? '0' : '16px';\n \n // Apply theme overrides or defaults\n const panelBorder = theme.panelBorder ?? defaultPanelBorder;\n const panelShadow = theme.panelShadow ?? defaultPanelShadow;\n const panelBorderRadius = theme.panelBorderRadius ?? defaultPanelBorderRadius;\n \n // Reset all inline styles first to handle mode toggling\n // This ensures styles don't persist when switching between modes\n mount.style.cssText = '';\n wrapper.style.cssText = '';\n panel.style.cssText = '';\n container.style.cssText = '';\n body.style.cssText = '';\n footer.style.cssText = '';\n \n // Re-apply panel width/maxWidth from initial setup\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(400px, calc(100vw - 24px))\";\n if (!sidebarMode) {\n panel.style.width = width;\n panel.style.maxWidth = width;\n }\n \n // Apply panel styling\n // Box-shadow is applied to panel (parent) instead of container to avoid\n // rendering artifacts when container has overflow:hidden + border-radius\n // Panel also gets border-radius to make the shadow follow the rounded corners\n panel.style.boxShadow = panelShadow;\n panel.style.borderRadius = panelBorderRadius;\n container.style.border = panelBorder;\n container.style.borderRadius = panelBorderRadius;\n \n // Check if this is inline embed mode (launcher disabled) vs launcher mode\n const isInlineEmbed = config.launcher?.enabled === false;\n \n if (fullHeight) {\n // Mount container\n mount.style.display = 'flex';\n mount.style.flexDirection = 'column';\n mount.style.height = '100%';\n mount.style.minHeight = '0';\n \n // Wrapper\n // - Inline embed: needs overflow:hidden to contain the flex layout\n // - Launcher mode: no overflow:hidden to allow panel's box-shadow to render fully\n wrapper.style.display = 'flex';\n wrapper.style.flexDirection = 'column';\n wrapper.style.flex = '1 1 0%';\n wrapper.style.minHeight = '0';\n wrapper.style.maxHeight = '100%';\n wrapper.style.height = '100%';\n if (isInlineEmbed) {\n wrapper.style.overflow = 'hidden';\n }\n \n // Panel\n panel.style.display = 'flex';\n panel.style.flexDirection = 'column';\n panel.style.flex = '1 1 0%';\n panel.style.minHeight = '0';\n panel.style.maxHeight = '100%';\n panel.style.height = '100%';\n panel.style.overflow = 'hidden';\n \n // Main container\n container.style.display = 'flex';\n container.style.flexDirection = 'column';\n container.style.flex = '1 1 0%';\n container.style.minHeight = '0';\n container.style.maxHeight = '100%';\n container.style.overflow = 'hidden';\n \n // Body (scrollable messages area)\n body.style.flex = '1 1 0%';\n body.style.minHeight = '0';\n body.style.overflowY = 'auto';\n \n // Footer (composer) - should not shrink\n footer.style.flexShrink = '0';\n }\n \n // Handle positioning classes based on mode\n // First remove all position classes to reset state\n wrapper.classList.remove(\n 'tvw-bottom-6', 'tvw-right-6', 'tvw-left-6', 'tvw-top-6',\n 'tvw-bottom-4', 'tvw-right-4', 'tvw-left-4', 'tvw-top-4'\n );\n \n if (!sidebarMode && !isInlineEmbed) {\n // Restore positioning classes when not in sidebar mode (launcher mode only)\n const positionClasses = positionMap[position as keyof typeof positionMap] ?? positionMap['bottom-right'];\n positionClasses.split(' ').forEach(cls => wrapper.classList.add(cls));\n }\n \n // Apply sidebar-specific styles\n if (sidebarMode) {\n const sidebarWidth = config.launcher?.sidebarWidth ?? '420px';\n \n // Wrapper - fixed position, flush with edges\n wrapper.style.cssText = `\n position: fixed !important;\n top: 0 !important;\n bottom: 0 !important;\n width: ${sidebarWidth} !important;\n height: 100vh !important;\n max-height: 100vh !important;\n margin: 0 !important;\n padding: 0 !important;\n display: flex !important;\n flex-direction: column !important;\n ${isLeftSidebar ? 'left: 0 !important; right: auto !important;' : 'left: auto !important; right: 0 !important;'}\n `;\n \n // Panel - fill wrapper (override inline width/max-width from panel.ts)\n // Box-shadow is on panel to avoid rendering artifacts with container's overflow:hidden\n // Border-radius on panel ensures shadow follows rounded corners\n panel.style.cssText = `\n position: relative !important;\n display: flex !important;\n flex-direction: column !important;\n flex: 1 1 0% !important;\n width: 100% !important;\n max-width: 100% !important;\n height: 100% !important;\n min-height: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n box-shadow: ${panelShadow} !important;\n border-radius: ${panelBorderRadius} !important;\n `;\n // Force override any inline width/maxWidth that may be set elsewhere\n panel.style.setProperty('width', '100%', 'important');\n panel.style.setProperty('max-width', '100%', 'important');\n \n // Container - apply configurable styles with sidebar layout\n // Note: box-shadow is on panel, not container\n container.style.cssText = `\n display: flex !important;\n flex-direction: column !important;\n flex: 1 1 0% !important;\n width: 100% !important;\n height: 100% !important;\n min-height: 0 !important;\n max-height: 100% !important;\n overflow: hidden !important;\n border-radius: ${panelBorderRadius} !important;\n border: ${panelBorder} !important;\n `;\n \n // Remove footer border in sidebar mode\n footer.style.cssText = `\n flex-shrink: 0 !important;\n border-top: none !important;\n padding: 8px 16px 12px 16px !important;\n `;\n }\n \n // Apply max-height constraints to wrapper to prevent expanding past viewport top\n // Use both -moz-available (Firefox) and stretch (standard) for cross-browser support\n // Append to cssText to allow multiple fallback values for the same property\n // Only apply to launcher mode (not sidebar or inline embed)\n if (!isInlineEmbed) {\n const maxHeightStyles = 'max-height: -moz-available !important; max-height: stretch !important;';\n const paddingStyles = sidebarMode ? '' : 'padding-top: 1.25em !important;';\n wrapper.style.cssText += maxHeightStyles + paddingStyles;\n }\n };\n applyFullHeightStyles();\n // Apply theme variables after applyFullHeightStyles since it resets mount.style.cssText\n applyThemeVariables(mount, config);\n\n const destroyCallbacks: Array<() => void> = [];\n\n // Set up theme observer for auto color scheme detection\n let cleanupThemeObserver: (() => void) | null = null;\n const setupThemeObserver = () => {\n // Clean up existing observer if any\n if (cleanupThemeObserver) {\n cleanupThemeObserver();\n cleanupThemeObserver = null;\n }\n // Set up new observer if colorScheme is 'auto'\n if (config.colorScheme === 'auto') {\n cleanupThemeObserver = createThemeObserver(() => {\n // Re-apply theme when color scheme changes\n applyThemeVariables(mount, config);\n });\n }\n };\n setupThemeObserver();\n destroyCallbacks.push(() => {\n if (cleanupThemeObserver) {\n cleanupThemeObserver();\n cleanupThemeObserver = null;\n }\n });\n\n const suggestionsManager = createSuggestions(suggestions);\n let closeHandler: (() => void) | null = null;\n let session: AgentWidgetSession;\n let isStreaming = false;\n let shouldAutoScroll = true;\n let lastScrollTop = 0;\n let lastAutoScrollTime = 0;\n let scrollRAF: number | null = null;\n let isAutoScrollBlocked = false;\n let blockUntilTime = 0;\n let isAutoScrolling = false;\n\n const AUTO_SCROLL_THROTTLE = 125;\n const AUTO_SCROLL_BLOCK_TIME = 2000;\n const USER_SCROLL_THRESHOLD = 5;\n const BOTTOM_THRESHOLD = 50;\n const messageState = new Map<\n string,\n { streaming?: boolean; role: AgentWidgetMessage[\"role\"] }\n >();\n const voiceState = {\n active: false,\n manuallyDeactivated: false,\n lastUserMessageWasVoice: false\n };\n const voiceAutoResumeMode = config.voiceRecognition?.autoResume ?? false;\n const emitVoiceState = (source: AgentWidgetVoiceStateEvent[\"source\"]) => {\n eventBus.emit(\"voice:state\", {\n active: voiceState.active,\n source,\n timestamp: Date.now()\n });\n };\n const persistVoiceMetadata = () => {\n updateMetadata((prev) => ({\n ...prev,\n voiceState: {\n active: voiceState.active,\n timestamp: Date.now(),\n manuallyDeactivated: voiceState.manuallyDeactivated\n }\n }));\n };\n const maybeRestoreVoiceFromMetadata = () => {\n if (config.voiceRecognition?.enabled === false) return;\n const rawVoiceState = ensureRecord((persistentMetadata as any).voiceState);\n const wasActive = Boolean(rawVoiceState.active);\n const timestamp = Number(rawVoiceState.timestamp ?? 0);\n voiceState.manuallyDeactivated = Boolean(rawVoiceState.manuallyDeactivated);\n if (wasActive && Date.now() - timestamp < VOICE_STATE_RESTORE_WINDOW) {\n setTimeout(() => {\n if (!voiceState.active) {\n voiceState.manuallyDeactivated = false;\n startVoiceRecognition(\"restore\");\n }\n }, 1000);\n }\n };\n\n const getMessagesForPersistence = () =>\n session \n ? stripStreamingFromMessages(session.getMessages()).filter(msg => !(msg as any).__skipPersist)\n : [];\n\n function persistState(messagesOverride?: AgentWidgetMessage[]) {\n if (!storageAdapter?.save) return;\n\n // Allow saving even if session doesn't exist yet (for metadata during init)\n const messages = messagesOverride\n ? stripStreamingFromMessages(messagesOverride)\n : session\n ? getMessagesForPersistence()\n : [];\n\n const payload = {\n messages,\n metadata: persistentMetadata\n };\n try {\n const result = storageAdapter.save(payload);\n if (result instanceof Promise) {\n result.catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to persist state:\", error);\n }\n });\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to persist state:\", error);\n }\n }\n }\n\n const scheduleAutoScroll = (force = false) => {\n if (!shouldAutoScroll) return;\n\n const now = Date.now();\n\n if (isAutoScrollBlocked && now < blockUntilTime) {\n if (!force) return;\n }\n\n if (isAutoScrollBlocked && now >= blockUntilTime) {\n isAutoScrollBlocked = false;\n }\n\n if (!force && !isStreaming) return;\n\n if (now - lastAutoScrollTime < AUTO_SCROLL_THROTTLE) return;\n lastAutoScrollTime = now;\n\n if (scrollRAF) {\n cancelAnimationFrame(scrollRAF);\n }\n\n scrollRAF = requestAnimationFrame(() => {\n if (isAutoScrollBlocked || !shouldAutoScroll) return;\n isAutoScrolling = true;\n body.scrollTop = body.scrollHeight;\n lastScrollTop = body.scrollTop;\n requestAnimationFrame(() => {\n isAutoScrolling = false;\n });\n scrollRAF = null;\n });\n };\n\n // Track ongoing smooth scroll animation\n let smoothScrollRAF: number | null = null;\n\n // Get the scrollable container using its unique ID\n const getScrollableContainer = (): HTMLElement => {\n // Use the unique ID for reliable selection\n const scrollable = wrapper.querySelector('#vanilla-agent-scroll-container') as HTMLElement;\n // Fallback to body if ID not found (shouldn't happen, but safe fallback)\n return scrollable || body;\n };\n\n // Custom smooth scroll animation with easing\n const smoothScrollToBottom = (element: HTMLElement, duration = 500) => {\n const start = element.scrollTop;\n const clientHeight = element.clientHeight;\n // Recalculate target dynamically to handle layout changes\n let target = element.scrollHeight;\n let distance = target - start;\n\n // Check if already at bottom: scrollTop + clientHeight should be >= scrollHeight\n // Add a small threshold (2px) to account for rounding/subpixel differences\n const isAtBottom = start + clientHeight >= target - 2;\n \n // If already at bottom or very close, skip animation to prevent glitch\n if (isAtBottom || Math.abs(distance) < 5) {\n return;\n }\n\n // Cancel any ongoing smooth scroll animation\n if (smoothScrollRAF !== null) {\n cancelAnimationFrame(smoothScrollRAF);\n smoothScrollRAF = null;\n }\n\n const startTime = performance.now();\n\n // Easing function: ease-out cubic for smooth deceleration\n const easeOutCubic = (t: number): number => {\n return 1 - Math.pow(1 - t, 3);\n };\n\n const animate = (currentTime: number) => {\n // Recalculate target each frame in case scrollHeight changed\n const currentTarget = element.scrollHeight;\n if (currentTarget !== target) {\n target = currentTarget;\n distance = target - start;\n }\n\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / duration, 1);\n const eased = easeOutCubic(progress);\n \n const currentScroll = start + distance * eased;\n element.scrollTop = currentScroll;\n\n if (progress < 1) {\n smoothScrollRAF = requestAnimationFrame(animate);\n } else {\n // Ensure we end exactly at the target\n element.scrollTop = element.scrollHeight;\n smoothScrollRAF = null;\n }\n };\n\n smoothScrollRAF = requestAnimationFrame(animate);\n };\n\n const trackMessages = (messages: AgentWidgetMessage[]) => {\n const nextState = new Map<\n string,\n { streaming?: boolean; role: AgentWidgetMessage[\"role\"] }\n >();\n\n messages.forEach((message) => {\n const previous = messageState.get(message.id);\n nextState.set(message.id, {\n streaming: message.streaming,\n role: message.role\n });\n\n if (!previous && message.role === \"assistant\") {\n eventBus.emit(\"assistant:message\", message);\n }\n\n if (\n message.role === \"assistant\" &&\n previous?.streaming &&\n message.streaming === false\n ) {\n eventBus.emit(\"assistant:complete\", message);\n }\n });\n\n messageState.clear();\n nextState.forEach((value, key) => {\n messageState.set(key, value);\n });\n };\n\n\n // Message rendering with plugin support (implementation)\n const renderMessagesWithPluginsImpl = (\n container: HTMLElement,\n messages: AgentWidgetMessage[],\n transform: MessageTransform\n ) => {\n // Build new content in a temporary container for morphing\n const tempContainer = document.createElement(\"div\");\n\n messages.forEach((message) => {\n let bubble: HTMLElement | null = null;\n\n // Try plugins first\n const matchingPlugin = plugins.find((p) => {\n if (message.variant === \"reasoning\" && p.renderReasoning) {\n return true;\n }\n if (message.variant === \"tool\" && p.renderToolCall) {\n return true;\n }\n if (!message.variant && p.renderMessage) {\n return true;\n }\n return false;\n });\n\n // Get message layout config\n const messageLayoutConfig = config.layout?.messages;\n\n if (matchingPlugin) {\n if (message.variant === \"reasoning\" && message.reasoning && matchingPlugin.renderReasoning) {\n if (!showReasoning) return;\n bubble = matchingPlugin.renderReasoning({\n message,\n defaultRenderer: () => createReasoningBubble(message),\n config\n });\n } else if (message.variant === \"tool\" && message.toolCall && matchingPlugin.renderToolCall) {\n if (!showToolCalls) return;\n bubble = matchingPlugin.renderToolCall({\n message,\n defaultRenderer: () => createToolBubble(message, config),\n config\n });\n } else if (matchingPlugin.renderMessage) {\n bubble = matchingPlugin.renderMessage({\n message,\n defaultRenderer: () => {\n const b = createStandardBubble(\n message, \n transform, \n messageLayoutConfig, \n config.messageActions, \n messageActionCallbacks\n );\n if (message.role !== \"user\") {\n enhanceWithForms(b, message, config, session);\n }\n return b;\n },\n config\n });\n }\n }\n\n // Check for component directive if no plugin handled it\n if (!bubble && message.role === \"assistant\" && !message.variant) {\n const enableComponentStreaming = config.enableComponentStreaming !== false; // Default to true\n if (enableComponentStreaming && hasComponentDirective(message)) {\n const directive = extractComponentDirectiveFromMessage(message);\n if (directive) {\n const componentBubble = renderComponentDirective(directive, {\n config,\n message,\n transform\n });\n if (componentBubble) {\n // Wrap component in standard bubble styling\n const componentWrapper = document.createElement(\"div\");\n componentWrapper.className = [\n \"vanilla-message-bubble\",\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-p-4\"\n ].join(\" \");\n // Set id for idiomorph matching\n componentWrapper.id = `bubble-${message.id}`;\n componentWrapper.setAttribute(\"data-message-id\", message.id);\n\n // Add text content above component if present (combined text+component response)\n if (message.content && message.content.trim()) {\n const textDiv = document.createElement(\"div\");\n textDiv.className = \"tvw-mb-3 tvw-text-sm tvw-leading-relaxed\";\n textDiv.innerHTML = transform({\n text: message.content,\n message,\n streaming: Boolean(message.streaming),\n raw: message.rawContent\n });\n componentWrapper.appendChild(textDiv);\n }\n\n componentWrapper.appendChild(componentBubble);\n bubble = componentWrapper;\n }\n }\n }\n }\n\n // Fallback to default rendering if plugin returned null or no plugin matched\n if (!bubble) {\n if (message.variant === \"reasoning\" && message.reasoning) {\n if (!showReasoning) return;\n bubble = createReasoningBubble(message);\n } else if (message.variant === \"tool\" && message.toolCall) {\n if (!showToolCalls) return;\n bubble = createToolBubble(message, config);\n } else {\n // Check for custom message renderers in layout config\n const messageLayoutConfig = config.layout?.messages;\n if (messageLayoutConfig?.renderUserMessage && message.role === \"user\") {\n bubble = messageLayoutConfig.renderUserMessage({\n message,\n config,\n streaming: Boolean(message.streaming)\n });\n } else if (messageLayoutConfig?.renderAssistantMessage && message.role === \"assistant\") {\n bubble = messageLayoutConfig.renderAssistantMessage({\n message,\n config,\n streaming: Boolean(message.streaming)\n });\n } else {\n bubble = createStandardBubble(\n message, \n transform, \n messageLayoutConfig, \n config.messageActions, \n messageActionCallbacks\n );\n }\n if (message.role !== \"user\" && bubble) {\n enhanceWithForms(bubble, message, config, session);\n }\n }\n }\n\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"tvw-flex\";\n // Set id for idiomorph matching\n wrapper.id = `wrapper-${message.id}`;\n wrapper.setAttribute(\"data-wrapper-id\", message.id);\n if (message.role === \"user\") {\n wrapper.classList.add(\"tvw-justify-end\");\n }\n wrapper.appendChild(bubble);\n tempContainer.appendChild(wrapper);\n });\n\n // Add standalone typing indicator only if streaming but no assistant message is streaming yet\n // (This shows while waiting for the stream to start)\n // Check for ANY streaming assistant message, even if empty (to avoid duplicate bubbles)\n const hasStreamingAssistantMessage = messages.some(\n (msg) => msg.role === \"assistant\" && msg.streaming\n );\n \n // Also check if there's a recently completed assistant message (streaming just ended)\n // This prevents flicker when the message completes but isStreaming hasn't updated yet\n const lastMessage = messages[messages.length - 1];\n const hasRecentAssistantResponse = lastMessage?.role === \"assistant\" && !lastMessage.streaming;\n\n if (isStreaming && messages.some((msg) => msg.role === \"user\") && !hasStreamingAssistantMessage && !hasRecentAssistantResponse) {\n const typingIndicator = createTypingIndicator();\n\n // Create a bubble wrapper for the typing indicator (similar to assistant messages)\n const typingBubble = document.createElement(\"div\");\n typingBubble.className = [\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\",\n \"tvw-shadow-sm\",\n \"tvw-bg-cw-surface\",\n \"tvw-border\",\n \"tvw-border-cw-message-border\",\n \"tvw-text-cw-primary\",\n \"tvw-px-5\",\n \"tvw-py-3\"\n ].join(\" \");\n typingBubble.setAttribute(\"data-typing-indicator\", \"true\");\n\n typingBubble.appendChild(typingIndicator);\n\n const typingWrapper = document.createElement(\"div\");\n typingWrapper.className = \"tvw-flex\";\n // Set id for idiomorph matching\n typingWrapper.id = \"wrapper-typing-indicator\";\n typingWrapper.setAttribute(\"data-wrapper-id\", \"typing-indicator\");\n typingWrapper.appendChild(typingBubble);\n tempContainer.appendChild(typingWrapper);\n }\n\n // Use idiomorph to morph the container contents\n morphMessages(container, tempContainer);\n // Defer scroll to next frame for smoother animation and to prevent jolt\n // This allows the browser to update layout (e.g., typing indicator removal) before scrolling\n // Use double RAF to ensure layout has fully settled before starting scroll animation\n // Get the scrollable container using its unique ID (#vanilla-agent-scroll-container)\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const scrollableContainer = getScrollableContainer();\n smoothScrollToBottom(scrollableContainer);\n });\n });\n };\n\n // Alias for clarity - the implementation handles flicker prevention via typing indicator logic\n const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;\n\n const updateOpenState = () => {\n if (!launcherEnabled) return;\n if (open) {\n wrapper.classList.remove(\"tvw-pointer-events-none\", \"tvw-opacity-0\");\n panel.classList.remove(\"tvw-scale-95\", \"tvw-opacity-0\");\n panel.classList.add(\"tvw-scale-100\", \"tvw-opacity-100\");\n // Hide launcher button when widget is open\n if (launcherButtonInstance) {\n launcherButtonInstance.element.style.display = \"none\";\n } else if (customLauncherElement) {\n customLauncherElement.style.display = \"none\";\n }\n } else {\n wrapper.classList.add(\"tvw-pointer-events-none\", \"tvw-opacity-0\");\n panel.classList.remove(\"tvw-scale-100\", \"tvw-opacity-100\");\n panel.classList.add(\"tvw-scale-95\", \"tvw-opacity-0\");\n // Show launcher button when widget is closed\n if (launcherButtonInstance) {\n launcherButtonInstance.element.style.display = \"\";\n } else if (customLauncherElement) {\n customLauncherElement.style.display = \"\";\n }\n }\n };\n\n const setOpenState = (nextOpen: boolean, source: \"user\" | \"auto\" | \"api\" | \"system\" = \"user\") => {\n if (!launcherEnabled) return;\n if (open === nextOpen) return;\n \n const prevOpen = open;\n open = nextOpen;\n updateOpenState();\n \n if (open) {\n recalcPanelHeight();\n scheduleAutoScroll(true);\n }\n \n // Emit widget state events\n const stateEvent: AgentWidgetStateEvent = {\n open,\n source,\n timestamp: Date.now()\n };\n \n if (open && !prevOpen) {\n eventBus.emit(\"widget:opened\", stateEvent);\n } else if (!open && prevOpen) {\n eventBus.emit(\"widget:closed\", stateEvent);\n }\n \n // Emit general state snapshot\n eventBus.emit(\"widget:state\", {\n open,\n launcherEnabled,\n voiceActive: voiceState.active,\n streaming: session.isStreaming()\n });\n };\n\n const setComposerDisabled = (disabled: boolean) => {\n // Keep textarea always enabled so users can type while streaming\n // Only disable submit controls to prevent sending during streaming\n sendButton.disabled = disabled;\n if (micButton) {\n micButton.disabled = disabled;\n }\n suggestionsManager.buttons.forEach((btn) => {\n btn.disabled = disabled;\n });\n };\n\n const updateCopy = () => {\n introTitle.textContent = config.copy?.welcomeTitle ?? \"Hello 👋\";\n introSubtitle.textContent =\n config.copy?.welcomeSubtitle ??\n \"Ask anything about your account or products.\";\n textarea.placeholder = config.copy?.inputPlaceholder ?? \"How can I help...\";\n\n // Only update send button text if NOT using icon mode\n const useIcon = config.sendButton?.useIcon ?? false;\n if (!useIcon) {\n sendButton.textContent = config.copy?.sendButtonLabel ?? \"Send\";\n }\n\n // Update textarea font family and weight\n const fontFamily = config.theme?.inputFontFamily ?? \"sans-serif\";\n const fontWeight = config.theme?.inputFontWeight ?? \"400\";\n \n const getFontFamilyValue = (family: \"sans-serif\" | \"serif\" | \"mono\"): string => {\n switch (family) {\n case \"serif\":\n return 'Georgia, \"Times New Roman\", Times, serif';\n case \"mono\":\n return '\"Courier New\", Courier, \"Lucida Console\", Monaco, monospace';\n case \"sans-serif\":\n default:\n return '-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif';\n }\n };\n \n textarea.style.fontFamily = getFontFamilyValue(fontFamily);\n textarea.style.fontWeight = fontWeight;\n };\n\n session = new AgentWidgetSession(config, {\n onMessagesChanged(messages) {\n renderMessagesWithPlugins(messagesWrapper, messages, postprocess);\n // Re-render suggestions to hide them after first user message\n // Pass messages directly to avoid calling session.getMessages() during construction\n if (session) {\n const hasUserMessage = messages.some((msg) => msg.role === \"user\");\n if (hasUserMessage) {\n // Hide suggestions if user message exists\n suggestionsManager.render([], session, textarea, messages);\n } else {\n // Show suggestions if no user message yet\n suggestionsManager.render(config.suggestionChips, session, textarea, messages, config.suggestionChipsConfig);\n }\n }\n scheduleAutoScroll(!isStreaming);\n trackMessages(messages);\n\n const lastUserMessage = [...messages]\n .reverse()\n .find((msg) => msg.role === \"user\");\n voiceState.lastUserMessageWasVoice = Boolean(lastUserMessage?.viaVoice);\n persistState(messages);\n },\n onStatusChanged(status) {\n const currentStatusConfig = config.statusIndicator ?? {};\n const getCurrentStatusText = (status: AgentWidgetSessionStatus): string => {\n if (status === \"idle\") return currentStatusConfig.idleText ?? statusCopy.idle;\n if (status === \"connecting\") return currentStatusConfig.connectingText ?? statusCopy.connecting;\n if (status === \"connected\") return currentStatusConfig.connectedText ?? statusCopy.connected;\n if (status === \"error\") return currentStatusConfig.errorText ?? statusCopy.error;\n return statusCopy[status];\n };\n statusText.textContent = getCurrentStatusText(status);\n },\n onStreamingChanged(streaming) {\n isStreaming = streaming;\n setComposerDisabled(streaming);\n // Re-render messages to show/hide typing indicator\n if (session) {\n renderMessagesWithPlugins(messagesWrapper, session.getMessages(), postprocess);\n }\n if (!streaming) {\n scheduleAutoScroll(true);\n }\n }\n });\n\n if (pendingStoredState) {\n pendingStoredState\n .then((state) => {\n if (!state) return;\n if (state.metadata) {\n persistentMetadata = ensureRecord(state.metadata);\n actionManager.syncFromMetadata();\n }\n if (state.messages?.length) {\n session.hydrateMessages(state.messages);\n }\n })\n .catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to hydrate stored state:\", error);\n }\n });\n }\n\n const handleSubmit = (event: Event) => {\n event.preventDefault();\n const value = textarea.value.trim();\n if (!value) return;\n textarea.value = \"\";\n session.sendMessage(value);\n };\n\n const handleInputEnter = (event: KeyboardEvent) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n sendButton.click();\n }\n };\n\n // Voice recognition state and logic\n let speechRecognition: any = null;\n let isRecording = false;\n let pauseTimer: number | null = null;\n let originalMicStyles: {\n backgroundColor: string;\n color: string;\n borderColor: string;\n } | null = null;\n\n const getSpeechRecognitionClass = (): any => {\n if (typeof window === 'undefined') return null;\n return (window as any).webkitSpeechRecognition || (window as any).SpeechRecognition || null;\n };\n\n const startVoiceRecognition = (\n source: AgentWidgetVoiceStateEvent[\"source\"] = \"user\"\n ) => {\n if (isRecording || session.isStreaming()) return;\n\n const SpeechRecognitionClass = getSpeechRecognitionClass();\n if (!SpeechRecognitionClass) return;\n\n speechRecognition = new SpeechRecognitionClass();\n const voiceConfig = config.voiceRecognition ?? {};\n const pauseDuration = voiceConfig.pauseDuration ?? 2000;\n\n speechRecognition.continuous = true;\n speechRecognition.interimResults = true;\n speechRecognition.lang = 'en-US';\n\n // Store the initial text that was in the textarea\n const initialText = textarea.value;\n\n speechRecognition.onresult = (event: any) => {\n // Build the complete transcript from all results\n let fullTranscript = \"\";\n let interimTranscript = \"\";\n \n // Process all results from the beginning\n for (let i = 0; i < event.results.length; i++) {\n const result = event.results[i];\n const transcript = result[0].transcript;\n \n if (result.isFinal) {\n fullTranscript += transcript + \" \";\n } else {\n // Only take the last interim result\n interimTranscript = transcript;\n }\n }\n \n // Update textarea with initial text + full transcript + interim\n const newValue = initialText + fullTranscript + interimTranscript;\n textarea.value = newValue;\n\n // Reset pause timer on each result\n if (pauseTimer) {\n clearTimeout(pauseTimer);\n }\n\n // Set timer to auto-submit after pause when we have any speech\n if (fullTranscript || interimTranscript) {\n pauseTimer = window.setTimeout(() => {\n const finalValue = textarea.value.trim();\n if (finalValue && speechRecognition && isRecording) {\n stopVoiceRecognition();\n textarea.value = \"\";\n session.sendMessage(finalValue, { viaVoice: true });\n }\n }, pauseDuration);\n }\n };\n\n speechRecognition.onerror = (event: any) => {\n // Don't stop on \"no-speech\" error, just ignore it\n if (event.error !== 'no-speech') {\n stopVoiceRecognition();\n }\n };\n\n speechRecognition.onend = () => {\n // If recognition ended naturally (not manually stopped), submit if there's text\n if (isRecording) {\n const finalValue = textarea.value.trim();\n if (finalValue && finalValue !== initialText.trim()) {\n textarea.value = \"\";\n session.sendMessage(finalValue, { viaVoice: true });\n }\n stopVoiceRecognition();\n }\n };\n\n try {\n speechRecognition.start();\n isRecording = true;\n voiceState.active = true;\n if (source !== \"system\") {\n voiceState.manuallyDeactivated = false;\n }\n emitVoiceState(source);\n persistVoiceMetadata();\n if (micButton) {\n // Store original styles\n originalMicStyles = {\n backgroundColor: micButton.style.backgroundColor,\n color: micButton.style.color,\n borderColor: micButton.style.borderColor\n };\n \n // Apply recording state styles from config\n const voiceConfig = config.voiceRecognition ?? {};\n const recordingBackgroundColor = voiceConfig.recordingBackgroundColor ?? \"#ef4444\";\n const recordingIconColor = voiceConfig.recordingIconColor;\n const recordingBorderColor = voiceConfig.recordingBorderColor;\n \n micButton.classList.add(\"tvw-voice-recording\");\n micButton.style.backgroundColor = recordingBackgroundColor;\n \n if (recordingIconColor) {\n micButton.style.color = recordingIconColor;\n // Update SVG stroke color if present\n const svg = micButton.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"stroke\", recordingIconColor);\n }\n }\n \n if (recordingBorderColor) {\n micButton.style.borderColor = recordingBorderColor;\n }\n \n micButton.setAttribute(\"aria-label\", \"Stop voice recognition\");\n }\n } catch (error) {\n stopVoiceRecognition(\"system\");\n }\n };\n\n const stopVoiceRecognition = (\n source: AgentWidgetVoiceStateEvent[\"source\"] = \"user\"\n ) => {\n if (!isRecording) return;\n\n isRecording = false;\n if (pauseTimer) {\n clearTimeout(pauseTimer);\n pauseTimer = null;\n }\n\n if (speechRecognition) {\n try {\n speechRecognition.stop();\n } catch (error) {\n // Ignore errors when stopping\n }\n speechRecognition = null;\n }\n\n voiceState.active = false;\n emitVoiceState(source);\n persistVoiceMetadata();\n\n if (micButton) {\n micButton.classList.remove(\"tvw-voice-recording\");\n \n // Restore original styles\n if (originalMicStyles) {\n micButton.style.backgroundColor = originalMicStyles.backgroundColor;\n micButton.style.color = originalMicStyles.color;\n micButton.style.borderColor = originalMicStyles.borderColor;\n \n // Restore SVG stroke color if present\n const svg = micButton.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"stroke\", originalMicStyles.color || \"currentColor\");\n }\n \n originalMicStyles = null;\n }\n \n micButton.setAttribute(\"aria-label\", \"Start voice recognition\");\n }\n };\n\n // Function to create mic button dynamically\n const createMicButton = (voiceConfig: AgentWidgetConfig['voiceRecognition'], sendButtonConfig: AgentWidgetConfig['sendButton']): { micButton: HTMLButtonElement; micButtonWrapper: HTMLElement } | null => {\n const hasSpeechRecognition = \n typeof window !== 'undefined' && \n (typeof (window as any).webkitSpeechRecognition !== 'undefined' || \n typeof (window as any).SpeechRecognition !== 'undefined');\n \n if (!hasSpeechRecognition) return null;\n\n const micButtonWrapper = createElement(\"div\", \"tvw-send-button-wrapper\");\n const micButton = createElement(\n \"button\",\n \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\"\n ) as HTMLButtonElement;\n \n micButton.type = \"button\";\n micButton.setAttribute(\"aria-label\", \"Start voice recognition\");\n \n const micIconName = voiceConfig?.iconName ?? \"mic\";\n const buttonSize = sendButtonConfig?.size ?? \"40px\";\n const micIconSize = voiceConfig?.iconSize ?? buttonSize;\n const micIconSizeNum = parseFloat(micIconSize) || 24;\n \n // Use dedicated colors from voice recognition config, fallback to send button colors\n const backgroundColor = voiceConfig?.backgroundColor ?? sendButtonConfig?.backgroundColor;\n const iconColor = voiceConfig?.iconColor ?? sendButtonConfig?.textColor;\n \n micButton.style.width = micIconSize;\n micButton.style.height = micIconSize;\n micButton.style.minWidth = micIconSize;\n micButton.style.minHeight = micIconSize;\n micButton.style.fontSize = \"18px\";\n micButton.style.lineHeight = \"1\";\n \n // Use Lucide mic icon with configured color (stroke width 1.5 for minimalist outline style)\n const iconColorValue = iconColor || \"currentColor\";\n const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColorValue, 1.5);\n if (micIconSvg) {\n micButton.appendChild(micIconSvg);\n micButton.style.color = iconColorValue;\n } else {\n // Fallback to text if icon fails\n micButton.textContent = \"🎤\";\n micButton.style.color = iconColorValue;\n }\n \n // Apply background color\n if (backgroundColor) {\n micButton.style.backgroundColor = backgroundColor;\n } else {\n micButton.classList.add(\"tvw-bg-cw-primary\");\n }\n \n // Apply icon/text color\n if (iconColor) {\n micButton.style.color = iconColor;\n } else if (!iconColor && !sendButtonConfig?.textColor) {\n micButton.classList.add(\"tvw-text-white\");\n }\n \n // Apply border styling\n if (voiceConfig?.borderWidth) {\n micButton.style.borderWidth = voiceConfig.borderWidth;\n micButton.style.borderStyle = \"solid\";\n }\n if (voiceConfig?.borderColor) {\n micButton.style.borderColor = voiceConfig.borderColor;\n }\n \n // Apply padding styling\n if (voiceConfig?.paddingX) {\n micButton.style.paddingLeft = voiceConfig.paddingX;\n micButton.style.paddingRight = voiceConfig.paddingX;\n }\n if (voiceConfig?.paddingY) {\n micButton.style.paddingTop = voiceConfig.paddingY;\n micButton.style.paddingBottom = voiceConfig.paddingY;\n }\n \n micButtonWrapper.appendChild(micButton);\n \n // Add tooltip if enabled\n const tooltipText = voiceConfig?.tooltipText ?? \"Start voice recognition\";\n const showTooltip = voiceConfig?.showTooltip ?? false;\n if (showTooltip && tooltipText) {\n const tooltip = createElement(\"div\", \"tvw-send-button-tooltip\");\n tooltip.textContent = tooltipText;\n micButtonWrapper.appendChild(tooltip);\n }\n \n return { micButton, micButtonWrapper };\n };\n\n // Wire up mic button click handler\n const handleMicButtonClick = () => {\n if (isRecording) {\n // Stop recording and submit\n const finalValue = textarea.value.trim();\n voiceState.manuallyDeactivated = true;\n persistVoiceMetadata();\n stopVoiceRecognition(\"user\");\n if (finalValue) {\n textarea.value = \"\";\n session.sendMessage(finalValue);\n }\n } else {\n // Start recording\n voiceState.manuallyDeactivated = false;\n persistVoiceMetadata();\n startVoiceRecognition(\"user\");\n }\n };\n\n if (micButton) {\n micButton.addEventListener(\"click\", handleMicButtonClick);\n\n destroyCallbacks.push(() => {\n stopVoiceRecognition(\"system\");\n if (micButton) {\n micButton.removeEventListener(\"click\", handleMicButtonClick);\n }\n });\n }\n\n const autoResumeUnsub = eventBus.on(\"assistant:complete\", () => {\n if (!voiceAutoResumeMode) return;\n if (voiceState.active || voiceState.manuallyDeactivated) return;\n if (voiceAutoResumeMode === \"assistant\" && !voiceState.lastUserMessageWasVoice) {\n return;\n }\n setTimeout(() => {\n if (!voiceState.active && !voiceState.manuallyDeactivated) {\n startVoiceRecognition(\"auto\");\n }\n }, 600);\n });\n destroyCallbacks.push(autoResumeUnsub);\n\n const toggleOpen = () => {\n setOpenState(!open, \"user\");\n };\n\n // Plugin hook: renderLauncher - allow plugins to provide custom launcher\n let launcherButtonInstance: ReturnType<typeof createLauncherButton> | null = null;\n let customLauncherElement: HTMLElement | null = null;\n \n if (launcherEnabled) {\n const launcherPlugin = plugins.find(p => p.renderLauncher);\n if (launcherPlugin?.renderLauncher) {\n const customLauncher = launcherPlugin.renderLauncher({\n config,\n defaultRenderer: () => {\n const btn = createLauncherButton(config, toggleOpen);\n return btn.element;\n },\n onToggle: toggleOpen\n });\n if (customLauncher) {\n customLauncherElement = customLauncher;\n }\n }\n \n // Use custom launcher if provided, otherwise use default\n if (!customLauncherElement) {\n launcherButtonInstance = createLauncherButton(config, toggleOpen);\n }\n }\n\n if (launcherButtonInstance) {\n mount.appendChild(launcherButtonInstance.element);\n } else if (customLauncherElement) {\n mount.appendChild(customLauncherElement);\n }\n updateOpenState();\n suggestionsManager.render(config.suggestionChips, session, textarea, undefined, config.suggestionChipsConfig);\n updateCopy();\n setComposerDisabled(session.isStreaming());\n scheduleAutoScroll(true);\n maybeRestoreVoiceFromMetadata();\n\n const recalcPanelHeight = () => {\n const sidebarMode = config.launcher?.sidebarMode ?? false;\n const fullHeight = sidebarMode || (config.launcher?.fullHeight ?? false);\n \n if (!launcherEnabled) {\n panel.style.height = \"\";\n panel.style.width = \"\";\n return;\n }\n \n // In sidebar/fullHeight mode, don't override the width - it's handled by applyFullHeightStyles\n if (!sidebarMode) {\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(400px, calc(100vw - 24px))\";\n panel.style.width = width;\n panel.style.maxWidth = width;\n }\n \n // In fullHeight mode, don't set a fixed height\n if (!fullHeight) {\n const viewportHeight = window.innerHeight;\n const verticalMargin = 64; // leave space for launcher's offset\n const heightOffset = config.launcher?.heightOffset ?? 0;\n const available = Math.max(200, viewportHeight - verticalMargin);\n const clamped = Math.min(640, available);\n const finalHeight = Math.max(200, clamped - heightOffset);\n panel.style.height = `${finalHeight}px`;\n }\n };\n\n recalcPanelHeight();\n window.addEventListener(\"resize\", recalcPanelHeight);\n destroyCallbacks.push(() => window.removeEventListener(\"resize\", recalcPanelHeight));\n\n lastScrollTop = body.scrollTop;\n\n const handleScroll = () => {\n const scrollTop = body.scrollTop;\n const scrollHeight = body.scrollHeight;\n const clientHeight = body.clientHeight;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n const delta = Math.abs(scrollTop - lastScrollTop);\n lastScrollTop = scrollTop;\n\n if (isAutoScrolling) return;\n if (delta <= USER_SCROLL_THRESHOLD) return;\n\n if (!shouldAutoScroll && distanceFromBottom < BOTTOM_THRESHOLD) {\n isAutoScrollBlocked = false;\n shouldAutoScroll = true;\n return;\n }\n\n if (shouldAutoScroll && distanceFromBottom > BOTTOM_THRESHOLD) {\n isAutoScrollBlocked = true;\n blockUntilTime = Date.now() + AUTO_SCROLL_BLOCK_TIME;\n shouldAutoScroll = false;\n }\n };\n\n body.addEventListener(\"scroll\", handleScroll, { passive: true });\n destroyCallbacks.push(() => body.removeEventListener(\"scroll\", handleScroll));\n destroyCallbacks.push(() => {\n if (scrollRAF) cancelAnimationFrame(scrollRAF);\n });\n\n const refreshCloseButton = () => {\n if (!closeButton) return;\n if (closeHandler) {\n closeButton.removeEventListener(\"click\", closeHandler);\n closeHandler = null;\n }\n if (launcherEnabled) {\n closeButton.style.display = \"\";\n closeHandler = () => {\n open = false;\n updateOpenState();\n };\n closeButton.addEventListener(\"click\", closeHandler);\n } else {\n closeButton.style.display = \"none\";\n }\n };\n\n refreshCloseButton();\n\n // Setup clear chat button click handler\n const setupClearChatButton = () => {\n const { clearChatButton } = panelElements;\n if (!clearChatButton) return;\n\n clearChatButton.addEventListener(\"click\", () => {\n // Clear messages in session (this will trigger onMessagesChanged which re-renders)\n session.clearMessages();\n\n // Always clear the default localStorage key\n try {\n localStorage.removeItem(DEFAULT_CHAT_HISTORY_STORAGE_KEY);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared default localStorage key: ${DEFAULT_CHAT_HISTORY_STORAGE_KEY}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear default localStorage:\", error);\n }\n\n // Also clear custom localStorage key if configured\n if (config.clearChatHistoryStorageKey && config.clearChatHistoryStorageKey !== DEFAULT_CHAT_HISTORY_STORAGE_KEY) {\n try {\n localStorage.removeItem(config.clearChatHistoryStorageKey);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared custom localStorage key: ${config.clearChatHistoryStorageKey}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear custom localStorage:\", error);\n }\n }\n\n // Dispatch custom event for external handlers (e.g., localStorage clearing in examples)\n const clearEvent = new CustomEvent(\"vanilla-agent:clear-chat\", {\n detail: { timestamp: new Date().toISOString() }\n });\n window.dispatchEvent(clearEvent);\n\n if (storageAdapter?.clear) {\n try {\n const result = storageAdapter.clear();\n if (result instanceof Promise) {\n result.catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n });\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n }\n }\n persistentMetadata = {};\n actionManager.syncFromMetadata();\n });\n };\n\n setupClearChatButton();\n\n composerForm.addEventListener(\"submit\", handleSubmit);\n textarea.addEventListener(\"keydown\", handleInputEnter);\n\n destroyCallbacks.push(() => {\n composerForm.removeEventListener(\"submit\", handleSubmit);\n textarea.removeEventListener(\"keydown\", handleInputEnter);\n });\n\n destroyCallbacks.push(() => {\n session.cancel();\n });\n\n if (launcherButtonInstance) {\n destroyCallbacks.push(() => {\n launcherButtonInstance?.destroy();\n });\n } else if (customLauncherElement) {\n destroyCallbacks.push(() => {\n customLauncherElement?.remove();\n });\n }\n\n const controller: Controller = {\n update(nextConfig: AgentWidgetConfig) {\n const previousToolCallConfig = config.toolCall;\n const previousColorScheme = config.colorScheme;\n config = { ...config, ...nextConfig };\n // applyFullHeightStyles resets mount.style.cssText, so call it before applyThemeVariables\n applyFullHeightStyles();\n applyThemeVariables(mount, config);\n\n // Re-setup theme observer if colorScheme changed\n if (config.colorScheme !== previousColorScheme) {\n setupThemeObserver();\n }\n\n // Update plugins\n const newPlugins = pluginRegistry.getForInstance(config.plugins);\n plugins.length = 0;\n plugins.push(...newPlugins);\n\n launcherEnabled = config.launcher?.enabled ?? true;\n autoExpand = config.launcher?.autoExpand ?? false;\n showReasoning = config.features?.showReasoning ?? true;\n showToolCalls = config.features?.showToolCalls ?? true;\n\n if (config.launcher?.enabled === false && launcherButtonInstance) {\n launcherButtonInstance.destroy();\n launcherButtonInstance = null;\n }\n if (config.launcher?.enabled === false && customLauncherElement) {\n customLauncherElement.remove();\n customLauncherElement = null;\n }\n\n if (config.launcher?.enabled !== false && !launcherButtonInstance && !customLauncherElement) {\n // Check for launcher plugin when re-enabling\n const launcherPlugin = plugins.find(p => p.renderLauncher);\n if (launcherPlugin?.renderLauncher) {\n const customLauncher = launcherPlugin.renderLauncher({\n config,\n defaultRenderer: () => {\n const btn = createLauncherButton(config, toggleOpen);\n return btn.element;\n },\n onToggle: toggleOpen\n });\n if (customLauncher) {\n customLauncherElement = customLauncher;\n mount.appendChild(customLauncherElement);\n }\n }\n if (!customLauncherElement) {\n launcherButtonInstance = createLauncherButton(config, toggleOpen);\n mount.appendChild(launcherButtonInstance.element);\n }\n }\n\n if (launcherButtonInstance) {\n launcherButtonInstance.update(config);\n }\n // Note: Custom launcher updates are handled by the plugin's own logic\n\n // Update panel header title and subtitle\n if (headerTitle && config.launcher?.title !== undefined) {\n headerTitle.textContent = config.launcher.title;\n }\n if (headerSubtitle && config.launcher?.subtitle !== undefined) {\n headerSubtitle.textContent = config.launcher.subtitle;\n }\n\n // Update header layout if it changed\n const headerLayoutConfig = config.layout?.header;\n const headerLayoutChanged = headerLayoutConfig?.layout !== prevHeaderLayout;\n\n if (headerLayoutChanged && header) {\n // Rebuild header with new layout\n const newHeaderElements = headerLayoutConfig\n ? buildHeaderWithLayout(config, headerLayoutConfig, {\n showClose: launcherEnabled,\n onClose: () => setOpenState(false, \"user\")\n })\n : buildHeader({\n config,\n showClose: launcherEnabled,\n onClose: () => setOpenState(false, \"user\")\n });\n\n // Replace the old header with the new one\n header.replaceWith(newHeaderElements.header);\n\n // Update references\n header = newHeaderElements.header;\n iconHolder = newHeaderElements.iconHolder;\n headerTitle = newHeaderElements.headerTitle;\n headerSubtitle = newHeaderElements.headerSubtitle;\n closeButton = newHeaderElements.closeButton;\n\n prevHeaderLayout = headerLayoutConfig?.layout;\n } else if (headerLayoutConfig) {\n // Apply visibility settings without rebuilding\n if (iconHolder) {\n iconHolder.style.display = headerLayoutConfig.showIcon === false ? \"none\" : \"\";\n }\n if (headerTitle) {\n headerTitle.style.display = headerLayoutConfig.showTitle === false ? \"none\" : \"\";\n }\n if (headerSubtitle) {\n headerSubtitle.style.display = headerLayoutConfig.showSubtitle === false ? \"none\" : \"\";\n }\n if (closeButton) {\n closeButton.style.display = headerLayoutConfig.showCloseButton === false ? \"none\" : \"\";\n }\n if (panelElements.clearChatButtonWrapper) {\n // showClearChat explicitly controls visibility when set\n const showClearChat = headerLayoutConfig.showClearChat;\n if (showClearChat !== undefined) {\n panelElements.clearChatButtonWrapper.style.display = showClearChat ? \"\" : \"none\";\n // When clear chat is hidden, close button needs ml-auto to stay right-aligned\n const { closeButtonWrapper } = panelElements;\n if (closeButtonWrapper && !closeButtonWrapper.classList.contains(\"tvw-absolute\")) {\n if (showClearChat) {\n closeButtonWrapper.classList.remove(\"tvw-ml-auto\");\n } else {\n closeButtonWrapper.classList.add(\"tvw-ml-auto\");\n }\n }\n }\n }\n }\n\n // Only update open state if launcher enabled state changed or autoExpand value changed\n const launcherEnabledChanged = launcherEnabled !== prevLauncherEnabled;\n const autoExpandChanged = autoExpand !== prevAutoExpand;\n\n if (launcherEnabledChanged) {\n // Launcher was enabled/disabled - update state accordingly\n if (!launcherEnabled) {\n // When launcher is disabled, always keep panel open\n open = true;\n updateOpenState();\n } else {\n // Launcher was just enabled - respect autoExpand setting\n setOpenState(autoExpand, \"auto\");\n }\n } else if (autoExpandChanged) {\n // autoExpand value changed - update state to match\n setOpenState(autoExpand, \"auto\");\n }\n // Otherwise, preserve current open state (user may have manually opened/closed)\n\n // Update previous values for next comparison\n prevAutoExpand = autoExpand;\n prevLauncherEnabled = launcherEnabled;\n recalcPanelHeight();\n refreshCloseButton();\n\n // Re-render messages if toolCall config changed (to apply new styles)\n const toolCallConfigChanged = JSON.stringify(nextConfig.toolCall) !== JSON.stringify(previousToolCallConfig);\n if (toolCallConfigChanged && session) {\n renderMessagesWithPlugins(messagesWrapper, session.getMessages(), postprocess);\n }\n\n // Update panel icon sizes\n const launcher = config.launcher ?? {};\n const headerIconHidden = launcher.headerIconHidden ?? false;\n const layoutShowIcon = config.layout?.header?.showIcon;\n // Hide icon if either headerIconHidden is true OR layout.header.showIcon is false\n const shouldHideIcon = headerIconHidden || layoutShowIcon === false;\n const headerIconName = launcher.headerIconName;\n const headerIconSize = launcher.headerIconSize ?? \"48px\";\n\n if (iconHolder) {\n const headerEl = container.querySelector(\".tvw-border-b-cw-divider\");\n const headerCopy = headerEl?.querySelector(\".tvw-flex-col\");\n\n // Handle hide/show\n if (shouldHideIcon) {\n // Hide iconHolder\n iconHolder.style.display = \"none\";\n // Ensure headerCopy is still in header\n if (headerEl && headerCopy && !headerEl.contains(headerCopy)) {\n headerEl.insertBefore(headerCopy, headerEl.firstChild);\n }\n } else {\n // Show iconHolder\n iconHolder.style.display = \"\";\n iconHolder.style.height = headerIconSize;\n iconHolder.style.width = headerIconSize;\n \n // Ensure iconHolder is before headerCopy in header\n if (headerEl && headerCopy) {\n if (!headerEl.contains(iconHolder)) {\n headerEl.insertBefore(iconHolder, headerCopy);\n } else if (iconHolder.nextSibling !== headerCopy) {\n // Reorder if needed\n iconHolder.remove();\n headerEl.insertBefore(iconHolder, headerCopy);\n }\n }\n \n // Update icon content based on priority: Lucide icon > iconUrl > agentIconText\n if (headerIconName) {\n // Use Lucide icon\n const iconSize = parseFloat(headerIconSize) || 24;\n const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.6, \"#ffffff\", 2);\n if (iconSvg) {\n iconHolder.replaceChildren(iconSvg);\n } else {\n // Fallback to agentIconText if Lucide icon fails\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n } else if (launcher.iconUrl) {\n // Use image URL\n const img = iconHolder.querySelector(\"img\");\n if (img) {\n img.src = launcher.iconUrl;\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n } else {\n // Create new img if it doesn't exist\n const newImg = document.createElement(\"img\");\n newImg.src = launcher.iconUrl;\n newImg.alt = \"\";\n newImg.className = \"tvw-rounded-xl tvw-object-cover\";\n newImg.style.height = headerIconSize;\n newImg.style.width = headerIconSize;\n iconHolder.replaceChildren(newImg);\n }\n } else {\n // Use text/emoji - clear any SVG or img first\n const existingSvg = iconHolder.querySelector(\"svg\");\n const existingImg = iconHolder.querySelector(\"img\");\n if (existingSvg || existingImg) {\n iconHolder.replaceChildren();\n }\n iconHolder.textContent = launcher.agentIconText ?? \"💬\";\n }\n \n // Update image size if present\n const img = iconHolder.querySelector(\"img\");\n if (img) {\n img.style.height = headerIconSize;\n img.style.width = headerIconSize;\n }\n }\n }\n\n // Handle title/subtitle visibility from layout config\n const layoutShowTitle = config.layout?.header?.showTitle;\n const layoutShowSubtitle = config.layout?.header?.showSubtitle;\n if (headerTitle) {\n headerTitle.style.display = layoutShowTitle === false ? \"none\" : \"\";\n }\n if (headerSubtitle) {\n headerSubtitle.style.display = layoutShowSubtitle === false ? \"none\" : \"\";\n }\n\n if (closeButton) {\n // Handle close button visibility from layout config\n const layoutShowCloseButton = config.layout?.header?.showCloseButton;\n if (layoutShowCloseButton === false) {\n closeButton.style.display = \"none\";\n } else {\n closeButton.style.display = \"\";\n }\n\n const closeButtonSize = launcher.closeButtonSize ?? \"32px\";\n const closeButtonPlacement = launcher.closeButtonPlacement ?? \"inline\";\n closeButton.style.height = closeButtonSize;\n closeButton.style.width = closeButtonSize;\n \n // Update placement if changed - move the wrapper (not just the button) to preserve tooltip\n const { closeButtonWrapper } = panelElements;\n const isTopRight = closeButtonPlacement === \"top-right\";\n const currentlyTopRight = closeButtonWrapper?.classList.contains(\"tvw-absolute\");\n \n if (closeButtonWrapper && isTopRight !== currentlyTopRight) {\n // Placement changed - need to move wrapper and update classes\n closeButtonWrapper.remove();\n \n // Update wrapper classes\n if (isTopRight) {\n closeButtonWrapper.className = \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50\";\n container.style.position = \"relative\";\n container.appendChild(closeButtonWrapper);\n } else {\n // Check if clear chat is inline to determine if we need ml-auto\n const clearChatPlacement = launcher.clearChat?.placement ?? \"inline\";\n const clearChatEnabled = launcher.clearChat?.enabled ?? true;\n closeButtonWrapper.className = (clearChatEnabled && clearChatPlacement === \"inline\") ? \"\" : \"tvw-ml-auto\";\n // Find header element\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n if (header) {\n header.appendChild(closeButtonWrapper);\n }\n }\n }\n \n // Apply close button styling from config\n if (launcher.closeButtonColor) {\n closeButton.style.color = launcher.closeButtonColor;\n closeButton.classList.remove(\"tvw-text-cw-muted\");\n } else {\n closeButton.style.color = \"\";\n closeButton.classList.add(\"tvw-text-cw-muted\");\n }\n \n if (launcher.closeButtonBackgroundColor) {\n closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;\n closeButton.classList.remove(\"hover:tvw-bg-gray-100\");\n } else {\n closeButton.style.backgroundColor = \"\";\n closeButton.classList.add(\"hover:tvw-bg-gray-100\");\n }\n \n // Apply border if width and/or color are provided\n if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {\n const borderWidth = launcher.closeButtonBorderWidth || \"0px\";\n const borderColor = launcher.closeButtonBorderColor || \"transparent\";\n closeButton.style.border = `${borderWidth} solid ${borderColor}`;\n closeButton.classList.remove(\"tvw-border-none\");\n } else {\n closeButton.style.border = \"\";\n closeButton.classList.add(\"tvw-border-none\");\n }\n \n if (launcher.closeButtonBorderRadius) {\n closeButton.style.borderRadius = launcher.closeButtonBorderRadius;\n closeButton.classList.remove(\"tvw-rounded-full\");\n } else {\n closeButton.style.borderRadius = \"\";\n closeButton.classList.add(\"tvw-rounded-full\");\n }\n\n // Update padding\n if (launcher.closeButtonPaddingX) {\n closeButton.style.paddingLeft = launcher.closeButtonPaddingX;\n closeButton.style.paddingRight = launcher.closeButtonPaddingX;\n } else {\n closeButton.style.paddingLeft = \"\";\n closeButton.style.paddingRight = \"\";\n }\n if (launcher.closeButtonPaddingY) {\n closeButton.style.paddingTop = launcher.closeButtonPaddingY;\n closeButton.style.paddingBottom = launcher.closeButtonPaddingY;\n } else {\n closeButton.style.paddingTop = \"\";\n closeButton.style.paddingBottom = \"\";\n }\n\n // Update icon\n const closeButtonIconName = launcher.closeButtonIconName ?? \"x\";\n const closeButtonIconText = launcher.closeButtonIconText ?? \"×\";\n\n // Clear existing content and render new icon\n closeButton.innerHTML = \"\";\n const iconSvg = renderLucideIcon(closeButtonIconName, \"20px\", launcher.closeButtonColor || \"\", 2);\n if (iconSvg) {\n closeButton.appendChild(iconSvg);\n } else {\n closeButton.textContent = closeButtonIconText;\n }\n\n // Update tooltip\n const closeButtonTooltipText = launcher.closeButtonTooltipText ?? \"Close chat\";\n const closeButtonShowTooltip = launcher.closeButtonShowTooltip ?? true;\n\n closeButton.setAttribute(\"aria-label\", closeButtonTooltipText);\n\n if (closeButtonWrapper) {\n // Clean up old tooltip event listeners if they exist\n if ((closeButtonWrapper as any)._cleanupTooltip) {\n (closeButtonWrapper as any)._cleanupTooltip();\n delete (closeButtonWrapper as any)._cleanupTooltip;\n }\n\n // Set up new portaled tooltip with event listeners\n if (closeButtonShowTooltip && closeButtonTooltipText) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip || !closeButton) return; // Already showing or button doesn't exist\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = closeButtonTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = closeButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n closeButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n closeButton.addEventListener(\"focus\", showTooltip);\n closeButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the wrapper for later use\n (closeButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n if (closeButtonWrapper) {\n closeButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n closeButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n }\n if (closeButton) {\n closeButton.removeEventListener(\"focus\", showTooltip);\n closeButton.removeEventListener(\"blur\", hideTooltip);\n }\n };\n }\n }\n }\n\n // Update clear chat button styling from config\n const { clearChatButton, clearChatButtonWrapper } = panelElements;\n if (clearChatButton) {\n const clearChatConfig = launcher.clearChat ?? {};\n const clearChatEnabled = clearChatConfig.enabled ?? true;\n const layoutShowClearChat = config.layout?.header?.showClearChat;\n // layout.header.showClearChat takes precedence if explicitly set\n // Otherwise fall back to launcher.clearChat.enabled\n const shouldShowClearChat = layoutShowClearChat !== undefined\n ? layoutShowClearChat\n : clearChatEnabled;\n const clearChatPlacement = clearChatConfig.placement ?? \"inline\";\n\n // Show/hide button based on layout config (primary) or launcher config (fallback)\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.style.display = shouldShowClearChat ? \"\" : \"none\";\n\n // When clear chat is hidden, close button needs ml-auto to stay right-aligned\n const { closeButtonWrapper } = panelElements;\n if (closeButtonWrapper && !closeButtonWrapper.classList.contains(\"tvw-absolute\")) {\n if (shouldShowClearChat) {\n closeButtonWrapper.classList.remove(\"tvw-ml-auto\");\n } else {\n closeButtonWrapper.classList.add(\"tvw-ml-auto\");\n }\n }\n\n // Update placement if changed\n const isTopRight = clearChatPlacement === \"top-right\";\n const currentlyTopRight = clearChatButtonWrapper.classList.contains(\"tvw-absolute\");\n\n if (isTopRight !== currentlyTopRight && shouldShowClearChat) {\n clearChatButtonWrapper.remove();\n\n if (isTopRight) {\n // Don't use tvw-clear-chat-button-wrapper class for top-right mode as its\n // display: inline-flex causes alignment issues with the close button\n clearChatButtonWrapper.className = \"tvw-absolute tvw-top-4 tvw-z-50\";\n // Position to the left of the close button (which is at right: 1rem/16px)\n // Close button is ~32px wide, plus small gap = 48px from right\n clearChatButtonWrapper.style.right = \"48px\";\n container.style.position = \"relative\";\n container.appendChild(clearChatButtonWrapper);\n } else {\n clearChatButtonWrapper.className = \"tvw-relative tvw-ml-auto tvw-clear-chat-button-wrapper\";\n // Clear the inline right style when switching back to inline mode\n clearChatButtonWrapper.style.right = \"\";\n // Find header and insert before close button\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n const closeButtonWrapperEl = panelElements.closeButtonWrapper;\n if (header && closeButtonWrapperEl && closeButtonWrapperEl.parentElement === header) {\n header.insertBefore(clearChatButtonWrapper, closeButtonWrapperEl);\n } else if (header) {\n header.appendChild(clearChatButtonWrapper);\n }\n }\n\n // Also update close button's ml-auto class based on clear chat position\n const closeButtonWrapperEl = panelElements.closeButtonWrapper;\n if (closeButtonWrapperEl && !closeButtonWrapperEl.classList.contains(\"tvw-absolute\")) {\n if (isTopRight) {\n // Clear chat moved to top-right, close needs ml-auto\n closeButtonWrapperEl.classList.add(\"tvw-ml-auto\");\n } else {\n // Clear chat is inline, close doesn't need ml-auto\n closeButtonWrapperEl.classList.remove(\"tvw-ml-auto\");\n }\n }\n }\n }\n\n if (shouldShowClearChat) {\n // Update size\n const clearChatSize = clearChatConfig.size ?? \"32px\";\n clearChatButton.style.height = clearChatSize;\n clearChatButton.style.width = clearChatSize;\n\n // Update icon\n const clearChatIconName = clearChatConfig.iconName ?? \"refresh-cw\";\n const clearChatIconColor = clearChatConfig.iconColor ?? \"\";\n\n // Clear existing icon and render new one\n clearChatButton.innerHTML = \"\";\n const iconSvg = renderLucideIcon(clearChatIconName, \"20px\", clearChatIconColor || \"\", 2);\n if (iconSvg) {\n clearChatButton.appendChild(iconSvg);\n }\n\n // Update icon color\n if (clearChatIconColor) {\n clearChatButton.style.color = clearChatIconColor;\n clearChatButton.classList.remove(\"tvw-text-cw-muted\");\n } else {\n clearChatButton.style.color = \"\";\n clearChatButton.classList.add(\"tvw-text-cw-muted\");\n }\n\n // Update background color\n if (clearChatConfig.backgroundColor) {\n clearChatButton.style.backgroundColor = clearChatConfig.backgroundColor;\n clearChatButton.classList.remove(\"hover:tvw-bg-gray-100\");\n } else {\n clearChatButton.style.backgroundColor = \"\";\n clearChatButton.classList.add(\"hover:tvw-bg-gray-100\");\n }\n\n // Update border\n if (clearChatConfig.borderWidth || clearChatConfig.borderColor) {\n const borderWidth = clearChatConfig.borderWidth || \"0px\";\n const borderColor = clearChatConfig.borderColor || \"transparent\";\n clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;\n clearChatButton.classList.remove(\"tvw-border-none\");\n } else {\n clearChatButton.style.border = \"\";\n clearChatButton.classList.add(\"tvw-border-none\");\n }\n\n // Update border radius\n if (clearChatConfig.borderRadius) {\n clearChatButton.style.borderRadius = clearChatConfig.borderRadius;\n clearChatButton.classList.remove(\"tvw-rounded-full\");\n } else {\n clearChatButton.style.borderRadius = \"\";\n clearChatButton.classList.add(\"tvw-rounded-full\");\n }\n\n // Update padding\n if (clearChatConfig.paddingX) {\n clearChatButton.style.paddingLeft = clearChatConfig.paddingX;\n clearChatButton.style.paddingRight = clearChatConfig.paddingX;\n } else {\n clearChatButton.style.paddingLeft = \"\";\n clearChatButton.style.paddingRight = \"\";\n }\n if (clearChatConfig.paddingY) {\n clearChatButton.style.paddingTop = clearChatConfig.paddingY;\n clearChatButton.style.paddingBottom = clearChatConfig.paddingY;\n } else {\n clearChatButton.style.paddingTop = \"\";\n clearChatButton.style.paddingBottom = \"\";\n }\n\n const clearChatTooltipText = clearChatConfig.tooltipText ?? \"Clear chat\";\n const clearChatShowTooltip = clearChatConfig.showTooltip ?? true;\n\n clearChatButton.setAttribute(\"aria-label\", clearChatTooltipText);\n\n if (clearChatButtonWrapper) {\n // Clean up old tooltip event listeners if they exist\n if ((clearChatButtonWrapper as any)._cleanupTooltip) {\n (clearChatButtonWrapper as any)._cleanupTooltip();\n delete (clearChatButtonWrapper as any)._cleanupTooltip;\n }\n\n // Set up new portaled tooltip with event listeners\n if (clearChatShowTooltip && clearChatTooltipText) {\n let portaledTooltip: HTMLElement | null = null;\n\n const showTooltip = () => {\n if (portaledTooltip || !clearChatButton) return; // Already showing or button doesn't exist\n\n // Create tooltip element\n portaledTooltip = createElement(\"div\", \"tvw-clear-chat-tooltip\");\n portaledTooltip.textContent = clearChatTooltipText;\n\n // Add arrow\n const arrow = createElement(\"div\");\n arrow.className = \"tvw-clear-chat-tooltip-arrow\";\n portaledTooltip.appendChild(arrow);\n\n // Get button position\n const buttonRect = clearChatButton.getBoundingClientRect();\n\n // Position tooltip above button\n portaledTooltip.style.position = \"fixed\";\n portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n portaledTooltip.style.top = `${buttonRect.top - 8}px`;\n portaledTooltip.style.transform = \"translate(-50%, -100%)\";\n\n // Append to body\n document.body.appendChild(portaledTooltip);\n };\n\n const hideTooltip = () => {\n if (portaledTooltip && portaledTooltip.parentNode) {\n portaledTooltip.parentNode.removeChild(portaledTooltip);\n portaledTooltip = null;\n }\n };\n\n // Add event listeners\n clearChatButtonWrapper.addEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.addEventListener(\"mouseleave\", hideTooltip);\n clearChatButton.addEventListener(\"focus\", showTooltip);\n clearChatButton.addEventListener(\"blur\", hideTooltip);\n\n // Store cleanup function on the button for later use\n (clearChatButtonWrapper as any)._cleanupTooltip = () => {\n hideTooltip();\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.removeEventListener(\"mouseenter\", showTooltip);\n clearChatButtonWrapper.removeEventListener(\"mouseleave\", hideTooltip);\n }\n if (clearChatButton) {\n clearChatButton.removeEventListener(\"focus\", showTooltip);\n clearChatButton.removeEventListener(\"blur\", hideTooltip);\n }\n };\n }\n }\n }\n }\n\n const nextParsers =\n config.actionParsers && config.actionParsers.length\n ? config.actionParsers\n : [defaultJsonActionParser];\n const nextHandlers =\n config.actionHandlers && config.actionHandlers.length\n ? config.actionHandlers\n : [defaultActionHandlers.message, defaultActionHandlers.messageAndClick];\n\n actionManager = createActionManager({\n parsers: nextParsers,\n handlers: nextHandlers,\n getMetadata,\n updateMetadata,\n emit: eventBus.emit,\n documentRef: typeof document !== \"undefined\" ? document : null\n });\n\n postprocess = buildPostprocessor(config, actionManager);\n session.updateConfig(config);\n renderMessagesWithPlugins(\n messagesWrapper,\n session.getMessages(),\n postprocess\n );\n suggestionsManager.render(config.suggestionChips, session, textarea, undefined, config.suggestionChipsConfig);\n updateCopy();\n setComposerDisabled(session.isStreaming());\n \n // Update voice recognition mic button visibility\n const voiceRecognitionEnabled = config.voiceRecognition?.enabled === true;\n const hasSpeechRecognition = \n typeof window !== 'undefined' && \n (typeof (window as any).webkitSpeechRecognition !== 'undefined' || \n typeof (window as any).SpeechRecognition !== 'undefined');\n \n // Update composer form gap based on voice recognition\n const shouldUseSmallGap = voiceRecognitionEnabled && hasSpeechRecognition;\n composerForm.classList.remove(\"tvw-gap-1\", \"tvw-gap-3\");\n composerForm.classList.add(shouldUseSmallGap ? \"tvw-gap-1\" : \"tvw-gap-3\");\n \n if (voiceRecognitionEnabled && hasSpeechRecognition) {\n // Create or update mic button\n if (!micButton || !micButtonWrapper) {\n // Create new mic button\n const micButtonResult = createMicButton(config.voiceRecognition, config.sendButton);\n if (micButtonResult) {\n // Update the mutable references\n micButton = micButtonResult.micButton;\n micButtonWrapper = micButtonResult.micButtonWrapper;\n \n // Insert before send button wrapper\n composerForm.insertBefore(micButtonWrapper, sendButtonWrapper);\n \n // Wire up click handler\n micButton.addEventListener(\"click\", handleMicButtonClick);\n \n // Set disabled state\n micButton.disabled = session.isStreaming();\n }\n } else {\n // Update existing mic button with new config\n const voiceConfig = config.voiceRecognition ?? {};\n const sendButtonConfig = config.sendButton ?? {};\n \n // Update icon name and size\n const micIconName = voiceConfig.iconName ?? \"mic\";\n const buttonSize = sendButtonConfig.size ?? \"40px\";\n const micIconSize = voiceConfig.iconSize ?? buttonSize;\n const micIconSizeNum = parseFloat(micIconSize) || 24;\n \n micButton.style.width = micIconSize;\n micButton.style.height = micIconSize;\n micButton.style.minWidth = micIconSize;\n micButton.style.minHeight = micIconSize;\n \n // Update icon\n const iconColor = voiceConfig.iconColor ?? sendButtonConfig.textColor ?? \"currentColor\";\n micButton.innerHTML = \"\";\n const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColor, 2);\n if (micIconSvg) {\n micButton.appendChild(micIconSvg);\n } else {\n micButton.textContent = \"🎤\";\n }\n \n // Update colors\n const backgroundColor = voiceConfig.backgroundColor ?? sendButtonConfig.backgroundColor;\n if (backgroundColor) {\n micButton.style.backgroundColor = backgroundColor;\n micButton.classList.remove(\"tvw-bg-cw-primary\");\n } else {\n micButton.style.backgroundColor = \"\";\n micButton.classList.add(\"tvw-bg-cw-primary\");\n }\n \n if (iconColor) {\n micButton.style.color = iconColor;\n micButton.classList.remove(\"tvw-text-white\");\n } else if (!iconColor && !sendButtonConfig.textColor) {\n micButton.style.color = \"\";\n micButton.classList.add(\"tvw-text-white\");\n }\n \n // Update border styling\n if (voiceConfig.borderWidth) {\n micButton.style.borderWidth = voiceConfig.borderWidth;\n micButton.style.borderStyle = \"solid\";\n } else {\n micButton.style.borderWidth = \"\";\n micButton.style.borderStyle = \"\";\n }\n if (voiceConfig.borderColor) {\n micButton.style.borderColor = voiceConfig.borderColor;\n } else {\n micButton.style.borderColor = \"\";\n }\n \n // Update padding styling\n if (voiceConfig.paddingX) {\n micButton.style.paddingLeft = voiceConfig.paddingX;\n micButton.style.paddingRight = voiceConfig.paddingX;\n } else {\n micButton.style.paddingLeft = \"\";\n micButton.style.paddingRight = \"\";\n }\n if (voiceConfig.paddingY) {\n micButton.style.paddingTop = voiceConfig.paddingY;\n micButton.style.paddingBottom = voiceConfig.paddingY;\n } else {\n micButton.style.paddingTop = \"\";\n micButton.style.paddingBottom = \"\";\n }\n \n // Update tooltip\n const tooltip = micButtonWrapper?.querySelector(\".tvw-send-button-tooltip\") as HTMLElement | null;\n const tooltipText = voiceConfig.tooltipText ?? \"Start voice recognition\";\n const showTooltip = voiceConfig.showTooltip ?? false;\n if (showTooltip && tooltipText) {\n if (!tooltip) {\n // Create tooltip if it doesn't exist\n const newTooltip = document.createElement(\"div\");\n newTooltip.className = \"tvw-send-button-tooltip\";\n newTooltip.textContent = tooltipText;\n micButtonWrapper?.insertBefore(newTooltip, micButton);\n } else {\n tooltip.textContent = tooltipText;\n tooltip.style.display = \"\";\n }\n } else if (tooltip) {\n // Hide tooltip if disabled\n tooltip.style.display = \"none\";\n }\n \n // Show and update disabled state\n micButtonWrapper.style.display = \"\";\n micButton.disabled = session.isStreaming();\n }\n } else {\n // Hide mic button\n if (micButton && micButtonWrapper) {\n micButtonWrapper.style.display = \"none\";\n // Stop any active recording if disabling\n if (isRecording) {\n stopVoiceRecognition();\n }\n }\n }\n \n // Update send button styling\n const sendButtonConfig = config.sendButton ?? {};\n const useIcon = sendButtonConfig.useIcon ?? false;\n const iconText = sendButtonConfig.iconText ?? \"↑\";\n const iconName = sendButtonConfig.iconName;\n const tooltipText = sendButtonConfig.tooltipText ?? \"Send message\";\n const showTooltip = sendButtonConfig.showTooltip ?? false;\n const buttonSize = sendButtonConfig.size ?? \"40px\";\n const backgroundColor = sendButtonConfig.backgroundColor;\n const textColor = sendButtonConfig.textColor;\n\n // Update button content and styling based on mode\n if (useIcon) {\n // Icon mode: circular button\n sendButton.style.width = buttonSize;\n sendButton.style.height = buttonSize;\n sendButton.style.minWidth = buttonSize;\n sendButton.style.minHeight = buttonSize;\n sendButton.style.fontSize = \"18px\";\n sendButton.style.lineHeight = \"1\";\n \n // Clear existing content\n sendButton.innerHTML = \"\";\n \n // Use Lucide icon if iconName is provided, otherwise fall back to iconText\n if (iconName) {\n const iconSize = parseFloat(buttonSize) || 24;\n const iconColor = textColor && typeof textColor === 'string' && textColor.trim() ? textColor.trim() : \"currentColor\";\n const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);\n if (iconSvg) {\n sendButton.appendChild(iconSvg);\n sendButton.style.color = iconColor;\n } else {\n // Fallback to text if icon fails to render\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n } else {\n sendButton.textContent = iconText;\n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n \n // Update classes\n sendButton.className = \"tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer\";\n \n if (backgroundColor) {\n sendButton.style.backgroundColor = backgroundColor;\n sendButton.classList.remove(\"tvw-bg-cw-primary\");\n } else {\n sendButton.classList.add(\"tvw-bg-cw-primary\");\n }\n } else {\n // Text mode: existing behavior\n sendButton.textContent = config.copy?.sendButtonLabel ?? \"Send\";\n sendButton.style.width = \"\";\n sendButton.style.height = \"\";\n sendButton.style.minWidth = \"\";\n sendButton.style.minHeight = \"\";\n sendButton.style.fontSize = \"\";\n sendButton.style.lineHeight = \"\";\n \n // Update classes\n sendButton.className = \"tvw-rounded-button tvw-bg-cw-accent tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold tvw-text-white disabled:tvw-opacity-50 tvw-cursor-pointer\";\n \n if (backgroundColor) {\n sendButton.style.backgroundColor = backgroundColor;\n sendButton.classList.remove(\"tvw-bg-cw-accent\");\n } else {\n sendButton.classList.add(\"tvw-bg-cw-accent\");\n }\n \n if (textColor) {\n sendButton.style.color = textColor;\n } else {\n sendButton.classList.add(\"tvw-text-white\");\n }\n }\n\n // Apply border styling\n if (sendButtonConfig.borderWidth) {\n sendButton.style.borderWidth = sendButtonConfig.borderWidth;\n sendButton.style.borderStyle = \"solid\";\n } else {\n sendButton.style.borderWidth = \"\";\n sendButton.style.borderStyle = \"\";\n }\n if (sendButtonConfig.borderColor) {\n sendButton.style.borderColor = sendButtonConfig.borderColor;\n } else {\n sendButton.style.borderColor = \"\";\n }\n\n // Apply padding styling (works in both icon and text mode)\n if (sendButtonConfig.paddingX) {\n sendButton.style.paddingLeft = sendButtonConfig.paddingX;\n sendButton.style.paddingRight = sendButtonConfig.paddingX;\n } else {\n sendButton.style.paddingLeft = \"\";\n sendButton.style.paddingRight = \"\";\n }\n if (sendButtonConfig.paddingY) {\n sendButton.style.paddingTop = sendButtonConfig.paddingY;\n sendButton.style.paddingBottom = sendButtonConfig.paddingY;\n } else {\n sendButton.style.paddingTop = \"\";\n sendButton.style.paddingBottom = \"\";\n }\n\n // Update tooltip\n const tooltip = sendButtonWrapper?.querySelector(\".tvw-send-button-tooltip\") as HTMLElement | null;\n if (showTooltip && tooltipText) {\n if (!tooltip) {\n // Create tooltip if it doesn't exist\n const newTooltip = document.createElement(\"div\");\n newTooltip.className = \"tvw-send-button-tooltip\";\n newTooltip.textContent = tooltipText;\n sendButtonWrapper?.insertBefore(newTooltip, sendButton);\n } else {\n tooltip.textContent = tooltipText;\n tooltip.style.display = \"\";\n }\n } else if (tooltip) {\n tooltip.style.display = \"none\";\n }\n \n // Update status indicator visibility and text\n const statusIndicatorConfig = config.statusIndicator ?? {};\n const isVisible = statusIndicatorConfig.visible ?? true;\n statusText.style.display = isVisible ? \"\" : \"none\";\n \n // Update status text if status is currently set\n if (session) {\n const currentStatus = session.getStatus();\n const getCurrentStatusText = (status: AgentWidgetSessionStatus): string => {\n if (status === \"idle\") return statusIndicatorConfig.idleText ?? statusCopy.idle;\n if (status === \"connecting\") return statusIndicatorConfig.connectingText ?? statusCopy.connecting;\n if (status === \"connected\") return statusIndicatorConfig.connectedText ?? statusCopy.connected;\n if (status === \"error\") return statusIndicatorConfig.errorText ?? statusCopy.error;\n return statusCopy[status];\n };\n statusText.textContent = getCurrentStatusText(currentStatus);\n }\n },\n open() {\n if (!launcherEnabled) return;\n setOpenState(true, \"api\");\n },\n close() {\n if (!launcherEnabled) return;\n setOpenState(false, \"api\");\n },\n toggle() {\n if (!launcherEnabled) return;\n setOpenState(!open, \"api\");\n },\n clearChat() {\n // Clear messages in session (this will trigger onMessagesChanged which re-renders)\n session.clearMessages();\n\n // Always clear the default localStorage key\n try {\n localStorage.removeItem(DEFAULT_CHAT_HISTORY_STORAGE_KEY);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared default localStorage key: ${DEFAULT_CHAT_HISTORY_STORAGE_KEY}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear default localStorage:\", error);\n }\n\n // Also clear custom localStorage key if configured\n if (config.clearChatHistoryStorageKey && config.clearChatHistoryStorageKey !== DEFAULT_CHAT_HISTORY_STORAGE_KEY) {\n try {\n localStorage.removeItem(config.clearChatHistoryStorageKey);\n if (config.debug) {\n console.log(`[AgentWidget] Cleared custom localStorage key: ${config.clearChatHistoryStorageKey}`);\n }\n } catch (error) {\n console.error(\"[AgentWidget] Failed to clear custom localStorage:\", error);\n }\n }\n\n // Dispatch custom event for external handlers (e.g., localStorage clearing in examples)\n const clearEvent = new CustomEvent(\"vanilla-agent:clear-chat\", {\n detail: { timestamp: new Date().toISOString() }\n });\n window.dispatchEvent(clearEvent);\n\n if (storageAdapter?.clear) {\n try {\n const result = storageAdapter.clear();\n if (result instanceof Promise) {\n result.catch((error) => {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n });\n }\n } catch (error) {\n if (typeof console !== \"undefined\") {\n // eslint-disable-next-line no-console\n console.error(\"[AgentWidget] Failed to clear storage adapter:\", error);\n }\n }\n }\n persistentMetadata = {};\n actionManager.syncFromMetadata();\n },\n setMessage(message: string): boolean {\n if (!textarea) return false;\n if (session.isStreaming()) return false;\n \n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n textarea.value = message;\n // Trigger input event for any listeners\n textarea.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n },\n submitMessage(message?: string): boolean {\n if (session.isStreaming()) return false;\n \n const valueToSubmit = message?.trim() || textarea.value.trim();\n if (!valueToSubmit) return false;\n \n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n textarea.value = \"\";\n session.sendMessage(valueToSubmit);\n return true;\n },\n startVoiceRecognition(): boolean {\n if (isRecording || session.isStreaming()) return false;\n \n const SpeechRecognitionClass = getSpeechRecognitionClass();\n if (!SpeechRecognitionClass) return false;\n \n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n voiceState.manuallyDeactivated = false;\n persistVoiceMetadata();\n startVoiceRecognition(\"user\");\n return true;\n },\n stopVoiceRecognition(): boolean {\n if (!isRecording) return false;\n \n voiceState.manuallyDeactivated = true;\n persistVoiceMetadata();\n stopVoiceRecognition(\"user\");\n return true;\n },\n injectTestMessage(event: AgentWidgetEvent) {\n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n session.injectTestEvent(event);\n },\n getMessages() {\n return session.getMessages();\n },\n getStatus() {\n return session.getStatus();\n },\n getPersistentMetadata() {\n return { ...persistentMetadata };\n },\n updatePersistentMetadata(\n updater: (prev: Record<string, unknown>) => Record<string, unknown>\n ) {\n updateMetadata(updater);\n },\n on(event, handler) {\n return eventBus.on(event, handler);\n },\n off(event, handler) {\n eventBus.off(event, handler);\n },\n // State query methods\n isOpen(): boolean {\n return launcherEnabled && open;\n },\n isVoiceActive(): boolean {\n return voiceState.active;\n },\n getState(): AgentWidgetStateSnapshot {\n return {\n open: launcherEnabled && open,\n launcherEnabled,\n voiceActive: voiceState.active,\n streaming: session.isStreaming()\n };\n },\n // Feedback methods (CSAT/NPS)\n showCSATFeedback(options?: Partial<CSATFeedbackOptions>) {\n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n // Remove any existing feedback forms\n const existingFeedback = messagesWrapper.querySelector('.tvw-feedback-container');\n if (existingFeedback) {\n existingFeedback.remove();\n }\n \n const feedbackEl = createCSATFeedback({\n onSubmit: async (rating, comment) => {\n if (session.isClientTokenMode()) {\n await session.submitCSATFeedback(rating, comment);\n }\n options?.onSubmit?.(rating, comment);\n },\n onDismiss: options?.onDismiss,\n ...options,\n });\n \n // Append to messages area at the bottom\n messagesWrapper.appendChild(feedbackEl);\n feedbackEl.scrollIntoView({ behavior: 'smooth', block: 'end' });\n },\n showNPSFeedback(options?: Partial<NPSFeedbackOptions>) {\n // Auto-open widget if closed and launcher is enabled\n if (!open && launcherEnabled) {\n setOpenState(true, \"system\");\n }\n \n // Remove any existing feedback forms\n const existingFeedback = messagesWrapper.querySelector('.tvw-feedback-container');\n if (existingFeedback) {\n existingFeedback.remove();\n }\n \n const feedbackEl = createNPSFeedback({\n onSubmit: async (rating, comment) => {\n if (session.isClientTokenMode()) {\n await session.submitNPSFeedback(rating, comment);\n }\n options?.onSubmit?.(rating, comment);\n },\n onDismiss: options?.onDismiss,\n ...options,\n });\n \n // Append to messages area at the bottom\n messagesWrapper.appendChild(feedbackEl);\n feedbackEl.scrollIntoView({ behavior: 'smooth', block: 'end' });\n },\n async submitCSATFeedback(rating: number, comment?: string): Promise<void> {\n return session.submitCSATFeedback(rating, comment);\n },\n async submitNPSFeedback(rating: number, comment?: string): Promise<void> {\n return session.submitNPSFeedback(rating, comment);\n },\n destroy() {\n destroyCallbacks.forEach((cb) => cb());\n wrapper.remove();\n launcherButtonInstance?.destroy();\n customLauncherElement?.remove();\n if (closeHandler) {\n closeButton.removeEventListener(\"click\", closeHandler);\n }\n }\n };\n\n const shouldExposeDebugApi =\n (runtimeOptions?.debugTools ?? false) || Boolean(config.debug);\n\n if (shouldExposeDebugApi && typeof window !== \"undefined\") {\n const previousDebug = (window as any).AgentWidgetBrowser;\n const debugApi = {\n controller,\n getMessages: controller.getMessages,\n getStatus: controller.getStatus,\n getMetadata: controller.getPersistentMetadata,\n updateMetadata: controller.updatePersistentMetadata,\n clearHistory: () => controller.clearChat(),\n setVoiceActive: (active: boolean) =>\n active\n ? controller.startVoiceRecognition()\n : controller.stopVoiceRecognition()\n };\n (window as any).AgentWidgetBrowser = debugApi;\n destroyCallbacks.push(() => {\n if ((window as any).AgentWidgetBrowser === debugApi) {\n (window as any).AgentWidgetBrowser = previousDebug;\n }\n });\n }\n\n return controller;\n};\n\nexport type AgentWidgetController = Controller;\n","import { createAgentExperience, AgentWidgetController } from \"../ui\";\nimport { AgentWidgetConfig, AgentWidgetInitOptions, AgentWidgetEvent } from \"../types\";\n\nconst ensureTarget = (target: string | HTMLElement): HTMLElement => {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new Error(\"Chat widget can only be mounted in a browser environment\");\n }\n\n if (typeof target === \"string\") {\n const element = document.querySelector<HTMLElement>(target);\n if (!element) {\n throw new Error(`Chat widget target \"${target}\" was not found`);\n }\n return element;\n }\n\n return target;\n};\n\nconst widgetCssHref = (): string | null => {\n try {\n // This works in ESM builds but not in IIFE builds\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n return new URL(\"../widget.css\", import.meta.url).href;\n }\n } catch {\n // Fallback for IIFE builds where CSS should be loaded separately\n }\n return null;\n};\n\nconst mountStyles = (root: ShadowRoot | HTMLElement) => {\n const href = widgetCssHref();\n\n const adoptExistingStylesheet = () => {\n if (!(root instanceof ShadowRoot)) {\n return;\n }\n\n if (root.querySelector('link[data-vanilla-agent]')) {\n return;\n }\n\n const globalLink = document.head.querySelector<HTMLLinkElement>(\n 'link[data-vanilla-agent]'\n );\n if (!globalLink) {\n return;\n }\n\n const clonedLink = globalLink.cloneNode(true) as HTMLLinkElement;\n root.insertBefore(clonedLink, root.firstChild);\n };\n\n if (root instanceof ShadowRoot) {\n // For shadow DOM, we need to load CSS into the shadow root\n if (href) {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.setAttribute(\"data-vanilla-agent\", \"true\");\n root.insertBefore(link, root.firstChild);\n } else {\n adoptExistingStylesheet();\n }\n // If href is null (IIFE build), CSS should already be loaded globally\n } else {\n // For non-shadow DOM, check if CSS is already loaded\n const existing = document.head.querySelector<HTMLLinkElement>(\n \"link[data-vanilla-agent]\"\n );\n if (!existing) {\n if (href) {\n // ESM build - load CSS dynamically\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.setAttribute(\"data-vanilla-agent\", \"true\");\n document.head.appendChild(link);\n }\n // IIFE build - CSS should be loaded via <link> tag before script\n // If not found, we'll assume it's loaded globally or warn in dev\n }\n }\n};\n\nexport type AgentWidgetInitHandle = AgentWidgetController & { host: HTMLElement };\n\nexport const initAgentWidget = (\n options: AgentWidgetInitOptions\n): AgentWidgetInitHandle => {\n const target = ensureTarget(options.target);\n const host = document.createElement(\"div\");\n host.className = \"vanilla-agent-host\";\n \n // When launcher is disabled (inline embed mode), ensure the host fills its container\n const launcherEnabled = options.config?.launcher?.enabled ?? true;\n if (!launcherEnabled) {\n host.style.height = \"100%\";\n }\n \n target.appendChild(host);\n\n const useShadow = options.useShadowDom === true;\n let mount: HTMLElement;\n let root: ShadowRoot | HTMLElement;\n\n if (useShadow) {\n const shadowRoot = host.attachShadow({ mode: \"open\" });\n root = shadowRoot;\n mount = document.createElement(\"div\");\n mount.id = \"vanilla-agent-root\";\n // When launcher is disabled, ensure mount fills the host\n if (!launcherEnabled) {\n mount.style.height = \"100%\";\n mount.style.display = \"flex\";\n mount.style.flexDirection = \"column\";\n mount.style.flex = \"1\";\n mount.style.minHeight = \"0\";\n }\n shadowRoot.appendChild(mount);\n mountStyles(shadowRoot);\n } else {\n root = host;\n mount = document.createElement(\"div\");\n mount.id = \"vanilla-agent-root\";\n // When launcher is disabled, ensure mount fills the host\n if (!launcherEnabled) {\n mount.style.height = \"100%\";\n mount.style.display = \"flex\";\n mount.style.flexDirection = \"column\";\n mount.style.flex = \"1\";\n mount.style.minHeight = \"0\";\n }\n host.appendChild(mount);\n mountStyles(host);\n }\n\n let controller = createAgentExperience(mount, options.config, {\n debugTools: options.debugTools\n });\n options.onReady?.();\n\n const handle: AgentWidgetInitHandle = {\n ...controller,\n host,\n destroy() {\n controller.destroy();\n host.remove();\n if (options.windowKey && typeof window !== \"undefined\") {\n delete (window as any)[options.windowKey];\n }\n }\n };\n\n // Store on window if windowKey is provided\n if (options.windowKey && typeof window !== 'undefined') {\n (window as any)[options.windowKey] = handle;\n }\n\n return handle;\n};\n","import type { AgentWidgetConfig } from \"../types\";\n\ntype ParserType = \"plain\" | \"json\" | \"regex-json\" | \"xml\";\nexport type CodeFormat = \"esm\" | \"script-installer\" | \"script-manual\" | \"script-advanced\" | \"react-component\" | \"react-advanced\";\n\nfunction detectParserTypeFromStreamParser(streamParser: any): ParserType | null {\n if (!streamParser) return null;\n const fnString = streamParser.toString();\n if (fnString.includes(\"createJsonStreamParser\") || fnString.includes(\"partial-json\")) {\n return \"json\";\n }\n if (fnString.includes(\"createRegexJsonParser\") || fnString.includes(\"regex\")) {\n return \"regex-json\";\n }\n if (fnString.includes(\"createXmlParser\") || fnString.includes(\"<text>\")) {\n return \"xml\";\n }\n return null;\n}\n\nfunction getParserTypeFromConfig(config: AgentWidgetConfig): ParserType {\n return config.parserType ?? detectParserTypeFromStreamParser(config.streamParser) ?? \"plain\";\n}\n\n// Helper to generate toolCall config\nfunction generateToolCallConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.toolCall) {\n lines.push(`${indent}toolCall: {`);\n Object.entries(config.toolCall).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n }\n });\n lines.push(`${indent}},`);\n }\n return lines;\n}\n\n// Helper to generate messageActions config (excluding callbacks)\nfunction generateMessageActionsConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.messageActions) {\n const hasSerializableProps = Object.entries(config.messageActions).some(\n ([key, value]) => key !== \"onFeedback\" && key !== \"onCopy\" && value !== undefined\n );\n if (hasSerializableProps) {\n lines.push(`${indent}messageActions: {`);\n Object.entries(config.messageActions).forEach(([key, value]) => {\n // Skip function callbacks\n if (key === \"onFeedback\" || key === \"onCopy\") return;\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent}},`);\n }\n }\n return lines;\n}\n\n// Helper to generate markdown config (excluding renderer functions)\nfunction generateMarkdownConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.markdown) {\n const hasOptions = config.markdown.options && Object.keys(config.markdown.options).length > 0;\n const hasDisableDefaultStyles = config.markdown.disableDefaultStyles !== undefined;\n \n if (hasOptions || hasDisableDefaultStyles) {\n lines.push(`${indent}markdown: {`);\n \n if (hasOptions) {\n lines.push(`${indent} options: {`);\n Object.entries(config.markdown.options).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent} },`);\n }\n \n if (hasDisableDefaultStyles) {\n lines.push(`${indent} disableDefaultStyles: ${config.markdown.disableDefaultStyles},`);\n }\n \n lines.push(`${indent}},`);\n }\n }\n return lines;\n}\n\n// Helper to generate layout config (excluding render functions and slots)\nfunction generateLayoutConfig(config: any, indent: string): string[] {\n const lines: string[] = [];\n if (config.layout) {\n const hasHeader = config.layout.header && Object.keys(config.layout.header).some(\n (key: string) => key !== \"render\"\n );\n const hasMessages = config.layout.messages && Object.keys(config.layout.messages).some(\n (key: string) => key !== \"renderUserMessage\" && key !== \"renderAssistantMessage\"\n );\n \n if (hasHeader || hasMessages) {\n lines.push(`${indent}layout: {`);\n \n // Header config (excluding render function)\n if (hasHeader) {\n lines.push(`${indent} header: {`);\n Object.entries(config.layout.header).forEach(([key, value]) => {\n if (key === \"render\") return; // Skip render function\n if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent} },`);\n }\n \n // Messages config (excluding render functions)\n if (hasMessages) {\n lines.push(`${indent} messages: {`);\n Object.entries(config.layout.messages).forEach(([key, value]) => {\n // Skip render functions\n if (key === \"renderUserMessage\" || key === \"renderAssistantMessage\") return;\n \n if (key === \"avatar\" && typeof value === \"object\" && value !== null) {\n lines.push(`${indent} avatar: {`);\n Object.entries(value as Record<string, unknown>).forEach(([avatarKey, avatarValue]) => {\n if (typeof avatarValue === \"string\") {\n lines.push(`${indent} ${avatarKey}: \"${avatarValue}\",`);\n } else if (typeof avatarValue === \"boolean\") {\n lines.push(`${indent} ${avatarKey}: ${avatarValue},`);\n }\n });\n lines.push(`${indent} },`);\n } else if (key === \"timestamp\" && typeof value === \"object\" && value !== null) {\n // Only emit serializable timestamp properties (skip format function)\n const hasSerializableTimestamp = Object.entries(value as Record<string, unknown>).some(\n ([k]) => k !== \"format\"\n );\n if (hasSerializableTimestamp) {\n lines.push(`${indent} timestamp: {`);\n Object.entries(value as Record<string, unknown>).forEach(([tsKey, tsValue]) => {\n if (tsKey === \"format\") return; // Skip format function\n if (typeof tsValue === \"string\") {\n lines.push(`${indent} ${tsKey}: \"${tsValue}\",`);\n } else if (typeof tsValue === \"boolean\") {\n lines.push(`${indent} ${tsKey}: ${tsValue},`);\n }\n });\n lines.push(`${indent} },`);\n }\n } else if (typeof value === \"string\") {\n lines.push(`${indent} ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(`${indent} ${key}: ${value},`);\n }\n });\n lines.push(`${indent} },`);\n }\n \n lines.push(`${indent}},`);\n }\n }\n return lines;\n}\n\nexport function generateCodeSnippet(config: any, format: CodeFormat = \"esm\"): string {\n // Remove non-serializable properties\n const cleanConfig = { ...config };\n delete cleanConfig.postprocessMessage;\n delete cleanConfig.initialMessages;\n\n if (format === \"esm\") {\n return generateESMCode(cleanConfig);\n } else if (format === \"script-installer\") {\n return generateScriptInstallerCode(cleanConfig);\n } else if (format === \"script-advanced\") {\n return generateScriptAdvancedCode(cleanConfig);\n } else if (format === \"react-component\") {\n return generateReactComponentCode(cleanConfig);\n } else if (format === \"react-advanced\") {\n return generateReactAdvancedCode(cleanConfig);\n } else {\n return generateScriptManualCode(cleanConfig);\n }\n}\n\nfunction generateESMCode(config: any): string {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n \n const lines: string[] = [\n \"import 'vanilla-agent/widget.css';\",\n \"import { initAgentWidget, markdownPostprocessor } from 'vanilla-agent';\",\n \"\",\n \"initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n if (shouldEmitParserType) lines.push(` parserType: \"${parserType}\",`);\n\n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" postprocessMessage: ({ text }) => markdownPostprocessor(text)\");\n lines.push(\" }\");\n lines.push(\"});\");\n\n return lines.join(\"\\n\");\n}\n\nfunction generateReactComponentCode(config: any): string {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n \n const lines: string[] = [\n \"// ChatWidget.tsx\",\n \"'use client'; // Required for Next.js - remove for Vite/CRA\",\n \"\",\n \"import { useEffect } from 'react';\",\n \"import 'vanilla-agent/widget.css';\",\n \"import { initAgentWidget, markdownPostprocessor } from 'vanilla-agent';\",\n \"import type { AgentWidgetInitHandle } from 'vanilla-agent';\",\n \"\",\n \"export function ChatWidget() {\",\n \" useEffect(() => {\",\n \" let handle: AgentWidgetInitHandle | null = null;\",\n \"\",\n \" handle = initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n if (shouldEmitParserType) lines.push(` parserType: \"${parserType}\",`);\n\n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" postprocessMessage: ({ text }) => markdownPostprocessor(text)\");\n lines.push(\" }\");\n lines.push(\" });\");\n lines.push(\"\");\n lines.push(\" // Cleanup on unmount\");\n lines.push(\" return () => {\");\n lines.push(\" if (handle) {\");\n lines.push(\" handle.destroy();\");\n lines.push(\" }\");\n lines.push(\" };\");\n lines.push(\" }, []);\");\n lines.push(\"\");\n lines.push(\" return null; // Widget injects itself into the DOM\");\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"// Usage in your app:\");\n lines.push(\"// import { ChatWidget } from './components/ChatWidget';\");\n lines.push(\"//\");\n lines.push(\"// export default function App() {\");\n lines.push(\"// return (\");\n lines.push(\"// <div>\");\n lines.push(\"// {/* Your app content */}\");\n lines.push(\"// <ChatWidget />\");\n lines.push(\"// </div>\");\n lines.push(\"// );\");\n lines.push(\"// }\");\n\n return lines.join(\"\\n\");\n}\n\nfunction generateReactAdvancedCode(config: any): string {\n const lines: string[] = [\n \"// ChatWidgetAdvanced.tsx\",\n \"'use client'; // Required for Next.js - remove for Vite/CRA\",\n \"\",\n \"import { useEffect } from 'react';\",\n \"import 'vanilla-agent/widget.css';\",\n \"import {\",\n \" initAgentWidget,\",\n \" createFlexibleJsonStreamParser,\",\n \" defaultJsonActionParser,\",\n \" defaultActionHandlers,\",\n \" markdownPostprocessor\",\n \"} from 'vanilla-agent';\",\n \"import type { AgentWidgetInitHandle } from 'vanilla-agent';\",\n \"\",\n \"const STORAGE_KEY = 'chat-widget-state';\",\n \"const PROCESSED_ACTIONS_KEY = 'chat-widget-processed-actions';\",\n \"\",\n \"// Types for DOM elements\",\n \"interface PageElement {\",\n \" type: string;\",\n \" tagName: string;\",\n \" selector: string;\",\n \" innerText: string;\",\n \" href?: string;\",\n \"}\",\n \"\",\n \"interface DOMContext {\",\n \" page_elements: PageElement[];\",\n \" page_element_count: number;\",\n \" element_types: Record<string, number>;\",\n \" page_url: string;\",\n \" page_title: string;\",\n \" timestamp: string;\",\n \"}\",\n \"\",\n \"// DOM context provider - extracts page elements for AI context\",\n \"const collectDOMContext = (): DOMContext => {\",\n \" const selectors = {\",\n \" products: '[data-product-id], .product-card, .product-item, [role=\\\"article\\\"]',\",\n \" buttons: 'button, [role=\\\"button\\\"], .btn',\",\n \" links: 'a[href]',\",\n \" inputs: 'input, textarea, select'\",\n \" };\",\n \"\",\n \" const elements: PageElement[] = [];\",\n \" Object.entries(selectors).forEach(([type, selector]) => {\",\n \" document.querySelectorAll(selector).forEach((element) => {\",\n \" if (!(element instanceof HTMLElement)) return;\",\n \" \",\n \" // Exclude elements within the widget\",\n \" const widgetHost = element.closest('.vanilla-agent-host');\",\n \" if (widgetHost) return;\",\n \" \",\n \" const text = element.innerText?.trim();\",\n \" if (!text) return;\",\n \"\",\n \" const selectorString =\",\n \" element.id ? `#${element.id}` :\",\n \" element.getAttribute('data-testid') ? `[data-testid=\\\"${element.getAttribute('data-testid')}\\\"]` :\",\n \" element.getAttribute('data-product-id') ? `[data-product-id=\\\"${element.getAttribute('data-product-id')}\\\"]` :\",\n \" element.tagName.toLowerCase();\",\n \"\",\n \" const elementData: PageElement = {\",\n \" type,\",\n \" tagName: element.tagName.toLowerCase(),\",\n \" selector: selectorString,\",\n \" innerText: text.substring(0, 200)\",\n \" };\",\n \"\",\n \" if (type === 'links' && element instanceof HTMLAnchorElement && element.href) {\",\n \" elementData.href = element.href;\",\n \" }\",\n \"\",\n \" elements.push(elementData);\",\n \" });\",\n \" });\",\n \"\",\n \" const counts = elements.reduce((acc, el) => {\",\n \" acc[el.type] = (acc[el.type] || 0) + 1;\",\n \" return acc;\",\n \" }, {} as Record<string, number>);\",\n \"\",\n \" return {\",\n \" page_elements: elements.slice(0, 50),\",\n \" page_element_count: elements.length,\",\n \" element_types: counts,\",\n \" page_url: window.location.href,\",\n \" page_title: document.title,\",\n \" timestamp: new Date().toISOString()\",\n \" };\",\n \"};\",\n \"\",\n \"export function ChatWidgetAdvanced() {\",\n \" useEffect(() => {\",\n \" let handle: AgentWidgetInitHandle | null = null;\",\n \"\",\n \" // Load saved state\",\n \" const loadSavedMessages = () => {\",\n \" const savedState = localStorage.getItem(STORAGE_KEY);\",\n \" if (savedState) {\",\n \" try {\",\n \" const { messages } = JSON.parse(savedState);\",\n \" return messages || [];\",\n \" } catch (e) {\",\n \" console.error('Failed to load saved state:', e);\",\n \" }\",\n \" }\",\n \" return [];\",\n \" };\",\n \"\",\n \" handle = initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n \n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" initialMessages: loadSavedMessages(),\");\n lines.push(\" // Flexible JSON stream parser for handling structured actions\");\n lines.push(\" streamParser: () => createFlexibleJsonStreamParser((parsed: any) => {\");\n lines.push(\" if (!parsed || typeof parsed !== 'object') return null;\");\n lines.push(\" // Extract display text based on action type\");\n lines.push(\" if (parsed.action === 'nav_then_click') return 'Navigating...';\");\n lines.push(\" if (parsed.action === 'message') return parsed.text || '';\");\n lines.push(\" if (parsed.action === 'message_and_click') return parsed.text || 'Processing...';\");\n lines.push(\" return parsed.text || null;\");\n lines.push(\" }),\");\n lines.push(\" // Action parsers to detect JSON actions in responses\");\n lines.push(\" actionParsers: [\");\n lines.push(\" defaultJsonActionParser,\");\n lines.push(\" // Custom parser for markdown-wrapped JSON\");\n lines.push(\" ({ text, message }: any) => {\");\n lines.push(\" const jsonSource = (message as any).rawContent || text || message.content;\");\n lines.push(\" if (!jsonSource || typeof jsonSource !== 'string') return null;\");\n lines.push(\" // Strip markdown code fences\");\n lines.push(\" let cleanJson = jsonSource\");\n lines.push(\" .replace(/^```(?:json)?\\\\s*\\\\n?/, '')\");\n lines.push(\" .replace(/\\\\n?```\\\\s*$/, '')\");\n lines.push(\" .trim();\");\n lines.push(\" if (!cleanJson.startsWith('{') || !cleanJson.endsWith('}')) return null;\");\n lines.push(\" try {\");\n lines.push(\" const parsed = JSON.parse(cleanJson);\");\n lines.push(\" if (parsed.action) return { type: parsed.action, payload: parsed };\");\n lines.push(\" } catch (e) { return null; }\");\n lines.push(\" return null;\");\n lines.push(\" }\");\n lines.push(\" ],\");\n lines.push(\" // Action handlers for navigation and other actions\");\n lines.push(\" actionHandlers: [\");\n lines.push(\" defaultActionHandlers.message,\");\n lines.push(\" defaultActionHandlers.messageAndClick,\");\n lines.push(\" // Handler for nav_then_click action\");\n lines.push(\" (action: any, context: any) => {\");\n lines.push(\" if (action.type !== 'nav_then_click') return;\");\n lines.push(\" const payload = action.payload || action.raw || {};\");\n lines.push(\" const url = payload?.page;\");\n lines.push(\" const text = payload?.on_load_text || 'Navigating...';\");\n lines.push(\" if (!url) return { handled: true, displayText: text };\");\n lines.push(\" // Check if already processed\");\n lines.push(\" const messageId = context.message?.id;\");\n lines.push(\" const processedActions = JSON.parse(localStorage.getItem(PROCESSED_ACTIONS_KEY) || '[]');\");\n lines.push(\" const actionKey = `nav_${messageId}_${url}`;\");\n lines.push(\" if (processedActions.includes(actionKey)) {\");\n lines.push(\" return { handled: true, displayText: text };\");\n lines.push(\" }\");\n lines.push(\" processedActions.push(actionKey);\");\n lines.push(\" localStorage.setItem(PROCESSED_ACTIONS_KEY, JSON.stringify(processedActions));\");\n lines.push(\" const targetUrl = url.startsWith('http') ? url : new URL(url, window.location.origin).toString();\");\n lines.push(\" window.location.href = targetUrl;\");\n lines.push(\" return { handled: true, displayText: text };\");\n lines.push(\" }\");\n lines.push(\" ],\");\n lines.push(\" postprocessMessage: ({ text }) => markdownPostprocessor(text),\");\n lines.push(\" requestMiddleware: ({ payload }) => {\");\n lines.push(\" return {\");\n lines.push(\" ...payload,\");\n lines.push(\" metadata: collectDOMContext()\");\n lines.push(\" };\");\n lines.push(\" }\");\n lines.push(\" }\");\n lines.push(\" });\");\n lines.push(\"\");\n lines.push(\" // Save state on message events\");\n lines.push(\" const handleMessage = () => {\");\n lines.push(\" const session = handle?.getSession?.();\");\n lines.push(\" if (session) {\");\n lines.push(\" localStorage.setItem(STORAGE_KEY, JSON.stringify({\");\n lines.push(\" messages: session.messages,\");\n lines.push(\" timestamp: new Date().toISOString()\");\n lines.push(\" }));\");\n lines.push(\" }\");\n lines.push(\" };\");\n lines.push(\"\");\n lines.push(\" // Clear state on clear chat\");\n lines.push(\" const handleClearChat = () => {\");\n lines.push(\" localStorage.removeItem(STORAGE_KEY);\");\n lines.push(\" localStorage.removeItem(PROCESSED_ACTIONS_KEY);\");\n lines.push(\" };\");\n lines.push(\"\");\n lines.push(\" window.addEventListener('vanilla-agent:message', handleMessage);\");\n lines.push(\" window.addEventListener('vanilla-agent:clear-chat', handleClearChat);\");\n lines.push(\"\");\n lines.push(\" // Cleanup on unmount\");\n lines.push(\" return () => {\");\n lines.push(\" window.removeEventListener('vanilla-agent:message', handleMessage);\");\n lines.push(\" window.removeEventListener('vanilla-agent:clear-chat', handleClearChat);\");\n lines.push(\" if (handle) {\");\n lines.push(\" handle.destroy();\");\n lines.push(\" }\");\n lines.push(\" };\");\n lines.push(\" }, []);\");\n lines.push(\"\");\n lines.push(\" return null; // Widget injects itself into the DOM\");\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"// Usage: Collects DOM context for AI-powered navigation\");\n lines.push(\"// Features:\");\n lines.push(\"// - Extracts page elements (products, buttons, links)\");\n lines.push(\"// - Persists chat history across page loads\");\n lines.push(\"// - Handles navigation actions (nav_then_click)\");\n lines.push(\"// - Processes structured JSON actions from AI\");\n lines.push(\"//\");\n lines.push(\"// Example usage in Next.js:\");\n lines.push(\"// import { ChatWidgetAdvanced } from './components/ChatWidgetAdvanced';\");\n lines.push(\"//\");\n lines.push(\"// export default function RootLayout({ children }) {\");\n lines.push(\"// return (\");\n lines.push(\"// <html lang=\\\"en\\\">\");\n lines.push(\"// <body>\");\n lines.push(\"// {children}\");\n lines.push(\"// <ChatWidgetAdvanced />\");\n lines.push(\"// </body>\");\n lines.push(\"// </html>\");\n lines.push(\"// );\");\n lines.push(\"// }\");\n\n return lines.join(\"\\n\");\n}\n\n// Helper to build a serializable config object for JSON export\nfunction buildSerializableConfig(config: any): Record<string, any> {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n \n const serializableConfig: Record<string, any> = {};\n \n if (config.apiUrl) serializableConfig.apiUrl = config.apiUrl;\n if (config.flowId) serializableConfig.flowId = config.flowId;\n if (shouldEmitParserType) serializableConfig.parserType = parserType;\n if (config.theme) serializableConfig.theme = config.theme;\n if (config.launcher) serializableConfig.launcher = config.launcher;\n if (config.copy) serializableConfig.copy = config.copy;\n if (config.sendButton) serializableConfig.sendButton = config.sendButton;\n if (config.voiceRecognition) serializableConfig.voiceRecognition = config.voiceRecognition;\n if (config.statusIndicator) serializableConfig.statusIndicator = config.statusIndicator;\n if (config.features) serializableConfig.features = config.features;\n if (config.suggestionChips?.length > 0) serializableConfig.suggestionChips = config.suggestionChips;\n if (config.suggestionChipsConfig) serializableConfig.suggestionChipsConfig = config.suggestionChipsConfig;\n if (config.debug) serializableConfig.debug = config.debug;\n \n // Add toolCall config (only serializable parts)\n if (config.toolCall) {\n const toolCallConfig: Record<string, any> = {};\n Object.entries(config.toolCall).forEach(([key, value]) => {\n if (typeof value === \"string\") toolCallConfig[key] = value;\n });\n if (Object.keys(toolCallConfig).length > 0) {\n serializableConfig.toolCall = toolCallConfig;\n }\n }\n \n // Add messageActions config (excluding callbacks)\n if (config.messageActions) {\n const messageActionsConfig: Record<string, any> = {};\n Object.entries(config.messageActions).forEach(([key, value]) => {\n if (key !== \"onFeedback\" && key !== \"onCopy\" && value !== undefined) {\n if (typeof value === \"string\" || typeof value === \"boolean\") {\n messageActionsConfig[key] = value;\n }\n }\n });\n if (Object.keys(messageActionsConfig).length > 0) {\n serializableConfig.messageActions = messageActionsConfig;\n }\n }\n \n // Add markdown config (excluding renderer functions)\n if (config.markdown) {\n const markdownConfig: Record<string, any> = {};\n if (config.markdown.options) markdownConfig.options = config.markdown.options;\n if (config.markdown.disableDefaultStyles !== undefined) {\n markdownConfig.disableDefaultStyles = config.markdown.disableDefaultStyles;\n }\n if (Object.keys(markdownConfig).length > 0) {\n serializableConfig.markdown = markdownConfig;\n }\n }\n \n // Add layout config (excluding render functions)\n if (config.layout) {\n const layoutConfig: Record<string, any> = {};\n \n if (config.layout.header) {\n const headerConfig: Record<string, any> = {};\n Object.entries(config.layout.header).forEach(([key, value]) => {\n if (key !== \"render\" && (typeof value === \"string\" || typeof value === \"boolean\")) {\n headerConfig[key] = value;\n }\n });\n if (Object.keys(headerConfig).length > 0) {\n layoutConfig.header = headerConfig;\n }\n }\n \n if (config.layout.messages) {\n const messagesConfig: Record<string, any> = {};\n Object.entries(config.layout.messages).forEach(([key, value]) => {\n if (key !== \"renderUserMessage\" && key !== \"renderAssistantMessage\") {\n if (key === \"avatar\" && typeof value === \"object\" && value !== null) {\n messagesConfig.avatar = value;\n } else if (key === \"timestamp\" && typeof value === \"object\" && value !== null) {\n // Exclude format function\n const tsConfig: Record<string, any> = {};\n Object.entries(value as Record<string, unknown>).forEach(([tsKey, tsValue]) => {\n if (tsKey !== \"format\" && (typeof tsValue === \"string\" || typeof tsValue === \"boolean\")) {\n tsConfig[tsKey] = tsValue;\n }\n });\n if (Object.keys(tsConfig).length > 0) {\n messagesConfig.timestamp = tsConfig;\n }\n } else if (typeof value === \"string\" || typeof value === \"boolean\") {\n messagesConfig[key] = value;\n }\n }\n });\n if (Object.keys(messagesConfig).length > 0) {\n layoutConfig.messages = messagesConfig;\n }\n }\n \n if (Object.keys(layoutConfig).length > 0) {\n serializableConfig.layout = layoutConfig;\n }\n }\n \n return serializableConfig;\n}\n\nfunction generateScriptInstallerCode(config: any): string {\n const serializableConfig = buildSerializableConfig(config);\n \n // Escape single quotes in JSON for HTML attribute\n const configJson = JSON.stringify(serializableConfig, null, 0).replace(/'/g, \"'\");\n \n return `<script src=\"https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist/install.global.js\" data-config='${configJson}'></script>`;\n}\n\nfunction generateScriptManualCode(config: any): string {\n const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);\n const shouldEmitParserType = parserType !== \"plain\";\n\n const lines: string[] = [\n \"<!-- Load CSS -->\",\n \"<link rel=\\\"stylesheet\\\" href=\\\"https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist/widget.css\\\" />\",\n \"\",\n \"<!-- Load JavaScript -->\",\n \"<script src=\\\"https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist/index.global.js\\\"></script>\",\n \"\",\n \"<!-- Initialize widget -->\",\n \"<script>\",\n \" window.AgentWidget.initAgentWidget({\",\n \" target: 'body',\",\n \" config: {\"\n ];\n\n if (config.apiUrl) lines.push(` apiUrl: \"${config.apiUrl}\",`);\n if (config.flowId) lines.push(` flowId: \"${config.flowId}\",`);\n if (shouldEmitParserType) lines.push(` parserType: \"${parserType}\",`);\n\n if (config.theme) {\n lines.push(\" theme: {\");\n Object.entries(config.theme).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.launcher) {\n lines.push(\" launcher: {\");\n Object.entries(config.launcher).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.copy) {\n lines.push(\" copy: {\");\n Object.entries(config.copy).forEach(([key, value]) => {\n lines.push(` ${key}: \"${value}\",`);\n });\n lines.push(\" },\");\n }\n\n if (config.sendButton) {\n lines.push(\" sendButton: {\");\n Object.entries(config.sendButton).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.voiceRecognition) {\n lines.push(\" voiceRecognition: {\");\n Object.entries(config.voiceRecognition).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n } else if (typeof value === \"number\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.statusIndicator) {\n lines.push(\" statusIndicator: {\");\n Object.entries(config.statusIndicator).forEach(([key, value]) => {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"boolean\") {\n lines.push(` ${key}: ${value},`);\n }\n });\n lines.push(\" },\");\n }\n\n if (config.features) {\n lines.push(\" features: {\");\n Object.entries(config.features).forEach(([key, value]) => {\n lines.push(` ${key}: ${value},`);\n });\n lines.push(\" },\");\n }\n\n if (config.suggestionChips && config.suggestionChips.length > 0) {\n lines.push(\" suggestionChips: [\");\n config.suggestionChips.forEach((chip: string) => {\n lines.push(` \"${chip}\",`);\n });\n lines.push(\" ],\");\n }\n\n if (config.suggestionChipsConfig) {\n lines.push(\" suggestionChipsConfig: {\");\n if (config.suggestionChipsConfig.fontFamily) {\n lines.push(` fontFamily: \"${config.suggestionChipsConfig.fontFamily}\",`);\n }\n if (config.suggestionChipsConfig.fontWeight) {\n lines.push(` fontWeight: \"${config.suggestionChipsConfig.fontWeight}\",`);\n }\n if (config.suggestionChipsConfig.paddingX) {\n lines.push(` paddingX: \"${config.suggestionChipsConfig.paddingX}\",`);\n }\n if (config.suggestionChipsConfig.paddingY) {\n lines.push(` paddingY: \"${config.suggestionChipsConfig.paddingY}\",`);\n }\n lines.push(\" },\");\n }\n\n // Add toolCall config\n lines.push(...generateToolCallConfig(config, \" \"));\n\n // Add messageActions config\n lines.push(...generateMessageActionsConfig(config, \" \"));\n\n // Add markdown config\n lines.push(...generateMarkdownConfig(config, \" \"));\n\n // Add layout config\n lines.push(...generateLayoutConfig(config, \" \"));\n\n if (config.debug) {\n lines.push(` debug: ${config.debug},`);\n }\n\n lines.push(\" postprocessMessage: ({ text }) => window.AgentWidget.markdownPostprocessor(text)\");\n lines.push(\" }\");\n lines.push(\" });\");\n lines.push(\"</script>\");\n\n return lines.join(\"\\n\");\n}\n\nfunction generateScriptAdvancedCode(config: any): string {\n const serializableConfig = buildSerializableConfig(config);\n const configJson = JSON.stringify(serializableConfig, null, 2);\n \n const lines: string[] = [\n \"<script>\",\n \"(function() {\",\n \" 'use strict';\",\n \"\",\n \" // Configuration\",\n ` var CONFIG = ${configJson.split('\\n').map((line, i) => i === 0 ? line : ' ' + line).join('\\n')};`,\n \"\",\n \" // Constants\",\n \" var CDN_BASE = 'https://cdn.jsdelivr.net/npm/vanilla-agent@latest/dist';\",\n \" var STORAGE_KEY = 'chat-widget-state';\",\n \" var PROCESSED_ACTIONS_KEY = 'chat-widget-processed-actions';\",\n \"\",\n \" // DOM context provider - extracts page elements for AI context\",\n \" var domContextProvider = function() {\",\n \" var selectors = {\",\n \" products: '[data-product-id], .product-card, .product-item, [role=\\\"article\\\"]',\",\n \" buttons: 'button, [role=\\\"button\\\"], .btn',\",\n \" links: 'a[href]',\",\n \" inputs: 'input, textarea, select'\",\n \" };\",\n \"\",\n \" var elements = [];\",\n \" Object.entries(selectors).forEach(function(entry) {\",\n \" var type = entry[0], selector = entry[1];\",\n \" document.querySelectorAll(selector).forEach(function(element) {\",\n \" if (!(element instanceof HTMLElement)) return;\",\n \" var widgetHost = element.closest('.vanilla-agent-host');\",\n \" if (widgetHost) return;\",\n \" var text = element.innerText ? element.innerText.trim() : '';\",\n \" if (!text) return;\",\n \"\",\n \" var selectorString = element.id ? '#' + element.id :\",\n \" element.getAttribute('data-testid') ? '[data-testid=\\\"' + element.getAttribute('data-testid') + '\\\"]' :\",\n \" element.getAttribute('data-product-id') ? '[data-product-id=\\\"' + element.getAttribute('data-product-id') + '\\\"]' :\",\n \" element.tagName.toLowerCase();\",\n \"\",\n \" var elementData = {\",\n \" type: type,\",\n \" tagName: element.tagName.toLowerCase(),\",\n \" selector: selectorString,\",\n \" innerText: text.substring(0, 200)\",\n \" };\",\n \"\",\n \" if (type === 'links' && element instanceof HTMLAnchorElement && element.href) {\",\n \" elementData.href = element.href;\",\n \" }\",\n \" elements.push(elementData);\",\n \" });\",\n \" });\",\n \"\",\n \" var counts = elements.reduce(function(acc, el) {\",\n \" acc[el.type] = (acc[el.type] || 0) + 1;\",\n \" return acc;\",\n \" }, {});\",\n \"\",\n \" return {\",\n \" page_elements: elements.slice(0, 50),\",\n \" page_element_count: elements.length,\",\n \" element_types: counts,\",\n \" page_url: window.location.href,\",\n \" page_title: document.title,\",\n \" timestamp: new Date().toISOString()\",\n \" };\",\n \" };\",\n \"\",\n \" // Load CSS dynamically\",\n \" var loadCSS = function() {\",\n \" if (document.querySelector('link[data-vanilla-agent]')) return;\",\n \" var link = document.createElement('link');\",\n \" link.rel = 'stylesheet';\",\n \" link.href = CDN_BASE + '/widget.css';\",\n \" link.setAttribute('data-vanilla-agent', 'true');\",\n \" document.head.appendChild(link);\",\n \" };\",\n \"\",\n \" // Load JS dynamically\",\n \" var loadJS = function(callback) {\",\n \" if (window.AgentWidget) { callback(); return; }\",\n \" var script = document.createElement('script');\",\n \" script.src = CDN_BASE + '/index.global.js';\",\n \" script.onload = callback;\",\n \" script.onerror = function() { console.error('Failed to load AgentWidget'); };\",\n \" document.head.appendChild(script);\",\n \" };\",\n \"\",\n \" // Create widget config with advanced features\",\n \" var createWidgetConfig = function(agentWidget) {\",\n \" var widgetConfig = Object.assign({}, CONFIG);\",\n \"\",\n \" // Flexible JSON stream parser for handling structured actions\",\n \" widgetConfig.streamParser = function() {\",\n \" return agentWidget.createFlexibleJsonStreamParser(function(parsed) {\",\n \" if (!parsed || typeof parsed !== 'object') return null;\",\n \" if (parsed.action === 'nav_then_click') return 'Navigating...';\",\n \" if (parsed.action === 'message') return parsed.text || '';\",\n \" if (parsed.action === 'message_and_click') return parsed.text || 'Processing...';\",\n \" return parsed.text || null;\",\n \" });\",\n \" };\",\n \"\",\n \" // Action parsers to detect JSON actions in responses\",\n \" widgetConfig.actionParsers = [\",\n \" agentWidget.defaultJsonActionParser,\",\n \" function(ctx) {\",\n \" var jsonSource = ctx.message.rawContent || ctx.text || ctx.message.content;\",\n \" if (!jsonSource || typeof jsonSource !== 'string') return null;\",\n \" var cleanJson = jsonSource\",\n \" .replace(/^```(?:json)?\\\\s*\\\\n?/, '')\",\n \" .replace(/\\\\n?```\\\\s*$/, '')\",\n \" .trim();\",\n \" if (!cleanJson.startsWith('{') || !cleanJson.endsWith('}')) return null;\",\n \" try {\",\n \" var parsed = JSON.parse(cleanJson);\",\n \" if (parsed.action) return { type: parsed.action, payload: parsed };\",\n \" } catch (e) { return null; }\",\n \" return null;\",\n \" }\",\n \" ];\",\n \"\",\n \" // Action handlers for navigation and other actions\",\n \" widgetConfig.actionHandlers = [\",\n \" agentWidget.defaultActionHandlers.message,\",\n \" agentWidget.defaultActionHandlers.messageAndClick,\",\n \" function(action, context) {\",\n \" if (action.type !== 'nav_then_click') return;\",\n \" var payload = action.payload || action.raw || {};\",\n \" var url = payload.page;\",\n \" var text = payload.on_load_text || 'Navigating...';\",\n \" if (!url) return { handled: true, displayText: text };\",\n \" var messageId = context.message ? context.message.id : null;\",\n \" var processedActions = JSON.parse(localStorage.getItem(PROCESSED_ACTIONS_KEY) || '[]');\",\n \" var actionKey = 'nav_' + messageId + '_' + url;\",\n \" if (processedActions.includes(actionKey)) {\",\n \" return { handled: true, displayText: text };\",\n \" }\",\n \" processedActions.push(actionKey);\",\n \" localStorage.setItem(PROCESSED_ACTIONS_KEY, JSON.stringify(processedActions));\",\n \" var targetUrl = url.startsWith('http') ? url : new URL(url, window.location.origin).toString();\",\n \" window.location.href = targetUrl;\",\n \" return { handled: true, displayText: text };\",\n \" }\",\n \" ];\",\n \"\",\n \" // Send DOM context with each request\",\n \" widgetConfig.requestMiddleware = function(ctx) {\",\n \" return Object.assign({}, ctx.payload, { metadata: domContextProvider() });\",\n \" };\",\n \"\",\n \" // Markdown postprocessor\",\n \" widgetConfig.postprocessMessage = function(ctx) {\",\n \" return agentWidget.markdownPostprocessor(ctx.text);\",\n \" };\",\n \"\",\n \" return widgetConfig;\",\n \" };\",\n \"\",\n \" // Initialize widget\",\n \" var init = function() {\",\n \" var agentWidget = window.AgentWidget;\",\n \" if (!agentWidget) {\",\n \" console.error('AgentWidget not loaded');\",\n \" return;\",\n \" }\",\n \"\",\n \" var widgetConfig = createWidgetConfig(agentWidget);\",\n \"\",\n \" // Load saved state\",\n \" var savedState = localStorage.getItem(STORAGE_KEY);\",\n \" if (savedState) {\",\n \" try {\",\n \" var parsed = JSON.parse(savedState);\",\n \" widgetConfig.initialMessages = parsed.messages || [];\",\n \" } catch (e) {\",\n \" console.error('Failed to load saved state:', e);\",\n \" }\",\n \" }\",\n \"\",\n \" // Initialize widget\",\n \" var handle = agentWidget.initAgentWidget({\",\n \" target: 'body',\",\n \" useShadowDom: false,\",\n \" config: widgetConfig\",\n \" });\",\n \"\",\n \" // Save state on message events\",\n \" window.addEventListener('vanilla-agent:message', function() {\",\n \" var session = handle.getSession ? handle.getSession() : null;\",\n \" if (session) {\",\n \" localStorage.setItem(STORAGE_KEY, JSON.stringify({\",\n \" messages: session.messages,\",\n \" timestamp: new Date().toISOString()\",\n \" }));\",\n \" }\",\n \" });\",\n \"\",\n \" // Clear state on clear chat\",\n \" window.addEventListener('vanilla-agent:clear-chat', function() {\",\n \" localStorage.removeItem(STORAGE_KEY);\",\n \" localStorage.removeItem(PROCESSED_ACTIONS_KEY);\",\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 \" var waitForHydration = function(callback) {\",\n \" var executed = false;\",\n \" \",\n \" var execute = function() {\",\n \" if (executed) return;\",\n \" executed = true;\",\n \" callback();\",\n \" };\",\n \"\",\n \" var afterDom = function() {\",\n \" // Strategy 1: Use requestIdleCallback if available (best for detecting idle after hydration)\",\n \" if (typeof requestIdleCallback !== 'undefined') {\",\n \" requestIdleCallback(function() {\",\n \" // Double requestAnimationFrame ensures at least one full paint cycle completed\",\n \" requestAnimationFrame(function() {\",\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 \" // Boot sequence: wait for hydration, then load CSS and JS, then initialize\",\n \" // This prevents Next.js/Nuxt/etc. from removing dynamically added CSS during reconciliation\",\n \" waitForHydration(function() {\",\n \" loadCSS();\",\n \" loadJS(function() {\",\n \" init();\",\n \" });\",\n \" });\",\n \"})();\",\n \"</script>\"\n ];\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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,KAAK,GAAG,EACdA,EAAM,KAAK,EAAE,EACbA,EAAM,KAAK,uBAAuB,EAClCA,EAAM,KAAK,0DAA0D,EACrEA,EAAM,KAAK,IAAI,EACfA,EAAM,KAAK,oCAAoC,EAC/CA,EAAM,KAAK,eAAe,EAC1BA,EAAM,KAAK,cAAc,EACzBA,EAAM,KAAK,mCAAmC,EAC9CA,EAAM,KAAK,yBAAyB,EACpCA,EAAM,KAAK,eAAe,EAC1BA,EAAM,KAAK,SAAS,EACpBA,EAAM,KAAK,MAAM,EAEVA,EAAM,KAAK;AAAA,CAAI,CACxB,CAEA,SAASsB,GAA0B3B,EAAqB,CACtD,IAAMK,EAAkB,CACtB,4BACA,8DACA,GACA,qCACA,qCACA,WACA,qBACA,oCACA,6BACA,2BACA,0BACA,0BACA,8DACA,GACA,2CACA,iEACA,GACA,4BACA,0BACA,kBACA,qBACA,sBACA,uBACA,mBACA,IACA,GACA,yBACA,kCACA,gCACA,2CACA,sBACA,wBACA,uBACA,IACA,GACA,kEACA,gDACA,wBACA,qFACA,gDACA,wBACA,wCACA,OACA,GACA,wCACA,8DACA,iEACA,uDACA,SACA,8CACA,mEACA,gCACA,SACA,gDACA,2BACA,GACA,+BACA,0CACA,6GACA,yHACA,yCACA,GACA,2CACA,gBACA,kDACA,oCACA,4CACA,WACA,GACA,wFACA,2CACA,UACA,GACA,oCACA,UACA,QACA,GACA,kDACA,8CACA,kBACA,sCACA,GACA,aACA,4CACA,2CACA,6BACA,sCACA,kCACA,0CACA,OACA,KACA,GACA,yCACA,sBACA,uDACA,GACA,0BACA,wCACA,8DACA,0BACA,gBACA,yDACA,mCACA,wBACA,6DACA,YACA,UACA,mBACA,SACA,GACA,iCACA,wBACA,iBACF,EAEA,OAAIL,EAAO,QAAQK,EAAM,KAAK,oBAAoBL,EAAO,MAAM,IAAI,EAC/DA,EAAO,QAAQK,EAAM,KAAK,oBAAoBL,EAAO,MAAM,IAAI,EAE/DA,EAAO,QACTK,EAAM,KAAK,kBAAkB,EAC7B,OAAO,QAAQL,EAAO,KAAK,EAAE,QAAQ,CAAC,CAACM,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ACA,SACA,OACA,GACA,4BACA,+BACA,sEACA,iDACA,+BACA,4CACA,uDACA,uCACA,OACA,GACA,2BACA,sCACA,sDACA,qDACA,kDACA,gCACA,oFACA,yCACA,OACA,GACA,mDACA,qDACA,oDACA,GACA,qEACA,+CACA,6EACA,kEACA,0EACA,qEACA,4FACA,sCACA,YACA,SACA,GACA,4DACA,qCACA,6CACA,wBACA,sFACA,0EACA,qCACA,kDACA,yCACA,qBACA,mFACA,gBACA,gDACA,gFACA,uCACA,uBACA,UACA,SACA,GACA,0DACA,sCACA,mDACA,2DACA,oCACA,wDACA,4DACA,kCACA,8DACA,iEACA,uEACA,kGACA,0DACA,sDACA,yDACA,YACA,4CACA,yFACA,0GACA,4CACA,uDACA,UACA,SACA,GACA,4CACA,uDACA,mFACA,SACA,GACA,gCACA,wDACA,4DACA,SACA,GACA,2BACA,OACA,GACA,yBACA,4BACA,4CACA,0BACA,iDACA,gBACA,QACA,GACA,0DACA,GACA,0BACA,0DACA,wBACA,cACA,+CACA,gEACA,sBACA,2DACA,UACA,QACA,GACA,2BACA,iDACA,wBACA,6BACA,6BACA,UACA,GACA,sCACA,oEACA,sEACA,uBACA,6DACA,wCACA,gDACA,eACA,UACA,UACA,GACA,mCACA,uEACA,8CACA,wDACA,UACA,OACA,GACA,sEACA,6FACA,gDACA,4BACA,OACA,iCACA,8BACA,yBACA,oBACA,SACA,GACA,kCACA,sGACA,0DACA,2CACA,4FACA,+CACA,8CACA,gBACA,4EACA,iBACA,sEACA,mEACA,oCACA,UACA,SACA,GACA,+CACA,iEACA,eACA,qEACA,oBACA,QACA,OACA,GACA,gFACA,iGACA,kCACA,iBACA,0BACA,gBACA,UACA,QACA,QACA,WACF,EAEa,KAAK;AAAA,CAAI,CACxB,CjC5sCA,IAAOE,GAAQC","names":["index_exports","__export","AgentWidgetClient","AgentWidgetSession","DEFAULT_DARK_THEME","DEFAULT_LIGHT_THEME","DEFAULT_WIDGET_CONFIG","attachHeaderToContainer","buildComposer","buildDefaultHeader","buildExpandedHeader","buildHeader","buildHeaderWithLayout","buildMinimalHeader","componentRegistry","createActionManager","createAgentExperience","createBubbleWithLayout","createCSATFeedback","createComponentMiddleware","createComponentStreamParser","createDirectivePostprocessor","createFlexibleJsonStreamParser","createJsonStreamParser","createLocalStorageAdapter","createMarkdownProcessor","createMarkdownProcessorFromConfig","createMessageActions","createNPSFeedback","createPlainTextParser","createRegexJsonParser","createStandardBubble","createTypingIndicator","createXmlParser","index_default","defaultActionHandlers","defaultJsonActionParser","directivePostprocessor","escapeHtml","extractComponentDirectiveFromMessage","generateAssistantMessageId","generateCodeSnippet","generateMessageId","generateUserMessageId","getHeaderLayout","hasComponentDirective","headerLayouts","initAgentWidget","isComponentDirectiveType","markdownPostprocessor","mergeWithDefaults","pluginRegistry","renderComponentDirective","__toCommonJS","import_marked","convertRendererOverrides","overrides","createMarkdownProcessor","options","_a","_b","opts","markedInstance","rendererOverrides","text","createMarkdownProcessorFromConfig","config","defaultMarkdownProcessor","markdownPostprocessor","escapeHtml","escapeAttribute","value","makeToken","idx","directiveReplacer","source","placeholders","working","match","jsonText","parsed","token","_","type","createDirectivePostprocessor","markdownConfig","processor","withTokens","html","tokenRegex","replacement","directivePostprocessor","import_partial_json","unescapeJsonString","str","formatUnknownValue","value","formatReasoningDuration","reasoning","_a","_b","end","start","seconds","describeReasonStatus","formatToolDuration","tool","_c","describeToolTitle","tool","formatToolDuration","createRegexJsonParserInternal","extractedText","processedLength","extractTextFromIncompleteJson","jsonString","textFieldRegex","match","incompleteTextFieldRegex","incompleteMatch","accumulatedContent","trimmed","extracted","extractTextFromJson","parsed","createPlainTextParser","parser","createRegexJsonParser","_a","regexParser","createJsonStreamParser","parsePartialJson","unescapeJsonString","createFlexibleJsonStreamParser","textExtractor","extractText","getText","value","newText","createXmlParser","DEFAULT_ENDPOINT","DEFAULT_CLIENT_API_BASE","getParserFromType","parserType","createJsonStreamParser","createRegexJsonParser","createXmlParser","createPlainTextParser","AgentWidgetClient","config","_a","_b","_c","endpoint","baseUrl","session","response","error","data","feedback","errorData","messageId","type","rating","comment","options","onEvent","_d","controller","basePayload","chatRequest","m","err","payload","headers","dynamicHeaders","messages","a","b","timeA","timeB","message","contextAggregate","provider","result","assistantMessageRef","emitMessage","nextSequence","ensureAssistant","msg","assistant","body","assistantMessageId","_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","_D","_E","_F","_G","_H","_I","_J","_K","_L","_M","_N","_O","_P","_Q","_R","_S","_T","_U","_V","_W","_X","_Y","_Z","__","_$","_aa","_ba","reader","decoder","buffer","baseSequence","sequenceCounter","cloneMessage","reasoning","toolCall","tools","tool","assistantMessage","reasoningMessages","toolMessages","reasoningContext","toolContext","normalizeKey","value","getStepKey","getToolCallKey","ensureAssistantMessage","trackReasoningId","stepKey","id","resolveReasoningId","allowCreate","rawId","resolved","existing","generated","ensureReasoningMessage","reasoningId","trackToolId","callKey","resolveToolId","ensureToolMessage","toolId","resolveTimestamp","parsed","dateParsed","ensureStringContent","streamParsers","rawContentBuffers","done","events","event","lines","eventType","line","payloadType","handled","reasoningMessage","chunk","start","toolMessage","chunkText","stepType","executionType","accumulatedRaw","parser","looksLikeJson","parsedResult","text","currentAssistant","finalContent","rawBuffer","contentToProcess","extractedText","asyncPending","extractTextFromJson","parserToClose","closeResult","hasExtractedText","currentExtractedText","finalExtractedText","stringContent","displayContent","currentText","contentChanged","streamingChanged","generateMessageId","timestamp","random","generateUserMessageId","generateAssistantMessageId","AgentWidgetSession","config","callbacks","event","_a","_b","message","AgentWidgetClient","session","error","welcomeMessage","messageId","type","rating","comment","next","rawInput","options","_c","_d","_e","input","userMessageId","generateUserMessageId","assistantMessageId","generateAssistantMessageId","userMessage","controller","snapshot","fallback","messages","status","streaming","withSequence","index","m","existing","idx","a","b","timeA","timeB","seqA","seqB","detectColorScheme","_a","getActiveTheme","config","_b","_c","colorScheme","lightTheme","darkTheme","createThemeObserver","callback","cleanupFns","observer","mediaQuery","handleChange","fn","applyThemeVariables","element","theme","key","value","kebabKey","letter","icons","renderLucideIcon","iconName","size","color","strokeWidth","pascalName","word","iconData","createSvgFromIconData","error","svg","elementData","tagName","attrs","element","key","value","createElement","tag","className","element","import_idiomorph","morphMessages","container","newContent","options","preserveTypingAnimation","oldNode","newNode","statusCopy","positionMap","createLauncherButton","config","onToggle","button","createElement","update","newConfig","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","launcher","titleEl","subtitleEl","textContainer","icon","iconSize","iconSizeNum","iconSvg","renderLucideIcon","img","callToActionIconEl","callToActionIconSize","paddingTotal","containerSize","positionClass","positionMap","base","defaultBorder","defaultShadow","destroy","buildHeader","context","_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","_D","_E","_F","config","showClose","header","createElement","launcher","headerIconSize","closeButtonSize","closeButtonPlacement","headerIconHidden","headerIconName","iconHolder","iconSize","iconSvg","renderLucideIcon","img","headerCopy","title","subtitle","clearChatConfig","clearChatEnabled","clearChatPlacement","clearChatButton","clearChatButtonWrapper","clearChatSize","clearChatIconName","clearChatIconColor","clearChatBgColor","clearChatBorderWidth","clearChatBorderColor","clearChatBorderRadius","clearChatPaddingX","clearChatPaddingY","clearChatTooltipText","clearChatShowTooltip","borderWidth","borderColor","portaledTooltip","showTooltip","arrow","buttonRect","hideTooltip","closeButtonWrapper","closeButton","closeButtonTooltipText","closeButtonShowTooltip","closeButtonIconName","closeButtonIconText","closeIconSvg","attachHeaderToContainer","container","headerElements","buildDefaultHeader","context","buildHeader","buildMinimalHeader","_a","_b","_c","_d","config","showClose","onClose","launcher","header","createElement","title","closeButtonSize","closeButtonWrapper","closeButton","closeButtonIconName","closeIconSvg","renderLucideIcon","iconHolder","headerSubtitle","buildExpandedHeader","_e","_f","_g","_h","onClearChat","topRow","headerIconSize","headerIconName","iconSize","iconSvg","img","headerCopy","subtitle","bottomRow","headerLayouts","getHeaderLayout","layoutName","buildHeaderWithLayout","layoutConfig","customHeader","headerTitle","headerElements","getFontFamilyValue","family","buildComposer","context","_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","config","footer","createElement","suggestions","voiceRecognitionEnabledForGap","hasSpeechRecognitionForGap","composerForm","textarea","fontFamily","fontWeight","sendButtonConfig","useIcon","iconText","iconName","tooltipText","showTooltip","buttonSize","backgroundColor","textColor","sendButtonWrapper","sendButton","iconSize","iconColor","iconSvg","renderLucideIcon","tooltip","voiceRecognitionConfig","voiceRecognitionEnabled","micButton","micButtonWrapper","hasSpeechRecognition","micIconName","micIconSize","micIconSizeNum","micBackgroundColor","micIconColor","iconColorValue","micIconSvg","micTooltipText","e","statusText","statusConfig","isVisible","createWrapper","config","_a","_b","_c","_d","_e","_f","_g","wrapper","createElement","panel","inlineWidth","launcher","position","positionMap","launcherWidth","width","buildPanel","showClose","container","headerLayoutConfig","headerElements","buildHeaderWithLayout","buildHeader","body","introCard","introTitle","introSubtitle","messagesWrapper","composerElements","buildComposer","attachHeaderToContainer","createTypingIndicator","container","dot1","dot2","dot3","srOnly","createAvatar","avatarConfig","role","avatar","createElement","avatarContent","img","createTimestamp","message","timestampConfig","timestamp","date","getBubbleClasses","layout","baseClasses","createMessageActions","actionsConfig","callbacks","_a","_b","_c","_d","_e","_f","showCopy","showUpvote","showDownvote","visibility","align","alignClass","layoutClass","currentVote","createActionButton","iconName","label","onClick","dataAction","button","icon","renderLucideIcon","e","copyButton","textToCopy","checkIcon","originalIcon","err","upvoteButton","downvoteBtn","feedback","downvoteButton","upvoteBtn","createStandardBubble","transform","layoutConfig","actionCallbacks","config","showAvatar","showTimestamp","avatarPosition","timestampPosition","classes","bubble","contentDiv","typingIndicator","actions","wrapper","createBubbleWithLayout","reasoningExpansionState","createReasoningBubble","message","reasoning","bubble","createElement","expanded","header","headerContent","title","status","describeReasonStatus","toggleIcon","chevronIcon","renderLucideIcon","headerMeta","content","text","body","applyExpansionState","toggleExpansion","event","toolExpansionState","createToolBubble","message","config","_a","tool","toolCallConfig","bubble","createElement","expanded","header","headerContent","title","describeToolTitle","toggleIcon","iconColor","chevronIcon","renderLucideIcon","headerMeta","content","toolName","argsBlock","argsLabel","argsPre","formatUnknownValue","logsBlock","logsLabel","logsPre","resultBlock","resultLabel","resultPre","duration","applyToolExpansion","toggleToolExpansion","event","createSuggestions","container","suggestionButtons","chips","session","textarea","messages","chipsConfig","msg","fragment","streaming","getFontFamilyValue","family","chip","btn","createElement","formDefinitions","enhanceWithForms","bubble","message","config","session","placeholders","placeholder","_a","_b","_c","type","definition","heading","createElement","title","desc","form","field","group","label","inputType","control","actions","status","submit","event","formEndpoint","formData","payload","value","key","response","data","error","PluginRegistry","plugin","_a","pluginId","a","b","_b","instancePlugins","allPlugins","instanceIds","p","pluginRegistry","DEFAULT_LIGHT_THEME","DEFAULT_DARK_THEME","DEFAULT_WIDGET_CONFIG","mergeWithDefaults","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","createEventBus","listeners","on","event","handler","off","_a","payload","error","stripCodeFence","value","match","extractJsonObject","trimmed","start","depth","i","char","defaultJsonActionParser","text","withoutFence","jsonBody","parsed","action","payload","asString","defaultActionHandlers","context","_a","selector","element","ensureArrayOfStrings","entry","createActionManager","options","processedIds","syncFromMetadata","persistProcessedIds","latestIds","prev","parseSource","acc","parser","eventPayload","handler","handlerResult","persist","error","safeJsonParse","value","error","sanitizeMessages","messages","message","createLocalStorageAdapter","key","getStorage","storage","state","payload","ComponentRegistry","name","renderer","components","componentRegistry","import_partial_json","isComponentDirective","obj","component","extractComponentDirective","parsed","rawJson","props","createComponentStreamParser","extractedDirective","processedLength","accumulatedContent","trimmed","parsePartialJson","directive","isComponentDirectiveType","renderComponentDirective","directive","options","config","message","onPropsUpdate","renderer","componentRegistry","context","newProps","error","createComponentMiddleware","parser","createComponentStreamParser","accumulatedContent","hasComponentDirective","parsed","extractComponentDirectiveFromMessage","defaultCSATLabels","createCSATFeedback","options","onSubmit","onDismiss","title","subtitle","commentPlaceholder","submitText","skipText","showComment","ratingLabels","container","selectedRating","content","header","titleEl","subtitleEl","ratingContainer","ratingButtons","i","ratingButton","btn","index","isSelected","commentTextarea","commentContainer","actions","skipButton","submitButton","comment","error","createNPSFeedback","lowLabel","highLabel","labelsRow","lowLabelEl","highLabelEl","numbersRow","DEFAULT_CHAT_HISTORY_STORAGE_KEY","VOICE_STATE_RESTORE_WINDOW","ensureRecord","value","stripStreamingFromMessages","messages","message","buildPostprocessor","cfg","actionManager","markdownProcessor","createMarkdownProcessorFromConfig","context","_a","_b","_c","nextText","rawPayload","actionResult","escapeHtml","createAgentExperience","mount","initialConfig","runtimeOptions","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","config","mergeWithDefaults","plugins","pluginRegistry","componentRegistry","eventBus","createEventBus","storageAdapter","createLocalStorageAdapter","persistentMetadata","pendingStoredState","storedState","immediateState","error","getMetadata","updateMetadata","updater","persistState","resolvedActionParsers","defaultJsonActionParser","resolvedActionHandlers","defaultActionHandlers","createActionManager","launcherEnabled","autoExpand","prevAutoExpand","prevLauncherEnabled","prevHeaderLayout","open","postprocess","showReasoning","showToolCalls","messageActionCallbacks","session","feedback","statusConfig","getStatusText","status","statusCopy","wrapper","panel","createWrapper","panelElements","buildPanel","container","body","messagesWrapper","suggestions","textarea","sendButton","sendButtonWrapper","composerForm","statusText","introTitle","introSubtitle","closeButton","iconHolder","headerTitle","headerSubtitle","header","footer","micButton","micButtonWrapper","headerPlugin","p","customHeader","headerElements","buildHeader","attachHeaderToContainer","setOpenState","existingHeader","composerPlugin","customComposer","buildComposer","text","slots","getDefaultSlotContent","slot","insertSlotContent","element","titleSection","introCard","slotName","renderer","slotElement","applyFullHeightStyles","sidebarMode","fullHeight","theme","position","isLeftSidebar","defaultPanelBorder","defaultPanelShadow","defaultPanelBorderRadius","panelBorder","panelShadow","panelBorderRadius","launcherWidth","width","isInlineEmbed","positionMap","cls","sidebarWidth","maxHeightStyles","paddingStyles","applyThemeVariables","destroyCallbacks","cleanupThemeObserver","setupThemeObserver","createThemeObserver","suggestionsManager","createSuggestions","closeHandler","isStreaming","shouldAutoScroll","lastScrollTop","lastAutoScrollTime","scrollRAF","isAutoScrollBlocked","blockUntilTime","isAutoScrolling","AUTO_SCROLL_THROTTLE","AUTO_SCROLL_BLOCK_TIME","USER_SCROLL_THRESHOLD","BOTTOM_THRESHOLD","messageState","voiceState","voiceAutoResumeMode","emitVoiceState","source","persistVoiceMetadata","prev","maybeRestoreVoiceFromMetadata","rawVoiceState","wasActive","timestamp","startVoiceRecognition","getMessagesForPersistence","msg","messagesOverride","payload","result","scheduleAutoScroll","force","now","smoothScrollRAF","getScrollableContainer","smoothScrollToBottom","duration","start","clientHeight","target","distance","startTime","easeOutCubic","t","animate","currentTime","currentTarget","elapsed","progress","eased","currentScroll","trackMessages","nextState","previous","key","renderMessagesWithPlugins","transform","tempContainer","bubble","matchingPlugin","messageLayoutConfig","createReasoningBubble","createToolBubble","b","createStandardBubble","enhanceWithForms","hasComponentDirective","directive","extractComponentDirectiveFromMessage","componentBubble","renderComponentDirective","componentWrapper","textDiv","hasStreamingAssistantMessage","lastMessage","hasRecentAssistantResponse","typingIndicator","createTypingIndicator","typingBubble","typingWrapper","morphMessages","scrollableContainer","updateOpenState","launcherButtonInstance","customLauncherElement","nextOpen","prevOpen","recalcPanelHeight","stateEvent","setComposerDisabled","disabled","btn","updateCopy","fontFamily","fontWeight","getFontFamilyValue","family","AgentWidgetSession","lastUserMessage","currentStatusConfig","getCurrentStatusText","streaming","state","handleSubmit","event","handleInputEnter","speechRecognition","isRecording","pauseTimer","originalMicStyles","getSpeechRecognitionClass","SpeechRecognitionClass","pauseDuration","initialText","fullTranscript","interimTranscript","i","transcript","newValue","finalValue","stopVoiceRecognition","voiceConfig","recordingBackgroundColor","recordingIconColor","recordingBorderColor","svg","createMicButton","sendButtonConfig","createElement","micIconName","buttonSize","micIconSize","micIconSizeNum","backgroundColor","iconColor","iconColorValue","micIconSvg","renderLucideIcon","tooltipText","tooltip","handleMicButtonClick","autoResumeUnsub","toggleOpen","launcherPlugin","customLauncher","createLauncherButton","viewportHeight","verticalMargin","heightOffset","available","clamped","finalHeight","handleScroll","scrollTop","scrollHeight","distanceFromBottom","delta","refreshCloseButton","clearChatButton","clearEvent","controller","nextConfig","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z","_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","__","_$","_aa","_ba","_ca","_da","_ea","_fa","_ga","_ha","_ia","_ja","_ka","_la","_ma","_na","previousToolCallConfig","previousColorScheme","newPlugins","headerLayoutConfig","newHeaderElements","buildHeaderWithLayout","showClearChat","closeButtonWrapper","launcher","headerIconHidden","layoutShowIcon","shouldHideIcon","headerIconName","headerIconSize","headerEl","headerCopy","iconSize","iconSvg","img","newImg","existingSvg","existingImg","layoutShowTitle","layoutShowSubtitle","closeButtonSize","closeButtonPlacement","isTopRight","currentlyTopRight","clearChatPlacement","clearChatEnabled","borderWidth","borderColor","closeButtonIconName","closeButtonIconText","closeButtonTooltipText","closeButtonShowTooltip","portaledTooltip","showTooltip","arrow","buttonRect","hideTooltip","clearChatButtonWrapper","clearChatConfig","layoutShowClearChat","shouldShowClearChat","closeButtonWrapperEl","clearChatSize","clearChatIconName","clearChatIconColor","clearChatTooltipText","clearChatShowTooltip","nextParsers","nextHandlers","voiceRecognitionEnabled","hasSpeechRecognition","shouldUseSmallGap","micButtonResult","newTooltip","useIcon","iconText","iconName","textColor","statusIndicatorConfig","isVisible","currentStatus","valueToSubmit","handler","options","existingFeedback","feedbackEl","createCSATFeedback","rating","comment","createNPSFeedback","cb","previousDebug","debugApi","active","import_meta","ensureTarget","target","element","widgetCssHref","mountStyles","root","href","adoptExistingStylesheet","globalLink","clonedLink","link","initAgentWidget","options","_a","_b","_c","_d","host","launcherEnabled","useShadow","mount","shadowRoot","controller","createAgentExperience","handle","detectParserTypeFromStreamParser","streamParser","fnString","getParserTypeFromConfig","config","_a","_b","generateToolCallConfig","indent","lines","key","value","generateMessageActionsConfig","generateMarkdownConfig","hasOptions","hasDisableDefaultStyles","generateLayoutConfig","hasHeader","hasMessages","avatarKey","avatarValue","k","tsKey","tsValue","generateCodeSnippet","format","cleanConfig","generateESMCode","generateScriptInstallerCode","generateScriptAdvancedCode","generateReactComponentCode","generateReactAdvancedCode","generateScriptManualCode","parserType","shouldEmitParserType","chip","buildSerializableConfig","serializableConfig","toolCallConfig","messageActionsConfig","markdownConfig","layoutConfig","headerConfig","messagesConfig","tsConfig","line","i","index_default","initAgentWidget"]}
|