chatbotlite 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -53
- package/dist/client/index.cjs +27 -91
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +14 -9
- package/dist/client/index.d.ts +14 -9
- package/dist/client/index.js +28 -91
- package/dist/client/index.js.map +1 -1
- package/dist/core/index.cjs +15 -50
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +9 -7
- package/dist/core/index.d.ts +9 -7
- package/dist/core/index.js +15 -50
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +27 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +28 -91
- package/dist/index.js.map +1 -1
- package/dist/node/index.cjs +41 -0
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.d.cts +37 -0
- package/dist/node/index.d.ts +37 -0
- package/dist/node/index.js +38 -0
- package/dist/node/index.js.map +1 -0
- package/dist/react/index.cjs +32 -95
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +7 -7
- package/dist/react/index.d.ts +7 -7
- package/dist/react/index.js +32 -95
- package/dist/react/index.js.map +1 -1
- package/dist/types-4alyzg8O.d.cts +16 -0
- package/dist/types-4alyzg8O.d.ts +16 -0
- package/dist/types-J7BXpiRU.d.cts +63 -0
- package/dist/types-J7BXpiRU.d.ts +63 -0
- package/package.json +12 -3
- package/dist/types-DS7rM6Vl.d.cts +0 -82
- package/dist/types-DS7rM6Vl.d.ts +0 -82
- package/dist/types-DYNx47by.d.cts +0 -39
- package/dist/types-DYNx47by.d.ts +0 -39
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/prompts.ts","../../src/core/guards.ts","../../src/client/types.ts","../../src/client/providers.ts","../../src/client/chatbot.ts","../../src/react/ChatWidget.tsx"],"names":["useState","useRef","useEffect","useMemo","jsxs","Fragment","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { BusinessConfig } from \"./types.js\";\n\n/**\n * Build the system prompt that anchors the bot to the business config.\n * Designed to minimize hallucination: only mention what's in the config,\n * defer to owner review for anything outside scope.\n */\nexport function buildSystemPrompt(business: BusinessConfig): string {\n const parts: string[] = [];\n\n parts.push(`You are an AI receptionist for ${business.name}.`);\n if (business.description) parts.push(business.description);\n parts.push(\"\");\n\n if (business.services && business.services.length > 0) {\n parts.push(\"Services offered (only these — do not invent others):\");\n for (const s of business.services) {\n const price = s.price ? ` — ${s.price}` : \"\";\n const notes = s.notes ? ` (${s.notes})` : \"\";\n parts.push(`- ${s.name}${price}${notes}`);\n }\n parts.push(\"\");\n }\n\n if (business.hours) {\n parts.push(`Hours: ${business.hours}`);\n }\n\n if (business.serviceArea && business.serviceArea.length > 0) {\n parts.push(`Service area: ${business.serviceArea.join(\", \")}.`);\n parts.push(\"If the caller is outside this area, say so and recommend owner review.\");\n }\n\n if (business.policies && business.policies.length > 0) {\n parts.push(\"\");\n parts.push(\"Known policies (use these exact answers when asked):\");\n for (const p of business.policies) {\n parts.push(`- ${p.topic}: ${p.answer}`);\n }\n }\n\n parts.push(\"\");\n parts.push(\"Rules:\");\n parts.push(\"- Reply in 1-2 short sentences, conversational tone.\");\n parts.push(\"- NEVER invent prices, availability, dispatch times, or appointment confirmations.\");\n parts.push(\"- For anything not covered in the setup above, say it needs owner review.\");\n parts.push('- If the caller is clearly a vendor/sales pitch, say: \"This does not look like a customer service request, so we will not continue this thread.\"');\n parts.push('- If wrong number or asked to stop, say: \"Sorry about that. We won\\'t text again.\"');\n\n if (business.doNotPromise && business.doNotPromise.length > 0) {\n parts.push(\"\");\n parts.push(\"Never promise:\");\n for (const p of business.doNotPromise) parts.push(`- ${p}`);\n }\n\n if (business.customInstructions) {\n parts.push(\"\");\n parts.push(\"Additional instructions:\");\n parts.push(business.customInstructions);\n }\n\n if (business.language && business.language !== \"en\") {\n parts.push(\"\");\n parts.push(`Reply in ${business.language}.`);\n }\n\n return parts.join(\"\\n\");\n}\n","import type { GuardResult } from \"./types.js\";\n\n/**\n * Phrases that almost always indicate hallucination for SMB customer service:\n * inventing dispatch promises, fake confirmations, or appointment locks.\n */\nexport const FORBIDDEN_PHRASES: readonly string[] = [\n \"help is coming\",\n \"someone is on the way\",\n \"technician is on the way\",\n \"provider is on the way\",\n \"dispatching someone\",\n \"i've booked\",\n \"i have booked\",\n \"reservation confirmed\",\n \"your appointment is confirmed\",\n \"i've scheduled\",\n \"i have scheduled\",\n \"we've dispatched\",\n \"we have dispatched\",\n \"i can confirm\",\n \"i guarantee\",\n \"guaranteed delivery\",\n \"guaranteed arrival\",\n \"will arrive at\",\n \"arriving at\",\n \"i'll send\",\n \"i will send\"\n];\n\n/**\n * Check a reply against the built-in forbidden phrase list.\n * Returns ok=true when clean, ok=false with violations when not.\n */\nexport function checkForbiddenPhrases(reply: string): GuardResult {\n const lower = reply.toLowerCase();\n const violations: string[] = [];\n for (const phrase of FORBIDDEN_PHRASES) {\n if (lower.includes(phrase)) {\n violations.push(`Forbidden phrase: \"${phrase}\"`);\n }\n }\n return { ok: violations.length === 0, violations };\n}\n\n/**\n * Remove forbidden sentences from a reply (best-effort sentence drop).\n * If too much is removed, returns a safe fallback.\n */\nexport function stripForbidden(reply: string): string {\n const sentences = reply.split(/(?<=[.!?])\\s+/);\n const kept = sentences.filter((s) => {\n const lower = s.toLowerCase();\n return !FORBIDDEN_PHRASES.some((p) => lower.includes(p));\n });\n const trimmed = kept.join(\" \").trim();\n if (trimmed.length < 10) {\n return \"Thanks for reaching out — let me check with the owner and get back to you.\";\n }\n return trimmed;\n}\n","// Client types — provider + chain config\n\nexport type Provider =\n | \"openai\"\n | \"deepseek\"\n | \"groq\"\n | \"gemini\"\n | \"anthropic\"\n | \"cerebras\"\n | \"sambanova\"\n | \"fireworks\"\n | \"mistral\"\n | \"openrouter\"\n | \"moonshot\";\n\n/**\n * One step in the fallback chain. Either a string spec or an object.\n *\n * - **String**: `\"provider/model\"` (e.g. `\"openai/gpt-4o\"`), or bare `\"provider\"` (uses provider's default model).\n * - **Object**: `{ provider, model? }` — type-safe alternative.\n */\nexport type ChainEntry =\n | string\n | { provider: Provider; model?: string };\n\n/**\n * Provider configuration.\n *\n * `keys` are auth credentials (one key per provider — that key covers all that provider's models).\n * `chain` is the ordered fallback list. Each entry is `\"provider/model\"` (string) or `{ provider, model }` (object).\n *\n * @example String form (compact, paste-friendly)\n * ```ts\n * providers: {\n * keys: {\n * deepseek: \"sk-...\",\n * groq: \"gsk-...\",\n * openai: \"sk-...\"\n * },\n * chain: [\n * \"deepseek/deepseek-chat\", // try first\n * \"groq/llama-3.3-70b-versatile\", // fallback 1\n * \"openai/gpt-4o-mini\" // fallback 2\n * ]\n * }\n * ```\n *\n * @example Object form (type-safe, IDE autocomplete on `provider`)\n * ```ts\n * providers: {\n * keys: { deepseek: \"sk-...\", openai: \"sk-...\" },\n * chain: [\n * { provider: \"deepseek\" }, // default model\n * { provider: \"openai\", model: \"gpt-4o\" },\n * { provider: \"openai\", model: \"gpt-4o-mini\" } // same key, cheaper model\n * ]\n * }\n * ```\n *\n * If `chain` is omitted, defaults to `[<each provider in keys> with its default model]`\n * in key insertion order.\n */\nexport interface ProviderConfig {\n /** API keys per provider. One key covers all that provider's models. */\n keys: Partial<Record<Provider, string>>;\n /**\n * Ordered fallback chain. Each entry: string `\"provider/model\"` OR object `{ provider, model? }`.\n * Defaults to `[provider/defaultModel]` for each key in insertion order.\n */\n chain?: ChainEntry[];\n}\n\nexport interface ClientOptions {\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n maxRetries?: number;\n}\n\nexport interface ChainStep {\n provider: Provider;\n model: string;\n /** Original spec string for diagnostics. */\n spec: string;\n}\n\nexport interface AttemptInfo {\n provider: Provider;\n model: string;\n status: \"ok\" | \"error\";\n error?: string;\n latencyMs: number;\n}\n\nconst PROVIDER_NAMES: ReadonlySet<string> = new Set([\n \"openai\", \"deepseek\", \"groq\", \"gemini\", \"anthropic\",\n \"cerebras\", \"sambanova\", \"fireworks\", \"mistral\", \"openrouter\", \"moonshot\"\n]);\n\nexport function parseChainSpec(spec: string): { provider: Provider; model: string | null } {\n const slash = spec.indexOf(\"/\");\n if (slash === -1) {\n if (!PROVIDER_NAMES.has(spec)) {\n throw new Error(`chatbotlite: unknown provider \"${spec}\". Use \"provider/model\" or a known provider name.`);\n }\n return { provider: spec as Provider, model: null };\n }\n const provider = spec.slice(0, slash);\n const model = spec.slice(slash + 1);\n if (!PROVIDER_NAMES.has(provider)) {\n throw new Error(`chatbotlite: unknown provider \"${provider}\" in chain spec \"${spec}\".`);\n }\n if (!model) {\n throw new Error(`chatbotlite: empty model name in chain spec \"${spec}\".`);\n }\n return { provider: provider as Provider, model };\n}\n\nexport function isKnownProvider(name: string): name is Provider {\n return PROVIDER_NAMES.has(name);\n}\n","import type { Provider } from \"./types.js\";\n\nexport interface ProviderEndpoint {\n baseUrl: string;\n defaultModel: string;\n}\n\n/**\n * Built-in OpenAI-compatible providers. All use /v1/chat/completions\n * with response in OpenAI format. Caller supplies API key per provider.\n */\nexport const PROVIDER_ENDPOINTS: Record<Provider, ProviderEndpoint> = {\n openai: { baseUrl: \"https://api.openai.com/v1\", defaultModel: \"gpt-4o-mini\" },\n deepseek: { baseUrl: \"https://api.deepseek.com/v1\", defaultModel: \"deepseek-chat\" },\n groq: { baseUrl: \"https://api.groq.com/openai/v1\", defaultModel: \"llama-3.3-70b-versatile\" },\n gemini: { baseUrl: \"https://generativelanguage.googleapis.com/v1beta/openai\", defaultModel: \"gemini-2.5-flash\" },\n anthropic: { baseUrl: \"https://api.anthropic.com/v1\", defaultModel: \"claude-haiku-4-5\" },\n cerebras: { baseUrl: \"https://api.cerebras.ai/v1\", defaultModel: \"qwen-3-235b-a22b-instruct-2507\" },\n sambanova: { baseUrl: \"https://api.sambanova.ai/v1\", defaultModel: \"Meta-Llama-3.3-70B-Instruct\" },\n fireworks: { baseUrl: \"https://api.fireworks.ai/inference/v1\", defaultModel: \"accounts/fireworks/models/llama-v3p3-70b-instruct\" },\n mistral: { baseUrl: \"https://api.mistral.ai/v1\", defaultModel: \"mistral-small-latest\" },\n openrouter: { baseUrl: \"https://openrouter.ai/api/v1\", defaultModel: \"deepseek/deepseek-chat\" },\n moonshot: { baseUrl: \"https://api.moonshot.ai/v1\", defaultModel: \"moonshot-v1-32k\" }\n};\n\nexport function isRetryableError(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err);\n return /\\b(429|rate.?limit|quota|exceed|5\\d\\d|timeout|ECONNRESET|fetch failed)\\b/i.test(msg);\n}\n","import type { BusinessConfig, Message } from \"../core/types.js\";\nimport { buildSystemPrompt } from \"../core/prompts.js\";\nimport { checkForbiddenPhrases, stripForbidden } from \"../core/guards.js\";\nimport type { Provider, ProviderConfig, ClientOptions, ChainStep, ChainEntry, AttemptInfo } from \"./types.js\";\nimport { parseChainSpec, isKnownProvider } from \"./types.js\";\nimport { PROVIDER_ENDPOINTS, isRetryableError } from \"./providers.js\";\n\nexport interface ChatBotInit {\n business: BusinessConfig;\n providers: ProviderConfig;\n options?: ClientOptions;\n}\n\nexport interface ReplyOptions {\n /** Conversation history (excluding the new user message). */\n history?: Message[];\n /** Override system prompt — advanced use only. */\n systemPrompt?: string;\n}\n\nexport interface ReplyResult {\n reply: string;\n /** Provider/model that produced the final reply (after fallback). */\n usedProvider: Provider;\n usedModel: string;\n /** Token usage if reported by the final provider. */\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n /** Guard violations the bot caught and stripped, if any. */\n guardWarnings: string[];\n /** Debug trace of every attempt in the chain. */\n attempts: AttemptInfo[];\n}\n\n/**\n * The main ChatBot entry. Holds business config + provider chain.\n *\n * @example\n * const bot = new ChatBot({\n * business: { name: \"Acme Plumbing\", services: [{ name: \"Sink leak\", price: \"$95\" }] },\n * providers: {\n * keys: { deepseek: \"sk-...\", groq: \"gsk-...\", openai: \"sk-...\" },\n * chain: [\"deepseek/deepseek-chat\", \"groq/llama-3.3-70b-versatile\", \"openai/gpt-4o-mini\"]\n * }\n * });\n * const { reply } = await bot.reply(\"My sink is leaking\");\n */\nexport class ChatBot {\n private readonly business: BusinessConfig;\n private readonly steps: ChainStep[];\n private readonly keys: Partial<Record<Provider, string>>;\n private readonly fetcher: typeof globalThis.fetch;\n private readonly timeoutMs: number;\n private readonly cachedSystemPrompt: string;\n\n constructor(init: ChatBotInit) {\n this.business = init.business;\n this.keys = init.providers.keys ?? {};\n this.steps = resolveChain(init.providers);\n this.fetcher = init.options?.fetch ?? globalThis.fetch.bind(globalThis);\n this.timeoutMs = init.options?.timeoutMs ?? 30_000;\n this.cachedSystemPrompt = buildSystemPrompt(this.business);\n }\n\n async reply(message: string, opts: ReplyOptions = {}): Promise<ReplyResult> {\n const systemPrompt = opts.systemPrompt ?? this.cachedSystemPrompt;\n const messages: Message[] = [\n { role: \"system\", content: systemPrompt },\n ...(opts.history ?? []),\n { role: \"user\", content: message }\n ];\n const attempts: AttemptInfo[] = [];\n let lastError: unknown;\n for (const step of this.steps) {\n const t0 = Date.now();\n try {\n const result = await this.callProvider(step, messages);\n attempts.push({ provider: step.provider, model: step.model, status: \"ok\", latencyMs: Date.now() - t0 });\n const guard = checkForbiddenPhrases(result.reply);\n const finalReply = guard.ok ? result.reply : stripForbidden(result.reply);\n return {\n reply: finalReply,\n usedProvider: step.provider,\n usedModel: step.model,\n ...(result.usage ? { usage: result.usage } : {}),\n guardWarnings: guard.violations,\n attempts\n };\n } catch (err) {\n lastError = err;\n const errMsg = err instanceof Error ? err.message : String(err);\n attempts.push({\n provider: step.provider,\n model: step.model,\n status: \"error\",\n error: errMsg,\n latencyMs: Date.now() - t0\n });\n if (!isRetryableError(err)) {\n throw new Error(`chatbotlite: ${step.provider}/${step.model} failed (non-retryable). ${errMsg}`);\n }\n }\n }\n const summary = attempts.map((a) => `${a.provider}/${a.model}:${a.error ?? \"ok\"}`).join(\" → \");\n throw new Error(`chatbotlite: all chain steps failed. Trace: ${summary}. Last error: ${lastError instanceof Error ? lastError.message : String(lastError)}`);\n }\n\n private async callProvider(step: ChainStep, messages: Message[]): Promise<{ reply: string; usage?: { prompt_tokens?: number; completion_tokens?: number } }> {\n const endpoint = PROVIDER_ENDPOINTS[step.provider];\n const key = this.keys[step.provider];\n if (!key) throw new Error(`Missing API key for provider: ${step.provider}`);\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const res = await this.fetcher(`${endpoint.baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${key}`,\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n model: step.model,\n messages,\n temperature: 0.3,\n max_tokens: 300\n }),\n signal: controller.signal\n });\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`${res.status}: ${body.slice(0, 200)}`);\n }\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string; reasoning_content?: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n };\n const msg = data.choices?.[0]?.message;\n const reply = (msg?.content?.trim() || msg?.reasoning_content?.trim()) ?? \"\";\n if (!reply) throw new Error(\"empty reply from provider\");\n const result: { reply: string; usage?: { prompt_tokens?: number; completion_tokens?: number } } = { reply };\n if (data.usage) result.usage = data.usage;\n return result;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n/**\n * Resolve `ProviderConfig` into an ordered list of concrete `{ provider, model }` steps.\n *\n * If `chain` is provided, parses each entry as `\"provider/model\"` or `\"provider\"` (uses default model).\n * If `chain` is omitted, builds chain from `keys` insertion order, each using provider's default model.\n */\nfunction resolveChain(providers: ProviderConfig): ChainStep[] {\n const keys = providers.keys ?? {};\n const explicit = providers.chain;\n if (explicit && explicit.length > 0) {\n return explicit.map((entry) => normalizeChainEntry(entry, keys));\n }\n const orderedProviders = Object.keys(keys).filter((k) => isKnownProvider(k) && keys[k as Provider]) as Provider[];\n if (orderedProviders.length === 0) {\n throw new Error(\"chatbotlite: at least one provider key is required.\");\n }\n return orderedProviders.map((provider) => ({\n provider,\n model: PROVIDER_ENDPOINTS[provider].defaultModel,\n spec: `${provider}/${PROVIDER_ENDPOINTS[provider].defaultModel}`\n }));\n}\n\nfunction normalizeChainEntry(entry: ChainEntry, keys: Partial<Record<Provider, string>>): ChainStep {\n let provider: Provider;\n let model: string;\n let spec: string;\n if (typeof entry === \"string\") {\n const parsed = parseChainSpec(entry);\n provider = parsed.provider;\n model = parsed.model ?? PROVIDER_ENDPOINTS[provider].defaultModel;\n spec = entry;\n } else {\n if (!isKnownProvider(entry.provider)) {\n throw new Error(`chatbotlite: unknown provider \"${entry.provider}\" in chain entry.`);\n }\n provider = entry.provider;\n model = entry.model ?? PROVIDER_ENDPOINTS[provider].defaultModel;\n spec = `${provider}/${model}`;\n }\n if (!keys[provider]) {\n throw new Error(`chatbotlite: chain step \"${spec}\" needs a key for provider \"${provider}\" but none was provided.`);\n }\n return { provider, model, spec };\n}\n","import { useState, useRef, useEffect, useMemo, type ReactElement, type CSSProperties } from \"react\";\nimport type { BusinessConfig, Message } from \"../core/types.js\";\nimport { ChatBot } from \"../client/chatbot.js\";\nimport type { ProviderConfig } from \"../client/types.js\";\n\ninterface ChatWidgetCommonProps {\n /** Optional theme overrides. */\n theme?: {\n /** Brand color used on launcher, header, user message bubbles, send button. */\n primary?: string;\n /** Optional explicit text color for primary surfaces (defaults to white/contrast). */\n onPrimary?: string;\n };\n /** Header title shown when widget is open (defaults to business.name or \"Chat\"). */\n title?: string;\n /** Optional subtitle under the title (e.g. \"We typically reply in minutes\"). */\n subtitle?: string;\n /** Initial greeting (defaults to \"Hi! How can we help?\"). */\n greeting?: string;\n /** Show \"Powered by chatbotlite\" footer (default true). Free tier marker. */\n showBranding?: boolean;\n /** Position of the launcher bubble. */\n position?: \"bottom-right\" | \"bottom-left\";\n}\n\ninterface ChatWidgetDirectProps extends ChatWidgetCommonProps {\n /** Business config — name, services, hours, area, policies. */\n business: BusinessConfig;\n /** Provider chain + API keys (client-side mode). Keys WILL be exposed. */\n providers: ProviderConfig;\n endpoint?: never;\n}\n\ninterface ChatWidgetEndpointProps extends ChatWidgetCommonProps {\n /** POST URL of your server route (e.g. \"/api/chat\"). Server should accept { message, transcript } and return { reply }. */\n endpoint: string;\n business?: never;\n providers?: never;\n}\n\nexport type ChatWidgetProps = ChatWidgetDirectProps | ChatWidgetEndpointProps;\n\ninterface ChatMessage extends Message {\n id: string;\n ts: number;\n}\n\nconst BOLT = \"\\u26A1\";\nconst DEFAULT_PRIMARY = \"#0f172a\";\nconst DEFAULT_ON_PRIMARY = \"#ffffff\";\nconst SURFACE = \"#ffffff\";\nconst SURFACE_MUTED = \"#fafbfc\";\nconst BORDER = \"#e5e7eb\";\nconst TEXT_BODY = \"#0f172a\";\nconst TEXT_MUTED = \"#64748b\";\nconst TEXT_FAINT = \"#94a3b8\";\nconst FONT_STACK = `'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif`;\n\nconst STYLE_TAG_ID = \"chatbotlite-widget-styles\";\nconst KEYFRAMES = `\n@keyframes chatbotlite-pop { 0% { opacity: 0; transform: scale(0.6); } 100% { opacity: 1; transform: scale(1); } }\n@keyframes chatbotlite-slide { 0% { opacity: 0; transform: translateY(16px) scale(0.98); } 100% { opacity: 1; transform: translateY(0) scale(1); } }\n@keyframes chatbotlite-fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes chatbotlite-dot { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }\n.chatbotlite-launcher { transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 180ms cubic-bezier(0.4, 0, 0.2, 1); }\n.chatbotlite-launcher:hover { transform: translateY(-2px) scale(1.04); }\n.chatbotlite-launcher:active { transform: translateY(0) scale(0.98); }\n.chatbotlite-close { transition: background 120ms ease; }\n.chatbotlite-close:hover { background: rgba(255,255,255,0.16); }\n.chatbotlite-send { transition: transform 120ms ease, opacity 120ms ease, box-shadow 120ms ease; }\n.chatbotlite-send:not(:disabled):hover { transform: translateY(-1px); }\n.chatbotlite-send:not(:disabled):active { transform: translateY(0); }\n.chatbotlite-input:focus { box-shadow: 0 0 0 3px rgba(15,23,42,0.06); }\n.chatbotlite-msg { animation: chatbotlite-fade-in 220ms cubic-bezier(0.4, 0, 0.2, 1); }\n.chatbotlite-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: ${TEXT_FAINT}; margin-right: 4px; animation: chatbotlite-dot 1.2s ease-in-out infinite; }\n.chatbotlite-dot:nth-child(2) { animation-delay: 0.15s; }\n.chatbotlite-dot:nth-child(3) { animation-delay: 0.3s; margin-right: 0; }\n.chatbotlite-brand:hover { color: ${TEXT_MUTED} !important; }\n`;\n\nfunction ensureStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_TAG_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_TAG_ID;\n style.textContent = KEYFRAMES;\n document.head.appendChild(style);\n}\n\nexport function ChatWidget(props: ChatWidgetProps): ReactElement {\n const {\n theme: themeOverrides,\n title,\n subtitle,\n greeting,\n showBranding = true,\n position = \"bottom-right\"\n } = props;\n\n const isEndpointMode = \"endpoint\" in props && typeof props.endpoint === \"string\";\n const resolvedTitle = title ?? props.business?.name ?? \"Chat\";\n const resolvedGreeting = greeting ?? (props.business\n ? `Hi! I'm here for ${props.business.name}. How can we help?`\n : \"Hi! How can we help?\");\n\n const primary = themeOverrides?.primary ?? DEFAULT_PRIMARY;\n const onPrimary = themeOverrides?.onPrimary ?? DEFAULT_ON_PRIMARY;\n\n const [open, setOpen] = useState(false);\n const [messages, setMessages] = useState<ChatMessage[]>([\n { id: \"g0\", role: \"assistant\", content: resolvedGreeting, ts: Date.now() }\n ]);\n const [input, setInput] = useState(\"\");\n const [sending, setSending] = useState(false);\n const scrollRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => { ensureStyles(); }, []);\n\n const bot = useMemo(() => {\n if (isEndpointMode) return null;\n if (!props.business || !props.providers) return null;\n return new ChatBot({ business: props.business, providers: props.providers });\n }, [isEndpointMode, props.business, props.providers]);\n\n useEffect(() => {\n if (scrollRef.current) {\n scrollRef.current.scrollTop = scrollRef.current.scrollHeight;\n }\n }, [messages, sending, open]);\n\n useEffect(() => {\n if (open && inputRef.current) {\n const t = setTimeout(() => inputRef.current?.focus(), 240);\n return () => clearTimeout(t);\n }\n return undefined;\n }, [open]);\n\n async function fetchReplyFromEndpoint(text: string, history: Message[]): Promise<string> {\n const res = await fetch(props.endpoint!, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message: text, transcript: history })\n });\n if (!res.ok) throw new Error(`Endpoint ${res.status}: ${await res.text().catch(() => \"\")}`);\n const data = (await res.json()) as { reply?: string; error?: string };\n if (data.error) throw new Error(data.error);\n if (!data.reply) throw new Error(\"Endpoint returned no reply.\");\n return data.reply;\n }\n\n async function send(): Promise<void> {\n const text = input.trim();\n if (!text || sending) return;\n setInput(\"\");\n const userMsg: ChatMessage = { id: `u${Date.now()}`, role: \"user\", content: text, ts: Date.now() };\n setMessages((prev) => [...prev, userMsg]);\n setSending(true);\n try {\n const history: Message[] = messages\n .filter((m) => m.role !== \"system\")\n .map((m) => ({ role: m.role, content: m.content }));\n const reply = isEndpointMode\n ? await fetchReplyFromEndpoint(text, history)\n : (await bot!.reply(text, { history })).reply;\n setMessages((prev) => [...prev, { id: `a${Date.now()}`, role: \"assistant\", content: reply, ts: Date.now() }]);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n setMessages((prev) => [...prev, { id: `e${Date.now()}`, role: \"assistant\", content: `Sorry — something went wrong. (${errMsg})`, ts: Date.now() }]);\n } finally {\n setSending(false);\n }\n }\n\n const launcherPos: CSSProperties = position === \"bottom-left\" ? { left: 20 } : { right: 20 };\n const panelPos: CSSProperties = position === \"bottom-left\" ? { left: 20 } : { right: 20 };\n\n return (\n <>\n {!open && (\n <button\n className=\"chatbotlite-launcher\"\n onClick={() => setOpen(true)}\n aria-label=\"Open chat\"\n style={{\n position: \"fixed\",\n bottom: 20,\n ...launcherPos,\n width: 60,\n height: 60,\n borderRadius: 18,\n background: primary,\n color: onPrimary,\n border: \"none\",\n fontSize: 28,\n lineHeight: 1,\n cursor: \"pointer\",\n boxShadow: \"0 12px 28px -8px rgba(15,23,42,0.32), 0 4px 8px -2px rgba(15,23,42,0.12)\",\n zIndex: 99999,\n animation: \"chatbotlite-pop 320ms cubic-bezier(0.34, 1.56, 0.64, 1)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\"\n }}\n >\n <span style={{ filter: \"drop-shadow(0 1px 2px rgba(0,0,0,0.2))\" }}>{BOLT}</span>\n </button>\n )}\n\n {open && (\n <div\n role=\"dialog\"\n aria-label=\"Chat\"\n style={{\n position: \"fixed\",\n bottom: 20,\n ...panelPos,\n width: 380,\n maxWidth: \"calc(100vw - 40px)\",\n height: 580,\n maxHeight: \"calc(100vh - 40px)\",\n background: SURFACE,\n color: TEXT_BODY,\n borderRadius: 20,\n boxShadow: \"0 24px 60px -16px rgba(15,23,42,0.32), 0 8px 24px -8px rgba(15,23,42,0.12), 0 0 0 1px rgba(15,23,42,0.04)\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n fontFamily: FONT_STACK,\n zIndex: 99999,\n animation: \"chatbotlite-slide 280ms cubic-bezier(0.16, 1, 0.3, 1)\"\n }}\n >\n <header style={{\n padding: \"16px 18px\",\n background: primary,\n color: onPrimary,\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: 12\n }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", lineHeight: 1.2, minWidth: 0 }}>\n <span style={{ fontWeight: 600, fontSize: 15, letterSpacing: \"-0.01em\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {resolvedTitle}\n </span>\n {subtitle && (\n <span style={{ fontSize: 12, opacity: 0.7, marginTop: 2, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {subtitle}\n </span>\n )}\n </div>\n <button\n className=\"chatbotlite-close\"\n onClick={() => setOpen(false)}\n aria-label=\"Close chat\"\n style={{\n background: \"transparent\",\n border: \"none\",\n color: onPrimary,\n width: 32,\n height: 32,\n borderRadius: 10,\n fontSize: 22,\n lineHeight: 1,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0\n }}\n >\n {\"\\u00D7\"}\n </button>\n </header>\n\n <div\n ref={scrollRef}\n style={{\n flex: 1,\n overflowY: \"auto\",\n padding: \"16px 14px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n background: SURFACE_MUTED\n }}\n >\n {messages.map((m) => (\n <div\n key={m.id}\n className=\"chatbotlite-msg\"\n style={{\n alignSelf: m.role === \"user\" ? \"flex-end\" : \"flex-start\",\n maxWidth: \"82%\",\n padding: \"9px 13px\",\n borderRadius: m.role === \"user\" ? \"18px 18px 4px 18px\" : \"18px 18px 18px 4px\",\n background: m.role === \"user\" ? primary : SURFACE,\n color: m.role === \"user\" ? onPrimary : TEXT_BODY,\n border: m.role === \"user\" ? \"none\" : `1px solid ${BORDER}`,\n fontSize: 14,\n lineHeight: 1.5,\n letterSpacing: \"-0.005em\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n boxShadow: m.role === \"user\"\n ? \"0 1px 2px rgba(15,23,42,0.12)\"\n : \"0 1px 2px rgba(15,23,42,0.04)\"\n }}\n >\n {m.content}\n </div>\n ))}\n {sending && (\n <div\n className=\"chatbotlite-msg\"\n style={{\n alignSelf: \"flex-start\",\n padding: \"12px 14px\",\n borderRadius: \"18px 18px 18px 4px\",\n background: SURFACE,\n border: `1px solid ${BORDER}`,\n boxShadow: \"0 1px 2px rgba(15,23,42,0.04)\"\n }}\n >\n <span className=\"chatbotlite-dot\" />\n <span className=\"chatbotlite-dot\" />\n <span className=\"chatbotlite-dot\" />\n </div>\n )}\n </div>\n\n <div style={{\n display: \"flex\",\n padding: 12,\n gap: 8,\n background: SURFACE,\n borderTop: `1px solid ${BORDER}`\n }}>\n <input\n ref={inputRef}\n className=\"chatbotlite-input\"\n type=\"text\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && !e.shiftKey) { e.preventDefault(); void send(); } }}\n placeholder=\"Type a message…\"\n disabled={sending}\n style={{\n flex: 1,\n padding: \"10px 14px\",\n borderRadius: 12,\n border: `1px solid ${BORDER}`,\n background: SURFACE_MUTED,\n fontSize: 14,\n fontFamily: FONT_STACK,\n color: TEXT_BODY,\n outline: \"none\",\n transition: \"box-shadow 120ms ease, border-color 120ms ease\"\n }}\n />\n <button\n className=\"chatbotlite-send\"\n onClick={() => void send()}\n disabled={sending || !input.trim()}\n aria-label=\"Send message\"\n style={{\n padding: \"0 16px\",\n height: 40,\n minWidth: 64,\n borderRadius: 12,\n background: primary,\n color: onPrimary,\n border: \"none\",\n fontSize: 14,\n fontWeight: 600,\n fontFamily: FONT_STACK,\n cursor: sending || !input.trim() ? \"default\" : \"pointer\",\n opacity: sending || !input.trim() ? 0.4 : 1,\n boxShadow: \"0 2px 6px -1px rgba(15,23,42,0.18)\"\n }}\n >\n Send\n </button>\n </div>\n\n {showBranding && (\n <a\n className=\"chatbotlite-brand\"\n href=\"https://github.com/agents-io/chatbotlite\"\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{\n padding: \"8px 12px\",\n fontSize: 11,\n fontWeight: 500,\n color: TEXT_FAINT,\n textAlign: \"center\",\n textDecoration: \"none\",\n background: SURFACE,\n borderTop: `1px solid ${BORDER}`,\n letterSpacing: \"0.01em\",\n transition: \"color 120ms ease\"\n }}\n >\n {BOLT} Powered by chatbotlite\n </a>\n )}\n </div>\n )}\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/prompts.ts","../../src/core/guards.ts","../../src/client/types.ts","../../src/client/providers.ts","../../src/client/chatbot.ts","../../src/react/ChatWidget.tsx"],"names":["useState","useRef","useEffect","useMemo","jsxs","Fragment","jsx"],"mappings":";;;;;;;;AASO,SAAS,kBAAkB,SAAA,EAA8B;AAC9D,EAAA,OAAO;AAAA,IACL,wFAAA;AAAA,IACA,EAAA;AAAA,IACA,uBAAA;AAAA,IACA,UAAU,IAAA,EAAK;AAAA,IACf,EAAA;AAAA,IACA,gBAAA;AAAA,IACA,sDAAA;AAAA,IACA,uIAAA;AAAA,IACA,sGAAA;AAAA,IACA,kJAAA;AAAA,IACA,CAAA,iFAAA,CAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;;;AClBO,IAAM,iBAAA,GAAuC;AAAA,EAClD,gBAAA;AAAA,EACA,uBAAA;AAAA,EACA,0BAAA;AAAA,EACA,wBAAA;AAAA,EACA,qBAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,uBAAA;AAAA,EACA,+BAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,oBAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA,qBAAA;AAAA,EACA,oBAAA;AAAA,EACA,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA;AAMO,SAAS,sBAAsB,KAAA,EAA4B;AAChE,EAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,EAAY;AAChC,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,UAAU,iBAAA,EAAmB;AACtC,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG;AAC1B,MAAA,UAAA,CAAW,IAAA,CAAK,CAAA,mBAAA,EAAsB,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IACjD;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,UAAA,CAAW,MAAA,KAAW,GAAG,UAAA,EAAW;AACnD;AAMO,SAAS,eAAe,KAAA,EAAuB;AACpD,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,eAAe,CAAA;AAC7C,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,KAAM;AACnC,IAAA,MAAM,KAAA,GAAQ,EAAE,WAAA,EAAY;AAC5B,IAAA,OAAO,CAAC,kBAAkB,IAAA,CAAK,CAAC,MAAM,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,EACzD,CAAC,CAAA;AACD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACpC,EAAA,IAAI,OAAA,CAAQ,SAAS,EAAA,EAAI;AACvB,IAAA,OAAO,iFAAA;AAAA,EACT;AACA,EAAA,OAAO,OAAA;AACT;;;ACmBA,IAAM,cAAA,uBAA0C,GAAA,CAAI;AAAA,EAClD,QAAA;AAAA,EAAU,UAAA;AAAA,EAAY,MAAA;AAAA,EAAQ,QAAA;AAAA,EAAU,WAAA;AAAA,EACxC,UAAA;AAAA,EAAY,WAAA;AAAA,EAAa,WAAA;AAAA,EAAa,SAAA;AAAA,EAAW,YAAA;AAAA,EAAc;AACjE,CAAC,CAAA;AAEM,SAAS,gBAAgB,IAAA,EAAgC;AAC9D,EAAA,OAAO,cAAA,CAAe,IAAI,IAAI,CAAA;AAChC;;;AC3EO,IAAM,kBAAA,GAAyD;AAAA,EACpE,MAAA,EAAY,EAAE,OAAA,EAAS,2BAAA,EAA0D,cAAc,aAAA,EAAc;AAAA,EAC7G,QAAA,EAAY,EAAE,OAAA,EAAS,6BAAA,EAA0D,cAAc,eAAA,EAAgB;AAAA,EAC/G,IAAA,EAAY,EAAE,OAAA,EAAS,gCAAA,EAA0D,cAAc,yBAAA,EAA0B;AAAA,EACzH,MAAA,EAAY,EAAE,OAAA,EAAS,yDAAA,EAA2D,cAAc,kBAAA,EAAmB;AAAA,EACnH,SAAA,EAAY,EAAE,OAAA,EAAS,8BAAA,EAA0D,cAAc,kBAAA,EAAmB;AAAA,EAClH,QAAA,EAAY,EAAE,OAAA,EAAS,4BAAA,EAA0D,cAAc,gCAAA,EAAiC;AAAA,EAChI,SAAA,EAAY,EAAE,OAAA,EAAS,6BAAA,EAA0D,cAAc,6BAAA,EAA8B;AAAA,EAC7H,SAAA,EAAY,EAAE,OAAA,EAAS,uCAAA,EAA0D,cAAc,mDAAA,EAAoD;AAAA,EACnJ,OAAA,EAAY,EAAE,OAAA,EAAS,2BAAA,EAA0D,cAAc,sBAAA,EAAuB;AAAA,EACtH,UAAA,EAAY,EAAE,OAAA,EAAS,8BAAA,EAA0D,cAAc,wBAAA,EAAyB;AAAA,EACxH,QAAA,EAAY,EAAE,OAAA,EAAS,4BAAA,EAA0D,cAAc,iBAAA;AACjG,CAAA;AAEO,SAAS,iBAAiB,GAAA,EAAuB;AACtD,EAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,EAAA,OAAO,2EAAA,CAA4E,KAAK,GAAG,CAAA;AAC7F;;;ACwBO,IAAM,UAAN,MAAc;AAAA,EACF,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,kBAAA;AAAA,EAEjB,YAAY,IAAA,EAAmB;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,IAAa,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,IAAY,IAAA,CAAK,SAAA,CAAU,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AAC/F,MAAA,MAAM,IAAI,MAAM,mEAAmE,CAAA;AAAA,IACrF;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,IAAQ,EAAC;AACpC,IAAA,IAAA,CAAK,KAAA,GAAQ,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA;AACxC,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA,EAAS,SAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AACtE,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,OAAA,EAAS,SAAA,IAAa,GAAA;AAC5C,IAAA,IAAA,CAAK,kBAAA,GAAqB,iBAAA,CAAkB,IAAA,CAAK,SAAS,CAAA;AAAA,EAC5D;AAAA,EAEA,MAAM,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAqB,EAAC,EAAyB;AAC1E,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,YAAA,IAAgB,IAAA,CAAK,kBAAA;AAC/C,IAAA,MAAM,QAAA,GAAsB;AAAA,MAC1B,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,YAAA,EAAa;AAAA,MACxC,GAAI,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,MACrB,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,OAAA;AAAQ,KACnC;AACA,IAAA,MAAM,WAA0B,EAAC;AACjC,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,MAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,CAAa,MAAM,QAAQ,CAAA;AACrD,QAAA,QAAA,CAAS,IAAA,CAAK,EAAE,QAAA,EAAU,IAAA,CAAK,UAAU,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,MAAA,EAAQ,MAAM,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,GAAI,IAAI,CAAA;AACtG,QAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,MAAA,CAAO,KAAK,CAAA;AAChD,QAAA,MAAM,aAAa,KAAA,CAAM,EAAA,GAAK,OAAO,KAAA,GAAQ,cAAA,CAAe,OAAO,KAAK,CAAA;AACxE,QAAA,OAAO;AAAA,UACL,KAAA,EAAO,UAAA;AAAA,UACP,cAAc,IAAA,CAAK,QAAA;AAAA,UACnB,WAAW,IAAA,CAAK,KAAA;AAAA,UAChB,GAAI,OAAO,KAAA,GAAQ,EAAE,OAAO,MAAA,CAAO,KAAA,KAAU,EAAC;AAAA,UAC9C,eAAe,KAAA,CAAM,UAAA;AAAA,UACrB;AAAA,SACF;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,SAAA,GAAY,GAAA;AACZ,QAAA,MAAM,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC9D,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,MAAA,EAAQ,OAAA;AAAA,UACR,KAAA,EAAO,MAAA;AAAA,UACP,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,SACzB,CAAA;AACD,QAAA,IAAI,CAAC,gBAAA,CAAiB,GAAG,CAAA,EAAG;AAC1B,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgB,KAAK,KAAK,CAAA,yBAAA,EAA4B,MAAM,CAAA,CAAE,CAAA;AAAA,QAChF;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,UAAU,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,EAAE,QAAQ,CAAA,CAAA,EAAI,CAAA,CAAE,KAAK,IAAI,CAAA,CAAE,KAAA,IAAS,IAAI,CAAA,CAAE,CAAA,CAAE,KAAK,UAAK,CAAA;AAC7F,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4CAAA,EAA+C,OAAO,CAAA,cAAA,EAAiB,SAAA,YAAqB,KAAA,GAAQ,SAAA,CAAU,OAAA,GAAU,MAAA,CAAO,SAAS,CAAC,CAAA,CAAE,CAAA;AAAA,EAC7J;AAAA,EAEA,MAAc,YAAA,CAAa,IAAA,EAAiB,QAAA,EAAiH;AAC3J,IAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,IAAA,CAAK,QAAQ,CAAA;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AACnC,IAAA,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,CAAA,8BAAA,EAAiC,IAAA,CAAK,QAAQ,CAAA,CAAE,CAAA;AAE1E,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,WAAW,KAAA,EAAM,EAAG,KAAK,SAAS,CAAA;AACjE,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,IAAA,CAAK,QAAQ,CAAA,EAAG,QAAA,CAAS,OAAO,CAAA,iBAAA,CAAA,EAAqB;AAAA,QACrE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,eAAA,EAAiB,UAAU,GAAG,CAAA,CAAA;AAAA,UAC9B,cAAA,EAAgB;AAAA,SAClB;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,QAAA;AAAA,UACA,WAAA,EAAa,GAAA;AAAA,UACb,UAAA,EAAY;AAAA,SACb,CAAA;AAAA,QACD,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,MACxD;AACA,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAI7B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,GAAU,CAAC,CAAA,EAAG,OAAA;AAC/B,MAAA,MAAM,KAAA,GAAA,CAAS,KAAK,OAAA,EAAS,IAAA,MAAU,GAAA,EAAK,iBAAA,EAAmB,MAAK,KAAM,EAAA;AAC1E,MAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,MAAM,2BAA2B,CAAA;AACvD,MAAA,MAAM,MAAA,GAA4F,EAAE,KAAA,EAAM;AAC1G,MAAA,IAAI,IAAA,CAAK,KAAA,EAAO,MAAA,CAAO,KAAA,GAAQ,IAAA,CAAK,KAAA;AACpC,MAAA,OAAO,MAAA;AAAA,IACT,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAA;AAEA,SAAS,aAAa,SAAA,EAAwC;AAC5D,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,IAAQ,EAAC;AAChC,EAAA,MAAM,WAAW,SAAA,CAAU,KAAA;AAC3B,EAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AACnC,IAAA,OAAO,SAAS,GAAA,CAAI,CAAC,UAAU,mBAAA,CAAoB,KAAA,EAAO,IAAI,CAAC,CAAA;AAAA,EACjE;AACA,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,eAAA,CAAgB,CAAC,CAAA,IAAK,IAAA,CAAK,CAAa,CAAC,CAAA;AAClG,EAAA,IAAI,gBAAA,CAAiB,WAAW,CAAA,EAAG;AACjC,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,gBAAA,CAAiB,GAAA,CAAI,CAAC,QAAA,MAAc;AAAA,IACzC,QAAA;AAAA,IACA,KAAA,EAAO,kBAAA,CAAmB,QAAQ,CAAA,CAAE,YAAA;AAAA,IACpC,OAAO,CAAA,EAAG,QAAQ,IAAI,kBAAA,CAAmB,QAAQ,EAAE,YAAY,CAAA;AAAA,GACjE,CAAE,CAAA;AACJ;AAEA,SAAS,mBAAA,CAAoB,OAAmB,IAAA,EAAoD;AAClG,EAAA,IAAI,CAAC,eAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA,EAAG;AACpC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+BAAA,EAAkC,KAAA,CAAM,QAAQ,CAAA,iBAAA,CAAmB,CAAA;AAAA,EACrF;AACA,EAAA,MAAM,WAAW,KAAA,CAAM,QAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,IAAS,kBAAA,CAAmB,QAAQ,CAAA,CAAE,YAAA;AAC1D,EAAA,IAAI,CAAC,IAAA,CAAK,QAAQ,CAAA,EAAG;AACnB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,QAAQ,CAAA,yCAAA,CAA2C,CAAA;AAAA,EACtG;AACA,EAAA,OAAO,EAAE,UAAU,KAAA,EAAO,KAAA,EAAO,GAAG,QAAQ,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAG;AAC1D;ACvIA,IAAM,IAAA,GAAO,QAAA;AACb,IAAM,eAAA,GAAkB,SAAA;AACxB,IAAM,kBAAA,GAAqB,SAAA;AAC3B,IAAM,OAAA,GAAU,SAAA;AAChB,IAAM,aAAA,GAAgB,SAAA;AACtB,IAAM,MAAA,GAAS,SAAA;AACf,IAAM,SAAA,GAAY,SAAA;AAClB,IAAM,UAAA,GAAa,SAAA;AACnB,IAAM,UAAA,GAAa,SAAA;AACnB,IAAM,UAAA,GAAa,CAAA,mGAAA,CAAA;AAEnB,IAAM,YAAA,GAAe,2BAAA;AACrB,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mGAAA,EAemF,UAAU,CAAA;AAAA;AAAA;AAAA,kCAAA,EAG3E,UAAU,CAAA;AAAA,CAAA;AAG9C,SAAS,YAAA,GAAqB;AAC5B,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAe,YAAY,CAAA,EAAG;AAC3C,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAK,YAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc,SAAA;AACpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;AAEO,SAAS,WAAW,KAAA,EAAsC;AAC/D,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,cAAA;AAAA,IACP,KAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA,GAAe,IAAA;AAAA,IACf,QAAA,GAAW;AAAA,GACb,GAAI,KAAA;AAEJ,EAAA,MAAM,cAAA,GAAiB,UAAA,IAAc,KAAA,IAAS,OAAO,MAAM,QAAA,KAAa,QAAA;AACxE,EAAA,MAAM,gBAAgB,KAAA,IAAS,MAAA;AAC/B,EAAA,MAAM,mBAAmB,QAAA,IAAY,sBAAA;AAErC,EAAA,MAAM,OAAA,GAAU,gBAAgB,OAAA,IAAW,eAAA;AAC3C,EAAA,MAAM,SAAA,GAAY,gBAAgB,SAAA,IAAa,kBAAA;AAE/C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAS,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAA,CAAwB;AAAA,IACtD,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,WAAA,EAAa,SAAS,gBAAA,EAAkB,EAAA,EAAI,IAAA,CAAK,GAAA,EAAI;AAAE,GAC1E,CAAA;AACD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,SAAA,GAAYC,aAAuB,IAAI,CAAA;AAC7C,EAAA,MAAM,QAAA,GAAWA,aAAyB,IAAI,CAAA;AAE9C,EAAAC,eAAA,CAAU,MAAM;AAAE,IAAA,YAAA,EAAa;AAAA,EAAG,CAAA,EAAG,EAAE,CAAA;AAEvC,EAAA,MAAM,GAAA,GAAMC,cAAQ,MAAM;AACxB,IAAA,IAAI,gBAAgB,OAAO,IAAA;AAC3B,IAAA,IAAI,CAAC,KAAA,CAAM,SAAA,IAAa,CAAC,KAAA,CAAM,WAAW,OAAO,IAAA;AACjD,IAAA,OAAO,IAAI,QAAQ,EAAE,SAAA,EAAW,MAAM,SAAA,EAAW,SAAA,EAAW,KAAA,CAAM,SAAA,EAAW,CAAA;AAAA,EAC/E,GAAG,CAAC,cAAA,EAAgB,MAAM,SAAA,EAAW,KAAA,CAAM,SAAS,CAAC,CAAA;AAErD,EAAAD,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,SAAA,CAAU,OAAA,CAAQ,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,YAAA;AAAA,IAClD;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,OAAA,EAAS,IAAI,CAAC,CAAA;AAE5B,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,IAAQ,SAAS,OAAA,EAAS;AAC5B,MAAA,MAAM,IAAI,UAAA,CAAW,MAAM,SAAS,OAAA,EAAS,KAAA,IAAS,GAAG,CAAA;AACzD,MAAA,OAAO,MAAM,aAAa,CAAC,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,eAAe,sBAAA,CAAuB,MAAc,OAAA,EAAqC;AACvF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,KAAA,CAAM,QAAA,EAAW;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU,EAAE,SAAS,IAAA,EAAM,UAAA,EAAY,SAAS;AAAA,KAC5D,CAAA;AACD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,QAAU,IAAI,KAAA,CAAM,YAAY,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,MAAM,IAAI,IAAA,EAAK,CAAE,MAAM,MAAM,EAAE,CAAC,CAAA,CAAE,CAAA;AAC1F,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,IAAA,IAAI,KAAK,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,KAAK,KAAK,CAAA;AAC1C,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAC9D,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAEA,EAAA,eAAe,IAAA,GAAsB;AACnC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,EAAK;AACxB,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AACtB,IAAA,QAAA,CAAS,EAAE,CAAA;AACX,IAAA,MAAM,OAAA,GAAuB,EAAE,EAAA,EAAI,CAAA,CAAA,EAAI,KAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,EAAM,QAAQ,OAAA,EAAS,IAAA,EAAM,EAAA,EAAI,IAAA,CAAK,KAAI,EAAE;AACjG,IAAA,WAAA,CAAY,CAAC,IAAA,KAAS,CAAC,GAAG,IAAA,EAAM,OAAO,CAAC,CAAA;AACxC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,MAAM,UAAqB,QAAA,CACxB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,QAAQ,CAAA,CACjC,IAAI,CAAC,CAAA,MAAO,EAAE,IAAA,EAAM,CAAA,CAAE,MAAM,OAAA,EAAS,CAAA,CAAE,SAAQ,CAAE,CAAA;AACpD,MAAA,MAAM,KAAA,GAAQ,cAAA,GACV,MAAM,sBAAA,CAAuB,MAAM,OAAO,CAAA,GAAA,CACzC,MAAM,GAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,OAAA,EAAS,CAAA,EAAG,KAAA;AAC1C,MAAA,WAAA,CAAY,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,EAAA,EAAI,IAAI,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,EAAM,aAAa,OAAA,EAAS,KAAA,EAAO,IAAI,IAAA,CAAK,GAAA,EAAI,EAAG,CAAC,CAAA;AAAA,IAC9G,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC9D,MAAA,WAAA,CAAY,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,EAAA,EAAI,CAAA,CAAA,EAAI,IAAA,CAAK,GAAA,EAAK,IAAI,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,CAAA,oCAAA,EAAkC,MAAM,CAAA,CAAA,CAAA,EAAK,IAAI,IAAA,CAAK,GAAA,EAAI,EAAG,CAAC,CAAA;AAAA,IACpJ,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAA6B,aAAa,aAAA,GAAgB,EAAE,MAAM,EAAA,EAAG,GAAI,EAAE,KAAA,EAAO,EAAA,EAAG;AAC3F,EAAA,MAAM,QAAA,GAA0B,aAAa,aAAA,GAAgB,EAAE,MAAM,EAAA,EAAG,GAAI,EAAE,KAAA,EAAO,EAAA,EAAG;AAExF,EAAA,uBACEE,eAAA,CAAAC,mBAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,CAAC,IAAA,oBACAC,cAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,sBAAA;AAAA,QACV,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAC3B,YAAA,EAAW,WAAA;AAAA,QACX,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,OAAA;AAAA,UACV,MAAA,EAAQ,EAAA;AAAA,UACR,GAAG,WAAA;AAAA,UACH,KAAA,EAAO,EAAA;AAAA,UACP,MAAA,EAAQ,EAAA;AAAA,UACR,YAAA,EAAc,EAAA;AAAA,UACd,UAAA,EAAY,OAAA;AAAA,UACZ,KAAA,EAAO,SAAA;AAAA,UACP,MAAA,EAAQ,MAAA;AAAA,UACR,QAAA,EAAU,EAAA;AAAA,UACV,UAAA,EAAY,CAAA;AAAA,UACZ,MAAA,EAAQ,SAAA;AAAA,UACR,SAAA,EAAW,0EAAA;AAAA,UACX,MAAA,EAAQ,KAAA;AAAA,UACR,SAAA,EAAW,yDAAA;AAAA,UACX,OAAA,EAAS,MAAA;AAAA,UACT,UAAA,EAAY,QAAA;AAAA,UACZ,cAAA,EAAgB;AAAA,SAClB;AAAA,QAEA,yCAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,MAAA,EAAQ,wCAAA,IAA6C,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA,KAC3E;AAAA,IAGD,IAAA,oBACCF,eAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,MAAA;AAAA,QACX,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,OAAA;AAAA,UACV,MAAA,EAAQ,EAAA;AAAA,UACR,GAAG,QAAA;AAAA,UACH,KAAA,EAAO,GAAA;AAAA,UACP,QAAA,EAAU,oBAAA;AAAA,UACV,MAAA,EAAQ,GAAA;AAAA,UACR,SAAA,EAAW,oBAAA;AAAA,UACX,UAAA,EAAY,OAAA;AAAA,UACZ,KAAA,EAAO,SAAA;AAAA,UACP,YAAA,EAAc,EAAA;AAAA,UACd,SAAA,EAAW,2GAAA;AAAA,UACX,OAAA,EAAS,MAAA;AAAA,UACT,aAAA,EAAe,QAAA;AAAA,UACf,QAAA,EAAU,QAAA;AAAA,UACV,UAAA,EAAY,UAAA;AAAA,UACZ,MAAA,EAAQ,KAAA;AAAA,UACR,SAAA,EAAW;AAAA,SACb;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAA,eAAA,CAAC,YAAO,KAAA,EAAO;AAAA,YACb,OAAA,EAAS,WAAA;AAAA,YACT,UAAA,EAAY,OAAA;AAAA,YACZ,KAAA,EAAO,SAAA;AAAA,YACP,OAAA,EAAS,MAAA;AAAA,YACT,cAAA,EAAgB,eAAA;AAAA,YAChB,UAAA,EAAY,QAAA;AAAA,YACZ,GAAA,EAAK;AAAA,WACP,EACE,QAAA,EAAA;AAAA,4BAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,aAAA,EAAe,QAAA,EAAU,UAAA,EAAY,GAAA,EAAK,QAAA,EAAU,CAAA,EAAE,EACnF,QAAA,EAAA;AAAA,8BAAAE,cAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAA,EAAY,GAAA,EAAK,UAAU,EAAA,EAAI,aAAA,EAAe,SAAA,EAAW,QAAA,EAAU,UAAU,YAAA,EAAc,UAAA,EAAY,UAAA,EAAY,QAAA,IAC/H,QAAA,EAAA,aAAA,EACH,CAAA;AAAA,cACC,4BACCA,cAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,QAAA,EAAU,IAAI,OAAA,EAAS,GAAA,EAAK,SAAA,EAAW,CAAA,EAAG,UAAU,QAAA,EAAU,YAAA,EAAc,YAAY,UAAA,EAAY,QAAA,IAChH,QAAA,EAAA,QAAA,EACH;AAAA,aAAA,EAEJ,CAAA;AAAA,4BACAA,cAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,mBAAA;AAAA,gBACV,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,gBAC5B,YAAA,EAAW,YAAA;AAAA,gBACX,KAAA,EAAO;AAAA,kBACL,UAAA,EAAY,aAAA;AAAA,kBACZ,MAAA,EAAQ,MAAA;AAAA,kBACR,KAAA,EAAO,SAAA;AAAA,kBACP,KAAA,EAAO,EAAA;AAAA,kBACP,MAAA,EAAQ,EAAA;AAAA,kBACR,YAAA,EAAc,EAAA;AAAA,kBACd,QAAA,EAAU,EAAA;AAAA,kBACV,UAAA,EAAY,CAAA;AAAA,kBACZ,MAAA,EAAQ,SAAA;AAAA,kBACR,OAAA,EAAS,MAAA;AAAA,kBACT,UAAA,EAAY,QAAA;AAAA,kBACZ,cAAA,EAAgB,QAAA;AAAA,kBAChB,UAAA,EAAY;AAAA,iBACd;AAAA,gBAEC,QAAA,EAAA;AAAA;AAAA;AACH,WAAA,EACF,CAAA;AAAA,0BAEAF,eAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,SAAA;AAAA,cACL,KAAA,EAAO;AAAA,gBACL,IAAA,EAAM,CAAA;AAAA,gBACN,SAAA,EAAW,MAAA;AAAA,gBACX,OAAA,EAAS,WAAA;AAAA,gBACT,OAAA,EAAS,MAAA;AAAA,gBACT,aAAA,EAAe,QAAA;AAAA,gBACf,GAAA,EAAK,CAAA;AAAA,gBACL,UAAA,EAAY;AAAA,eACd;AAAA,cAEC,QAAA,EAAA;AAAA,gBAAA,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,qBACbE,cAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBAEC,SAAA,EAAU,iBAAA;AAAA,oBACV,KAAA,EAAO;AAAA,sBACL,SAAA,EAAW,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,UAAA,GAAa,YAAA;AAAA,sBAC5C,QAAA,EAAU,KAAA;AAAA,sBACV,OAAA,EAAS,UAAA;AAAA,sBACT,YAAA,EAAc,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,oBAAA,GAAuB,oBAAA;AAAA,sBACzD,UAAA,EAAY,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,OAAA,GAAU,OAAA;AAAA,sBAC1C,KAAA,EAAO,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,SAAA,GAAY,SAAA;AAAA,sBACvC,QAAQ,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,MAAA,GAAS,aAAa,MAAM,CAAA,CAAA;AAAA,sBACxD,QAAA,EAAU,EAAA;AAAA,sBACV,UAAA,EAAY,GAAA;AAAA,sBACZ,aAAA,EAAe,UAAA;AAAA,sBACf,UAAA,EAAY,UAAA;AAAA,sBACZ,SAAA,EAAW,YAAA;AAAA,sBACX,SAAA,EAAW,CAAA,CAAE,IAAA,KAAS,MAAA,GAClB,+BAAA,GACA;AAAA,qBACN;AAAA,oBAEC,QAAA,EAAA,CAAA,CAAE;AAAA,mBAAA;AAAA,kBApBE,CAAA,CAAE;AAAA,iBAsBV,CAAA;AAAA,gBACA,OAAA,oBACCF,eAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,iBAAA;AAAA,oBACV,KAAA,EAAO;AAAA,sBACL,SAAA,EAAW,YAAA;AAAA,sBACX,OAAA,EAAS,WAAA;AAAA,sBACT,YAAA,EAAc,oBAAA;AAAA,sBACd,UAAA,EAAY,OAAA;AAAA,sBACZ,MAAA,EAAQ,aAAa,MAAM,CAAA,CAAA;AAAA,sBAC3B,SAAA,EAAW;AAAA,qBACb;AAAA,oBAEA,QAAA,EAAA;AAAA,sCAAAE,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,iBAAA,EAAkB,CAAA;AAAA,sCAClCA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iBAAA,EAAkB,CAAA;AAAA,sCAClCA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iBAAA,EAAkB;AAAA;AAAA;AAAA;AACpC;AAAA;AAAA,WAEJ;AAAA,0BAEAF,eAAA,CAAC,SAAI,KAAA,EAAO;AAAA,YACV,OAAA,EAAS,MAAA;AAAA,YACT,OAAA,EAAS,EAAA;AAAA,YACT,GAAA,EAAK,CAAA;AAAA,YACL,UAAA,EAAY,OAAA;AAAA,YACZ,SAAA,EAAW,aAAa,MAAM,CAAA;AAAA,WAChC,EACE,QAAA,EAAA;AAAA,4BAAAE,cAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,QAAA;AAAA,gBACL,SAAA,EAAU,mBAAA;AAAA,gBACV,IAAA,EAAK,MAAA;AAAA,gBACL,KAAA,EAAO,KAAA;AAAA,gBACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,gBACxC,SAAA,EAAW,CAAC,CAAA,KAAM;AAAE,kBAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAC,EAAE,QAAA,EAAU;AAAE,oBAAA,CAAA,CAAE,cAAA,EAAe;AAAG,oBAAA,KAAK,IAAA,EAAK;AAAA,kBAAG;AAAA,gBAAE,CAAA;AAAA,gBAC/F,WAAA,EAAY,sBAAA;AAAA,gBACZ,QAAA,EAAU,OAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,IAAA,EAAM,CAAA;AAAA,kBACN,OAAA,EAAS,WAAA;AAAA,kBACT,YAAA,EAAc,EAAA;AAAA,kBACd,MAAA,EAAQ,aAAa,MAAM,CAAA,CAAA;AAAA,kBAC3B,UAAA,EAAY,aAAA;AAAA,kBACZ,QAAA,EAAU,EAAA;AAAA,kBACV,UAAA,EAAY,UAAA;AAAA,kBACZ,KAAA,EAAO,SAAA;AAAA,kBACP,OAAA,EAAS,MAAA;AAAA,kBACT,UAAA,EAAY;AAAA;AACd;AAAA,aACF;AAAA,4BACAA,cAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,kBAAA;AAAA,gBACV,OAAA,EAAS,MAAM,KAAK,IAAA,EAAK;AAAA,gBACzB,QAAA,EAAU,OAAA,IAAW,CAAC,KAAA,CAAM,IAAA,EAAK;AAAA,gBACjC,YAAA,EAAW,cAAA;AAAA,gBACX,KAAA,EAAO;AAAA,kBACL,OAAA,EAAS,QAAA;AAAA,kBACT,MAAA,EAAQ,EAAA;AAAA,kBACR,QAAA,EAAU,EAAA;AAAA,kBACV,YAAA,EAAc,EAAA;AAAA,kBACd,UAAA,EAAY,OAAA;AAAA,kBACZ,KAAA,EAAO,SAAA;AAAA,kBACP,MAAA,EAAQ,MAAA;AAAA,kBACR,QAAA,EAAU,EAAA;AAAA,kBACV,UAAA,EAAY,GAAA;AAAA,kBACZ,UAAA,EAAY,UAAA;AAAA,kBACZ,QAAQ,OAAA,IAAW,CAAC,KAAA,CAAM,IAAA,KAAS,SAAA,GAAY,SAAA;AAAA,kBAC/C,SAAS,OAAA,IAAW,CAAC,KAAA,CAAM,IAAA,KAAS,GAAA,GAAM,CAAA;AAAA,kBAC1C,SAAA,EAAW;AAAA,iBACb;AAAA,gBACD,QAAA,EAAA;AAAA;AAAA;AAED,WAAA,EACF,CAAA;AAAA,UAEC,YAAA,oBACCF,eAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,mBAAA;AAAA,cACV,IAAA,EAAK,0CAAA;AAAA,cACL,MAAA,EAAO,QAAA;AAAA,cACP,GAAA,EAAI,YAAA;AAAA,cACJ,KAAA,EAAO;AAAA,gBACL,OAAA,EAAS,UAAA;AAAA,gBACT,QAAA,EAAU,EAAA;AAAA,gBACV,UAAA,EAAY,GAAA;AAAA,gBACZ,KAAA,EAAO,UAAA;AAAA,gBACP,SAAA,EAAW,QAAA;AAAA,gBACX,cAAA,EAAgB,MAAA;AAAA,gBAChB,UAAA,EAAY,OAAA;AAAA,gBACZ,SAAA,EAAW,aAAa,MAAM,CAAA,CAAA;AAAA,gBAC9B,aAAA,EAAe,QAAA;AAAA,gBACf,UAAA,EAAY;AAAA,eACd;AAAA,cAEC,QAAA,EAAA;AAAA,gBAAA,IAAA;AAAA,gBAAK;AAAA;AAAA;AAAA;AACR;AAAA;AAAA;AAEJ,GAAA,EAEJ,CAAA;AAEJ","file":"index.cjs","sourcesContent":["import type { Knowledge } from \"./types.js\";\n\n/**\n * Build the system prompt by wrapping the user's markdown knowledge\n * with anti-hallucination rules and reply-style guidance.\n *\n * The markdown is injected verbatim — headings, lists, tables all preserved.\n * Works for any vertical because we don't enforce a schema.\n */\nexport function buildSystemPrompt(knowledge: Knowledge): string {\n return [\n \"You are an AI assistant on a business website. Use ONLY the knowledge below to answer.\",\n \"\",\n \"## Business knowledge\",\n knowledge.trim(),\n \"\",\n \"## Reply rules\",\n \"- Reply in 1-2 short sentences, conversational tone.\",\n \"- NEVER invent prices, availability, dispatch times, appointment confirmations, or facts not present in the business knowledge above.\",\n \"- For anything not covered in the knowledge above, say the owner will follow up — do NOT guess.\",\n '- If the caller is clearly a vendor/sales pitch, say: \"This does not look like a customer service request, so we will not continue this thread.\"',\n '- If wrong number or asked to stop, say: \"Sorry about that. We won\\'t text again.\"',\n \"- Match the caller's language automatically.\"\n ].join(\"\\n\");\n}\n","import type { GuardResult } from \"./types.js\";\n\n/**\n * Phrases that almost always indicate hallucination for SMB customer service:\n * inventing dispatch promises, fake confirmations, or appointment locks.\n */\nexport const FORBIDDEN_PHRASES: readonly string[] = [\n \"help is coming\",\n \"someone is on the way\",\n \"technician is on the way\",\n \"provider is on the way\",\n \"dispatching someone\",\n \"i've booked\",\n \"i have booked\",\n \"reservation confirmed\",\n \"your appointment is confirmed\",\n \"i've scheduled\",\n \"i have scheduled\",\n \"we've dispatched\",\n \"we have dispatched\",\n \"i can confirm\",\n \"i guarantee\",\n \"guaranteed delivery\",\n \"guaranteed arrival\",\n \"will arrive at\",\n \"arriving at\",\n \"i'll send\",\n \"i will send\"\n];\n\n/**\n * Check a reply against the built-in forbidden phrase list.\n * Returns ok=true when clean, ok=false with violations when not.\n */\nexport function checkForbiddenPhrases(reply: string): GuardResult {\n const lower = reply.toLowerCase();\n const violations: string[] = [];\n for (const phrase of FORBIDDEN_PHRASES) {\n if (lower.includes(phrase)) {\n violations.push(`Forbidden phrase: \"${phrase}\"`);\n }\n }\n return { ok: violations.length === 0, violations };\n}\n\n/**\n * Remove forbidden sentences from a reply (best-effort sentence drop).\n * If too much is removed, returns a safe fallback.\n */\nexport function stripForbidden(reply: string): string {\n const sentences = reply.split(/(?<=[.!?])\\s+/);\n const kept = sentences.filter((s) => {\n const lower = s.toLowerCase();\n return !FORBIDDEN_PHRASES.some((p) => lower.includes(p));\n });\n const trimmed = kept.join(\" \").trim();\n if (trimmed.length < 10) {\n return \"Thanks for reaching out — let me check with the owner and get back to you.\";\n }\n return trimmed;\n}\n","// Client types — provider + chain config\n\nexport type Provider =\n | \"openai\"\n | \"deepseek\"\n | \"groq\"\n | \"gemini\"\n | \"anthropic\"\n | \"cerebras\"\n | \"sambanova\"\n | \"fireworks\"\n | \"mistral\"\n | \"openrouter\"\n | \"moonshot\";\n\n/**\n * One step in the fallback chain. Provider is required; model defaults to the provider's preset.\n */\nexport interface ChainEntry {\n provider: Provider;\n model?: string;\n}\n\n/**\n * Provider configuration.\n *\n * `keys` are auth credentials (one key per provider — that key covers all that provider's models).\n * `chain` is the ordered fallback list. Each entry is `{ provider, model? }`.\n *\n * @example\n * ```ts\n * providers: {\n * keys: {\n * deepseek: \"sk-...\",\n * groq: \"gsk-...\",\n * openai: \"sk-...\"\n * },\n * chain: [\n * { provider: \"deepseek\", model: \"deepseek-chat\" },\n * { provider: \"groq\", model: \"llama-3.3-70b-versatile\" },\n * { provider: \"openai\", model: \"gpt-4o-mini\" }\n * ]\n * }\n * ```\n *\n * If `chain` is omitted, defaults to one entry per key (in insertion order) using each provider's\n * default model.\n */\nexport interface ProviderConfig {\n /** API keys per provider. One key covers all that provider's models. */\n keys: Partial<Record<Provider, string>>;\n /**\n * Ordered fallback chain. Each entry: `{ provider, model? }`.\n * Omit `model` to use the provider's default model.\n * Omit `chain` entirely to auto-build from keys.\n */\n chain?: ChainEntry[];\n}\n\nexport interface ClientOptions {\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n}\n\nexport interface ChainStep {\n provider: Provider;\n model: string;\n /** Human-readable label used in attempt traces, e.g. `\"openai/gpt-4o-mini\"`. */\n label: string;\n}\n\nexport interface AttemptInfo {\n provider: Provider;\n model: string;\n status: \"ok\" | \"error\";\n error?: string;\n latencyMs: number;\n}\n\nconst PROVIDER_NAMES: ReadonlySet<string> = new Set([\n \"openai\", \"deepseek\", \"groq\", \"gemini\", \"anthropic\",\n \"cerebras\", \"sambanova\", \"fireworks\", \"mistral\", \"openrouter\", \"moonshot\"\n]);\n\nexport function isKnownProvider(name: string): name is Provider {\n return PROVIDER_NAMES.has(name);\n}\n","import type { Provider } from \"./types.js\";\n\nexport interface ProviderEndpoint {\n baseUrl: string;\n defaultModel: string;\n}\n\n/**\n * Built-in OpenAI-compatible providers. All use /v1/chat/completions\n * with response in OpenAI format. Caller supplies API key per provider.\n */\nexport const PROVIDER_ENDPOINTS: Record<Provider, ProviderEndpoint> = {\n openai: { baseUrl: \"https://api.openai.com/v1\", defaultModel: \"gpt-4o-mini\" },\n deepseek: { baseUrl: \"https://api.deepseek.com/v1\", defaultModel: \"deepseek-chat\" },\n groq: { baseUrl: \"https://api.groq.com/openai/v1\", defaultModel: \"llama-3.3-70b-versatile\" },\n gemini: { baseUrl: \"https://generativelanguage.googleapis.com/v1beta/openai\", defaultModel: \"gemini-2.5-flash\" },\n anthropic: { baseUrl: \"https://api.anthropic.com/v1\", defaultModel: \"claude-haiku-4-5\" },\n cerebras: { baseUrl: \"https://api.cerebras.ai/v1\", defaultModel: \"qwen-3-235b-a22b-instruct-2507\" },\n sambanova: { baseUrl: \"https://api.sambanova.ai/v1\", defaultModel: \"Meta-Llama-3.3-70B-Instruct\" },\n fireworks: { baseUrl: \"https://api.fireworks.ai/inference/v1\", defaultModel: \"accounts/fireworks/models/llama-v3p3-70b-instruct\" },\n mistral: { baseUrl: \"https://api.mistral.ai/v1\", defaultModel: \"mistral-small-latest\" },\n openrouter: { baseUrl: \"https://openrouter.ai/api/v1\", defaultModel: \"deepseek/deepseek-chat\" },\n moonshot: { baseUrl: \"https://api.moonshot.ai/v1\", defaultModel: \"moonshot-v1-32k\" }\n};\n\nexport function isRetryableError(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err);\n return /\\b(429|rate.?limit|quota|exceed|5\\d\\d|timeout|ECONNRESET|fetch failed)\\b/i.test(msg);\n}\n","import type { Knowledge, Message } from \"../core/types.js\";\nimport { buildSystemPrompt } from \"../core/prompts.js\";\nimport { checkForbiddenPhrases, stripForbidden } from \"../core/guards.js\";\nimport type { Provider, ProviderConfig, ClientOptions, ChainStep, ChainEntry, AttemptInfo } from \"./types.js\";\nimport { isKnownProvider } from \"./types.js\";\nimport { PROVIDER_ENDPOINTS, isRetryableError } from \"./providers.js\";\n\nexport interface ChatBotInit {\n /** Markdown describing the business — services, hours, policies, anything. */\n knowledge: Knowledge;\n /** Provider keys + fallback chain. */\n providers: ProviderConfig;\n /** Optional runtime overrides. */\n options?: ClientOptions;\n}\n\nexport interface ReplyOptions {\n /** Conversation history (excluding the new user message). */\n history?: Message[];\n /** Override system prompt — advanced use only. */\n systemPrompt?: string;\n}\n\nexport interface ReplyResult {\n reply: string;\n /** Provider/model that produced the final reply (after fallback). */\n usedProvider: Provider;\n usedModel: string;\n /** Token usage if reported by the final provider. */\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n /** Guard violations the bot caught and stripped, if any. */\n guardWarnings: string[];\n /** Debug trace of every attempt in the chain. */\n attempts: AttemptInfo[];\n}\n\n/**\n * The main ChatBot entry. Holds knowledge + provider chain.\n *\n * @example\n * const bot = new ChatBot({\n * knowledge: `# Acme Plumbing\\n## Services\\n- Sink leak: $95`,\n * providers: {\n * keys: { deepseek: \"sk-...\", openai: \"sk-...\" },\n * chain: [\n * { provider: \"deepseek\", model: \"deepseek-chat\" },\n * { provider: \"openai\", model: \"gpt-4o-mini\" }\n * ]\n * }\n * });\n * const { reply } = await bot.reply(\"My sink is leaking\");\n */\nexport class ChatBot {\n private readonly steps: ChainStep[];\n private readonly keys: Partial<Record<Provider, string>>;\n private readonly fetcher: typeof globalThis.fetch;\n private readonly timeoutMs: number;\n private readonly cachedSystemPrompt: string;\n\n constructor(init: ChatBotInit) {\n if (!init.knowledge || typeof init.knowledge !== \"string\" || init.knowledge.trim().length === 0) {\n throw new Error(\"chatbotlite: knowledge is required (a non-empty markdown string).\");\n }\n this.keys = init.providers.keys ?? {};\n this.steps = resolveChain(init.providers);\n this.fetcher = init.options?.fetch ?? globalThis.fetch.bind(globalThis);\n this.timeoutMs = init.options?.timeoutMs ?? 30_000;\n this.cachedSystemPrompt = buildSystemPrompt(init.knowledge);\n }\n\n async reply(message: string, opts: ReplyOptions = {}): Promise<ReplyResult> {\n const systemPrompt = opts.systemPrompt ?? this.cachedSystemPrompt;\n const messages: Message[] = [\n { role: \"system\", content: systemPrompt },\n ...(opts.history ?? []),\n { role: \"user\", content: message }\n ];\n const attempts: AttemptInfo[] = [];\n let lastError: unknown;\n for (const step of this.steps) {\n const t0 = Date.now();\n try {\n const result = await this.callProvider(step, messages);\n attempts.push({ provider: step.provider, model: step.model, status: \"ok\", latencyMs: Date.now() - t0 });\n const guard = checkForbiddenPhrases(result.reply);\n const finalReply = guard.ok ? result.reply : stripForbidden(result.reply);\n return {\n reply: finalReply,\n usedProvider: step.provider,\n usedModel: step.model,\n ...(result.usage ? { usage: result.usage } : {}),\n guardWarnings: guard.violations,\n attempts\n };\n } catch (err) {\n lastError = err;\n const errMsg = err instanceof Error ? err.message : String(err);\n attempts.push({\n provider: step.provider,\n model: step.model,\n status: \"error\",\n error: errMsg,\n latencyMs: Date.now() - t0\n });\n if (!isRetryableError(err)) {\n throw new Error(`chatbotlite: ${step.label} failed (non-retryable). ${errMsg}`);\n }\n }\n }\n const summary = attempts.map((a) => `${a.provider}/${a.model}:${a.error ?? \"ok\"}`).join(\" → \");\n throw new Error(`chatbotlite: all chain steps failed. Trace: ${summary}. Last error: ${lastError instanceof Error ? lastError.message : String(lastError)}`);\n }\n\n private async callProvider(step: ChainStep, messages: Message[]): Promise<{ reply: string; usage?: { prompt_tokens?: number; completion_tokens?: number } }> {\n const endpoint = PROVIDER_ENDPOINTS[step.provider];\n const key = this.keys[step.provider];\n if (!key) throw new Error(`Missing API key for provider: ${step.provider}`);\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const res = await this.fetcher(`${endpoint.baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${key}`,\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n model: step.model,\n messages,\n temperature: 0.3,\n max_tokens: 300\n }),\n signal: controller.signal\n });\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`${res.status}: ${body.slice(0, 200)}`);\n }\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string; reasoning_content?: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n };\n const msg = data.choices?.[0]?.message;\n const reply = (msg?.content?.trim() || msg?.reasoning_content?.trim()) ?? \"\";\n if (!reply) throw new Error(\"empty reply from provider\");\n const result: { reply: string; usage?: { prompt_tokens?: number; completion_tokens?: number } } = { reply };\n if (data.usage) result.usage = data.usage;\n return result;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\nfunction resolveChain(providers: ProviderConfig): ChainStep[] {\n const keys = providers.keys ?? {};\n const explicit = providers.chain;\n if (explicit && explicit.length > 0) {\n return explicit.map((entry) => normalizeChainEntry(entry, keys));\n }\n const orderedProviders = Object.keys(keys).filter((k) => isKnownProvider(k) && keys[k as Provider]) as Provider[];\n if (orderedProviders.length === 0) {\n throw new Error(\"chatbotlite: at least one provider key is required.\");\n }\n return orderedProviders.map((provider) => ({\n provider,\n model: PROVIDER_ENDPOINTS[provider].defaultModel,\n label: `${provider}/${PROVIDER_ENDPOINTS[provider].defaultModel}`\n }));\n}\n\nfunction normalizeChainEntry(entry: ChainEntry, keys: Partial<Record<Provider, string>>): ChainStep {\n if (!isKnownProvider(entry.provider)) {\n throw new Error(`chatbotlite: unknown provider \"${entry.provider}\" in chain entry.`);\n }\n const provider = entry.provider;\n const model = entry.model ?? PROVIDER_ENDPOINTS[provider].defaultModel;\n if (!keys[provider]) {\n throw new Error(`chatbotlite: chain entry for \"${provider}\" needs a matching key in providers.keys.`);\n }\n return { provider, model, label: `${provider}/${model}` };\n}\n","import { useState, useRef, useEffect, useMemo, type ReactElement, type CSSProperties } from \"react\";\nimport type { Knowledge, Message } from \"../core/types.js\";\nimport { ChatBot } from \"../client/chatbot.js\";\nimport type { ProviderConfig } from \"../client/types.js\";\n\ninterface ChatWidgetCommonProps {\n /** Optional theme overrides. */\n theme?: {\n /** Brand color used on launcher, header, user message bubbles, send button. */\n primary?: string;\n /** Optional explicit text color for primary surfaces (defaults to white/contrast). */\n onPrimary?: string;\n };\n /** Header title shown when widget is open. */\n title?: string;\n /** Optional subtitle under the title (e.g. \"We typically reply in minutes\"). */\n subtitle?: string;\n /** Initial greeting (defaults to \"Hi! How can we help?\"). */\n greeting?: string;\n /** Show \"Powered by chatbotlite\" footer (default true). Free tier marker. */\n showBranding?: boolean;\n /** Position of the launcher bubble. */\n position?: \"bottom-right\" | \"bottom-left\";\n}\n\ninterface ChatWidgetDirectProps extends ChatWidgetCommonProps {\n /** Markdown knowledge for the bot. Client-side mode — API keys WILL be exposed. */\n knowledge: Knowledge;\n /** Provider chain + API keys. */\n providers: ProviderConfig;\n endpoint?: never;\n}\n\ninterface ChatWidgetEndpointProps extends ChatWidgetCommonProps {\n /** POST URL of your server route (e.g. \"/api/chat\"). Server should accept { message, transcript } and return { reply }. */\n endpoint: string;\n knowledge?: never;\n providers?: never;\n}\n\nexport type ChatWidgetProps = ChatWidgetDirectProps | ChatWidgetEndpointProps;\n\ninterface ChatMessage extends Message {\n id: string;\n ts: number;\n}\n\nconst BOLT = \"\\u26A1\";\nconst DEFAULT_PRIMARY = \"#0f172a\";\nconst DEFAULT_ON_PRIMARY = \"#ffffff\";\nconst SURFACE = \"#ffffff\";\nconst SURFACE_MUTED = \"#fafbfc\";\nconst BORDER = \"#e5e7eb\";\nconst TEXT_BODY = \"#0f172a\";\nconst TEXT_MUTED = \"#64748b\";\nconst TEXT_FAINT = \"#94a3b8\";\nconst FONT_STACK = `'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif`;\n\nconst STYLE_TAG_ID = \"chatbotlite-widget-styles\";\nconst KEYFRAMES = `\n@keyframes chatbotlite-pop { 0% { opacity: 0; transform: scale(0.6); } 100% { opacity: 1; transform: scale(1); } }\n@keyframes chatbotlite-slide { 0% { opacity: 0; transform: translateY(16px) scale(0.98); } 100% { opacity: 1; transform: translateY(0) scale(1); } }\n@keyframes chatbotlite-fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes chatbotlite-dot { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }\n.chatbotlite-launcher { transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 180ms cubic-bezier(0.4, 0, 0.2, 1); }\n.chatbotlite-launcher:hover { transform: translateY(-2px) scale(1.04); }\n.chatbotlite-launcher:active { transform: translateY(0) scale(0.98); }\n.chatbotlite-close { transition: background 120ms ease; }\n.chatbotlite-close:hover { background: rgba(255,255,255,0.16); }\n.chatbotlite-send { transition: transform 120ms ease, opacity 120ms ease, box-shadow 120ms ease; }\n.chatbotlite-send:not(:disabled):hover { transform: translateY(-1px); }\n.chatbotlite-send:not(:disabled):active { transform: translateY(0); }\n.chatbotlite-input:focus { box-shadow: 0 0 0 3px rgba(15,23,42,0.06); }\n.chatbotlite-msg { animation: chatbotlite-fade-in 220ms cubic-bezier(0.4, 0, 0.2, 1); }\n.chatbotlite-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: ${TEXT_FAINT}; margin-right: 4px; animation: chatbotlite-dot 1.2s ease-in-out infinite; }\n.chatbotlite-dot:nth-child(2) { animation-delay: 0.15s; }\n.chatbotlite-dot:nth-child(3) { animation-delay: 0.3s; margin-right: 0; }\n.chatbotlite-brand:hover { color: ${TEXT_MUTED} !important; }\n`;\n\nfunction ensureStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_TAG_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_TAG_ID;\n style.textContent = KEYFRAMES;\n document.head.appendChild(style);\n}\n\nexport function ChatWidget(props: ChatWidgetProps): ReactElement {\n const {\n theme: themeOverrides,\n title,\n subtitle,\n greeting,\n showBranding = true,\n position = \"bottom-right\"\n } = props;\n\n const isEndpointMode = \"endpoint\" in props && typeof props.endpoint === \"string\";\n const resolvedTitle = title ?? \"Chat\";\n const resolvedGreeting = greeting ?? \"Hi! How can we help?\";\n\n const primary = themeOverrides?.primary ?? DEFAULT_PRIMARY;\n const onPrimary = themeOverrides?.onPrimary ?? DEFAULT_ON_PRIMARY;\n\n const [open, setOpen] = useState(false);\n const [messages, setMessages] = useState<ChatMessage[]>([\n { id: \"g0\", role: \"assistant\", content: resolvedGreeting, ts: Date.now() }\n ]);\n const [input, setInput] = useState(\"\");\n const [sending, setSending] = useState(false);\n const scrollRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => { ensureStyles(); }, []);\n\n const bot = useMemo(() => {\n if (isEndpointMode) return null;\n if (!props.knowledge || !props.providers) return null;\n return new ChatBot({ knowledge: props.knowledge, providers: props.providers });\n }, [isEndpointMode, props.knowledge, props.providers]);\n\n useEffect(() => {\n if (scrollRef.current) {\n scrollRef.current.scrollTop = scrollRef.current.scrollHeight;\n }\n }, [messages, sending, open]);\n\n useEffect(() => {\n if (open && inputRef.current) {\n const t = setTimeout(() => inputRef.current?.focus(), 240);\n return () => clearTimeout(t);\n }\n return undefined;\n }, [open]);\n\n async function fetchReplyFromEndpoint(text: string, history: Message[]): Promise<string> {\n const res = await fetch(props.endpoint!, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message: text, transcript: history })\n });\n if (!res.ok) throw new Error(`Endpoint ${res.status}: ${await res.text().catch(() => \"\")}`);\n const data = (await res.json()) as { reply?: string; error?: string };\n if (data.error) throw new Error(data.error);\n if (!data.reply) throw new Error(\"Endpoint returned no reply.\");\n return data.reply;\n }\n\n async function send(): Promise<void> {\n const text = input.trim();\n if (!text || sending) return;\n setInput(\"\");\n const userMsg: ChatMessage = { id: `u${Date.now()}`, role: \"user\", content: text, ts: Date.now() };\n setMessages((prev) => [...prev, userMsg]);\n setSending(true);\n try {\n const history: Message[] = messages\n .filter((m) => m.role !== \"system\")\n .map((m) => ({ role: m.role, content: m.content }));\n const reply = isEndpointMode\n ? await fetchReplyFromEndpoint(text, history)\n : (await bot!.reply(text, { history })).reply;\n setMessages((prev) => [...prev, { id: `a${Date.now()}`, role: \"assistant\", content: reply, ts: Date.now() }]);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n setMessages((prev) => [...prev, { id: `e${Date.now()}`, role: \"assistant\", content: `Sorry — something went wrong. (${errMsg})`, ts: Date.now() }]);\n } finally {\n setSending(false);\n }\n }\n\n const launcherPos: CSSProperties = position === \"bottom-left\" ? { left: 20 } : { right: 20 };\n const panelPos: CSSProperties = position === \"bottom-left\" ? { left: 20 } : { right: 20 };\n\n return (\n <>\n {!open && (\n <button\n className=\"chatbotlite-launcher\"\n onClick={() => setOpen(true)}\n aria-label=\"Open chat\"\n style={{\n position: \"fixed\",\n bottom: 20,\n ...launcherPos,\n width: 60,\n height: 60,\n borderRadius: 18,\n background: primary,\n color: onPrimary,\n border: \"none\",\n fontSize: 28,\n lineHeight: 1,\n cursor: \"pointer\",\n boxShadow: \"0 12px 28px -8px rgba(15,23,42,0.32), 0 4px 8px -2px rgba(15,23,42,0.12)\",\n zIndex: 99999,\n animation: \"chatbotlite-pop 320ms cubic-bezier(0.34, 1.56, 0.64, 1)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\"\n }}\n >\n <span style={{ filter: \"drop-shadow(0 1px 2px rgba(0,0,0,0.2))\" }}>{BOLT}</span>\n </button>\n )}\n\n {open && (\n <div\n role=\"dialog\"\n aria-label=\"Chat\"\n style={{\n position: \"fixed\",\n bottom: 20,\n ...panelPos,\n width: 380,\n maxWidth: \"calc(100vw - 40px)\",\n height: 580,\n maxHeight: \"calc(100vh - 40px)\",\n background: SURFACE,\n color: TEXT_BODY,\n borderRadius: 20,\n boxShadow: \"0 24px 60px -16px rgba(15,23,42,0.32), 0 8px 24px -8px rgba(15,23,42,0.12), 0 0 0 1px rgba(15,23,42,0.04)\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n fontFamily: FONT_STACK,\n zIndex: 99999,\n animation: \"chatbotlite-slide 280ms cubic-bezier(0.16, 1, 0.3, 1)\"\n }}\n >\n <header style={{\n padding: \"16px 18px\",\n background: primary,\n color: onPrimary,\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: 12\n }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", lineHeight: 1.2, minWidth: 0 }}>\n <span style={{ fontWeight: 600, fontSize: 15, letterSpacing: \"-0.01em\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {resolvedTitle}\n </span>\n {subtitle && (\n <span style={{ fontSize: 12, opacity: 0.7, marginTop: 2, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {subtitle}\n </span>\n )}\n </div>\n <button\n className=\"chatbotlite-close\"\n onClick={() => setOpen(false)}\n aria-label=\"Close chat\"\n style={{\n background: \"transparent\",\n border: \"none\",\n color: onPrimary,\n width: 32,\n height: 32,\n borderRadius: 10,\n fontSize: 22,\n lineHeight: 1,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0\n }}\n >\n {\"\\u00D7\"}\n </button>\n </header>\n\n <div\n ref={scrollRef}\n style={{\n flex: 1,\n overflowY: \"auto\",\n padding: \"16px 14px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n background: SURFACE_MUTED\n }}\n >\n {messages.map((m) => (\n <div\n key={m.id}\n className=\"chatbotlite-msg\"\n style={{\n alignSelf: m.role === \"user\" ? \"flex-end\" : \"flex-start\",\n maxWidth: \"82%\",\n padding: \"9px 13px\",\n borderRadius: m.role === \"user\" ? \"18px 18px 4px 18px\" : \"18px 18px 18px 4px\",\n background: m.role === \"user\" ? primary : SURFACE,\n color: m.role === \"user\" ? onPrimary : TEXT_BODY,\n border: m.role === \"user\" ? \"none\" : `1px solid ${BORDER}`,\n fontSize: 14,\n lineHeight: 1.5,\n letterSpacing: \"-0.005em\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n boxShadow: m.role === \"user\"\n ? \"0 1px 2px rgba(15,23,42,0.12)\"\n : \"0 1px 2px rgba(15,23,42,0.04)\"\n }}\n >\n {m.content}\n </div>\n ))}\n {sending && (\n <div\n className=\"chatbotlite-msg\"\n style={{\n alignSelf: \"flex-start\",\n padding: \"12px 14px\",\n borderRadius: \"18px 18px 18px 4px\",\n background: SURFACE,\n border: `1px solid ${BORDER}`,\n boxShadow: \"0 1px 2px rgba(15,23,42,0.04)\"\n }}\n >\n <span className=\"chatbotlite-dot\" />\n <span className=\"chatbotlite-dot\" />\n <span className=\"chatbotlite-dot\" />\n </div>\n )}\n </div>\n\n <div style={{\n display: \"flex\",\n padding: 12,\n gap: 8,\n background: SURFACE,\n borderTop: `1px solid ${BORDER}`\n }}>\n <input\n ref={inputRef}\n className=\"chatbotlite-input\"\n type=\"text\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && !e.shiftKey) { e.preventDefault(); void send(); } }}\n placeholder=\"Type a message…\"\n disabled={sending}\n style={{\n flex: 1,\n padding: \"10px 14px\",\n borderRadius: 12,\n border: `1px solid ${BORDER}`,\n background: SURFACE_MUTED,\n fontSize: 14,\n fontFamily: FONT_STACK,\n color: TEXT_BODY,\n outline: \"none\",\n transition: \"box-shadow 120ms ease, border-color 120ms ease\"\n }}\n />\n <button\n className=\"chatbotlite-send\"\n onClick={() => void send()}\n disabled={sending || !input.trim()}\n aria-label=\"Send message\"\n style={{\n padding: \"0 16px\",\n height: 40,\n minWidth: 64,\n borderRadius: 12,\n background: primary,\n color: onPrimary,\n border: \"none\",\n fontSize: 14,\n fontWeight: 600,\n fontFamily: FONT_STACK,\n cursor: sending || !input.trim() ? \"default\" : \"pointer\",\n opacity: sending || !input.trim() ? 0.4 : 1,\n boxShadow: \"0 2px 6px -1px rgba(15,23,42,0.18)\"\n }}\n >\n Send\n </button>\n </div>\n\n {showBranding && (\n <a\n className=\"chatbotlite-brand\"\n href=\"https://github.com/agents-io/chatbotlite\"\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{\n padding: \"8px 12px\",\n fontSize: 11,\n fontWeight: 500,\n color: TEXT_FAINT,\n textAlign: \"center\",\n textDecoration: \"none\",\n background: SURFACE,\n borderTop: `1px solid ${BORDER}`,\n letterSpacing: \"0.01em\",\n transition: \"color 120ms ease\"\n }}\n >\n {BOLT} Powered by chatbotlite\n </a>\n )}\n </div>\n )}\n </>\n );\n}\n"]}
|
package/dist/react/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { c as ProviderConfig } from '../types-
|
|
2
|
+
import { K as Knowledge } from '../types-4alyzg8O.cjs';
|
|
3
|
+
import { c as ProviderConfig } from '../types-J7BXpiRU.cjs';
|
|
4
4
|
|
|
5
5
|
interface ChatWidgetCommonProps {
|
|
6
6
|
/** Optional theme overrides. */
|
|
@@ -10,7 +10,7 @@ interface ChatWidgetCommonProps {
|
|
|
10
10
|
/** Optional explicit text color for primary surfaces (defaults to white/contrast). */
|
|
11
11
|
onPrimary?: string;
|
|
12
12
|
};
|
|
13
|
-
/** Header title shown when widget is open
|
|
13
|
+
/** Header title shown when widget is open. */
|
|
14
14
|
title?: string;
|
|
15
15
|
/** Optional subtitle under the title (e.g. "We typically reply in minutes"). */
|
|
16
16
|
subtitle?: string;
|
|
@@ -22,16 +22,16 @@ interface ChatWidgetCommonProps {
|
|
|
22
22
|
position?: "bottom-right" | "bottom-left";
|
|
23
23
|
}
|
|
24
24
|
interface ChatWidgetDirectProps extends ChatWidgetCommonProps {
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
/** Provider chain + API keys
|
|
25
|
+
/** Markdown knowledge for the bot. Client-side mode — API keys WILL be exposed. */
|
|
26
|
+
knowledge: Knowledge;
|
|
27
|
+
/** Provider chain + API keys. */
|
|
28
28
|
providers: ProviderConfig;
|
|
29
29
|
endpoint?: never;
|
|
30
30
|
}
|
|
31
31
|
interface ChatWidgetEndpointProps extends ChatWidgetCommonProps {
|
|
32
32
|
/** POST URL of your server route (e.g. "/api/chat"). Server should accept { message, transcript } and return { reply }. */
|
|
33
33
|
endpoint: string;
|
|
34
|
-
|
|
34
|
+
knowledge?: never;
|
|
35
35
|
providers?: never;
|
|
36
36
|
}
|
|
37
37
|
type ChatWidgetProps = ChatWidgetDirectProps | ChatWidgetEndpointProps;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { c as ProviderConfig } from '../types-
|
|
2
|
+
import { K as Knowledge } from '../types-4alyzg8O.js';
|
|
3
|
+
import { c as ProviderConfig } from '../types-J7BXpiRU.js';
|
|
4
4
|
|
|
5
5
|
interface ChatWidgetCommonProps {
|
|
6
6
|
/** Optional theme overrides. */
|
|
@@ -10,7 +10,7 @@ interface ChatWidgetCommonProps {
|
|
|
10
10
|
/** Optional explicit text color for primary surfaces (defaults to white/contrast). */
|
|
11
11
|
onPrimary?: string;
|
|
12
12
|
};
|
|
13
|
-
/** Header title shown when widget is open
|
|
13
|
+
/** Header title shown when widget is open. */
|
|
14
14
|
title?: string;
|
|
15
15
|
/** Optional subtitle under the title (e.g. "We typically reply in minutes"). */
|
|
16
16
|
subtitle?: string;
|
|
@@ -22,16 +22,16 @@ interface ChatWidgetCommonProps {
|
|
|
22
22
|
position?: "bottom-right" | "bottom-left";
|
|
23
23
|
}
|
|
24
24
|
interface ChatWidgetDirectProps extends ChatWidgetCommonProps {
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
/** Provider chain + API keys
|
|
25
|
+
/** Markdown knowledge for the bot. Client-side mode — API keys WILL be exposed. */
|
|
26
|
+
knowledge: Knowledge;
|
|
27
|
+
/** Provider chain + API keys. */
|
|
28
28
|
providers: ProviderConfig;
|
|
29
29
|
endpoint?: never;
|
|
30
30
|
}
|
|
31
31
|
interface ChatWidgetEndpointProps extends ChatWidgetCommonProps {
|
|
32
32
|
/** POST URL of your server route (e.g. "/api/chat"). Server should accept { message, transcript } and return { reply }. */
|
|
33
33
|
endpoint: string;
|
|
34
|
-
|
|
34
|
+
knowledge?: never;
|
|
35
35
|
providers?: never;
|
|
36
36
|
}
|
|
37
37
|
type ChatWidgetProps = ChatWidgetDirectProps | ChatWidgetEndpointProps;
|
package/dist/react/index.js
CHANGED
|
@@ -4,56 +4,21 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
|
4
4
|
// src/react/ChatWidget.tsx
|
|
5
5
|
|
|
6
6
|
// src/core/prompts.ts
|
|
7
|
-
function buildSystemPrompt(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
parts.push(`Hours: ${business.hours}`);
|
|
23
|
-
}
|
|
24
|
-
if (business.serviceArea && business.serviceArea.length > 0) {
|
|
25
|
-
parts.push(`Service area: ${business.serviceArea.join(", ")}.`);
|
|
26
|
-
parts.push("If the caller is outside this area, say so and recommend owner review.");
|
|
27
|
-
}
|
|
28
|
-
if (business.policies && business.policies.length > 0) {
|
|
29
|
-
parts.push("");
|
|
30
|
-
parts.push("Known policies (use these exact answers when asked):");
|
|
31
|
-
for (const p of business.policies) {
|
|
32
|
-
parts.push(`- ${p.topic}: ${p.answer}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
parts.push("");
|
|
36
|
-
parts.push("Rules:");
|
|
37
|
-
parts.push("- Reply in 1-2 short sentences, conversational tone.");
|
|
38
|
-
parts.push("- NEVER invent prices, availability, dispatch times, or appointment confirmations.");
|
|
39
|
-
parts.push("- For anything not covered in the setup above, say it needs owner review.");
|
|
40
|
-
parts.push('- If the caller is clearly a vendor/sales pitch, say: "This does not look like a customer service request, so we will not continue this thread."');
|
|
41
|
-
parts.push(`- If wrong number or asked to stop, say: "Sorry about that. We won't text again."`);
|
|
42
|
-
if (business.doNotPromise && business.doNotPromise.length > 0) {
|
|
43
|
-
parts.push("");
|
|
44
|
-
parts.push("Never promise:");
|
|
45
|
-
for (const p of business.doNotPromise) parts.push(`- ${p}`);
|
|
46
|
-
}
|
|
47
|
-
if (business.customInstructions) {
|
|
48
|
-
parts.push("");
|
|
49
|
-
parts.push("Additional instructions:");
|
|
50
|
-
parts.push(business.customInstructions);
|
|
51
|
-
}
|
|
52
|
-
if (business.language && business.language !== "en") {
|
|
53
|
-
parts.push("");
|
|
54
|
-
parts.push(`Reply in ${business.language}.`);
|
|
55
|
-
}
|
|
56
|
-
return parts.join("\n");
|
|
7
|
+
function buildSystemPrompt(knowledge) {
|
|
8
|
+
return [
|
|
9
|
+
"You are an AI assistant on a business website. Use ONLY the knowledge below to answer.",
|
|
10
|
+
"",
|
|
11
|
+
"## Business knowledge",
|
|
12
|
+
knowledge.trim(),
|
|
13
|
+
"",
|
|
14
|
+
"## Reply rules",
|
|
15
|
+
"- Reply in 1-2 short sentences, conversational tone.",
|
|
16
|
+
"- NEVER invent prices, availability, dispatch times, appointment confirmations, or facts not present in the business knowledge above.",
|
|
17
|
+
"- For anything not covered in the knowledge above, say the owner will follow up \u2014 do NOT guess.",
|
|
18
|
+
'- If the caller is clearly a vendor/sales pitch, say: "This does not look like a customer service request, so we will not continue this thread."',
|
|
19
|
+
`- If wrong number or asked to stop, say: "Sorry about that. We won't text again."`,
|
|
20
|
+
"- Match the caller's language automatically."
|
|
21
|
+
].join("\n");
|
|
57
22
|
}
|
|
58
23
|
|
|
59
24
|
// src/core/guards.ts
|
|
@@ -117,24 +82,6 @@ var PROVIDER_NAMES = /* @__PURE__ */ new Set([
|
|
|
117
82
|
"openrouter",
|
|
118
83
|
"moonshot"
|
|
119
84
|
]);
|
|
120
|
-
function parseChainSpec(spec) {
|
|
121
|
-
const slash = spec.indexOf("/");
|
|
122
|
-
if (slash === -1) {
|
|
123
|
-
if (!PROVIDER_NAMES.has(spec)) {
|
|
124
|
-
throw new Error(`chatbotlite: unknown provider "${spec}". Use "provider/model" or a known provider name.`);
|
|
125
|
-
}
|
|
126
|
-
return { provider: spec, model: null };
|
|
127
|
-
}
|
|
128
|
-
const provider = spec.slice(0, slash);
|
|
129
|
-
const model = spec.slice(slash + 1);
|
|
130
|
-
if (!PROVIDER_NAMES.has(provider)) {
|
|
131
|
-
throw new Error(`chatbotlite: unknown provider "${provider}" in chain spec "${spec}".`);
|
|
132
|
-
}
|
|
133
|
-
if (!model) {
|
|
134
|
-
throw new Error(`chatbotlite: empty model name in chain spec "${spec}".`);
|
|
135
|
-
}
|
|
136
|
-
return { provider, model };
|
|
137
|
-
}
|
|
138
85
|
function isKnownProvider(name) {
|
|
139
86
|
return PROVIDER_NAMES.has(name);
|
|
140
87
|
}
|
|
@@ -160,19 +107,20 @@ function isRetryableError(err) {
|
|
|
160
107
|
|
|
161
108
|
// src/client/chatbot.ts
|
|
162
109
|
var ChatBot = class {
|
|
163
|
-
business;
|
|
164
110
|
steps;
|
|
165
111
|
keys;
|
|
166
112
|
fetcher;
|
|
167
113
|
timeoutMs;
|
|
168
114
|
cachedSystemPrompt;
|
|
169
115
|
constructor(init) {
|
|
170
|
-
|
|
116
|
+
if (!init.knowledge || typeof init.knowledge !== "string" || init.knowledge.trim().length === 0) {
|
|
117
|
+
throw new Error("chatbotlite: knowledge is required (a non-empty markdown string).");
|
|
118
|
+
}
|
|
171
119
|
this.keys = init.providers.keys ?? {};
|
|
172
120
|
this.steps = resolveChain(init.providers);
|
|
173
121
|
this.fetcher = init.options?.fetch ?? globalThis.fetch.bind(globalThis);
|
|
174
122
|
this.timeoutMs = init.options?.timeoutMs ?? 3e4;
|
|
175
|
-
this.cachedSystemPrompt = buildSystemPrompt(
|
|
123
|
+
this.cachedSystemPrompt = buildSystemPrompt(init.knowledge);
|
|
176
124
|
}
|
|
177
125
|
async reply(message, opts = {}) {
|
|
178
126
|
const systemPrompt = opts.systemPrompt ?? this.cachedSystemPrompt;
|
|
@@ -209,7 +157,7 @@ var ChatBot = class {
|
|
|
209
157
|
latencyMs: Date.now() - t0
|
|
210
158
|
});
|
|
211
159
|
if (!isRetryableError(err)) {
|
|
212
|
-
throw new Error(`chatbotlite: ${step.
|
|
160
|
+
throw new Error(`chatbotlite: ${step.label} failed (non-retryable). ${errMsg}`);
|
|
213
161
|
}
|
|
214
162
|
}
|
|
215
163
|
}
|
|
@@ -266,30 +214,19 @@ function resolveChain(providers) {
|
|
|
266
214
|
return orderedProviders.map((provider) => ({
|
|
267
215
|
provider,
|
|
268
216
|
model: PROVIDER_ENDPOINTS[provider].defaultModel,
|
|
269
|
-
|
|
217
|
+
label: `${provider}/${PROVIDER_ENDPOINTS[provider].defaultModel}`
|
|
270
218
|
}));
|
|
271
219
|
}
|
|
272
220
|
function normalizeChainEntry(entry, keys) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
let spec;
|
|
276
|
-
if (typeof entry === "string") {
|
|
277
|
-
const parsed = parseChainSpec(entry);
|
|
278
|
-
provider = parsed.provider;
|
|
279
|
-
model = parsed.model ?? PROVIDER_ENDPOINTS[provider].defaultModel;
|
|
280
|
-
spec = entry;
|
|
281
|
-
} else {
|
|
282
|
-
if (!isKnownProvider(entry.provider)) {
|
|
283
|
-
throw new Error(`chatbotlite: unknown provider "${entry.provider}" in chain entry.`);
|
|
284
|
-
}
|
|
285
|
-
provider = entry.provider;
|
|
286
|
-
model = entry.model ?? PROVIDER_ENDPOINTS[provider].defaultModel;
|
|
287
|
-
spec = `${provider}/${model}`;
|
|
221
|
+
if (!isKnownProvider(entry.provider)) {
|
|
222
|
+
throw new Error(`chatbotlite: unknown provider "${entry.provider}" in chain entry.`);
|
|
288
223
|
}
|
|
224
|
+
const provider = entry.provider;
|
|
225
|
+
const model = entry.model ?? PROVIDER_ENDPOINTS[provider].defaultModel;
|
|
289
226
|
if (!keys[provider]) {
|
|
290
|
-
throw new Error(`chatbotlite: chain
|
|
227
|
+
throw new Error(`chatbotlite: chain entry for "${provider}" needs a matching key in providers.keys.`);
|
|
291
228
|
}
|
|
292
|
-
return { provider, model,
|
|
229
|
+
return { provider, model, label: `${provider}/${model}` };
|
|
293
230
|
}
|
|
294
231
|
var BOLT = "\u26A1";
|
|
295
232
|
var DEFAULT_PRIMARY = "#0f172a";
|
|
@@ -340,8 +277,8 @@ function ChatWidget(props) {
|
|
|
340
277
|
position = "bottom-right"
|
|
341
278
|
} = props;
|
|
342
279
|
const isEndpointMode = "endpoint" in props && typeof props.endpoint === "string";
|
|
343
|
-
const resolvedTitle = title ??
|
|
344
|
-
const resolvedGreeting = greeting ??
|
|
280
|
+
const resolvedTitle = title ?? "Chat";
|
|
281
|
+
const resolvedGreeting = greeting ?? "Hi! How can we help?";
|
|
345
282
|
const primary = themeOverrides?.primary ?? DEFAULT_PRIMARY;
|
|
346
283
|
const onPrimary = themeOverrides?.onPrimary ?? DEFAULT_ON_PRIMARY;
|
|
347
284
|
const [open, setOpen] = useState(false);
|
|
@@ -357,9 +294,9 @@ function ChatWidget(props) {
|
|
|
357
294
|
}, []);
|
|
358
295
|
const bot = useMemo(() => {
|
|
359
296
|
if (isEndpointMode) return null;
|
|
360
|
-
if (!props.
|
|
361
|
-
return new ChatBot({
|
|
362
|
-
}, [isEndpointMode, props.
|
|
297
|
+
if (!props.knowledge || !props.providers) return null;
|
|
298
|
+
return new ChatBot({ knowledge: props.knowledge, providers: props.providers });
|
|
299
|
+
}, [isEndpointMode, props.knowledge, props.providers]);
|
|
363
300
|
useEffect(() => {
|
|
364
301
|
if (scrollRef.current) {
|
|
365
302
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|