@mnexium/chat-react 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -133,6 +133,7 @@ GOOGLE_API_KEY=...
133
133
  | `placeholder` | `string` | `'Type a message...'` | Input placeholder |
134
134
  | `position` | `'bottom-right' \| 'bottom-left'` | `'bottom-right'` | Widget position |
135
135
  | `primaryColor` | `string` | `'#facc15'` | Accent color (use 6-char hex, e.g. `#45b1eb`) |
136
+ | `textColor` | `string` | `'#000'` | Text color for button and user messages |
136
137
  | `theme` | `'light' \| 'dark'` | `'dark'` | Color theme |
137
138
  | `defaultOpen` | `boolean` | `false` | Start with chat open |
138
139
  | `eagerInit` | `boolean` | `true` | Initialize on page load (no "Initializing..." delay) |
@@ -166,6 +167,7 @@ const mnx = createHandlers({
166
167
  | `mnxOptions.recall` | `boolean` | `true` | Inject relevant memories |
167
168
  | `mnxOptions.profile` | `boolean` | `true` | Include user profile |
168
169
  | `mnxOptions.summarize` | `'light' \| 'balanced' \| 'aggressive' \| false` | `'balanced'` | Summarization mode |
170
+ | `mnxOptions.system_prompt_id` | `string` | - | Use a saved Mnexium system prompt by ID |
169
171
 
170
172
  ### Individual Handlers
171
173
 
@@ -231,6 +233,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
231
233
  buttonLabel="Ask AI"
232
234
  position="bottom-right"
233
235
  primaryColor="#45b1eb"
236
+ textColor="#fff"
234
237
  theme="dark"
235
238
  logo="/logo.png"
236
239
  welcomeIcon="🤖"
package/dist/index.d.mts CHANGED
@@ -13,6 +13,7 @@ interface MnexiumChatProps {
13
13
  buttonLabel?: string;
14
14
  position?: 'bottom-right' | 'bottom-left';
15
15
  primaryColor?: string;
16
+ textColor?: string;
16
17
  defaultOpen?: boolean;
17
18
  logo?: string;
18
19
  theme?: 'light' | 'dark';
@@ -21,6 +22,6 @@ interface MnexiumChatProps {
21
22
  history?: boolean;
22
23
  eagerInit?: boolean;
23
24
  }
24
- declare function MnexiumChat({ endpoint, placeholder, title, buttonLabel, position, primaryColor, defaultOpen, logo, theme, welcomeIcon, welcomeMessage, history, eagerInit, }: MnexiumChatProps): react_jsx_runtime.JSX.Element;
25
+ declare function MnexiumChat({ endpoint, placeholder, title, buttonLabel, position, primaryColor, textColor, defaultOpen, logo, theme, welcomeIcon, welcomeMessage, history, eagerInit, }: MnexiumChatProps): react_jsx_runtime.JSX.Element;
25
26
 
26
27
  export { type Message, MnexiumChat, type MnexiumChatProps, MnexiumChat as default };
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface MnexiumChatProps {
13
13
  buttonLabel?: string;
14
14
  position?: 'bottom-right' | 'bottom-left';
15
15
  primaryColor?: string;
16
+ textColor?: string;
16
17
  defaultOpen?: boolean;
17
18
  logo?: string;
18
19
  theme?: 'light' | 'dark';
@@ -21,6 +22,6 @@ interface MnexiumChatProps {
21
22
  history?: boolean;
22
23
  eagerInit?: boolean;
23
24
  }
24
- declare function MnexiumChat({ endpoint, placeholder, title, buttonLabel, position, primaryColor, defaultOpen, logo, theme, welcomeIcon, welcomeMessage, history, eagerInit, }: MnexiumChatProps): react_jsx_runtime.JSX.Element;
25
+ declare function MnexiumChat({ endpoint, placeholder, title, buttonLabel, position, primaryColor, textColor, defaultOpen, logo, theme, welcomeIcon, welcomeMessage, history, eagerInit, }: MnexiumChatProps): react_jsx_runtime.JSX.Element;
25
26
 
26
27
  export { type Message, MnexiumChat, type MnexiumChatProps, MnexiumChat as default };
package/dist/index.js CHANGED
@@ -147,6 +147,7 @@ function MnexiumChat({
147
147
  buttonLabel = "Ask AI",
148
148
  position = "bottom-right",
149
149
  primaryColor = "#facc15",
150
+ textColor = "#000",
150
151
  defaultOpen = false,
151
152
  logo,
152
153
  theme = "dark",
@@ -339,9 +340,6 @@ function MnexiumChat({
339
340
  .mnx-btn-icon {
340
341
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
341
342
  }
342
- .mnx-btn-icon.open {
343
- transform: rotate(45deg);
344
- }
345
343
  ` }),
346
344
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
347
345
  position: "fixed",
@@ -464,7 +462,7 @@ function MnexiumChat({
464
462
  ...message.role === "user" ? {
465
463
  alignSelf: "flex-end",
466
464
  backgroundColor: `${primaryColor}cc`,
467
- color: "#000",
465
+ color: textColor,
468
466
  borderBottomRightRadius: "4px"
469
467
  } : {
470
468
  alignSelf: "flex-start",
@@ -564,7 +562,7 @@ function MnexiumChat({
564
562
  gap: "8px",
565
563
  padding: "12px 16px",
566
564
  backgroundColor: primaryColor,
567
- color: "#000",
565
+ color: textColor,
568
566
  border: "none",
569
567
  borderRadius: "12px",
570
568
  fontSize: "14px",
@@ -597,11 +595,30 @@ function MnexiumChat({
597
595
  ] })
598
596
  }
599
597
  ),
600
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
601
- transition: "opacity 0.2s, width 0.3s",
598
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: {
599
+ display: "inline-flex",
602
600
  overflow: "hidden",
603
- whiteSpace: "nowrap"
604
- }, children: isOpen ? "Close" : buttonLabel })
601
+ whiteSpace: "nowrap",
602
+ position: "relative",
603
+ height: "1.2em",
604
+ alignItems: "center"
605
+ }, children: [
606
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
607
+ display: "inline-block",
608
+ transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
609
+ transform: isOpen ? "translateY(-100%)" : "translateY(0)",
610
+ opacity: isOpen ? 0 : 1,
611
+ maxWidth: isOpen ? "0" : "300px"
612
+ }, children: buttonLabel }),
613
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
614
+ display: "inline-block",
615
+ transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
616
+ transform: isOpen ? "translateY(0)" : "translateY(100%)",
617
+ opacity: isOpen ? 1 : 0,
618
+ maxWidth: isOpen ? "50px" : "0",
619
+ overflow: "hidden"
620
+ }, children: "Close" })
621
+ ] })
605
622
  ]
606
623
  }
607
624
  )
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client/MnexiumChat.tsx"],"sourcesContent":["export { MnexiumChat, type MnexiumChatProps, type Message } from './client/MnexiumChat';\nexport { MnexiumChat as default } from './client/MnexiumChat';\n","'use client';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: Date;\n}\n\nexport interface MnexiumChatProps {\n endpoint?: string;\n placeholder?: string;\n title?: string;\n buttonLabel?: string;\n position?: 'bottom-right' | 'bottom-left';\n primaryColor?: string;\n defaultOpen?: boolean;\n logo?: string;\n theme?: 'light' | 'dark';\n welcomeIcon?: string;\n welcomeMessage?: string;\n history?: boolean;\n eagerInit?: boolean;\n}\n\nconst themes = {\n dark: {\n bg: '#1a1a1a',\n bgSecondary: '#2a2a2a',\n border: '#333',\n text: '#fff',\n textSecondary: '#e5e5e5',\n textMuted: '#888',\n inputBg: '#2a2a2a',\n inputBorder: '#444',\n codeBg: '#374151',\n codeBlockBg: '#1f2937',\n },\n light: {\n bg: '#ffffff',\n bgSecondary: '#f3f4f6',\n border: '#e5e7eb',\n text: '#111827',\n textSecondary: '#374151',\n textMuted: '#6b7280',\n inputBg: '#f9fafb',\n inputBorder: '#d1d5db',\n codeBg: '#e5e7eb',\n codeBlockBg: '#f3f4f6',\n },\n};\n\nfunction generateId(): string {\n return Math.random().toString(36).substring(2, 15);\n}\n\nfunction renderMarkdown(text: string, themeColors: { codeBg: string; codeBlockBg: string }): React.ReactNode {\n if (!text) return null;\n const lines = text.split('\\n');\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeContent: string[] = [];\n\n const processInline = (line: string): React.ReactNode => {\n const parts: React.ReactNode[] = [];\n let remaining = line;\n let key = 0;\n\n while (remaining.length > 0) {\n const codeMatch = remaining.match(/`([^`]+)`/);\n const boldMatch = remaining.match(/\\*\\*([^*]+)\\*\\*/);\n const italicMatch = remaining.match(/\\*([^*]+)\\*/);\n\n const matches = [\n codeMatch ? { type: 'code', match: codeMatch, index: codeMatch.index! } : null,\n boldMatch ? { type: 'bold', match: boldMatch, index: boldMatch.index! } : null,\n italicMatch ? { type: 'italic', match: italicMatch, index: italicMatch.index! } : null,\n ].filter(Boolean).sort((a, b) => a!.index - b!.index);\n\n if (matches.length === 0) {\n parts.push(remaining);\n break;\n }\n\n const first = matches[0]!;\n if (first.index > 0) {\n parts.push(remaining.substring(0, first.index));\n }\n\n if (first.type === 'code') {\n parts.push(\n <code key={key++} style={{ backgroundColor: themeColors.codeBg, padding: '2px 6px', borderRadius: '4px', fontSize: '13px' }}>\n {first.match![1]}\n </code>\n );\n } else if (first.type === 'bold') {\n parts.push(<strong key={key++}>{first.match![1]}</strong>);\n } else if (first.type === 'italic') {\n parts.push(<em key={key++}>{first.match![1]}</em>);\n }\n\n remaining = remaining.substring(first.index + first.match![0].length);\n }\n\n return parts.length === 1 ? parts[0] : parts;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('```')) {\n if (!inCodeBlock) {\n inCodeBlock = true;\n codeContent = [];\n } else {\n elements.push(\n <pre key={i} style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n inCodeBlock = false;\n }\n continue;\n }\n\n if (inCodeBlock) {\n codeContent.push(line);\n continue;\n }\n\n if (line.startsWith('### ')) {\n elements.push(<h4 key={i} style={{ margin: '12px 0 8px', fontSize: '14px', fontWeight: 600 }}>{processInline(line.slice(4))}</h4>);\n } else if (line.startsWith('## ')) {\n elements.push(<h3 key={i} style={{ margin: '12px 0 8px', fontSize: '15px', fontWeight: 600 }}>{processInline(line.slice(3))}</h3>);\n } else if (line.startsWith('# ')) {\n elements.push(<h2 key={i} style={{ margin: '12px 0 8px', fontSize: '16px', fontWeight: 600 }}>{processInline(line.slice(2))}</h2>);\n } else if (line.startsWith('- ') || line.startsWith('* ')) {\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'disc' }}>{processInline(line.slice(2))}</li>);\n } else if (/^\\d+\\.\\s/.test(line)) {\n const content = line.replace(/^\\d+\\.\\s/, '');\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'decimal' }}>{processInline(content)}</li>);\n } else if (line.trim() === '') {\n elements.push(<br key={i} />);\n } else {\n elements.push(<p key={i} style={{ margin: '4px 0' }}>{processInline(line)}</p>);\n }\n }\n\n if (inCodeBlock && codeContent.length > 0) {\n elements.push(\n <pre key=\"final-code\" style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n }\n\n return <div>{elements}</div>;\n}\n\nexport function MnexiumChat({\n endpoint = '/api/mnx',\n placeholder = 'Type a message...',\n title = 'Ask AI',\n buttonLabel = 'Ask AI',\n position = 'bottom-right',\n primaryColor = '#facc15',\n defaultOpen = false,\n logo,\n theme = 'dark',\n welcomeIcon = '👋',\n welcomeMessage = 'How can I help you today?',\n history = false,\n eagerInit = true,\n}: MnexiumChatProps) {\n const t = themes[theme];\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const scrollToBottom = useCallback(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, []);\n\n useEffect(() => {\n scrollToBottom();\n }, [messages, scrollToBottom]);\n\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!eagerInit && !isOpen) return;\n \n const bootstrap = async () => {\n if (isInitialized) return;\n \n try {\n const res = await fetch(`${endpoint}/bootstrap`);\n if (!res.ok) throw new Error('Failed to bootstrap');\n \n const data = await res.json();\n \n if (history && data.chat_id) {\n try {\n const historyRes = await fetch(`${endpoint}/conversations/${data.chat_id}`);\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n if (historyData.messages && Array.isArray(historyData.messages)) {\n setMessages(historyData.messages.map((m: { role: string; content: string }) => ({\n id: generateId(),\n role: m.role as 'user' | 'assistant',\n content: m.content,\n timestamp: new Date(),\n })));\n }\n }\n } catch {\n // History endpoint is optional\n }\n }\n \n setIsInitialized(true);\n } catch (err) {\n setError('Failed to initialize chat');\n console.error('Bootstrap error:', err);\n }\n };\n\n bootstrap();\n }, [endpoint, isOpen, isInitialized, history, eagerInit]);\n\n const sendMessage = async () => {\n if (!input.trim() || isLoading || isStreaming) return;\n\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content: input.trim(),\n timestamp: new Date(),\n };\n\n setMessages(prev => [...prev, userMessage]);\n setInput('');\n setIsLoading(true);\n setError(null);\n\n const assistantMessageId = generateId();\n\n try {\n const res = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: userMessage.content }),\n });\n\n if (!res.ok) throw new Error('Failed to send message');\n if (!res.body) throw new Error('No response body');\n\n setIsLoading(false);\n setIsStreaming(true);\n\n const assistantMessage: Message = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n };\n setMessages(prev => [...prev, assistantMessage]);\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6);\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6);\n if (data !== '[DONE]') {\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } catch (err) {\n setError('Failed to send message');\n console.error('Chat error:', err);\n setMessages(prev => prev.filter(m => m.id !== assistantMessageId));\n } finally {\n setIsLoading(false);\n setIsStreaming(false);\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n sendMessage();\n }\n };\n\n const startNewChat = async () => {\n try {\n const res = await fetch(`${endpoint}/new-chat`, { method: 'POST' });\n if (res.ok) {\n setMessages([]);\n }\n } catch {\n // Fallback: just clear messages locally\n setMessages([]);\n }\n };\n\n const positionStyles = position === 'bottom-right' \n ? { right: '20px', bottom: '20px' }\n : { left: '20px', bottom: '20px' };\n\n const chatPositionStyles = position === 'bottom-right'\n ? { right: '0', bottom: '60px' }\n : { left: '0', bottom: '60px' };\n\n return (\n <>\n <style>{`\n @keyframes mnx-typing {\n 0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }\n 40% { transform: scale(1); opacity: 1; }\n }\n @keyframes mnx-fade-in {\n from { opacity: 0; transform: translateY(10px) scale(0.95); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n @keyframes mnx-fade-out {\n from { opacity: 1; transform: translateY(0) scale(1); }\n to { opacity: 0; transform: translateY(10px) scale(0.95); }\n }\n @keyframes mnx-pulse {\n 0% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n 50% { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); }\n 100% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n }\n .mnx-typing-dot:nth-child(1) { animation-delay: 0s; }\n .mnx-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n .mnx-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n .mnx-btn-icon {\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n .mnx-btn-icon.open {\n transform: rotate(45deg);\n }\n `}</style>\n\n <div style={{\n position: 'fixed',\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n ...positionStyles,\n }}>\n {isOpen && (\n <div style={{\n position: 'absolute',\n ...chatPositionStyles,\n width: '380px',\n height: '500px',\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.9)' : 'rgba(255, 255, 255, 0.9)',\n backdropFilter: 'blur(8px) saturate(180%)',\n WebkitBackdropFilter: 'blur(16px) saturate(180%)',\n borderRadius: '16px',\n border: `1px solid ${primaryColor}33`,\n boxShadow: theme === 'dark' ? '0 25px 50px -12px rgba(0, 0, 0, 0.5)' : '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n animation: 'mnx-fade-in 0.2s ease-out',\n transform: 'translateZ(0)',\n isolation: 'isolate',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 8px',\n borderBottom: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.7)' : 'rgba(255, 255, 255, 0.7)',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\n <div style={{\n width: '32px',\n height: '32px',\n backgroundColor: primaryColor,\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}>\n {logo ? (\n <img src={logo} alt=\"\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#000\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </div>\n <span style={{ color: t.text, fontWeight: 600, fontSize: '15px' }}>{title}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <button\n onClick={startNewChat}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '6px',\n borderRadius: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title=\"New chat\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>\n </svg>\n </button>\n <button\n onClick={() => setIsOpen(false)}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n </div>\n\n <div style={{\n flex: 1,\n overflowY: 'auto',\n padding: '8px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n }}>\n {!isInitialized && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted }}>\n Initializing...\n </div>\n )}\n {error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#ef4444' }}>\n {error}\n </div>\n )}\n {isInitialized && messages.length === 0 && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted, textAlign: 'center' }}>\n <div>\n <div style={{ fontSize: '24px', marginBottom: '8px' }}>{welcomeIcon}</div>\n <div>{welcomeMessage}</div>\n </div>\n </div>\n )}\n {messages.map(message => (\n <div\n key={message.id}\n style={{\n maxWidth: '85%',\n padding: '10px 14px',\n borderRadius: '12px',\n fontSize: '14px',\n lineHeight: 1.5,\n wordBreak: 'break-word',\n ...(message.role === 'user' \n ? { \n alignSelf: 'flex-end',\n backgroundColor: `${primaryColor}cc`,\n color: '#000',\n borderBottomRightRadius: '4px',\n }\n : {\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n color: t.textSecondary,\n borderBottomLeftRadius: '4px',\n }\n ),\n }}\n >\n {message.role === 'assistant' ? renderMarkdown(message.content, { codeBg: t.codeBg, codeBlockBg: t.codeBlockBg }) : message.content}\n </div>\n ))}\n {isLoading && (\n <div style={{\n display: 'flex',\n gap: '4px',\n padding: '10px 14px',\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n borderRadius: '12px',\n borderBottomLeftRadius: '4px',\n }}>\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <div style={{\n display: 'flex',\n gap: '8px',\n padding: '8px 8px',\n borderTop: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.5)' : 'rgba(255, 255, 255, 0.5)',\n }}>\n <input\n ref={inputRef}\n type=\"text\"\n value={input}\n onChange={e => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={!isInitialized || isLoading || isStreaming}\n style={{\n flex: 1,\n padding: '10px 14px',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.6)' : 'rgba(249, 250, 251, 0.6)',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n color: t.text,\n outline: 'none',\n transition: 'box-shadow 0.15s ease',\n }}\n onFocus={e => {\n e.currentTarget.style.boxShadow = `0 0 0 2px ${primaryColor}`;\n }}\n onBlur={e => {\n e.currentTarget.style.boxShadow = 'none';\n }}\n />\n <button\n onClick={sendMessage}\n disabled={!isInitialized || !input.trim() || isLoading || isStreaming}\n style={{\n padding: '10px 16px',\n backgroundColor: !isInitialized || !input.trim() || isLoading || isStreaming ? t.inputBorder : primaryColor,\n color: '#000',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: !isInitialized || !input.trim() || isLoading || isStreaming ? 'not-allowed' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>\n </svg>\n </button>\n </div>\n </div>\n )}\n\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '12px 16px',\n backgroundColor: primaryColor,\n color: '#000',\n border: 'none',\n borderRadius: '12px',\n fontSize: '14px',\n fontWeight: 600,\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n }}\n onMouseEnter={e => {\n e.currentTarget.style.transform = 'scale(1.05)';\n e.currentTarget.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.4)';\n }}\n onMouseLeave={e => {\n e.currentTarget.style.transform = 'scale(1)';\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)';\n }}\n >\n <span \n className={`mnx-btn-icon ${isOpen ? 'open' : ''}`}\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}\n >\n {isOpen ? (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n ) : logo ? (\n <img src={logo} alt=\"\" style={{ height: '28px', width: 'auto', objectFit: 'contain' }} />\n ) : (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </span>\n <span style={{ \n transition: 'opacity 0.2s, width 0.3s',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }}>\n {isOpen ? 'Close' : buttonLabel}\n </span>\n </button>\n </div>\n </>\n );\n}\n\nexport default MnexiumChat;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client/MnexiumChat.tsx"],"sourcesContent":["export { MnexiumChat, type MnexiumChatProps, type Message } from './client/MnexiumChat';\nexport { MnexiumChat as default } from './client/MnexiumChat';\n","'use client';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: Date;\n}\n\nexport interface MnexiumChatProps {\n endpoint?: string;\n placeholder?: string;\n title?: string;\n buttonLabel?: string;\n position?: 'bottom-right' | 'bottom-left';\n primaryColor?: string;\n textColor?: string;\n defaultOpen?: boolean;\n logo?: string;\n theme?: 'light' | 'dark';\n welcomeIcon?: string;\n welcomeMessage?: string;\n history?: boolean;\n eagerInit?: boolean;\n}\n\nconst themes = {\n dark: {\n bg: '#1a1a1a',\n bgSecondary: '#2a2a2a',\n border: '#333',\n text: '#fff',\n textSecondary: '#e5e5e5',\n textMuted: '#888',\n inputBg: '#2a2a2a',\n inputBorder: '#444',\n codeBg: '#374151',\n codeBlockBg: '#1f2937',\n },\n light: {\n bg: '#ffffff',\n bgSecondary: '#f3f4f6',\n border: '#e5e7eb',\n text: '#111827',\n textSecondary: '#374151',\n textMuted: '#6b7280',\n inputBg: '#f9fafb',\n inputBorder: '#d1d5db',\n codeBg: '#e5e7eb',\n codeBlockBg: '#f3f4f6',\n },\n};\n\nfunction generateId(): string {\n return Math.random().toString(36).substring(2, 15);\n}\n\nfunction renderMarkdown(text: string, themeColors: { codeBg: string; codeBlockBg: string }): React.ReactNode {\n if (!text) return null;\n const lines = text.split('\\n');\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeContent: string[] = [];\n\n const processInline = (line: string): React.ReactNode => {\n const parts: React.ReactNode[] = [];\n let remaining = line;\n let key = 0;\n\n while (remaining.length > 0) {\n const codeMatch = remaining.match(/`([^`]+)`/);\n const boldMatch = remaining.match(/\\*\\*([^*]+)\\*\\*/);\n const italicMatch = remaining.match(/\\*([^*]+)\\*/);\n\n const matches = [\n codeMatch ? { type: 'code', match: codeMatch, index: codeMatch.index! } : null,\n boldMatch ? { type: 'bold', match: boldMatch, index: boldMatch.index! } : null,\n italicMatch ? { type: 'italic', match: italicMatch, index: italicMatch.index! } : null,\n ].filter(Boolean).sort((a, b) => a!.index - b!.index);\n\n if (matches.length === 0) {\n parts.push(remaining);\n break;\n }\n\n const first = matches[0]!;\n if (first.index > 0) {\n parts.push(remaining.substring(0, first.index));\n }\n\n if (first.type === 'code') {\n parts.push(\n <code key={key++} style={{ backgroundColor: themeColors.codeBg, padding: '2px 6px', borderRadius: '4px', fontSize: '13px' }}>\n {first.match![1]}\n </code>\n );\n } else if (first.type === 'bold') {\n parts.push(<strong key={key++}>{first.match![1]}</strong>);\n } else if (first.type === 'italic') {\n parts.push(<em key={key++}>{first.match![1]}</em>);\n }\n\n remaining = remaining.substring(first.index + first.match![0].length);\n }\n\n return parts.length === 1 ? parts[0] : parts;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('```')) {\n if (!inCodeBlock) {\n inCodeBlock = true;\n codeContent = [];\n } else {\n elements.push(\n <pre key={i} style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n inCodeBlock = false;\n }\n continue;\n }\n\n if (inCodeBlock) {\n codeContent.push(line);\n continue;\n }\n\n if (line.startsWith('### ')) {\n elements.push(<h4 key={i} style={{ margin: '12px 0 8px', fontSize: '14px', fontWeight: 600 }}>{processInline(line.slice(4))}</h4>);\n } else if (line.startsWith('## ')) {\n elements.push(<h3 key={i} style={{ margin: '12px 0 8px', fontSize: '15px', fontWeight: 600 }}>{processInline(line.slice(3))}</h3>);\n } else if (line.startsWith('# ')) {\n elements.push(<h2 key={i} style={{ margin: '12px 0 8px', fontSize: '16px', fontWeight: 600 }}>{processInline(line.slice(2))}</h2>);\n } else if (line.startsWith('- ') || line.startsWith('* ')) {\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'disc' }}>{processInline(line.slice(2))}</li>);\n } else if (/^\\d+\\.\\s/.test(line)) {\n const content = line.replace(/^\\d+\\.\\s/, '');\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'decimal' }}>{processInline(content)}</li>);\n } else if (line.trim() === '') {\n elements.push(<br key={i} />);\n } else {\n elements.push(<p key={i} style={{ margin: '4px 0' }}>{processInline(line)}</p>);\n }\n }\n\n if (inCodeBlock && codeContent.length > 0) {\n elements.push(\n <pre key=\"final-code\" style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n }\n\n return <div>{elements}</div>;\n}\n\nexport function MnexiumChat({\n endpoint = '/api/mnx',\n placeholder = 'Type a message...',\n title = 'Ask AI',\n buttonLabel = 'Ask AI',\n position = 'bottom-right',\n primaryColor = '#facc15',\n textColor = '#000',\n defaultOpen = false,\n logo,\n theme = 'dark',\n welcomeIcon = '👋',\n welcomeMessage = 'How can I help you today?',\n history = false,\n eagerInit = true,\n}: MnexiumChatProps) {\n const t = themes[theme];\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const scrollToBottom = useCallback(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, []);\n\n useEffect(() => {\n scrollToBottom();\n }, [messages, scrollToBottom]);\n\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!eagerInit && !isOpen) return;\n \n const bootstrap = async () => {\n if (isInitialized) return;\n \n try {\n const res = await fetch(`${endpoint}/bootstrap`);\n if (!res.ok) throw new Error('Failed to bootstrap');\n \n const data = await res.json();\n \n if (history && data.chat_id) {\n try {\n const historyRes = await fetch(`${endpoint}/conversations/${data.chat_id}`);\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n if (historyData.messages && Array.isArray(historyData.messages)) {\n setMessages(historyData.messages.map((m: { role: string; content: string }) => ({\n id: generateId(),\n role: m.role as 'user' | 'assistant',\n content: m.content,\n timestamp: new Date(),\n })));\n }\n }\n } catch {\n // History endpoint is optional\n }\n }\n \n setIsInitialized(true);\n } catch (err) {\n setError('Failed to initialize chat');\n console.error('Bootstrap error:', err);\n }\n };\n\n bootstrap();\n }, [endpoint, isOpen, isInitialized, history, eagerInit]);\n\n const sendMessage = async () => {\n if (!input.trim() || isLoading || isStreaming) return;\n\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content: input.trim(),\n timestamp: new Date(),\n };\n\n setMessages(prev => [...prev, userMessage]);\n setInput('');\n setIsLoading(true);\n setError(null);\n\n const assistantMessageId = generateId();\n\n try {\n const res = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: userMessage.content }),\n });\n\n if (!res.ok) throw new Error('Failed to send message');\n if (!res.body) throw new Error('No response body');\n\n setIsLoading(false);\n setIsStreaming(true);\n\n const assistantMessage: Message = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n };\n setMessages(prev => [...prev, assistantMessage]);\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6);\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6);\n if (data !== '[DONE]') {\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } catch (err) {\n setError('Failed to send message');\n console.error('Chat error:', err);\n setMessages(prev => prev.filter(m => m.id !== assistantMessageId));\n } finally {\n setIsLoading(false);\n setIsStreaming(false);\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n sendMessage();\n }\n };\n\n const startNewChat = async () => {\n try {\n const res = await fetch(`${endpoint}/new-chat`, { method: 'POST' });\n if (res.ok) {\n setMessages([]);\n }\n } catch {\n // Fallback: just clear messages locally\n setMessages([]);\n }\n };\n\n const positionStyles = position === 'bottom-right' \n ? { right: '20px', bottom: '20px' }\n : { left: '20px', bottom: '20px' };\n\n const chatPositionStyles = position === 'bottom-right'\n ? { right: '0', bottom: '60px' }\n : { left: '0', bottom: '60px' };\n\n return (\n <>\n <style>{`\n @keyframes mnx-typing {\n 0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }\n 40% { transform: scale(1); opacity: 1; }\n }\n @keyframes mnx-fade-in {\n from { opacity: 0; transform: translateY(10px) scale(0.95); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n @keyframes mnx-fade-out {\n from { opacity: 1; transform: translateY(0) scale(1); }\n to { opacity: 0; transform: translateY(10px) scale(0.95); }\n }\n @keyframes mnx-pulse {\n 0% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n 50% { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); }\n 100% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n }\n .mnx-typing-dot:nth-child(1) { animation-delay: 0s; }\n .mnx-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n .mnx-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n .mnx-btn-icon {\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n `}</style>\n\n <div style={{\n position: 'fixed',\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n ...positionStyles,\n }}>\n {isOpen && (\n <div style={{\n position: 'absolute',\n ...chatPositionStyles,\n width: '380px',\n height: '500px',\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.9)' : 'rgba(255, 255, 255, 0.9)',\n backdropFilter: 'blur(8px) saturate(180%)',\n WebkitBackdropFilter: 'blur(16px) saturate(180%)',\n borderRadius: '16px',\n border: `1px solid ${primaryColor}33`,\n boxShadow: theme === 'dark' ? '0 25px 50px -12px rgba(0, 0, 0, 0.5)' : '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n animation: 'mnx-fade-in 0.2s ease-out',\n transform: 'translateZ(0)',\n isolation: 'isolate',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 8px',\n borderBottom: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.7)' : 'rgba(255, 255, 255, 0.7)',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\n <div style={{\n width: '32px',\n height: '32px',\n backgroundColor: primaryColor,\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}>\n {logo ? (\n <img src={logo} alt=\"\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#000\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </div>\n <span style={{ color: t.text, fontWeight: 600, fontSize: '15px' }}>{title}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <button\n onClick={startNewChat}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '6px',\n borderRadius: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title=\"New chat\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>\n </svg>\n </button>\n <button\n onClick={() => setIsOpen(false)}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n </div>\n\n <div style={{\n flex: 1,\n overflowY: 'auto',\n padding: '8px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n }}>\n {!isInitialized && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted }}>\n Initializing...\n </div>\n )}\n {error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#ef4444' }}>\n {error}\n </div>\n )}\n {isInitialized && messages.length === 0 && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted, textAlign: 'center' }}>\n <div>\n <div style={{ fontSize: '24px', marginBottom: '8px' }}>{welcomeIcon}</div>\n <div>{welcomeMessage}</div>\n </div>\n </div>\n )}\n {messages.map(message => (\n <div\n key={message.id}\n style={{\n maxWidth: '85%',\n padding: '10px 14px',\n borderRadius: '12px',\n fontSize: '14px',\n lineHeight: 1.5,\n wordBreak: 'break-word',\n ...(message.role === 'user' \n ? { \n alignSelf: 'flex-end',\n backgroundColor: `${primaryColor}cc`,\n color: textColor,\n borderBottomRightRadius: '4px',\n }\n : {\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n color: t.textSecondary,\n borderBottomLeftRadius: '4px',\n }\n ),\n }}\n >\n {message.role === 'assistant' ? renderMarkdown(message.content, { codeBg: t.codeBg, codeBlockBg: t.codeBlockBg }) : message.content}\n </div>\n ))}\n {isLoading && (\n <div style={{\n display: 'flex',\n gap: '4px',\n padding: '10px 14px',\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n borderRadius: '12px',\n borderBottomLeftRadius: '4px',\n }}>\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <div style={{\n display: 'flex',\n gap: '8px',\n padding: '8px 8px',\n borderTop: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.5)' : 'rgba(255, 255, 255, 0.5)',\n }}>\n <input\n ref={inputRef}\n type=\"text\"\n value={input}\n onChange={e => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={!isInitialized || isLoading || isStreaming}\n style={{\n flex: 1,\n padding: '10px 14px',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.6)' : 'rgba(249, 250, 251, 0.6)',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n color: t.text,\n outline: 'none',\n transition: 'box-shadow 0.15s ease',\n }}\n onFocus={e => {\n e.currentTarget.style.boxShadow = `0 0 0 2px ${primaryColor}`;\n }}\n onBlur={e => {\n e.currentTarget.style.boxShadow = 'none';\n }}\n />\n <button\n onClick={sendMessage}\n disabled={!isInitialized || !input.trim() || isLoading || isStreaming}\n style={{\n padding: '10px 16px',\n backgroundColor: !isInitialized || !input.trim() || isLoading || isStreaming ? t.inputBorder : primaryColor,\n color: '#000',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: !isInitialized || !input.trim() || isLoading || isStreaming ? 'not-allowed' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>\n </svg>\n </button>\n </div>\n </div>\n )}\n\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '12px 16px',\n backgroundColor: primaryColor,\n color: textColor,\n border: 'none',\n borderRadius: '12px',\n fontSize: '14px',\n fontWeight: 600,\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n }}\n onMouseEnter={e => {\n e.currentTarget.style.transform = 'scale(1.05)';\n e.currentTarget.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.4)';\n }}\n onMouseLeave={e => {\n e.currentTarget.style.transform = 'scale(1)';\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)';\n }}\n >\n <span \n className={`mnx-btn-icon ${isOpen ? 'open' : ''}`}\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}\n >\n {isOpen ? (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n ) : logo ? (\n <img src={logo} alt=\"\" style={{ height: '28px', width: 'auto', objectFit: 'contain' }} />\n ) : (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </span>\n <span style={{ \n display: 'inline-flex',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n position: 'relative',\n height: '1.2em',\n alignItems: 'center',\n }}>\n <span style={{\n display: 'inline-block',\n transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n transform: isOpen ? 'translateY(-100%)' : 'translateY(0)',\n opacity: isOpen ? 0 : 1,\n maxWidth: isOpen ? '0' : '300px',\n }}>\n {buttonLabel}\n </span>\n <span style={{\n display: 'inline-block',\n transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n transform: isOpen ? 'translateY(0)' : 'translateY(100%)',\n opacity: isOpen ? 1 : 0,\n maxWidth: isOpen ? '50px' : '0',\n overflow: 'hidden',\n }}>\n Close\n </span>\n </span>\n </button>\n </div>\n </>\n );\n}\n\nexport default MnexiumChat;\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -121,6 +121,7 @@ function MnexiumChat({
121
121
  buttonLabel = "Ask AI",
122
122
  position = "bottom-right",
123
123
  primaryColor = "#facc15",
124
+ textColor = "#000",
124
125
  defaultOpen = false,
125
126
  logo,
126
127
  theme = "dark",
@@ -313,9 +314,6 @@ function MnexiumChat({
313
314
  .mnx-btn-icon {
314
315
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
315
316
  }
316
- .mnx-btn-icon.open {
317
- transform: rotate(45deg);
318
- }
319
317
  ` }),
320
318
  /* @__PURE__ */ jsxs("div", { style: {
321
319
  position: "fixed",
@@ -438,7 +436,7 @@ function MnexiumChat({
438
436
  ...message.role === "user" ? {
439
437
  alignSelf: "flex-end",
440
438
  backgroundColor: `${primaryColor}cc`,
441
- color: "#000",
439
+ color: textColor,
442
440
  borderBottomRightRadius: "4px"
443
441
  } : {
444
442
  alignSelf: "flex-start",
@@ -538,7 +536,7 @@ function MnexiumChat({
538
536
  gap: "8px",
539
537
  padding: "12px 16px",
540
538
  backgroundColor: primaryColor,
541
- color: "#000",
539
+ color: textColor,
542
540
  border: "none",
543
541
  borderRadius: "12px",
544
542
  fontSize: "14px",
@@ -571,11 +569,30 @@ function MnexiumChat({
571
569
  ] })
572
570
  }
573
571
  ),
574
- /* @__PURE__ */ jsx("span", { style: {
575
- transition: "opacity 0.2s, width 0.3s",
572
+ /* @__PURE__ */ jsxs("span", { style: {
573
+ display: "inline-flex",
576
574
  overflow: "hidden",
577
- whiteSpace: "nowrap"
578
- }, children: isOpen ? "Close" : buttonLabel })
575
+ whiteSpace: "nowrap",
576
+ position: "relative",
577
+ height: "1.2em",
578
+ alignItems: "center"
579
+ }, children: [
580
+ /* @__PURE__ */ jsx("span", { style: {
581
+ display: "inline-block",
582
+ transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
583
+ transform: isOpen ? "translateY(-100%)" : "translateY(0)",
584
+ opacity: isOpen ? 0 : 1,
585
+ maxWidth: isOpen ? "0" : "300px"
586
+ }, children: buttonLabel }),
587
+ /* @__PURE__ */ jsx("span", { style: {
588
+ display: "inline-block",
589
+ transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
590
+ transform: isOpen ? "translateY(0)" : "translateY(100%)",
591
+ opacity: isOpen ? 1 : 0,
592
+ maxWidth: isOpen ? "50px" : "0",
593
+ overflow: "hidden"
594
+ }, children: "Close" })
595
+ ] })
579
596
  ]
580
597
  }
581
598
  )
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/MnexiumChat.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: Date;\n}\n\nexport interface MnexiumChatProps {\n endpoint?: string;\n placeholder?: string;\n title?: string;\n buttonLabel?: string;\n position?: 'bottom-right' | 'bottom-left';\n primaryColor?: string;\n defaultOpen?: boolean;\n logo?: string;\n theme?: 'light' | 'dark';\n welcomeIcon?: string;\n welcomeMessage?: string;\n history?: boolean;\n eagerInit?: boolean;\n}\n\nconst themes = {\n dark: {\n bg: '#1a1a1a',\n bgSecondary: '#2a2a2a',\n border: '#333',\n text: '#fff',\n textSecondary: '#e5e5e5',\n textMuted: '#888',\n inputBg: '#2a2a2a',\n inputBorder: '#444',\n codeBg: '#374151',\n codeBlockBg: '#1f2937',\n },\n light: {\n bg: '#ffffff',\n bgSecondary: '#f3f4f6',\n border: '#e5e7eb',\n text: '#111827',\n textSecondary: '#374151',\n textMuted: '#6b7280',\n inputBg: '#f9fafb',\n inputBorder: '#d1d5db',\n codeBg: '#e5e7eb',\n codeBlockBg: '#f3f4f6',\n },\n};\n\nfunction generateId(): string {\n return Math.random().toString(36).substring(2, 15);\n}\n\nfunction renderMarkdown(text: string, themeColors: { codeBg: string; codeBlockBg: string }): React.ReactNode {\n if (!text) return null;\n const lines = text.split('\\n');\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeContent: string[] = [];\n\n const processInline = (line: string): React.ReactNode => {\n const parts: React.ReactNode[] = [];\n let remaining = line;\n let key = 0;\n\n while (remaining.length > 0) {\n const codeMatch = remaining.match(/`([^`]+)`/);\n const boldMatch = remaining.match(/\\*\\*([^*]+)\\*\\*/);\n const italicMatch = remaining.match(/\\*([^*]+)\\*/);\n\n const matches = [\n codeMatch ? { type: 'code', match: codeMatch, index: codeMatch.index! } : null,\n boldMatch ? { type: 'bold', match: boldMatch, index: boldMatch.index! } : null,\n italicMatch ? { type: 'italic', match: italicMatch, index: italicMatch.index! } : null,\n ].filter(Boolean).sort((a, b) => a!.index - b!.index);\n\n if (matches.length === 0) {\n parts.push(remaining);\n break;\n }\n\n const first = matches[0]!;\n if (first.index > 0) {\n parts.push(remaining.substring(0, first.index));\n }\n\n if (first.type === 'code') {\n parts.push(\n <code key={key++} style={{ backgroundColor: themeColors.codeBg, padding: '2px 6px', borderRadius: '4px', fontSize: '13px' }}>\n {first.match![1]}\n </code>\n );\n } else if (first.type === 'bold') {\n parts.push(<strong key={key++}>{first.match![1]}</strong>);\n } else if (first.type === 'italic') {\n parts.push(<em key={key++}>{first.match![1]}</em>);\n }\n\n remaining = remaining.substring(first.index + first.match![0].length);\n }\n\n return parts.length === 1 ? parts[0] : parts;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('```')) {\n if (!inCodeBlock) {\n inCodeBlock = true;\n codeContent = [];\n } else {\n elements.push(\n <pre key={i} style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n inCodeBlock = false;\n }\n continue;\n }\n\n if (inCodeBlock) {\n codeContent.push(line);\n continue;\n }\n\n if (line.startsWith('### ')) {\n elements.push(<h4 key={i} style={{ margin: '12px 0 8px', fontSize: '14px', fontWeight: 600 }}>{processInline(line.slice(4))}</h4>);\n } else if (line.startsWith('## ')) {\n elements.push(<h3 key={i} style={{ margin: '12px 0 8px', fontSize: '15px', fontWeight: 600 }}>{processInline(line.slice(3))}</h3>);\n } else if (line.startsWith('# ')) {\n elements.push(<h2 key={i} style={{ margin: '12px 0 8px', fontSize: '16px', fontWeight: 600 }}>{processInline(line.slice(2))}</h2>);\n } else if (line.startsWith('- ') || line.startsWith('* ')) {\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'disc' }}>{processInline(line.slice(2))}</li>);\n } else if (/^\\d+\\.\\s/.test(line)) {\n const content = line.replace(/^\\d+\\.\\s/, '');\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'decimal' }}>{processInline(content)}</li>);\n } else if (line.trim() === '') {\n elements.push(<br key={i} />);\n } else {\n elements.push(<p key={i} style={{ margin: '4px 0' }}>{processInline(line)}</p>);\n }\n }\n\n if (inCodeBlock && codeContent.length > 0) {\n elements.push(\n <pre key=\"final-code\" style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n }\n\n return <div>{elements}</div>;\n}\n\nexport function MnexiumChat({\n endpoint = '/api/mnx',\n placeholder = 'Type a message...',\n title = 'Ask AI',\n buttonLabel = 'Ask AI',\n position = 'bottom-right',\n primaryColor = '#facc15',\n defaultOpen = false,\n logo,\n theme = 'dark',\n welcomeIcon = '👋',\n welcomeMessage = 'How can I help you today?',\n history = false,\n eagerInit = true,\n}: MnexiumChatProps) {\n const t = themes[theme];\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const scrollToBottom = useCallback(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, []);\n\n useEffect(() => {\n scrollToBottom();\n }, [messages, scrollToBottom]);\n\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!eagerInit && !isOpen) return;\n \n const bootstrap = async () => {\n if (isInitialized) return;\n \n try {\n const res = await fetch(`${endpoint}/bootstrap`);\n if (!res.ok) throw new Error('Failed to bootstrap');\n \n const data = await res.json();\n \n if (history && data.chat_id) {\n try {\n const historyRes = await fetch(`${endpoint}/conversations/${data.chat_id}`);\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n if (historyData.messages && Array.isArray(historyData.messages)) {\n setMessages(historyData.messages.map((m: { role: string; content: string }) => ({\n id: generateId(),\n role: m.role as 'user' | 'assistant',\n content: m.content,\n timestamp: new Date(),\n })));\n }\n }\n } catch {\n // History endpoint is optional\n }\n }\n \n setIsInitialized(true);\n } catch (err) {\n setError('Failed to initialize chat');\n console.error('Bootstrap error:', err);\n }\n };\n\n bootstrap();\n }, [endpoint, isOpen, isInitialized, history, eagerInit]);\n\n const sendMessage = async () => {\n if (!input.trim() || isLoading || isStreaming) return;\n\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content: input.trim(),\n timestamp: new Date(),\n };\n\n setMessages(prev => [...prev, userMessage]);\n setInput('');\n setIsLoading(true);\n setError(null);\n\n const assistantMessageId = generateId();\n\n try {\n const res = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: userMessage.content }),\n });\n\n if (!res.ok) throw new Error('Failed to send message');\n if (!res.body) throw new Error('No response body');\n\n setIsLoading(false);\n setIsStreaming(true);\n\n const assistantMessage: Message = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n };\n setMessages(prev => [...prev, assistantMessage]);\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6);\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6);\n if (data !== '[DONE]') {\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } catch (err) {\n setError('Failed to send message');\n console.error('Chat error:', err);\n setMessages(prev => prev.filter(m => m.id !== assistantMessageId));\n } finally {\n setIsLoading(false);\n setIsStreaming(false);\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n sendMessage();\n }\n };\n\n const startNewChat = async () => {\n try {\n const res = await fetch(`${endpoint}/new-chat`, { method: 'POST' });\n if (res.ok) {\n setMessages([]);\n }\n } catch {\n // Fallback: just clear messages locally\n setMessages([]);\n }\n };\n\n const positionStyles = position === 'bottom-right' \n ? { right: '20px', bottom: '20px' }\n : { left: '20px', bottom: '20px' };\n\n const chatPositionStyles = position === 'bottom-right'\n ? { right: '0', bottom: '60px' }\n : { left: '0', bottom: '60px' };\n\n return (\n <>\n <style>{`\n @keyframes mnx-typing {\n 0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }\n 40% { transform: scale(1); opacity: 1; }\n }\n @keyframes mnx-fade-in {\n from { opacity: 0; transform: translateY(10px) scale(0.95); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n @keyframes mnx-fade-out {\n from { opacity: 1; transform: translateY(0) scale(1); }\n to { opacity: 0; transform: translateY(10px) scale(0.95); }\n }\n @keyframes mnx-pulse {\n 0% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n 50% { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); }\n 100% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n }\n .mnx-typing-dot:nth-child(1) { animation-delay: 0s; }\n .mnx-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n .mnx-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n .mnx-btn-icon {\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n .mnx-btn-icon.open {\n transform: rotate(45deg);\n }\n `}</style>\n\n <div style={{\n position: 'fixed',\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n ...positionStyles,\n }}>\n {isOpen && (\n <div style={{\n position: 'absolute',\n ...chatPositionStyles,\n width: '380px',\n height: '500px',\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.9)' : 'rgba(255, 255, 255, 0.9)',\n backdropFilter: 'blur(8px) saturate(180%)',\n WebkitBackdropFilter: 'blur(16px) saturate(180%)',\n borderRadius: '16px',\n border: `1px solid ${primaryColor}33`,\n boxShadow: theme === 'dark' ? '0 25px 50px -12px rgba(0, 0, 0, 0.5)' : '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n animation: 'mnx-fade-in 0.2s ease-out',\n transform: 'translateZ(0)',\n isolation: 'isolate',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 8px',\n borderBottom: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.7)' : 'rgba(255, 255, 255, 0.7)',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\n <div style={{\n width: '32px',\n height: '32px',\n backgroundColor: primaryColor,\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}>\n {logo ? (\n <img src={logo} alt=\"\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#000\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </div>\n <span style={{ color: t.text, fontWeight: 600, fontSize: '15px' }}>{title}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <button\n onClick={startNewChat}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '6px',\n borderRadius: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title=\"New chat\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>\n </svg>\n </button>\n <button\n onClick={() => setIsOpen(false)}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n </div>\n\n <div style={{\n flex: 1,\n overflowY: 'auto',\n padding: '8px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n }}>\n {!isInitialized && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted }}>\n Initializing...\n </div>\n )}\n {error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#ef4444' }}>\n {error}\n </div>\n )}\n {isInitialized && messages.length === 0 && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted, textAlign: 'center' }}>\n <div>\n <div style={{ fontSize: '24px', marginBottom: '8px' }}>{welcomeIcon}</div>\n <div>{welcomeMessage}</div>\n </div>\n </div>\n )}\n {messages.map(message => (\n <div\n key={message.id}\n style={{\n maxWidth: '85%',\n padding: '10px 14px',\n borderRadius: '12px',\n fontSize: '14px',\n lineHeight: 1.5,\n wordBreak: 'break-word',\n ...(message.role === 'user' \n ? { \n alignSelf: 'flex-end',\n backgroundColor: `${primaryColor}cc`,\n color: '#000',\n borderBottomRightRadius: '4px',\n }\n : {\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n color: t.textSecondary,\n borderBottomLeftRadius: '4px',\n }\n ),\n }}\n >\n {message.role === 'assistant' ? renderMarkdown(message.content, { codeBg: t.codeBg, codeBlockBg: t.codeBlockBg }) : message.content}\n </div>\n ))}\n {isLoading && (\n <div style={{\n display: 'flex',\n gap: '4px',\n padding: '10px 14px',\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n borderRadius: '12px',\n borderBottomLeftRadius: '4px',\n }}>\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <div style={{\n display: 'flex',\n gap: '8px',\n padding: '8px 8px',\n borderTop: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.5)' : 'rgba(255, 255, 255, 0.5)',\n }}>\n <input\n ref={inputRef}\n type=\"text\"\n value={input}\n onChange={e => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={!isInitialized || isLoading || isStreaming}\n style={{\n flex: 1,\n padding: '10px 14px',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.6)' : 'rgba(249, 250, 251, 0.6)',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n color: t.text,\n outline: 'none',\n transition: 'box-shadow 0.15s ease',\n }}\n onFocus={e => {\n e.currentTarget.style.boxShadow = `0 0 0 2px ${primaryColor}`;\n }}\n onBlur={e => {\n e.currentTarget.style.boxShadow = 'none';\n }}\n />\n <button\n onClick={sendMessage}\n disabled={!isInitialized || !input.trim() || isLoading || isStreaming}\n style={{\n padding: '10px 16px',\n backgroundColor: !isInitialized || !input.trim() || isLoading || isStreaming ? t.inputBorder : primaryColor,\n color: '#000',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: !isInitialized || !input.trim() || isLoading || isStreaming ? 'not-allowed' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>\n </svg>\n </button>\n </div>\n </div>\n )}\n\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '12px 16px',\n backgroundColor: primaryColor,\n color: '#000',\n border: 'none',\n borderRadius: '12px',\n fontSize: '14px',\n fontWeight: 600,\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n }}\n onMouseEnter={e => {\n e.currentTarget.style.transform = 'scale(1.05)';\n e.currentTarget.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.4)';\n }}\n onMouseLeave={e => {\n e.currentTarget.style.transform = 'scale(1)';\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)';\n }}\n >\n <span \n className={`mnx-btn-icon ${isOpen ? 'open' : ''}`}\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}\n >\n {isOpen ? (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n ) : logo ? (\n <img src={logo} alt=\"\" style={{ height: '28px', width: 'auto', objectFit: 'contain' }} />\n ) : (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </span>\n <span style={{ \n transition: 'opacity 0.2s, width 0.3s',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }}>\n {isOpen ? 'Close' : buttonLabel}\n </span>\n </button>\n </div>\n </>\n );\n}\n\nexport default MnexiumChat;\n"],"mappings":";;;AAEA,SAAgB,UAAU,WAAW,QAAQ,mBAAmB;AA2FtD,SA4RN,UA5RM,KAyWU,YAzWV;AAlEV,IAAM,SAAS;AAAA,EACb,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,eAAe;AAAA,IACf,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,eAAe;AAAA,IACf,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AACF;AAEA,SAAS,aAAqB;AAC5B,SAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AACnD;AAEA,SAAS,eAAe,MAAc,aAAuE;AAC3G,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,WAA8B,CAAC;AACrC,MAAI,cAAc;AAClB,MAAI,cAAwB,CAAC;AAE7B,QAAM,gBAAgB,CAAC,SAAkC;AACvD,UAAM,QAA2B,CAAC;AAClC,QAAI,YAAY;AAChB,QAAI,MAAM;AAEV,WAAO,UAAU,SAAS,GAAG;AAC3B,YAAM,YAAY,UAAU,MAAM,WAAW;AAC7C,YAAM,YAAY,UAAU,MAAM,iBAAiB;AACnD,YAAM,cAAc,UAAU,MAAM,aAAa;AAEjD,YAAM,UAAU;AAAA,QACd,YAAY,EAAE,MAAM,QAAQ,OAAO,WAAW,OAAO,UAAU,MAAO,IAAI;AAAA,QAC1E,YAAY,EAAE,MAAM,QAAQ,OAAO,WAAW,OAAO,UAAU,MAAO,IAAI;AAAA,QAC1E,cAAc,EAAE,MAAM,UAAU,OAAO,aAAa,OAAO,YAAY,MAAO,IAAI;AAAA,MACpF,EAAE,OAAO,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAG,QAAQ,EAAG,KAAK;AAEpD,UAAI,QAAQ,WAAW,GAAG;AACxB,cAAM,KAAK,SAAS;AACpB;AAAA,MACF;AAEA,YAAM,QAAQ,QAAQ,CAAC;AACvB,UAAI,MAAM,QAAQ,GAAG;AACnB,cAAM,KAAK,UAAU,UAAU,GAAG,MAAM,KAAK,CAAC;AAAA,MAChD;AAEA,UAAI,MAAM,SAAS,QAAQ;AACzB,cAAM;AAAA,UACJ,oBAAC,UAAiB,OAAO,EAAE,iBAAiB,YAAY,QAAQ,SAAS,WAAW,cAAc,OAAO,UAAU,OAAO,GACvH,gBAAM,MAAO,CAAC,KADN,KAEX;AAAA,QACF;AAAA,MACF,WAAW,MAAM,SAAS,QAAQ;AAChC,cAAM,KAAK,oBAAC,YAAoB,gBAAM,MAAO,CAAC,KAAtB,KAAwB,CAAS;AAAA,MAC3D,WAAW,MAAM,SAAS,UAAU;AAClC,cAAM,KAAK,oBAAC,QAAgB,gBAAM,MAAO,CAAC,KAAtB,KAAwB,CAAK;AAAA,MACnD;AAEA,kBAAY,UAAU,UAAU,MAAM,QAAQ,MAAM,MAAO,CAAC,EAAE,MAAM;AAAA,IACtE;AAEA,WAAO,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI;AAAA,EACzC;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AAEpB,QAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,UAAI,CAAC,aAAa;AAChB,sBAAc;AACd,sBAAc,CAAC;AAAA,MACjB,OAAO;AACL,iBAAS;AAAA,UACP,oBAAC,SAAY,OAAO,EAAE,iBAAiB,YAAY,aAAa,SAAS,QAAQ,cAAc,OAAO,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,GACxJ,8BAAC,UAAM,sBAAY,KAAK,IAAI,GAAE,KADtB,CAEV;AAAA,QACF;AACA,sBAAc;AAAA,MAChB;AACA;AAAA,IACF;AAEA,QAAI,aAAa;AACf,kBAAY,KAAK,IAAI;AACrB;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,eAAS,KAAK,oBAAC,QAAW,OAAO,EAAE,QAAQ,cAAc,UAAU,QAAQ,YAAY,IAAI,GAAI,wBAAc,KAAK,MAAM,CAAC,CAAC,KAAnG,CAAqG,CAAK;AAAA,IACnI,WAAW,KAAK,WAAW,KAAK,GAAG;AACjC,eAAS,KAAK,oBAAC,QAAW,OAAO,EAAE,QAAQ,cAAc,UAAU,QAAQ,YAAY,IAAI,GAAI,wBAAc,KAAK,MAAM,CAAC,CAAC,KAAnG,CAAqG,CAAK;AAAA,IACnI,WAAW,KAAK,WAAW,IAAI,GAAG;AAChC,eAAS,KAAK,oBAAC,QAAW,OAAO,EAAE,QAAQ,cAAc,UAAU,QAAQ,YAAY,IAAI,GAAI,wBAAc,KAAK,MAAM,CAAC,CAAC,KAAnG,CAAqG,CAAK;AAAA,IACnI,WAAW,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,IAAI,GAAG;AACzD,eAAS,KAAK,oBAAC,QAAW,OAAO,EAAE,YAAY,QAAQ,eAAe,OAAO,GAAI,wBAAc,KAAK,MAAM,CAAC,CAAC,KAArF,CAAuF,CAAK;AAAA,IACrH,WAAW,WAAW,KAAK,IAAI,GAAG;AAChC,YAAM,UAAU,KAAK,QAAQ,YAAY,EAAE;AAC3C,eAAS,KAAK,oBAAC,QAAW,OAAO,EAAE,YAAY,QAAQ,eAAe,UAAU,GAAI,wBAAc,OAAO,KAAlF,CAAoF,CAAK;AAAA,IAClH,WAAW,KAAK,KAAK,MAAM,IAAI;AAC7B,eAAS,KAAK,oBAAC,UAAQ,CAAG,CAAE;AAAA,IAC9B,OAAO;AACL,eAAS,KAAK,oBAAC,OAAU,OAAO,EAAE,QAAQ,QAAQ,GAAI,wBAAc,IAAI,KAAlD,CAAoD,CAAI;AAAA,IAChF;AAAA,EACF;AAEA,MAAI,eAAe,YAAY,SAAS,GAAG;AACzC,aAAS;AAAA,MACP,oBAAC,SAAqB,OAAO,EAAE,iBAAiB,YAAY,aAAa,SAAS,QAAQ,cAAc,OAAO,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,GACjK,8BAAC,UAAM,sBAAY,KAAK,IAAI,GAAE,KADvB,YAET;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,SAAK,oBAAS;AACxB;AAEO,SAAS,YAAY;AAAA,EAC1B,WAAW;AAAA,EACX,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AAAA,EACf,cAAc;AAAA,EACd;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,YAAY;AACd,GAAqB;AACnB,QAAM,IAAI,OAAO,KAAK;AACtB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,WAAW;AAChD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAoB,CAAC,CAAC;AACtD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AACxD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,iBAAiB,OAAuB,IAAI;AAClD,QAAM,WAAW,OAAyB,IAAI;AAE9C,QAAM,iBAAiB,YAAY,MAAM;AACvC,mBAAe,SAAS,eAAe,EAAE,UAAU,SAAS,CAAC;AAAA,EAC/D,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,mBAAe;AAAA,EACjB,GAAG,CAAC,UAAU,cAAc,CAAC;AAE7B,YAAU,MAAM;AACd,QAAI,UAAU,SAAS,SAAS;AAC9B,eAAS,QAAQ,MAAM;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,YAAU,MAAM;AACd,QAAI,CAAC,aAAa,CAAC,OAAQ;AAE3B,UAAM,YAAY,YAAY;AAC5B,UAAI,cAAe;AAEnB,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,YAAY;AAC/C,YAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,qBAAqB;AAElD,cAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,YAAI,WAAW,KAAK,SAAS;AAC3B,cAAI;AACF,kBAAM,aAAa,MAAM,MAAM,GAAG,QAAQ,kBAAkB,KAAK,OAAO,EAAE;AAC1E,gBAAI,WAAW,IAAI;AACjB,oBAAM,cAAc,MAAM,WAAW,KAAK;AAC1C,kBAAI,YAAY,YAAY,MAAM,QAAQ,YAAY,QAAQ,GAAG;AAC/D,4BAAY,YAAY,SAAS,IAAI,CAAC,OAA0C;AAAA,kBAC9E,IAAI,WAAW;AAAA,kBACf,MAAM,EAAE;AAAA,kBACR,SAAS,EAAE;AAAA,kBACX,WAAW,oBAAI,KAAK;AAAA,gBACtB,EAAE,CAAC;AAAA,cACL;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAEA,yBAAiB,IAAI;AAAA,MACvB,SAAS,KAAK;AACZ,iBAAS,2BAA2B;AACpC,gBAAQ,MAAM,oBAAoB,GAAG;AAAA,MACvC;AAAA,IACF;AAEA,cAAU;AAAA,EACZ,GAAG,CAAC,UAAU,QAAQ,eAAe,SAAS,SAAS,CAAC;AAExD,QAAM,cAAc,YAAY;AAC9B,QAAI,CAAC,MAAM,KAAK,KAAK,aAAa,YAAa;AAE/C,UAAM,cAAuB;AAAA,MAC3B,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,SAAS,MAAM,KAAK;AAAA,MACpB,WAAW,oBAAI,KAAK;AAAA,IACtB;AAEA,gBAAY,UAAQ,CAAC,GAAG,MAAM,WAAW,CAAC;AAC1C,aAAS,EAAE;AACX,iBAAa,IAAI;AACjB,aAAS,IAAI;AAEb,UAAM,qBAAqB,WAAW;AAEtC,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,SAAS;AAAA,QAC1C,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,SAAS,YAAY,QAAQ,CAAC;AAAA,MACvD,CAAC;AAED,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,wBAAwB;AACrD,UAAI,CAAC,IAAI,KAAM,OAAM,IAAI,MAAM,kBAAkB;AAEjD,mBAAa,KAAK;AAClB,qBAAe,IAAI;AAEnB,YAAM,mBAA4B;AAAA,QAChC,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW,oBAAI,KAAK;AAAA,MACtB;AACA,kBAAY,UAAQ,CAAC,GAAG,MAAM,gBAAgB,CAAC;AAE/C,YAAM,SAAS,IAAI,KAAK,UAAU;AAClC,YAAM,UAAU,IAAI,YAAY;AAChC,UAAI,SAAS;AAEb,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AAEV,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AAExB,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,kBAAM,OAAO,KAAK,MAAM,CAAC;AACzB,gBAAI,SAAS,SAAU;AAEvB,gBAAI;AACF,oBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,oBAAM,UAAU,OAAO,UAAU,CAAC,GAAG,OAAO;AAC5C,kBAAI,SAAS;AACX;AAAA,kBAAY,UACV,KAAK;AAAA,oBAAI,OACP,EAAE,OAAO,qBACL,EAAE,GAAG,GAAG,SAAS,EAAE,UAAU,QAAQ,IACrC;AAAA,kBACN;AAAA,gBACF;AAAA,cACF;AAAA,YACF,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,OAAO,WAAW,QAAQ,GAAG;AAC/B,cAAM,OAAO,OAAO,MAAM,CAAC;AAC3B,YAAI,SAAS,UAAU;AACrB,cAAI;AACF,kBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,kBAAM,UAAU,OAAO,UAAU,CAAC,GAAG,OAAO;AAC5C,gBAAI,SAAS;AACX;AAAA,gBAAY,UACV,KAAK;AAAA,kBAAI,OACP,EAAE,OAAO,qBACL,EAAE,GAAG,GAAG,SAAS,EAAE,UAAU,QAAQ,IACrC;AAAA,gBACN;AAAA,cACF;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,eAAS,wBAAwB;AACjC,cAAQ,MAAM,eAAe,GAAG;AAChC,kBAAY,UAAQ,KAAK,OAAO,OAAK,EAAE,OAAO,kBAAkB,CAAC;AAAA,IACnE,UAAE;AACA,mBAAa,KAAK;AAClB,qBAAe,KAAK;AACpB,4BAAsB,MAAM;AAC1B,iBAAS,SAAS,MAAM;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,MAA2B;AAChD,QAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,QAAE,eAAe;AACjB,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,eAAe,YAAY;AAC/B,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,aAAa,EAAE,QAAQ,OAAO,CAAC;AAClE,UAAI,IAAI,IAAI;AACV,oBAAY,CAAC,CAAC;AAAA,MAChB;AAAA,IACF,QAAQ;AAEN,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,iBAAiB,aAAa,iBAChC,EAAE,OAAO,QAAQ,QAAQ,OAAO,IAChC,EAAE,MAAM,QAAQ,QAAQ,OAAO;AAEnC,QAAM,qBAAqB,aAAa,iBACpC,EAAE,OAAO,KAAK,QAAQ,OAAO,IAC7B,EAAE,MAAM,KAAK,QAAQ,OAAO;AAEhC,SACE,iCACE;AAAA,wBAAC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SA2BN;AAAA,IAEF,qBAAC,SAAI,OAAO;AAAA,MACV,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,GAAG;AAAA,IACL,GACG;AAAA,gBACC,qBAAC,SAAI,OAAO;AAAA,QACV,UAAU;AAAA,QACV,GAAG;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,iBAAiB,UAAU,SAAS,0BAA0B;AAAA,QAC9D,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,cAAc;AAAA,QACd,QAAQ,aAAa,YAAY;AAAA,QACjC,WAAW,UAAU,SAAS,yCAAyC;AAAA,QACvE,SAAS;AAAA,QACT,eAAe;AAAA,QACf,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,WAAW;AAAA,MACb,GACE;AAAA,6BAAC,SAAI,OAAO;AAAA,UACV,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,SAAS;AAAA,UACT,cAAc,aAAa,EAAE,MAAM;AAAA,UACnC,iBAAiB,UAAU,SAAS,0BAA0B;AAAA,QAChE,GACE;AAAA,+BAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,OAAO,GAC/D;AAAA,gCAAC,SAAI,OAAO;AAAA,cACV,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,cAAc;AAAA,cACd,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,UAAU;AAAA,YACZ,GACG,iBACC,oBAAC,SAAI,KAAK,MAAM,KAAI,IAAG,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,QAAQ,GAAG,IAErF,qBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,QAAO,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAC/H;AAAA,kCAAC,UAAK,GAAE,6BAA2B;AAAA,cACnC,oBAAC,UAAK,GAAE,mBAAiB;AAAA,cACzB,oBAAC,UAAK,GAAE,mBAAiB;AAAA,eAC3B,GAEJ;AAAA,YACA,oBAAC,UAAK,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,KAAK,UAAU,OAAO,GAAI,iBAAM;AAAA,aAC5E;AAAA,UACA,qBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,MAAM,GAC9D;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS;AAAA,gBACT,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,QAAQ;AAAA,kBACR,OAAO,EAAE;AAAA,kBACT,QAAQ;AAAA,kBACR,SAAS;AAAA,kBACT,cAAc;AAAA,kBACd,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,gBAClB;AAAA,gBACA,OAAM;AAAA,gBAEN,+BAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACrI;AAAA,sCAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAI;AAAA,kBACpC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAI;AAAA,mBACtC;AAAA;AAAA,YACF;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS,MAAM,UAAU,KAAK;AAAA,gBAC9B,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,QAAQ;AAAA,kBACR,OAAO,EAAE;AAAA,kBACT,QAAQ;AAAA,kBACR,SAAS;AAAA,kBACT,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,gBAClB;AAAA,gBAEA,+BAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACrI;AAAA,sCAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAI;AAAA,kBACnC,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,MAAI;AAAA,mBACrC;AAAA;AAAA,YACF;AAAA,aACF;AAAA,WACF;AAAA,QAEA,qBAAC,SAAI,OAAO;AAAA,UACV,MAAM;AAAA,UACN,WAAW;AAAA,UACX,SAAS;AAAA,UACT,SAAS;AAAA,UACT,eAAe;AAAA,UACf,KAAK;AAAA,QACP,GACG;AAAA,WAAC,iBAAiB,CAAC,SAClB,oBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,QAAQ,QAAQ,OAAO,EAAE,UAAU,GAAG,6BAErH;AAAA,UAED,SACC,oBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,QAAQ,QAAQ,OAAO,UAAU,GAC7G,iBACH;AAAA,UAED,iBAAiB,SAAS,WAAW,KAAK,CAAC,SAC1C,oBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,QAAQ,QAAQ,OAAO,EAAE,WAAW,WAAW,SAAS,GACrI,+BAAC,SACC;AAAA,gCAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,cAAc,MAAM,GAAI,uBAAY;AAAA,YACpE,oBAAC,SAAK,0BAAe;AAAA,aACvB,GACF;AAAA,UAED,SAAS,IAAI,aACZ;AAAA,YAAC;AAAA;AAAA,cAEC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,WAAW;AAAA,gBACX,GAAI,QAAQ,SAAS,SACjB;AAAA,kBACE,WAAW;AAAA,kBACX,iBAAiB,GAAG,YAAY;AAAA,kBAChC,OAAO;AAAA,kBACP,yBAAyB;AAAA,gBAC3B,IACA;AAAA,kBACE,WAAW;AAAA,kBACX,iBAAiB,UAAU,SAAS,0BAA0B;AAAA,kBAC9D,OAAO,EAAE;AAAA,kBACT,wBAAwB;AAAA,gBAC1B;AAAA,cAEN;AAAA,cAEC,kBAAQ,SAAS,cAAc,eAAe,QAAQ,SAAS,EAAE,QAAQ,EAAE,QAAQ,aAAa,EAAE,YAAY,CAAC,IAAI,QAAQ;AAAA;AAAA,YAxBvH,QAAQ;AAAA,UAyBf,CACD;AAAA,UACA,aACC,qBAAC,SAAI,OAAO;AAAA,YACV,SAAS;AAAA,YACT,KAAK;AAAA,YACL,SAAS;AAAA,YACT,WAAW;AAAA,YACX,iBAAiB,UAAU,SAAS,0BAA0B;AAAA,YAC9D,cAAc;AAAA,YACd,wBAAwB;AAAA,UAC1B,GACE;AAAA,gCAAC,SAAI,WAAU,kBAAiB,OAAO,EAAE,OAAO,OAAO,QAAQ,OAAO,iBAAiB,EAAE,WAAW,cAAc,OAAO,WAAW,uCAAuC,GAAG;AAAA,YAC9K,oBAAC,SAAI,WAAU,kBAAiB,OAAO,EAAE,OAAO,OAAO,QAAQ,OAAO,iBAAiB,EAAE,WAAW,cAAc,OAAO,WAAW,uCAAuC,GAAG;AAAA,YAC9K,oBAAC,SAAI,WAAU,kBAAiB,OAAO,EAAE,OAAO,OAAO,QAAQ,OAAO,iBAAiB,EAAE,WAAW,cAAc,OAAO,WAAW,uCAAuC,GAAG;AAAA,aAChL;AAAA,UAEF,oBAAC,SAAI,KAAK,gBAAgB;AAAA,WAC5B;AAAA,QAEA,qBAAC,SAAI,OAAO;AAAA,UACV,SAAS;AAAA,UACT,KAAK;AAAA,UACL,SAAS;AAAA,UACT,WAAW,aAAa,EAAE,MAAM;AAAA,UAChC,iBAAiB,UAAU,SAAS,0BAA0B;AAAA,QAChE,GACE;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,OAAK,SAAS,EAAE,OAAO,KAAK;AAAA,cACtC,WAAW;AAAA,cACX;AAAA,cACA,UAAU,CAAC,iBAAiB,aAAa;AAAA,cACzC,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,iBAAiB,UAAU,SAAS,0BAA0B;AAAA,gBAC9D,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,UAAU;AAAA,gBACV,OAAO,EAAE;AAAA,gBACT,SAAS;AAAA,gBACT,YAAY;AAAA,cACd;AAAA,cACA,SAAS,OAAK;AACZ,kBAAE,cAAc,MAAM,YAAY,aAAa,YAAY;AAAA,cAC7D;AAAA,cACA,QAAQ,OAAK;AACX,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA;AAAA,UACF;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,UAAU,CAAC,iBAAiB,CAAC,MAAM,KAAK,KAAK,aAAa;AAAA,cAC1D,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,iBAAiB,CAAC,iBAAiB,CAAC,MAAM,KAAK,KAAK,aAAa,cAAc,EAAE,cAAc;AAAA,gBAC/F,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,QAAQ,CAAC,iBAAiB,CAAC,MAAM,KAAK,KAAK,aAAa,cAAc,gBAAgB;AAAA,gBACtF,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,cAClB;AAAA,cAEA,+BAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACrI;AAAA,oCAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAI;AAAA,gBACpC,oBAAC,aAAQ,QAAO,6BAA2B;AAAA,iBAC7C;AAAA;AAAA,UACF;AAAA,WACF;AAAA,SACF;AAAA,MAGF;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM,UAAU,CAAC,MAAM;AAAA,UAChC,OAAO;AAAA,YACL,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,KAAK;AAAA,YACL,SAAS;AAAA,YACT,iBAAiB;AAAA,YACjB,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,WAAW;AAAA,YACX,YAAY;AAAA,UACd;AAAA,UACA,cAAc,OAAK;AACjB,cAAE,cAAc,MAAM,YAAY;AAClC,cAAE,cAAc,MAAM,YAAY;AAAA,UACpC;AAAA,UACA,cAAc,OAAK;AACjB,cAAE,cAAc,MAAM,YAAY;AAClC,cAAE,cAAc,MAAM,YAAY;AAAA,UACpC;AAAA,UAEA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW,gBAAgB,SAAS,SAAS,EAAE;AAAA,gBAC/C,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,SAAS;AAAA,gBAExE,mBACC,qBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,gBAAe,SACvI;AAAA,sCAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAI;AAAA,kBACnC,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,MAAI;AAAA,mBACrC,IACE,OACF,oBAAC,SAAI,KAAK,MAAM,KAAI,IAAG,OAAO,EAAE,QAAQ,QAAQ,OAAO,QAAQ,WAAW,UAAU,GAAG,IAEvF,qBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,gBAAe,SACvI;AAAA,sCAAC,UAAK,GAAE,6BAA2B;AAAA,kBACnC,oBAAC,UAAK,GAAE,mBAAiB;AAAA,kBACzB,oBAAC,UAAK,GAAE,mBAAiB;AAAA,mBAC3B;AAAA;AAAA,YAEJ;AAAA,YACA,oBAAC,UAAK,OAAO;AAAA,cACX,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,YAAY;AAAA,YACd,GACG,mBAAS,UAAU,aACtB;AAAA;AAAA;AAAA,MACF;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/client/MnexiumChat.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: Date;\n}\n\nexport interface MnexiumChatProps {\n endpoint?: string;\n placeholder?: string;\n title?: string;\n buttonLabel?: string;\n position?: 'bottom-right' | 'bottom-left';\n primaryColor?: string;\n textColor?: string;\n defaultOpen?: boolean;\n logo?: string;\n theme?: 'light' | 'dark';\n welcomeIcon?: string;\n welcomeMessage?: string;\n history?: boolean;\n eagerInit?: boolean;\n}\n\nconst themes = {\n dark: {\n bg: '#1a1a1a',\n bgSecondary: '#2a2a2a',\n border: '#333',\n text: '#fff',\n textSecondary: '#e5e5e5',\n textMuted: '#888',\n inputBg: '#2a2a2a',\n inputBorder: '#444',\n codeBg: '#374151',\n codeBlockBg: '#1f2937',\n },\n light: {\n bg: '#ffffff',\n bgSecondary: '#f3f4f6',\n border: '#e5e7eb',\n text: '#111827',\n textSecondary: '#374151',\n textMuted: '#6b7280',\n inputBg: '#f9fafb',\n inputBorder: '#d1d5db',\n codeBg: '#e5e7eb',\n codeBlockBg: '#f3f4f6',\n },\n};\n\nfunction generateId(): string {\n return Math.random().toString(36).substring(2, 15);\n}\n\nfunction renderMarkdown(text: string, themeColors: { codeBg: string; codeBlockBg: string }): React.ReactNode {\n if (!text) return null;\n const lines = text.split('\\n');\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeContent: string[] = [];\n\n const processInline = (line: string): React.ReactNode => {\n const parts: React.ReactNode[] = [];\n let remaining = line;\n let key = 0;\n\n while (remaining.length > 0) {\n const codeMatch = remaining.match(/`([^`]+)`/);\n const boldMatch = remaining.match(/\\*\\*([^*]+)\\*\\*/);\n const italicMatch = remaining.match(/\\*([^*]+)\\*/);\n\n const matches = [\n codeMatch ? { type: 'code', match: codeMatch, index: codeMatch.index! } : null,\n boldMatch ? { type: 'bold', match: boldMatch, index: boldMatch.index! } : null,\n italicMatch ? { type: 'italic', match: italicMatch, index: italicMatch.index! } : null,\n ].filter(Boolean).sort((a, b) => a!.index - b!.index);\n\n if (matches.length === 0) {\n parts.push(remaining);\n break;\n }\n\n const first = matches[0]!;\n if (first.index > 0) {\n parts.push(remaining.substring(0, first.index));\n }\n\n if (first.type === 'code') {\n parts.push(\n <code key={key++} style={{ backgroundColor: themeColors.codeBg, padding: '2px 6px', borderRadius: '4px', fontSize: '13px' }}>\n {first.match![1]}\n </code>\n );\n } else if (first.type === 'bold') {\n parts.push(<strong key={key++}>{first.match![1]}</strong>);\n } else if (first.type === 'italic') {\n parts.push(<em key={key++}>{first.match![1]}</em>);\n }\n\n remaining = remaining.substring(first.index + first.match![0].length);\n }\n\n return parts.length === 1 ? parts[0] : parts;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('```')) {\n if (!inCodeBlock) {\n inCodeBlock = true;\n codeContent = [];\n } else {\n elements.push(\n <pre key={i} style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n inCodeBlock = false;\n }\n continue;\n }\n\n if (inCodeBlock) {\n codeContent.push(line);\n continue;\n }\n\n if (line.startsWith('### ')) {\n elements.push(<h4 key={i} style={{ margin: '12px 0 8px', fontSize: '14px', fontWeight: 600 }}>{processInline(line.slice(4))}</h4>);\n } else if (line.startsWith('## ')) {\n elements.push(<h3 key={i} style={{ margin: '12px 0 8px', fontSize: '15px', fontWeight: 600 }}>{processInline(line.slice(3))}</h3>);\n } else if (line.startsWith('# ')) {\n elements.push(<h2 key={i} style={{ margin: '12px 0 8px', fontSize: '16px', fontWeight: 600 }}>{processInline(line.slice(2))}</h2>);\n } else if (line.startsWith('- ') || line.startsWith('* ')) {\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'disc' }}>{processInline(line.slice(2))}</li>);\n } else if (/^\\d+\\.\\s/.test(line)) {\n const content = line.replace(/^\\d+\\.\\s/, '');\n elements.push(<li key={i} style={{ marginLeft: '16px', listStyleType: 'decimal' }}>{processInline(content)}</li>);\n } else if (line.trim() === '') {\n elements.push(<br key={i} />);\n } else {\n elements.push(<p key={i} style={{ margin: '4px 0' }}>{processInline(line)}</p>);\n }\n }\n\n if (inCodeBlock && codeContent.length > 0) {\n elements.push(\n <pre key=\"final-code\" style={{ backgroundColor: themeColors.codeBlockBg, padding: '12px', borderRadius: '8px', overflow: 'auto', fontSize: '13px', margin: '8px 0' }}>\n <code>{codeContent.join('\\n')}</code>\n </pre>\n );\n }\n\n return <div>{elements}</div>;\n}\n\nexport function MnexiumChat({\n endpoint = '/api/mnx',\n placeholder = 'Type a message...',\n title = 'Ask AI',\n buttonLabel = 'Ask AI',\n position = 'bottom-right',\n primaryColor = '#facc15',\n textColor = '#000',\n defaultOpen = false,\n logo,\n theme = 'dark',\n welcomeIcon = '👋',\n welcomeMessage = 'How can I help you today?',\n history = false,\n eagerInit = true,\n}: MnexiumChatProps) {\n const t = themes[theme];\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const scrollToBottom = useCallback(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, []);\n\n useEffect(() => {\n scrollToBottom();\n }, [messages, scrollToBottom]);\n\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!eagerInit && !isOpen) return;\n \n const bootstrap = async () => {\n if (isInitialized) return;\n \n try {\n const res = await fetch(`${endpoint}/bootstrap`);\n if (!res.ok) throw new Error('Failed to bootstrap');\n \n const data = await res.json();\n \n if (history && data.chat_id) {\n try {\n const historyRes = await fetch(`${endpoint}/conversations/${data.chat_id}`);\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n if (historyData.messages && Array.isArray(historyData.messages)) {\n setMessages(historyData.messages.map((m: { role: string; content: string }) => ({\n id: generateId(),\n role: m.role as 'user' | 'assistant',\n content: m.content,\n timestamp: new Date(),\n })));\n }\n }\n } catch {\n // History endpoint is optional\n }\n }\n \n setIsInitialized(true);\n } catch (err) {\n setError('Failed to initialize chat');\n console.error('Bootstrap error:', err);\n }\n };\n\n bootstrap();\n }, [endpoint, isOpen, isInitialized, history, eagerInit]);\n\n const sendMessage = async () => {\n if (!input.trim() || isLoading || isStreaming) return;\n\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content: input.trim(),\n timestamp: new Date(),\n };\n\n setMessages(prev => [...prev, userMessage]);\n setInput('');\n setIsLoading(true);\n setError(null);\n\n const assistantMessageId = generateId();\n\n try {\n const res = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: userMessage.content }),\n });\n\n if (!res.ok) throw new Error('Failed to send message');\n if (!res.body) throw new Error('No response body');\n\n setIsLoading(false);\n setIsStreaming(true);\n\n const assistantMessage: Message = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n };\n setMessages(prev => [...prev, assistantMessage]);\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6);\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6);\n if (data !== '[DONE]') {\n try {\n const parsed = JSON.parse(data);\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n setMessages(prev =>\n prev.map(m =>\n m.id === assistantMessageId\n ? { ...m, content: m.content + content }\n : m\n )\n );\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } catch (err) {\n setError('Failed to send message');\n console.error('Chat error:', err);\n setMessages(prev => prev.filter(m => m.id !== assistantMessageId));\n } finally {\n setIsLoading(false);\n setIsStreaming(false);\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n sendMessage();\n }\n };\n\n const startNewChat = async () => {\n try {\n const res = await fetch(`${endpoint}/new-chat`, { method: 'POST' });\n if (res.ok) {\n setMessages([]);\n }\n } catch {\n // Fallback: just clear messages locally\n setMessages([]);\n }\n };\n\n const positionStyles = position === 'bottom-right' \n ? { right: '20px', bottom: '20px' }\n : { left: '20px', bottom: '20px' };\n\n const chatPositionStyles = position === 'bottom-right'\n ? { right: '0', bottom: '60px' }\n : { left: '0', bottom: '60px' };\n\n return (\n <>\n <style>{`\n @keyframes mnx-typing {\n 0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }\n 40% { transform: scale(1); opacity: 1; }\n }\n @keyframes mnx-fade-in {\n from { opacity: 0; transform: translateY(10px) scale(0.95); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n @keyframes mnx-fade-out {\n from { opacity: 1; transform: translateY(0) scale(1); }\n to { opacity: 0; transform: translateY(10px) scale(0.95); }\n }\n @keyframes mnx-pulse {\n 0% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n 50% { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); }\n 100% { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }\n }\n .mnx-typing-dot:nth-child(1) { animation-delay: 0s; }\n .mnx-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n .mnx-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n .mnx-btn-icon {\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n `}</style>\n\n <div style={{\n position: 'fixed',\n zIndex: 9999,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n ...positionStyles,\n }}>\n {isOpen && (\n <div style={{\n position: 'absolute',\n ...chatPositionStyles,\n width: '380px',\n height: '500px',\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.9)' : 'rgba(255, 255, 255, 0.9)',\n backdropFilter: 'blur(8px) saturate(180%)',\n WebkitBackdropFilter: 'blur(16px) saturate(180%)',\n borderRadius: '16px',\n border: `1px solid ${primaryColor}33`,\n boxShadow: theme === 'dark' ? '0 25px 50px -12px rgba(0, 0, 0, 0.5)' : '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n animation: 'mnx-fade-in 0.2s ease-out',\n transform: 'translateZ(0)',\n isolation: 'isolate',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 8px',\n borderBottom: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.7)' : 'rgba(255, 255, 255, 0.7)',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\n <div style={{\n width: '32px',\n height: '32px',\n backgroundColor: primaryColor,\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}>\n {logo ? (\n <img src={logo} alt=\"\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#000\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </div>\n <span style={{ color: t.text, fontWeight: 600, fontSize: '15px' }}>{title}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <button\n onClick={startNewChat}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '6px',\n borderRadius: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title=\"New chat\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>\n </svg>\n </button>\n <button\n onClick={() => setIsOpen(false)}\n style={{\n background: 'none',\n border: 'none',\n color: t.textMuted,\n cursor: 'pointer',\n padding: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n </div>\n\n <div style={{\n flex: 1,\n overflowY: 'auto',\n padding: '8px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n }}>\n {!isInitialized && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted }}>\n Initializing...\n </div>\n )}\n {error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#ef4444' }}>\n {error}\n </div>\n )}\n {isInitialized && messages.length === 0 && !error && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: t.textMuted, textAlign: 'center' }}>\n <div>\n <div style={{ fontSize: '24px', marginBottom: '8px' }}>{welcomeIcon}</div>\n <div>{welcomeMessage}</div>\n </div>\n </div>\n )}\n {messages.map(message => (\n <div\n key={message.id}\n style={{\n maxWidth: '85%',\n padding: '10px 14px',\n borderRadius: '12px',\n fontSize: '14px',\n lineHeight: 1.5,\n wordBreak: 'break-word',\n ...(message.role === 'user' \n ? { \n alignSelf: 'flex-end',\n backgroundColor: `${primaryColor}cc`,\n color: textColor,\n borderBottomRightRadius: '4px',\n }\n : {\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n color: t.textSecondary,\n borderBottomLeftRadius: '4px',\n }\n ),\n }}\n >\n {message.role === 'assistant' ? renderMarkdown(message.content, { codeBg: t.codeBg, codeBlockBg: t.codeBlockBg }) : message.content}\n </div>\n ))}\n {isLoading && (\n <div style={{\n display: 'flex',\n gap: '4px',\n padding: '10px 14px',\n alignSelf: 'flex-start',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.7)' : 'rgba(243, 244, 246, 0.7)',\n borderRadius: '12px',\n borderBottomLeftRadius: '4px',\n }}>\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n <div className=\"mnx-typing-dot\" style={{ width: '6px', height: '6px', backgroundColor: t.textMuted, borderRadius: '50%', animation: 'mnx-typing 1.4s infinite ease-in-out' }} />\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <div style={{\n display: 'flex',\n gap: '8px',\n padding: '8px 8px',\n borderTop: `1px solid ${t.border}`,\n backgroundColor: theme === 'dark' ? 'rgba(26, 26, 26, 0.5)' : 'rgba(255, 255, 255, 0.5)',\n }}>\n <input\n ref={inputRef}\n type=\"text\"\n value={input}\n onChange={e => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={!isInitialized || isLoading || isStreaming}\n style={{\n flex: 1,\n padding: '10px 14px',\n backgroundColor: theme === 'dark' ? 'rgba(42, 42, 42, 0.6)' : 'rgba(249, 250, 251, 0.6)',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n color: t.text,\n outline: 'none',\n transition: 'box-shadow 0.15s ease',\n }}\n onFocus={e => {\n e.currentTarget.style.boxShadow = `0 0 0 2px ${primaryColor}`;\n }}\n onBlur={e => {\n e.currentTarget.style.boxShadow = 'none';\n }}\n />\n <button\n onClick={sendMessage}\n disabled={!isInitialized || !input.trim() || isLoading || isStreaming}\n style={{\n padding: '10px 16px',\n backgroundColor: !isInitialized || !input.trim() || isLoading || isStreaming ? t.inputBorder : primaryColor,\n color: '#000',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: !isInitialized || !input.trim() || isLoading || isStreaming ? 'not-allowed' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\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\"/>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>\n </svg>\n </button>\n </div>\n </div>\n )}\n\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '12px 16px',\n backgroundColor: primaryColor,\n color: textColor,\n border: 'none',\n borderRadius: '12px',\n fontSize: '14px',\n fontWeight: 600,\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n }}\n onMouseEnter={e => {\n e.currentTarget.style.transform = 'scale(1.05)';\n e.currentTarget.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.4)';\n }}\n onMouseLeave={e => {\n e.currentTarget.style.transform = 'scale(1)';\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)';\n }}\n >\n <span \n className={`mnx-btn-icon ${isOpen ? 'open' : ''}`}\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}\n >\n {isOpen ? (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n ) : logo ? (\n <img src={logo} alt=\"\" style={{ height: '28px', width: 'auto', objectFit: 'contain' }} />\n ) : (\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path d=\"M2 17l10 5 10-5\"/>\n <path d=\"M2 12l10 5 10-5\"/>\n </svg>\n )}\n </span>\n <span style={{ \n display: 'inline-flex',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n position: 'relative',\n height: '1.2em',\n alignItems: 'center',\n }}>\n <span style={{\n display: 'inline-block',\n transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n transform: isOpen ? 'translateY(-100%)' : 'translateY(0)',\n opacity: isOpen ? 0 : 1,\n maxWidth: isOpen ? '0' : '300px',\n }}>\n {buttonLabel}\n </span>\n <span style={{\n display: 'inline-block',\n transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s, max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n transform: isOpen ? 'translateY(0)' : 'translateY(100%)',\n opacity: isOpen ? 1 : 0,\n maxWidth: isOpen ? '50px' : '0',\n overflow: 'hidden',\n }}>\n Close\n </span>\n </span>\n </button>\n </div>\n </>\n );\n}\n\nexport default MnexiumChat;\n"],"mappings":"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","names":[]}
@@ -17,6 +17,7 @@ interface ChatOptions {
17
17
  recall?: boolean;
18
18
  profile?: boolean;
19
19
  summarize?: 'light' | 'balanced' | 'aggressive' | false;
20
+ system_prompt_id?: string;
20
21
  };
