vanilla-agent 0.2.0 → 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/postprocessors.ts","../src/client.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/panel.ts","../src/components/message-bubble.ts","../src/utils/formatting.ts","../src/components/reasoning-bubble.ts","../src/components/tool-bubble.ts","../src/components/suggestions.ts","../src/components/forms.ts","../src/plugins/registry.ts","../src/ui.ts","../src/runtime/init.ts"],"sourcesContent":["import {\n initChatWidget as initChatWidgetFn,\n type ChatWidgetInitHandle\n} from \"./runtime/init\";\n\nexport type {\n ChatWidgetConfig,\n ChatWidgetTheme,\n ChatWidgetFeatureFlags,\n ChatWidgetInitOptions,\n ChatWidgetMessage,\n ChatWidgetLauncherConfig,\n ChatWidgetEvent\n} from \"./types\";\n\nexport { initChatWidgetFn as initChatWidget };\nexport {\n createChatExperience,\n type ChatWidgetController\n} from \"./ui\";\nexport {\n ChatWidgetSession,\n type ChatWidgetSessionStatus\n} from \"./session\";\nexport { ChatWidgetClient } from \"./client\";\nexport {\n markdownPostprocessor,\n escapeHtml,\n directivePostprocessor\n} from \"./postprocessors\";\nexport type { ChatWidgetInitHandle };\n\n// Plugin system exports\nexport type { ChatWidgetPlugin } from \"./plugins/types\";\nexport { pluginRegistry } from \"./plugins/registry\";\n\nexport default initChatWidgetFn;\n","import { marked } from \"marked\";\n\nmarked.setOptions({ breaks: true });\n\n/**\n * Basic markdown renderer. Remember to sanitize the returned HTML if you render\n * untrusted content in your host page.\n */\nexport const markdownPostprocessor = (text: string): string => {\n return marked.parse(text) as string;\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, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n\nconst escapeAttribute = (value: string) =>\n value.replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\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 * 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.\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 { ChatWidgetConfig, ChatWidgetMessage, ChatWidgetEvent } from \"./types\";\n\ntype DispatchOptions = {\n messages: ChatWidgetMessage[];\n signal?: AbortSignal;\n};\n\ntype SSEHandler = (event: ChatWidgetEvent) => void;\n\nconst DEFAULT_ENDPOINT = \"https://api.travrse.ai/v1/dispatch\";\n\nexport class ChatWidgetClient {\n private readonly apiUrl: string;\n private readonly headers: Record<string, string>;\n private readonly debug: boolean;\n\n constructor(private config: ChatWidgetConfig = {}) {\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 }\n\n public async dispatch(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 // Build simplified payload with just messages and optional flowId\n // Sort by createdAt to ensure chronological order (not local sequence)\n const body = {\n messages: options.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.content,\n createdAt: message.createdAt\n })),\n ...(this.config.flowId && { flowId: this.config.flowId })\n };\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[ChatWidgetClient] dispatch body\", body);\n }\n\n const response = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(body),\n signal: controller.signal\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 streamResponse(\n body: ReadableStream<Uint8Array>,\n onEvent: SSEHandler\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: ChatWidgetMessage): ChatWidgetMessage => {\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: ChatWidgetMessage) => {\n onEvent({\n type: \"message\",\n message: cloneMessage(msg)\n });\n };\n\n let assistantMessage: ChatWidgetMessage | null = null;\n const reasoningMessages = new Map<string, ChatWidgetMessage>();\n const toolMessages = new Map<string, ChatWidgetMessage>();\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 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 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: ChatWidgetMessage = {\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: ChatWidgetMessage = {\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 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 (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 const assistant = ensureAssistantMessage();\n const chunk = payload.text ?? payload.delta ?? payload.content ?? \"\";\n if (chunk) {\n assistant.content += chunk;\n emitMessage(assistant);\n }\n if (payload.isComplete) {\n const finalContent = payload.result?.response ?? assistant.content;\n if (finalContent) {\n assistant.content = finalContent;\n assistant.streaming = false;\n emitMessage(assistant);\n }\n }\n } else if (payloadType === \"step_complete\") {\n const finalContent = payload.result?.response;\n const assistant = ensureAssistantMessage();\n if (finalContent) {\n assistant.content = finalContent;\n assistant.streaming = false;\n emitMessage(assistant);\n } else {\n // No final content, just mark as complete\n assistant.streaming = false;\n emitMessage(assistant);\n }\n } else if (payloadType === \"flow_complete\") {\n const finalContent = payload.result?.response;\n if (finalContent) {\n const assistant = ensureAssistantMessage();\n if (finalContent !== assistant.content) {\n assistant.content = finalContent;\n emitMessage(assistant);\n }\n assistant.streaming = false;\n emitMessage(assistant);\n } else {\n const existingAssistant = assistantMessage;\n if (existingAssistant) {\n const assistantFinal = existingAssistant as ChatWidgetMessage;\n assistantFinal.streaming = false;\n emitMessage(assistantFinal);\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","import { ChatWidgetClient } from \"./client\";\nimport {\n ChatWidgetConfig,\n ChatWidgetEvent,\n ChatWidgetMessage\n} from \"./types\";\n\nexport type ChatWidgetSessionStatus =\n | \"idle\"\n | \"connecting\"\n | \"connected\"\n | \"error\";\n\ntype SessionCallbacks = {\n onMessagesChanged: (messages: ChatWidgetMessage[]) => void;\n onStatusChanged: (status: ChatWidgetSessionStatus) => void;\n onStreamingChanged: (streaming: boolean) => void;\n onError?: (error: Error) => void;\n};\n\nexport class ChatWidgetSession {\n private client: ChatWidgetClient;\n private messages: ChatWidgetMessage[];\n private status: ChatWidgetSessionStatus = \"idle\";\n private streaming = false;\n private abortController: AbortController | null = null;\n private sequenceCounter = Date.now();\n\n constructor(\n private config: ChatWidgetConfig = {},\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 ChatWidgetClient(config);\n\n if (this.messages.length) {\n this.callbacks.onMessagesChanged([...this.messages]);\n }\n this.callbacks.onStatusChanged(this.status);\n }\n\n public updateConfig(next: ChatWidgetConfig) {\n this.config = { ...this.config, ...next };\n this.client = new ChatWidgetClient(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 async sendMessage(rawInput: string) {\n const input = rawInput.trim();\n if (!input) return;\n\n this.abortController?.abort();\n\n const userMessage: ChatWidgetMessage = {\n id: `user-${Date.now()}`,\n role: \"user\",\n content: input,\n createdAt: new Date().toISOString(),\n sequence: this.nextSequence()\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 },\n this.handleEvent\n );\n } catch (error) {\n const fallback: ChatWidgetMessage = {\n id: `assistant-${Date.now()}`,\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 private handleEvent = (event: ChatWidgetEvent) => {\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: ChatWidgetSessionStatus) {\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: ChatWidgetMessage) {\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: ChatWidgetMessage) {\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: ChatWidgetMessage): ChatWidgetMessage {\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: ChatWidgetMessage[]) {\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 { ChatWidgetConfig } from \"../types\";\n\nexport const applyThemeVariables = (\n element: HTMLElement,\n config?: ChatWidgetConfig\n) => {\n const theme = config?.theme ?? {};\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","import { 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","import { ChatWidgetSessionStatus } from \"../session\";\n\nexport const statusCopy: Record<ChatWidgetSessionStatus, string> = {\n idle: \"Online\",\n connecting: \"Connecting…\",\n connected: \"Streaming…\",\n error: \"Offline\"\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","import { createElement } from \"../utils/dom\";\nimport { ChatWidgetConfig } from \"../types\";\nimport { positionMap } from \"../utils/positioning\";\nimport { renderLucideIcon } from \"../utils/icons\";\n\nexport interface LauncherButton {\n element: HTMLButtonElement;\n update: (config: ChatWidgetConfig) => void;\n destroy: () => void;\n}\n\nexport const createLauncherButton = (\n config: ChatWidgetConfig | 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: ChatWidgetConfig) => {\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 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-shadow-lg tvw-border tvw-border-gray-200 tvw-transition hover:tvw-translate-y-[-2px] tvw-cursor-pointer\";\n\n button.className = `${base} ${positionClass}`;\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 { ChatWidgetConfig } from \"../types\";\nimport { positionMap } from \"../utils/positioning\";\n\nexport interface PanelWrapper {\n wrapper: HTMLElement;\n panel: HTMLElement;\n}\n\nexport const createWrapper = (config?: ChatWidgetConfig): PanelWrapper => {\n const launcherEnabled = config?.launcher?.enabled ?? true;\n\n if (!launcherEnabled) {\n const wrapper = createElement(\n \"div\",\n \"tvw-relative tvw-w-full tvw-h-full\"\n );\n const panel = createElement(\n \"div\",\n \"tvw-relative tvw-w-full tvw-h-full tvw-min-h-[360px]\"\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-fixed ${position} tvw-z-50 tvw-transition`\n );\n\n const panel = createElement(\n \"div\",\n \"tvw-relative tvw-min-h-[320px]\"\n );\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(360px, 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 iconHolder: HTMLElement;\n}\n\nexport const buildPanel = (config?: ChatWidgetConfig, showClose = true): PanelElements => {\n const container = createElement(\n \"div\",\n \"tvw-flex tvw-h-full tvw-w-full tvw-flex-col tvw-bg-cw-surface tvw-text-cw-primary tvw-rounded-2xl tvw-overflow-hidden tvw-shadow-2xl tvw-border tvw-border-cw-border\"\n );\n\n const header = createElement(\n \"div\",\n \"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(\n \"span\",\n \"tvw-text-base tvw-font-semibold\"\n );\n title.textContent =\n config?.launcher?.title ?? \"Chat Assistant\";\n const subtitle = createElement(\n \"span\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\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 close button with base classes\n const closeButton = createElement(\n \"button\",\n closeButtonPlacement === \"top-right\"\n ? \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50 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 : \"tvw-ml-auto 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.textContent = \"×\";\n closeButton.style.display = showClose ? \"\" : \"none\";\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 // Position close button based on placement\n if (closeButtonPlacement === \"top-right\") {\n // Make container position relative for absolute positioning\n container.style.position = \"relative\";\n container.appendChild(closeButton);\n } else {\n // Inline placement: append to header\n header.appendChild(closeButton);\n }\n\n const body = createElement(\n \"div\",\n \"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 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 const footer = createElement(\n \"div\",\n \"tvw-border-t-cw-divider tvw-bg-cw-surface tvw-px-6 tvw-py-4\"\n );\n const suggestions = createElement(\n \"div\",\n \"tvw-mb-3 tvw-flex tvw-flex-wrap tvw-gap-2\"\n );\n // Determine gap based on voice recognition\n const voiceRecognitionEnabledForGap = 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 = voiceRecognitionEnabledForGap && hasSpeechRecognitionForGap;\n const gapClass = shouldUseSmallGap ? \"tvw-gap-1\" : \"tvw-gap-3\";\n \n const composerForm = createElement(\n \"form\",\n `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 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 // 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 // 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 = 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 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 = 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(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 (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 tooltipText = voiceRecognitionConfig.tooltipText ?? \"Start voice recognition\";\n const showTooltip = voiceRecognitionConfig.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 \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 (e.target !== sendButton && e.target !== sendButtonWrapper && \n e.target !== micButton && e.target !== micButtonWrapper) {\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 container.append(header, body, footer);\n\n return {\n container,\n body,\n messagesWrapper,\n suggestions,\n textarea,\n sendButton,\n sendButtonWrapper,\n micButton,\n micButtonWrapper,\n composerForm,\n statusText,\n introTitle,\n introSubtitle,\n closeButton,\n iconHolder\n };\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { ChatWidgetMessage } from \"../types\";\n\nexport type MessageTransform = (context: {\n text: string;\n message: ChatWidgetMessage;\n streaming: boolean;\n}) => string;\n\nexport const createStandardBubble = (\n message: ChatWidgetMessage,\n transform: MessageTransform\n): HTMLElement => {\n const classes = [\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\",\n \"tvw-shadow-sm\"\n ];\n\n if (message.role === \"user\") {\n classes.push(\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 classes.push(\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\n const bubble = createElement(\"div\", classes.join(\" \"));\n bubble.innerHTML = transform({\n text: message.content,\n message,\n streaming: Boolean(message.streaming)\n });\n\n return bubble;\n};\n\n\n\n","import { ChatWidgetReasoning, ChatWidgetToolCall } from \"../types\";\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: ChatWidgetReasoning) => {\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: ChatWidgetReasoning) => {\n if (reasoning.status === \"complete\") return formatReasoningDuration(reasoning);\n if (reasoning.status === \"pending\") return \"Waiting\";\n return \"\";\n};\n\nexport const formatToolDuration = (tool: ChatWidgetToolCall) => {\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: ChatWidgetToolCall[\"status\"]) => {\n if (status === \"complete\") return \"\";\n if (status === \"pending\") return \"Starting\";\n return \"Running\";\n};\n\nexport const describeToolTitle = (tool: ChatWidgetToolCall) => {\n if (tool.status === \"complete\") {\n return formatToolDuration(tool);\n }\n return \"Using tool...\";\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { ChatWidgetMessage } from \"../types\";\nimport { describeReasonStatus } from \"../utils/formatting\";\n\n// Expansion state per widget instance\nconst reasoningExpansionState = new Set<string>();\n\nexport const createReasoningBubble = (message: ChatWidgetMessage): HTMLElement => {\n const reasoning = message.reasoning;\n const bubble = createElement(\n \"div\",\n [\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-font-semibold 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 toggleLabel = createElement(\n \"span\",\n \"tvw-text-xs tvw-text-cw-primary\"\n );\n toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\n\n header.append(headerContent, toggleLabel);\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 toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\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 { ChatWidgetMessage } from \"../types\";\nimport { formatUnknownValue, describeToolTitle } from \"../utils/formatting\";\n\n// Expansion state per widget instance\nconst toolExpansionState = new Set<string>();\n\nexport const createToolBubble = (message: ChatWidgetMessage): HTMLElement => {\n const tool = message.toolCall;\n const bubble = createElement(\n \"div\",\n [\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 (!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 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 = describeToolTitle(tool);\n headerContent.appendChild(title);\n\n if (tool.name) {\n const name = createElement(\"span\", \"tvw-text-[11px] tvw-text-cw-muted\");\n name.textContent = tool.name;\n headerContent.appendChild(name);\n }\n\n const toggleLabel = createElement(\n \"span\",\n \"tvw-text-xs tvw-text-cw-primary\"\n );\n toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\n\n const headerMeta = createElement(\"div\", \"tvw-flex tvw-items-center tvw-gap-2\");\n headerMeta.append(toggleLabel);\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 if (tool.args !== undefined) {\n const argsBlock = createElement(\"div\", \"tvw-space-y-1\");\n const argsLabel = createElement(\n \"div\",\n \"tvw-font-xxs tvw-font-medium tvw-text-cw-muted\"\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-font-xxs tvw-text-cw-primary\"\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-font-xxs tvw-font-medium tvw-text-cw-muted\"\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-font-xxs tvw-text-cw-primary\"\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-font-xxs tvw-text-sm tvw-text-cw-muted\"\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-font-xxs tvw-text-cw-primary\"\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-font-xxs tvw-text-cw-muted\"\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 toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\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 { ChatWidgetSession } from \"../session\";\nimport { ChatWidgetMessage } from \"../types\";\n\nexport interface SuggestionButtons {\n buttons: HTMLButtonElement[];\n render: (chips: string[] | undefined, session: ChatWidgetSession, textarea: HTMLTextAreaElement, messages?: ChatWidgetMessage[]) => void;\n}\n\nexport const createSuggestions = (container: HTMLElement): SuggestionButtons => {\n const suggestionButtons: HTMLButtonElement[] = [];\n\n const render = (chips: string[] | undefined, session: ChatWidgetSession, textarea: HTMLTextAreaElement, messages?: ChatWidgetMessage[]) => {\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 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 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 { ChatWidgetMessage, ChatWidgetConfig } from \"../types\";\nimport { ChatWidgetSession } 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: ChatWidgetMessage,\n config: ChatWidgetConfig,\n session: ChatWidgetSession\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","import { ChatWidgetPlugin } from \"./types\";\n\nclass PluginRegistry {\n private plugins: Map<string, ChatWidgetPlugin> = new Map();\n\n /**\n * Register a plugin\n */\n register(plugin: ChatWidgetPlugin): 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(): ChatWidgetPlugin[] {\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?: ChatWidgetPlugin[]): ChatWidgetPlugin[] {\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","import { escapeHtml } from \"./postprocessors\";\nimport { ChatWidgetSession, ChatWidgetSessionStatus } from \"./session\";\nimport { ChatWidgetConfig, ChatWidgetMessage } from \"./types\";\nimport { applyThemeVariables } 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 } from \"./components/panel\";\nimport { MessageTransform } from \"./components/message-bubble\";\nimport { createStandardBubble } 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\";\n\ntype Controller = {\n update: (config: ChatWidgetConfig) => void;\n destroy: () => void;\n open: () => void;\n close: () => void;\n toggle: () => void;\n};\n\nconst buildPostprocessor = (cfg?: ChatWidgetConfig): MessageTransform => {\n if (cfg?.postprocessMessage) {\n return (context) =>\n cfg.postprocessMessage!({\n text: context.text,\n message: context.message,\n streaming: context.streaming\n });\n }\n return ({ text }) => escapeHtml(text);\n};\n\nexport const createChatExperience = (\n mount: HTMLElement,\n initialConfig?: ChatWidgetConfig\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 = { ...initialConfig };\n applyThemeVariables(mount, config);\n\n // Get plugins for this instance\n const plugins = pluginRegistry.getForInstance(config.plugins);\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);\n let showReasoning = config.features?.showReasoning ?? true;\n let showToolCalls = config.features?.showToolCalls ?? true;\n \n // Get status indicator config\n const statusConfig = config.statusIndicator ?? {};\n const getStatusText = (status: ChatWidgetSessionStatus): 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 const {\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 } = 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 panel.appendChild(container);\n mount.appendChild(wrapper);\n\n const destroyCallbacks: Array<() => void> = [];\n const suggestionsManager = createSuggestions(suggestions);\n let closeHandler: (() => void) | null = null;\n let session: ChatWidgetSession;\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\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 // Create typing indicator element\n const createTypingIndicator = (): HTMLElement => {\n const container = document.createElement(\"div\");\n container.className = \"tvw-flex tvw-items-center tvw-space-x-1 tvw-h-5\";\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 // Message rendering with plugin support\n const renderMessagesWithPlugins = (\n container: HTMLElement,\n messages: ChatWidgetMessage[],\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 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),\n config\n });\n } else if (matchingPlugin.renderMessage) {\n bubble = matchingPlugin.renderMessage({\n message,\n defaultRenderer: () => {\n const b = createStandardBubble(message, transform);\n if (message.role !== \"user\") {\n enhanceWithForms(b, message, config, session);\n }\n return b;\n },\n config\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);\n } else {\n bubble = createStandardBubble(message, transform);\n if (message.role !== \"user\") {\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 typing indicator if streaming and there's at least one user message\n if (isStreaming && messages.some((msg) => msg.role === \"user\")) {\n const typingIndicator = createTypingIndicator();\n const typingWrapper = document.createElement(\"div\");\n typingWrapper.className = \"tvw-flex tvw-justify-end\";\n typingWrapper.appendChild(typingIndicator);\n fragment.appendChild(typingWrapper);\n }\n\n container.appendChild(fragment);\n container.scrollTop = container.scrollHeight;\n };\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 }\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 }\n }\n };\n\n const setOpenState = (nextOpen: boolean) => {\n if (!launcherEnabled) return;\n if (open === nextOpen) return;\n open = nextOpen;\n updateOpenState();\n if (open) {\n recalcPanelHeight();\n scheduleAutoScroll(true);\n }\n };\n\n const setComposerDisabled = (disabled: boolean) => {\n textarea.disabled = disabled;\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 ?? \"Type your message…\";\n sendButton.textContent = config.copy?.sendButtonLabel ?? \"Send\";\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 ChatWidgetSession(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);\n }\n }\n scheduleAutoScroll(!isStreaming);\n },\n onStatusChanged(status) {\n const currentStatusConfig = config.statusIndicator ?? {};\n const getCurrentStatusText = (status: ChatWidgetSessionStatus): 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 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 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);\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);\n }\n stopVoiceRecognition();\n }\n };\n\n try {\n speechRecognition.start();\n isRecording = true;\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();\n }\n };\n\n const stopVoiceRecognition = () => {\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 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: ChatWidgetConfig['voiceRecognition'], sendButtonConfig: ChatWidgetConfig['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 stopVoiceRecognition();\n if (finalValue) {\n textarea.value = \"\";\n session.sendMessage(finalValue);\n }\n } else {\n // Start recording\n startVoiceRecognition();\n }\n };\n\n if (micButton) {\n micButton.addEventListener(\"click\", handleMicButtonClick);\n\n destroyCallbacks.push(() => {\n stopVoiceRecognition();\n if (micButton) {\n micButton.removeEventListener(\"click\", handleMicButtonClick);\n }\n });\n }\n\n const toggleOpen = () => {\n setOpenState(!open);\n };\n\n let launcherButtonInstance = launcherEnabled\n ? createLauncherButton(config, toggleOpen)\n : null;\n\n if (launcherButtonInstance) {\n mount.appendChild(launcherButtonInstance.element);\n }\n updateOpenState();\n suggestionsManager.render(config.suggestionChips, session, textarea);\n updateCopy();\n setComposerDisabled(session.isStreaming());\n scheduleAutoScroll(true);\n\n const recalcPanelHeight = () => {\n if (!launcherEnabled) {\n panel.style.height = \"\";\n panel.style.width = \"\";\n return;\n }\n const launcherWidth = config?.launcher?.width ?? config?.launcherWidth;\n const width = launcherWidth ?? \"min(360px, calc(100vw - 24px))\";\n panel.style.width = width;\n panel.style.maxWidth = width;\n const viewportHeight = window.innerHeight;\n const verticalMargin = 64; // leave space for launcher's offset\n const available = Math.max(200, viewportHeight - verticalMargin);\n const clamped = Math.min(640, available);\n panel.style.height = `${clamped}px`;\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 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 }\n\n return {\n update(nextConfig: ChatWidgetConfig) {\n config = { ...config, ...nextConfig };\n applyThemeVariables(mount, config);\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\n if (config.launcher?.enabled !== false && !launcherButtonInstance) {\n launcherButtonInstance = createLauncherButton(config, toggleOpen);\n mount.appendChild(launcherButtonInstance.element);\n }\n\n if (launcherButtonInstance) {\n launcherButtonInstance.update(config);\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);\n }\n } else if (autoExpandChanged) {\n // autoExpand value changed - update state to match\n setOpenState(autoExpand);\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 // 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\n const isTopRight = closeButtonPlacement === \"top-right\";\n const hasTopRightClasses = closeButton.classList.contains(\"tvw-absolute\");\n \n if (isTopRight !== hasTopRightClasses) {\n // Placement changed - need to move button and update classes\n closeButton.remove();\n \n // Update classes\n if (isTopRight) {\n closeButton.className = \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50 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 container.style.position = \"relative\";\n container.appendChild(closeButton);\n } else {\n closeButton.className = \"tvw-ml-auto 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 // Find header element (first child of container)\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n if (header) {\n header.appendChild(closeButton);\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\n postprocess = buildPostprocessor(config);\n session.updateConfig(config);\n renderMessagesWithPlugins(\n messagesWrapper,\n session.getMessages(),\n postprocess\n );\n suggestionsManager.render(config.suggestionChips, session, textarea);\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: ChatWidgetSessionStatus): 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);\n },\n close() {\n if (!launcherEnabled) return;\n setOpenState(false);\n },\n toggle() {\n if (!launcherEnabled) return;\n setOpenState(!open);\n },\n destroy() {\n destroyCallbacks.forEach((cb) => cb());\n wrapper.remove();\n launcherButtonInstance?.destroy();\n if (closeHandler) {\n closeButton.removeEventListener(\"click\", closeHandler);\n }\n }\n };\n};\n\nexport type ChatWidgetController = Controller;\n","import { createChatExperience, ChatWidgetController } from \"../ui\";\nimport { ChatWidgetConfig, ChatWidgetInitOptions } 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 ChatWidgetInitHandle = ChatWidgetController & { host: HTMLElement };\n\nexport const initChatWidget = (\n options: ChatWidgetInitOptions\n): ChatWidgetInitHandle => {\n const target = ensureTarget(options.target);\n const host = document.createElement(\"div\");\n host.className = \"vanilla-agent-host\";\n target.appendChild(host);\n\n const useShadow = options.useShadowDom !== false;\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 shadowRoot.appendChild(mount);\n mountStyles(shadowRoot);\n } else {\n root = host;\n mount = document.createElement(\"div\");\n mount.id = \"vanilla-agent-root\";\n host.appendChild(mount);\n mountStyles(host);\n }\n\n let controller = createChatExperience(mount, options.config);\n options.onReady?.();\n\n return {\n host,\n update(nextConfig: ChatWidgetConfig) {\n controller.update(nextConfig);\n },\n open() {\n controller.open();\n },\n close() {\n controller.close();\n },\n toggle() {\n controller.toggle();\n },\n destroy() {\n controller.destroy();\n host.remove();\n }\n };\n};\n"],"mappings":"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","names":["index_exports","__export","ChatWidgetClient","ChatWidgetSession","createChatExperience","index_default","directivePostprocessor","escapeHtml","initChatWidget","markdownPostprocessor","pluginRegistry","__toCommonJS","import_marked","markdownPostprocessor","text","escapeHtml","escapeAttribute","value","makeToken","idx","directiveReplacer","source","placeholders","working","match","jsonText","parsed","token","_","type","directivePostprocessor","withTokens","html","tokenRegex","replacement","DEFAULT_ENDPOINT","ChatWidgetClient","config","_a","options","onEvent","controller","body","b","timeA","timeB","message","response","error","_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","_G","_H","_I","_J","_K","_L","_M","_N","_O","_P","_Q","_R","_S","_T","_U","_V","_W","reader","decoder","buffer","baseSequence","sequenceCounter","nextSequence","cloneMessage","msg","reasoning","toolCall","tools","tool","emitMessage","assistantMessage","reasoningMessages","toolMessages","reasoningContext","toolContext","normalizeKey","value","getStepKey","payload","getToolCallKey","ensureAssistantMessage","trackReasoningId","stepKey","id","resolveReasoningId","allowCreate","rawId","resolved","existing","generated","ensureReasoningMessage","reasoningId","trackToolId","callKey","resolveToolId","ensureToolMessage","toolId","resolveTimestamp","parsed","dateParsed","done","events","event","lines","eventType","data","line","payloadType","reasoningMessage","chunk","start","toolMessage","chunkText","assistant","finalContent","existingAssistant","assistantFinal","ChatWidgetSession","config","callbacks","event","_a","_b","message","ChatWidgetClient","next","rawInput","_c","_d","_e","input","userMessage","controller","snapshot","error","fallback","status","streaming","withSequence","index","m","existing","idx","messages","a","b","timeA","timeB","seqA","seqB","applyThemeVariables","element","config","_a","theme","key","value","kebabKey","letter","import_lucide","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","launcher","titleEl","subtitleEl","textContainer","icon","iconSize","iconSizeNum","iconSvg","renderLucideIcon","img","callToActionIconEl","callToActionIconSize","paddingTotal","containerSize","positionClass","positionMap","base","destroy","createWrapper","config","_a","_b","_c","_d","_e","wrapper","createElement","panel","launcher","position","positionMap","launcherWidth","width","buildPanel","showClose","_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","container","header","headerIconSize","closeButtonSize","closeButtonPlacement","headerIconHidden","headerIconName","iconHolder","iconSize","iconSvg","renderLucideIcon","img","headerCopy","title","subtitle","closeButton","borderWidth","borderColor","body","introCard","introTitle","introSubtitle","messagesWrapper","footer","suggestions","voiceRecognitionEnabledForGap","hasSpeechRecognitionForGap","composerForm","textarea","fontFamily","fontWeight","getFontFamilyValue","family","sendButtonConfig","useIcon","iconText","iconName","tooltipText","showTooltip","buttonSize","backgroundColor","textColor","sendButtonWrapper","sendButton","iconColor","tooltip","voiceRecognitionConfig","voiceRecognitionEnabled","micButton","micButtonWrapper","hasSpeechRecognition","micIconName","micIconSize","micIconSizeNum","micBackgroundColor","micIconColor","iconColorValue","micIconSvg","e","statusText","statusConfig","isVisible","createStandardBubble","message","transform","classes","bubble","createElement","formatUnknownValue","value","formatReasoningDuration","reasoning","_a","_b","end","start","seconds","describeReasonStatus","formatToolDuration","tool","_c","describeToolTitle","tool","formatToolDuration","reasoningExpansionState","createReasoningBubble","message","reasoning","bubble","createElement","expanded","header","headerContent","title","status","describeReasonStatus","toggleLabel","content","text","body","applyExpansionState","toggleExpansion","event","toolExpansionState","createToolBubble","message","tool","bubble","createElement","expanded","header","headerContent","title","describeToolTitle","name","toggleLabel","headerMeta","content","argsBlock","argsLabel","argsPre","formatUnknownValue","logsBlock","logsLabel","logsPre","resultBlock","resultLabel","resultPre","duration","applyToolExpansion","toggleToolExpansion","event","createSuggestions","container","suggestionButtons","chips","session","textarea","messages","msg","fragment","streaming","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","buildPostprocessor","cfg","context","text","escapeHtml","createChatExperience","mount","initialConfig","_a","_b","_c","_d","_e","_f","_g","_h","_i","config","applyThemeVariables","plugins","pluginRegistry","launcherEnabled","autoExpand","prevAutoExpand","prevLauncherEnabled","open","postprocess","showReasoning","showToolCalls","statusConfig","getStatusText","status","statusCopy","wrapper","panel","createWrapper","panelElements","buildPanel","container","body","messagesWrapper","suggestions","textarea","sendButton","sendButtonWrapper","composerForm","statusText","introTitle","introSubtitle","closeButton","iconHolder","micButton","micButtonWrapper","destroyCallbacks","suggestionsManager","createSuggestions","closeHandler","session","isStreaming","shouldAutoScroll","lastScrollTop","lastAutoScrollTime","scrollRAF","isAutoScrollBlocked","blockUntilTime","isAutoScrolling","AUTO_SCROLL_THROTTLE","AUTO_SCROLL_BLOCK_TIME","USER_SCROLL_THRESHOLD","BOTTOM_THRESHOLD","scheduleAutoScroll","force","now","createTypingIndicator","dot1","dot2","dot3","srOnly","renderMessagesWithPlugins","messages","transform","fragment","message","bubble","matchingPlugin","p","createReasoningBubble","createToolBubble","b","createStandardBubble","enhanceWithForms","msg","typingIndicator","typingWrapper","updateOpenState","launcherButtonInstance","setOpenState","nextOpen","recalcPanelHeight","setComposerDisabled","disabled","btn","updateCopy","_j","_k","_l","fontFamily","fontWeight","getFontFamilyValue","family","ChatWidgetSession","currentStatusConfig","getCurrentStatusText","streaming","handleSubmit","event","value","handleInputEnter","speechRecognition","isRecording","pauseTimer","originalMicStyles","getSpeechRecognitionClass","startVoiceRecognition","SpeechRecognitionClass","pauseDuration","initialText","fullTranscript","interimTranscript","i","result","transcript","newValue","finalValue","stopVoiceRecognition","voiceConfig","recordingBackgroundColor","recordingIconColor","recordingBorderColor","svg","createMicButton","sendButtonConfig","createElement","micIconName","buttonSize","micIconSize","micIconSizeNum","backgroundColor","iconColor","iconColorValue","micIconSvg","renderLucideIcon","tooltipText","tooltip","handleMicButtonClick","toggleOpen","createLauncherButton","launcherWidth","width","viewportHeight","available","clamped","handleScroll","scrollTop","scrollHeight","clientHeight","distanceFromBottom","delta","refreshCloseButton","nextConfig","_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","newPlugins","launcher","headerIconHidden","headerIconName","headerIconSize","header","headerCopy","iconSize","iconSvg","img","newImg","existingSvg","existingImg","closeButtonSize","closeButtonPlacement","isTopRight","hasTopRightClasses","borderWidth","borderColor","voiceRecognitionEnabled","hasSpeechRecognition","shouldUseSmallGap","micButtonResult","newTooltip","useIcon","iconText","iconName","showTooltip","textColor","statusIndicatorConfig","isVisible","currentStatus","cb","import_meta","ensureTarget","target","element","widgetCssHref","mountStyles","root","href","adoptExistingStylesheet","globalLink","clonedLink","link","initChatWidget","options","_a","host","useShadow","mount","shadowRoot","controller","createChatExperience","nextConfig","index_default","initChatWidget"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/postprocessors.ts","../src/client.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/panel.ts","../src/components/message-bubble.ts","../src/utils/formatting.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/ui.ts","../src/runtime/init.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} 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 {\n markdownPostprocessor,\n escapeHtml,\n directivePostprocessor\n} from \"./postprocessors\";\nexport type { AgentWidgetInitHandle };\n\n// Plugin system exports\nexport type { AgentWidgetPlugin } from \"./plugins/types\";\nexport { pluginRegistry } from \"./plugins/registry\";\n\n// Default configuration exports\nexport { DEFAULT_WIDGET_CONFIG, mergeWithDefaults } from \"./defaults\";\n\nexport default initAgentWidgetFn;\n","import { marked } from \"marked\";\n\nmarked.setOptions({ breaks: true });\n\n/**\n * Basic markdown renderer. Remember to sanitize the returned HTML if you render\n * untrusted content in your host page.\n */\nexport const markdownPostprocessor = (text: string): string => {\n return marked.parse(text) as string;\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, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n\nconst escapeAttribute = (value: string) =>\n value.replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\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 * 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.\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 { AgentWidgetConfig, AgentWidgetMessage, AgentWidgetEvent } from \"./types\";\n\ntype DispatchOptions = {\n messages: AgentWidgetMessage[];\n signal?: AbortSignal;\n};\n\ntype SSEHandler = (event: AgentWidgetEvent) => void;\n\nconst DEFAULT_ENDPOINT = \"https://api.travrse.ai/v1/dispatch\";\n\nexport class AgentWidgetClient {\n private readonly apiUrl: string;\n private readonly headers: Record<string, string>;\n private readonly debug: boolean;\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 }\n\n public async dispatch(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 // Build simplified payload with just messages and optional flowId\n // Sort by createdAt to ensure chronological order (not local sequence)\n const body = {\n messages: options.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.content,\n createdAt: message.createdAt\n })),\n ...(this.config.flowId && { flowId: this.config.flowId })\n };\n\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(\"[AgentWidgetClient] dispatch body\", body);\n }\n\n const response = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(body),\n signal: controller.signal\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 streamResponse(\n body: ReadableStream<Uint8Array>,\n onEvent: SSEHandler\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 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 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 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 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 (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 const assistant = ensureAssistantMessage();\n const chunk = payload.text ?? payload.delta ?? payload.content ?? \"\";\n if (chunk) {\n assistant.content += chunk;\n emitMessage(assistant);\n }\n if (payload.isComplete) {\n const finalContent = payload.result?.response ?? assistant.content;\n if (finalContent) {\n assistant.content = finalContent;\n assistant.streaming = false;\n emitMessage(assistant);\n }\n }\n } else if (payloadType === \"step_complete\") {\n const finalContent = payload.result?.response;\n const assistant = ensureAssistantMessage();\n if (finalContent) {\n assistant.content = finalContent;\n assistant.streaming = false;\n emitMessage(assistant);\n } else {\n // No final content, just mark as complete\n assistant.streaming = false;\n emitMessage(assistant);\n }\n } else if (payloadType === \"flow_complete\") {\n const finalContent = payload.result?.response;\n if (finalContent) {\n const assistant = ensureAssistantMessage();\n if (finalContent !== assistant.content) {\n assistant.content = finalContent;\n emitMessage(assistant);\n }\n assistant.streaming = false;\n emitMessage(assistant);\n } else {\n const existingAssistant = assistantMessage;\n if (existingAssistant) {\n const assistantFinal = existingAssistant as AgentWidgetMessage;\n assistantFinal.streaming = false;\n emitMessage(assistantFinal);\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","import { AgentWidgetClient } from \"./client\";\nimport {\n AgentWidgetConfig,\n AgentWidgetEvent,\n AgentWidgetMessage\n} from \"./types\";\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 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 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 async sendMessage(rawInput: string) {\n const input = rawInput.trim();\n if (!input) return;\n\n this.abortController?.abort();\n\n const userMessage: AgentWidgetMessage = {\n id: `user-${Date.now()}`,\n role: \"user\",\n content: input,\n createdAt: new Date().toISOString(),\n sequence: this.nextSequence()\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 },\n this.handleEvent\n );\n } catch (error) {\n const fallback: AgentWidgetMessage = {\n id: `assistant-${Date.now()}`,\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 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 } from \"../types\";\n\nexport const applyThemeVariables = (\n element: HTMLElement,\n config?: AgentWidgetConfig\n) => {\n const theme = config?.theme ?? {};\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\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","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","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","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 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-shadow-lg tvw-border tvw-border-gray-200 tvw-transition hover:tvw-translate-y-[-2px] tvw-cursor-pointer\";\n\n button.className = `${base} ${positionClass}`;\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\";\nimport { positionMap } from \"../utils/positioning\";\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 const wrapper = createElement(\n \"div\",\n \"tvw-relative tvw-w-full tvw-h-full\"\n );\n const panel = createElement(\n \"div\",\n \"tvw-relative tvw-w-full tvw-h-full tvw-min-h-[360px]\"\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-fixed ${position} tvw-z-50 tvw-transition`\n );\n\n const panel = createElement(\n \"div\",\n \"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}\n\nexport const buildPanel = (config?: AgentWidgetConfig, showClose = true): PanelElements => {\n const container = createElement(\n \"div\",\n \"tvw-flex tvw-h-full tvw-w-full tvw-flex-col tvw-bg-cw-surface tvw-text-cw-primary tvw-rounded-2xl tvw-overflow-hidden tvw-shadow-2xl tvw-border tvw-border-cw-border\"\n );\n\n const header = createElement(\n \"div\",\n \"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(\n \"span\",\n \"tvw-text-base tvw-font-semibold\"\n );\n title.textContent =\n config?.launcher?.title ?? \"Chat Assistant\";\n const subtitle = createElement(\n \"span\",\n \"tvw-text-xs tvw-text-cw-muted\"\n );\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 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\n clearChatButtonWrapper = createElement(\n \"div\",\n \"tvw-relative tvw-ml-auto tvw-clear-chat-button-wrapper\"\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(clearChatIconName, \"20px\", clearChatIconColor || \"\", 2);\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 (clearChatShowTooltip && clearChatTooltipText && clearChatButton && clearChatButtonWrapper) {\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 header.appendChild(clearChatButtonWrapper);\n }\n\n // Create close button wrapper for tooltip positioning\n const closeButtonWrapper = createElement(\n \"div\",\n closeButtonPlacement === \"top-right\"\n ? \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50\"\n : (clearChatEnabled\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 iconSvg = renderLucideIcon(closeButtonIconName, \"20px\", launcher.closeButtonColor || \"\", 2);\n if (iconSvg) {\n closeButton.appendChild(iconSvg);\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 // Position close button wrapper based on placement\n if (closeButtonPlacement === \"top-right\") {\n // Make container position relative for absolute positioning\n container.style.position = \"relative\";\n container.appendChild(closeButtonWrapper);\n } else {\n // Inline placement: append to header\n header.appendChild(closeButtonWrapper);\n }\n\n const body = createElement(\n \"div\",\n \"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 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 const footer = createElement(\n \"div\",\n \"tvw-border-t-cw-divider tvw-bg-cw-surface tvw-px-6 tvw-py-4\"\n );\n const suggestions = createElement(\n \"div\",\n \"tvw-mb-3 tvw-flex tvw-flex-wrap tvw-gap-2\"\n );\n // Determine gap based on voice recognition\n const voiceRecognitionEnabledForGap = 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 = voiceRecognitionEnabledForGap && hasSpeechRecognitionForGap;\n const gapClass = shouldUseSmallGap ? \"tvw-gap-1\" : \"tvw-gap-3\";\n \n const composerForm = createElement(\n \"form\",\n `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 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 // 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 // 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 = 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 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 = 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(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 (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 tooltipText = voiceRecognitionConfig.tooltipText ?? \"Start voice recognition\";\n const showTooltip = voiceRecognitionConfig.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 \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 (e.target !== sendButton && e.target !== sendButtonWrapper && \n e.target !== micButton && e.target !== micButtonWrapper) {\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 container.append(header, body, footer);\n\n return {\n container,\n body,\n messagesWrapper,\n suggestions,\n textarea,\n sendButton,\n sendButtonWrapper,\n micButton,\n micButtonWrapper,\n composerForm,\n statusText,\n introTitle,\n introSubtitle,\n closeButton,\n closeButtonWrapper,\n clearChatButton,\n clearChatButtonWrapper,\n iconHolder\n };\n};\n\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage } from \"../types\";\n\nexport type MessageTransform = (context: {\n text: string;\n message: AgentWidgetMessage;\n streaming: boolean;\n}) => string;\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\nexport const createStandardBubble = (\n message: AgentWidgetMessage,\n transform: MessageTransform\n): HTMLElement => {\n const classes = [\n \"tvw-max-w-[85%]\",\n \"tvw-rounded-2xl\",\n \"tvw-text-sm\",\n \"tvw-leading-relaxed\",\n \"tvw-shadow-sm\"\n ];\n\n if (message.role === \"user\") {\n classes.push(\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 classes.push(\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\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 });\n bubble.appendChild(contentDiv);\n\n // Add typing indicator if this is a streaming assistant message with content\n if (message.streaming && message.role === \"assistant\" && message.content && message.content.trim()) {\n const typingIndicator = createTypingIndicator();\n bubble.appendChild(typingIndicator);\n }\n\n return bubble;\n};\n\n\n\n","import { AgentWidgetReasoning, AgentWidgetToolCall } from \"../types\";\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\n\n\n","import { createElement } from \"../utils/dom\";\nimport { AgentWidgetMessage } from \"../types\";\nimport { describeReasonStatus } from \"../utils/formatting\";\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 \"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-font-semibold 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 toggleLabel = createElement(\n \"span\",\n \"tvw-text-xs tvw-text-cw-primary\"\n );\n toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\n\n header.append(headerContent, toggleLabel);\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 toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\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 } from \"../types\";\nimport { formatUnknownValue, describeToolTitle } from \"../utils/formatting\";\n\n// Expansion state per widget instance\nconst toolExpansionState = new Set<string>();\n\nexport const createToolBubble = (message: AgentWidgetMessage): HTMLElement => {\n const tool = message.toolCall;\n const bubble = createElement(\n \"div\",\n [\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 (!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 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 = describeToolTitle(tool);\n headerContent.appendChild(title);\n\n if (tool.name) {\n const name = createElement(\"span\", \"tvw-text-[11px] tvw-text-cw-muted\");\n name.textContent = tool.name;\n headerContent.appendChild(name);\n }\n\n const toggleLabel = createElement(\n \"span\",\n \"tvw-text-xs tvw-text-cw-primary\"\n );\n toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\n\n const headerMeta = createElement(\"div\", \"tvw-flex tvw-items-center tvw-gap-2\");\n headerMeta.append(toggleLabel);\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 if (tool.args !== undefined) {\n const argsBlock = createElement(\"div\", \"tvw-space-y-1\");\n const argsLabel = createElement(\n \"div\",\n \"tvw-font-xxs tvw-font-medium tvw-text-cw-muted\"\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-font-xxs tvw-text-cw-primary\"\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-font-xxs tvw-font-medium tvw-text-cw-muted\"\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-font-xxs tvw-text-cw-primary\"\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-font-xxs tvw-text-sm tvw-text-cw-muted\"\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-font-xxs tvw-text-cw-primary\"\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-font-xxs tvw-text-cw-muted\"\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 toggleLabel.textContent = expanded ? \"Hide\" : \"Show\";\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 } from \"../types\";\n\nexport interface SuggestionButtons {\n buttons: HTMLButtonElement[];\n render: (chips: string[] | undefined, session: AgentWidgetSession, textarea: HTMLTextAreaElement, messages?: AgentWidgetMessage[]) => void;\n}\n\nexport const createSuggestions = (container: HTMLElement): SuggestionButtons => {\n const suggestionButtons: HTMLButtonElement[] = [];\n\n const render = (chips: string[] | undefined, session: AgentWidgetSession, textarea: HTMLTextAreaElement, messages?: AgentWidgetMessage[]) => {\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 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 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","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","import type { AgentWidgetConfig } from \"./types\";\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 theme: {\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 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 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 iconName: \"refresh-cw\",\n size: \"29px\",\n showTooltip: true,\n tooltipText: \"Clear chat\",\n paddingX: \"0px\",\n paddingY: \"0px\",\n },\n headerIconHidden: false,\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 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 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 };\n}\n","import { escapeHtml } from \"./postprocessors\";\nimport { AgentWidgetSession, AgentWidgetSessionStatus } from \"./session\";\nimport { AgentWidgetConfig, AgentWidgetMessage } from \"./types\";\nimport { applyThemeVariables } 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 } from \"./components/panel\";\nimport { MessageTransform } 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\";\n\ntype Controller = {\n update: (config: AgentWidgetConfig) => void;\n destroy: () => void;\n open: () => void;\n close: () => void;\n toggle: () => void;\n clearChat: () => void;\n};\n\nconst buildPostprocessor = (cfg?: AgentWidgetConfig): MessageTransform => {\n if (cfg?.postprocessMessage) {\n return (context) =>\n cfg.postprocessMessage!({\n text: context.text,\n message: context.message,\n streaming: context.streaming\n });\n }\n return ({ text }) => escapeHtml(text);\n};\n\nexport const createAgentExperience = (\n mount: HTMLElement,\n initialConfig?: AgentWidgetConfig\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 applyThemeVariables(mount, config);\n\n // Get plugins for this instance\n const plugins = pluginRegistry.getForInstance(config.plugins);\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);\n let showReasoning = config.features?.showReasoning ?? true;\n let showToolCalls = config.features?.showToolCalls ?? true;\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 const {\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 } = 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 panel.appendChild(container);\n mount.appendChild(wrapper);\n\n const destroyCallbacks: Array<() => void> = [];\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\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\n // Message rendering with plugin support\n const renderMessagesWithPlugins = (\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 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),\n config\n });\n } else if (matchingPlugin.renderMessage) {\n bubble = matchingPlugin.renderMessage({\n message,\n defaultRenderer: () => {\n const b = createStandardBubble(message, transform);\n if (message.role !== \"user\") {\n enhanceWithForms(b, message, config, session);\n }\n return b;\n },\n config\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);\n } else {\n bubble = createStandardBubble(message, transform);\n if (message.role !== \"user\") {\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 const hasStreamingAssistantMessage = messages.some(\n (msg) => msg.role === \"assistant\" && msg.streaming && msg.content && msg.content.trim()\n );\n\n if (isStreaming && messages.some((msg) => msg.role === \"user\") && !hasStreamingAssistantMessage) {\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 container.scrollTop = container.scrollHeight;\n };\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 }\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 }\n }\n };\n\n const setOpenState = (nextOpen: boolean) => {\n if (!launcherEnabled) return;\n if (open === nextOpen) return;\n open = nextOpen;\n updateOpenState();\n if (open) {\n recalcPanelHeight();\n scheduleAutoScroll(true);\n }\n };\n\n const setComposerDisabled = (disabled: boolean) => {\n textarea.disabled = disabled;\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);\n }\n }\n scheduleAutoScroll(!isStreaming);\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 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 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);\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);\n }\n stopVoiceRecognition();\n }\n };\n\n try {\n speechRecognition.start();\n isRecording = true;\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();\n }\n };\n\n const stopVoiceRecognition = () => {\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 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 stopVoiceRecognition();\n if (finalValue) {\n textarea.value = \"\";\n session.sendMessage(finalValue);\n }\n } else {\n // Start recording\n startVoiceRecognition();\n }\n };\n\n if (micButton) {\n micButton.addEventListener(\"click\", handleMicButtonClick);\n\n destroyCallbacks.push(() => {\n stopVoiceRecognition();\n if (micButton) {\n micButton.removeEventListener(\"click\", handleMicButtonClick);\n }\n });\n }\n\n const toggleOpen = () => {\n setOpenState(!open);\n };\n\n let launcherButtonInstance = launcherEnabled\n ? createLauncherButton(config, toggleOpen)\n : null;\n\n if (launcherButtonInstance) {\n mount.appendChild(launcherButtonInstance.element);\n }\n updateOpenState();\n suggestionsManager.render(config.suggestionChips, session, textarea);\n updateCopy();\n setComposerDisabled(session.isStreaming());\n scheduleAutoScroll(true);\n\n const recalcPanelHeight = () => {\n if (!launcherEnabled) {\n panel.style.height = \"\";\n panel.style.width = \"\";\n return;\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 const viewportHeight = window.innerHeight;\n const verticalMargin = 64; // leave space for launcher's offset\n const available = Math.max(200, viewportHeight - verticalMargin);\n const clamped = Math.min(640, available);\n panel.style.height = `${clamped}px`;\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 // 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 };\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 }\n\n return {\n update(nextConfig: AgentWidgetConfig) {\n config = { ...config, ...nextConfig };\n applyThemeVariables(mount, config);\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\n if (config.launcher?.enabled !== false && !launcherButtonInstance) {\n launcherButtonInstance = createLauncherButton(config, toggleOpen);\n mount.appendChild(launcherButtonInstance.element);\n }\n\n if (launcherButtonInstance) {\n launcherButtonInstance.update(config);\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);\n }\n } else if (autoExpandChanged) {\n // autoExpand value changed - update state to match\n setOpenState(autoExpand);\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 // 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\n const isTopRight = closeButtonPlacement === \"top-right\";\n const hasTopRightClasses = closeButton.classList.contains(\"tvw-absolute\");\n \n if (isTopRight !== hasTopRightClasses) {\n // Placement changed - need to move button and update classes\n closeButton.remove();\n \n // Update classes\n if (isTopRight) {\n closeButton.className = \"tvw-absolute tvw-top-4 tvw-right-4 tvw-z-50 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 container.style.position = \"relative\";\n container.appendChild(closeButton);\n } else {\n closeButton.className = \"tvw-ml-auto 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 // Find header element (first child of container)\n const header = container.querySelector(\".tvw-border-b-cw-divider\");\n if (header) {\n header.appendChild(closeButton);\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 { closeButtonWrapper } = panelElements;\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\n // Show/hide button based on enabled state\n if (clearChatButtonWrapper) {\n clearChatButtonWrapper.style.display = clearChatEnabled ? \"\" : \"none\";\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 postprocess = buildPostprocessor(config);\n session.updateConfig(config);\n renderMessagesWithPlugins(\n messagesWrapper,\n session.getMessages(),\n postprocess\n );\n suggestionsManager.render(config.suggestionChips, session, textarea);\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);\n },\n close() {\n if (!launcherEnabled) return;\n setOpenState(false);\n },\n toggle() {\n if (!launcherEnabled) return;\n setOpenState(!open);\n },\n clearChat() {\n // Clear messages in session (this will trigger onMessagesChanged which re-renders)\n session.clearMessages();\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 destroy() {\n destroyCallbacks.forEach((cb) => cb());\n wrapper.remove();\n launcherButtonInstance?.destroy();\n if (closeHandler) {\n closeButton.removeEventListener(\"click\", closeHandler);\n }\n }\n };\n};\n\nexport type AgentWidgetController = Controller;\n","import { createAgentExperience, AgentWidgetController } from \"../ui\";\nimport { AgentWidgetConfig, AgentWidgetInitOptions } 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 target.appendChild(host);\n\n const useShadow = options.useShadowDom !== false;\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 shadowRoot.appendChild(mount);\n mountStyles(shadowRoot);\n } else {\n root = host;\n mount = document.createElement(\"div\");\n mount.id = \"vanilla-agent-root\";\n host.appendChild(mount);\n mountStyles(host);\n }\n\n let controller = createAgentExperience(mount, options.config);\n options.onReady?.();\n\n return {\n host,\n update(nextConfig: AgentWidgetConfig) {\n controller.update(nextConfig);\n },\n open() {\n controller.open();\n },\n close() {\n controller.close();\n },\n toggle() {\n controller.toggle();\n },\n clearChat() {\n controller.clearChat();\n },\n destroy() {\n controller.destroy();\n host.remove();\n }\n };\n};\n"],"mappings":"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","names":["index_exports","__export","AgentWidgetClient","AgentWidgetSession","DEFAULT_WIDGET_CONFIG","createAgentExperience","index_default","directivePostprocessor","escapeHtml","initAgentWidget","markdownPostprocessor","mergeWithDefaults","pluginRegistry","__toCommonJS","import_marked","markdownPostprocessor","text","escapeHtml","escapeAttribute","value","makeToken","idx","directiveReplacer","source","placeholders","working","match","jsonText","parsed","token","_","type","directivePostprocessor","withTokens","html","tokenRegex","replacement","DEFAULT_ENDPOINT","AgentWidgetClient","config","_a","options","onEvent","controller","body","b","timeA","timeB","message","response","error","_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","_G","_H","_I","_J","_K","_L","_M","_N","_O","_P","_Q","_R","_S","_T","_U","_V","_W","reader","decoder","buffer","baseSequence","sequenceCounter","nextSequence","cloneMessage","msg","reasoning","toolCall","tools","tool","emitMessage","assistantMessage","reasoningMessages","toolMessages","reasoningContext","toolContext","normalizeKey","value","getStepKey","payload","getToolCallKey","ensureAssistantMessage","trackReasoningId","stepKey","id","resolveReasoningId","allowCreate","rawId","resolved","existing","generated","ensureReasoningMessage","reasoningId","trackToolId","callKey","resolveToolId","ensureToolMessage","toolId","resolveTimestamp","parsed","dateParsed","done","events","event","lines","eventType","data","line","payloadType","reasoningMessage","chunk","start","toolMessage","chunkText","assistant","finalContent","existingAssistant","assistantFinal","AgentWidgetSession","config","callbacks","event","_a","_b","message","AgentWidgetClient","next","rawInput","_c","_d","_e","input","userMessage","controller","snapshot","error","fallback","status","streaming","withSequence","index","m","existing","idx","messages","a","b","timeA","timeB","seqA","seqB","applyThemeVariables","element","config","_a","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","launcher","titleEl","subtitleEl","textContainer","icon","iconSize","iconSizeNum","iconSvg","renderLucideIcon","img","callToActionIconEl","callToActionIconSize","paddingTotal","containerSize","positionClass","positionMap","base","destroy","createWrapper","config","_a","_b","_c","_d","_e","wrapper","createElement","panel","launcher","position","positionMap","launcherWidth","width","buildPanel","showClose","_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","_ca","_da","_ea","_fa","container","header","headerIconSize","closeButtonSize","closeButtonPlacement","headerIconHidden","headerIconName","iconHolder","iconSize","iconSvg","renderLucideIcon","img","headerCopy","title","subtitle","clearChatConfig","clearChatEnabled","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","body","introCard","introTitle","introSubtitle","messagesWrapper","footer","suggestions","voiceRecognitionEnabledForGap","hasSpeechRecognitionForGap","composerForm","textarea","fontFamily","fontWeight","getFontFamilyValue","family","sendButtonConfig","useIcon","iconText","iconName","tooltipText","buttonSize","backgroundColor","textColor","sendButtonWrapper","sendButton","iconColor","tooltip","voiceRecognitionConfig","voiceRecognitionEnabled","micButton","micButtonWrapper","hasSpeechRecognition","micIconName","micIconSize","micIconSizeNum","micBackgroundColor","micIconColor","iconColorValue","micIconSvg","e","statusText","statusConfig","isVisible","createTypingIndicator","container","dot1","dot2","dot3","srOnly","createStandardBubble","message","transform","classes","bubble","createElement","contentDiv","typingIndicator","formatUnknownValue","value","formatReasoningDuration","reasoning","_a","_b","end","start","seconds","describeReasonStatus","formatToolDuration","tool","_c","describeToolTitle","tool","formatToolDuration","reasoningExpansionState","createReasoningBubble","message","reasoning","bubble","createElement","expanded","header","headerContent","title","status","describeReasonStatus","toggleLabel","content","text","body","applyExpansionState","toggleExpansion","event","toolExpansionState","createToolBubble","message","tool","bubble","createElement","expanded","header","headerContent","title","describeToolTitle","name","toggleLabel","headerMeta","content","argsBlock","argsLabel","argsPre","formatUnknownValue","logsBlock","logsLabel","logsPre","resultBlock","resultLabel","resultPre","duration","applyToolExpansion","toggleToolExpansion","event","createSuggestions","container","suggestionButtons","chips","session","textarea","messages","msg","fragment","streaming","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_WIDGET_CONFIG","mergeWithDefaults","config","_a","_b","_c","buildPostprocessor","cfg","context","text","escapeHtml","createAgentExperience","mount","initialConfig","_a","_b","_c","_d","_e","_f","_g","_h","_i","config","mergeWithDefaults","applyThemeVariables","plugins","pluginRegistry","launcherEnabled","autoExpand","prevAutoExpand","prevLauncherEnabled","open","postprocess","showReasoning","showToolCalls","statusConfig","getStatusText","status","statusCopy","wrapper","panel","createWrapper","panelElements","buildPanel","container","body","messagesWrapper","suggestions","textarea","sendButton","sendButtonWrapper","composerForm","statusText","introTitle","introSubtitle","closeButton","iconHolder","micButton","micButtonWrapper","destroyCallbacks","suggestionsManager","createSuggestions","closeHandler","session","isStreaming","shouldAutoScroll","lastScrollTop","lastAutoScrollTime","scrollRAF","isAutoScrollBlocked","blockUntilTime","isAutoScrolling","AUTO_SCROLL_THROTTLE","AUTO_SCROLL_BLOCK_TIME","USER_SCROLL_THRESHOLD","BOTTOM_THRESHOLD","scheduleAutoScroll","force","now","renderMessagesWithPlugins","messages","transform","fragment","message","bubble","matchingPlugin","p","createReasoningBubble","createToolBubble","b","createStandardBubble","enhanceWithForms","hasStreamingAssistantMessage","msg","typingIndicator","createTypingIndicator","typingBubble","typingWrapper","updateOpenState","launcherButtonInstance","setOpenState","nextOpen","recalcPanelHeight","setComposerDisabled","disabled","btn","updateCopy","_j","_k","_l","_m","_n","fontFamily","fontWeight","getFontFamilyValue","family","AgentWidgetSession","currentStatusConfig","getCurrentStatusText","streaming","handleSubmit","event","value","handleInputEnter","speechRecognition","isRecording","pauseTimer","originalMicStyles","getSpeechRecognitionClass","startVoiceRecognition","SpeechRecognitionClass","pauseDuration","initialText","fullTranscript","interimTranscript","i","result","transcript","newValue","finalValue","stopVoiceRecognition","voiceConfig","recordingBackgroundColor","recordingIconColor","recordingBorderColor","svg","createMicButton","sendButtonConfig","createElement","micIconName","buttonSize","micIconSize","micIconSizeNum","backgroundColor","iconColor","iconColorValue","micIconSvg","renderLucideIcon","tooltipText","tooltip","handleMicButtonClick","toggleOpen","createLauncherButton","launcherWidth","width","viewportHeight","available","clamped","handleScroll","scrollTop","scrollHeight","clientHeight","distanceFromBottom","delta","refreshCloseButton","clearChatButton","clearEvent","nextConfig","_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","newPlugins","launcher","headerIconHidden","headerIconName","headerIconSize","header","headerCopy","iconSize","iconSvg","img","newImg","existingSvg","existingImg","closeButtonSize","closeButtonPlacement","isTopRight","hasTopRightClasses","borderWidth","borderColor","closeButtonIconName","closeButtonIconText","closeButtonWrapper","closeButtonTooltipText","closeButtonShowTooltip","portaledTooltip","showTooltip","arrow","buttonRect","hideTooltip","clearChatButtonWrapper","clearChatConfig","clearChatEnabled","clearChatSize","clearChatIconName","clearChatIconColor","clearChatTooltipText","clearChatShowTooltip","voiceRecognitionEnabled","hasSpeechRecognition","shouldUseSmallGap","micButtonResult","newTooltip","useIcon","iconText","iconName","textColor","statusIndicatorConfig","isVisible","currentStatus","cb","import_meta","ensureTarget","target","element","widgetCssHref","mountStyles","root","href","adoptExistingStylesheet","globalLink","clonedLink","link","initAgentWidget","options","_a","host","useShadow","mount","shadowRoot","controller","createAgentExperience","nextConfig","index_default","initAgentWidget"]}