@mzhub/cortex 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +0 -0
  2. package/dist/{BaseAdapter-WunbfD_n.d.ts → BaseAdapter-BcNZrPzG.d.ts} +1 -1
  3. package/dist/{BaseAdapter-Bjj4JG_S.d.mts → BaseAdapter-CH2Gg9xO.d.mts} +1 -1
  4. package/dist/BaseProvider-8dmLKPhr.d.mts +61 -0
  5. package/dist/BaseProvider-DgYEmkh_.d.ts +61 -0
  6. package/dist/adapters/index.d.mts +4 -4
  7. package/dist/adapters/index.d.ts +4 -4
  8. package/dist/adapters/index.js +9 -1
  9. package/dist/adapters/index.js.map +1 -1
  10. package/dist/adapters/index.mjs +9 -1
  11. package/dist/adapters/index.mjs.map +1 -1
  12. package/dist/{index-DnOyj7gs.d.ts → index-BHvGS1BY.d.mts} +14 -10
  13. package/dist/{index-C_w3EJQT.d.mts → index-CA79C0tz.d.ts} +14 -10
  14. package/dist/index.d.mts +16 -13
  15. package/dist/index.d.ts +16 -13
  16. package/dist/index.js +277 -135
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +277 -135
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/middleware/index.d.mts +4 -4
  21. package/dist/middleware/index.d.ts +4 -4
  22. package/dist/middleware/index.js +0 -0
  23. package/dist/middleware/index.js.map +1 -1
  24. package/dist/middleware/index.mjs +0 -0
  25. package/dist/middleware/index.mjs.map +1 -1
  26. package/dist/providers/index.d.mts +2 -2
  27. package/dist/providers/index.d.ts +2 -2
  28. package/dist/providers/index.js +72 -17
  29. package/dist/providers/index.js.map +1 -1
  30. package/dist/providers/index.mjs +72 -17
  31. package/dist/providers/index.mjs.map +1 -1
  32. package/dist/{types-DybcUhEZ.d.mts → types-DUn4u5hk.d.mts} +1 -1
  33. package/dist/{types-DybcUhEZ.d.ts → types-DUn4u5hk.d.ts} +1 -1
  34. package/logo.png +0 -0
  35. package/package.json +20 -19
  36. package/dist/BaseProvider-B8x1pJXP.d.mts +0 -34
  37. package/dist/BaseProvider-BIkJVjtg.d.ts +0 -34