21
22
  }
22
23
  declare function chatHandler(req: Request, options?: ChatOptions): Promise<Response>;
@@ -39,6 +40,7 @@ interface MnexiumHandlersConfig {
39
40
  recall?: boolean;
40
41
  profile?: boolean;
41
42
  summarize?: 'light' | 'balanced' | 'aggressive' | false;
43
+ system_prompt_id?: string;
42
44
  };
43
45
  }
44
46
  interface MnexiumHandlers {
@@ -17,6 +17,7 @@ interface ChatOptions {
17
17
  recall?: boolean;
18
18
  profile?: boolean;
19
19
  summarize?: 'light' | 'balanced' | 'aggressive' | false;
20
+ system_prompt_id?: string;
20
21
  };
21
22
  }
22
23
  declare function chatHandler(req: Request, options?: ChatOptions): Promise<Response>;
@@ -39,6 +40,7 @@ interface MnexiumHandlersConfig {
39
40
  recall?: boolean;
40
41
  profile?: boolean;
41
42
  summarize?: 'light' | 'balanced' | 'aggressive' | false;
43
+ system_prompt_id?: string;
42
44
  };
43
45
  }
44
46
  interface MnexiumHandlers {
@@ -73,7 +73,7 @@ async function bootstrapHandler(req, options = {}) {
73
73
  const setCookies = [];
74
74
  const isSecure = req.url.startsWith("https://") || req.headers.get("x-forwarded-proto") === "https";
75
75
  if (!subjectId) {
76
- subjectId = generateUUID();
76
+ subjectId = `mnx_em_${generateUUID()}`;
77
77
  setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));
78
78
  }
