@mnexium/chat-react 1.0.2 → 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
@@ -167,6 +167,7 @@ const mnx = createHandlers({
167
167
  | `mnxOptions.recall` | `boolean` | `true` | Inject relevant memories |
168
168
  | `mnxOptions.profile` | `boolean` | `true` | Include user profile |
169
169
  | `mnxOptions.summarize` | `'light' \| 'balanced' \| 'aggressive' \| false` | `'balanced'` | Summarization mode |
170
+ | `mnxOptions.system_prompt_id` | `string` | - | Use a saved Mnexium system prompt by ID |
170
171
 
171
172
  ### Individual Handlers
172
173
 
@@ -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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAM,mBAAmB;AACzB,IAAM,iBAAiB,KAAK,KAAK,KAAK;AAWtC,SAAS,eAAuB;AAC9B,MAAI,OAAO,WAAW,eAAe,OAAO,YAAY;AACtD,WAAO,OAAO,WAAW;AAAA,EAC3B;AAGA,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,SAAO,gBAAgB,KAAK;AAG5B,QAAM,CAAC,IAAK,MAAM,CAAC,IAAI,KAAQ;AAC/B,QAAM,CAAC,IAAK,MAAM,CAAC,IAAI,KAAQ;AAE/B,QAAM,MAAM,MAAM,KAAK,OAAO,OAAK,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAC3E,SAAO,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;AAC1G;AAEA,SAAS,aAAa,cAAqD;AACzE,MAAI,CAAC,aAAc,QAAO,CAAC;AAC3B,SAAO,aAAa,MAAM,GAAG,EAAE,OAAO,CAAC,KAAK,WAAW;AACrD,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC5C,QAAI,OAAO,MAAO,KAAI,GAAG,IAAI,mBAAmB,KAAK;AACrD,WAAO;AAAA,EACT,GAAG,CAAC,CAA2B;AACjC;AAEA,SAAS,aAAa,MAAc,OAAe,SAAkB,MAAc;AACjF,QAAM,QAAQ;AAAA,IACZ,GAAG,IAAI,IAAI,mBAAmB,KAAK,CAAC;AAAA,IACpC,WAAW,cAAc;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,OAAQ,OAAM,KAAK,QAAQ;AAC/B,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAsB,iBACpB,KACA,UAA4B,CAAC,GACV;AACnB,QAAM,EAAE,eAAe,MAAM,IAAI;AACjC,QAAM,oBAAoB,GAAG,YAAY;AACzC,QAAM,iBAAiB,GAAG,YAAY;AAEtC,QAAM,eAAe,IAAI,QAAQ,IAAI,QAAQ;AAC7C,QAAM,UAAU,aAAa,YAAY;AAEzC,MAAI,YAAY,QAAQ,iBAAiB;AACzC,MAAI,SAAS,QAAQ,cAAc;AACnC,QAAM,aAAuB,CAAC;AAE9B,QAAM,WAAW,IAAI,IAAI,WAAW,UAAU,KAC5C,IAAI,QAAQ,IAAI,mBAAmB,MAAM;AAG3C,MAAI,CAAC,WAAW;AACd,gBAAY,UAAU,aAAa,CAAC;AACpC,eAAW,KAAK,aAAa,mBAAmB,WAAW,QAAQ,CAAC;AAAA,EACtE;AAGA,MAAI,CAAC,QAAQ;AACX,UAAM,SAAS,QAAQ,IAAI;AAE3B,QAAI,QAAQ;AACV,UAAI;AAEF,cAAM,aAAa,MAAM,MAAM,GAAG,gBAAgB,YAAY,SAAS,IAAI;AAAA,UACzE,SAAS;AAAA,YACP,iBAAiB,UAAU,MAAM;AAAA,UACnC;AAAA,QACF,CAAC;AAED,YAAI,WAAW,IAAI;AACjB,gBAAM,cAAc,MAAM,WAAW,KAAK;AAE1C,cAAI,YAAY,SAAS,YAAY,MAAM,SAAS,GAAG;AACrD,qBAAS,YAAY,MAAM,CAAC,EAAE;AAAA,UAChC;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,iCAAiC,GAAG;AAAA,MACpD;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ;AACX,eAAS,aAAa;AAAA,IACxB;AAEA,eAAW,KAAK,aAAa,gBAAgB,QAAQ,QAAQ,CAAC;AAAA,EAChE;AAEA,QAAM,eAAkC;AAAA,IACtC,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AAEA,QAAM,UAAU,IAAI,QAAQ;AAAA,IAC1B,gBAAgB;AAAA,EAClB,CAAC;AAED,aAAW,UAAU,YAAY;AAC/B,YAAQ,OAAO,cAAc,MAAM;AAAA,EACrC;AAEA,SAAO,IAAI,SAAS,KAAK,UAAU,YAAY,GAAG;AAAA,IAChD,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,eACpB,KACA,UAA4B,CAAC,GACV;AACnB,QAAM,EAAE,eAAe,MAAM,IAAI;AACjC,QAAM,oBAAoB,GAAG,YAAY;AACzC,QAAM,iBAAiB,GAAG,YAAY;AAEtC,QAAM,eAAe,IAAI,QAAQ,IAAI,QAAQ;AAC7C,QAAM,UAAU,aAAa,YAAY;AAEzC,MAAI,YAAY,QAAQ,iBAAiB;AACzC,QAAM,aAAuB,CAAC;AAE9B,QAAM,WAAW,IAAI,IAAI,WAAW,UAAU,KAC5C,IAAI,QAAQ,IAAI,mBAAmB,MAAM;AAG3C,MAAI,CAAC,WAAW;AACd,gBAAY,aAAa;AACzB,eAAW,KAAK,aAAa,mBAAmB,WAAW,QAAQ,CAAC;AAAA,EACtE;AAGA,QAAM,SAAS,aAAa;AAC5B,aAAW,KAAK,aAAa,gBAAgB,QAAQ,QAAQ,CAAC;AAE9D,QAAM,eAAkC;AAAA,IACtC,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AAEA,QAAM,UAAU,IAAI,QAAQ;AAAA,IAC1B,gBAAgB;AAAA,EAClB,CAAC;AAED,aAAW,UAAU,YAAY;AAC/B,YAAQ,OAAO,cAAc,MAAM;AAAA,EACrC;AAEA,SAAO,IAAI,SAAS,KAAK,UAAU,YAAY,GAAG;AAAA,IAChD,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AACH;;;ACrKO,SAAS,iBAAiB,MAA6B;AAC5D,MAAI,SAAS,SAAU,QAAO;AAE9B,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAO,OAAO,UAAU,CAAC,GAAG,OAAO,WAAW;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,MAAuB;AACpD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAO,aAAa;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClBO,SAAS,oBAAoB,MAA6B;AAC/D,MAAI,SAAS,SAAU,QAAO;AAE9B,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAG9B,QAAI,OAAO,SAAS,yBAAyB,OAAO,OAAO,SAAS,cAAc;AAChF,aAAO,OAAO,MAAM,QAAQ;AAAA,IAC9B;AAGA,QAAI,OAAO,SAAS,iBAAiB;AACnC,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,kBAAkB,MAAuB;AACvD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAO,UAAU,WACf,OAAO,SAAS,mBAChB,OAAO,SAAS,yBAChB,OAAO,SAAS,yBAChB,OAAO,SAAS,wBAChB,OAAO,SAAS,mBAChB,OAAO,SAAS;AAAA,EAEpB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACrCO,SAAS,iBAAiB,MAA6B;AAC5D,MAAI,SAAS,SAAU,QAAO;AAE9B,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAG9B,UAAM,OAAO,OAAO,aAAa,CAAC,GAAG,SAAS,QAAQ,CAAC,GAAG;AAC1D,QAAI,KAAM,QAAO;AAEjB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,MAAuB;AACpD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAO,gBAAgB;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACrBO,SAAS,eAAe,OAA6B;AAC1D,QAAM,aAAa,MAAM,YAAY;AAErC,MAAI,WAAW,SAAS,QAAQ,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,SAAS,QAAQ,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACNO,SAAS,WAAW,MAAc,UAAwC;AAC/E,MAAI,SAAS,SAAU,QAAO;AAG9B,MAAI,aAAa,aAAa;AAC5B,WAAO,oBAAoB,IAAI;AAAA,EACjC;AACA,MAAI,aAAa,UAAU;AACzB,WAAO,iBAAiB,IAAI;AAAA,EAC9B;AACA,MAAI,aAAa,UAAU;AACzB,WAAO,iBAAiB,IAAI;AAAA,EAC9B;AAGA,MAAI,eAAe,IAAI,GAAG;AACxB,WAAO,iBAAiB,IAAI;AAAA,EAC9B;AACA,MAAI,kBAAkB,IAAI,GAAG;AAC3B,WAAO,oBAAoB,IAAI;AAAA,EACjC;AACA,MAAI,eAAe,IAAI,GAAG;AACxB,WAAO,iBAAiB,IAAI;AAAA,EAC9B;AAEA,SAAO;AACT;AAKO,SAAS,eAAe,SAAyB;AACtD,QAAM,QAAQ;AAAA,IACZ,SAAS,CAAC;AAAA,MACR,OAAO,EAAE,QAAQ;AAAA,MACjB,OAAO;AAAA,MACP,eAAe;AAAA,IACjB,CAAC;AAAA,EACH;AACA,SAAO,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA;AACvC;AAKO,SAAS,uBAAuB,OAAwD;AAC7F,QAAM,WAAW,eAAe,KAAK;AACrC,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,SAAO,IAAI,gBAAgB;AAAA,IACzB,UAAU,OAAO,YAAY;AAC3B,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,gBAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAEhC,cAAI,SAAS,UAAU;AACrB,uBAAW,QAAQ,QAAQ,OAAO,kBAAkB,CAAC;AACrD;AAAA,UACF;AAEA,gBAAM,UAAU,WAAW,MAAM,QAAQ;AACzC,cAAI,SAAS;AACX,uBAAW,QAAQ,QAAQ,OAAO,eAAe,OAAO,CAAC,CAAC;AAAA,UAC5D;AAAA,QACF,WAAW,KAAK,WAAW,SAAS,GAAG;AAErC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,YAAY;AAChB,UAAI,OAAO,WAAW,QAAQ,GAAG;AAC/B,cAAM,OAAO,OAAO,MAAM,CAAC,EAAE,KAAK;AAClC,YAAI,QAAQ,SAAS,UAAU;AAC7B,gBAAM,UAAU,WAAW,MAAM,QAAQ;AACzC,cAAI,SAAS;AACX,uBAAW,QAAQ,QAAQ,OAAO,eAAe,OAAO,CAAC,CAAC;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AACA,iBAAW,QAAQ,QAAQ,OAAO,kBAAkB,CAAC;AAAA,IACvD;AAAA,EACF,CAAC;AACH;;;ACpGA,IAAMA,oBAAmB;AAezB,SAASC,cAAa,cAAqD;AACzE,MAAI,CAAC,aAAc,QAAO,CAAC;AAC3B,SAAO,aAAa,MAAM,GAAG,EAAE,OAAO,CAAC,KAAK,WAAW;AACrD,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC5C,QAAI,OAAO,MAAO,KAAI,GAAG,IAAI,mBAAmB,KAAK;AACrD,WAAO;AAAA,EACT,GAAG,CAAC,CAA2B;AACjC;AAEA,eAAsB,YACpB,KACA,UAAuB,CAAC,GACL;AACnB,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,aAAa;AAAA,MACX,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,EACF,IAAI;AAEJ,QAAM,oBAAoB,GAAG,YAAY;AACzC,QAAM,iBAAiB,GAAG,YAAY;AAGtC,QAAM,eAAe,IAAI,QAAQ,IAAI,QAAQ;AAC7C,QAAM,UAAUA,cAAa,YAAY;AAEzC,QAAM,YAAY,QAAQ,iBAAiB;AAC3C,QAAM,SAAS,QAAQ,cAAc;AAErC,MAAI,CAAC,aAAa,CAAC,QAAQ;AACzB,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,kDAAkD,CAAC;AAAA,MAC3E,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,QAAQ;AACN,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,oBAAoB,CAAC;AAAA,MAC7C,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,mCAAmC,CAAC;AAAA,MAC5D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,YAAY,QAAQ,IAAI;AAC9B,MAAI,CAAC,WAAW;AACd,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,kDAAkD,CAAC;AAAA,MAC3E,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,UAAuB;AAAA,IAC3B,iBAAiB,UAAU,SAAS;AAAA,IACpC,gBAAgB;AAAA,EAClB;AAGA,MAAI,QAAQ,IAAI,gBAAgB;AAC9B,YAAQ,cAAc,IAAI,QAAQ,IAAI;AAAA,EACxC;AACA,MAAI,QAAQ,IAAI,mBAAmB;AACjC,YAAQ,iBAAiB,IAAI,QAAQ,IAAI;AAAA,EAC3C;AACA,MAAI,QAAQ,IAAI,gBAAgB;AAC9B,YAAQ,cAAc,IAAI,QAAQ,IAAI;AAAA,EACxC;AAGA,QAAM,aAAsC;AAAA,IAC1C,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,SAAS,WAAW,WAAW;AAAA,IAC/B,OAAO,WAAW,SAAS;AAAA,IAC3B,QAAQ,WAAW,UAAU;AAAA,IAC7B,SAAS,WAAW,WAAW;AAAA,IAC/B,WAAW,WAAW,aAAa;AAAA,EACrC;AAGA,MAAI,WAAW,kBAAkB;AAC/B,eAAW,mBAAmB,WAAW;AAAA,EAC3C;AAEA,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,QAAQ,CAAC;AAAA,IAC7C,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAGA,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,MAAM,GAAGD,iBAAgB,qBAAqB;AAAA,MAChE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,WAAW;AAAA,IAClC,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,MAAM,sBAAsB,GAAG;AACvC,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,mCAAmC,CAAC;AAAA,MAC5D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,CAAC,YAAY,IAAI;AACnB,UAAM,YAAY,MAAM,YAAY,KAAK;AACzC,YAAQ,MAAM,sBAAsB,YAAY,QAAQ,SAAS;AACjE,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,qBAAqB,SAAS,UAAU,CAAC;AAAA,MACjE,EAAE,QAAQ,YAAY,QAAQ,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IAChF;AAAA,EACF;AAGA,MAAI,CAAC,YAAY,MAAM;AACrB,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,gCAAgC,CAAC;AAAA,MACzD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,mBAAmB,YAAY,KAAK,YAAY,uBAAuB,KAAK,CAAC;AAEnF,SAAO,IAAI,SAAS,kBAAkB;AAAA,IACpC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AACH;;;AC3KA,IAAME,oBAAmB;AAEzB,SAASC,cAAa,cAAqD;AACzE,MAAI,CAAC,aAAc,QAAO,CAAC;AAC3B,SAAO,aAAa,MAAM,GAAG,EAAE,OAAO,CAAC,KAAK,WAAW;AACrD,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC5C,QAAI,OAAO,MAAO,KAAI,GAAG,IAAI,mBAAmB,KAAK;AACrD,WAAO;AAAA,EACT,GAAG,CAAC,CAA2B;AACjC;AAMA,eAAsB,eACpB,KACA,UAA0B,CAAC,GACR;AACnB,QAAM,EAAE,eAAe,MAAM,IAAI;AACjC,QAAM,oBAAoB,GAAG,YAAY;AAEzC,QAAM,eAAe,IAAI,QAAQ,IAAI,QAAQ;AAC7C,QAAM,UAAUA,cAAa,YAAY;AACzC,QAAM,YAAY,QAAQ,iBAAiB;AAE3C,MAAI,CAAC,WAAW;AACd,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,sBAAsB,CAAC;AAAA,MAC/C,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,QAAQ;AACX,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,kDAAkD,CAAC;AAAA,MAC3E,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAGD,iBAAgB,YAAY,SAAS,IAAI;AAAA,MAClE,SAAS;AAAA,QACP,iBAAiB,UAAU,MAAM;AAAA,MACnC;AAAA,IACF,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,YAAY,MAAM,IAAI,KAAK;AACjC,cAAQ,MAAM,0BAA0B,IAAI,QAAQ,SAAS;AAC7D,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC;AAAA,QACpC,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAG5B,UAAM,iBAAiB,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,UAAyF;AAAA,MACrI,IAAI,KAAK;AAAA,MACT,OAAO,KAAK,SAAS;AAAA,MACrB,YAAY,KAAK,cAAc,KAAK,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC3E,EAAE;AAEF,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,cAAc,CAAC;AAAA,MAChC,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,4BAA4B,GAAG;AAC7C,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC;AAAA,MACpC,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AACF;AAMA,eAAsB,oBACpB,KACA,QACA,UAA+B,CAAC,GACb;AACnB,QAAM,EAAE,eAAe,MAAM,IAAI;AACjC,QAAM,oBAAoB,GAAG,YAAY;AAEzC,QAAM,eAAe,IAAI,QAAQ,IAAI,QAAQ;AAC7C,QAAM,UAAUC,cAAa,YAAY;AACzC,QAAM,YAAY,QAAQ,iBAAiB;AAE3C,MAAI,CAAC,WAAW;AACd,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,sBAAsB,CAAC;AAAA,MAC/C,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,QAAQ;AACX,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,kDAAkD,CAAC;AAAA,MAC3E,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,MAAM,GAAGD,iBAAgB,8BAA8B,MAAM,eAAe,SAAS;AAC3F,UAAM,MAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,SAAS;AAAA,QACP,iBAAiB,UAAU,MAAM;AAAA,MACnC;AAAA,IACF,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,YAAY,MAAM,IAAI,KAAK;AACjC,cAAQ,MAAM,+BAA+B,IAAI,QAAQ,SAAS;AAClE,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;AAAA,QAC/B,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAI5B,UAAM,cAAc,KAAK,YAAY,KAAK,WAAW,QAAQ,CAAC;AAC9D,UAAM,gBAAgB,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC;AAElE,UAAM,WAAW,cACd,OAAO,CAAC,MAAwB,EAAE,SAAS,UAAU,EAAE,SAAS,WAAW,EAC3E,IAAI,CAAC,OAA6D;AAAA,MACjE,MAAM,EAAE;AAAA,MACR,SAAS,EAAE,WAAW,EAAE,WAAW;AAAA,IACrC,EAAE,EACD,OAAO,CAAC,MAA2B,EAAE,OAAO;AAE/C,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,MAC3B,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,iCAAiC,GAAG;AAClD,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;AAAA,MAC/B,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AACF;;;ACxGO,SAAS,eAAe,SAAgC,CAAC,GAAoB;AAClF,QAAM,EAAE,OAAO,cAAc,WAAW,IAAI;AAE5C,QAAM,gBAAkC,EAAE,aAAa;AACvD,QAAM,WAAwB,EAAE,OAAO,cAAc,WAAW;AAChE,QAAM,cAA8B,EAAE,aAAa;AACnD,QAAM,mBAAwC,EAAE,aAAa;AAE7D,SAAO;AAAA,IACL,WAAW,CAAC,QAAiB,iBAAiB,KAAK,aAAa;AAAA,IAChE,MAAM,CAAC,QAAiB,YAAY,KAAK,QAAQ;AAAA,IACjD,SAAS,CAAC,QAAiB,eAAe,KAAK,aAAa;AAAA,IAC5D,SAAS,CAAC,QAAiB,eAAe,KAAK,WAAW;AAAA,IAC1D,cAAc,CAAC,KAAc,WAAmB,oBAAoB,KAAK,QAAQ,gBAAgB;AAAA,EACnG;AACF;","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.2",
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",