@@ -1,4 +1,4 @@
1
- export { b as MemoryMiddlewareOptions, e as MiddlewareRequest, f as MiddlewareResponse, N as NextFunction, c as createMemoryMiddleware, d as digestAfterResponse, w as withMemory } from '../index-C_w3EJQT.mjs';
2
- import '../types-DybcUhEZ.mjs';
3
- import '../BaseAdapter-Bjj4JG_S.mjs';
4
- import '../BaseProvider-B8x1pJXP.mjs';
1
+ export { M as MemoryMiddlewareOptions, e as MiddlewareRequest, f as MiddlewareResponse, N as NextFunction, c as createMemoryMiddleware, d as digestAfterResponse, w as withMemory } from '../index-BHvGS1BY.mjs';
2
+ import '../types-DUn4u5hk.mjs';
3
+ import '../BaseAdapter-CH2Gg9xO.mjs';
4
+ import '../BaseProvider-8dmLKPhr.mjs';
@@ -1,4 +1,4 @@
1
- export { b as MemoryMiddlewareOptions, e as MiddlewareRequest, f as MiddlewareResponse, N as NextFunction, c as createMemoryMiddleware, d as digestAfterResponse, w as withMemory } from '../index-DnOyj7gs.js';
2
- import '../types-DybcUhEZ.js';
3
- import '../BaseAdapter-WunbfD_n.js';
4
- import '../BaseProvider-BIkJVjtg.js';
1
+ export { M as MemoryMiddlewareOptions, e as MiddlewareRequest, f as MiddlewareResponse, N as NextFunction, c as createMemoryMiddleware, d as digestAfterResponse, w as withMemory } from '../index-CA79C0tz.js';
2
+ import '../types-DUn4u5hk.js';
3
+ import '../BaseAdapter-BcNZrPzG.js';
4
+ import '../BaseProvider-DgYEmkh_.js';
File without changes
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/middleware/index.ts"],"names":[],"mappings":";;;AAiFO,SAAS,sBAAA,CACd,MAAA,EACA,OAAA,GAAmC,EAAC,EACpC;AACA,EAAA,MAAM;AAAA,IACJ,SAAA,GAAY,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,MAAM,GAAA,CAAI,IAAA,EAAM,MAAA,IAAU,GAAA,CAAI,IAAA,EAAM,MAAA;AAAA,IACnE,UAAA,GAAa,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,OAAA;AAAA,IAChC,eAAA,GAAkB;AAAA,GACpB,GAAI,OAAA;AAEJ,EAAA,OAAO,OACL,GAAA,EACA,GAAA,EACA,IAAA,KACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,UAAU,GAAG,CAAA;AAC5B,MAAA,MAAM,OAAA,GAAU,WAAW,GAAG,CAAA;AAE9B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAA,EAAK;AAAA,MACd;AAGA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AAGpD,MAAA,IAAI,eAAA,EAAiB;AACnB,QAAA,GAAA,CAAI,aAAA,GAAgB,OAAA;AACpB,QAAA,IAAI,IAAI,MAAA,EAAQ;AACd,UAAA,GAAA,CAAI,OAAO,aAAA,GAAgB,OAAA;AAAA,QAC7B;AAAA,MACF;AAEA,MAAA,IAAA,EAAK;AAAA,IACP,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACZ;AAAA,EACF,CAAA;AACF;AAiBO,SAAS,mBAAA,CACd,MAAA,EACA,MAAA,EACA,WAAA,EACA,iBAAA,EACM;AAEN,EAAA,YAAA,CAAa,MAAM;AACjB,IAAA,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,WAAA,EAAa,iBAAiB,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;AAmBO,SAAS,UAAA,CAGd,MAAA,EACA,OAAA,EACA,OAAA,GAGI,EAAC,EACL;AACA,EAAA,OAAO,OAAO,GAAA,KAA8B;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,GAAY,GAAG,KAAK,IAAA,EAAM,MAAA;AACjD,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,UAAA,GAAa,IAAI,KAAK,IAAA,EAAM,OAAA;AAEpD,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAI,QAAA;AAAA,UACT,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mCAAmC,CAAA;AAAA,UAC3D,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAS,EAAE,cAAA,EAAgB,oBAAmB;AAAE,SACjE;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AACpD,MAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,gBAAA;AACzD,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG;AAAA,QACtD,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACF","file":"index.js","sourcesContent":["import type { MemoryOS } from \"../MemoryOS\";\r\nimport type { HydratedContext } from \"../types\";\r\n\r\n/**\r\n * Express/Connect-style request object\r\n */\r\nexport interface MiddlewareRequest {\r\n body?: { userId?: string; message?: string; [key: string]: unknown };\r\n params?: Record<string, string>;\r\n query?: Record<string, string>;\r\n headers?: Record<string, string | string[] | undefined>;\r\n user?: { id?: string; userId?: string; [key: string]: unknown };\r\n memoryContext?: HydratedContext;\r\n}\r\n\r\n/**\r\n * Express/Connect-style response object\r\n */\r\nexport interface MiddlewareResponse {\r\n locals?: Record<string, unknown>;\r\n json?: (body: unknown) => void;\r\n on?: (event: string, callback: () => void) => void;\r\n}\r\n\r\n/**\r\n * Next function to call the next middleware\r\n */\r\nexport type NextFunction = (error?: unknown) => void;\r\n\r\n/**\r\n * Options for the memory middleware\r\n */\r\nexport interface MemoryMiddlewareOptions {\r\n /** Function to extract userId from request */\r\n getUserId?: (req: MiddlewareRequest) => string | undefined;\r\n /** Function to extract user message from request */\r\n getMessage?: (req: MiddlewareRequest) => string | undefined;\r\n /** Attach context to request object */\r\n attachToRequest?: boolean;\r\n /** Auto-digest on response finish (requires response body capture) */\r\n autoDigest?: boolean;\r\n}\r\n\r\n/**\r\n * Result attached to request/response\r\n */\r\ndeclare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace Express {\r\n interface Request {\r\n memoryContext?: HydratedContext;\r\n }\r\n interface Locals {\r\n memoryContext?: HydratedContext;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create Express middleware for automatic context hydration.\r\n *\r\n * @example\r\n * ```typescript\r\n * import express from 'express';\r\n * import { MemoryOS } from 'mem-ts';\r\n * import { createMemoryMiddleware } from 'mem-ts/middleware';\r\n *\r\n * const app = express();\r\n * const memory = new MemoryOS({ ... });\r\n *\r\n * app.use('/chat', createMemoryMiddleware(memory, {\r\n * getUserId: (req) => req.user?.id,\r\n * getMessage: (req) => req.body?.message,\r\n * }));\r\n *\r\n * app.post('/chat', (req, res) => {\r\n * const context = req.memoryContext;\r\n * // Use context.compiledPrompt in your LLM call\r\n * });\r\n * ```\r\n */\r\nexport function createMemoryMiddleware(\r\n memory: MemoryOS,\r\n options: MemoryMiddlewareOptions = {}\r\n) {\r\n const {\r\n getUserId = (req) => req.user?.id || req.user?.userId || req.body?.userId,\r\n getMessage = (req) => req.body?.message,\r\n attachToRequest = true,\r\n } = options;\r\n\r\n return async (\r\n req: MiddlewareRequest,\r\n res: MiddlewareResponse,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n const userId = getUserId(req);\r\n const message = getMessage(req);\r\n\r\n if (!userId || !message) {\r\n return next();\r\n }\r\n\r\n // Hydrate context\r\n const context = await memory.hydrate(userId, message);\r\n\r\n // Attach to request\r\n if (attachToRequest) {\r\n req.memoryContext = context;\r\n if (res.locals) {\r\n res.locals.memoryContext = context;\r\n }\r\n }\r\n\r\n next();\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to digest after response in Express.\r\n * Call this after sending the response.\r\n *\r\n * @example\r\n * ```typescript\r\n * app.post('/chat', async (req, res) => {\r\n * const response = await callLLM(req.memoryContext, req.body.message);\r\n * res.json({ message: response });\r\n *\r\n * // Digest in background\r\n * digestAfterResponse(memory, req.user.id, req.body.message, response);\r\n * });\r\n * ```\r\n */\r\nexport function digestAfterResponse(\r\n memory: MemoryOS,\r\n userId: string,\r\n userMessage: string,\r\n assistantResponse: string\r\n): void {\r\n // Fire and forget\r\n setImmediate(() => {\r\n memory.digest(userId, userMessage, assistantResponse);\r\n });\r\n}\r\n\r\n/**\r\n * Create a Next.js API route handler wrapper.\r\n *\r\n * @example\r\n * ```typescript\r\n * // pages/api/chat.ts or app/api/chat/route.ts\r\n * import { withMemory } from 'mem-ts/middleware';\r\n *\r\n * export const POST = withMemory(memory, async (req, context) => {\r\n * const { message } = await req.json();\r\n * const response = await callLLM(context.compiledPrompt, message);\r\n * return Response.json({ message: response });\r\n * }, {\r\n * getUserId: (req) => req.headers.get('x-user-id'),\r\n * });\r\n * ```\r\n */\r\nexport function withMemory<\r\n T extends { json: () => Promise<{ message?: string; userId?: string }> }\r\n>(\r\n memory: MemoryOS,\r\n handler: (req: T, context: HydratedContext) => Promise<Response>,\r\n options: {\r\n getUserId?: (req: T) => string | null | undefined;\r\n getMessage?: (body: { message?: string }) => string | undefined;\r\n } = {}\r\n) {\r\n return async (req: T): Promise<Response> => {\r\n try {\r\n const body = await req.json();\r\n const userId = options.getUserId?.(req) || body?.userId;\r\n const message = options.getMessage?.(body) || body?.message;\r\n\r\n if (!userId || !message) {\r\n return new Response(\r\n JSON.stringify({ error: \"userId and message are required\" }),\r\n { status: 400, headers: { \"Content-Type\": \"application/json\" } }\r\n );\r\n }\r\n\r\n const context = await memory.hydrate(userId, message);\r\n return handler(req, context);\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : \"Internal error\";\r\n return new Response(JSON.stringify({ error: message }), {\r\n status: 500,\r\n headers: { \"Content-Type\": \"application/json\" },\r\n });\r\n }\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/middleware/index.ts"],"names":[],"mappings":";;;AAiFO,SAAS,sBAAA,CACd,MAAA,EACA,OAAA,GAAmC,EAAC,EACpC;AACA,EAAA,MAAM;AAAA,IACJ,SAAA,GAAY,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,MAAM,GAAA,CAAI,IAAA,EAAM,MAAA,IAAU,GAAA,CAAI,IAAA,EAAM,MAAA;AAAA,IACnE,UAAA,GAAa,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,OAAA;AAAA,IAChC,eAAA,GAAkB;AAAA,GACpB,GAAI,OAAA;AAEJ,EAAA,OAAO,OACL,GAAA,EACA,GAAA,EACA,IAAA,KACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,UAAU,GAAG,CAAA;AAC5B,MAAA,MAAM,OAAA,GAAU,WAAW,GAAG,CAAA;AAE9B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAA,EAAK;AAAA,MACd;AAGA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AAGpD,MAAA,IAAI,eAAA,EAAiB;AACnB,QAAA,GAAA,CAAI,aAAA,GAAgB,OAAA;AACpB,QAAA,IAAI,IAAI,MAAA,EAAQ;AACd,UAAA,GAAA,CAAI,OAAO,aAAA,GAAgB,OAAA;AAAA,QAC7B;AAAA,MACF;AAEA,MAAA,IAAA,EAAK;AAAA,IACP,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACZ;AAAA,EACF,CAAA;AACF;AAiBO,SAAS,mBAAA,CACd,MAAA,EACA,MAAA,EACA,WAAA,EACA,iBAAA,EACM;AAEN,EAAA,YAAA,CAAa,MAAM;AACjB,IAAA,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,WAAA,EAAa,iBAAiB,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;AAmBO,SAAS,UAAA,CAGd,MAAA,EACA,OAAA,EACA,OAAA,GAGI,EAAC,EACL;AACA,EAAA,OAAO,OAAO,GAAA,KAA8B;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,GAAY,GAAG,KAAK,IAAA,EAAM,MAAA;AACjD,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,UAAA,GAAa,IAAI,KAAK,IAAA,EAAM,OAAA;AAEpD,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAI,QAAA;AAAA,UACT,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mCAAmC,CAAA;AAAA,UAC3D,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAS,EAAE,cAAA,EAAgB,oBAAmB;AAAE,SACjE;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AACpD,MAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,gBAAA;AACzD,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG;AAAA,QACtD,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACF","file":"index.js","sourcesContent":["import type { MemoryOS } from \"../MemoryOS\";\r\nimport type { HydratedContext } from \"../types\";\r\n\r\n/**\r\n * Express/Connect-style request object\r\n */\r\nexport interface MiddlewareRequest {\r\n body?: { userId?: string; message?: string; [key: string]: unknown };\r\n params?: Record<string, string>;\r\n query?: Record<string, string>;\r\n headers?: Record<string, string | string[] | undefined>;\r\n user?: { id?: string; userId?: string; [key: string]: unknown };\r\n memoryContext?: HydratedContext;\r\n}\r\n\r\n/**\r\n * Express/Connect-style response object\r\n */\r\nexport interface MiddlewareResponse {\r\n locals?: Record<string, unknown>;\r\n json?: (body: unknown) => void;\r\n on?: (event: string, callback: () => void) => void;\r\n}\r\n\r\n/**\r\n * Next function to call the next middleware\r\n */\r\nexport type NextFunction = (error?: unknown) => void;\r\n\r\n/**\r\n * Options for the memory middleware\r\n */\r\nexport interface MemoryMiddlewareOptions {\r\n /** Function to extract userId from request */\r\n getUserId?: (req: MiddlewareRequest) => string | undefined;\r\n /** Function to extract user message from request */\r\n getMessage?: (req: MiddlewareRequest) => string | undefined;\r\n /** Attach context to request object */\r\n attachToRequest?: boolean;\r\n /** Auto-digest on response finish (requires response body capture) */\r\n autoDigest?: boolean;\r\n}\r\n\r\n/**\r\n * Result attached to request/response\r\n */\r\ndeclare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace Express {\r\n interface Request {\r\n memoryContext?: HydratedContext;\r\n }\r\n interface Locals {\r\n memoryContext?: HydratedContext;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create Express middleware for automatic context hydration.\r\n *\r\n * @example\r\n * ```typescript\r\n * import express from 'express';\r\n * import { MemoryOS } from 'cortex';\r\n * import { createMemoryMiddleware } from 'cortex/middleware';\r\n *\r\n * const app = express();\r\n * const memory = new MemoryOS({ ... });\r\n *\r\n * app.use('/chat', createMemoryMiddleware(memory, {\r\n * getUserId: (req) => req.user?.id,\r\n * getMessage: (req) => req.body?.message,\r\n * }));\r\n *\r\n * app.post('/chat', (req, res) => {\r\n * const context = req.memoryContext;\r\n * // Use context.compiledPrompt in your LLM call\r\n * });\r\n * ```\r\n */\r\nexport function createMemoryMiddleware(\r\n memory: MemoryOS,\r\n options: MemoryMiddlewareOptions = {},\r\n) {\r\n const {\r\n getUserId = (req) => req.user?.id || req.user?.userId || req.body?.userId,\r\n getMessage = (req) => req.body?.message,\r\n attachToRequest = true,\r\n } = options;\r\n\r\n return async (\r\n req: MiddlewareRequest,\r\n res: MiddlewareResponse,\r\n next: NextFunction,\r\n ): Promise<void> => {\r\n try {\r\n const userId = getUserId(req);\r\n const message = getMessage(req);\r\n\r\n if (!userId || !message) {\r\n return next();\r\n }\r\n\r\n // Hydrate context\r\n const context = await memory.hydrate(userId, message);\r\n\r\n // Attach to request\r\n if (attachToRequest) {\r\n req.memoryContext = context;\r\n if (res.locals) {\r\n res.locals.memoryContext = context;\r\n }\r\n }\r\n\r\n next();\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to digest after response in Express.\r\n * Call this after sending the response.\r\n *\r\n * @example\r\n * ```typescript\r\n * app.post('/chat', async (req, res) => {\r\n * const response = await callLLM(req.memoryContext, req.body.message);\r\n * res.json({ message: response });\r\n *\r\n * // Digest in background\r\n * digestAfterResponse(memory, req.user.id, req.body.message, response);\r\n * });\r\n * ```\r\n */\r\nexport function digestAfterResponse(\r\n memory: MemoryOS,\r\n userId: string,\r\n userMessage: string,\r\n assistantResponse: string,\r\n): void {\r\n // Fire and forget\r\n setImmediate(() => {\r\n memory.digest(userId, userMessage, assistantResponse);\r\n });\r\n}\r\n\r\n/**\r\n * Create a Next.js API route handler wrapper.\r\n *\r\n * @example\r\n * ```typescript\r\n * // pages/api/chat.ts or app/api/chat/route.ts\r\n * import { withMemory } from 'cortex/middleware';\r\n *\r\n * export const POST = withMemory(memory, async (req, context) => {\r\n * const { message } = await req.json();\r\n * const response = await callLLM(context.compiledPrompt, message);\r\n * return Response.json({ message: response });\r\n * }, {\r\n * getUserId: (req) => req.headers.get('x-user-id'),\r\n * });\r\n * ```\r\n */\r\nexport function withMemory<\r\n T extends { json: () => Promise<{ message?: string; userId?: string }> },\r\n>(\r\n memory: MemoryOS,\r\n handler: (req: T, context: HydratedContext) => Promise<Response>,\r\n options: {\r\n getUserId?: (req: T) => string | null | undefined;\r\n getMessage?: (body: { message?: string }) => string | undefined;\r\n } = {},\r\n) {\r\n return async (req: T): Promise<Response> => {\r\n try {\r\n const body = await req.json();\r\n const userId = options.getUserId?.(req) || body?.userId;\r\n const message = options.getMessage?.(body) || body?.message;\r\n\r\n if (!userId || !message) {\r\n return new Response(\r\n JSON.stringify({ error: \"userId and message are required\" }),\r\n { status: 400, headers: { \"Content-Type\": \"application/json\" } },\r\n );\r\n }\r\n\r\n const context = await memory.hydrate(userId, message);\r\n return handler(req, context);\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : \"Internal error\";\r\n return new Response(JSON.stringify({ error: message }), {\r\n status: 500,\r\n headers: { \"Content-Type\": \"application/json\" },\r\n });\r\n }\r\n };\r\n}\r\n"]}
File without changes
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/middleware/index.ts"],"names":[],"mappings":";AAiFO,SAAS,sBAAA,CACd,MAAA,EACA,OAAA,GAAmC,EAAC,EACpC;AACA,EAAA,MAAM;AAAA,IACJ,SAAA,GAAY,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,MAAM,GAAA,CAAI,IAAA,EAAM,MAAA,IAAU,GAAA,CAAI,IAAA,EAAM,MAAA;AAAA,IACnE,UAAA,GAAa,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,OAAA;AAAA,IAChC,eAAA,GAAkB;AAAA,GACpB,GAAI,OAAA;AAEJ,EAAA,OAAO,OACL,GAAA,EACA,GAAA,EACA,IAAA,KACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,UAAU,GAAG,CAAA;AAC5B,MAAA,MAAM,OAAA,GAAU,WAAW,GAAG,CAAA;AAE9B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAA,EAAK;AAAA,MACd;AAGA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AAGpD,MAAA,IAAI,eAAA,EAAiB;AACnB,QAAA,GAAA,CAAI,aAAA,GAAgB,OAAA;AACpB,QAAA,IAAI,IAAI,MAAA,EAAQ;AACd,UAAA,GAAA,CAAI,OAAO,aAAA,GAAgB,OAAA;AAAA,QAC7B;AAAA,MACF;AAEA,MAAA,IAAA,EAAK;AAAA,IACP,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACZ;AAAA,EACF,CAAA;AACF;AAiBO,SAAS,mBAAA,CACd,MAAA,EACA,MAAA,EACA,WAAA,EACA,iBAAA,EACM;AAEN,EAAA,YAAA,CAAa,MAAM;AACjB,IAAA,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,WAAA,EAAa,iBAAiB,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;AAmBO,SAAS,UAAA,CAGd,MAAA,EACA,OAAA,EACA,OAAA,GAGI,EAAC,EACL;AACA,EAAA,OAAO,OAAO,GAAA,KAA8B;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,GAAY,GAAG,KAAK,IAAA,EAAM,MAAA;AACjD,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,UAAA,GAAa,IAAI,KAAK,IAAA,EAAM,OAAA;AAEpD,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAI,QAAA;AAAA,UACT,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mCAAmC,CAAA;AAAA,UAC3D,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAS,EAAE,cAAA,EAAgB,oBAAmB;AAAE,SACjE;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AACpD,MAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,gBAAA;AACzD,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG;AAAA,QACtD,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACF","file":"index.mjs","sourcesContent":["import type { MemoryOS } from \"../MemoryOS\";\r\nimport type { HydratedContext } from \"../types\";\r\n\r\n/**\r\n * Express/Connect-style request object\r\n */\r\nexport interface MiddlewareRequest {\r\n body?: { userId?: string; message?: string; [key: string]: unknown };\r\n params?: Record<string, string>;\r\n query?: Record<string, string>;\r\n headers?: Record<string, string | string[] | undefined>;\r\n user?: { id?: string; userId?: string; [key: string]: unknown };\r\n memoryContext?: HydratedContext;\r\n}\r\n\r\n/**\r\n * Express/Connect-style response object\r\n */\r\nexport interface MiddlewareResponse {\r\n locals?: Record<string, unknown>;\r\n json?: (body: unknown) => void;\r\n on?: (event: string, callback: () => void) => void;\r\n}\r\n\r\n/**\r\n * Next function to call the next middleware\r\n */\r\nexport type NextFunction = (error?: unknown) => void;\r\n\r\n/**\r\n * Options for the memory middleware\r\n */\r\nexport interface MemoryMiddlewareOptions {\r\n /** Function to extract userId from request */\r\n getUserId?: (req: MiddlewareRequest) => string | undefined;\r\n /** Function to extract user message from request */\r\n getMessage?: (req: MiddlewareRequest) => string | undefined;\r\n /** Attach context to request object */\r\n attachToRequest?: boolean;\r\n /** Auto-digest on response finish (requires response body capture) */\r\n autoDigest?: boolean;\r\n}\r\n\r\n/**\r\n * Result attached to request/response\r\n */\r\ndeclare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace Express {\r\n interface Request {\r\n memoryContext?: HydratedContext;\r\n }\r\n interface Locals {\r\n memoryContext?: HydratedContext;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create Express middleware for automatic context hydration.\r\n *\r\n * @example\r\n * ```typescript\r\n * import express from 'express';\r\n * import { MemoryOS } from 'mem-ts';\r\n * import { createMemoryMiddleware } from 'mem-ts/middleware';\r\n *\r\n * const app = express();\r\n * const memory = new MemoryOS({ ... });\r\n *\r\n * app.use('/chat', createMemoryMiddleware(memory, {\r\n * getUserId: (req) => req.user?.id,\r\n * getMessage: (req) => req.body?.message,\r\n * }));\r\n *\r\n * app.post('/chat', (req, res) => {\r\n * const context = req.memoryContext;\r\n * // Use context.compiledPrompt in your LLM call\r\n * });\r\n * ```\r\n */\r\nexport function createMemoryMiddleware(\r\n memory: MemoryOS,\r\n options: MemoryMiddlewareOptions = {}\r\n) {\r\n const {\r\n getUserId = (req) => req.user?.id || req.user?.userId || req.body?.userId,\r\n getMessage = (req) => req.body?.message,\r\n attachToRequest = true,\r\n } = options;\r\n\r\n return async (\r\n req: MiddlewareRequest,\r\n res: MiddlewareResponse,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n const userId = getUserId(req);\r\n const message = getMessage(req);\r\n\r\n if (!userId || !message) {\r\n return next();\r\n }\r\n\r\n // Hydrate context\r\n const context = await memory.hydrate(userId, message);\r\n\r\n // Attach to request\r\n if (attachToRequest) {\r\n req.memoryContext = context;\r\n if (res.locals) {\r\n res.locals.memoryContext = context;\r\n }\r\n }\r\n\r\n next();\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to digest after response in Express.\r\n * Call this after sending the response.\r\n *\r\n * @example\r\n * ```typescript\r\n * app.post('/chat', async (req, res) => {\r\n * const response = await callLLM(req.memoryContext, req.body.message);\r\n * res.json({ message: response });\r\n *\r\n * // Digest in background\r\n * digestAfterResponse(memory, req.user.id, req.body.message, response);\r\n * });\r\n * ```\r\n */\r\nexport function digestAfterResponse(\r\n memory: MemoryOS,\r\n userId: string,\r\n userMessage: string,\r\n assistantResponse: string\r\n): void {\r\n // Fire and forget\r\n setImmediate(() => {\r\n memory.digest(userId, userMessage, assistantResponse);\r\n });\r\n}\r\n\r\n/**\r\n * Create a Next.js API route handler wrapper.\r\n *\r\n * @example\r\n * ```typescript\r\n * // pages/api/chat.ts or app/api/chat/route.ts\r\n * import { withMemory } from 'mem-ts/middleware';\r\n *\r\n * export const POST = withMemory(memory, async (req, context) => {\r\n * const { message } = await req.json();\r\n * const response = await callLLM(context.compiledPrompt, message);\r\n * return Response.json({ message: response });\r\n * }, {\r\n * getUserId: (req) => req.headers.get('x-user-id'),\r\n * });\r\n * ```\r\n */\r\nexport function withMemory<\r\n T extends { json: () => Promise<{ message?: string; userId?: string }> }\r\n>(\r\n memory: MemoryOS,\r\n handler: (req: T, context: HydratedContext) => Promise<Response>,\r\n options: {\r\n getUserId?: (req: T) => string | null | undefined;\r\n getMessage?: (body: { message?: string }) => string | undefined;\r\n } = {}\r\n) {\r\n return async (req: T): Promise<Response> => {\r\n try {\r\n const body = await req.json();\r\n const userId = options.getUserId?.(req) || body?.userId;\r\n const message = options.getMessage?.(body) || body?.message;\r\n\r\n if (!userId || !message) {\r\n return new Response(\r\n JSON.stringify({ error: \"userId and message are required\" }),\r\n { status: 400, headers: { \"Content-Type\": \"application/json\" } }\r\n );\r\n }\r\n\r\n const context = await memory.hydrate(userId, message);\r\n return handler(req, context);\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : \"Internal error\";\r\n return new Response(JSON.stringify({ error: message }), {\r\n status: 500,\r\n headers: { \"Content-Type\": \"application/json\" },\r\n });\r\n }\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/middleware/index.ts"],"names":[],"mappings":";AAiFO,SAAS,sBAAA,CACd,MAAA,EACA,OAAA,GAAmC,EAAC,EACpC;AACA,EAAA,MAAM;AAAA,IACJ,SAAA,GAAY,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,MAAM,GAAA,CAAI,IAAA,EAAM,MAAA,IAAU,GAAA,CAAI,IAAA,EAAM,MAAA;AAAA,IACnE,UAAA,GAAa,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,OAAA;AAAA,IAChC,eAAA,GAAkB;AAAA,GACpB,GAAI,OAAA;AAEJ,EAAA,OAAO,OACL,GAAA,EACA,GAAA,EACA,IAAA,KACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,UAAU,GAAG,CAAA;AAC5B,MAAA,MAAM,OAAA,GAAU,WAAW,GAAG,CAAA;AAE9B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAA,EAAK;AAAA,MACd;AAGA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AAGpD,MAAA,IAAI,eAAA,EAAiB;AACnB,QAAA,GAAA,CAAI,aAAA,GAAgB,OAAA;AACpB,QAAA,IAAI,IAAI,MAAA,EAAQ;AACd,UAAA,GAAA,CAAI,OAAO,aAAA,GAAgB,OAAA;AAAA,QAC7B;AAAA,MACF;AAEA,MAAA,IAAA,EAAK;AAAA,IACP,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACZ;AAAA,EACF,CAAA;AACF;AAiBO,SAAS,mBAAA,CACd,MAAA,EACA,MAAA,EACA,WAAA,EACA,iBAAA,EACM;AAEN,EAAA,YAAA,CAAa,MAAM;AACjB,IAAA,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,WAAA,EAAa,iBAAiB,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;AAmBO,SAAS,UAAA,CAGd,MAAA,EACA,OAAA,EACA,OAAA,GAGI,EAAC,EACL;AACA,EAAA,OAAO,OAAO,GAAA,KAA8B;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,GAAY,GAAG,KAAK,IAAA,EAAM,MAAA;AACjD,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,UAAA,GAAa,IAAI,KAAK,IAAA,EAAM,OAAA;AAEpD,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAO,IAAI,QAAA;AAAA,UACT,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mCAAmC,CAAA;AAAA,UAC3D,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAS,EAAE,cAAA,EAAgB,oBAAmB;AAAE,SACjE;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,OAAO,CAAA;AACpD,MAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,gBAAA;AACzD,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG;AAAA,QACtD,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACF","file":"index.mjs","sourcesContent":["import type { MemoryOS } from \"../MemoryOS\";\r\nimport type { HydratedContext } from \"../types\";\r\n\r\n/**\r\n * Express/Connect-style request object\r\n */\r\nexport interface MiddlewareRequest {\r\n body?: { userId?: string; message?: string; [key: string]: unknown };\r\n params?: Record<string, string>;\r\n query?: Record<string, string>;\r\n headers?: Record<string, string | string[] | undefined>;\r\n user?: { id?: string; userId?: string; [key: string]: unknown };\r\n memoryContext?: HydratedContext;\r\n}\r\n\r\n/**\r\n * Express/Connect-style response object\r\n */\r\nexport interface MiddlewareResponse {\r\n locals?: Record<string, unknown>;\r\n json?: (body: unknown) => void;\r\n on?: (event: string, callback: () => void) => void;\r\n}\r\n\r\n/**\r\n * Next function to call the next middleware\r\n */\r\nexport type NextFunction = (error?: unknown) => void;\r\n\r\n/**\r\n * Options for the memory middleware\r\n */\r\nexport interface MemoryMiddlewareOptions {\r\n /** Function to extract userId from request */\r\n getUserId?: (req: MiddlewareRequest) => string | undefined;\r\n /** Function to extract user message from request */\r\n getMessage?: (req: MiddlewareRequest) => string | undefined;\r\n /** Attach context to request object */\r\n attachToRequest?: boolean;\r\n /** Auto-digest on response finish (requires response body capture) */\r\n autoDigest?: boolean;\r\n}\r\n\r\n/**\r\n * Result attached to request/response\r\n */\r\ndeclare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace Express {\r\n interface Request {\r\n memoryContext?: HydratedContext;\r\n }\r\n interface Locals {\r\n memoryContext?: HydratedContext;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create Express middleware for automatic context hydration.\r\n *\r\n * @example\r\n * ```typescript\r\n * import express from 'express';\r\n * import { MemoryOS } from 'cortex';\r\n * import { createMemoryMiddleware } from 'cortex/middleware';\r\n *\r\n * const app = express();\r\n * const memory = new MemoryOS({ ... });\r\n *\r\n * app.use('/chat', createMemoryMiddleware(memory, {\r\n * getUserId: (req) => req.user?.id,\r\n * getMessage: (req) => req.body?.message,\r\n * }));\r\n *\r\n * app.post('/chat', (req, res) => {\r\n * const context = req.memoryContext;\r\n * // Use context.compiledPrompt in your LLM call\r\n * });\r\n * ```\r\n */\r\nexport function createMemoryMiddleware(\r\n memory: MemoryOS,\r\n options: MemoryMiddlewareOptions = {},\r\n) {\r\n const {\r\n getUserId = (req) => req.user?.id || req.user?.userId || req.body?.userId,\r\n getMessage = (req) => req.body?.message,\r\n attachToRequest = true,\r\n } = options;\r\n\r\n return async (\r\n req: MiddlewareRequest,\r\n res: MiddlewareResponse,\r\n next: NextFunction,\r\n ): Promise<void> => {\r\n try {\r\n const userId = getUserId(req);\r\n const message = getMessage(req);\r\n\r\n if (!userId || !message) {\r\n return next();\r\n }\r\n\r\n // Hydrate context\r\n const context = await memory.hydrate(userId, message);\r\n\r\n // Attach to request\r\n if (attachToRequest) {\r\n req.memoryContext = context;\r\n if (res.locals) {\r\n res.locals.memoryContext = context;\r\n }\r\n }\r\n\r\n next();\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to digest after response in Express.\r\n * Call this after sending the response.\r\n *\r\n * @example\r\n * ```typescript\r\n * app.post('/chat', async (req, res) => {\r\n * const response = await callLLM(req.memoryContext, req.body.message);\r\n * res.json({ message: response });\r\n *\r\n * // Digest in background\r\n * digestAfterResponse(memory, req.user.id, req.body.message, response);\r\n * });\r\n * ```\r\n */\r\nexport function digestAfterResponse(\r\n memory: MemoryOS,\r\n userId: string,\r\n userMessage: string,\r\n assistantResponse: string,\r\n): void {\r\n // Fire and forget\r\n setImmediate(() => {\r\n memory.digest(userId, userMessage, assistantResponse);\r\n });\r\n}\r\n\r\n/**\r\n * Create a Next.js API route handler wrapper.\r\n *\r\n * @example\r\n * ```typescript\r\n * // pages/api/chat.ts or app/api/chat/route.ts\r\n * import { withMemory } from 'cortex/middleware';\r\n *\r\n * export const POST = withMemory(memory, async (req, context) => {\r\n * const { message } = await req.json();\r\n * const response = await callLLM(context.compiledPrompt, message);\r\n * return Response.json({ message: response });\r\n * }, {\r\n * getUserId: (req) => req.headers.get('x-user-id'),\r\n * });\r\n * ```\r\n */\r\nexport function withMemory<\r\n T extends { json: () => Promise<{ message?: string; userId?: string }> },\r\n>(\r\n memory: MemoryOS,\r\n handler: (req: T, context: HydratedContext) => Promise<Response>,\r\n options: {\r\n getUserId?: (req: T) => string | null | undefined;\r\n getMessage?: (body: { message?: string }) => string | undefined;\r\n } = {},\r\n) {\r\n return async (req: T): Promise<Response> => {\r\n try {\r\n const body = await req.json();\r\n const userId = options.getUserId?.(req) || body?.userId;\r\n const message = options.getMessage?.(body) || body?.message;\r\n\r\n if (!userId || !message) {\r\n return new Response(\r\n JSON.stringify({ error: \"userId and message are required\" }),\r\n { status: 400, headers: { \"Content-Type\": \"application/json\" } },\r\n );\r\n }\r\n\r\n const context = await memory.hydrate(userId, message);\r\n return handler(req, context);\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : \"Internal error\";\r\n return new Response(JSON.stringify({ error: message }), {\r\n status: 500,\r\n headers: { \"Content-Type\": \"application/json\" },\r\n });\r\n }\r\n };\r\n}\r\n"]}
@@ -1,5 +1,5 @@
1
- import { B as BaseProvider } from '../BaseProvider-B8x1pJXP.mjs';
2
- import { a as CompletionOptions, b as CompletionResult, P as ProviderConfig, e as ProviderName } from '../types-DybcUhEZ.mjs';
1
+ import { B as BaseProvider } from '../BaseProvider-8dmLKPhr.mjs';
2
+ import { a as CompletionOptions, b as CompletionResult, P as ProviderConfig, e as ProviderName } from '../types-DUn4u5hk.mjs';
3
3
 