79
79
  if (!chatId) {
@@ -369,19 +369,23 @@ async function chatHandler(req, options = {}) {
369
369
  if (process.env.GOOGLE_API_KEY) {
370
370
  headers["x-google-key"] = process.env.GOOGLE_API_KEY;
371
371
  }
372
+ const mnxPayload = {
373
+ subject_id: subjectId,
374
+ chat_id: chatId,
375
+ history: mnxOptions.history ?? true,
376
+ learn: mnxOptions.learn ?? true,
377
+ recall: mnxOptions.recall ?? true,
378
+ profile: mnxOptions.profile ?? true,
379
+ summarize: mnxOptions.summarize ?? "balanced"
380
+ };
381
+ if (mnxOptions.system_prompt_id) {
382
+ mnxPayload.system_prompt_id = mnxOptions.system_prompt_id;
383
+ }
372
384
  const mnexiumBody = {
373
385
  model,
374
386
  messages: [{ role: "user", content: message }],
375
387
  stream: true,
376
- mnx: {
377
- subject_id: subjectId,
378
- chat_id: chatId,
379
- history: mnxOptions.history ?? true,
380
- learn: mnxOptions.learn ?? true,
381
- recall: mnxOptions.recall ?? true,
382
- profile: mnxOptions.profile ?? true,
383
- summarize: mnxOptions.summarize ?? "balanced"
384
- }
388
+ mnx: mnxPayload
385
389
  };
386
390
  let upstreamRes;
387
391
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/index.ts","../../src/server/bootstrap.ts","../../src/server/providers/openai.ts","../../src/server/providers/anthropic.ts","../../src/server/providers/google.ts","../../src/server/providers/types.ts","../../src/server/providers/normalizer.ts","../../src/server/chat.ts","../../src/server/history.ts","../../src/server/factory.ts"],"sourcesContent":["export { bootstrapHandler, newChatHandler, type BootstrapResponse, type BootstrapOptions } from './bootstrap';\nexport { chatHandler, type ChatOptions } from './chat';\nexport { historyHandler, conversationHandler, type HistoryOptions, type ConversationOptions } from './history';\nexport { createHandlers, type MnexiumHandlersConfig, type MnexiumHandlers } from './factory';\n","const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 180; // 180 days\n\nexport interface BootstrapResponse {\n subject_id: string;\n chat_id: string;\n}\n\nexport interface BootstrapOptions {\n cookiePrefix?: string;\n}\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback using crypto.getRandomValues\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n \n // Set version (4) and variant (RFC4122)\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n \n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nfunction createCookie(name: string, value: string, secure: boolean = true): string {\n const parts = [\n `${name}=${encodeURIComponent(value)}`,\n `Max-Age=${COOKIE_MAX_AGE}`,\n 'Path=/',\n 'HttpOnly',\n 'SameSite=Lax',\n ];\n if (secure) parts.push('Secure');\n return parts.join('; ');\n}\n\nexport async function bootstrapHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n let chatId = cookies[chatCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = generateUUID();\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Get or generate chat_id\n if (!chatId) {\n const apiKey = process.env.MNX_API_KEY;\n \n if (apiKey) {\n try {\n // Try to get existing chat history\n const historyRes = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n // Use most recent chat if available\n if (historyData.chats && historyData.chats.length > 0) {\n chatId = historyData.chats[0].chat_id;\n }\n }\n } catch (err) {\n console.error('Failed to fetch chat history:', err);\n }\n }\n\n // Generate new chat_id if none found\n if (!chatId) {\n chatId = generateUUID();\n }\n \n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n }\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport async function newChatHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = generateUUID();\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Always generate a new chat_id\n const chatId = generateUUID();\n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport default bootstrapHandler;\n","/**\n * OpenAI streaming format parser\n * Format: data: {\"choices\":[{\"delta\":{\"content\":\"text\"}}]}\n */\n\nexport function parseOpenAIChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n return parsed.choices?.[0]?.delta?.content || null;\n } catch {\n return null;\n }\n}\n\nexport function isOpenAIFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'choices' in parsed;\n } catch {\n return false;\n }\n}\n","/**\n * Anthropic streaming format parser\n * Format: data: {\"type\":\"content_block_delta\",\"delta\":{\"type\":\"text_delta\",\"text\":\"content\"}}\n */\n\nexport function parseAnthropicChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle content_block_delta events\n if (parsed.type === 'content_block_delta' && parsed.delta?.type === 'text_delta') {\n return parsed.delta.text || null;\n }\n \n // Handle message_delta for stop events\n if (parsed.type === 'message_delta') {\n return null;\n }\n \n // Handle message_start, content_block_start, etc.\n return null;\n } catch {\n return null;\n }\n}\n\nexport function isAnthropicFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'type' in parsed && (\n parsed.type === 'message_start' ||\n parsed.type === 'content_block_start' ||\n parsed.type === 'content_block_delta' ||\n parsed.type === 'content_block_stop' ||\n parsed.type === 'message_delta' ||\n parsed.type === 'message_stop'\n );\n } catch {\n return false;\n }\n}\n","/**\n * Google Gemini streaming format parser\n * Format: data: {\"candidates\":[{\"content\":{\"parts\":[{\"text\":\"content\"}]}}]}\n */\n\nexport function parseGoogleChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle Gemini format\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) return text;\n \n return null;\n } catch {\n return null;\n }\n}\n\nexport function isGoogleFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'candidates' in parsed;\n } catch {\n return false;\n }\n}\n","export interface StreamChunk {\n content: string;\n done: boolean;\n}\n\nexport type ProviderType = 'openai' | 'anthropic' | 'google';\n\nexport function detectProvider(model: string): ProviderType {\n const lowerModel = model.toLowerCase();\n \n if (lowerModel.includes('claude')) {\n return 'anthropic';\n }\n \n if (lowerModel.includes('gemini')) {\n return 'google';\n }\n \n return 'openai';\n}\n","/**\n * Stream normalizer - converts all provider formats to OpenAI-compatible SSE\n * This ensures the client only needs to handle one format\n */\n\nimport { parseOpenAIChunk, isOpenAIFormat } from './openai';\nimport { parseAnthropicChunk, isAnthropicFormat } from './anthropic';\nimport { parseGoogleChunk, isGoogleFormat } from './google';\nimport { detectProvider, type ProviderType } from './types';\n\n/**\n * Parse a chunk from any provider and extract the content\n */\nexport function parseChunk(data: string, provider?: ProviderType): string | null {\n if (data === '[DONE]') return null;\n \n // If provider is specified, use that parser\n if (provider === 'anthropic') {\n return parseAnthropicChunk(data);\n }\n if (provider === 'google') {\n return parseGoogleChunk(data);\n }\n if (provider === 'openai') {\n return parseOpenAIChunk(data);\n }\n \n // Auto-detect format\n if (isOpenAIFormat(data)) {\n return parseOpenAIChunk(data);\n }\n if (isAnthropicFormat(data)) {\n return parseAnthropicChunk(data);\n }\n if (isGoogleFormat(data)) {\n return parseGoogleChunk(data);\n }\n \n return null;\n}\n\n/**\n * Convert content to OpenAI-compatible SSE format\n */\nexport function toOpenAIFormat(content: string): string {\n const chunk = {\n choices: [{\n delta: { content },\n index: 0,\n finish_reason: null,\n }],\n };\n return `data: ${JSON.stringify(chunk)}\\n\\n`;\n}\n\n/**\n * Create a transform stream that normalizes any provider format to OpenAI format\n */\nexport function createNormalizerStream(model: string): TransformStream<Uint8Array, Uint8Array> {\n const provider = detectProvider(model);\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = '';\n\n return new TransformStream({\n transform(chunk, controller) {\n buffer += decoder.decode(chunk, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n \n if (data === '[DONE]') {\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n continue;\n }\n\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n } else if (line.startsWith('event: ')) {\n // Skip event lines (Anthropic uses these)\n continue;\n }\n }\n },\n flush(controller) {\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6).trim();\n if (data && data !== '[DONE]') {\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n }\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n },\n });\n}\n","import { createNormalizerStream } from './providers';\n\nconst MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nexport interface ChatOptions {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n };\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport async function chatHandler(\n req: Request,\n options: ChatOptions = {}\n): Promise<Response> {\n const {\n model = 'gpt-4o-mini',\n cookiePrefix = 'mnx',\n mnxOptions = {\n history: true,\n learn: true,\n recall: true,\n profile: true,\n summarize: 'balanced',\n },\n } = options;\n\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n // Parse cookies\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n const subjectId = cookies[subjectCookieName];\n const chatId = cookies[chatCookieName];\n\n if (!subjectId || !chatId) {\n return new Response(\n JSON.stringify({ error: 'Missing session cookies. Call /bootstrap first.' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Parse request body\n let body: { message?: string };\n try {\n body = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const { message } = body;\n if (!message || typeof message !== 'string') {\n return new Response(\n JSON.stringify({ error: 'Missing or invalid message field' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Get API keys from environment\n const mnxApiKey = process.env.MNX_API_KEY;\n if (!mnxApiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Build headers for Mnexium API\n const headers: HeadersInit = {\n 'Authorization': `Bearer ${mnxApiKey}`,\n 'Content-Type': 'application/json',\n };\n\n // Add provider API keys if available\n if (process.env.OPENAI_API_KEY) {\n headers['x-openai-key'] = process.env.OPENAI_API_KEY;\n }\n if (process.env.ANTHROPIC_API_KEY) {\n headers['x-anthropic-key'] = process.env.ANTHROPIC_API_KEY;\n }\n if (process.env.GOOGLE_API_KEY) {\n headers['x-google-key'] = process.env.GOOGLE_API_KEY;\n }\n\n // Build request body for Mnexium\n const mnexiumBody = {\n model,\n messages: [{ role: 'user', content: message }],\n stream: true,\n mnx: {\n subject_id: subjectId,\n chat_id: chatId,\n history: mnxOptions.history ?? true,\n learn: mnxOptions.learn ?? true,\n recall: mnxOptions.recall ?? true,\n profile: mnxOptions.profile ?? true,\n summarize: mnxOptions.summarize ?? 'balanced',\n },\n };\n\n // Forward request to Mnexium\n let upstreamRes: Response;\n try {\n upstreamRes = await fetch(`${MNEXIUM_API_BASE}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(mnexiumBody),\n });\n } catch (err) {\n console.error('Mnexium API error:', err);\n return new Response(\n JSON.stringify({ error: 'Failed to connect to Mnexium API' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n if (!upstreamRes.ok) {\n const errorText = await upstreamRes.text();\n console.error('Mnexium API error:', upstreamRes.status, errorText);\n return new Response(\n JSON.stringify({ error: 'Mnexium API error', details: errorText }),\n { status: upstreamRes.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Stream the response back to client without buffering\n if (!upstreamRes.body) {\n return new Response(\n JSON.stringify({ error: 'No response body from Mnexium' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Normalize the stream to OpenAI format (handles Anthropic, Google, etc.)\n const normalizedStream = upstreamRes.body.pipeThrough(createNormalizerStream(model));\n\n return new Response(normalizedStream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n });\n}\n\nexport default chatHandler;\n","const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport interface HistoryOptions {\n cookiePrefix?: string;\n}\n\nexport async function historyHandler(\n req: Request,\n options: HistoryOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const res = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium history error:', res.status, errorText);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response to our format\n const conversations = (data.chats || []).map((chat: { chat_id: string; title?: string; updated_at?: string; created_at?: string }) => ({\n id: chat.chat_id,\n title: chat.title || 'Untitled conversation',\n updated_at: chat.updated_at || chat.created_at || new Date().toISOString(),\n }));\n\n return new Response(\n JSON.stringify({ conversations }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch history:', err);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport interface ConversationOptions {\n cookiePrefix?: string;\n}\n\nexport async function conversationHandler(\n req: Request,\n chatId: string,\n options: ConversationOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const url = `${MNEXIUM_API_BASE}/chat/history/read?chat_id=${chatId}&subject_id=${subjectId}&limit=200`;\n const res = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium conversation error:', res.status, errorText);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response - filter to only user and assistant messages\n // The API may return messages directly or nested under a key\n const rawMessages = data.messages || data.history || data || [];\n const messagesArray = Array.isArray(rawMessages) ? rawMessages : [];\n \n const messages = messagesArray\n .filter((m: { role: string }) => m.role === 'user' || m.role === 'assistant')\n .map((m: { role: string; message?: string; content?: string }) => ({\n role: m.role,\n content: m.message || m.content || '',\n }))\n .filter((m: { content: string }) => m.content);\n\n return new Response(\n JSON.stringify({ messages }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch conversation:', err);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport default { historyHandler, conversationHandler };\n","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler, type HistoryOptions, type ConversationOptions } from './history';\n\nexport interface MnexiumHandlersConfig {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n };\n}\n\nexport interface MnexiumHandlers {\n bootstrap: (req: Request) => Promise<Response>;\n chat: (req: Request) => Promise<Response>;\n newChat: (req: Request) => Promise<Response>;\n history: (req: Request) => Promise<Response>;\n conversation: (req: Request, chatId: string) => Promise<Response>;\n}\n\n/**\n * Creates a set of configured handlers for Mnexium chat endpoints.\n * This allows you to define your configuration once and reuse it across all routes.\n * \n * @example\n * ```ts\n * // lib/mnx.ts\n * import { createHandlers } from '@mnexium/chat-react/server';\n * \n * export const mnx = createHandlers({\n * model: 'gpt-4o',\n * cookiePrefix: 'mnx',\n * mnxOptions: {\n * history: true,\n * learn: true,\n * recall: true,\n * },\n * });\n * \n * // app/api/mnx/chat/route.ts\n * import { mnx } from '@/lib/mnx';\n * export const POST = mnx.chat;\n * ```\n */\nexport function createHandlers(config: MnexiumHandlersConfig = {}): MnexiumHandlers {\n const { model, cookiePrefix, mnxOptions } = config;\n\n const bootstrapOpts: BootstrapOptions = { cookiePrefix };\n const chatOpts: ChatOptions = { model, cookiePrefix, mnxOptions };\n const historyOpts: HistoryOptions = { cookiePrefix };\n const conversationOpts: ConversationOptions = { cookiePrefix };\n\n return {\n bootstrap: (req: Request) => bootstrapHandler(req, bootstrapOpts),\n chat: (req: Request) => chatHandler(req, chatOpts),\n newChat: (req: Request) => newChatHandler(req, bootstrapOpts),\n history: (req: Request) => historyHandler(req, historyOpts),\n conversation: (req: Request, chatId: string) => conversationHandler(req, chatId, conversationOpts),\n };\n}\n\nexport default createHandlers;\n"],"mappings":"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","names":["MNEXIUM_API_BASE","parseCookies","MNEXIUM_API_BASE","parseCookies"]}
1
+ {"version":3,"sources":["../../src/server/index.ts","../../src/server/bootstrap.ts","../../src/server/providers/openai.ts","../../src/server/providers/anthropic.ts","../../src/server/providers/google.ts","../../src/server/providers/types.ts","../../src/server/providers/normalizer.ts","../../src/server/chat.ts","../../src/server/history.ts","../../src/server/factory.ts"],"sourcesContent":["export { bootstrapHandler, newChatHandler, type BootstrapResponse, type BootstrapOptions } from './bootstrap';\nexport { chatHandler, type ChatOptions } from './chat';\nexport { historyHandler, conversationHandler, type HistoryOptions, type ConversationOptions } from './history';\nexport { createHandlers, type MnexiumHandlersConfig, type MnexiumHandlers } from './factory';\n","const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 180; // 180 days\n\nexport interface BootstrapResponse {\n subject_id: string;\n chat_id: string;\n}\n\nexport interface BootstrapOptions {\n cookiePrefix?: string;\n}\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback using crypto.getRandomValues\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n \n // Set version (4) and variant (RFC4122)\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n \n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nfunction createCookie(name: string, value: string, secure: boolean = true): string {\n const parts = [\n `${name}=${encodeURIComponent(value)}`,\n `Max-Age=${COOKIE_MAX_AGE}`,\n 'Path=/',\n 'HttpOnly',\n 'SameSite=Lax',\n ];\n if (secure) parts.push('Secure');\n return parts.join('; ');\n}\n\nexport async function bootstrapHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n let chatId = cookies[chatCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = `mnx_em_${generateUUID()}`;\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Get or generate chat_id\n if (!chatId) {\n const apiKey = process.env.MNX_API_KEY;\n \n if (apiKey) {\n try {\n // Try to get existing chat history\n const historyRes = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n // Use most recent chat if available\n if (historyData.chats && historyData.chats.length > 0) {\n chatId = historyData.chats[0].chat_id;\n }\n }\n } catch (err) {\n console.error('Failed to fetch chat history:', err);\n }\n }\n\n // Generate new chat_id if none found\n if (!chatId) {\n chatId = generateUUID();\n }\n \n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n }\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport async function newChatHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = generateUUID();\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Always generate a new chat_id\n const chatId = generateUUID();\n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport default bootstrapHandler;\n","/**\n * OpenAI streaming format parser\n * Format: data: {\"choices\":[{\"delta\":{\"content\":\"text\"}}]}\n */\n\nexport function parseOpenAIChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n return parsed.choices?.[0]?.delta?.content || null;\n } catch {\n return null;\n }\n}\n\nexport function isOpenAIFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'choices' in parsed;\n } catch {\n return false;\n }\n}\n","/**\n * Anthropic streaming format parser\n * Format: data: {\"type\":\"content_block_delta\",\"delta\":{\"type\":\"text_delta\",\"text\":\"content\"}}\n */\n\nexport function parseAnthropicChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle content_block_delta events\n if (parsed.type === 'content_block_delta' && parsed.delta?.type === 'text_delta') {\n return parsed.delta.text || null;\n }\n \n // Handle message_delta for stop events\n if (parsed.type === 'message_delta') {\n return null;\n }\n \n // Handle message_start, content_block_start, etc.\n return null;\n } catch {\n return null;\n }\n}\n\nexport function isAnthropicFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'type' in parsed && (\n parsed.type === 'message_start' ||\n parsed.type === 'content_block_start' ||\n parsed.type === 'content_block_delta' ||\n parsed.type === 'content_block_stop' ||\n parsed.type === 'message_delta' ||\n parsed.type === 'message_stop'\n );\n } catch {\n return false;\n }\n}\n","/**\n * Google Gemini streaming format parser\n * Format: data: {\"candidates\":[{\"content\":{\"parts\":[{\"text\":\"content\"}]}}]}\n */\n\nexport function parseGoogleChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle Gemini format\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) return text;\n \n return null;\n } catch {\n return null;\n }\n}\n\nexport function isGoogleFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'candidates' in parsed;\n } catch {\n return false;\n }\n}\n","export interface StreamChunk {\n content: string;\n done: boolean;\n}\n\nexport type ProviderType = 'openai' | 'anthropic' | 'google';\n\nexport function detectProvider(model: string): ProviderType {\n const lowerModel = model.toLowerCase();\n \n if (lowerModel.includes('claude')) {\n return 'anthropic';\n }\n \n if (lowerModel.includes('gemini')) {\n return 'google';\n }\n \n return 'openai';\n}\n","/**\n * Stream normalizer - converts all provider formats to OpenAI-compatible SSE\n * This ensures the client only needs to handle one format\n */\n\nimport { parseOpenAIChunk, isOpenAIFormat } from './openai';\nimport { parseAnthropicChunk, isAnthropicFormat } from './anthropic';\nimport { parseGoogleChunk, isGoogleFormat } from './google';\nimport { detectProvider, type ProviderType } from './types';\n\n/**\n * Parse a chunk from any provider and extract the content\n */\nexport function parseChunk(data: string, provider?: ProviderType): string | null {\n if (data === '[DONE]') return null;\n \n // If provider is specified, use that parser\n if (provider === 'anthropic') {\n return parseAnthropicChunk(data);\n }\n if (provider === 'google') {\n return parseGoogleChunk(data);\n }\n if (provider === 'openai') {\n return parseOpenAIChunk(data);\n }\n \n // Auto-detect format\n if (isOpenAIFormat(data)) {\n return parseOpenAIChunk(data);\n }\n if (isAnthropicFormat(data)) {\n return parseAnthropicChunk(data);\n }\n if (isGoogleFormat(data)) {\n return parseGoogleChunk(data);\n }\n \n return null;\n}\n\n/**\n * Convert content to OpenAI-compatible SSE format\n */\nexport function toOpenAIFormat(content: string): string {\n const chunk = {\n choices: [{\n delta: { content },\n index: 0,\n finish_reason: null,\n }],\n };\n return `data: ${JSON.stringify(chunk)}\\n\\n`;\n}\n\n/**\n * Create a transform stream that normalizes any provider format to OpenAI format\n */\nexport function createNormalizerStream(model: string): TransformStream<Uint8Array, Uint8Array> {\n const provider = detectProvider(model);\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = '';\n\n return new TransformStream({\n transform(chunk, controller) {\n buffer += decoder.decode(chunk, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n \n if (data === '[DONE]') {\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n continue;\n }\n\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n } else if (line.startsWith('event: ')) {\n // Skip event lines (Anthropic uses these)\n continue;\n }\n }\n },\n flush(controller) {\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6).trim();\n if (data && data !== '[DONE]') {\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n }\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n },\n });\n}\n","import { createNormalizerStream } from './providers';\n\nconst MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nexport interface ChatOptions {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n system_prompt_id?: string;\n };\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport async function chatHandler(\n req: Request,\n options: ChatOptions = {}\n): Promise<Response> {\n const {\n model = 'gpt-4o-mini',\n cookiePrefix = 'mnx',\n mnxOptions = {\n history: true,\n learn: true,\n recall: true,\n profile: true,\n summarize: 'balanced',\n },\n } = options;\n\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n // Parse cookies\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n const subjectId = cookies[subjectCookieName];\n const chatId = cookies[chatCookieName];\n\n if (!subjectId || !chatId) {\n return new Response(\n JSON.stringify({ error: 'Missing session cookies. Call /bootstrap first.' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Parse request body\n let body: { message?: string };\n try {\n body = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const { message } = body;\n if (!message || typeof message !== 'string') {\n return new Response(\n JSON.stringify({ error: 'Missing or invalid message field' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Get API keys from environment\n const mnxApiKey = process.env.MNX_API_KEY;\n if (!mnxApiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Build headers for Mnexium API\n const headers: HeadersInit = {\n 'Authorization': `Bearer ${mnxApiKey}`,\n 'Content-Type': 'application/json',\n };\n\n // Add provider API keys if available\n if (process.env.OPENAI_API_KEY) {\n headers['x-openai-key'] = process.env.OPENAI_API_KEY;\n }\n if (process.env.ANTHROPIC_API_KEY) {\n headers['x-anthropic-key'] = process.env.ANTHROPIC_API_KEY;\n }\n if (process.env.GOOGLE_API_KEY) {\n headers['x-google-key'] = process.env.GOOGLE_API_KEY;\n }\n\n // Build request body for Mnexium\n const mnxPayload: Record<string, unknown> = {\n subject_id: subjectId,\n chat_id: chatId,\n history: mnxOptions.history ?? true,\n learn: mnxOptions.learn ?? true,\n recall: mnxOptions.recall ?? true,\n profile: mnxOptions.profile ?? true,\n summarize: mnxOptions.summarize ?? 'balanced',\n };\n\n // Add system_prompt_id if provided\n if (mnxOptions.system_prompt_id) {\n mnxPayload.system_prompt_id = mnxOptions.system_prompt_id;\n }\n\n const mnexiumBody = {\n model,\n messages: [{ role: 'user', content: message }],\n stream: true,\n mnx: mnxPayload,\n };\n\n // Forward request to Mnexium\n let upstreamRes: Response;\n try {\n upstreamRes = await fetch(`${MNEXIUM_API_BASE}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(mnexiumBody),\n });\n } catch (err) {\n console.error('Mnexium API error:', err);\n return new Response(\n JSON.stringify({ error: 'Failed to connect to Mnexium API' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n if (!upstreamRes.ok) {\n const errorText = await upstreamRes.text();\n console.error('Mnexium API error:', upstreamRes.status, errorText);\n return new Response(\n JSON.stringify({ error: 'Mnexium API error', details: errorText }),\n { status: upstreamRes.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Stream the response back to client without buffering\n if (!upstreamRes.body) {\n return new Response(\n JSON.stringify({ error: 'No response body from Mnexium' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Normalize the stream to OpenAI format (handles Anthropic, Google, etc.)\n const normalizedStream = upstreamRes.body.pipeThrough(createNormalizerStream(model));\n\n return new Response(normalizedStream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n });\n}\n\nexport default chatHandler;\n","const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport interface HistoryOptions {\n cookiePrefix?: string;\n}\n\nexport async function historyHandler(\n req: Request,\n options: HistoryOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const res = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium history error:', res.status, errorText);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response to our format\n const conversations = (data.chats || []).map((chat: { chat_id: string; title?: string; updated_at?: string; created_at?: string }) => ({\n id: chat.chat_id,\n title: chat.title || 'Untitled conversation',\n updated_at: chat.updated_at || chat.created_at || new Date().toISOString(),\n }));\n\n return new Response(\n JSON.stringify({ conversations }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch history:', err);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport interface ConversationOptions {\n cookiePrefix?: string;\n}\n\nexport async function conversationHandler(\n req: Request,\n chatId: string,\n options: ConversationOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const url = `${MNEXIUM_API_BASE}/chat/history/read?chat_id=${chatId}&subject_id=${subjectId}&limit=200`;\n const res = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium conversation error:', res.status, errorText);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response - filter to only user and assistant messages\n // The API may return messages directly or nested under a key\n const rawMessages = data.messages || data.history || data || [];\n const messagesArray = Array.isArray(rawMessages) ? rawMessages : [];\n \n const messages = messagesArray\n .filter((m: { role: string }) => m.role === 'user' || m.role === 'assistant')\n .map((m: { role: string; message?: string; content?: string }) => ({\n role: m.role,\n content: m.message || m.content || '',\n }))\n .filter((m: { content: string }) => m.content);\n\n return new Response(\n JSON.stringify({ messages }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch conversation:', err);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport default { historyHandler, conversationHandler };\n","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler, type HistoryOptions, type ConversationOptions } from './history';\n\nexport interface MnexiumHandlersConfig {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n system_prompt_id?: string;\n };\n}\n\nexport interface MnexiumHandlers {\n bootstrap: (req: Request) => Promise<Response>;\n chat: (req: Request) => Promise<Response>;\n newChat: (req: Request) => Promise<Response>;\n history: (req: Request) => Promise<Response>;\n conversation: (req: Request, chatId: string) => Promise<Response>;\n}\n\n/**\n * Creates a set of configured handlers for Mnexium chat endpoints.\n * This allows you to define your configuration once and reuse it across all routes.\n * \n * @example\n * ```ts\n * // lib/mnx.ts\n * import { createHandlers } from '@mnexium/chat-react/server';\n * \n * export const mnx = createHandlers({\n * model: 'gpt-4o',\n * cookiePrefix: 'mnx',\n * mnxOptions: {\n * history: true,\n * learn: true,\n * recall: true,\n * },\n * });\n * \n * // app/api/mnx/chat/route.ts\n * import { mnx } from '@/lib/mnx';\n * export const POST = mnx.chat;\n * ```\n */\nexport function createHandlers(config: MnexiumHandlersConfig = {}): MnexiumHandlers {\n const { model, cookiePrefix, mnxOptions } = config;\n\n const bootstrapOpts: BootstrapOptions = { cookiePrefix };\n const chatOpts: ChatOptions = { model, cookiePrefix, mnxOptions };\n const historyOpts: HistoryOptions = { cookiePrefix };\n const conversationOpts: ConversationOptions = { cookiePrefix };\n\n return {\n bootstrap: (req: Request) => bootstrapHandler(req, bootstrapOpts),\n chat: (req: Request) => chatHandler(req, chatOpts),\n newChat: (req: Request) => newChatHandler(req, bootstrapOpts),\n history: (req: Request) => historyHandler(req, historyOpts),\n conversation: (req: Request, chatId: string) => conversationHandler(req, chatId, conversationOpts),\n };\n}\n\nexport default createHandlers;\n"],"mappings":"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","names":["MNEXIUM_API_BASE","parseCookies","MNEXIUM_API_BASE","parseCookies"]}
@@ -42,7 +42,7 @@ async function bootstrapHandler(req, options = {}) {
42
42
  const setCookies = [];
43
43
  const isSecure = req.url.startsWith("https://") || req.headers.get("x-forwarded-proto") === "https";
44
44
  if (!subjectId) {
45
- subjectId = generateUUID();
45
+ subjectId = `mnx_em_${generateUUID()}`;
46
46
  setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));
47
47
  }
48
48
  if (!chatId) {
@@ -338,19 +338,23 @@ async function chatHandler(req, options = {}) {
338
338
  if (process.env.GOOGLE_API_KEY) {
339
339
  headers["x-google-key"] = process.env.GOOGLE_API_KEY;
340
340
  }
341
+ const mnxPayload = {
342
+ subject_id: subjectId,
343
+ chat_id: chatId,
344
+ history: mnxOptions.history ?? true,
345
+ learn: mnxOptions.learn ?? true,
346
+ recall: mnxOptions.recall ?? true,
347
+ profile: mnxOptions.profile ?? true,
348
+ summarize: mnxOptions.summarize ?? "balanced"
349
+ };
350
+ if (mnxOptions.system_prompt_id) {
351
+ mnxPayload.system_prompt_id = mnxOptions.system_prompt_id;
352
+ }
341
353
  const mnexiumBody = {
342
354
  model,
343
355
  messages: [{ role: "user", content: message }],
344
356
  stream: true,
345
- mnx: {
346
- subject_id: subjectId,
347
- chat_id: chatId,
348
- history: mnxOptions.history ?? true,
349
- learn: mnxOptions.learn ?? true,
350
- recall: mnxOptions.recall ?? true,
351
- profile: mnxOptions.profile ?? true,
352
- summarize: mnxOptions.summarize ?? "balanced"
353
- }
357
+ mnx: mnxPayload
354
358
  };
355
359
  let upstreamRes;
356
360
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/bootstrap.ts","../../src/server/providers/openai.ts","../../src/server/providers/anthropic.ts","../../src/server/providers/google.ts","../../src/server/providers/types.ts","../../src/server/providers/normalizer.ts","../../src/server/chat.ts","../../src/server/history.ts","../../src/server/factory.ts"],"sourcesContent":["const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 180; // 180 days\n\nexport interface BootstrapResponse {\n subject_id: string;\n chat_id: string;\n}\n\nexport interface BootstrapOptions {\n cookiePrefix?: string;\n}\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback using crypto.getRandomValues\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n \n // Set version (4) and variant (RFC4122)\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n \n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nfunction createCookie(name: string, value: string, secure: boolean = true): string {\n const parts = [\n `${name}=${encodeURIComponent(value)}`,\n `Max-Age=${COOKIE_MAX_AGE}`,\n 'Path=/',\n 'HttpOnly',\n 'SameSite=Lax',\n ];\n if (secure) parts.push('Secure');\n return parts.join('; ');\n}\n\nexport async function bootstrapHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n let chatId = cookies[chatCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = generateUUID();\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Get or generate chat_id\n if (!chatId) {\n const apiKey = process.env.MNX_API_KEY;\n \n if (apiKey) {\n try {\n // Try to get existing chat history\n const historyRes = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n // Use most recent chat if available\n if (historyData.chats && historyData.chats.length > 0) {\n chatId = historyData.chats[0].chat_id;\n }\n }\n } catch (err) {\n console.error('Failed to fetch chat history:', err);\n }\n }\n\n // Generate new chat_id if none found\n if (!chatId) {\n chatId = generateUUID();\n }\n \n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n }\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport async function newChatHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = generateUUID();\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Always generate a new chat_id\n const chatId = generateUUID();\n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport default bootstrapHandler;\n","/**\n * OpenAI streaming format parser\n * Format: data: {\"choices\":[{\"delta\":{\"content\":\"text\"}}]}\n */\n\nexport function parseOpenAIChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n return parsed.choices?.[0]?.delta?.content || null;\n } catch {\n return null;\n }\n}\n\nexport function isOpenAIFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'choices' in parsed;\n } catch {\n return false;\n }\n}\n","/**\n * Anthropic streaming format parser\n * Format: data: {\"type\":\"content_block_delta\",\"delta\":{\"type\":\"text_delta\",\"text\":\"content\"}}\n */\n\nexport function parseAnthropicChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle content_block_delta events\n if (parsed.type === 'content_block_delta' && parsed.delta?.type === 'text_delta') {\n return parsed.delta.text || null;\n }\n \n // Handle message_delta for stop events\n if (parsed.type === 'message_delta') {\n return null;\n }\n \n // Handle message_start, content_block_start, etc.\n return null;\n } catch {\n return null;\n }\n}\n\nexport function isAnthropicFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'type' in parsed && (\n parsed.type === 'message_start' ||\n parsed.type === 'content_block_start' ||\n parsed.type === 'content_block_delta' ||\n parsed.type === 'content_block_stop' ||\n parsed.type === 'message_delta' ||\n parsed.type === 'message_stop'\n );\n } catch {\n return false;\n }\n}\n","/**\n * Google Gemini streaming format parser\n * Format: data: {\"candidates\":[{\"content\":{\"parts\":[{\"text\":\"content\"}]}}]}\n */\n\nexport function parseGoogleChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle Gemini format\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) return text;\n \n return null;\n } catch {\n return null;\n }\n}\n\nexport function isGoogleFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'candidates' in parsed;\n } catch {\n return false;\n }\n}\n","export interface StreamChunk {\n content: string;\n done: boolean;\n}\n\nexport type ProviderType = 'openai' | 'anthropic' | 'google';\n\nexport function detectProvider(model: string): ProviderType {\n const lowerModel = model.toLowerCase();\n \n if (lowerModel.includes('claude')) {\n return 'anthropic';\n }\n \n if (lowerModel.includes('gemini')) {\n return 'google';\n }\n \n return 'openai';\n}\n","/**\n * Stream normalizer - converts all provider formats to OpenAI-compatible SSE\n * This ensures the client only needs to handle one format\n */\n\nimport { parseOpenAIChunk, isOpenAIFormat } from './openai';\nimport { parseAnthropicChunk, isAnthropicFormat } from './anthropic';\nimport { parseGoogleChunk, isGoogleFormat } from './google';\nimport { detectProvider, type ProviderType } from './types';\n\n/**\n * Parse a chunk from any provider and extract the content\n */\nexport function parseChunk(data: string, provider?: ProviderType): string | null {\n if (data === '[DONE]') return null;\n \n // If provider is specified, use that parser\n if (provider === 'anthropic') {\n return parseAnthropicChunk(data);\n }\n if (provider === 'google') {\n return parseGoogleChunk(data);\n }\n if (provider === 'openai') {\n return parseOpenAIChunk(data);\n }\n \n // Auto-detect format\n if (isOpenAIFormat(data)) {\n return parseOpenAIChunk(data);\n }\n if (isAnthropicFormat(data)) {\n return parseAnthropicChunk(data);\n }\n if (isGoogleFormat(data)) {\n return parseGoogleChunk(data);\n }\n \n return null;\n}\n\n/**\n * Convert content to OpenAI-compatible SSE format\n */\nexport function toOpenAIFormat(content: string): string {\n const chunk = {\n choices: [{\n delta: { content },\n index: 0,\n finish_reason: null,\n }],\n };\n return `data: ${JSON.stringify(chunk)}\\n\\n`;\n}\n\n/**\n * Create a transform stream that normalizes any provider format to OpenAI format\n */\nexport function createNormalizerStream(model: string): TransformStream<Uint8Array, Uint8Array> {\n const provider = detectProvider(model);\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = '';\n\n return new TransformStream({\n transform(chunk, controller) {\n buffer += decoder.decode(chunk, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n \n if (data === '[DONE]') {\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n continue;\n }\n\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n } else if (line.startsWith('event: ')) {\n // Skip event lines (Anthropic uses these)\n continue;\n }\n }\n },\n flush(controller) {\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6).trim();\n if (data && data !== '[DONE]') {\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n }\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n },\n });\n}\n","import { createNormalizerStream } from './providers';\n\nconst MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nexport interface ChatOptions {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n };\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport async function chatHandler(\n req: Request,\n options: ChatOptions = {}\n): Promise<Response> {\n const {\n model = 'gpt-4o-mini',\n cookiePrefix = 'mnx',\n mnxOptions = {\n history: true,\n learn: true,\n recall: true,\n profile: true,\n summarize: 'balanced',\n },\n } = options;\n\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n // Parse cookies\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n const subjectId = cookies[subjectCookieName];\n const chatId = cookies[chatCookieName];\n\n if (!subjectId || !chatId) {\n return new Response(\n JSON.stringify({ error: 'Missing session cookies. Call /bootstrap first.' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Parse request body\n let body: { message?: string };\n try {\n body = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const { message } = body;\n if (!message || typeof message !== 'string') {\n return new Response(\n JSON.stringify({ error: 'Missing or invalid message field' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Get API keys from environment\n const mnxApiKey = process.env.MNX_API_KEY;\n if (!mnxApiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Build headers for Mnexium API\n const headers: HeadersInit = {\n 'Authorization': `Bearer ${mnxApiKey}`,\n 'Content-Type': 'application/json',\n };\n\n // Add provider API keys if available\n if (process.env.OPENAI_API_KEY) {\n headers['x-openai-key'] = process.env.OPENAI_API_KEY;\n }\n if (process.env.ANTHROPIC_API_KEY) {\n headers['x-anthropic-key'] = process.env.ANTHROPIC_API_KEY;\n }\n if (process.env.GOOGLE_API_KEY) {\n headers['x-google-key'] = process.env.GOOGLE_API_KEY;\n }\n\n // Build request body for Mnexium\n const mnexiumBody = {\n model,\n messages: [{ role: 'user', content: message }],\n stream: true,\n mnx: {\n subject_id: subjectId,\n chat_id: chatId,\n history: mnxOptions.history ?? true,\n learn: mnxOptions.learn ?? true,\n recall: mnxOptions.recall ?? true,\n profile: mnxOptions.profile ?? true,\n summarize: mnxOptions.summarize ?? 'balanced',\n },\n };\n\n // Forward request to Mnexium\n let upstreamRes: Response;\n try {\n upstreamRes = await fetch(`${MNEXIUM_API_BASE}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(mnexiumBody),\n });\n } catch (err) {\n console.error('Mnexium API error:', err);\n return new Response(\n JSON.stringify({ error: 'Failed to connect to Mnexium API' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n if (!upstreamRes.ok) {\n const errorText = await upstreamRes.text();\n console.error('Mnexium API error:', upstreamRes.status, errorText);\n return new Response(\n JSON.stringify({ error: 'Mnexium API error', details: errorText }),\n { status: upstreamRes.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Stream the response back to client without buffering\n if (!upstreamRes.body) {\n return new Response(\n JSON.stringify({ error: 'No response body from Mnexium' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Normalize the stream to OpenAI format (handles Anthropic, Google, etc.)\n const normalizedStream = upstreamRes.body.pipeThrough(createNormalizerStream(model));\n\n return new Response(normalizedStream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n });\n}\n\nexport default chatHandler;\n","const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport interface HistoryOptions {\n cookiePrefix?: string;\n}\n\nexport async function historyHandler(\n req: Request,\n options: HistoryOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const res = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium history error:', res.status, errorText);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response to our format\n const conversations = (data.chats || []).map((chat: { chat_id: string; title?: string; updated_at?: string; created_at?: string }) => ({\n id: chat.chat_id,\n title: chat.title || 'Untitled conversation',\n updated_at: chat.updated_at || chat.created_at || new Date().toISOString(),\n }));\n\n return new Response(\n JSON.stringify({ conversations }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch history:', err);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport interface ConversationOptions {\n cookiePrefix?: string;\n}\n\nexport async function conversationHandler(\n req: Request,\n chatId: string,\n options: ConversationOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const url = `${MNEXIUM_API_BASE}/chat/history/read?chat_id=${chatId}&subject_id=${subjectId}&limit=200`;\n const res = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium conversation error:', res.status, errorText);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response - filter to only user and assistant messages\n // The API may return messages directly or nested under a key\n const rawMessages = data.messages || data.history || data || [];\n const messagesArray = Array.isArray(rawMessages) ? rawMessages : [];\n \n const messages = messagesArray\n .filter((m: { role: string }) => m.role === 'user' || m.role === 'assistant')\n .map((m: { role: string; message?: string; content?: string }) => ({\n role: m.role,\n content: m.message || m.content || '',\n }))\n .filter((m: { content: string }) => m.content);\n\n return new Response(\n JSON.stringify({ messages }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch conversation:', err);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport default { historyHandler, conversationHandler };\n","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler, type HistoryOptions, type ConversationOptions } from './history';\n\nexport interface MnexiumHandlersConfig {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n };\n}\n\nexport interface MnexiumHandlers {\n bootstrap: (req: Request) => Promise<Response>;\n chat: (req: Request) => Promise<Response>;\n newChat: (req: Request) => Promise<Response>;\n history: (req: Request) => Promise<Response>;\n conversation: (req: Request, chatId: string) => Promise<Response>;\n}\n\n/**\n * Creates a set of configured handlers for Mnexium chat endpoints.\n * This allows you to define your configuration once and reuse it across all routes.\n * \n * @example\n * ```ts\n * // lib/mnx.ts\n * import { createHandlers } from '@mnexium/chat-react/server';\n * \n * export const mnx = createHandlers({\n * model: 'gpt-4o',\n * cookiePrefix: 'mnx',\n * mnxOptions: {\n * history: true,\n * learn: true,\n * recall: true,\n * },\n * });\n * \n * // app/api/mnx/chat/route.ts\n * import { mnx } from '@/lib/mnx';\n * export const POST = mnx.chat;\n * ```\n */\nexport function createHandlers(config: MnexiumHandlersConfig = {}): MnexiumHandlers {\n const { model, cookiePrefix, mnxOptions } = config;\n\n const bootstrapOpts: BootstrapOptions = { cookiePrefix };\n const chatOpts: ChatOptions = { model, cookiePrefix, mnxOptions };\n const historyOpts: HistoryOptions = { cookiePrefix };\n const conversationOpts: ConversationOptions = { cookiePrefix };\n\n return {\n bootstrap: (req: Request) => bootstrapHandler(req, bootstrapOpts),\n chat: (req: Request) => chatHandler(req, chatOpts),\n newChat: (req: Request) => newChatHandler(req, bootstrapOpts),\n history: (req: Request) => historyHandler(req, historyOpts),\n conversation: (req: Request, chatId: string) => conversationHandler(req, chatId, conversationOpts),\n };\n}\n\nexport default createHandlers;\n"],"mappings":"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","names":["MNEXIUM_API_BASE","parseCookies","MNEXIUM_API_BASE","parseCookies"]}
1
+ {"version":3,"sources":["../../src/server/bootstrap.ts","../../src/server/providers/openai.ts","../../src/server/providers/anthropic.ts","../../src/server/providers/google.ts","../../src/server/providers/types.ts","../../src/server/providers/normalizer.ts","../../src/server/chat.ts","../../src/server/history.ts","../../src/server/factory.ts"],"sourcesContent":["const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 180; // 180 days\n\nexport interface BootstrapResponse {\n subject_id: string;\n chat_id: string;\n}\n\nexport interface BootstrapOptions {\n cookiePrefix?: string;\n}\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback using crypto.getRandomValues\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n \n // Set version (4) and variant (RFC4122)\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n \n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nfunction createCookie(name: string, value: string, secure: boolean = true): string {\n const parts = [\n `${name}=${encodeURIComponent(value)}`,\n `Max-Age=${COOKIE_MAX_AGE}`,\n 'Path=/',\n 'HttpOnly',\n 'SameSite=Lax',\n ];\n if (secure) parts.push('Secure');\n return parts.join('; ');\n}\n\nexport async function bootstrapHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n let chatId = cookies[chatCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = `mnx_em_${generateUUID()}`;\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Get or generate chat_id\n if (!chatId) {\n const apiKey = process.env.MNX_API_KEY;\n \n if (apiKey) {\n try {\n // Try to get existing chat history\n const historyRes = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (historyRes.ok) {\n const historyData = await historyRes.json();\n // Use most recent chat if available\n if (historyData.chats && historyData.chats.length > 0) {\n chatId = historyData.chats[0].chat_id;\n }\n }\n } catch (err) {\n console.error('Failed to fetch chat history:', err);\n }\n }\n\n // Generate new chat_id if none found\n if (!chatId) {\n chatId = generateUUID();\n }\n \n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n }\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport async function newChatHandler(\n req: Request,\n options: BootstrapOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n let subjectId = cookies[subjectCookieName];\n const setCookies: string[] = [];\n\n const isSecure = req.url.startsWith('https://') || \n req.headers.get('x-forwarded-proto') === 'https';\n\n // Generate subject_id if missing\n if (!subjectId) {\n subjectId = generateUUID();\n setCookies.push(createCookie(subjectCookieName, subjectId, isSecure));\n }\n\n // Always generate a new chat_id\n const chatId = generateUUID();\n setCookies.push(createCookie(chatCookieName, chatId, isSecure));\n\n const responseBody: BootstrapResponse = {\n subject_id: subjectId,\n chat_id: chatId,\n };\n\n const headers = new Headers({\n 'Content-Type': 'application/json',\n });\n\n for (const cookie of setCookies) {\n headers.append('Set-Cookie', cookie);\n }\n\n return new Response(JSON.stringify(responseBody), {\n status: 200,\n headers,\n });\n}\n\nexport default bootstrapHandler;\n","/**\n * OpenAI streaming format parser\n * Format: data: {\"choices\":[{\"delta\":{\"content\":\"text\"}}]}\n */\n\nexport function parseOpenAIChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n return parsed.choices?.[0]?.delta?.content || null;\n } catch {\n return null;\n }\n}\n\nexport function isOpenAIFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'choices' in parsed;\n } catch {\n return false;\n }\n}\n","/**\n * Anthropic streaming format parser\n * Format: data: {\"type\":\"content_block_delta\",\"delta\":{\"type\":\"text_delta\",\"text\":\"content\"}}\n */\n\nexport function parseAnthropicChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle content_block_delta events\n if (parsed.type === 'content_block_delta' && parsed.delta?.type === 'text_delta') {\n return parsed.delta.text || null;\n }\n \n // Handle message_delta for stop events\n if (parsed.type === 'message_delta') {\n return null;\n }\n \n // Handle message_start, content_block_start, etc.\n return null;\n } catch {\n return null;\n }\n}\n\nexport function isAnthropicFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'type' in parsed && (\n parsed.type === 'message_start' ||\n parsed.type === 'content_block_start' ||\n parsed.type === 'content_block_delta' ||\n parsed.type === 'content_block_stop' ||\n parsed.type === 'message_delta' ||\n parsed.type === 'message_stop'\n );\n } catch {\n return false;\n }\n}\n","/**\n * Google Gemini streaming format parser\n * Format: data: {\"candidates\":[{\"content\":{\"parts\":[{\"text\":\"content\"}]}}]}\n */\n\nexport function parseGoogleChunk(data: string): string | null {\n if (data === '[DONE]') return null;\n \n try {\n const parsed = JSON.parse(data);\n \n // Handle Gemini format\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) return text;\n \n return null;\n } catch {\n return null;\n }\n}\n\nexport function isGoogleFormat(data: string): boolean {\n try {\n const parsed = JSON.parse(data);\n return 'candidates' in parsed;\n } catch {\n return false;\n }\n}\n","export interface StreamChunk {\n content: string;\n done: boolean;\n}\n\nexport type ProviderType = 'openai' | 'anthropic' | 'google';\n\nexport function detectProvider(model: string): ProviderType {\n const lowerModel = model.toLowerCase();\n \n if (lowerModel.includes('claude')) {\n return 'anthropic';\n }\n \n if (lowerModel.includes('gemini')) {\n return 'google';\n }\n \n return 'openai';\n}\n","/**\n * Stream normalizer - converts all provider formats to OpenAI-compatible SSE\n * This ensures the client only needs to handle one format\n */\n\nimport { parseOpenAIChunk, isOpenAIFormat } from './openai';\nimport { parseAnthropicChunk, isAnthropicFormat } from './anthropic';\nimport { parseGoogleChunk, isGoogleFormat } from './google';\nimport { detectProvider, type ProviderType } from './types';\n\n/**\n * Parse a chunk from any provider and extract the content\n */\nexport function parseChunk(data: string, provider?: ProviderType): string | null {\n if (data === '[DONE]') return null;\n \n // If provider is specified, use that parser\n if (provider === 'anthropic') {\n return parseAnthropicChunk(data);\n }\n if (provider === 'google') {\n return parseGoogleChunk(data);\n }\n if (provider === 'openai') {\n return parseOpenAIChunk(data);\n }\n \n // Auto-detect format\n if (isOpenAIFormat(data)) {\n return parseOpenAIChunk(data);\n }\n if (isAnthropicFormat(data)) {\n return parseAnthropicChunk(data);\n }\n if (isGoogleFormat(data)) {\n return parseGoogleChunk(data);\n }\n \n return null;\n}\n\n/**\n * Convert content to OpenAI-compatible SSE format\n */\nexport function toOpenAIFormat(content: string): string {\n const chunk = {\n choices: [{\n delta: { content },\n index: 0,\n finish_reason: null,\n }],\n };\n return `data: ${JSON.stringify(chunk)}\\n\\n`;\n}\n\n/**\n * Create a transform stream that normalizes any provider format to OpenAI format\n */\nexport function createNormalizerStream(model: string): TransformStream<Uint8Array, Uint8Array> {\n const provider = detectProvider(model);\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = '';\n\n return new TransformStream({\n transform(chunk, controller) {\n buffer += decoder.decode(chunk, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n \n if (data === '[DONE]') {\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n continue;\n }\n\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n } else if (line.startsWith('event: ')) {\n // Skip event lines (Anthropic uses these)\n continue;\n }\n }\n },\n flush(controller) {\n if (buffer.startsWith('data: ')) {\n const data = buffer.slice(6).trim();\n if (data && data !== '[DONE]') {\n const content = parseChunk(data, provider);\n if (content) {\n controller.enqueue(encoder.encode(toOpenAIFormat(content)));\n }\n }\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n },\n });\n}\n","import { createNormalizerStream } from './providers';\n\nconst MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nexport interface ChatOptions {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n system_prompt_id?: string;\n };\n}\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport async function chatHandler(\n req: Request,\n options: ChatOptions = {}\n): Promise<Response> {\n const {\n model = 'gpt-4o-mini',\n cookiePrefix = 'mnx',\n mnxOptions = {\n history: true,\n learn: true,\n recall: true,\n profile: true,\n summarize: 'balanced',\n },\n } = options;\n\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = `${cookiePrefix}_chat`;\n\n // Parse cookies\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n\n const subjectId = cookies[subjectCookieName];\n const chatId = cookies[chatCookieName];\n\n if (!subjectId || !chatId) {\n return new Response(\n JSON.stringify({ error: 'Missing session cookies. Call /bootstrap first.' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Parse request body\n let body: { message?: string };\n try {\n body = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const { message } = body;\n if (!message || typeof message !== 'string') {\n return new Response(\n JSON.stringify({ error: 'Missing or invalid message field' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Get API keys from environment\n const mnxApiKey = process.env.MNX_API_KEY;\n if (!mnxApiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Build headers for Mnexium API\n const headers: HeadersInit = {\n 'Authorization': `Bearer ${mnxApiKey}`,\n 'Content-Type': 'application/json',\n };\n\n // Add provider API keys if available\n if (process.env.OPENAI_API_KEY) {\n headers['x-openai-key'] = process.env.OPENAI_API_KEY;\n }\n if (process.env.ANTHROPIC_API_KEY) {\n headers['x-anthropic-key'] = process.env.ANTHROPIC_API_KEY;\n }\n if (process.env.GOOGLE_API_KEY) {\n headers['x-google-key'] = process.env.GOOGLE_API_KEY;\n }\n\n // Build request body for Mnexium\n const mnxPayload: Record<string, unknown> = {\n subject_id: subjectId,\n chat_id: chatId,\n history: mnxOptions.history ?? true,\n learn: mnxOptions.learn ?? true,\n recall: mnxOptions.recall ?? true,\n profile: mnxOptions.profile ?? true,\n summarize: mnxOptions.summarize ?? 'balanced',\n };\n\n // Add system_prompt_id if provided\n if (mnxOptions.system_prompt_id) {\n mnxPayload.system_prompt_id = mnxOptions.system_prompt_id;\n }\n\n const mnexiumBody = {\n model,\n messages: [{ role: 'user', content: message }],\n stream: true,\n mnx: mnxPayload,\n };\n\n // Forward request to Mnexium\n let upstreamRes: Response;\n try {\n upstreamRes = await fetch(`${MNEXIUM_API_BASE}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(mnexiumBody),\n });\n } catch (err) {\n console.error('Mnexium API error:', err);\n return new Response(\n JSON.stringify({ error: 'Failed to connect to Mnexium API' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n if (!upstreamRes.ok) {\n const errorText = await upstreamRes.text();\n console.error('Mnexium API error:', upstreamRes.status, errorText);\n return new Response(\n JSON.stringify({ error: 'Mnexium API error', details: errorText }),\n { status: upstreamRes.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Stream the response back to client without buffering\n if (!upstreamRes.body) {\n return new Response(\n JSON.stringify({ error: 'No response body from Mnexium' }),\n { status: 502, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Normalize the stream to OpenAI format (handles Anthropic, Google, etc.)\n const normalizedStream = upstreamRes.body.pipeThrough(createNormalizerStream(model));\n\n return new Response(normalizedStream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n });\n}\n\nexport default chatHandler;\n","const MNEXIUM_API_BASE = 'https://www.mnexium.com/api/v1';\n\nfunction parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) return {};\n return cookieHeader.split(';').reduce((acc, cookie) => {\n const [key, value] = cookie.trim().split('=');\n if (key && value) acc[key] = decodeURIComponent(value);\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport interface HistoryOptions {\n cookiePrefix?: string;\n}\n\nexport async function historyHandler(\n req: Request,\n options: HistoryOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const res = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium history error:', res.status, errorText);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response to our format\n const conversations = (data.chats || []).map((chat: { chat_id: string; title?: string; updated_at?: string; created_at?: string }) => ({\n id: chat.chat_id,\n title: chat.title || 'Untitled conversation',\n updated_at: chat.updated_at || chat.created_at || new Date().toISOString(),\n }));\n\n return new Response(\n JSON.stringify({ conversations }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch history:', err);\n return new Response(\n JSON.stringify({ conversations: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport interface ConversationOptions {\n cookiePrefix?: string;\n}\n\nexport async function conversationHandler(\n req: Request,\n chatId: string,\n options: ConversationOptions = {}\n): Promise<Response> {\n const { cookiePrefix = 'mnx' } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n\n const cookieHeader = req.headers.get('cookie');\n const cookies = parseCookies(cookieHeader);\n const subjectId = cookies[subjectCookieName];\n\n if (!subjectId) {\n return new Response(\n JSON.stringify({ error: 'No subject ID found' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const apiKey = process.env.MNX_API_KEY;\n if (!apiKey) {\n return new Response(\n JSON.stringify({ error: 'Server configuration error: Missing MNX_API_KEY' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n try {\n const url = `${MNEXIUM_API_BASE}/chat/history/read?chat_id=${chatId}&subject_id=${subjectId}&limit=200`;\n const res = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('Mnexium conversation error:', res.status, errorText);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const data = await res.json();\n \n // Transform Mnexium response - filter to only user and assistant messages\n // The API may return messages directly or nested under a key\n const rawMessages = data.messages || data.history || data || [];\n const messagesArray = Array.isArray(rawMessages) ? rawMessages : [];\n \n const messages = messagesArray\n .filter((m: { role: string }) => m.role === 'user' || m.role === 'assistant')\n .map((m: { role: string; message?: string; content?: string }) => ({\n role: m.role,\n content: m.message || m.content || '',\n }))\n .filter((m: { content: string }) => m.content);\n\n return new Response(\n JSON.stringify({ messages }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n console.error('Failed to fetch conversation:', err);\n return new Response(\n JSON.stringify({ messages: [] }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\nexport default { historyHandler, conversationHandler };\n","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler, type HistoryOptions, type ConversationOptions } from './history';\n\nexport interface MnexiumHandlersConfig {\n model?: string;\n cookiePrefix?: string;\n mnxOptions?: {\n history?: boolean;\n learn?: boolean | 'force';\n recall?: boolean;\n profile?: boolean;\n summarize?: 'light' | 'balanced' | 'aggressive' | false;\n system_prompt_id?: string;\n };\n}\n\nexport interface MnexiumHandlers {\n bootstrap: (req: Request) => Promise<Response>;\n chat: (req: Request) => Promise<Response>;\n newChat: (req: Request) => Promise<Response>;\n history: (req: Request) => Promise<Response>;\n conversation: (req: Request, chatId: string) => Promise<Response>;\n}\n\n/**\n * Creates a set of configured handlers for Mnexium chat endpoints.\n * This allows you to define your configuration once and reuse it across all routes.\n * \n * @example\n * ```ts\n * // lib/mnx.ts\n * import { createHandlers } from '@mnexium/chat-react/server';\n * \n * export const mnx = createHandlers({\n * model: 'gpt-4o',\n * cookiePrefix: 'mnx',\n * mnxOptions: {\n * history: true,\n * learn: true,\n * recall: true,\n * },\n * });\n * \n * // app/api/mnx/chat/route.ts\n * import { mnx } from '@/lib/mnx';\n * export const POST = mnx.chat;\n * ```\n */\nexport function createHandlers(config: MnexiumHandlersConfig = {}): MnexiumHandlers {\n const { model, cookiePrefix, mnxOptions } = config;\n\n const bootstrapOpts: BootstrapOptions = { cookiePrefix };\n const chatOpts: ChatOptions = { model, cookiePrefix, mnxOptions };\n const historyOpts: HistoryOptions = { cookiePrefix };\n const conversationOpts: ConversationOptions = { cookiePrefix };\n\n return {\n bootstrap: (req: Request) => bootstrapHandler(req, bootstrapOpts),\n chat: (req: Request) => chatHandler(req, chatOpts),\n newChat: (req: Request) => newChatHandler(req, bootstrapOpts),\n history: (req: Request) => historyHandler(req, historyOpts),\n conversation: (req: Request, chatId: string) => conversationHandler(req, chatId, conversationOpts),\n };\n}\n\nexport default createHandlers;\n"],"mappings":"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","names":["MNEXIUM_API_BASE","parseCookies","MNEXIUM_API_BASE","parseCookies"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnexium/chat-react",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "Drop-in React chat widget with AI memory powered by Mnexium",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",