kanha-ai 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +84 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +84 -5
- package/dist/index.js.map +1 -1
- package/dist/widget.js +2 -1
- package/dist/widget.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,11 @@ function toWebLLMModelUrl(modelUrl) {
|
|
|
29
29
|
}
|
|
30
30
|
return url;
|
|
31
31
|
}
|
|
32
|
+
var MIN_RAM_GB = {
|
|
33
|
+
small: 4,
|
|
34
|
+
medium: 8,
|
|
35
|
+
large: 12
|
|
36
|
+
};
|
|
32
37
|
async function checkWebGPU() {
|
|
33
38
|
try {
|
|
34
39
|
const nav = navigator;
|
|
@@ -41,6 +46,56 @@ async function checkWebGPU() {
|
|
|
41
46
|
return false;
|
|
42
47
|
}
|
|
43
48
|
}
|
|
49
|
+
var MODEL_WEIGHT_BYTES = {
|
|
50
|
+
small: 400 * 1024 * 1024,
|
|
51
|
+
// ~400MB
|
|
52
|
+
medium: 1100 * 1024 * 1024,
|
|
53
|
+
// ~1.1GB
|
|
54
|
+
large: 2500 * 1024 * 1024
|
|
55
|
+
// ~2.5GB
|
|
56
|
+
};
|
|
57
|
+
async function checkAvailableMemory(modelSize) {
|
|
58
|
+
try {
|
|
59
|
+
const nav2 = navigator;
|
|
60
|
+
if (nav2.gpu) {
|
|
61
|
+
const adapter = await nav2.gpu.requestAdapter();
|
|
62
|
+
if (adapter) {
|
|
63
|
+
const maxBufferSize = adapter.limits.maxBufferSize;
|
|
64
|
+
const needed2 = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;
|
|
65
|
+
if (maxBufferSize < needed2) {
|
|
66
|
+
const maxMB = Math.round(maxBufferSize / (1024 * 1024));
|
|
67
|
+
const needMB = Math.round(needed2 / (1024 * 1024));
|
|
68
|
+
return `Your GPU can only allocate ~${maxMB}MB but the ${modelSize} model needs ~${needMB}MB. Try a smaller model or close other GPU-heavy tabs.`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
const needed = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;
|
|
75
|
+
const probeSize = Math.min(needed, 512 * 1024 * 1024);
|
|
76
|
+
try {
|
|
77
|
+
const buf = new ArrayBuffer(probeSize);
|
|
78
|
+
if (buf.byteLength !== probeSize) {
|
|
79
|
+
return `Your device doesn't have enough free memory to load the ${modelSize} model. Close other tabs and try again.`;
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
const needMB = Math.round(needed / (1024 * 1024));
|
|
83
|
+
return `Not enough free memory to load the ${modelSize} model (~${needMB}MB required). Close other tabs and try again.`;
|
|
84
|
+
}
|
|
85
|
+
const nav = navigator;
|
|
86
|
+
if (nav.deviceMemory) {
|
|
87
|
+
const required = MIN_RAM_GB[modelSize] ?? MIN_RAM_GB.small;
|
|
88
|
+
if (nav.deviceMemory < required) {
|
|
89
|
+
return `Your device has ~${nav.deviceMemory}GB RAM but the ${modelSize} model needs at least ${required}GB.`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
function isMemoryError(err) {
|
|
95
|
+
if (!(err instanceof Error)) return false;
|
|
96
|
+
const msg = err.message.toLowerCase();
|
|
97
|
+
return msg.includes("out of memory") || msg.includes("oom") || msg.includes("allocation failed") || msg.includes("err_failed") || msg.includes("arraybuffer") || msg.includes("could not allocate") || msg.includes("webgpu device lost");
|
|
98
|
+
}
|
|
44
99
|
function stripThinkTokens(text) {
|
|
45
100
|
let cleaned = text.replace(/<think>[\s\S]*?<\/think>/g, "");
|
|
46
101
|
cleaned = cleaned.replace(/<think>[\s\S]*$/g, "");
|
|
@@ -85,6 +140,13 @@ function useKanhaChat(config) {
|
|
|
85
140
|
setError("WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.");
|
|
86
141
|
return;
|
|
87
142
|
}
|
|
143
|
+
const modelSize = configRef.current.modelSize ?? "small";
|
|
144
|
+
const memWarning = await checkAvailableMemory(modelSize);
|
|
145
|
+
if (memWarning) {
|
|
146
|
+
setMode("error");
|
|
147
|
+
setError(memWarning);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
88
150
|
if (cancelled) return;
|
|
89
151
|
setMode("loading");
|
|
90
152
|
try {
|
|
@@ -103,11 +165,13 @@ function useKanhaChat(config) {
|
|
|
103
165
|
context_window_size: configRef.current.contextWindowSize ?? 4096
|
|
104
166
|
}
|
|
105
167
|
}
|
|
106
|
-
]
|
|
168
|
+
],
|
|
169
|
+
useIndexedDBCache: true
|
|
107
170
|
},
|
|
108
171
|
initProgressCallback: (report) => {
|
|
109
172
|
if (!cancelled) setLoadProgress(Math.round(report.progress * 100));
|
|
110
|
-
}
|
|
173
|
+
},
|
|
174
|
+
logLevel: "SILENT"
|
|
111
175
|
});
|
|
112
176
|
if (cancelled) return;
|
|
113
177
|
engineRef.current = engine;
|
|
@@ -115,14 +179,29 @@ function useKanhaChat(config) {
|
|
|
115
179
|
} catch (err) {
|
|
116
180
|
if (cancelled) return;
|
|
117
181
|
setMode("error");
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
182
|
+
if (isMemoryError(err)) {
|
|
183
|
+
const size = configRef.current.modelSize ?? "small";
|
|
184
|
+
const ram = navigator.deviceMemory;
|
|
185
|
+
setError(
|
|
186
|
+
`Not enough memory to load the ${size} model${ram ? ` (device has ~${ram}GB RAM)` : ""}. Close other tabs or try a smaller model.`
|
|
187
|
+
);
|
|
188
|
+
} else {
|
|
189
|
+
setError(
|
|
190
|
+
err instanceof Error ? err.message : "Failed to load AI model."
|
|
191
|
+
);
|
|
192
|
+
}
|
|
121
193
|
}
|
|
122
194
|
};
|
|
123
195
|
init();
|
|
124
196
|
return () => {
|
|
125
197
|
cancelled = true;
|
|
198
|
+
if (engineRef.current) {
|
|
199
|
+
try {
|
|
200
|
+
engineRef.current.unload();
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
engineRef.current = null;
|
|
204
|
+
}
|
|
126
205
|
};
|
|
127
206
|
}, [config.modelUrl, config.modelLib, config.modelSize]);
|
|
128
207
|
const send = react.useCallback(async () => {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/use-kanha-chat.ts","../src/styles.ts","../src/KanhaBot.tsx"],"names":["useState","useRef","useCallback","useEffect","jsx","jsxs","Fragment","ReactMarkdown"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useState, useEffect, useRef, useCallback } from \"react\";\nimport type { Message, InferenceMode, KanhaChatConfig, KanhaChatReturn } from \"./types\";\n\nconst MODEL_LIB_PREFIX =\n \"https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_80\";\n\nconst WASM_BY_SIZE: Record<string, string> = {\n small: `${MODEL_LIB_PREFIX}/Qwen3-0.6B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n medium: `${MODEL_LIB_PREFIX}/Qwen3-1.7B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n large: `${MODEL_LIB_PREFIX}/Qwen3-4B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n};\n\nfunction resolveModelLib(config: KanhaChatConfig): string {\n if (config.modelLib) return config.modelLib;\n const size = config.modelSize ?? \"small\";\n const lib = WASM_BY_SIZE[size];\n if (!lib) throw new Error(`Unknown model size \"${size}\". Provide modelLib explicitly.`);\n return lib;\n}\n\n/**\n * Converts a storage URL into a format web-llm's cleanModelUrl won't mangle.\n * web-llm checks for /resolve/ in the URL — if missing, it appends /resolve/main/.\n * We append /resolve/v1/ so the URL passes through untouched.\n * Files must be stored at {modelUrl}/resolve/v1/{filename} in storage.\n */\nfunction toWebLLMModelUrl(modelUrl: string): string {\n let url = modelUrl.endsWith(\"/\") ? modelUrl.slice(0, -1) : modelUrl;\n if (!url.includes(\"/resolve/\")) {\n url += \"/resolve/v1\";\n }\n return url;\n}\n\nasync function checkWebGPU(): Promise<boolean> {\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<unknown> } };\n if (!nav.gpu) return false;\n const adapter = (await nav.gpu.requestAdapter()) as { requestDevice(): Promise<unknown> } | null;\n if (!adapter) return false;\n const device = await adapter.requestDevice();\n return !!device;\n } catch {\n return false;\n }\n}\n\nfunction stripThinkTokens(text: string): string {\n let cleaned = text.replace(/<think>[\\s\\S]*?<\\/think>/g, \"\");\n cleaned = cleaned.replace(/<think>[\\s\\S]*$/g, \"\");\n return cleaned.trimStart();\n}\n\nexport function useKanhaChat(config: KanhaChatConfig): KanhaChatReturn {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [isThinking, setIsThinking] = useState(false);\n const [mode, setMode] = useState<InferenceMode>(\"detecting\");\n const [loadProgress, setLoadProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const engineRef = useRef<any>(null);\n const configRef = useRef(config);\n configRef.current = config;\n\n const updateAssistantMessage = useCallback((text: string) => {\n const cleaned = stripThinkTokens(text);\n if (!cleaned) {\n setIsThinking(true);\n return;\n }\n setIsThinking(false);\n setMessages((prev) => {\n const msgs = [...prev];\n if (msgs[msgs.length - 1]?.role === \"assistant\") {\n msgs[msgs.length - 1] = { role: \"assistant\", content: cleaned };\n } else {\n msgs.push({ role: \"assistant\", content: cleaned });\n }\n return msgs;\n });\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n let cancelled = false;\n\n const init = async () => {\n setMode(\"detecting\");\n\n const hasWebGPU = await checkWebGPU();\n if (!hasWebGPU) {\n setMode(\"error\");\n setError(\"WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.\");\n return;\n }\n\n if (cancelled) return;\n setMode(\"loading\");\n\n try {\n const webllm = await import(\"@mlc-ai/web-llm\");\n const modelId = \"kanha-custom-model\";\n const modelLib = resolveModelLib(configRef.current);\n const modelUrl = toWebLLMModelUrl(configRef.current.modelUrl);\n\n const engine = await webllm.CreateMLCEngine(modelId, {\n appConfig: {\n model_list: [\n {\n model: modelUrl,\n model_id: modelId,\n model_lib: modelLib,\n overrides: {\n context_window_size: configRef.current.contextWindowSize ?? 4096,\n },\n },\n ],\n },\n initProgressCallback: (report: { progress: number }) => {\n if (!cancelled) setLoadProgress(Math.round(report.progress * 100));\n },\n });\n\n if (cancelled) return;\n engineRef.current = engine;\n setMode(\"ready\");\n } catch (err) {\n if (cancelled) return;\n setMode(\"error\");\n setError(\n err instanceof Error ? err.message : \"Failed to load AI model.\"\n );\n }\n };\n\n init();\n return () => { cancelled = true; };\n }, [config.modelUrl, config.modelLib, config.modelSize]);\n\n const send = useCallback(async () => {\n if (!input.trim() || mode !== \"ready\" || isLoading || !engineRef.current) return;\n\n const userMsg: Message = { role: \"user\", content: input.trim() };\n const allMessages = [...messages, userMsg];\n setMessages(allMessages);\n setInput(\"\");\n setIsLoading(true);\n setIsThinking(true);\n setError(null);\n\n try {\n const systemMessages: Message[] = configRef.current.systemPrompt\n ? [{ role: \"system\", content: configRef.current.systemPrompt }]\n : [];\n\n const completion = await engineRef.current.chat.completions.create({\n messages: [...systemMessages, ...allMessages],\n temperature: configRef.current.temperature ?? 0.7,\n max_tokens: configRef.current.maxTokens ?? 1024,\n stream: true,\n });\n\n let text = \"\";\n for await (const chunk of completion) {\n const delta = chunk.choices[0]?.delta?.content || \"\";\n text += delta;\n updateAssistantMessage(text);\n }\n } catch {\n setError(\"Failed to generate response. Please try again.\");\n setMessages((prev) => [\n ...prev,\n { role: \"assistant\", content: \"Sorry, I encountered an error. Please try again.\" },\n ]);\n } finally {\n setIsLoading(false);\n setIsThinking(false);\n }\n }, [input, mode, isLoading, messages, updateAssistantMessage]);\n\n const clear = useCallback(() => {\n setMessages([]);\n setError(null);\n }, []);\n\n return {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n };\n}\n","import type { CSSProperties } from \"react\";\n\nexport function fabStyle(\n primaryColor: string,\n position: \"bottom-right\" | \"bottom-left\",\n): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 24,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 56,\n height: 56,\n borderRadius: \"50%\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n zIndex: 9999,\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n };\n}\n\nexport function panelStyle(position: \"bottom-right\" | \"bottom-left\"): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 96,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 384,\n maxWidth: \"calc(100vw - 48px)\",\n maxHeight: \"calc(100vh - 120px)\",\n borderRadius: 16,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n boxShadow: \"0 8px 30px rgba(0,0,0,0.12)\",\n border: \"1px solid #e5e7eb\",\n background: \"#ffffff\",\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n}\n\nexport const headerStyle: CSSProperties = {\n padding: \"16px\",\n color: \"#fff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n};\n\nexport const headerTitleStyle: CSSProperties = {\n fontWeight: 600,\n fontSize: 15,\n margin: 0,\n};\n\nexport const headerSubtitleStyle: CSSProperties = {\n fontSize: 12,\n opacity: 0.85,\n margin: \"4px 0 0\",\n};\n\nexport const messagesContainerStyle: CSSProperties = {\n flex: 1,\n overflowY: \"auto\",\n padding: 16,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n minHeight: 300,\n maxHeight: 384,\n background: \"#fafafa\",\n};\n\nexport const emptyStateStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n textAlign: \"center\",\n color: \"#6b7280\",\n fontSize: 14,\n padding: 16,\n};\n\nexport function userBubbleStyle(primaryColor: string): CSSProperties {\n return {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: primaryColor,\n color: \"#fff\",\n fontSize: 14,\n lineHeight: 1.5,\n alignSelf: \"flex-end\",\n wordBreak: \"break-word\",\n };\n}\n\nexport const assistantBubbleStyle: CSSProperties = {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: \"#fff\",\n color: \"#1f2937\",\n fontSize: 14,\n lineHeight: 1.5,\n border: \"1px solid #e5e7eb\",\n alignSelf: \"flex-start\",\n wordBreak: \"break-word\",\n};\n\nexport const inputBarStyle: CSSProperties = {\n display: \"flex\",\n gap: 8,\n padding: \"12px 16px\",\n borderTop: \"1px solid #e5e7eb\",\n background: \"#fff\",\n};\n\nexport const textareaStyle: CSSProperties = {\n flex: 1,\n padding: \"8px 12px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n fontSize: 14,\n resize: \"none\",\n overflow: \"hidden\",\n outline: \"none\",\n fontFamily: \"inherit\",\n minHeight: 40,\n maxHeight: 120,\n lineHeight: 1.5,\n};\n\nexport function sendButtonStyle(primaryColor: string): CSSProperties {\n return {\n padding: \"8px 14px\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n borderRadius: 10,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n transition: \"opacity 0.15s ease\",\n };\n}\n\nexport const iconButtonStyle: CSSProperties = {\n background: \"none\",\n border: \"none\",\n color: \"inherit\",\n cursor: \"pointer\",\n padding: 4,\n borderRadius: 8,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: 0.8,\n transition: \"opacity 0.15s ease\",\n};\n\nexport function suggestionButtonStyle(primaryColor: string): CSSProperties {\n return {\n fontSize: 13,\n padding: \"8px 12px\",\n borderRadius: 10,\n border: \"1px solid #e5e7eb\",\n background: \"#fff\",\n color: \"#374151\",\n cursor: \"pointer\",\n textAlign: \"left\" as const,\n width: \"100%\",\n transition: \"border-color 0.15s ease\",\n // hover handled inline\n };\n}\n\nexport const progressBarContainer: CSSProperties = {\n width: \"60%\",\n height: 4,\n borderRadius: 2,\n background: \"rgba(255,255,255,0.3)\",\n marginTop: 8,\n overflow: \"hidden\",\n};\n\nexport function progressBarFill(progress: number, primaryColor: string): CSSProperties {\n return {\n width: `${progress}%`,\n height: \"100%\",\n borderRadius: 2,\n background: primaryColor,\n transition: \"width 0.3s ease\",\n };\n}\n","import {\n useState,\n useEffect,\n useRef,\n type KeyboardEvent,\n type CSSProperties,\n} from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport { useKanhaChat } from \"./use-kanha-chat\";\nimport type { KanhaBotProps } from \"./types\";\nimport * as s from \"./styles\";\n\n// Inline SVG icons (no icon library dependency)\nconst ChatIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n\nconst SendIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\nconst TrashIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\" /><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n);\n\nconst Spinner = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" style={{ animation: \"kanha-spin 1s linear infinite\" }}>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nconst spinKeyframes = `@keyframes kanha-spin { to { transform: rotate(360deg); } }`;\nconst bounceKeyframes = `\n@keyframes kanha-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-4px); }\n}`;\n\nfunction ThinkingDots() {\n const dotStyle = (delay: number): CSSProperties => ({\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n background: \"#9ca3af\",\n animation: `kanha-bounce 1.2s ease-in-out ${delay}ms infinite`,\n });\n return (\n <span style={{ display: \"flex\", gap: 3, alignItems: \"center\" }}>\n <span style={dotStyle(0)} />\n <span style={dotStyle(150)} />\n <span style={dotStyle(300)} />\n <span style={{ fontSize: 12, color: \"#9ca3af\", marginLeft: 6 }}>Thinking</span>\n </span>\n );\n}\n\nexport function KanhaBot({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n botName = \"AI Assistant\",\n welcomeMessage = \"Ask me anything!\",\n suggestions = [],\n theme = {},\n}: KanhaBotProps) {\n const primaryColor = theme.primaryColor ?? \"#0d9488\";\n const position = theme.position ?? \"bottom-right\";\n\n const {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n } = useKanhaChat({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n });\n\n const [isOpen, setIsOpen] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n useEffect(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 120) + \"px\";\n }\n }, [input]);\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n };\n\n const isReady = mode === \"ready\";\n\n return (\n <>\n <style>{spinKeyframes}{bounceKeyframes}</style>\n\n {isOpen && (\n <div style={s.panelStyle(position)}>\n {/* Header */}\n <div style={{ ...s.headerStyle, background: primaryColor }}>\n <div>\n <p style={s.headerTitleStyle}>{botName}</p>\n <p style={s.headerSubtitleStyle}>\n {isReady\n ? welcomeMessage\n : mode === \"loading\"\n ? `Loading AI model (${loadProgress}%)`\n : mode === \"error\"\n ? \"Failed to load\"\n : \"Detecting capabilities...\"}\n </p>\n {mode === \"loading\" && (\n <div style={s.progressBarContainer}>\n <div style={s.progressBarFill(loadProgress, \"#fff\")} />\n </div>\n )}\n </div>\n <div style={{ display: \"flex\", gap: 4 }}>\n {messages.length > 0 && (\n <button onClick={clear} style={s.iconButtonStyle} aria-label=\"Clear chat\">\n <TrashIcon />\n </button>\n )}\n <button onClick={() => setIsOpen(false)} style={s.iconButtonStyle} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Error banner */}\n {error && (\n <div style={{ padding: \"10px 16px\", background: \"#fef2f2\", borderBottom: \"1px solid #fecaca\", fontSize: 13, color: \"#b91c1c\" }}>\n {error}\n </div>\n )}\n\n {/* Messages */}\n <div style={s.messagesContainerStyle}>\n {messages.length === 0 ? (\n <div style={s.emptyStateStyle}>\n {isReady ? (\n <>\n <ChatIcon />\n <p style={{ marginTop: 12, fontWeight: 500, color: \"#374151\" }}>\n {welcomeMessage}\n </p>\n {suggestions.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, width: \"100%\", marginTop: 16 }}>\n {suggestions.map((text) => (\n <button\n key={text}\n onClick={() => { setInput(text); setTimeout(send, 0); }}\n style={s.suggestionButtonStyle(primaryColor)}\n onMouseEnter={(e) => { (e.target as HTMLElement).style.borderColor = primaryColor; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.borderColor = \"#e5e7eb\"; }}\n >\n {text}\n </button>\n ))}\n </div>\n )}\n </>\n ) : mode === \"loading\" ? (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Loading AI model ({loadProgress}%)</p>\n <p style={{ fontSize: 12, marginTop: 4 }}>First load takes about a minute</p>\n </>\n ) : mode === \"error\" ? (\n <p>{error}</p>\n ) : (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Detecting browser capabilities...</p>\n </>\n )}\n </div>\n ) : (\n <>\n {messages.map((msg, i) => (\n <div\n key={i}\n style={{\n display: \"flex\",\n justifyContent: msg.role === \"user\" ? \"flex-end\" : \"flex-start\",\n }}\n >\n <div style={msg.role === \"user\" ? s.userBubbleStyle(primaryColor) : s.assistantBubbleStyle}>\n {msg.role === \"assistant\" ? (\n <ReactMarkdown>{msg.content}</ReactMarkdown>\n ) : (\n <span style={{ whiteSpace: \"pre-wrap\" }}>{msg.content}</span>\n )}\n </div>\n </div>\n ))}\n {isLoading && (isThinking || messages[messages.length - 1]?.role !== \"assistant\") && (\n <div style={{ display: \"flex\", justifyContent: \"flex-start\" }}>\n <div style={s.assistantBubbleStyle}>\n {isThinking ? <ThinkingDots /> : <Spinner size={16} />}\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </>\n )}\n </div>\n\n {/* Input */}\n <div style={s.inputBarStyle}>\n <textarea\n ref={textareaRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder={isReady ? \"Type your message...\" : \"Waiting for model...\"}\n disabled={!isReady || isLoading}\n rows={1}\n style={{\n ...s.textareaStyle,\n opacity: !isReady ? 0.5 : 1,\n }}\n />\n <button\n onClick={send}\n disabled={!isReady || isLoading || !input.trim()}\n style={{\n ...s.sendButtonStyle(primaryColor),\n opacity: !isReady || isLoading || !input.trim() ? 0.5 : 1,\n cursor: !isReady || isLoading || !input.trim() ? \"not-allowed\" : \"pointer\",\n }}\n aria-label=\"Send message\"\n >\n {isLoading ? <Spinner size={18} /> : <SendIcon />}\n </button>\n </div>\n </div>\n )}\n\n {/* FAB */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={s.fabStyle(primaryColor, position)}\n aria-label=\"Toggle chat\"\n onMouseEnter={(e) => { (e.target as HTMLElement).style.transform = \"scale(1.05)\"; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.transform = \"scale(1)\"; }}\n >\n {isOpen ? <CloseIcon /> : <ChatIcon />}\n </button>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/use-kanha-chat.ts","../src/styles.ts","../src/KanhaBot.tsx"],"names":["nav","needed","useState","useRef","useCallback","useEffect","jsx","jsxs","Fragment","ReactMarkdown"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useState, useEffect, useRef, useCallback } from \"react\";\nimport type { Message, InferenceMode, KanhaChatConfig, KanhaChatReturn } from \"./types\";\n\nconst MODEL_LIB_PREFIX =\n \"https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_80\";\n\nconst WASM_BY_SIZE: Record<string, string> = {\n small: `${MODEL_LIB_PREFIX}/Qwen3-0.6B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n medium: `${MODEL_LIB_PREFIX}/Qwen3-1.7B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n large: `${MODEL_LIB_PREFIX}/Qwen3-4B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n};\n\nfunction resolveModelLib(config: KanhaChatConfig): string {\n if (config.modelLib) return config.modelLib;\n const size = config.modelSize ?? \"small\";\n const lib = WASM_BY_SIZE[size];\n if (!lib) throw new Error(`Unknown model size \"${size}\". Provide modelLib explicitly.`);\n return lib;\n}\n\n/**\n * Converts a storage URL into a format web-llm's cleanModelUrl won't mangle.\n * web-llm checks for /resolve/ in the URL — if missing, it appends /resolve/main/.\n * We append /resolve/v1/ so the URL passes through untouched.\n * Files must be stored at {modelUrl}/resolve/v1/{filename} in storage.\n */\nfunction toWebLLMModelUrl(modelUrl: string): string {\n let url = modelUrl.endsWith(\"/\") ? modelUrl.slice(0, -1) : modelUrl;\n if (!url.includes(\"/resolve/\")) {\n url += \"/resolve/v1\";\n }\n return url;\n}\n\n// Minimum device RAM (GB) recommended per model size\nconst MIN_RAM_GB: Record<string, number> = {\n small: 4,\n medium: 8,\n large: 12,\n};\n\nasync function checkWebGPU(): Promise<boolean> {\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<unknown> } };\n if (!nav.gpu) return false;\n const adapter = (await nav.gpu.requestAdapter()) as { requestDevice(): Promise<unknown> } | null;\n if (!adapter) return false;\n const device = await adapter.requestDevice();\n return !!device;\n } catch {\n return false;\n }\n}\n\n// Approximate model weight sizes in bytes (q4f16_1 quantized)\nconst MODEL_WEIGHT_BYTES: Record<string, number> = {\n small: 400 * 1024 * 1024, // ~400MB\n medium: 1100 * 1024 * 1024, // ~1.1GB\n large: 2500 * 1024 * 1024, // ~2.5GB\n};\n\nasync function checkAvailableMemory(modelSize: string): Promise<string | null> {\n // 1. Try WebGPU adapter limits (most reliable for GPU memory)\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<{ limits: { maxBufferSize: number } } | null> } };\n if (nav.gpu) {\n const adapter = await nav.gpu.requestAdapter();\n if (adapter) {\n const maxBufferSize = adapter.limits.maxBufferSize;\n const needed = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;\n // If the GPU's max buffer is smaller than model weights, it won't fit\n if (maxBufferSize < needed) {\n const maxMB = Math.round(maxBufferSize / (1024 * 1024));\n const needMB = Math.round(needed / (1024 * 1024));\n return `Your GPU can only allocate ~${maxMB}MB but the ${modelSize} model needs ~${needMB}MB. Try a smaller model or close other GPU-heavy tabs.`;\n }\n }\n }\n } catch { /* ignore, fall through */ }\n\n // 2. Try probing available system memory with a test allocation\n const needed = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;\n const probeSize = Math.min(needed, 512 * 1024 * 1024); // probe up to 512MB\n try {\n const buf = new ArrayBuffer(probeSize);\n // If we got here, allocation succeeded — free it\n // (TypeScript doesn't have explicit free, but losing the reference lets GC collect)\n if (buf.byteLength !== probeSize) {\n return `Your device doesn't have enough free memory to load the ${modelSize} model. Close other tabs and try again.`;\n }\n } catch {\n const needMB = Math.round(needed / (1024 * 1024));\n return `Not enough free memory to load the ${modelSize} model (~${needMB}MB required). Close other tabs and try again.`;\n }\n\n // 3. Fallback: check navigator.deviceMemory (coarse, total RAM)\n const nav = navigator as Navigator & { deviceMemory?: number };\n if (nav.deviceMemory) {\n const required = MIN_RAM_GB[modelSize] ?? MIN_RAM_GB.small;\n if (nav.deviceMemory < required) {\n return `Your device has ~${nav.deviceMemory}GB RAM but the ${modelSize} model needs at least ${required}GB.`;\n }\n }\n\n return null;\n}\n\nfunction isMemoryError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const msg = err.message.toLowerCase();\n return (\n msg.includes(\"out of memory\") ||\n msg.includes(\"oom\") ||\n msg.includes(\"allocation failed\") ||\n msg.includes(\"err_failed\") ||\n msg.includes(\"arraybuffer\") ||\n msg.includes(\"could not allocate\") ||\n msg.includes(\"webgpu device lost\")\n );\n}\n\nfunction stripThinkTokens(text: string): string {\n let cleaned = text.replace(/<think>[\\s\\S]*?<\\/think>/g, \"\");\n cleaned = cleaned.replace(/<think>[\\s\\S]*$/g, \"\");\n return cleaned.trimStart();\n}\n\nexport function useKanhaChat(config: KanhaChatConfig): KanhaChatReturn {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [isThinking, setIsThinking] = useState(false);\n const [mode, setMode] = useState<InferenceMode>(\"detecting\");\n const [loadProgress, setLoadProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const engineRef = useRef<any>(null);\n const configRef = useRef(config);\n configRef.current = config;\n\n const updateAssistantMessage = useCallback((text: string) => {\n const cleaned = stripThinkTokens(text);\n if (!cleaned) {\n setIsThinking(true);\n return;\n }\n setIsThinking(false);\n setMessages((prev) => {\n const msgs = [...prev];\n if (msgs[msgs.length - 1]?.role === \"assistant\") {\n msgs[msgs.length - 1] = { role: \"assistant\", content: cleaned };\n } else {\n msgs.push({ role: \"assistant\", content: cleaned });\n }\n return msgs;\n });\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n let cancelled = false;\n\n const init = async () => {\n setMode(\"detecting\");\n\n const hasWebGPU = await checkWebGPU();\n if (!hasWebGPU) {\n setMode(\"error\");\n setError(\"WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.\");\n return;\n }\n\n const modelSize = configRef.current.modelSize ?? \"small\";\n const memWarning = await checkAvailableMemory(modelSize);\n if (memWarning) {\n setMode(\"error\");\n setError(memWarning);\n return;\n }\n\n if (cancelled) return;\n setMode(\"loading\");\n\n try {\n const webllm = await import(\"@mlc-ai/web-llm\");\n const modelId = \"kanha-custom-model\";\n const modelLib = resolveModelLib(configRef.current);\n const modelUrl = toWebLLMModelUrl(configRef.current.modelUrl);\n\n const engine = await webllm.CreateMLCEngine(modelId, {\n appConfig: {\n model_list: [\n {\n model: modelUrl,\n model_id: modelId,\n model_lib: modelLib,\n overrides: {\n context_window_size: configRef.current.contextWindowSize ?? 4096,\n },\n },\n ],\n useIndexedDBCache: true,\n },\n initProgressCallback: (report: { progress: number }) => {\n if (!cancelled) setLoadProgress(Math.round(report.progress * 100));\n },\n logLevel: \"SILENT\",\n });\n\n if (cancelled) return;\n engineRef.current = engine;\n setMode(\"ready\");\n } catch (err) {\n if (cancelled) return;\n setMode(\"error\");\n if (isMemoryError(err)) {\n const size = configRef.current.modelSize ?? \"small\";\n const ram = (navigator as Navigator & { deviceMemory?: number }).deviceMemory;\n setError(\n `Not enough memory to load the ${size} model${ram ? ` (device has ~${ram}GB RAM)` : \"\"}. ` +\n `Close other tabs or try a smaller model.`\n );\n } else {\n setError(\n err instanceof Error ? err.message : \"Failed to load AI model.\"\n );\n }\n }\n };\n\n init();\n return () => {\n cancelled = true;\n if (engineRef.current) {\n try { engineRef.current.unload(); } catch { /* best-effort */ }\n engineRef.current = null;\n }\n };\n }, [config.modelUrl, config.modelLib, config.modelSize]);\n\n const send = useCallback(async () => {\n if (!input.trim() || mode !== \"ready\" || isLoading || !engineRef.current) return;\n\n const userMsg: Message = { role: \"user\", content: input.trim() };\n const allMessages = [...messages, userMsg];\n setMessages(allMessages);\n setInput(\"\");\n setIsLoading(true);\n setIsThinking(true);\n setError(null);\n\n try {\n const systemMessages: Message[] = configRef.current.systemPrompt\n ? [{ role: \"system\", content: configRef.current.systemPrompt }]\n : [];\n\n const completion = await engineRef.current.chat.completions.create({\n messages: [...systemMessages, ...allMessages],\n temperature: configRef.current.temperature ?? 0.7,\n max_tokens: configRef.current.maxTokens ?? 1024,\n stream: true,\n });\n\n let text = \"\";\n for await (const chunk of completion) {\n const delta = chunk.choices[0]?.delta?.content || \"\";\n text += delta;\n updateAssistantMessage(text);\n }\n } catch {\n setError(\"Failed to generate response. Please try again.\");\n setMessages((prev) => [\n ...prev,\n { role: \"assistant\", content: \"Sorry, I encountered an error. Please try again.\" },\n ]);\n } finally {\n setIsLoading(false);\n setIsThinking(false);\n }\n }, [input, mode, isLoading, messages, updateAssistantMessage]);\n\n const clear = useCallback(() => {\n setMessages([]);\n setError(null);\n }, []);\n\n return {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n };\n}\n","import type { CSSProperties } from \"react\";\n\nexport function fabStyle(\n primaryColor: string,\n position: \"bottom-right\" | \"bottom-left\",\n): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 24,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 56,\n height: 56,\n borderRadius: \"50%\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n zIndex: 9999,\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n };\n}\n\nexport function panelStyle(position: \"bottom-right\" | \"bottom-left\"): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 96,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 384,\n maxWidth: \"calc(100vw - 48px)\",\n maxHeight: \"calc(100vh - 120px)\",\n borderRadius: 16,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n boxShadow: \"0 8px 30px rgba(0,0,0,0.12)\",\n border: \"1px solid #e5e7eb\",\n background: \"#ffffff\",\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n}\n\nexport const headerStyle: CSSProperties = {\n padding: \"16px\",\n color: \"#fff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n};\n\nexport const headerTitleStyle: CSSProperties = {\n fontWeight: 600,\n fontSize: 15,\n margin: 0,\n};\n\nexport const headerSubtitleStyle: CSSProperties = {\n fontSize: 12,\n opacity: 0.85,\n margin: \"4px 0 0\",\n};\n\nexport const messagesContainerStyle: CSSProperties = {\n flex: 1,\n overflowY: \"auto\",\n padding: 16,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n minHeight: 300,\n maxHeight: 384,\n background: \"#fafafa\",\n};\n\nexport const emptyStateStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n textAlign: \"center\",\n color: \"#6b7280\",\n fontSize: 14,\n padding: 16,\n};\n\nexport function userBubbleStyle(primaryColor: string): CSSProperties {\n return {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: primaryColor,\n color: \"#fff\",\n fontSize: 14,\n lineHeight: 1.5,\n alignSelf: \"flex-end\",\n wordBreak: \"break-word\",\n };\n}\n\nexport const assistantBubbleStyle: CSSProperties = {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: \"#fff\",\n color: \"#1f2937\",\n fontSize: 14,\n lineHeight: 1.5,\n border: \"1px solid #e5e7eb\",\n alignSelf: \"flex-start\",\n wordBreak: \"break-word\",\n};\n\nexport const inputBarStyle: CSSProperties = {\n display: \"flex\",\n gap: 8,\n padding: \"12px 16px\",\n borderTop: \"1px solid #e5e7eb\",\n background: \"#fff\",\n};\n\nexport const textareaStyle: CSSProperties = {\n flex: 1,\n padding: \"8px 12px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n fontSize: 14,\n resize: \"none\",\n overflow: \"hidden\",\n outline: \"none\",\n fontFamily: \"inherit\",\n minHeight: 40,\n maxHeight: 120,\n lineHeight: 1.5,\n};\n\nexport function sendButtonStyle(primaryColor: string): CSSProperties {\n return {\n padding: \"8px 14px\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n borderRadius: 10,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n transition: \"opacity 0.15s ease\",\n };\n}\n\nexport const iconButtonStyle: CSSProperties = {\n background: \"none\",\n border: \"none\",\n color: \"inherit\",\n cursor: \"pointer\",\n padding: 4,\n borderRadius: 8,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: 0.8,\n transition: \"opacity 0.15s ease\",\n};\n\nexport function suggestionButtonStyle(primaryColor: string): CSSProperties {\n return {\n fontSize: 13,\n padding: \"8px 12px\",\n borderRadius: 10,\n border: \"1px solid #e5e7eb\",\n background: \"#fff\",\n color: \"#374151\",\n cursor: \"pointer\",\n textAlign: \"left\" as const,\n width: \"100%\",\n transition: \"border-color 0.15s ease\",\n // hover handled inline\n };\n}\n\nexport const progressBarContainer: CSSProperties = {\n width: \"60%\",\n height: 4,\n borderRadius: 2,\n background: \"rgba(255,255,255,0.3)\",\n marginTop: 8,\n overflow: \"hidden\",\n};\n\nexport function progressBarFill(progress: number, primaryColor: string): CSSProperties {\n return {\n width: `${progress}%`,\n height: \"100%\",\n borderRadius: 2,\n background: primaryColor,\n transition: \"width 0.3s ease\",\n };\n}\n","import {\n useState,\n useEffect,\n useRef,\n type KeyboardEvent,\n type CSSProperties,\n} from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport { useKanhaChat } from \"./use-kanha-chat\";\nimport type { KanhaBotProps } from \"./types\";\nimport * as s from \"./styles\";\n\n// Inline SVG icons (no icon library dependency)\nconst ChatIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n\nconst SendIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\nconst TrashIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\" /><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n);\n\nconst Spinner = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" style={{ animation: \"kanha-spin 1s linear infinite\" }}>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nconst spinKeyframes = `@keyframes kanha-spin { to { transform: rotate(360deg); } }`;\nconst bounceKeyframes = `\n@keyframes kanha-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-4px); }\n}`;\n\nfunction ThinkingDots() {\n const dotStyle = (delay: number): CSSProperties => ({\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n background: \"#9ca3af\",\n animation: `kanha-bounce 1.2s ease-in-out ${delay}ms infinite`,\n });\n return (\n <span style={{ display: \"flex\", gap: 3, alignItems: \"center\" }}>\n <span style={dotStyle(0)} />\n <span style={dotStyle(150)} />\n <span style={dotStyle(300)} />\n <span style={{ fontSize: 12, color: \"#9ca3af\", marginLeft: 6 }}>Thinking</span>\n </span>\n );\n}\n\nexport function KanhaBot({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n botName = \"AI Assistant\",\n welcomeMessage = \"Ask me anything!\",\n suggestions = [],\n theme = {},\n}: KanhaBotProps) {\n const primaryColor = theme.primaryColor ?? \"#0d9488\";\n const position = theme.position ?? \"bottom-right\";\n\n const {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n } = useKanhaChat({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n });\n\n const [isOpen, setIsOpen] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n useEffect(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 120) + \"px\";\n }\n }, [input]);\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n };\n\n const isReady = mode === \"ready\";\n\n return (\n <>\n <style>{spinKeyframes}{bounceKeyframes}</style>\n\n {isOpen && (\n <div style={s.panelStyle(position)}>\n {/* Header */}\n <div style={{ ...s.headerStyle, background: primaryColor }}>\n <div>\n <p style={s.headerTitleStyle}>{botName}</p>\n <p style={s.headerSubtitleStyle}>\n {isReady\n ? welcomeMessage\n : mode === \"loading\"\n ? `Loading AI model (${loadProgress}%)`\n : mode === \"error\"\n ? \"Failed to load\"\n : \"Detecting capabilities...\"}\n </p>\n {mode === \"loading\" && (\n <div style={s.progressBarContainer}>\n <div style={s.progressBarFill(loadProgress, \"#fff\")} />\n </div>\n )}\n </div>\n <div style={{ display: \"flex\", gap: 4 }}>\n {messages.length > 0 && (\n <button onClick={clear} style={s.iconButtonStyle} aria-label=\"Clear chat\">\n <TrashIcon />\n </button>\n )}\n <button onClick={() => setIsOpen(false)} style={s.iconButtonStyle} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Error banner */}\n {error && (\n <div style={{ padding: \"10px 16px\", background: \"#fef2f2\", borderBottom: \"1px solid #fecaca\", fontSize: 13, color: \"#b91c1c\" }}>\n {error}\n </div>\n )}\n\n {/* Messages */}\n <div style={s.messagesContainerStyle}>\n {messages.length === 0 ? (\n <div style={s.emptyStateStyle}>\n {isReady ? (\n <>\n <ChatIcon />\n <p style={{ marginTop: 12, fontWeight: 500, color: \"#374151\" }}>\n {welcomeMessage}\n </p>\n {suggestions.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, width: \"100%\", marginTop: 16 }}>\n {suggestions.map((text) => (\n <button\n key={text}\n onClick={() => { setInput(text); setTimeout(send, 0); }}\n style={s.suggestionButtonStyle(primaryColor)}\n onMouseEnter={(e) => { (e.target as HTMLElement).style.borderColor = primaryColor; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.borderColor = \"#e5e7eb\"; }}\n >\n {text}\n </button>\n ))}\n </div>\n )}\n </>\n ) : mode === \"loading\" ? (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Loading AI model ({loadProgress}%)</p>\n <p style={{ fontSize: 12, marginTop: 4 }}>First load takes about a minute</p>\n </>\n ) : mode === \"error\" ? (\n <p>{error}</p>\n ) : (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Detecting browser capabilities...</p>\n </>\n )}\n </div>\n ) : (\n <>\n {messages.map((msg, i) => (\n <div\n key={i}\n style={{\n display: \"flex\",\n justifyContent: msg.role === \"user\" ? \"flex-end\" : \"flex-start\",\n }}\n >\n <div style={msg.role === \"user\" ? s.userBubbleStyle(primaryColor) : s.assistantBubbleStyle}>\n {msg.role === \"assistant\" ? (\n <ReactMarkdown>{msg.content}</ReactMarkdown>\n ) : (\n <span style={{ whiteSpace: \"pre-wrap\" }}>{msg.content}</span>\n )}\n </div>\n </div>\n ))}\n {isLoading && (isThinking || messages[messages.length - 1]?.role !== \"assistant\") && (\n <div style={{ display: \"flex\", justifyContent: \"flex-start\" }}>\n <div style={s.assistantBubbleStyle}>\n {isThinking ? <ThinkingDots /> : <Spinner size={16} />}\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </>\n )}\n </div>\n\n {/* Input */}\n <div style={s.inputBarStyle}>\n <textarea\n ref={textareaRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder={isReady ? \"Type your message...\" : \"Waiting for model...\"}\n disabled={!isReady || isLoading}\n rows={1}\n style={{\n ...s.textareaStyle,\n opacity: !isReady ? 0.5 : 1,\n }}\n />\n <button\n onClick={send}\n disabled={!isReady || isLoading || !input.trim()}\n style={{\n ...s.sendButtonStyle(primaryColor),\n opacity: !isReady || isLoading || !input.trim() ? 0.5 : 1,\n cursor: !isReady || isLoading || !input.trim() ? \"not-allowed\" : \"pointer\",\n }}\n aria-label=\"Send message\"\n >\n {isLoading ? <Spinner size={18} /> : <SendIcon />}\n </button>\n </div>\n </div>\n )}\n\n {/* FAB */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={s.fabStyle(primaryColor, position)}\n aria-label=\"Toggle chat\"\n onMouseEnter={(e) => { (e.target as HTMLElement).style.transform = \"scale(1.05)\"; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.transform = \"scale(1)\"; }}\n >\n {isOpen ? <CloseIcon /> : <ChatIcon />}\n </button>\n </>\n );\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,11 @@ function toWebLLMModelUrl(modelUrl) {
|
|
|
23
23
|
}
|
|
24
24
|
return url;
|
|
25
25
|
}
|
|
26
|
+
var MIN_RAM_GB = {
|
|
27
|
+
small: 4,
|
|
28
|
+
medium: 8,
|
|
29
|
+
large: 12
|
|
30
|
+
};
|
|
26
31
|
async function checkWebGPU() {
|
|
27
32
|
try {
|
|
28
33
|
const nav = navigator;
|
|
@@ -35,6 +40,56 @@ async function checkWebGPU() {
|
|
|
35
40
|
return false;
|
|
36
41
|
}
|
|
37
42
|
}
|
|
43
|
+
var MODEL_WEIGHT_BYTES = {
|
|
44
|
+
small: 400 * 1024 * 1024,
|
|
45
|
+
// ~400MB
|
|
46
|
+
medium: 1100 * 1024 * 1024,
|
|
47
|
+
// ~1.1GB
|
|
48
|
+
large: 2500 * 1024 * 1024
|
|
49
|
+
// ~2.5GB
|
|
50
|
+
};
|
|
51
|
+
async function checkAvailableMemory(modelSize) {
|
|
52
|
+
try {
|
|
53
|
+
const nav2 = navigator;
|
|
54
|
+
if (nav2.gpu) {
|
|
55
|
+
const adapter = await nav2.gpu.requestAdapter();
|
|
56
|
+
if (adapter) {
|
|
57
|
+
const maxBufferSize = adapter.limits.maxBufferSize;
|
|
58
|
+
const needed2 = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;
|
|
59
|
+
if (maxBufferSize < needed2) {
|
|
60
|
+
const maxMB = Math.round(maxBufferSize / (1024 * 1024));
|
|
61
|
+
const needMB = Math.round(needed2 / (1024 * 1024));
|
|
62
|
+
return `Your GPU can only allocate ~${maxMB}MB but the ${modelSize} model needs ~${needMB}MB. Try a smaller model or close other GPU-heavy tabs.`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
const needed = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;
|
|
69
|
+
const probeSize = Math.min(needed, 512 * 1024 * 1024);
|
|
70
|
+
try {
|
|
71
|
+
const buf = new ArrayBuffer(probeSize);
|
|
72
|
+
if (buf.byteLength !== probeSize) {
|
|
73
|
+
return `Your device doesn't have enough free memory to load the ${modelSize} model. Close other tabs and try again.`;
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
const needMB = Math.round(needed / (1024 * 1024));
|
|
77
|
+
return `Not enough free memory to load the ${modelSize} model (~${needMB}MB required). Close other tabs and try again.`;
|
|
78
|
+
}
|
|
79
|
+
const nav = navigator;
|
|
80
|
+
if (nav.deviceMemory) {
|
|
81
|
+
const required = MIN_RAM_GB[modelSize] ?? MIN_RAM_GB.small;
|
|
82
|
+
if (nav.deviceMemory < required) {
|
|
83
|
+
return `Your device has ~${nav.deviceMemory}GB RAM but the ${modelSize} model needs at least ${required}GB.`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
function isMemoryError(err) {
|
|
89
|
+
if (!(err instanceof Error)) return false;
|
|
90
|
+
const msg = err.message.toLowerCase();
|
|
91
|
+
return msg.includes("out of memory") || msg.includes("oom") || msg.includes("allocation failed") || msg.includes("err_failed") || msg.includes("arraybuffer") || msg.includes("could not allocate") || msg.includes("webgpu device lost");
|
|
92
|
+
}
|
|
38
93
|
function stripThinkTokens(text) {
|
|
39
94
|
let cleaned = text.replace(/<think>[\s\S]*?<\/think>/g, "");
|
|
40
95
|
cleaned = cleaned.replace(/<think>[\s\S]*$/g, "");
|
|
@@ -79,6 +134,13 @@ function useKanhaChat(config) {
|
|
|
79
134
|
setError("WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.");
|
|
80
135
|
return;
|
|
81
136
|
}
|
|
137
|
+
const modelSize = configRef.current.modelSize ?? "small";
|
|
138
|
+
const memWarning = await checkAvailableMemory(modelSize);
|
|
139
|
+
if (memWarning) {
|
|
140
|
+
setMode("error");
|
|
141
|
+
setError(memWarning);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
82
144
|
if (cancelled) return;
|
|
83
145
|
setMode("loading");
|
|
84
146
|
try {
|
|
@@ -97,11 +159,13 @@ function useKanhaChat(config) {
|
|
|
97
159
|
context_window_size: configRef.current.contextWindowSize ?? 4096
|
|
98
160
|
}
|
|
99
161
|
}
|
|
100
|
-
]
|
|
162
|
+
],
|
|
163
|
+
useIndexedDBCache: true
|
|
101
164
|
},
|
|
102
165
|
initProgressCallback: (report) => {
|
|
103
166
|
if (!cancelled) setLoadProgress(Math.round(report.progress * 100));
|
|
104
|
-
}
|
|
167
|
+
},
|
|
168
|
+
logLevel: "SILENT"
|
|
105
169
|
});
|
|
106
170
|
if (cancelled) return;
|
|
107
171
|
engineRef.current = engine;
|
|
@@ -109,14 +173,29 @@ function useKanhaChat(config) {
|
|
|
109
173
|
} catch (err) {
|
|
110
174
|
if (cancelled) return;
|
|
111
175
|
setMode("error");
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
176
|
+
if (isMemoryError(err)) {
|
|
177
|
+
const size = configRef.current.modelSize ?? "small";
|
|
178
|
+
const ram = navigator.deviceMemory;
|
|
179
|
+
setError(
|
|
180
|
+
`Not enough memory to load the ${size} model${ram ? ` (device has ~${ram}GB RAM)` : ""}. Close other tabs or try a smaller model.`
|
|
181
|
+
);
|
|
182
|
+
} else {
|
|
183
|
+
setError(
|
|
184
|
+
err instanceof Error ? err.message : "Failed to load AI model."
|
|
185
|
+
);
|
|
186
|
+
}
|
|
115
187
|
}
|
|
116
188
|
};
|
|
117
189
|
init();
|
|
118
190
|
return () => {
|
|
119
191
|
cancelled = true;
|
|
192
|
+
if (engineRef.current) {
|
|
193
|
+
try {
|
|
194
|
+
engineRef.current.unload();
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
engineRef.current = null;
|
|
198
|
+
}
|
|
120
199
|
};
|
|
121
200
|
}, [config.modelUrl, config.modelLib, config.modelSize]);
|
|
122
201
|
const send = useCallback(async () => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/use-kanha-chat.ts","../src/styles.ts","../src/KanhaBot.tsx"],"names":["useState","useRef","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["import { useState, useEffect, useRef, useCallback } from \"react\";\nimport type { Message, InferenceMode, KanhaChatConfig, KanhaChatReturn } from \"./types\";\n\nconst MODEL_LIB_PREFIX =\n \"https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_80\";\n\nconst WASM_BY_SIZE: Record<string, string> = {\n small: `${MODEL_LIB_PREFIX}/Qwen3-0.6B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n medium: `${MODEL_LIB_PREFIX}/Qwen3-1.7B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n large: `${MODEL_LIB_PREFIX}/Qwen3-4B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n};\n\nfunction resolveModelLib(config: KanhaChatConfig): string {\n if (config.modelLib) return config.modelLib;\n const size = config.modelSize ?? \"small\";\n const lib = WASM_BY_SIZE[size];\n if (!lib) throw new Error(`Unknown model size \"${size}\". Provide modelLib explicitly.`);\n return lib;\n}\n\n/**\n * Converts a storage URL into a format web-llm's cleanModelUrl won't mangle.\n * web-llm checks for /resolve/ in the URL — if missing, it appends /resolve/main/.\n * We append /resolve/v1/ so the URL passes through untouched.\n * Files must be stored at {modelUrl}/resolve/v1/{filename} in storage.\n */\nfunction toWebLLMModelUrl(modelUrl: string): string {\n let url = modelUrl.endsWith(\"/\") ? modelUrl.slice(0, -1) : modelUrl;\n if (!url.includes(\"/resolve/\")) {\n url += \"/resolve/v1\";\n }\n return url;\n}\n\nasync function checkWebGPU(): Promise<boolean> {\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<unknown> } };\n if (!nav.gpu) return false;\n const adapter = (await nav.gpu.requestAdapter()) as { requestDevice(): Promise<unknown> } | null;\n if (!adapter) return false;\n const device = await adapter.requestDevice();\n return !!device;\n } catch {\n return false;\n }\n}\n\nfunction stripThinkTokens(text: string): string {\n let cleaned = text.replace(/<think>[\\s\\S]*?<\\/think>/g, \"\");\n cleaned = cleaned.replace(/<think>[\\s\\S]*$/g, \"\");\n return cleaned.trimStart();\n}\n\nexport function useKanhaChat(config: KanhaChatConfig): KanhaChatReturn {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [isThinking, setIsThinking] = useState(false);\n const [mode, setMode] = useState<InferenceMode>(\"detecting\");\n const [loadProgress, setLoadProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const engineRef = useRef<any>(null);\n const configRef = useRef(config);\n configRef.current = config;\n\n const updateAssistantMessage = useCallback((text: string) => {\n const cleaned = stripThinkTokens(text);\n if (!cleaned) {\n setIsThinking(true);\n return;\n }\n setIsThinking(false);\n setMessages((prev) => {\n const msgs = [...prev];\n if (msgs[msgs.length - 1]?.role === \"assistant\") {\n msgs[msgs.length - 1] = { role: \"assistant\", content: cleaned };\n } else {\n msgs.push({ role: \"assistant\", content: cleaned });\n }\n return msgs;\n });\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n let cancelled = false;\n\n const init = async () => {\n setMode(\"detecting\");\n\n const hasWebGPU = await checkWebGPU();\n if (!hasWebGPU) {\n setMode(\"error\");\n setError(\"WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.\");\n return;\n }\n\n if (cancelled) return;\n setMode(\"loading\");\n\n try {\n const webllm = await import(\"@mlc-ai/web-llm\");\n const modelId = \"kanha-custom-model\";\n const modelLib = resolveModelLib(configRef.current);\n const modelUrl = toWebLLMModelUrl(configRef.current.modelUrl);\n\n const engine = await webllm.CreateMLCEngine(modelId, {\n appConfig: {\n model_list: [\n {\n model: modelUrl,\n model_id: modelId,\n model_lib: modelLib,\n overrides: {\n context_window_size: configRef.current.contextWindowSize ?? 4096,\n },\n },\n ],\n },\n initProgressCallback: (report: { progress: number }) => {\n if (!cancelled) setLoadProgress(Math.round(report.progress * 100));\n },\n });\n\n if (cancelled) return;\n engineRef.current = engine;\n setMode(\"ready\");\n } catch (err) {\n if (cancelled) return;\n setMode(\"error\");\n setError(\n err instanceof Error ? err.message : \"Failed to load AI model.\"\n );\n }\n };\n\n init();\n return () => { cancelled = true; };\n }, [config.modelUrl, config.modelLib, config.modelSize]);\n\n const send = useCallback(async () => {\n if (!input.trim() || mode !== \"ready\" || isLoading || !engineRef.current) return;\n\n const userMsg: Message = { role: \"user\", content: input.trim() };\n const allMessages = [...messages, userMsg];\n setMessages(allMessages);\n setInput(\"\");\n setIsLoading(true);\n setIsThinking(true);\n setError(null);\n\n try {\n const systemMessages: Message[] = configRef.current.systemPrompt\n ? [{ role: \"system\", content: configRef.current.systemPrompt }]\n : [];\n\n const completion = await engineRef.current.chat.completions.create({\n messages: [...systemMessages, ...allMessages],\n temperature: configRef.current.temperature ?? 0.7,\n max_tokens: configRef.current.maxTokens ?? 1024,\n stream: true,\n });\n\n let text = \"\";\n for await (const chunk of completion) {\n const delta = chunk.choices[0]?.delta?.content || \"\";\n text += delta;\n updateAssistantMessage(text);\n }\n } catch {\n setError(\"Failed to generate response. Please try again.\");\n setMessages((prev) => [\n ...prev,\n { role: \"assistant\", content: \"Sorry, I encountered an error. Please try again.\" },\n ]);\n } finally {\n setIsLoading(false);\n setIsThinking(false);\n }\n }, [input, mode, isLoading, messages, updateAssistantMessage]);\n\n const clear = useCallback(() => {\n setMessages([]);\n setError(null);\n }, []);\n\n return {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n };\n}\n","import type { CSSProperties } from \"react\";\n\nexport function fabStyle(\n primaryColor: string,\n position: \"bottom-right\" | \"bottom-left\",\n): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 24,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 56,\n height: 56,\n borderRadius: \"50%\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n zIndex: 9999,\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n };\n}\n\nexport function panelStyle(position: \"bottom-right\" | \"bottom-left\"): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 96,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 384,\n maxWidth: \"calc(100vw - 48px)\",\n maxHeight: \"calc(100vh - 120px)\",\n borderRadius: 16,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n boxShadow: \"0 8px 30px rgba(0,0,0,0.12)\",\n border: \"1px solid #e5e7eb\",\n background: \"#ffffff\",\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n}\n\nexport const headerStyle: CSSProperties = {\n padding: \"16px\",\n color: \"#fff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n};\n\nexport const headerTitleStyle: CSSProperties = {\n fontWeight: 600,\n fontSize: 15,\n margin: 0,\n};\n\nexport const headerSubtitleStyle: CSSProperties = {\n fontSize: 12,\n opacity: 0.85,\n margin: \"4px 0 0\",\n};\n\nexport const messagesContainerStyle: CSSProperties = {\n flex: 1,\n overflowY: \"auto\",\n padding: 16,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n minHeight: 300,\n maxHeight: 384,\n background: \"#fafafa\",\n};\n\nexport const emptyStateStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n textAlign: \"center\",\n color: \"#6b7280\",\n fontSize: 14,\n padding: 16,\n};\n\nexport function userBubbleStyle(primaryColor: string): CSSProperties {\n return {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: primaryColor,\n color: \"#fff\",\n fontSize: 14,\n lineHeight: 1.5,\n alignSelf: \"flex-end\",\n wordBreak: \"break-word\",\n };\n}\n\nexport const assistantBubbleStyle: CSSProperties = {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: \"#fff\",\n color: \"#1f2937\",\n fontSize: 14,\n lineHeight: 1.5,\n border: \"1px solid #e5e7eb\",\n alignSelf: \"flex-start\",\n wordBreak: \"break-word\",\n};\n\nexport const inputBarStyle: CSSProperties = {\n display: \"flex\",\n gap: 8,\n padding: \"12px 16px\",\n borderTop: \"1px solid #e5e7eb\",\n background: \"#fff\",\n};\n\nexport const textareaStyle: CSSProperties = {\n flex: 1,\n padding: \"8px 12px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n fontSize: 14,\n resize: \"none\",\n overflow: \"hidden\",\n outline: \"none\",\n fontFamily: \"inherit\",\n minHeight: 40,\n maxHeight: 120,\n lineHeight: 1.5,\n};\n\nexport function sendButtonStyle(primaryColor: string): CSSProperties {\n return {\n padding: \"8px 14px\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n borderRadius: 10,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n transition: \"opacity 0.15s ease\",\n };\n}\n\nexport const iconButtonStyle: CSSProperties = {\n background: \"none\",\n border: \"none\",\n color: \"inherit\",\n cursor: \"pointer\",\n padding: 4,\n borderRadius: 8,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: 0.8,\n transition: \"opacity 0.15s ease\",\n};\n\nexport function suggestionButtonStyle(primaryColor: string): CSSProperties {\n return {\n fontSize: 13,\n padding: \"8px 12px\",\n borderRadius: 10,\n border: \"1px solid #e5e7eb\",\n background: \"#fff\",\n color: \"#374151\",\n cursor: \"pointer\",\n textAlign: \"left\" as const,\n width: \"100%\",\n transition: \"border-color 0.15s ease\",\n // hover handled inline\n };\n}\n\nexport const progressBarContainer: CSSProperties = {\n width: \"60%\",\n height: 4,\n borderRadius: 2,\n background: \"rgba(255,255,255,0.3)\",\n marginTop: 8,\n overflow: \"hidden\",\n};\n\nexport function progressBarFill(progress: number, primaryColor: string): CSSProperties {\n return {\n width: `${progress}%`,\n height: \"100%\",\n borderRadius: 2,\n background: primaryColor,\n transition: \"width 0.3s ease\",\n };\n}\n","import {\n useState,\n useEffect,\n useRef,\n type KeyboardEvent,\n type CSSProperties,\n} from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport { useKanhaChat } from \"./use-kanha-chat\";\nimport type { KanhaBotProps } from \"./types\";\nimport * as s from \"./styles\";\n\n// Inline SVG icons (no icon library dependency)\nconst ChatIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n\nconst SendIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\nconst TrashIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\" /><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n);\n\nconst Spinner = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" style={{ animation: \"kanha-spin 1s linear infinite\" }}>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nconst spinKeyframes = `@keyframes kanha-spin { to { transform: rotate(360deg); } }`;\nconst bounceKeyframes = `\n@keyframes kanha-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-4px); }\n}`;\n\nfunction ThinkingDots() {\n const dotStyle = (delay: number): CSSProperties => ({\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n background: \"#9ca3af\",\n animation: `kanha-bounce 1.2s ease-in-out ${delay}ms infinite`,\n });\n return (\n <span style={{ display: \"flex\", gap: 3, alignItems: \"center\" }}>\n <span style={dotStyle(0)} />\n <span style={dotStyle(150)} />\n <span style={dotStyle(300)} />\n <span style={{ fontSize: 12, color: \"#9ca3af\", marginLeft: 6 }}>Thinking</span>\n </span>\n );\n}\n\nexport function KanhaBot({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n botName = \"AI Assistant\",\n welcomeMessage = \"Ask me anything!\",\n suggestions = [],\n theme = {},\n}: KanhaBotProps) {\n const primaryColor = theme.primaryColor ?? \"#0d9488\";\n const position = theme.position ?? \"bottom-right\";\n\n const {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n } = useKanhaChat({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n });\n\n const [isOpen, setIsOpen] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n useEffect(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 120) + \"px\";\n }\n }, [input]);\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n };\n\n const isReady = mode === \"ready\";\n\n return (\n <>\n <style>{spinKeyframes}{bounceKeyframes}</style>\n\n {isOpen && (\n <div style={s.panelStyle(position)}>\n {/* Header */}\n <div style={{ ...s.headerStyle, background: primaryColor }}>\n <div>\n <p style={s.headerTitleStyle}>{botName}</p>\n <p style={s.headerSubtitleStyle}>\n {isReady\n ? welcomeMessage\n : mode === \"loading\"\n ? `Loading AI model (${loadProgress}%)`\n : mode === \"error\"\n ? \"Failed to load\"\n : \"Detecting capabilities...\"}\n </p>\n {mode === \"loading\" && (\n <div style={s.progressBarContainer}>\n <div style={s.progressBarFill(loadProgress, \"#fff\")} />\n </div>\n )}\n </div>\n <div style={{ display: \"flex\", gap: 4 }}>\n {messages.length > 0 && (\n <button onClick={clear} style={s.iconButtonStyle} aria-label=\"Clear chat\">\n <TrashIcon />\n </button>\n )}\n <button onClick={() => setIsOpen(false)} style={s.iconButtonStyle} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Error banner */}\n {error && (\n <div style={{ padding: \"10px 16px\", background: \"#fef2f2\", borderBottom: \"1px solid #fecaca\", fontSize: 13, color: \"#b91c1c\" }}>\n {error}\n </div>\n )}\n\n {/* Messages */}\n <div style={s.messagesContainerStyle}>\n {messages.length === 0 ? (\n <div style={s.emptyStateStyle}>\n {isReady ? (\n <>\n <ChatIcon />\n <p style={{ marginTop: 12, fontWeight: 500, color: \"#374151\" }}>\n {welcomeMessage}\n </p>\n {suggestions.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, width: \"100%\", marginTop: 16 }}>\n {suggestions.map((text) => (\n <button\n key={text}\n onClick={() => { setInput(text); setTimeout(send, 0); }}\n style={s.suggestionButtonStyle(primaryColor)}\n onMouseEnter={(e) => { (e.target as HTMLElement).style.borderColor = primaryColor; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.borderColor = \"#e5e7eb\"; }}\n >\n {text}\n </button>\n ))}\n </div>\n )}\n </>\n ) : mode === \"loading\" ? (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Loading AI model ({loadProgress}%)</p>\n <p style={{ fontSize: 12, marginTop: 4 }}>First load takes about a minute</p>\n </>\n ) : mode === \"error\" ? (\n <p>{error}</p>\n ) : (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Detecting browser capabilities...</p>\n </>\n )}\n </div>\n ) : (\n <>\n {messages.map((msg, i) => (\n <div\n key={i}\n style={{\n display: \"flex\",\n justifyContent: msg.role === \"user\" ? \"flex-end\" : \"flex-start\",\n }}\n >\n <div style={msg.role === \"user\" ? s.userBubbleStyle(primaryColor) : s.assistantBubbleStyle}>\n {msg.role === \"assistant\" ? (\n <ReactMarkdown>{msg.content}</ReactMarkdown>\n ) : (\n <span style={{ whiteSpace: \"pre-wrap\" }}>{msg.content}</span>\n )}\n </div>\n </div>\n ))}\n {isLoading && (isThinking || messages[messages.length - 1]?.role !== \"assistant\") && (\n <div style={{ display: \"flex\", justifyContent: \"flex-start\" }}>\n <div style={s.assistantBubbleStyle}>\n {isThinking ? <ThinkingDots /> : <Spinner size={16} />}\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </>\n )}\n </div>\n\n {/* Input */}\n <div style={s.inputBarStyle}>\n <textarea\n ref={textareaRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder={isReady ? \"Type your message...\" : \"Waiting for model...\"}\n disabled={!isReady || isLoading}\n rows={1}\n style={{\n ...s.textareaStyle,\n opacity: !isReady ? 0.5 : 1,\n }}\n />\n <button\n onClick={send}\n disabled={!isReady || isLoading || !input.trim()}\n style={{\n ...s.sendButtonStyle(primaryColor),\n opacity: !isReady || isLoading || !input.trim() ? 0.5 : 1,\n cursor: !isReady || isLoading || !input.trim() ? \"not-allowed\" : \"pointer\",\n }}\n aria-label=\"Send message\"\n >\n {isLoading ? <Spinner size={18} /> : <SendIcon />}\n </button>\n </div>\n </div>\n )}\n\n {/* FAB */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={s.fabStyle(primaryColor, position)}\n aria-label=\"Toggle chat\"\n onMouseEnter={(e) => { (e.target as HTMLElement).style.transform = \"scale(1.05)\"; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.transform = \"scale(1)\"; }}\n >\n {isOpen ? <CloseIcon /> : <ChatIcon />}\n </button>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/use-kanha-chat.ts","../src/styles.ts","../src/KanhaBot.tsx"],"names":["nav","needed","useState","useRef","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["import { useState, useEffect, useRef, useCallback } from \"react\";\nimport type { Message, InferenceMode, KanhaChatConfig, KanhaChatReturn } from \"./types\";\n\nconst MODEL_LIB_PREFIX =\n \"https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_80\";\n\nconst WASM_BY_SIZE: Record<string, string> = {\n small: `${MODEL_LIB_PREFIX}/Qwen3-0.6B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n medium: `${MODEL_LIB_PREFIX}/Qwen3-1.7B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n large: `${MODEL_LIB_PREFIX}/Qwen3-4B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n};\n\nfunction resolveModelLib(config: KanhaChatConfig): string {\n if (config.modelLib) return config.modelLib;\n const size = config.modelSize ?? \"small\";\n const lib = WASM_BY_SIZE[size];\n if (!lib) throw new Error(`Unknown model size \"${size}\". Provide modelLib explicitly.`);\n return lib;\n}\n\n/**\n * Converts a storage URL into a format web-llm's cleanModelUrl won't mangle.\n * web-llm checks for /resolve/ in the URL — if missing, it appends /resolve/main/.\n * We append /resolve/v1/ so the URL passes through untouched.\n * Files must be stored at {modelUrl}/resolve/v1/{filename} in storage.\n */\nfunction toWebLLMModelUrl(modelUrl: string): string {\n let url = modelUrl.endsWith(\"/\") ? modelUrl.slice(0, -1) : modelUrl;\n if (!url.includes(\"/resolve/\")) {\n url += \"/resolve/v1\";\n }\n return url;\n}\n\n// Minimum device RAM (GB) recommended per model size\nconst MIN_RAM_GB: Record<string, number> = {\n small: 4,\n medium: 8,\n large: 12,\n};\n\nasync function checkWebGPU(): Promise<boolean> {\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<unknown> } };\n if (!nav.gpu) return false;\n const adapter = (await nav.gpu.requestAdapter()) as { requestDevice(): Promise<unknown> } | null;\n if (!adapter) return false;\n const device = await adapter.requestDevice();\n return !!device;\n } catch {\n return false;\n }\n}\n\n// Approximate model weight sizes in bytes (q4f16_1 quantized)\nconst MODEL_WEIGHT_BYTES: Record<string, number> = {\n small: 400 * 1024 * 1024, // ~400MB\n medium: 1100 * 1024 * 1024, // ~1.1GB\n large: 2500 * 1024 * 1024, // ~2.5GB\n};\n\nasync function checkAvailableMemory(modelSize: string): Promise<string | null> {\n // 1. Try WebGPU adapter limits (most reliable for GPU memory)\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<{ limits: { maxBufferSize: number } } | null> } };\n if (nav.gpu) {\n const adapter = await nav.gpu.requestAdapter();\n if (adapter) {\n const maxBufferSize = adapter.limits.maxBufferSize;\n const needed = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;\n // If the GPU's max buffer is smaller than model weights, it won't fit\n if (maxBufferSize < needed) {\n const maxMB = Math.round(maxBufferSize / (1024 * 1024));\n const needMB = Math.round(needed / (1024 * 1024));\n return `Your GPU can only allocate ~${maxMB}MB but the ${modelSize} model needs ~${needMB}MB. Try a smaller model or close other GPU-heavy tabs.`;\n }\n }\n }\n } catch { /* ignore, fall through */ }\n\n // 2. Try probing available system memory with a test allocation\n const needed = MODEL_WEIGHT_BYTES[modelSize] ?? MODEL_WEIGHT_BYTES.small;\n const probeSize = Math.min(needed, 512 * 1024 * 1024); // probe up to 512MB\n try {\n const buf = new ArrayBuffer(probeSize);\n // If we got here, allocation succeeded — free it\n // (TypeScript doesn't have explicit free, but losing the reference lets GC collect)\n if (buf.byteLength !== probeSize) {\n return `Your device doesn't have enough free memory to load the ${modelSize} model. Close other tabs and try again.`;\n }\n } catch {\n const needMB = Math.round(needed / (1024 * 1024));\n return `Not enough free memory to load the ${modelSize} model (~${needMB}MB required). Close other tabs and try again.`;\n }\n\n // 3. Fallback: check navigator.deviceMemory (coarse, total RAM)\n const nav = navigator as Navigator & { deviceMemory?: number };\n if (nav.deviceMemory) {\n const required = MIN_RAM_GB[modelSize] ?? MIN_RAM_GB.small;\n if (nav.deviceMemory < required) {\n return `Your device has ~${nav.deviceMemory}GB RAM but the ${modelSize} model needs at least ${required}GB.`;\n }\n }\n\n return null;\n}\n\nfunction isMemoryError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const msg = err.message.toLowerCase();\n return (\n msg.includes(\"out of memory\") ||\n msg.includes(\"oom\") ||\n msg.includes(\"allocation failed\") ||\n msg.includes(\"err_failed\") ||\n msg.includes(\"arraybuffer\") ||\n msg.includes(\"could not allocate\") ||\n msg.includes(\"webgpu device lost\")\n );\n}\n\nfunction stripThinkTokens(text: string): string {\n let cleaned = text.replace(/<think>[\\s\\S]*?<\\/think>/g, \"\");\n cleaned = cleaned.replace(/<think>[\\s\\S]*$/g, \"\");\n return cleaned.trimStart();\n}\n\nexport function useKanhaChat(config: KanhaChatConfig): KanhaChatReturn {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [isThinking, setIsThinking] = useState(false);\n const [mode, setMode] = useState<InferenceMode>(\"detecting\");\n const [loadProgress, setLoadProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const engineRef = useRef<any>(null);\n const configRef = useRef(config);\n configRef.current = config;\n\n const updateAssistantMessage = useCallback((text: string) => {\n const cleaned = stripThinkTokens(text);\n if (!cleaned) {\n setIsThinking(true);\n return;\n }\n setIsThinking(false);\n setMessages((prev) => {\n const msgs = [...prev];\n if (msgs[msgs.length - 1]?.role === \"assistant\") {\n msgs[msgs.length - 1] = { role: \"assistant\", content: cleaned };\n } else {\n msgs.push({ role: \"assistant\", content: cleaned });\n }\n return msgs;\n });\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n let cancelled = false;\n\n const init = async () => {\n setMode(\"detecting\");\n\n const hasWebGPU = await checkWebGPU();\n if (!hasWebGPU) {\n setMode(\"error\");\n setError(\"WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.\");\n return;\n }\n\n const modelSize = configRef.current.modelSize ?? \"small\";\n const memWarning = await checkAvailableMemory(modelSize);\n if (memWarning) {\n setMode(\"error\");\n setError(memWarning);\n return;\n }\n\n if (cancelled) return;\n setMode(\"loading\");\n\n try {\n const webllm = await import(\"@mlc-ai/web-llm\");\n const modelId = \"kanha-custom-model\";\n const modelLib = resolveModelLib(configRef.current);\n const modelUrl = toWebLLMModelUrl(configRef.current.modelUrl);\n\n const engine = await webllm.CreateMLCEngine(modelId, {\n appConfig: {\n model_list: [\n {\n model: modelUrl,\n model_id: modelId,\n model_lib: modelLib,\n overrides: {\n context_window_size: configRef.current.contextWindowSize ?? 4096,\n },\n },\n ],\n useIndexedDBCache: true,\n },\n initProgressCallback: (report: { progress: number }) => {\n if (!cancelled) setLoadProgress(Math.round(report.progress * 100));\n },\n logLevel: \"SILENT\",\n });\n\n if (cancelled) return;\n engineRef.current = engine;\n setMode(\"ready\");\n } catch (err) {\n if (cancelled) return;\n setMode(\"error\");\n if (isMemoryError(err)) {\n const size = configRef.current.modelSize ?? \"small\";\n const ram = (navigator as Navigator & { deviceMemory?: number }).deviceMemory;\n setError(\n `Not enough memory to load the ${size} model${ram ? ` (device has ~${ram}GB RAM)` : \"\"}. ` +\n `Close other tabs or try a smaller model.`\n );\n } else {\n setError(\n err instanceof Error ? err.message : \"Failed to load AI model.\"\n );\n }\n }\n };\n\n init();\n return () => {\n cancelled = true;\n if (engineRef.current) {\n try { engineRef.current.unload(); } catch { /* best-effort */ }\n engineRef.current = null;\n }\n };\n }, [config.modelUrl, config.modelLib, config.modelSize]);\n\n const send = useCallback(async () => {\n if (!input.trim() || mode !== \"ready\" || isLoading || !engineRef.current) return;\n\n const userMsg: Message = { role: \"user\", content: input.trim() };\n const allMessages = [...messages, userMsg];\n setMessages(allMessages);\n setInput(\"\");\n setIsLoading(true);\n setIsThinking(true);\n setError(null);\n\n try {\n const systemMessages: Message[] = configRef.current.systemPrompt\n ? [{ role: \"system\", content: configRef.current.systemPrompt }]\n : [];\n\n const completion = await engineRef.current.chat.completions.create({\n messages: [...systemMessages, ...allMessages],\n temperature: configRef.current.temperature ?? 0.7,\n max_tokens: configRef.current.maxTokens ?? 1024,\n stream: true,\n });\n\n let text = \"\";\n for await (const chunk of completion) {\n const delta = chunk.choices[0]?.delta?.content || \"\";\n text += delta;\n updateAssistantMessage(text);\n }\n } catch {\n setError(\"Failed to generate response. Please try again.\");\n setMessages((prev) => [\n ...prev,\n { role: \"assistant\", content: \"Sorry, I encountered an error. Please try again.\" },\n ]);\n } finally {\n setIsLoading(false);\n setIsThinking(false);\n }\n }, [input, mode, isLoading, messages, updateAssistantMessage]);\n\n const clear = useCallback(() => {\n setMessages([]);\n setError(null);\n }, []);\n\n return {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n };\n}\n","import type { CSSProperties } from \"react\";\n\nexport function fabStyle(\n primaryColor: string,\n position: \"bottom-right\" | \"bottom-left\",\n): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 24,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 56,\n height: 56,\n borderRadius: \"50%\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n zIndex: 9999,\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n };\n}\n\nexport function panelStyle(position: \"bottom-right\" | \"bottom-left\"): CSSProperties {\n return {\n position: \"fixed\",\n bottom: 96,\n [position === \"bottom-right\" ? \"right\" : \"left\"]: 24,\n width: 384,\n maxWidth: \"calc(100vw - 48px)\",\n maxHeight: \"calc(100vh - 120px)\",\n borderRadius: 16,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n boxShadow: \"0 8px 30px rgba(0,0,0,0.12)\",\n border: \"1px solid #e5e7eb\",\n background: \"#ffffff\",\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n}\n\nexport const headerStyle: CSSProperties = {\n padding: \"16px\",\n color: \"#fff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n};\n\nexport const headerTitleStyle: CSSProperties = {\n fontWeight: 600,\n fontSize: 15,\n margin: 0,\n};\n\nexport const headerSubtitleStyle: CSSProperties = {\n fontSize: 12,\n opacity: 0.85,\n margin: \"4px 0 0\",\n};\n\nexport const messagesContainerStyle: CSSProperties = {\n flex: 1,\n overflowY: \"auto\",\n padding: 16,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n minHeight: 300,\n maxHeight: 384,\n background: \"#fafafa\",\n};\n\nexport const emptyStateStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n textAlign: \"center\",\n color: \"#6b7280\",\n fontSize: 14,\n padding: 16,\n};\n\nexport function userBubbleStyle(primaryColor: string): CSSProperties {\n return {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: primaryColor,\n color: \"#fff\",\n fontSize: 14,\n lineHeight: 1.5,\n alignSelf: \"flex-end\",\n wordBreak: \"break-word\",\n };\n}\n\nexport const assistantBubbleStyle: CSSProperties = {\n maxWidth: \"80%\",\n padding: \"8px 14px\",\n borderRadius: 16,\n background: \"#fff\",\n color: \"#1f2937\",\n fontSize: 14,\n lineHeight: 1.5,\n border: \"1px solid #e5e7eb\",\n alignSelf: \"flex-start\",\n wordBreak: \"break-word\",\n};\n\nexport const inputBarStyle: CSSProperties = {\n display: \"flex\",\n gap: 8,\n padding: \"12px 16px\",\n borderTop: \"1px solid #e5e7eb\",\n background: \"#fff\",\n};\n\nexport const textareaStyle: CSSProperties = {\n flex: 1,\n padding: \"8px 12px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n fontSize: 14,\n resize: \"none\",\n overflow: \"hidden\",\n outline: \"none\",\n fontFamily: \"inherit\",\n minHeight: 40,\n maxHeight: 120,\n lineHeight: 1.5,\n};\n\nexport function sendButtonStyle(primaryColor: string): CSSProperties {\n return {\n padding: \"8px 14px\",\n background: primaryColor,\n color: \"#fff\",\n border: \"none\",\n borderRadius: 10,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n transition: \"opacity 0.15s ease\",\n };\n}\n\nexport const iconButtonStyle: CSSProperties = {\n background: \"none\",\n border: \"none\",\n color: \"inherit\",\n cursor: \"pointer\",\n padding: 4,\n borderRadius: 8,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: 0.8,\n transition: \"opacity 0.15s ease\",\n};\n\nexport function suggestionButtonStyle(primaryColor: string): CSSProperties {\n return {\n fontSize: 13,\n padding: \"8px 12px\",\n borderRadius: 10,\n border: \"1px solid #e5e7eb\",\n background: \"#fff\",\n color: \"#374151\",\n cursor: \"pointer\",\n textAlign: \"left\" as const,\n width: \"100%\",\n transition: \"border-color 0.15s ease\",\n // hover handled inline\n };\n}\n\nexport const progressBarContainer: CSSProperties = {\n width: \"60%\",\n height: 4,\n borderRadius: 2,\n background: \"rgba(255,255,255,0.3)\",\n marginTop: 8,\n overflow: \"hidden\",\n};\n\nexport function progressBarFill(progress: number, primaryColor: string): CSSProperties {\n return {\n width: `${progress}%`,\n height: \"100%\",\n borderRadius: 2,\n background: primaryColor,\n transition: \"width 0.3s ease\",\n };\n}\n","import {\n useState,\n useEffect,\n useRef,\n type KeyboardEvent,\n type CSSProperties,\n} from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport { useKanhaChat } from \"./use-kanha-chat\";\nimport type { KanhaBotProps } from \"./types\";\nimport * as s from \"./styles\";\n\n// Inline SVG icons (no icon library dependency)\nconst ChatIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n\nconst SendIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\nconst TrashIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\" /><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n);\n\nconst Spinner = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" style={{ animation: \"kanha-spin 1s linear infinite\" }}>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nconst spinKeyframes = `@keyframes kanha-spin { to { transform: rotate(360deg); } }`;\nconst bounceKeyframes = `\n@keyframes kanha-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-4px); }\n}`;\n\nfunction ThinkingDots() {\n const dotStyle = (delay: number): CSSProperties => ({\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n background: \"#9ca3af\",\n animation: `kanha-bounce 1.2s ease-in-out ${delay}ms infinite`,\n });\n return (\n <span style={{ display: \"flex\", gap: 3, alignItems: \"center\" }}>\n <span style={dotStyle(0)} />\n <span style={dotStyle(150)} />\n <span style={dotStyle(300)} />\n <span style={{ fontSize: 12, color: \"#9ca3af\", marginLeft: 6 }}>Thinking</span>\n </span>\n );\n}\n\nexport function KanhaBot({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n botName = \"AI Assistant\",\n welcomeMessage = \"Ask me anything!\",\n suggestions = [],\n theme = {},\n}: KanhaBotProps) {\n const primaryColor = theme.primaryColor ?? \"#0d9488\";\n const position = theme.position ?? \"bottom-right\";\n\n const {\n messages,\n input,\n setInput,\n isLoading,\n isThinking,\n mode,\n loadProgress,\n error,\n send,\n clear,\n } = useKanhaChat({\n modelUrl,\n modelLib,\n modelSize,\n systemPrompt,\n temperature,\n maxTokens,\n contextWindowSize,\n });\n\n const [isOpen, setIsOpen] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n useEffect(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 120) + \"px\";\n }\n }, [input]);\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n };\n\n const isReady = mode === \"ready\";\n\n return (\n <>\n <style>{spinKeyframes}{bounceKeyframes}</style>\n\n {isOpen && (\n <div style={s.panelStyle(position)}>\n {/* Header */}\n <div style={{ ...s.headerStyle, background: primaryColor }}>\n <div>\n <p style={s.headerTitleStyle}>{botName}</p>\n <p style={s.headerSubtitleStyle}>\n {isReady\n ? welcomeMessage\n : mode === \"loading\"\n ? `Loading AI model (${loadProgress}%)`\n : mode === \"error\"\n ? \"Failed to load\"\n : \"Detecting capabilities...\"}\n </p>\n {mode === \"loading\" && (\n <div style={s.progressBarContainer}>\n <div style={s.progressBarFill(loadProgress, \"#fff\")} />\n </div>\n )}\n </div>\n <div style={{ display: \"flex\", gap: 4 }}>\n {messages.length > 0 && (\n <button onClick={clear} style={s.iconButtonStyle} aria-label=\"Clear chat\">\n <TrashIcon />\n </button>\n )}\n <button onClick={() => setIsOpen(false)} style={s.iconButtonStyle} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Error banner */}\n {error && (\n <div style={{ padding: \"10px 16px\", background: \"#fef2f2\", borderBottom: \"1px solid #fecaca\", fontSize: 13, color: \"#b91c1c\" }}>\n {error}\n </div>\n )}\n\n {/* Messages */}\n <div style={s.messagesContainerStyle}>\n {messages.length === 0 ? (\n <div style={s.emptyStateStyle}>\n {isReady ? (\n <>\n <ChatIcon />\n <p style={{ marginTop: 12, fontWeight: 500, color: \"#374151\" }}>\n {welcomeMessage}\n </p>\n {suggestions.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, width: \"100%\", marginTop: 16 }}>\n {suggestions.map((text) => (\n <button\n key={text}\n onClick={() => { setInput(text); setTimeout(send, 0); }}\n style={s.suggestionButtonStyle(primaryColor)}\n onMouseEnter={(e) => { (e.target as HTMLElement).style.borderColor = primaryColor; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.borderColor = \"#e5e7eb\"; }}\n >\n {text}\n </button>\n ))}\n </div>\n )}\n </>\n ) : mode === \"loading\" ? (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Loading AI model ({loadProgress}%)</p>\n <p style={{ fontSize: 12, marginTop: 4 }}>First load takes about a minute</p>\n </>\n ) : mode === \"error\" ? (\n <p>{error}</p>\n ) : (\n <>\n <Spinner size={32} />\n <p style={{ marginTop: 8 }}>Detecting browser capabilities...</p>\n </>\n )}\n </div>\n ) : (\n <>\n {messages.map((msg, i) => (\n <div\n key={i}\n style={{\n display: \"flex\",\n justifyContent: msg.role === \"user\" ? \"flex-end\" : \"flex-start\",\n }}\n >\n <div style={msg.role === \"user\" ? s.userBubbleStyle(primaryColor) : s.assistantBubbleStyle}>\n {msg.role === \"assistant\" ? (\n <ReactMarkdown>{msg.content}</ReactMarkdown>\n ) : (\n <span style={{ whiteSpace: \"pre-wrap\" }}>{msg.content}</span>\n )}\n </div>\n </div>\n ))}\n {isLoading && (isThinking || messages[messages.length - 1]?.role !== \"assistant\") && (\n <div style={{ display: \"flex\", justifyContent: \"flex-start\" }}>\n <div style={s.assistantBubbleStyle}>\n {isThinking ? <ThinkingDots /> : <Spinner size={16} />}\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </>\n )}\n </div>\n\n {/* Input */}\n <div style={s.inputBarStyle}>\n <textarea\n ref={textareaRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder={isReady ? \"Type your message...\" : \"Waiting for model...\"}\n disabled={!isReady || isLoading}\n rows={1}\n style={{\n ...s.textareaStyle,\n opacity: !isReady ? 0.5 : 1,\n }}\n />\n <button\n onClick={send}\n disabled={!isReady || isLoading || !input.trim()}\n style={{\n ...s.sendButtonStyle(primaryColor),\n opacity: !isReady || isLoading || !input.trim() ? 0.5 : 1,\n cursor: !isReady || isLoading || !input.trim() ? \"not-allowed\" : \"pointer\",\n }}\n aria-label=\"Send message\"\n >\n {isLoading ? <Spinner size={18} /> : <SendIcon />}\n </button>\n </div>\n </div>\n )}\n\n {/* FAB */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={s.fabStyle(primaryColor, position)}\n aria-label=\"Toggle chat\"\n onMouseEnter={(e) => { (e.target as HTMLElement).style.transform = \"scale(1.05)\"; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.transform = \"scale(1)\"; }}\n >\n {isOpen ? <CloseIcon /> : <ChatIcon />}\n </button>\n </>\n );\n}\n"]}
|
package/dist/widget.js
CHANGED
|
@@ -170,7 +170,8 @@ var KanhaBotWidget = class {
|
|
|
170
170
|
model_id: modelId,
|
|
171
171
|
model_lib: modelLib,
|
|
172
172
|
overrides: { context_window_size: this.props.contextWindowSize ?? 4096 }
|
|
173
|
-
}]
|
|
173
|
+
}],
|
|
174
|
+
useIndexedDBCache: true
|
|
174
175
|
},
|
|
175
176
|
initProgressCallback: (report) => {
|
|
176
177
|
if (!this.unmounted) this.setState({ loadProgress: Math.round(report.progress * 100) });
|
package/dist/widget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widget.ts"],"names":[],"mappings":"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","file":"widget.js","sourcesContent":["/**\n * Standalone widget for CDN / vanilla JS usage.\n * No React dependency — pure DOM manipulation.\n *\n * Usage via CDN:\n * <script type=\"module\">\n * import { mount } from 'https://cdn.jsdelivr.net/npm/kanha/dist/widget.js';\n * const bot = mount('#chat', { modelUrl: '...', systemPrompt: '...' });\n * </script>\n *\n * Or as a web component:\n * <script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/kanha/dist/widget.js\"></script>\n * <kanha-bot model-url=\"...\" system-prompt=\"...\" bot-name=\"Acme Bot\"></kanha-bot>\n */\n\nimport type { KanhaBotProps, KanhaBotTheme, Message, InferenceMode } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Engine (same logic as use-kanha-chat.ts, but non-React)\n// ---------------------------------------------------------------------------\n\nconst MODEL_LIB_PREFIX =\n \"https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_80\";\n\nconst WASM_BY_SIZE: Record<string, string> = {\n small: `${MODEL_LIB_PREFIX}/Qwen3-0.6B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n medium: `${MODEL_LIB_PREFIX}/Qwen3-1.7B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n large: `${MODEL_LIB_PREFIX}/Qwen3-4B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n};\n\nfunction resolveModelLib(modelLib?: string, modelSize?: string): string {\n if (modelLib) return modelLib;\n const size = modelSize ?? \"small\";\n const lib = WASM_BY_SIZE[size];\n if (!lib) throw new Error(`Unknown model size \"${size}\". Provide modelLib explicitly.`);\n return lib;\n}\n\nfunction toWebLLMModelUrl(modelUrl: string): string {\n let url = modelUrl.endsWith(\"/\") ? modelUrl.slice(0, -1) : modelUrl;\n if (!url.includes(\"/resolve/\")) url += \"/resolve/v1\";\n return url;\n}\n\nasync function checkWebGPU(): Promise<boolean> {\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<unknown> } };\n if (!nav.gpu) return false;\n const adapter = (await nav.gpu.requestAdapter()) as { requestDevice(): Promise<unknown> } | null;\n if (!adapter) return false;\n return !!(await adapter.requestDevice());\n } catch {\n return false;\n }\n}\n\nfunction stripThinkTokens(text: string): string {\n let cleaned = text.replace(/<think>[\\s\\S]*?<\\/think>/g, \"\");\n cleaned = cleaned.replace(/<think>[\\s\\S]*$/g, \"\");\n return cleaned.trimStart();\n}\n\nfunction esc(text: string): string {\n const el = document.createElement(\"span\");\n el.textContent = text;\n return el.innerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// DOM Widget\n// ---------------------------------------------------------------------------\n\nconst CSS = `\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n}\n@keyframes kb-spin { to { transform: rotate(360deg); } }\n@keyframes kb-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-4px); }\n}\n.kb-fab {\n position: fixed; bottom: 24px; width: 56px; height: 56px; border-radius: 50%;\n color: #fff; border: none; cursor: pointer; display: flex; align-items: center;\n justify-content: center; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 9999;\n transition: transform 0.15s ease;\n}\n.kb-fab:hover { transform: scale(1.05); }\n.kb-panel {\n position: fixed; bottom: 96px; width: 384px; max-width: calc(100vw - 48px);\n border-radius: 16px; overflow: hidden; display: flex; flex-direction: column;\n box-shadow: 0 8px 30px rgba(0,0,0,0.12); border: 1px solid #e5e7eb;\n background: #fff; z-index: 9999;\n}\n.kb-header { padding: 16px; color: #fff; display: flex; align-items: center; justify-content: space-between; }\n.kb-header-title { font-weight: 600; font-size: 15px; margin: 0; }\n.kb-header-sub { font-size: 12px; opacity: 0.85; margin: 4px 0 0; }\n.kb-progress { width: 60%; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.3); margin-top: 8px; overflow: hidden; }\n.kb-progress-fill { height: 100%; border-radius: 2px; background: #fff; transition: width 0.3s ease; }\n.kb-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; min-height: 300px; max-height: 384px; background: #fafafa; }\n.kb-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; color: #6b7280; font-size: 14px; padding: 16px; }\n.kb-msg { display: flex; }\n.kb-msg-user { justify-content: flex-end; }\n.kb-msg-assistant { justify-content: flex-start; }\n.kb-bubble { max-width: 80%; padding: 8px 14px; border-radius: 16px; font-size: 14px; line-height: 1.5; word-break: break-word; }\n.kb-bubble-user { color: #fff; }\n.kb-bubble-assistant { background: #fff; color: #1f2937; border: 1px solid #e5e7eb; }\n.kb-bubble p { margin: 0; } .kb-bubble p + p { margin-top: 8px; }\n.kb-thinking { display: flex; gap: 3px; align-items: center; }\n.kb-dot { width: 6px; height: 6px; border-radius: 50%; background: #9ca3af; }\n.kb-dot:nth-child(1) { animation: kb-bounce 1.2s ease-in-out 0ms infinite; }\n.kb-dot:nth-child(2) { animation: kb-bounce 1.2s ease-in-out 150ms infinite; }\n.kb-dot:nth-child(3) { animation: kb-bounce 1.2s ease-in-out 300ms infinite; }\n.kb-thinking-label { font-size: 12px; color: #9ca3af; margin-left: 6px; }\n.kb-spinner { animation: kb-spin 1s linear infinite; }\n.kb-input-bar { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid #e5e7eb; background: #fff; }\n.kb-textarea {\n flex: 1; padding: 8px 12px; border: 1px solid #e5e7eb; border-radius: 10px; font-size: 14px;\n resize: none; overflow: hidden; outline: none; font-family: inherit; min-height: 40px; max-height: 120px; line-height: 1.5;\n}\n.kb-textarea:focus { box-shadow: 0 0 0 2px rgba(13,148,136,0.25); }\n.kb-send {\n padding: 8px 14px; color: #fff; border: none; border-radius: 10px; cursor: pointer;\n display: flex; align-items: center; justify-content: center; flex-shrink: 0;\n transition: opacity 0.15s ease;\n}\n.kb-send:disabled { opacity: 0.5; cursor: not-allowed; }\n.kb-icon-btn { background: none; border: none; color: inherit; cursor: pointer; padding: 4px; border-radius: 8px; display: flex; align-items: center; opacity: 0.8; }\n.kb-icon-btn:hover { opacity: 1; }\n.kb-suggestions { display: flex; flex-direction: column; gap: 6px; width: 100%; margin-top: 16px; }\n.kb-suggestion {\n font-size: 13px; padding: 8px 12px; border-radius: 10px; border: 1px solid #e5e7eb;\n background: #fff; color: #374151; cursor: pointer; text-align: left; width: 100%;\n transition: border-color 0.15s ease;\n}\n.kb-suggestion:hover { border-color: var(--kb-primary, #0d9488); }\n.kb-error { padding: 10px 16px; background: #fef2f2; border-bottom: 1px solid #fecaca; font-size: 13px; color: #b91c1c; }\n`;\n\nconst SVG_CHAT = `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`;\nconst SVG_CLOSE = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\nconst SVG_SEND = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/></svg>`;\nconst SVG_TRASH = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`;\nconst SVG_SPINNER = `<svg width=\"SIZE\" height=\"SIZE\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" class=\"kb-spinner\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg>`;\n\nfunction spinner(size = 18) {\n return SVG_SPINNER.replace(/SIZE/g, String(size));\n}\n\ninterface WidgetState {\n messages: Message[];\n input: string;\n isLoading: boolean;\n isThinking: boolean;\n mode: InferenceMode;\n loadProgress: number;\n error: string | null;\n isOpen: boolean;\n}\n\nclass KanhaBotWidget {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private engine: any = null;\n private props: KanhaBotProps;\n private state: WidgetState;\n private root: ShadowRoot;\n private panelEl: HTMLElement | null = null;\n private messagesEl: HTMLElement | null = null;\n private textareaEl: HTMLTextAreaElement | null = null;\n private unmounted = false;\n\n constructor(container: HTMLElement, props: KanhaBotProps) {\n this.props = {\n botName: \"AI Assistant\",\n welcomeMessage: \"Ask me anything!\",\n suggestions: [],\n theme: {},\n ...props,\n };\n this.state = {\n messages: [],\n input: \"\",\n isLoading: false,\n isThinking: false,\n mode: \"detecting\",\n loadProgress: 0,\n error: null,\n isOpen: false,\n };\n\n this.root = container.attachShadow({ mode: \"open\" });\n const style = document.createElement(\"style\");\n style.textContent = CSS;\n this.root.appendChild(style);\n\n this.render();\n this.initEngine();\n }\n\n private get primary(): string {\n return this.props.theme?.primaryColor ?? \"#0d9488\";\n }\n\n private get position(): \"bottom-right\" | \"bottom-left\" {\n return this.props.theme?.position ?? \"bottom-right\";\n }\n\n private async initEngine() {\n const hasWebGPU = await checkWebGPU();\n if (!hasWebGPU) {\n this.setState({ mode: \"error\", error: \"WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.\" });\n return;\n }\n\n this.setState({ mode: \"loading\" });\n\n try {\n const webllm = await import(\"@mlc-ai/web-llm\");\n const modelId = \"kanha-custom-model\";\n const modelLib = resolveModelLib(this.props.modelLib, this.props.modelSize);\n const modelUrl = toWebLLMModelUrl(this.props.modelUrl);\n\n this.engine = await webllm.CreateMLCEngine(modelId, {\n appConfig: {\n model_list: [{\n model: modelUrl,\n model_id: modelId,\n model_lib: modelLib,\n overrides: { context_window_size: this.props.contextWindowSize ?? 4096 },\n }],\n },\n initProgressCallback: (report: { progress: number }) => {\n if (!this.unmounted) this.setState({ loadProgress: Math.round(report.progress * 100) });\n },\n });\n\n if (!this.unmounted) this.setState({ mode: \"ready\" });\n } catch (err) {\n if (!this.unmounted) {\n this.setState({\n mode: \"error\",\n error: err instanceof Error ? err.message : \"Failed to load AI model.\",\n });\n }\n }\n }\n\n private setState(partial: Partial<WidgetState>) {\n Object.assign(this.state, partial);\n this.render();\n }\n\n private async handleSend() {\n const text = this.state.input.trim();\n if (!text || this.state.mode !== \"ready\" || this.state.isLoading || !this.engine) return;\n\n const userMsg: Message = { role: \"user\", content: text };\n const allMessages = [...this.state.messages, userMsg];\n this.setState({ messages: allMessages, input: \"\", isLoading: true, isThinking: true, error: null });\n\n try {\n const systemMessages: Message[] = this.props.systemPrompt\n ? [{ role: \"system\", content: this.props.systemPrompt }]\n : [];\n\n const completion = await this.engine.chat.completions.create({\n messages: [...systemMessages, ...allMessages],\n temperature: this.props.temperature ?? 0.7,\n max_tokens: this.props.maxTokens ?? 1024,\n stream: true,\n });\n\n let fullText = \"\";\n for await (const chunk of completion) {\n const delta = chunk.choices[0]?.delta?.content || \"\";\n fullText += delta;\n const cleaned = stripThinkTokens(fullText);\n if (!cleaned) {\n this.setState({ isThinking: true });\n } else {\n const msgs = [...allMessages];\n if (msgs[msgs.length - 1]?.role === \"assistant\") {\n msgs[msgs.length - 1] = { role: \"assistant\", content: cleaned };\n } else {\n msgs.push({ role: \"assistant\", content: cleaned });\n }\n this.setState({ messages: msgs, isThinking: false });\n }\n }\n } catch {\n this.setState({\n error: \"Failed to generate response. Please try again.\",\n messages: [...allMessages, { role: \"assistant\", content: \"Sorry, I encountered an error. Please try again.\" }],\n });\n } finally {\n this.setState({ isLoading: false, isThinking: false });\n }\n }\n\n private render() {\n const { messages, isLoading, isThinking, mode, loadProgress, error, isOpen } = this.state;\n const isReady = mode === \"ready\";\n\n // Clear non-style children\n const style = this.root.querySelector(\"style\");\n this.root.innerHTML = \"\";\n if (style) this.root.appendChild(style);\n\n // Set CSS variable for primary color\n const wrapper = document.createElement(\"div\");\n wrapper.style.setProperty(\"--kb-primary\", this.primary);\n this.root.appendChild(wrapper);\n\n // FAB\n const fab = document.createElement(\"button\");\n fab.className = \"kb-fab\";\n fab.style.background = this.primary;\n fab.style[this.position === \"bottom-right\" ? \"right\" : \"left\"] = \"24px\";\n fab.innerHTML = isOpen ? SVG_CLOSE : SVG_CHAT;\n fab.setAttribute(\"aria-label\", \"Toggle chat\");\n fab.onclick = () => this.setState({ isOpen: !isOpen });\n wrapper.appendChild(fab);\n\n if (!isOpen) return;\n\n // Panel\n const panel = document.createElement(\"div\");\n panel.className = \"kb-panel\";\n panel.style[this.position === \"bottom-right\" ? \"right\" : \"left\"] = \"24px\";\n wrapper.appendChild(panel);\n this.panelEl = panel;\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"kb-header\";\n header.style.background = this.primary;\n header.innerHTML = `\n <div>\n <p class=\"kb-header-title\">${esc(this.props.botName!)}</p>\n <p class=\"kb-header-sub\">${\n isReady ? esc(this.props.welcomeMessage!)\n : mode === \"loading\" ? `Loading AI model (${loadProgress}%)`\n : mode === \"error\" ? \"Failed to load\"\n : \"Detecting capabilities...\"\n }</p>\n ${mode === \"loading\" ? `<div class=\"kb-progress\"><div class=\"kb-progress-fill\" style=\"width:${loadProgress}%\"></div></div>` : \"\"}\n </div>\n <div style=\"display:flex;gap:4px\">\n ${messages.length > 0 ? `<button class=\"kb-icon-btn\" data-action=\"clear\" aria-label=\"Clear\">${SVG_TRASH}</button>` : \"\"}\n <button class=\"kb-icon-btn\" data-action=\"close\" aria-label=\"Close\">${SVG_CLOSE}</button>\n </div>`;\n header.querySelector(\"[data-action=clear]\")?.addEventListener(\"click\", () => this.setState({ messages: [], error: null }));\n header.querySelector(\"[data-action=close]\")?.addEventListener(\"click\", () => this.setState({ isOpen: false }));\n panel.appendChild(header);\n\n // Error\n if (error) {\n const errEl = document.createElement(\"div\");\n errEl.className = \"kb-error\";\n errEl.textContent = error;\n panel.appendChild(errEl);\n }\n\n // Messages\n const msgsContainer = document.createElement(\"div\");\n msgsContainer.className = \"kb-messages\";\n panel.appendChild(msgsContainer);\n this.messagesEl = msgsContainer;\n\n if (messages.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"kb-empty\";\n if (isReady) {\n empty.innerHTML = `${SVG_CHAT}<p style=\"margin-top:12px;font-weight:500;color:#374151\">${esc(this.props.welcomeMessage!)}</p>`;\n if (this.props.suggestions && this.props.suggestions.length > 0) {\n const sugDiv = document.createElement(\"div\");\n sugDiv.className = \"kb-suggestions\";\n for (const text of this.props.suggestions) {\n const btn = document.createElement(\"button\");\n btn.className = \"kb-suggestion\";\n btn.textContent = text;\n btn.onclick = () => {\n this.setState({ input: text });\n setTimeout(() => this.handleSend(), 0);\n };\n sugDiv.appendChild(btn);\n }\n empty.appendChild(sugDiv);\n }\n } else if (mode === \"loading\") {\n empty.innerHTML = `${spinner(32)}<p style=\"margin-top:8px\">Loading AI model (${loadProgress}%)</p><p style=\"font-size:12px;margin-top:4px\">First load takes about a minute</p>`;\n } else if (mode === \"error\") {\n empty.innerHTML = `<p>${esc(error ?? \"An error occurred\")}</p>`;\n } else {\n empty.innerHTML = `${spinner(32)}<p style=\"margin-top:8px\">Detecting browser capabilities...</p>`;\n }\n msgsContainer.appendChild(empty);\n } else {\n for (const msg of messages) {\n const row = document.createElement(\"div\");\n row.className = `kb-msg kb-msg-${msg.role}`;\n const bubble = document.createElement(\"div\");\n bubble.className = `kb-bubble kb-bubble-${msg.role}`;\n if (msg.role === \"user\") {\n bubble.style.background = this.primary;\n bubble.innerHTML = `<span style=\"white-space:pre-wrap\">${esc(msg.content)}</span>`;\n } else {\n // Simple markdown: paragraphs only (no heavy dep for CDN build)\n bubble.innerHTML = msg.content\n .split(\"\\n\\n\")\n .map((p) => `<p>${esc(p).replace(/\\n/g, \"<br>\")}</p>`)\n .join(\"\");\n }\n row.appendChild(bubble);\n msgsContainer.appendChild(row);\n }\n // Thinking/loading indicator\n if (isLoading && (isThinking || messages[messages.length - 1]?.role !== \"assistant\")) {\n const row = document.createElement(\"div\");\n row.className = \"kb-msg kb-msg-assistant\";\n const bubble = document.createElement(\"div\");\n bubble.className = \"kb-bubble kb-bubble-assistant\";\n bubble.innerHTML = isThinking\n ? `<span class=\"kb-thinking\"><span class=\"kb-dot\"></span><span class=\"kb-dot\"></span><span class=\"kb-dot\"></span><span class=\"kb-thinking-label\">Thinking</span></span>`\n : spinner(16);\n row.appendChild(bubble);\n msgsContainer.appendChild(row);\n }\n msgsContainer.scrollTop = msgsContainer.scrollHeight;\n }\n\n // Input bar\n const inputBar = document.createElement(\"div\");\n inputBar.className = \"kb-input-bar\";\n panel.appendChild(inputBar);\n\n const textarea = document.createElement(\"textarea\");\n textarea.className = \"kb-textarea\";\n textarea.rows = 1;\n textarea.placeholder = isReady ? \"Type your message...\" : \"Waiting for model...\";\n textarea.disabled = !isReady || isLoading;\n textarea.value = this.state.input;\n textarea.oninput = () => {\n this.state.input = textarea.value;\n textarea.style.height = \"auto\";\n textarea.style.height = Math.min(textarea.scrollHeight, 120) + \"px\";\n };\n textarea.onkeydown = (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n this.handleSend();\n }\n };\n inputBar.appendChild(textarea);\n this.textareaEl = textarea;\n\n const sendBtn = document.createElement(\"button\");\n sendBtn.className = \"kb-send\";\n sendBtn.style.background = this.primary;\n sendBtn.disabled = !isReady || isLoading || !this.state.input.trim();\n sendBtn.innerHTML = isLoading ? spinner(18) : SVG_SEND;\n sendBtn.setAttribute(\"aria-label\", \"Send\");\n sendBtn.onclick = () => this.handleSend();\n inputBar.appendChild(sendBtn);\n\n // Re-focus textarea if panel is open\n if (isReady && !isLoading) {\n requestAnimationFrame(() => textarea.focus());\n }\n }\n\n destroy() {\n this.unmounted = true;\n this.root.innerHTML = \"\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Mount a Kanha chatbot widget onto a DOM element.\n *\n * @param target - CSS selector string or HTMLElement\n * @param props - Bot configuration\n * @returns Object with `destroy()` method to unmount\n */\nexport function mount(\n target: string | HTMLElement,\n props: KanhaBotProps,\n): { destroy: () => void } {\n const el = typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!el) throw new Error(`Kanha: element \"${target}\" not found`);\n const widget = new KanhaBotWidget(el, props);\n return { destroy: () => widget.destroy() };\n}\n\n// ---------------------------------------------------------------------------\n// Web Component: <kanha-bot>\n// ---------------------------------------------------------------------------\n\nclass KanhaBotElement extends HTMLElement {\n private widget: KanhaBotWidget | null = null;\n\n connectedCallback() {\n const props: KanhaBotProps = {\n modelUrl: this.getAttribute(\"model-url\") ?? \"\",\n modelLib: this.getAttribute(\"model-lib\") ?? undefined,\n modelSize: (this.getAttribute(\"model-size\") as KanhaBotProps[\"modelSize\"]) ?? undefined,\n systemPrompt: this.getAttribute(\"system-prompt\") ?? undefined,\n temperature: this.hasAttribute(\"temperature\") ? Number(this.getAttribute(\"temperature\")) : undefined,\n maxTokens: this.hasAttribute(\"max-tokens\") ? Number(this.getAttribute(\"max-tokens\")) : undefined,\n botName: this.getAttribute(\"bot-name\") ?? undefined,\n welcomeMessage: this.getAttribute(\"welcome-message\") ?? undefined,\n suggestions: this.hasAttribute(\"suggestions\")\n ? JSON.parse(this.getAttribute(\"suggestions\")!)\n : undefined,\n theme: {\n primaryColor: this.getAttribute(\"primary-color\") ?? undefined,\n position: (this.getAttribute(\"position\") as KanhaBotTheme[\"position\"]) ?? undefined,\n },\n };\n this.widget = new KanhaBotWidget(this, props);\n }\n\n disconnectedCallback() {\n this.widget?.destroy();\n }\n}\n\nif (typeof customElements !== \"undefined\" && !customElements.get(\"kanha-bot\")) {\n customElements.define(\"kanha-bot\", KanhaBotElement);\n}\n\nexport type { KanhaBotProps, KanhaBotTheme, Message, InferenceMode };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/widget.ts"],"names":[],"mappings":"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","file":"widget.js","sourcesContent":["/**\n * Standalone widget for CDN / vanilla JS usage.\n * No React dependency — pure DOM manipulation.\n *\n * Usage via CDN:\n * <script type=\"module\">\n * import { mount } from 'https://cdn.jsdelivr.net/npm/kanha/dist/widget.js';\n * const bot = mount('#chat', { modelUrl: '...', systemPrompt: '...' });\n * </script>\n *\n * Or as a web component:\n * <script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/kanha/dist/widget.js\"></script>\n * <kanha-bot model-url=\"...\" system-prompt=\"...\" bot-name=\"Acme Bot\"></kanha-bot>\n */\n\nimport type { KanhaBotProps, KanhaBotTheme, Message, InferenceMode } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Engine (same logic as use-kanha-chat.ts, but non-React)\n// ---------------------------------------------------------------------------\n\nconst MODEL_LIB_PREFIX =\n \"https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_80\";\n\nconst WASM_BY_SIZE: Record<string, string> = {\n small: `${MODEL_LIB_PREFIX}/Qwen3-0.6B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n medium: `${MODEL_LIB_PREFIX}/Qwen3-1.7B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n large: `${MODEL_LIB_PREFIX}/Qwen3-4B-q4f16_1-ctx4k_cs1k-webgpu.wasm`,\n};\n\nfunction resolveModelLib(modelLib?: string, modelSize?: string): string {\n if (modelLib) return modelLib;\n const size = modelSize ?? \"small\";\n const lib = WASM_BY_SIZE[size];\n if (!lib) throw new Error(`Unknown model size \"${size}\". Provide modelLib explicitly.`);\n return lib;\n}\n\nfunction toWebLLMModelUrl(modelUrl: string): string {\n let url = modelUrl.endsWith(\"/\") ? modelUrl.slice(0, -1) : modelUrl;\n if (!url.includes(\"/resolve/\")) url += \"/resolve/v1\";\n return url;\n}\n\nasync function checkWebGPU(): Promise<boolean> {\n try {\n const nav = navigator as Navigator & { gpu?: { requestAdapter(): Promise<unknown> } };\n if (!nav.gpu) return false;\n const adapter = (await nav.gpu.requestAdapter()) as { requestDevice(): Promise<unknown> } | null;\n if (!adapter) return false;\n return !!(await adapter.requestDevice());\n } catch {\n return false;\n }\n}\n\nfunction stripThinkTokens(text: string): string {\n let cleaned = text.replace(/<think>[\\s\\S]*?<\\/think>/g, \"\");\n cleaned = cleaned.replace(/<think>[\\s\\S]*$/g, \"\");\n return cleaned.trimStart();\n}\n\nfunction esc(text: string): string {\n const el = document.createElement(\"span\");\n el.textContent = text;\n return el.innerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// DOM Widget\n// ---------------------------------------------------------------------------\n\nconst CSS = `\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n}\n@keyframes kb-spin { to { transform: rotate(360deg); } }\n@keyframes kb-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-4px); }\n}\n.kb-fab {\n position: fixed; bottom: 24px; width: 56px; height: 56px; border-radius: 50%;\n color: #fff; border: none; cursor: pointer; display: flex; align-items: center;\n justify-content: center; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 9999;\n transition: transform 0.15s ease;\n}\n.kb-fab:hover { transform: scale(1.05); }\n.kb-panel {\n position: fixed; bottom: 96px; width: 384px; max-width: calc(100vw - 48px);\n border-radius: 16px; overflow: hidden; display: flex; flex-direction: column;\n box-shadow: 0 8px 30px rgba(0,0,0,0.12); border: 1px solid #e5e7eb;\n background: #fff; z-index: 9999;\n}\n.kb-header { padding: 16px; color: #fff; display: flex; align-items: center; justify-content: space-between; }\n.kb-header-title { font-weight: 600; font-size: 15px; margin: 0; }\n.kb-header-sub { font-size: 12px; opacity: 0.85; margin: 4px 0 0; }\n.kb-progress { width: 60%; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.3); margin-top: 8px; overflow: hidden; }\n.kb-progress-fill { height: 100%; border-radius: 2px; background: #fff; transition: width 0.3s ease; }\n.kb-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; min-height: 300px; max-height: 384px; background: #fafafa; }\n.kb-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; color: #6b7280; font-size: 14px; padding: 16px; }\n.kb-msg { display: flex; }\n.kb-msg-user { justify-content: flex-end; }\n.kb-msg-assistant { justify-content: flex-start; }\n.kb-bubble { max-width: 80%; padding: 8px 14px; border-radius: 16px; font-size: 14px; line-height: 1.5; word-break: break-word; }\n.kb-bubble-user { color: #fff; }\n.kb-bubble-assistant { background: #fff; color: #1f2937; border: 1px solid #e5e7eb; }\n.kb-bubble p { margin: 0; } .kb-bubble p + p { margin-top: 8px; }\n.kb-thinking { display: flex; gap: 3px; align-items: center; }\n.kb-dot { width: 6px; height: 6px; border-radius: 50%; background: #9ca3af; }\n.kb-dot:nth-child(1) { animation: kb-bounce 1.2s ease-in-out 0ms infinite; }\n.kb-dot:nth-child(2) { animation: kb-bounce 1.2s ease-in-out 150ms infinite; }\n.kb-dot:nth-child(3) { animation: kb-bounce 1.2s ease-in-out 300ms infinite; }\n.kb-thinking-label { font-size: 12px; color: #9ca3af; margin-left: 6px; }\n.kb-spinner { animation: kb-spin 1s linear infinite; }\n.kb-input-bar { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid #e5e7eb; background: #fff; }\n.kb-textarea {\n flex: 1; padding: 8px 12px; border: 1px solid #e5e7eb; border-radius: 10px; font-size: 14px;\n resize: none; overflow: hidden; outline: none; font-family: inherit; min-height: 40px; max-height: 120px; line-height: 1.5;\n}\n.kb-textarea:focus { box-shadow: 0 0 0 2px rgba(13,148,136,0.25); }\n.kb-send {\n padding: 8px 14px; color: #fff; border: none; border-radius: 10px; cursor: pointer;\n display: flex; align-items: center; justify-content: center; flex-shrink: 0;\n transition: opacity 0.15s ease;\n}\n.kb-send:disabled { opacity: 0.5; cursor: not-allowed; }\n.kb-icon-btn { background: none; border: none; color: inherit; cursor: pointer; padding: 4px; border-radius: 8px; display: flex; align-items: center; opacity: 0.8; }\n.kb-icon-btn:hover { opacity: 1; }\n.kb-suggestions { display: flex; flex-direction: column; gap: 6px; width: 100%; margin-top: 16px; }\n.kb-suggestion {\n font-size: 13px; padding: 8px 12px; border-radius: 10px; border: 1px solid #e5e7eb;\n background: #fff; color: #374151; cursor: pointer; text-align: left; width: 100%;\n transition: border-color 0.15s ease;\n}\n.kb-suggestion:hover { border-color: var(--kb-primary, #0d9488); }\n.kb-error { padding: 10px 16px; background: #fef2f2; border-bottom: 1px solid #fecaca; font-size: 13px; color: #b91c1c; }\n`;\n\nconst SVG_CHAT = `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`;\nconst SVG_CLOSE = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\nconst SVG_SEND = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/></svg>`;\nconst SVG_TRASH = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`;\nconst SVG_SPINNER = `<svg width=\"SIZE\" height=\"SIZE\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" class=\"kb-spinner\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg>`;\n\nfunction spinner(size = 18) {\n return SVG_SPINNER.replace(/SIZE/g, String(size));\n}\n\ninterface WidgetState {\n messages: Message[];\n input: string;\n isLoading: boolean;\n isThinking: boolean;\n mode: InferenceMode;\n loadProgress: number;\n error: string | null;\n isOpen: boolean;\n}\n\nclass KanhaBotWidget {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private engine: any = null;\n private props: KanhaBotProps;\n private state: WidgetState;\n private root: ShadowRoot;\n private panelEl: HTMLElement | null = null;\n private messagesEl: HTMLElement | null = null;\n private textareaEl: HTMLTextAreaElement | null = null;\n private unmounted = false;\n\n constructor(container: HTMLElement, props: KanhaBotProps) {\n this.props = {\n botName: \"AI Assistant\",\n welcomeMessage: \"Ask me anything!\",\n suggestions: [],\n theme: {},\n ...props,\n };\n this.state = {\n messages: [],\n input: \"\",\n isLoading: false,\n isThinking: false,\n mode: \"detecting\",\n loadProgress: 0,\n error: null,\n isOpen: false,\n };\n\n this.root = container.attachShadow({ mode: \"open\" });\n const style = document.createElement(\"style\");\n style.textContent = CSS;\n this.root.appendChild(style);\n\n this.render();\n this.initEngine();\n }\n\n private get primary(): string {\n return this.props.theme?.primaryColor ?? \"#0d9488\";\n }\n\n private get position(): \"bottom-right\" | \"bottom-left\" {\n return this.props.theme?.position ?? \"bottom-right\";\n }\n\n private async initEngine() {\n const hasWebGPU = await checkWebGPU();\n if (!hasWebGPU) {\n this.setState({ mode: \"error\", error: \"WebGPU is not supported in this browser. Try Chrome 113+ or Edge 113+.\" });\n return;\n }\n\n this.setState({ mode: \"loading\" });\n\n try {\n const webllm = await import(\"@mlc-ai/web-llm\");\n const modelId = \"kanha-custom-model\";\n const modelLib = resolveModelLib(this.props.modelLib, this.props.modelSize);\n const modelUrl = toWebLLMModelUrl(this.props.modelUrl);\n\n this.engine = await webllm.CreateMLCEngine(modelId, {\n appConfig: {\n model_list: [{\n model: modelUrl,\n model_id: modelId,\n model_lib: modelLib,\n overrides: { context_window_size: this.props.contextWindowSize ?? 4096 },\n }],\n useIndexedDBCache: true,\n },\n initProgressCallback: (report: { progress: number }) => {\n if (!this.unmounted) this.setState({ loadProgress: Math.round(report.progress * 100) });\n },\n });\n\n if (!this.unmounted) this.setState({ mode: \"ready\" });\n } catch (err) {\n if (!this.unmounted) {\n this.setState({\n mode: \"error\",\n error: err instanceof Error ? err.message : \"Failed to load AI model.\",\n });\n }\n }\n }\n\n private setState(partial: Partial<WidgetState>) {\n Object.assign(this.state, partial);\n this.render();\n }\n\n private async handleSend() {\n const text = this.state.input.trim();\n if (!text || this.state.mode !== \"ready\" || this.state.isLoading || !this.engine) return;\n\n const userMsg: Message = { role: \"user\", content: text };\n const allMessages = [...this.state.messages, userMsg];\n this.setState({ messages: allMessages, input: \"\", isLoading: true, isThinking: true, error: null });\n\n try {\n const systemMessages: Message[] = this.props.systemPrompt\n ? [{ role: \"system\", content: this.props.systemPrompt }]\n : [];\n\n const completion = await this.engine.chat.completions.create({\n messages: [...systemMessages, ...allMessages],\n temperature: this.props.temperature ?? 0.7,\n max_tokens: this.props.maxTokens ?? 1024,\n stream: true,\n });\n\n let fullText = \"\";\n for await (const chunk of completion) {\n const delta = chunk.choices[0]?.delta?.content || \"\";\n fullText += delta;\n const cleaned = stripThinkTokens(fullText);\n if (!cleaned) {\n this.setState({ isThinking: true });\n } else {\n const msgs = [...allMessages];\n if (msgs[msgs.length - 1]?.role === \"assistant\") {\n msgs[msgs.length - 1] = { role: \"assistant\", content: cleaned };\n } else {\n msgs.push({ role: \"assistant\", content: cleaned });\n }\n this.setState({ messages: msgs, isThinking: false });\n }\n }\n } catch {\n this.setState({\n error: \"Failed to generate response. Please try again.\",\n messages: [...allMessages, { role: \"assistant\", content: \"Sorry, I encountered an error. Please try again.\" }],\n });\n } finally {\n this.setState({ isLoading: false, isThinking: false });\n }\n }\n\n private render() {\n const { messages, isLoading, isThinking, mode, loadProgress, error, isOpen } = this.state;\n const isReady = mode === \"ready\";\n\n // Clear non-style children\n const style = this.root.querySelector(\"style\");\n this.root.innerHTML = \"\";\n if (style) this.root.appendChild(style);\n\n // Set CSS variable for primary color\n const wrapper = document.createElement(\"div\");\n wrapper.style.setProperty(\"--kb-primary\", this.primary);\n this.root.appendChild(wrapper);\n\n // FAB\n const fab = document.createElement(\"button\");\n fab.className = \"kb-fab\";\n fab.style.background = this.primary;\n fab.style[this.position === \"bottom-right\" ? \"right\" : \"left\"] = \"24px\";\n fab.innerHTML = isOpen ? SVG_CLOSE : SVG_CHAT;\n fab.setAttribute(\"aria-label\", \"Toggle chat\");\n fab.onclick = () => this.setState({ isOpen: !isOpen });\n wrapper.appendChild(fab);\n\n if (!isOpen) return;\n\n // Panel\n const panel = document.createElement(\"div\");\n panel.className = \"kb-panel\";\n panel.style[this.position === \"bottom-right\" ? \"right\" : \"left\"] = \"24px\";\n wrapper.appendChild(panel);\n this.panelEl = panel;\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"kb-header\";\n header.style.background = this.primary;\n header.innerHTML = `\n <div>\n <p class=\"kb-header-title\">${esc(this.props.botName!)}</p>\n <p class=\"kb-header-sub\">${\n isReady ? esc(this.props.welcomeMessage!)\n : mode === \"loading\" ? `Loading AI model (${loadProgress}%)`\n : mode === \"error\" ? \"Failed to load\"\n : \"Detecting capabilities...\"\n }</p>\n ${mode === \"loading\" ? `<div class=\"kb-progress\"><div class=\"kb-progress-fill\" style=\"width:${loadProgress}%\"></div></div>` : \"\"}\n </div>\n <div style=\"display:flex;gap:4px\">\n ${messages.length > 0 ? `<button class=\"kb-icon-btn\" data-action=\"clear\" aria-label=\"Clear\">${SVG_TRASH}</button>` : \"\"}\n <button class=\"kb-icon-btn\" data-action=\"close\" aria-label=\"Close\">${SVG_CLOSE}</button>\n </div>`;\n header.querySelector(\"[data-action=clear]\")?.addEventListener(\"click\", () => this.setState({ messages: [], error: null }));\n header.querySelector(\"[data-action=close]\")?.addEventListener(\"click\", () => this.setState({ isOpen: false }));\n panel.appendChild(header);\n\n // Error\n if (error) {\n const errEl = document.createElement(\"div\");\n errEl.className = \"kb-error\";\n errEl.textContent = error;\n panel.appendChild(errEl);\n }\n\n // Messages\n const msgsContainer = document.createElement(\"div\");\n msgsContainer.className = \"kb-messages\";\n panel.appendChild(msgsContainer);\n this.messagesEl = msgsContainer;\n\n if (messages.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"kb-empty\";\n if (isReady) {\n empty.innerHTML = `${SVG_CHAT}<p style=\"margin-top:12px;font-weight:500;color:#374151\">${esc(this.props.welcomeMessage!)}</p>`;\n if (this.props.suggestions && this.props.suggestions.length > 0) {\n const sugDiv = document.createElement(\"div\");\n sugDiv.className = \"kb-suggestions\";\n for (const text of this.props.suggestions) {\n const btn = document.createElement(\"button\");\n btn.className = \"kb-suggestion\";\n btn.textContent = text;\n btn.onclick = () => {\n this.setState({ input: text });\n setTimeout(() => this.handleSend(), 0);\n };\n sugDiv.appendChild(btn);\n }\n empty.appendChild(sugDiv);\n }\n } else if (mode === \"loading\") {\n empty.innerHTML = `${spinner(32)}<p style=\"margin-top:8px\">Loading AI model (${loadProgress}%)</p><p style=\"font-size:12px;margin-top:4px\">First load takes about a minute</p>`;\n } else if (mode === \"error\") {\n empty.innerHTML = `<p>${esc(error ?? \"An error occurred\")}</p>`;\n } else {\n empty.innerHTML = `${spinner(32)}<p style=\"margin-top:8px\">Detecting browser capabilities...</p>`;\n }\n msgsContainer.appendChild(empty);\n } else {\n for (const msg of messages) {\n const row = document.createElement(\"div\");\n row.className = `kb-msg kb-msg-${msg.role}`;\n const bubble = document.createElement(\"div\");\n bubble.className = `kb-bubble kb-bubble-${msg.role}`;\n if (msg.role === \"user\") {\n bubble.style.background = this.primary;\n bubble.innerHTML = `<span style=\"white-space:pre-wrap\">${esc(msg.content)}</span>`;\n } else {\n // Simple markdown: paragraphs only (no heavy dep for CDN build)\n bubble.innerHTML = msg.content\n .split(\"\\n\\n\")\n .map((p) => `<p>${esc(p).replace(/\\n/g, \"<br>\")}</p>`)\n .join(\"\");\n }\n row.appendChild(bubble);\n msgsContainer.appendChild(row);\n }\n // Thinking/loading indicator\n if (isLoading && (isThinking || messages[messages.length - 1]?.role !== \"assistant\")) {\n const row = document.createElement(\"div\");\n row.className = \"kb-msg kb-msg-assistant\";\n const bubble = document.createElement(\"div\");\n bubble.className = \"kb-bubble kb-bubble-assistant\";\n bubble.innerHTML = isThinking\n ? `<span class=\"kb-thinking\"><span class=\"kb-dot\"></span><span class=\"kb-dot\"></span><span class=\"kb-dot\"></span><span class=\"kb-thinking-label\">Thinking</span></span>`\n : spinner(16);\n row.appendChild(bubble);\n msgsContainer.appendChild(row);\n }\n msgsContainer.scrollTop = msgsContainer.scrollHeight;\n }\n\n // Input bar\n const inputBar = document.createElement(\"div\");\n inputBar.className = \"kb-input-bar\";\n panel.appendChild(inputBar);\n\n const textarea = document.createElement(\"textarea\");\n textarea.className = \"kb-textarea\";\n textarea.rows = 1;\n textarea.placeholder = isReady ? \"Type your message...\" : \"Waiting for model...\";\n textarea.disabled = !isReady || isLoading;\n textarea.value = this.state.input;\n textarea.oninput = () => {\n this.state.input = textarea.value;\n textarea.style.height = \"auto\";\n textarea.style.height = Math.min(textarea.scrollHeight, 120) + \"px\";\n };\n textarea.onkeydown = (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n this.handleSend();\n }\n };\n inputBar.appendChild(textarea);\n this.textareaEl = textarea;\n\n const sendBtn = document.createElement(\"button\");\n sendBtn.className = \"kb-send\";\n sendBtn.style.background = this.primary;\n sendBtn.disabled = !isReady || isLoading || !this.state.input.trim();\n sendBtn.innerHTML = isLoading ? spinner(18) : SVG_SEND;\n sendBtn.setAttribute(\"aria-label\", \"Send\");\n sendBtn.onclick = () => this.handleSend();\n inputBar.appendChild(sendBtn);\n\n // Re-focus textarea if panel is open\n if (isReady && !isLoading) {\n requestAnimationFrame(() => textarea.focus());\n }\n }\n\n destroy() {\n this.unmounted = true;\n this.root.innerHTML = \"\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Mount a Kanha chatbot widget onto a DOM element.\n *\n * @param target - CSS selector string or HTMLElement\n * @param props - Bot configuration\n * @returns Object with `destroy()` method to unmount\n */\nexport function mount(\n target: string | HTMLElement,\n props: KanhaBotProps,\n): { destroy: () => void } {\n const el = typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!el) throw new Error(`Kanha: element \"${target}\" not found`);\n const widget = new KanhaBotWidget(el, props);\n return { destroy: () => widget.destroy() };\n}\n\n// ---------------------------------------------------------------------------\n// Web Component: <kanha-bot>\n// ---------------------------------------------------------------------------\n\nclass KanhaBotElement extends HTMLElement {\n private widget: KanhaBotWidget | null = null;\n\n connectedCallback() {\n const props: KanhaBotProps = {\n modelUrl: this.getAttribute(\"model-url\") ?? \"\",\n modelLib: this.getAttribute(\"model-lib\") ?? undefined,\n modelSize: (this.getAttribute(\"model-size\") as KanhaBotProps[\"modelSize\"]) ?? undefined,\n systemPrompt: this.getAttribute(\"system-prompt\") ?? undefined,\n temperature: this.hasAttribute(\"temperature\") ? Number(this.getAttribute(\"temperature\")) : undefined,\n maxTokens: this.hasAttribute(\"max-tokens\") ? Number(this.getAttribute(\"max-tokens\")) : undefined,\n botName: this.getAttribute(\"bot-name\") ?? undefined,\n welcomeMessage: this.getAttribute(\"welcome-message\") ?? undefined,\n suggestions: this.hasAttribute(\"suggestions\")\n ? JSON.parse(this.getAttribute(\"suggestions\")!)\n : undefined,\n theme: {\n primaryColor: this.getAttribute(\"primary-color\") ?? undefined,\n position: (this.getAttribute(\"position\") as KanhaBotTheme[\"position\"]) ?? undefined,\n },\n };\n this.widget = new KanhaBotWidget(this, props);\n }\n\n disconnectedCallback() {\n this.widget?.destroy();\n }\n}\n\nif (typeof customElements !== \"undefined\" && !customElements.get(\"kanha-bot\")) {\n customElements.define(\"kanha-bot\", KanhaBotElement);\n}\n\nexport type { KanhaBotProps, KanhaBotTheme, Message, InferenceMode };\n"]}
|