4
4
  /**
5
5
  * OpenAI provider using native fetch (no SDK required)
@@ -1,5 +1,5 @@
1
- import { B as BaseProvider } from '../BaseProvider-BIkJVjtg.js';
2
- import { a as CompletionOptions, b as CompletionResult, P as ProviderConfig, e as ProviderName } from '../types-DybcUhEZ.js';
1
+ import { B as BaseProvider } from '../BaseProvider-DgYEmkh_.js';
2
+ import { a as CompletionOptions, b as CompletionResult, P as ProviderConfig, e as ProviderName } from '../types-DUn4u5hk.js';
3
3
 
4
4
  /**
5
5
  * OpenAI provider using native fetch (no SDK required)
@@ -12,6 +12,9 @@ var BaseProvider = class {
12
12
  apiKey;
13
13
  model;
14
14
  baseUrl;
15
+ timeoutMs;
16
+ maxRetries;
17
+ retryDelayMs;
15
18
  constructor(config) {
16
19
  if (!config.apiKey) {
17
20
  throw new Error("API key is required");
@@ -19,6 +22,9 @@ var BaseProvider = class {
19
22
  this.apiKey = config.apiKey;
20
23
  this.model = config.model || this.getDefaultModel();
21
24
  this.baseUrl = config.baseUrl;
25
+ this.timeoutMs = config.retry?.timeoutMs ?? 3e4;
26
+ this.maxRetries = config.retry?.maxRetries ?? 3;
27
+ this.retryDelayMs = config.retry?.retryDelayMs ?? 1e3;
22
28
  }
23
29
  /**
24
30
  * Check if the provider SDK is available
@@ -26,6 +32,52 @@ var BaseProvider = class {
26
32
  static isAvailable() {
27
33
  return true;
28
34
  }
35
+ /**
36
+ * Execute a fetch request with timeout and retry logic
37
+ */
38
+ async fetchWithRetry(url, init) {
39
+ let lastError;
40
+ for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
41
+ try {
42
+ const controller = new AbortController();
43
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
44
+ const response = await fetch(url, {
45
+ ...init,
46
+ signal: controller.signal
47
+ });
48
+ clearTimeout(timeoutId);
49
+ if (response.ok || !this.isRetryableStatus(response.status)) {
50
+ return response;
51
+ }
52
+ lastError = new Error(
53
+ `HTTP ${response.status}: ${response.statusText}`
54
+ );
55
+ } catch (error) {
56
+ if (error instanceof Error && error.name === "AbortError") {
57
+ lastError = new Error(`Request timeout after ${this.timeoutMs}ms`);
58
+ } else {
59
+ lastError = error instanceof Error ? error : new Error(String(error));
60
+ }
61
+ }
62
+ if (attempt < this.maxRetries) {
63
+ const delay = this.retryDelayMs * Math.pow(2, attempt - 1);
64
+ await this.sleep(delay);
65
+ }
66
+ }
67
+ throw lastError || new Error("Request failed after retries");
68
+ }
69
+ /**
70
+ * Check if an HTTP status code is retryable
71
+ */
72
+ isRetryableStatus(status) {
73
+ return status === 429 || status === 500 || status === 502 || status === 503 || status === 504;
74
+ }
75
+ /**
76
+ * Sleep for a given number of milliseconds
77
+ */
78
+ sleep(ms) {
79
+ return new Promise((resolve) => setTimeout(resolve, ms));
80
+ }
29
81
  };
