@mnexium/chat 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -244,6 +244,7 @@ Creates all handlers with shared configuration:
244
244
  const mnx = createHandlers({
245
245
  model: 'gpt-4o-mini',
246
246
  cookiePrefix: 'mnx',
247
+ chatPrefix: '_landing', // Optional: creates separate chat sessions
247
248
  mnxOptions: { ... },
248
249
  });
249
250
 
@@ -254,6 +255,7 @@ const mnx = createHandlers({
254
255
  |--------|------|---------|-------------|
255
256
  | `model` | `string` | `'gpt-4o-mini'` | LLM model to use |
256
257
  | `cookiePrefix` | `string` | `'mnx'` | Prefix for session cookies |
258
+ | `chatPrefix` | `string` | - | Optional suffix appended to `cookiePrefix` for the chat cookie (e.g., `cookiePrefix: 'mnx'` + `chatPrefix: '_landing'` → cookie name `mnx_landing_chat`) |
257
259
  | `mnxOptions.history` | `boolean` | `true` | Enable conversation history |
258
260
  | `mnxOptions.learn` | `boolean \| 'force'` | `true` | Extract and store memories |
259
261
  | `mnxOptions.recall` | `boolean` | `true` | Inject relevant memories |
@@ -4,6 +4,7 @@ interface BootstrapResponse {
4
4
  }
5
5
  interface BootstrapOptions {
6
6
  cookiePrefix?: string;
7
+ chatPrefix?: string;
7
8
  }
8
9
  declare function bootstrapHandler(req: Request, options?: BootstrapOptions): Promise<Response>;
9
10
  declare function newChatHandler(req: Request, options?: BootstrapOptions): Promise<Response>;
@@ -11,6 +12,7 @@ declare function newChatHandler(req: Request, options?: BootstrapOptions): Promi
11
12
  interface ChatOptions {
12
13
  model?: string;
13
14
  cookiePrefix?: string;
15
+ chatPrefix?: string;
14
16
  mnxOptions?: {
15
17
  history?: boolean;
16
18
  learn?: boolean | 'force';
@@ -34,6 +36,7 @@ declare function conversationHandler(req: Request, chatId: string, options?: Con
34
36
  interface MnexiumHandlersConfig {
35
37
  model?: string;
36
38
  cookiePrefix?: string;
39
+ chatPrefix?: string;
37
40
  mnxOptions?: {
38
41
  history?: boolean;
39
42
  learn?: boolean | 'force';
@@ -4,6 +4,7 @@ interface BootstrapResponse {
4
4
  }
5
5
  interface BootstrapOptions {
6
6
  cookiePrefix?: string;
7
+ chatPrefix?: string;
7
8
  }
8
9
  declare function bootstrapHandler(req: Request, options?: BootstrapOptions): Promise<Response>;
9
10
  declare function newChatHandler(req: Request, options?: BootstrapOptions): Promise<Response>;
@@ -11,6 +12,7 @@ declare function newChatHandler(req: Request, options?: BootstrapOptions): Promi
11
12
  interface ChatOptions {
12
13
  model?: string;
13
14
  cookiePrefix?: string;
15
+ chatPrefix?: string;
14
16
  mnxOptions?: {
15
17
  history?: boolean;
16
18
  learn?: boolean | 'force';
@@ -34,6 +36,7 @@ declare function conversationHandler(req: Request, chatId: string, options?: Con
34
36
  interface MnexiumHandlersConfig {
35
37
  model?: string;
36
38
  cookiePrefix?: string;
39
+ chatPrefix?: string;
37
40
  mnxOptions?: {
38
41
  history?: boolean;
39
42
  learn?: boolean | 'force';
@@ -65,9 +65,9 @@ function createCookie(name, value, secure = true) {
65
65
  return parts.join("; ");
66
66
  }
67
67
  async function bootstrapHandler(req, options = {}) {
68
- const { cookiePrefix = "mnx" } = options;
68
+ const { cookiePrefix = "mnx", chatPrefix } = options;
69
69
  const subjectCookieName = `${cookiePrefix}_subject`;
70
- const chatCookieName = `${cookiePrefix}_chat`;
70
+ const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${cookiePrefix}_chat`;
71
71
  const cookieHeader = req.headers.get("cookie");
72
72
  const cookies = parseCookies(cookieHeader);
73
73
  let subjectId = cookies[subjectCookieName];
@@ -80,6 +80,9 @@ async function bootstrapHandler(req, options = {}) {
80
80
  }
81
81
  if (!chatId) {
82
82
  const apiKey = process.env.MNX_API_KEY;
83
+ if (!apiKey) {
84
+ console.error("[Mnexium] MNX_API_KEY is not set. Chat history lookup skipped.");
85
+ }
83
86
  if (apiKey) {
84
87
  try {
85
88
  const historyRes = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {
@@ -118,9 +121,9 @@ async function bootstrapHandler(req, options = {}) {
118
121
  });
119
122
  }
120
123
  async function newChatHandler(req, options = {}) {
121
- const { cookiePrefix = "mnx" } = options;
124
+ const { cookiePrefix = "mnx", chatPrefix } = options;
122
125
  const subjectCookieName = `${cookiePrefix}_subject`;
123
- const chatCookieName = `${cookiePrefix}_chat`;
126
+ const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${cookiePrefix}_chat`;
124
127
  const cookieHeader = req.headers.get("cookie");
125
128
  const cookies = parseCookies(cookieHeader);
126
129
  let subjectId = cookies[subjectCookieName];
@@ -315,6 +318,7 @@ async function chatHandler(req, options = {}) {
315
318
  const {
316
319
  model = "gpt-4o-mini",
317
320
  cookiePrefix = "mnx",
321
+ chatPrefix,
318
322
  mnxOptions = {
319
323
  history: true,
320
324
  learn: true,
@@ -324,7 +328,7 @@ async function chatHandler(req, options = {}) {
324
328
  }
325
329
  } = options;
326
330
  const subjectCookieName = `${cookiePrefix}_subject`;
327
- const chatCookieName = `${cookiePrefix}_chat`;
331
+ const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${cookiePrefix}_chat`;
328
332
  const cookieHeader = req.headers.get("cookie");
329
333
  const cookies = parseCookies2(cookieHeader);
330
334
  const subjectId = cookies[subjectCookieName];
@@ -353,6 +357,7 @@ async function chatHandler(req, options = {}) {
353
357
  }
354
358
  const mnxApiKey = process.env.MNX_API_KEY;
355
359
  if (!mnxApiKey) {
360
+ console.error("[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.");
356
361
  return new Response(
357
362
  JSON.stringify({ error: "Server configuration error: Missing MNX_API_KEY" }),
358
363
  { status: 500, headers: { "Content-Type": "application/json" } }
@@ -452,6 +457,7 @@ async function historyHandler(req, options = {}) {
452
457
  }
453
458
  const apiKey = process.env.MNX_API_KEY;
454
459
  if (!apiKey) {
460
+ console.error("[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.");
455
461
  return new Response(
456
462
  JSON.stringify({ error: "Server configuration error: Missing MNX_API_KEY" }),
457
463
  { status: 500, headers: { "Content-Type": "application/json" } }
@@ -503,6 +509,7 @@ async function conversationHandler(req, chatId, options = {}) {
503
509
  }
504
510
  const apiKey = process.env.MNX_API_KEY;
505
511
  if (!apiKey) {
512
+ console.error("[Mnexium] MNX_API_KEY is not set.Please visit https://mnexium.com/docs#quickstart to get your API key.");
506
513
  return new Response(
507
514
  JSON.stringify({ error: "Server configuration error: Missing MNX_API_KEY" }),
508
515
  { status: 500, headers: { "Content-Type": "application/json" } }
@@ -545,9 +552,9 @@ async function conversationHandler(req, chatId, options = {}) {
545
552
 
546
553
  // src/server/factory.ts
547
554
  function createHandlers(config = {}) {
548
- const { model, cookiePrefix, mnxOptions } = config;
549
- const bootstrapOpts = { cookiePrefix };
550
- const chatOpts = { model, cookiePrefix, mnxOptions };
555
+ const { model, cookiePrefix, chatPrefix, mnxOptions } = config;
556
+ const bootstrapOpts = { cookiePrefix, chatPrefix };
557
+ const chatOpts = { model, cookiePrefix, chatPrefix, mnxOptions };
551
558
  const historyOpts = { cookiePrefix };
552
559
  const conversationOpts = { cookiePrefix };
553
560
  return {
@@ -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","../../src/server/express.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';\nexport { createExpressMiddleware, mountMnexiumRoutes, type MnexiumExpressOptions, type ExpressRequest, type ExpressResponse } from './express';\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?: 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 if provided\n if (mnxOptions.system_prompt) {\n mnxPayload.system_prompt = mnxOptions.system_prompt;\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?: 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","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler } from './history';\n\n// Express-compatible request/response types (minimal interface)\nexport interface ExpressRequest {\n body?: unknown;\n params?: Record<string, string>;\n cookies?: Record<string, string>;\n headers: Record<string, string | string[] | undefined>;\n url?: string;\n protocol?: string;\n get?: (name: string) => string | undefined;\n}\n\nexport interface ExpressResponse {\n status(code: number): ExpressResponse;\n json(data: unknown): void;\n send(data: string | Buffer): void;\n setHeader(name: string, value: string): ExpressResponse;\n write(chunk: string | Buffer): boolean;\n end(): void;\n headersSent?: boolean;\n}\n\nexport interface MnexiumExpressOptions {\n cookiePrefix?: string;\n chatOptions?: ChatOptions;\n bootstrapOptions?: BootstrapOptions;\n}\n\n// Convert Express request to Web API Request\nfunction toWebRequest(req: ExpressRequest, body?: unknown): Request {\n // Build headers\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n }\n\n // Build URL\n const protocol = req.protocol || (req.get?.('x-forwarded-proto')) || 'http';\n const host = req.headers.host || 'localhost';\n const url = `${protocol}://${host}${req.url || '/'}`;\n\n // Create Request\n const init: RequestInit = {\n method: body ? 'POST' : 'GET',\n headers,\n };\n\n if (body) {\n init.body = JSON.stringify(body);\n headers.set('Content-Type', 'application/json');\n }\n\n return new Request(url, init);\n}\n\n// Send Web API Response to Express response\nasync function sendWebResponse(webRes: Response, res: ExpressResponse): Promise<void> {\n // Copy status\n res.status(webRes.status);\n\n // Copy headers\n webRes.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n\n // Handle streaming response\n if (webRes.body) {\n const reader = webRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(decoder.decode(value, { stream: true }));\n }\n } finally {\n res.end();\n }\n } else {\n // Non-streaming response\n const text = await webRes.text();\n res.send(text);\n }\n}\n\nexport function createExpressMiddleware(options: MnexiumExpressOptions = {}) {\n const { cookiePrefix = 'mnx', chatOptions = {}, bootstrapOptions = {} } = options;\n\n return {\n // POST /chat\n chat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req, req.body);\n const webRes = await chatHandler(webReq, { ...chatOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /bootstrap\n bootstrap: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await bootstrapHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Bootstrap error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // POST /new-chat\n newChat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await newChatHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('New chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /history\n history: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await historyHandler(webReq, { cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('History error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /conversations/:chatId\n conversation: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const chatId = req.params?.chatId;\n if (!chatId) {\n res.status(400).json({ error: 'Chat ID required' });\n return;\n }\n const webReq = toWebRequest(req);\n const webRes = await conversationHandler(webReq, chatId);\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Conversation error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n };\n}\n\n// Helper to mount all routes at once\nexport function mountMnexiumRoutes(\n app: { \n get: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n post: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n },\n basePath: string,\n options: MnexiumExpressOptions = {}\n): void {\n const handlers = createExpressMiddleware(options);\n \n app.get(`${basePath}/bootstrap`, handlers.bootstrap);\n app.post(`${basePath}/chat`, handlers.chat);\n app.post(`${basePath}/new-chat`, handlers.newChat);\n app.get(`${basePath}/history`, handlers.history);\n app.get(`${basePath}/conversations/:chatId`, handlers.conversation);\n}\n\nexport { type ChatOptions, type BootstrapOptions };\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","../../src/server/express.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';\nexport { createExpressMiddleware, mountMnexiumRoutes, type MnexiumExpressOptions, type ExpressRequest, type ExpressResponse } from './express';\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 chatPrefix?: 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', chatPrefix } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${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 console.error('[Mnexium] MNX_API_KEY is not set. Chat history lookup skipped.');\n }\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', chatPrefix } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${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 chatPrefix?: 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?: 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 chatPrefix,\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 = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${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 console.error('[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.');\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 if provided\n if (mnxOptions.system_prompt) {\n mnxPayload.system_prompt = mnxOptions.system_prompt;\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 console.error('[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.');\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 console.error('[Mnexium] MNX_API_KEY is not set.Please visit https://mnexium.com/docs#quickstart to get your API key.');\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 chatPrefix?: 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?: 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, chatPrefix, mnxOptions } = config;\n\n const bootstrapOpts: BootstrapOptions = { cookiePrefix, chatPrefix };\n const chatOpts: ChatOptions = { model, cookiePrefix, chatPrefix, 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","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler } from './history';\n\n// Express-compatible request/response types (minimal interface)\nexport interface ExpressRequest {\n body?: unknown;\n params?: Record<string, string>;\n cookies?: Record<string, string>;\n headers: Record<string, string | string[] | undefined>;\n url?: string;\n protocol?: string;\n get?: (name: string) => string | undefined;\n}\n\nexport interface ExpressResponse {\n status(code: number): ExpressResponse;\n json(data: unknown): void;\n send(data: string | Buffer): void;\n setHeader(name: string, value: string): ExpressResponse;\n write(chunk: string | Buffer): boolean;\n end(): void;\n headersSent?: boolean;\n}\n\nexport interface MnexiumExpressOptions {\n cookiePrefix?: string;\n chatOptions?: ChatOptions;\n bootstrapOptions?: BootstrapOptions;\n}\n\n// Convert Express request to Web API Request\nfunction toWebRequest(req: ExpressRequest, body?: unknown): Request {\n // Build headers\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n }\n\n // Build URL\n const protocol = req.protocol || (req.get?.('x-forwarded-proto')) || 'http';\n const host = req.headers.host || 'localhost';\n const url = `${protocol}://${host}${req.url || '/'}`;\n\n // Create Request\n const init: RequestInit = {\n method: body ? 'POST' : 'GET',\n headers,\n };\n\n if (body) {\n init.body = JSON.stringify(body);\n headers.set('Content-Type', 'application/json');\n }\n\n return new Request(url, init);\n}\n\n// Send Web API Response to Express response\nasync function sendWebResponse(webRes: Response, res: ExpressResponse): Promise<void> {\n // Copy status\n res.status(webRes.status);\n\n // Copy headers\n webRes.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n\n // Handle streaming response\n if (webRes.body) {\n const reader = webRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(decoder.decode(value, { stream: true }));\n }\n } finally {\n res.end();\n }\n } else {\n // Non-streaming response\n const text = await webRes.text();\n res.send(text);\n }\n}\n\nexport function createExpressMiddleware(options: MnexiumExpressOptions = {}) {\n const { cookiePrefix = 'mnx', chatOptions = {}, bootstrapOptions = {} } = options;\n\n return {\n // POST /chat\n chat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req, req.body);\n const webRes = await chatHandler(webReq, { ...chatOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /bootstrap\n bootstrap: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await bootstrapHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Bootstrap error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // POST /new-chat\n newChat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await newChatHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('New chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /history\n history: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await historyHandler(webReq, { cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('History error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /conversations/:chatId\n conversation: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const chatId = req.params?.chatId;\n if (!chatId) {\n res.status(400).json({ error: 'Chat ID required' });\n return;\n }\n const webReq = toWebRequest(req);\n const webRes = await conversationHandler(webReq, chatId);\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Conversation error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n };\n}\n\n// Helper to mount all routes at once\nexport function mountMnexiumRoutes(\n app: { \n get: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n post: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n },\n basePath: string,\n options: MnexiumExpressOptions = {}\n): void {\n const handlers = createExpressMiddleware(options);\n \n app.get(`${basePath}/bootstrap`, handlers.bootstrap);\n app.post(`${basePath}/chat`, handlers.chat);\n app.post(`${basePath}/new-chat`, handlers.newChat);\n app.get(`${basePath}/history`, handlers.history);\n app.get(`${basePath}/conversations/:chatId`, handlers.conversation);\n}\n\nexport { type ChatOptions, type BootstrapOptions };\n"],"mappings":"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","names":["MNEXIUM_API_BASE","parseCookies","MNEXIUM_API_BASE","parseCookies"]}
@@ -32,9 +32,9 @@ function createCookie(name, value, secure = true) {
32
32
  return parts.join("; ");
33
33
  }
34
34
  async function bootstrapHandler(req, options = {}) {
35
- const { cookiePrefix = "mnx" } = options;
35
+ const { cookiePrefix = "mnx", chatPrefix } = options;
36
36
  const subjectCookieName = `${cookiePrefix}_subject`;
37
- const chatCookieName = `${cookiePrefix}_chat`;
37
+ const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${cookiePrefix}_chat`;
38
38
  const cookieHeader = req.headers.get("cookie");
39
39
  const cookies = parseCookies(cookieHeader);
40
40
  let subjectId = cookies[subjectCookieName];
@@ -47,6 +47,9 @@ async function bootstrapHandler(req, options = {}) {
47
47
  }
48
48
  if (!chatId) {
49
49
  const apiKey = process.env.MNX_API_KEY;
50
+ if (!apiKey) {
51
+ console.error("[Mnexium] MNX_API_KEY is not set. Chat history lookup skipped.");
52
+ }
50
53
  if (apiKey) {
51
54
  try {
52
55
  const historyRes = await fetch(`${MNEXIUM_API_BASE}/history/${subjectId}`, {
@@ -85,9 +88,9 @@ async function bootstrapHandler(req, options = {}) {
85
88
  });
86
89
  }
87
90
  async function newChatHandler(req, options = {}) {
88
- const { cookiePrefix = "mnx" } = options;
91
+ const { cookiePrefix = "mnx", chatPrefix } = options;
89
92
  const subjectCookieName = `${cookiePrefix}_subject`;
90
- const chatCookieName = `${cookiePrefix}_chat`;
93
+ const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${cookiePrefix}_chat`;
91
94
  const cookieHeader = req.headers.get("cookie");
92
95
  const cookies = parseCookies(cookieHeader);
93
96
  let subjectId = cookies[subjectCookieName];
@@ -282,6 +285,7 @@ async function chatHandler(req, options = {}) {
282
285
  const {
283
286
  model = "gpt-4o-mini",
284
287
  cookiePrefix = "mnx",
288
+ chatPrefix,
285
289
  mnxOptions = {
286
290
  history: true,
287
291
  learn: true,
@@ -291,7 +295,7 @@ async function chatHandler(req, options = {}) {
291
295
  }
292
296
  } = options;
293
297
  const subjectCookieName = `${cookiePrefix}_subject`;
294
- const chatCookieName = `${cookiePrefix}_chat`;
298
+ const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${cookiePrefix}_chat`;
295
299
  const cookieHeader = req.headers.get("cookie");
296
300
  const cookies = parseCookies2(cookieHeader);
297
301
  const subjectId = cookies[subjectCookieName];
@@ -320,6 +324,7 @@ async function chatHandler(req, options = {}) {
320
324
  }
321
325
  const mnxApiKey = process.env.MNX_API_KEY;
322
326
  if (!mnxApiKey) {
327
+ console.error("[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.");
323
328
  return new Response(
324
329
  JSON.stringify({ error: "Server configuration error: Missing MNX_API_KEY" }),
325
330
  { status: 500, headers: { "Content-Type": "application/json" } }
@@ -419,6 +424,7 @@ async function historyHandler(req, options = {}) {
419
424
  }
420
425
  const apiKey = process.env.MNX_API_KEY;
421
426
  if (!apiKey) {
427
+ console.error("[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.");
422
428
  return new Response(
423
429
  JSON.stringify({ error: "Server configuration error: Missing MNX_API_KEY" }),
424
430
  { status: 500, headers: { "Content-Type": "application/json" } }
@@ -470,6 +476,7 @@ async function conversationHandler(req, chatId, options = {}) {
470
476
  }
471
477
  const apiKey = process.env.MNX_API_KEY;
472
478
  if (!apiKey) {
479
+ console.error("[Mnexium] MNX_API_KEY is not set.Please visit https://mnexium.com/docs#quickstart to get your API key.");
473
480
  return new Response(
474
481
  JSON.stringify({ error: "Server configuration error: Missing MNX_API_KEY" }),
475
482
  { status: 500, headers: { "Content-Type": "application/json" } }
@@ -512,9 +519,9 @@ async function conversationHandler(req, chatId, options = {}) {
512
519
 
513
520
  // src/server/factory.ts
514
521
  function createHandlers(config = {}) {
515
- const { model, cookiePrefix, mnxOptions } = config;
516
- const bootstrapOpts = { cookiePrefix };
517
- const chatOpts = { model, cookiePrefix, mnxOptions };
522
+ const { model, cookiePrefix, chatPrefix, mnxOptions } = config;
523
+ const bootstrapOpts = { cookiePrefix, chatPrefix };
524
+ const chatOpts = { model, cookiePrefix, chatPrefix, mnxOptions };
518
525
  const historyOpts = { cookiePrefix };
519
526
  const conversationOpts = { cookiePrefix };
520
527
  return {
@@ -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","../../src/server/express.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?: 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 if provided\n if (mnxOptions.system_prompt) {\n mnxPayload.system_prompt = mnxOptions.system_prompt;\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?: 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","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler } from './history';\n\n// Express-compatible request/response types (minimal interface)\nexport interface ExpressRequest {\n body?: unknown;\n params?: Record<string, string>;\n cookies?: Record<string, string>;\n headers: Record<string, string | string[] | undefined>;\n url?: string;\n protocol?: string;\n get?: (name: string) => string | undefined;\n}\n\nexport interface ExpressResponse {\n status(code: number): ExpressResponse;\n json(data: unknown): void;\n send(data: string | Buffer): void;\n setHeader(name: string, value: string): ExpressResponse;\n write(chunk: string | Buffer): boolean;\n end(): void;\n headersSent?: boolean;\n}\n\nexport interface MnexiumExpressOptions {\n cookiePrefix?: string;\n chatOptions?: ChatOptions;\n bootstrapOptions?: BootstrapOptions;\n}\n\n// Convert Express request to Web API Request\nfunction toWebRequest(req: ExpressRequest, body?: unknown): Request {\n // Build headers\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n }\n\n // Build URL\n const protocol = req.protocol || (req.get?.('x-forwarded-proto')) || 'http';\n const host = req.headers.host || 'localhost';\n const url = `${protocol}://${host}${req.url || '/'}`;\n\n // Create Request\n const init: RequestInit = {\n method: body ? 'POST' : 'GET',\n headers,\n };\n\n if (body) {\n init.body = JSON.stringify(body);\n headers.set('Content-Type', 'application/json');\n }\n\n return new Request(url, init);\n}\n\n// Send Web API Response to Express response\nasync function sendWebResponse(webRes: Response, res: ExpressResponse): Promise<void> {\n // Copy status\n res.status(webRes.status);\n\n // Copy headers\n webRes.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n\n // Handle streaming response\n if (webRes.body) {\n const reader = webRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(decoder.decode(value, { stream: true }));\n }\n } finally {\n res.end();\n }\n } else {\n // Non-streaming response\n const text = await webRes.text();\n res.send(text);\n }\n}\n\nexport function createExpressMiddleware(options: MnexiumExpressOptions = {}) {\n const { cookiePrefix = 'mnx', chatOptions = {}, bootstrapOptions = {} } = options;\n\n return {\n // POST /chat\n chat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req, req.body);\n const webRes = await chatHandler(webReq, { ...chatOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /bootstrap\n bootstrap: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await bootstrapHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Bootstrap error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // POST /new-chat\n newChat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await newChatHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('New chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /history\n history: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await historyHandler(webReq, { cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('History error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /conversations/:chatId\n conversation: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const chatId = req.params?.chatId;\n if (!chatId) {\n res.status(400).json({ error: 'Chat ID required' });\n return;\n }\n const webReq = toWebRequest(req);\n const webRes = await conversationHandler(webReq, chatId);\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Conversation error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n };\n}\n\n// Helper to mount all routes at once\nexport function mountMnexiumRoutes(\n app: { \n get: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n post: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n },\n basePath: string,\n options: MnexiumExpressOptions = {}\n): void {\n const handlers = createExpressMiddleware(options);\n \n app.get(`${basePath}/bootstrap`, handlers.bootstrap);\n app.post(`${basePath}/chat`, handlers.chat);\n app.post(`${basePath}/new-chat`, handlers.newChat);\n app.get(`${basePath}/history`, handlers.history);\n app.get(`${basePath}/conversations/:chatId`, handlers.conversation);\n}\n\nexport { type ChatOptions, type BootstrapOptions };\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","../../src/server/express.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 chatPrefix?: 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', chatPrefix } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${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 console.error('[Mnexium] MNX_API_KEY is not set. Chat history lookup skipped.');\n }\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', chatPrefix } = options;\n const subjectCookieName = `${cookiePrefix}_subject`;\n const chatCookieName = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${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 chatPrefix?: 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?: 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 chatPrefix,\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 = chatPrefix ? `${cookiePrefix}${chatPrefix}_chat` : `${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 console.error('[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.');\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 if provided\n if (mnxOptions.system_prompt) {\n mnxPayload.system_prompt = mnxOptions.system_prompt;\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 console.error('[Mnexium] MNX_API_KEY is not set. Please visit https://mnexium.com/docs#quickstart to get your API key.');\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 console.error('[Mnexium] MNX_API_KEY is not set.Please visit https://mnexium.com/docs#quickstart to get your API key.');\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 chatPrefix?: 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?: 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, chatPrefix, mnxOptions } = config;\n\n const bootstrapOpts: BootstrapOptions = { cookiePrefix, chatPrefix };\n const chatOpts: ChatOptions = { model, cookiePrefix, chatPrefix, 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","import { bootstrapHandler, newChatHandler, type BootstrapOptions } from './bootstrap';\nimport { chatHandler, type ChatOptions } from './chat';\nimport { historyHandler, conversationHandler } from './history';\n\n// Express-compatible request/response types (minimal interface)\nexport interface ExpressRequest {\n body?: unknown;\n params?: Record<string, string>;\n cookies?: Record<string, string>;\n headers: Record<string, string | string[] | undefined>;\n url?: string;\n protocol?: string;\n get?: (name: string) => string | undefined;\n}\n\nexport interface ExpressResponse {\n status(code: number): ExpressResponse;\n json(data: unknown): void;\n send(data: string | Buffer): void;\n setHeader(name: string, value: string): ExpressResponse;\n write(chunk: string | Buffer): boolean;\n end(): void;\n headersSent?: boolean;\n}\n\nexport interface MnexiumExpressOptions {\n cookiePrefix?: string;\n chatOptions?: ChatOptions;\n bootstrapOptions?: BootstrapOptions;\n}\n\n// Convert Express request to Web API Request\nfunction toWebRequest(req: ExpressRequest, body?: unknown): Request {\n // Build headers\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n }\n\n // Build URL\n const protocol = req.protocol || (req.get?.('x-forwarded-proto')) || 'http';\n const host = req.headers.host || 'localhost';\n const url = `${protocol}://${host}${req.url || '/'}`;\n\n // Create Request\n const init: RequestInit = {\n method: body ? 'POST' : 'GET',\n headers,\n };\n\n if (body) {\n init.body = JSON.stringify(body);\n headers.set('Content-Type', 'application/json');\n }\n\n return new Request(url, init);\n}\n\n// Send Web API Response to Express response\nasync function sendWebResponse(webRes: Response, res: ExpressResponse): Promise<void> {\n // Copy status\n res.status(webRes.status);\n\n // Copy headers\n webRes.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n\n // Handle streaming response\n if (webRes.body) {\n const reader = webRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(decoder.decode(value, { stream: true }));\n }\n } finally {\n res.end();\n }\n } else {\n // Non-streaming response\n const text = await webRes.text();\n res.send(text);\n }\n}\n\nexport function createExpressMiddleware(options: MnexiumExpressOptions = {}) {\n const { cookiePrefix = 'mnx', chatOptions = {}, bootstrapOptions = {} } = options;\n\n return {\n // POST /chat\n chat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req, req.body);\n const webRes = await chatHandler(webReq, { ...chatOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /bootstrap\n bootstrap: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await bootstrapHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Bootstrap error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // POST /new-chat\n newChat: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await newChatHandler(webReq, { ...bootstrapOptions, cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('New chat error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /history\n history: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const webReq = toWebRequest(req);\n const webRes = await historyHandler(webReq, { cookiePrefix });\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('History error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n\n // GET /conversations/:chatId\n conversation: async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n try {\n const chatId = req.params?.chatId;\n if (!chatId) {\n res.status(400).json({ error: 'Chat ID required' });\n return;\n }\n const webReq = toWebRequest(req);\n const webRes = await conversationHandler(webReq, chatId);\n await sendWebResponse(webRes, res);\n } catch (error) {\n console.error('Conversation error:', error);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n },\n };\n}\n\n// Helper to mount all routes at once\nexport function mountMnexiumRoutes(\n app: { \n get: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n post: (path: string, handler: (req: ExpressRequest, res: ExpressResponse) => Promise<void>) => void;\n },\n basePath: string,\n options: MnexiumExpressOptions = {}\n): void {\n const handlers = createExpressMiddleware(options);\n \n app.get(`${basePath}/bootstrap`, handlers.bootstrap);\n app.post(`${basePath}/chat`, handlers.chat);\n app.post(`${basePath}/new-chat`, handlers.newChat);\n app.get(`${basePath}/history`, handlers.history);\n app.get(`${basePath}/conversations/:chatId`, handlers.conversation);\n}\n\nexport { type ChatOptions, type BootstrapOptions };\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",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "Drop-in chat widget with AI memory powered by Mnexium - works with React, Express, or vanilla JS",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",