30
82
 
31
83
  // src/providers/OpenAIProvider.ts
@@ -49,23 +101,26 @@ var OpenAIProvider = class extends BaseProvider {
49
101
  temperature = 0.3,
50
102
  jsonMode = true
51
103
  } = options;
52
- const response = await fetch(`${this.endpoint}/chat/completions`, {
53
- method: "POST",
54
- headers: {
55
- "Content-Type": "application/json",
56
- Authorization: `Bearer ${this.apiKey}`
57
- },
58
- body: JSON.stringify({
59
- model: this.model,
60
- messages: [
61
- { role: "system", content: systemPrompt },
62
- { role: "user", content: userPrompt }
63
- ],
64
- max_tokens: maxTokens,
65
- temperature,
66
- ...jsonMode && { response_format: { type: "json_object" } }
67
- })
68
- });
104
+ const response = await this.fetchWithRetry(
105
+ `${this.endpoint}/chat/completions`,
106
+ {
107
+ method: "POST",
108
+ headers: {
109
+ "Content-Type": "application/json",
110
+ Authorization: `Bearer ${this.apiKey}`
111
+ },
112
+ body: JSON.stringify({
113
+ model: this.model,
114
+ messages: [
115
+ { role: "system", content: systemPrompt },
116
+ { role: "user", content: userPrompt }
117
+ ],
118
+ max_tokens: maxTokens,
119
+ temperature,
120
+ ...jsonMode && { response_format: { type: "json_object" } }
121
+ })
122
+ }
123
+ );
69
124
  if (!response.ok) {
70
125
  const errorData = await response.json().catch(() => ({ error: { message: response.statusText } }));
71
126
  throw new Error(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/BaseProvider.ts","../../src/providers/OpenAIProvider.ts","../../src/providers/AnthropicProvider.ts","../../src/providers/GeminiProvider.ts","../../src/providers/GroqProvider.ts","../../src/providers/CerebrasProvider.ts","../../src/providers/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Abstract base class for LLM providers.\r\n * All provider implementations must extend this class.\r\n */\r\nexport abstract class BaseProvider {\r\n protected apiKey: string;\r\n protected model: string;\r\n protected baseUrl?: string;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n if (!config.apiKey) {\r\n throw new Error(\"API key is required\");\r\n }\r\n this.apiKey = config.apiKey;\r\n this.model = config.model || this.getDefaultModel();\r\n this.baseUrl = config.baseUrl;\r\n }\r\n\r\n /**\r\n * Get the default model for this provider\r\n */\r\n abstract getDefaultModel(): string;\r\n\r\n /**\r\n * Get the provider name\r\n */\r\n abstract getName(): string;\r\n\r\n /**\r\n * Generate a completion from the LLM\r\n */\r\n abstract complete(options: CompletionOptions): Promise<CompletionResult>;\r\n\r\n /**\r\n * Check if the provider SDK is available\r\n */\r\n static isAvailable(): boolean {\r\n return true;\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * OpenAI provider using native fetch (no SDK required)\r\n */\r\nexport class OpenAIProvider extends BaseProvider {\r\n private endpoint: string;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.endpoint = this.baseUrl || \"https://api.openai.com/v1\";\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gpt-4o-mini\";\r\n }\r\n\r\n getName(): string {\r\n return \"openai\";\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n jsonMode = true,\r\n } = options;\r\n\r\n const response = await fetch(`${this.endpoint}/chat/completions`, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n ...(jsonMode && { response_format: { type: \"json_object\" } }),\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = (await response\r\n .json()\r\n .catch(() => ({ error: { message: response.statusText } }))) as {\r\n error?: { message?: string };\r\n };\r\n throw new Error(\r\n `OpenAI API error: ${errorData.error?.message || response.statusText}`\r\n );\r\n }\r\n\r\n interface OpenAIResponse {\r\n choices: Array<{ message?: { content?: string } }>;\r\n usage?: { prompt_tokens?: number; completion_tokens?: number };\r\n }\r\n\r\n const data = (await response.json()) as OpenAIResponse;\r\n\r\n return {\r\n content: data.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: data.usage?.prompt_tokens || 0,\r\n outputTokens: data.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Anthropic provider using the official @anthropic-ai/sdk package\r\n */\r\nexport class AnthropicProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Anthropic } = await import(\"@anthropic-ai/sdk\");\r\n this.client = new Anthropic({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Anthropic SDK not installed. Run: npm install @anthropic-ai/sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"claude-3-haiku-20240307\";\r\n }\r\n\r\n getName(): string {\r\n return \"anthropic\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@anthropic-ai/sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const message = await client.messages.create({\r\n model: this.model,\r\n max_tokens: maxTokens,\r\n temperature,\r\n system: systemPrompt,\r\n messages: [{ role: \"user\", content: userPrompt }],\r\n });\r\n\r\n return {\r\n content: message.content[0]?.text || \"\",\r\n usage: {\r\n inputTokens: message.usage?.input_tokens || 0,\r\n outputTokens: message.usage?.output_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Google Gemini provider using the official @google/generative-ai package\r\n */\r\nexport class GeminiProvider extends BaseProvider {\r\n private genAI: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { GoogleGenerativeAI } = await import(\"@google/generative-ai\");\r\n this.genAI = new GoogleGenerativeAI(this.apiKey);\r\n } catch {\r\n throw new Error(\r\n \"Google Generative AI SDK not installed. Run: npm install @google/generative-ai\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gemini-2.0-flash\";\r\n }\r\n\r\n getName(): string {\r\n return \"gemini\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@google/generative-ai\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.genAI) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const genAI = this.genAI as any;\r\n const model = genAI.getGenerativeModel({\r\n model: this.model,\r\n systemInstruction: systemPrompt,\r\n });\r\n\r\n const result = await model.generateContent({\r\n contents: [{ role: \"user\", parts: [{ text: userPrompt }] }],\r\n generationConfig: {\r\n maxOutputTokens: maxTokens,\r\n temperature,\r\n },\r\n });\r\n\r\n const response = result.response;\r\n\r\n return {\r\n content: response.text() || \"\",\r\n usage: {\r\n inputTokens: response.usageMetadata?.promptTokenCount || 0,\r\n outputTokens: response.usageMetadata?.candidatesTokenCount || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Groq provider using the official groq-sdk package\r\n */\r\nexport class GroqProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Groq } = await import(\"groq-sdk\");\r\n this.client = new Groq({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\"Groq SDK not installed. Run: npm install groq-sdk\");\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b-versatile\";\r\n }\r\n\r\n getName(): string {\r\n return \"groq\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"groq-sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Cerebras provider using the official @cerebras/cerebras_cloud_sdk package\r\n */\r\nexport class CerebrasProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Cerebras } = await import(\r\n \"@cerebras/cerebras_cloud_sdk\"\r\n );\r\n this.client = new Cerebras({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Cerebras SDK not installed. Run: npm install @cerebras/cerebras_cloud_sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b\";\r\n }\r\n\r\n getName(): string {\r\n return \"cerebras\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@cerebras/cerebras_cloud_sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_completion_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport { OpenAIProvider } from \"./OpenAIProvider\";\r\nimport { AnthropicProvider } from \"./AnthropicProvider\";\r\nimport { GeminiProvider } from \"./GeminiProvider\";\r\nimport { GroqProvider } from \"./GroqProvider\";\r\nimport { CerebrasProvider } from \"./CerebrasProvider\";\r\nimport type { ProviderConfig, ProviderName } from \"../types\";\r\n\r\nexport {\r\n BaseProvider,\r\n OpenAIProvider,\r\n AnthropicProvider,\r\n GeminiProvider,\r\n GroqProvider,\r\n CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Provider registry for creating providers by name\r\n */\r\nconst providerRegistry: Record<\r\n ProviderName,\r\n new (config: {\r\n apiKey: string;\r\n model?: string;\r\n baseUrl?: string;\r\n }) => BaseProvider\r\n> = {\r\n openai: OpenAIProvider,\r\n anthropic: AnthropicProvider,\r\n gemini: GeminiProvider,\r\n groq: GroqProvider,\r\n cerebras: CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Create a provider instance from configuration\r\n */\r\nexport function createProvider(config: ProviderConfig): BaseProvider {\r\n const ProviderClass = providerRegistry[config.provider];\r\n if (!ProviderClass) {\r\n throw new Error(\r\n `Unknown provider: ${config.provider}. Available: ${Object.keys(\r\n providerRegistry\r\n ).join(\", \")}`\r\n );\r\n }\r\n\r\n return new ProviderClass({\r\n apiKey: config.apiKey,\r\n model: config.model,\r\n baseUrl: config.baseUrl,\r\n });\r\n}\r\n\r\n/**\r\n * Check which providers are available (have their SDKs installed)\r\n */\r\nexport function getAvailableProviders(): ProviderName[] {\r\n const available: ProviderName[] = [\"openai\"]; // OpenAI uses fetch, always available\r\n\r\n if (AnthropicProvider.isAvailable()) available.push(\"anthropic\");\r\n if (GeminiProvider.isAvailable()) available.push(\"gemini\");\r\n if (GroqProvider.isAvailable()) available.push(\"groq\");\r\n if (CerebrasProvider.isAvailable()) available.push(\"cerebras\");\r\n\r\n return available;\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/providers/BaseProvider.ts","../../src/providers/OpenAIProvider.ts","../../src/providers/AnthropicProvider.ts","../../src/providers/GeminiProvider.ts","../../src/providers/GroqProvider.ts","../../src/providers/CerebrasProvider.ts","../../src/providers/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Configuration for provider retry and timeout behavior\r\n */\r\nexport interface ProviderRetryConfig {\r\n /** Request timeout in milliseconds (default: 30000) */\r\n timeoutMs?: number;\r\n /** Maximum retry attempts (default: 3) */\r\n maxRetries?: number;\r\n /** Initial retry delay in milliseconds (default: 1000) */\r\n retryDelayMs?: number;\r\n}\r\n\r\n/**\r\n * Abstract base class for LLM providers.\r\n * All provider implementations must extend this class.\r\n */\r\nexport abstract class BaseProvider {\r\n protected apiKey: string;\r\n protected model: string;\r\n protected baseUrl?: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n protected retryDelayMs: number;\r\n\r\n constructor(config: {\r\n apiKey: string;\r\n model?: string;\r\n baseUrl?: string;\r\n retry?: ProviderRetryConfig;\r\n }) {\r\n if (!config.apiKey) {\r\n throw new Error(\"API key is required\");\r\n }\r\n this.apiKey = config.apiKey;\r\n this.model = config.model || this.getDefaultModel();\r\n this.baseUrl = config.baseUrl;\r\n\r\n this.timeoutMs = config.retry?.timeoutMs ?? 30000;\r\n this.maxRetries = config.retry?.maxRetries ?? 3;\r\n this.retryDelayMs = config.retry?.retryDelayMs ?? 1000;\r\n }\r\n\r\n /**\r\n * Get the default model for this provider\r\n */\r\n abstract getDefaultModel(): string;\r\n\r\n /**\r\n * Get the provider name\r\n */\r\n abstract getName(): string;\r\n\r\n /**\r\n * Generate a completion from the LLM\r\n */\r\n abstract complete(options: CompletionOptions): Promise<CompletionResult>;\r\n\r\n /**\r\n * Check if the provider SDK is available\r\n */\r\n static isAvailable(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Execute a fetch request with timeout and retry logic\r\n */\r\n protected async fetchWithRetry(\r\n url: string,\r\n init: RequestInit,\r\n ): Promise<Response> {\r\n let lastError: Error | undefined;\r\n\r\n for (let attempt = 1; attempt <= this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n ...init,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || !this.isRetryableStatus(response.status)) {\r\n return response;\r\n }\r\n\r\n lastError = new Error(\r\n `HTTP ${response.status}: ${response.statusText}`,\r\n );\r\n } catch (error) {\r\n if (error instanceof Error && error.name === \"AbortError\") {\r\n lastError = new Error(`Request timeout after ${this.timeoutMs}ms`);\r\n } else {\r\n lastError = error instanceof Error ? error : new Error(String(error));\r\n }\r\n }\r\n\r\n if (attempt < this.maxRetries) {\r\n const delay = this.retryDelayMs * Math.pow(2, attempt - 1);\r\n await this.sleep(delay);\r\n }\r\n }\r\n\r\n throw lastError || new Error(\"Request failed after retries\");\r\n }\r\n\r\n /**\r\n * Check if an HTTP status code is retryable\r\n */\r\n private isRetryableStatus(status: number): boolean {\r\n return (\r\n status === 429 ||\r\n status === 500 ||\r\n status === 502 ||\r\n status === 503 ||\r\n status === 504\r\n );\r\n }\r\n\r\n /**\r\n * Sleep for a given number of milliseconds\r\n */\r\n protected sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * OpenAI provider using native fetch (no SDK required)\r\n */\r\nexport class OpenAIProvider extends BaseProvider {\r\n private endpoint: string;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.endpoint = this.baseUrl || \"https://api.openai.com/v1\";\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gpt-4o-mini\";\r\n }\r\n\r\n getName(): string {\r\n return \"openai\";\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n jsonMode = true,\r\n } = options;\r\n\r\n const response = await this.fetchWithRetry(\r\n `${this.endpoint}/chat/completions`,\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n ...(jsonMode && { response_format: { type: \"json_object\" } }),\r\n }),\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = (await response\r\n .json()\r\n .catch(() => ({ error: { message: response.statusText } }))) as {\r\n error?: { message?: string };\r\n };\r\n throw new Error(\r\n `OpenAI API error: ${errorData.error?.message || response.statusText}`,\r\n );\r\n }\r\n\r\n interface OpenAIResponse {\r\n choices: Array<{ message?: { content?: string } }>;\r\n usage?: { prompt_tokens?: number; completion_tokens?: number };\r\n }\r\n\r\n const data = (await response.json()) as OpenAIResponse;\r\n\r\n return {\r\n content: data.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: data.usage?.prompt_tokens || 0,\r\n outputTokens: data.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Anthropic provider using the official @anthropic-ai/sdk package\r\n */\r\nexport class AnthropicProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Anthropic } = await import(\"@anthropic-ai/sdk\");\r\n this.client = new Anthropic({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Anthropic SDK not installed. Run: npm install @anthropic-ai/sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"claude-3-haiku-20240307\";\r\n }\r\n\r\n getName(): string {\r\n return \"anthropic\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@anthropic-ai/sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const message = await client.messages.create({\r\n model: this.model,\r\n max_tokens: maxTokens,\r\n temperature,\r\n system: systemPrompt,\r\n messages: [{ role: \"user\", content: userPrompt }],\r\n });\r\n\r\n return {\r\n content: message.content[0]?.text || \"\",\r\n usage: {\r\n inputTokens: message.usage?.input_tokens || 0,\r\n outputTokens: message.usage?.output_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Google Gemini provider using the official @google/generative-ai package\r\n */\r\nexport class GeminiProvider extends BaseProvider {\r\n private genAI: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { GoogleGenerativeAI } = await import(\"@google/generative-ai\");\r\n this.genAI = new GoogleGenerativeAI(this.apiKey);\r\n } catch {\r\n throw new Error(\r\n \"Google Generative AI SDK not installed. Run: npm install @google/generative-ai\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gemini-2.0-flash\";\r\n }\r\n\r\n getName(): string {\r\n return \"gemini\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@google/generative-ai\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.genAI) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const genAI = this.genAI as any;\r\n const model = genAI.getGenerativeModel({\r\n model: this.model,\r\n systemInstruction: systemPrompt,\r\n });\r\n\r\n const result = await model.generateContent({\r\n contents: [{ role: \"user\", parts: [{ text: userPrompt }] }],\r\n generationConfig: {\r\n maxOutputTokens: maxTokens,\r\n temperature,\r\n },\r\n });\r\n\r\n const response = result.response;\r\n\r\n return {\r\n content: response.text() || \"\",\r\n usage: {\r\n inputTokens: response.usageMetadata?.promptTokenCount || 0,\r\n outputTokens: response.usageMetadata?.candidatesTokenCount || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Groq provider using the official groq-sdk package\r\n */\r\nexport class GroqProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Groq } = await import(\"groq-sdk\");\r\n this.client = new Groq({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\"Groq SDK not installed. Run: npm install groq-sdk\");\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b-versatile\";\r\n }\r\n\r\n getName(): string {\r\n return \"groq\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"groq-sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Cerebras provider using the official @cerebras/cerebras_cloud_sdk package\r\n */\r\nexport class CerebrasProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Cerebras } = await import(\r\n \"@cerebras/cerebras_cloud_sdk\"\r\n );\r\n this.client = new Cerebras({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Cerebras SDK not installed. Run: npm install @cerebras/cerebras_cloud_sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b\";\r\n }\r\n\r\n getName(): string {\r\n return \"cerebras\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@cerebras/cerebras_cloud_sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_completion_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport { OpenAIProvider } from \"./OpenAIProvider\";\r\nimport { AnthropicProvider } from \"./AnthropicProvider\";\r\nimport { GeminiProvider } from \"./GeminiProvider\";\r\nimport { GroqProvider } from \"./GroqProvider\";\r\nimport { CerebrasProvider } from \"./CerebrasProvider\";\r\nimport type { ProviderConfig, ProviderName } from \"../types\";\r\n\r\nexport {\r\n BaseProvider,\r\n OpenAIProvider,\r\n AnthropicProvider,\r\n GeminiProvider,\r\n GroqProvider,\r\n CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Provider registry for creating providers by name\r\n */\r\nconst providerRegistry: Record<\r\n ProviderName,\r\n new (config: {\r\n apiKey: string;\r\n model?: string;\r\n baseUrl?: string;\r\n }) => BaseProvider\r\n> = {\r\n openai: OpenAIProvider,\r\n anthropic: AnthropicProvider,\r\n gemini: GeminiProvider,\r\n groq: GroqProvider,\r\n cerebras: CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Create a provider instance from configuration\r\n */\r\nexport function createProvider(config: ProviderConfig): BaseProvider {\r\n const ProviderClass = providerRegistry[config.provider];\r\n if (!ProviderClass) {\r\n throw new Error(\r\n `Unknown provider: ${config.provider}. Available: ${Object.keys(\r\n providerRegistry\r\n ).join(\", \")}`\r\n );\r\n }\r\n\r\n return new ProviderClass({\r\n apiKey: config.apiKey,\r\n model: config.model,\r\n baseUrl: config.baseUrl,\r\n });\r\n}\r\n\r\n/**\r\n * Check which providers are available (have their SDKs installed)\r\n */\r\nexport function getAvailableProviders(): ProviderName[] {\r\n const available: ProviderName[] = [\"openai\"]; // OpenAI uses fetch, always available\r\n\r\n if (AnthropicProvider.isAvailable()) available.push(\"anthropic\");\r\n if (GeminiProvider.isAvailable()) available.push(\"gemini\");\r\n if (GroqProvider.isAvailable()) available.push(\"groq\");\r\n if (CerebrasProvider.isAvailable()) available.push(\"cerebras\");\r\n\r\n return available;\r\n}\r\n"]}
@@ -10,6 +10,9 @@ var BaseProvider = class {
10
10
  apiKey;
11
11
  model;
12
12
  baseUrl;
13
+ timeoutMs;
14
+ maxRetries;
15
+ retryDelayMs;
13
16
  constructor(config) {
14
17
  if (!config.apiKey) {
15
18
  throw new Error("API key is required");
@@ -17,6 +20,9 @@ var BaseProvider = class {
17
20
  this.apiKey = config.apiKey;
18
21
  this.model = config.model || this.getDefaultModel();
19
22
  this.baseUrl = config.baseUrl;
23
+ this.timeoutMs = config.retry?.timeoutMs ?? 3e4;
24
+ this.maxRetries = config.retry?.maxRetries ?? 3;
25
+ this.retryDelayMs = config.retry?.retryDelayMs ?? 1e3;
20
26
  }
21
27
  /**
22
28
  * Check if the provider SDK is available
@@ -24,6 +30,52 @@ var BaseProvider = class {
24
30
  static isAvailable() {
25
31
  return true;
26
32
  }
33
+ /**
34
+ * Execute a fetch request with timeout and retry logic
35
+ */
36
+ async fetchWithRetry(url, init) {
37
+ let lastError;
38
+ for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
39
+ try {
40
+ const controller = new AbortController();
41
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
42
+ const response = await fetch(url, {
43
+ ...init,
44
+ signal: controller.signal
45
+ });
46
+ clearTimeout(timeoutId);
47
+ if (response.ok || !this.isRetryableStatus(response.status)) {
48
+ return response;
49
+ }
50
+ lastError = new Error(
51
+ `HTTP ${response.status}: ${response.statusText}`
52
+ );
53
+ } catch (error) {
54
+ if (error instanceof Error && error.name === "AbortError") {
55
+ lastError = new Error(`Request timeout after ${this.timeoutMs}ms`);
56
+ } else {
57
+ lastError = error instanceof Error ? error : new Error(String(error));
58
+ }
59
+ }
60
+ if (attempt < this.maxRetries) {
61
+ const delay = this.retryDelayMs * Math.pow(2, attempt - 1);
62
+ await this.sleep(delay);
63
+ }
64
+ }
65
+ throw lastError || new Error("Request failed after retries");
66
+ }
67
+ /**
68
+ * Check if an HTTP status code is retryable
69
+ */
70
+ isRetryableStatus(status) {
71
+ return status === 429 || status === 500 || status === 502 || status === 503 || status === 504;
72
+ }
73
+ /**
74
+ * Sleep for a given number of milliseconds
75
+ */
76
+ sleep(ms) {
77
+ return new Promise((resolve) => setTimeout(resolve, ms));
78
+ }
27
79
  };
28
80
 
29
81
  // src/providers/OpenAIProvider.ts
@@ -47,23 +99,26 @@ var OpenAIProvider = class extends BaseProvider {
47
99
  temperature = 0.3,
48
100
  jsonMode = true
49
101
  } = options;
50
- const response = await fetch(`${this.endpoint}/chat/completions`, {
51
- method: "POST",
52
- headers: {
53
- "Content-Type": "application/json",
54
- Authorization: `Bearer ${this.apiKey}`
55
- },
56
- body: JSON.stringify({
57
- model: this.model,
58
- messages: [
59
- { role: "system", content: systemPrompt },
60
- { role: "user", content: userPrompt }
61
- ],
62
- max_tokens: maxTokens,
63
- temperature,
64
- ...jsonMode && { response_format: { type: "json_object" } }
65
- })
66
- });
102
+ const response = await this.fetchWithRetry(
103
+ `${this.endpoint}/chat/completions`,
104
+ {
105
+ method: "POST",
106
+ headers: {
107
+ "Content-Type": "application/json",
108
+ Authorization: `Bearer ${this.apiKey}`
109
+ },
110
+ body: JSON.stringify({
111
+ model: this.model,
112
+ messages: [
113
+ { role: "system", content: systemPrompt },
114
+ { role: "user", content: userPrompt }
115
+ ],
116
+ max_tokens: maxTokens,
117
+ temperature,
118
+ ...jsonMode && { response_format: { type: "json_object" } }
119
+ })
120
+ }
121
+ );
67
122
  if (!response.ok) {
68
123
  const errorData = await response.json().catch(() => ({ error: { message: response.statusText } }));
69
124
  throw new Error(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/BaseProvider.ts","../../src/providers/OpenAIProvider.ts","../../src/providers/AnthropicProvider.ts","../../src/providers/GeminiProvider.ts","../../src/providers/GroqProvider.ts","../../src/providers/CerebrasProvider.ts","../../src/providers/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Abstract base class for LLM providers.\r\n * All provider implementations must extend this class.\r\n */\r\nexport abstract class BaseProvider {\r\n protected apiKey: string;\r\n protected model: string;\r\n protected baseUrl?: string;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n if (!config.apiKey) {\r\n throw new Error(\"API key is required\");\r\n }\r\n this.apiKey = config.apiKey;\r\n this.model = config.model || this.getDefaultModel();\r\n this.baseUrl = config.baseUrl;\r\n }\r\n\r\n /**\r\n * Get the default model for this provider\r\n */\r\n abstract getDefaultModel(): string;\r\n\r\n /**\r\n * Get the provider name\r\n */\r\n abstract getName(): string;\r\n\r\n /**\r\n * Generate a completion from the LLM\r\n */\r\n abstract complete(options: CompletionOptions): Promise<CompletionResult>;\r\n\r\n /**\r\n * Check if the provider SDK is available\r\n */\r\n static isAvailable(): boolean {\r\n return true;\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * OpenAI provider using native fetch (no SDK required)\r\n */\r\nexport class OpenAIProvider extends BaseProvider {\r\n private endpoint: string;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.endpoint = this.baseUrl || \"https://api.openai.com/v1\";\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gpt-4o-mini\";\r\n }\r\n\r\n getName(): string {\r\n return \"openai\";\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n jsonMode = true,\r\n } = options;\r\n\r\n const response = await fetch(`${this.endpoint}/chat/completions`, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n ...(jsonMode && { response_format: { type: \"json_object\" } }),\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = (await response\r\n .json()\r\n .catch(() => ({ error: { message: response.statusText } }))) as {\r\n error?: { message?: string };\r\n };\r\n throw new Error(\r\n `OpenAI API error: ${errorData.error?.message || response.statusText}`\r\n );\r\n }\r\n\r\n interface OpenAIResponse {\r\n choices: Array<{ message?: { content?: string } }>;\r\n usage?: { prompt_tokens?: number; completion_tokens?: number };\r\n }\r\n\r\n const data = (await response.json()) as OpenAIResponse;\r\n\r\n return {\r\n content: data.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: data.usage?.prompt_tokens || 0,\r\n outputTokens: data.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Anthropic provider using the official @anthropic-ai/sdk package\r\n */\r\nexport class AnthropicProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Anthropic } = await import(\"@anthropic-ai/sdk\");\r\n this.client = new Anthropic({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Anthropic SDK not installed. Run: npm install @anthropic-ai/sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"claude-3-haiku-20240307\";\r\n }\r\n\r\n getName(): string {\r\n return \"anthropic\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@anthropic-ai/sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const message = await client.messages.create({\r\n model: this.model,\r\n max_tokens: maxTokens,\r\n temperature,\r\n system: systemPrompt,\r\n messages: [{ role: \"user\", content: userPrompt }],\r\n });\r\n\r\n return {\r\n content: message.content[0]?.text || \"\",\r\n usage: {\r\n inputTokens: message.usage?.input_tokens || 0,\r\n outputTokens: message.usage?.output_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Google Gemini provider using the official @google/generative-ai package\r\n */\r\nexport class GeminiProvider extends BaseProvider {\r\n private genAI: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { GoogleGenerativeAI } = await import(\"@google/generative-ai\");\r\n this.genAI = new GoogleGenerativeAI(this.apiKey);\r\n } catch {\r\n throw new Error(\r\n \"Google Generative AI SDK not installed. Run: npm install @google/generative-ai\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gemini-2.0-flash\";\r\n }\r\n\r\n getName(): string {\r\n return \"gemini\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@google/generative-ai\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.genAI) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const genAI = this.genAI as any;\r\n const model = genAI.getGenerativeModel({\r\n model: this.model,\r\n systemInstruction: systemPrompt,\r\n });\r\n\r\n const result = await model.generateContent({\r\n contents: [{ role: \"user\", parts: [{ text: userPrompt }] }],\r\n generationConfig: {\r\n maxOutputTokens: maxTokens,\r\n temperature,\r\n },\r\n });\r\n\r\n const response = result.response;\r\n\r\n return {\r\n content: response.text() || \"\",\r\n usage: {\r\n inputTokens: response.usageMetadata?.promptTokenCount || 0,\r\n outputTokens: response.usageMetadata?.candidatesTokenCount || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Groq provider using the official groq-sdk package\r\n */\r\nexport class GroqProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Groq } = await import(\"groq-sdk\");\r\n this.client = new Groq({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\"Groq SDK not installed. Run: npm install groq-sdk\");\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b-versatile\";\r\n }\r\n\r\n getName(): string {\r\n return \"groq\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"groq-sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Cerebras provider using the official @cerebras/cerebras_cloud_sdk package\r\n */\r\nexport class CerebrasProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Cerebras } = await import(\r\n \"@cerebras/cerebras_cloud_sdk\"\r\n );\r\n this.client = new Cerebras({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Cerebras SDK not installed. Run: npm install @cerebras/cerebras_cloud_sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b\";\r\n }\r\n\r\n getName(): string {\r\n return \"cerebras\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@cerebras/cerebras_cloud_sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_completion_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport { OpenAIProvider } from \"./OpenAIProvider\";\r\nimport { AnthropicProvider } from \"./AnthropicProvider\";\r\nimport { GeminiProvider } from \"./GeminiProvider\";\r\nimport { GroqProvider } from \"./GroqProvider\";\r\nimport { CerebrasProvider } from \"./CerebrasProvider\";\r\nimport type { ProviderConfig, ProviderName } from \"../types\";\r\n\r\nexport {\r\n BaseProvider,\r\n OpenAIProvider,\r\n AnthropicProvider,\r\n GeminiProvider,\r\n GroqProvider,\r\n CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Provider registry for creating providers by name\r\n */\r\nconst providerRegistry: Record<\r\n ProviderName,\r\n new (config: {\r\n apiKey: string;\r\n model?: string;\r\n baseUrl?: string;\r\n }) => BaseProvider\r\n> = {\r\n openai: OpenAIProvider,\r\n anthropic: AnthropicProvider,\r\n gemini: GeminiProvider,\r\n groq: GroqProvider,\r\n cerebras: CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Create a provider instance from configuration\r\n */\r\nexport function createProvider(config: ProviderConfig): BaseProvider {\r\n const ProviderClass = providerRegistry[config.provider];\r\n if (!ProviderClass) {\r\n throw new Error(\r\n `Unknown provider: ${config.provider}. Available: ${Object.keys(\r\n providerRegistry\r\n ).join(\", \")}`\r\n );\r\n }\r\n\r\n return new ProviderClass({\r\n apiKey: config.apiKey,\r\n model: config.model,\r\n baseUrl: config.baseUrl,\r\n });\r\n}\r\n\r\n/**\r\n * Check which providers are available (have their SDKs installed)\r\n */\r\nexport function getAvailableProviders(): ProviderName[] {\r\n const available: ProviderName[] = [\"openai\"]; // OpenAI uses fetch, always available\r\n\r\n if (AnthropicProvider.isAvailable()) available.push(\"anthropic\");\r\n if (GeminiProvider.isAvailable()) available.push(\"gemini\");\r\n if (GroqProvider.isAvailable()) available.push(\"groq\");\r\n if (CerebrasProvider.isAvailable()) available.push(\"cerebras\");\r\n\r\n return available;\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/providers/BaseProvider.ts","../../src/providers/OpenAIProvider.ts","../../src/providers/AnthropicProvider.ts","../../src/providers/GeminiProvider.ts","../../src/providers/GroqProvider.ts","../../src/providers/CerebrasProvider.ts","../../src/providers/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Configuration for provider retry and timeout behavior\r\n */\r\nexport interface ProviderRetryConfig {\r\n /** Request timeout in milliseconds (default: 30000) */\r\n timeoutMs?: number;\r\n /** Maximum retry attempts (default: 3) */\r\n maxRetries?: number;\r\n /** Initial retry delay in milliseconds (default: 1000) */\r\n retryDelayMs?: number;\r\n}\r\n\r\n/**\r\n * Abstract base class for LLM providers.\r\n * All provider implementations must extend this class.\r\n */\r\nexport abstract class BaseProvider {\r\n protected apiKey: string;\r\n protected model: string;\r\n protected baseUrl?: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n protected retryDelayMs: number;\r\n\r\n constructor(config: {\r\n apiKey: string;\r\n model?: string;\r\n baseUrl?: string;\r\n retry?: ProviderRetryConfig;\r\n }) {\r\n if (!config.apiKey) {\r\n throw new Error(\"API key is required\");\r\n }\r\n this.apiKey = config.apiKey;\r\n this.model = config.model || this.getDefaultModel();\r\n this.baseUrl = config.baseUrl;\r\n\r\n this.timeoutMs = config.retry?.timeoutMs ?? 30000;\r\n this.maxRetries = config.retry?.maxRetries ?? 3;\r\n this.retryDelayMs = config.retry?.retryDelayMs ?? 1000;\r\n }\r\n\r\n /**\r\n * Get the default model for this provider\r\n */\r\n abstract getDefaultModel(): string;\r\n\r\n /**\r\n * Get the provider name\r\n */\r\n abstract getName(): string;\r\n\r\n /**\r\n * Generate a completion from the LLM\r\n */\r\n abstract complete(options: CompletionOptions): Promise<CompletionResult>;\r\n\r\n /**\r\n * Check if the provider SDK is available\r\n */\r\n static isAvailable(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Execute a fetch request with timeout and retry logic\r\n */\r\n protected async fetchWithRetry(\r\n url: string,\r\n init: RequestInit,\r\n ): Promise<Response> {\r\n let lastError: Error | undefined;\r\n\r\n for (let attempt = 1; attempt <= this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n ...init,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || !this.isRetryableStatus(response.status)) {\r\n return response;\r\n }\r\n\r\n lastError = new Error(\r\n `HTTP ${response.status}: ${response.statusText}`,\r\n );\r\n } catch (error) {\r\n if (error instanceof Error && error.name === \"AbortError\") {\r\n lastError = new Error(`Request timeout after ${this.timeoutMs}ms`);\r\n } else {\r\n lastError = error instanceof Error ? error : new Error(String(error));\r\n }\r\n }\r\n\r\n if (attempt < this.maxRetries) {\r\n const delay = this.retryDelayMs * Math.pow(2, attempt - 1);\r\n await this.sleep(delay);\r\n }\r\n }\r\n\r\n throw lastError || new Error(\"Request failed after retries\");\r\n }\r\n\r\n /**\r\n * Check if an HTTP status code is retryable\r\n */\r\n private isRetryableStatus(status: number): boolean {\r\n return (\r\n status === 429 ||\r\n status === 500 ||\r\n status === 502 ||\r\n status === 503 ||\r\n status === 504\r\n );\r\n }\r\n\r\n /**\r\n * Sleep for a given number of milliseconds\r\n */\r\n protected sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * OpenAI provider using native fetch (no SDK required)\r\n */\r\nexport class OpenAIProvider extends BaseProvider {\r\n private endpoint: string;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.endpoint = this.baseUrl || \"https://api.openai.com/v1\";\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gpt-4o-mini\";\r\n }\r\n\r\n getName(): string {\r\n return \"openai\";\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n jsonMode = true,\r\n } = options;\r\n\r\n const response = await this.fetchWithRetry(\r\n `${this.endpoint}/chat/completions`,\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n ...(jsonMode && { response_format: { type: \"json_object\" } }),\r\n }),\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = (await response\r\n .json()\r\n .catch(() => ({ error: { message: response.statusText } }))) as {\r\n error?: { message?: string };\r\n };\r\n throw new Error(\r\n `OpenAI API error: ${errorData.error?.message || response.statusText}`,\r\n );\r\n }\r\n\r\n interface OpenAIResponse {\r\n choices: Array<{ message?: { content?: string } }>;\r\n usage?: { prompt_tokens?: number; completion_tokens?: number };\r\n }\r\n\r\n const data = (await response.json()) as OpenAIResponse;\r\n\r\n return {\r\n content: data.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: data.usage?.prompt_tokens || 0,\r\n outputTokens: data.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Anthropic provider using the official @anthropic-ai/sdk package\r\n */\r\nexport class AnthropicProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Anthropic } = await import(\"@anthropic-ai/sdk\");\r\n this.client = new Anthropic({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Anthropic SDK not installed. Run: npm install @anthropic-ai/sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"claude-3-haiku-20240307\";\r\n }\r\n\r\n getName(): string {\r\n return \"anthropic\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@anthropic-ai/sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const message = await client.messages.create({\r\n model: this.model,\r\n max_tokens: maxTokens,\r\n temperature,\r\n system: systemPrompt,\r\n messages: [{ role: \"user\", content: userPrompt }],\r\n });\r\n\r\n return {\r\n content: message.content[0]?.text || \"\",\r\n usage: {\r\n inputTokens: message.usage?.input_tokens || 0,\r\n outputTokens: message.usage?.output_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Google Gemini provider using the official @google/generative-ai package\r\n */\r\nexport class GeminiProvider extends BaseProvider {\r\n private genAI: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { GoogleGenerativeAI } = await import(\"@google/generative-ai\");\r\n this.genAI = new GoogleGenerativeAI(this.apiKey);\r\n } catch {\r\n throw new Error(\r\n \"Google Generative AI SDK not installed. Run: npm install @google/generative-ai\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"gemini-2.0-flash\";\r\n }\r\n\r\n getName(): string {\r\n return \"gemini\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@google/generative-ai\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.genAI) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const genAI = this.genAI as any;\r\n const model = genAI.getGenerativeModel({\r\n model: this.model,\r\n systemInstruction: systemPrompt,\r\n });\r\n\r\n const result = await model.generateContent({\r\n contents: [{ role: \"user\", parts: [{ text: userPrompt }] }],\r\n generationConfig: {\r\n maxOutputTokens: maxTokens,\r\n temperature,\r\n },\r\n });\r\n\r\n const response = result.response;\r\n\r\n return {\r\n content: response.text() || \"\",\r\n usage: {\r\n inputTokens: response.usageMetadata?.promptTokenCount || 0,\r\n outputTokens: response.usageMetadata?.candidatesTokenCount || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Groq provider using the official groq-sdk package\r\n */\r\nexport class GroqProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Groq } = await import(\"groq-sdk\");\r\n this.client = new Groq({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\"Groq SDK not installed. Run: npm install groq-sdk\");\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b-versatile\";\r\n }\r\n\r\n getName(): string {\r\n return \"groq\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"groq-sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport type { CompletionOptions, CompletionResult } from \"../types\";\r\n\r\n/**\r\n * Cerebras provider using the official @cerebras/cerebras_cloud_sdk package\r\n */\r\nexport class CerebrasProvider extends BaseProvider {\r\n private client: unknown;\r\n\r\n constructor(config: { apiKey: string; model?: string; baseUrl?: string }) {\r\n super(config);\r\n this.initClient();\r\n }\r\n\r\n private async initClient(): Promise<void> {\r\n try {\r\n // Dynamic import to make the SDK optional\r\n const { default: Cerebras } = await import(\r\n \"@cerebras/cerebras_cloud_sdk\"\r\n );\r\n this.client = new Cerebras({\r\n apiKey: this.apiKey,\r\n ...(this.baseUrl && { baseURL: this.baseUrl }),\r\n });\r\n } catch {\r\n throw new Error(\r\n \"Cerebras SDK not installed. Run: npm install @cerebras/cerebras_cloud_sdk\"\r\n );\r\n }\r\n }\r\n\r\n getDefaultModel(): string {\r\n return \"llama-3.3-70b\";\r\n }\r\n\r\n getName(): string {\r\n return \"cerebras\";\r\n }\r\n\r\n static isAvailable(): boolean {\r\n try {\r\n require.resolve(\"@cerebras/cerebras_cloud_sdk\");\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async complete(options: CompletionOptions): Promise<CompletionResult> {\r\n const {\r\n systemPrompt,\r\n userPrompt,\r\n maxTokens = 1000,\r\n temperature = 0.3,\r\n } = options;\r\n\r\n if (!this.client) {\r\n await this.initClient();\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const client = this.client as any;\r\n const completion = await client.chat.completions.create({\r\n model: this.model,\r\n messages: [\r\n { role: \"system\", content: systemPrompt },\r\n { role: \"user\", content: userPrompt },\r\n ],\r\n max_completion_tokens: maxTokens,\r\n temperature,\r\n });\r\n\r\n return {\r\n content: completion.choices[0]?.message?.content || \"\",\r\n usage: {\r\n inputTokens: completion.usage?.prompt_tokens || 0,\r\n outputTokens: completion.usage?.completion_tokens || 0,\r\n },\r\n };\r\n }\r\n}\r\n","import { BaseProvider } from \"./BaseProvider\";\r\nimport { OpenAIProvider } from \"./OpenAIProvider\";\r\nimport { AnthropicProvider } from \"./AnthropicProvider\";\r\nimport { GeminiProvider } from \"./GeminiProvider\";\r\nimport { GroqProvider } from \"./GroqProvider\";\r\nimport { CerebrasProvider } from \"./CerebrasProvider\";\r\nimport type { ProviderConfig, ProviderName } from \"../types\";\r\n\r\nexport {\r\n BaseProvider,\r\n OpenAIProvider,\r\n AnthropicProvider,\r\n GeminiProvider,\r\n GroqProvider,\r\n CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Provider registry for creating providers by name\r\n */\r\nconst providerRegistry: Record<\r\n ProviderName,\r\n new (config: {\r\n apiKey: string;\r\n model?: string;\r\n baseUrl?: string;\r\n }) => BaseProvider\r\n> = {\r\n openai: OpenAIProvider,\r\n anthropic: AnthropicProvider,\r\n gemini: GeminiProvider,\r\n groq: GroqProvider,\r\n cerebras: CerebrasProvider,\r\n};\r\n\r\n/**\r\n * Create a provider instance from configuration\r\n */\r\nexport function createProvider(config: ProviderConfig): BaseProvider {\r\n const ProviderClass = providerRegistry[config.provider];\r\n if (!ProviderClass) {\r\n throw new Error(\r\n `Unknown provider: ${config.provider}. Available: ${Object.keys(\r\n providerRegistry\r\n ).join(\", \")}`\r\n );\r\n }\r\n\r\n return new ProviderClass({\r\n apiKey: config.apiKey,\r\n model: config.model,\r\n baseUrl: config.baseUrl,\r\n });\r\n}\r\n\r\n/**\r\n * Check which providers are available (have their SDKs installed)\r\n */\r\nexport function getAvailableProviders(): ProviderName[] {\r\n const available: ProviderName[] = [\"openai\"]; // OpenAI uses fetch, always available\r\n\r\n if (AnthropicProvider.isAvailable()) available.push(\"anthropic\");\r\n if (GeminiProvider.isAvailable()) available.push(\"gemini\");\r\n if (GroqProvider.isAvailable()) available.push(\"groq\");\r\n if (CerebrasProvider.isAvailable()) available.push(\"cerebras\");\r\n\r\n return available;\r\n}\r\n"]}