{"version":3,"sources":["../../src/adapters/web-llm.ts"],"names":["webLlmAdapter","CreateMLCEngine","_task","config","_device","onProgress","modelId","info","model","input","options","engine","chatInput","onChunk","asyncChunks","chunk","delta"],"mappings":"aAiDO,SAASA,GAAqC,CACnD,OAAO,CACL,IAAA,CAAM,UAEN,MAAM,MAAA,EAAgC,CAEpC,GAAM,CAAE,eAAA,CAAAC,CAAgB,EAAI,MAAM,OAAO,iBAAiB,CAAA,CAE1D,OAAO,CACL,IAAA,CAAM,UAEN,gBAAA,CAAiBC,CAAAA,CAAeC,EAAyC,CACvE,OAAQA,EAAO,iBAAA,EAA4C,GAC7D,CAAA,CAEA,MAAM,KACJD,CAAAA,CACAC,CAAAA,CACAC,EACAC,CAAAA,CACsB,CACtB,IAAMC,CAAAA,CAAUH,CAAAA,CAAO,KAAA,CAYvB,OAAO,CACL,QAAA,CAXwB,MAAMF,EAAgBK,CAAAA,CAAS,CACvD,qBAAuBC,CAAAA,EAA6C,CAClEF,CAAAA,CAAW,CACT,OAAQE,CAAAA,CAAK,QAAA,CACb,MAAOA,CAAAA,CAAK,IAAA,CACZ,MAAO,CACT,CAAC,EACH,CACF,CAAC,CAAA,CAIC,QAAA,CAAWJ,EAAO,iBAAA,EAA4C,GAChE,CACF,CAAA,CAEA,MAAM,GAAA,CAAIK,CAAAA,CAAoBC,EAAgBC,CAAAA,CAAqC,CACjF,IAAMC,CAAAA,CAASH,CAAAA,CAAM,SACfI,CAAAA,CAAYH,CAAAA,CAMlB,OAAA,CALiB,MAAME,EAAO,IAAA,CAAK,WAAA,CAAY,OAAO,CACpD,GAAID,GAAqB,EAAC,CAC1B,QAAA,CAAUE,CAAAA,CAAU,SACpB,MAAA,CAAQ,KACV,CAAC,CAAA,EACe,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,EAAS,OAAA,EAAW,EAClD,EAEA,MAAM,MAAA,CACJJ,EACAC,CAAAA,CACAI,CAAAA,CACAH,EACe,CACf,IAAMC,CAAAA,CAASH,CAAAA,CAAM,SACfI,CAAAA,CAAYH,CAAAA,CAEZK,EAAc,MAAMH,CAAAA,CAAO,KAAK,WAAA,CAAY,MAAA,CAAO,CACvD,GAAID,GAAqB,EAAC,CAC1B,SAAUE,CAAAA,CAAU,QAAA,CACpB,OAAQ,IACV,CAAC,CAAA,CAED,UAAA,IAAiBG,KAASD,CAAAA,CAAa,CACrC,IAAME,CAAAA,CAAQD,CAAAA,CAAM,QAAQ,CAAC,CAAA,EAAG,KAAA,EAAO,OAAA,CACnCC,GACFH,CAAAA,CAAQG,CAAK,EACjB,CACF,CAAA,CAEA,MAAM,MAAA,CAAOR,CAAAA,CAAmC,CAE9C,MADeA,EAAM,QAAA,CACR,MAAA,KACf,CACF,CACF,CACF,CACF","file":"web-llm.cjs","sourcesContent":["import type {\n  Device,\n  LoadedModel,\n  LoadProgressEvent,\n  ModelAdapter,\n  ModelAdapterFactory,\n} from '../core/types.js';\n\n// eslint-disable-next-line ts/no-explicit-any\ntype MLCEngine = any;\n\ninterface ChatMessage {\n  role: 'system' | 'user' | 'assistant';\n  content: string;\n}\n\ninterface ChatInput {\n  messages: ChatMessage[];\n  temperature?: number;\n  top_p?: number;\n  max_tokens?: number;\n}\n\n/**\n * Adapter for @mlc-ai/web-llm.\n *\n * @remarks\n * Optimized for LLM text generation with WebGPU acceleration.\n * Streaming is natively supported via the OpenAI-compatible chat API.\n *\n * @example\n * ```ts\n * import { createPool } from 'inferis-ml';\n * import { webLlmAdapter } from 'inferis-ml/adapters/web-llm';\n *\n * const pool = await createPool({\n *   adapter: webLlmAdapter(),\n *   defaultDevice: 'webgpu',\n *   maxWorkers: 1,\n * });\n *\n * const llm = await pool.load<string>('text-generation', {\n *   model: 'Llama-3.1-8B-Instruct-q4f32_1-MLC',\n * });\n *\n * const stream = llm.stream({ messages: [{ role: 'user', content: 'Hello' }] });\n * for await (const token of stream) { ... }\n * ```\n */\nexport function webLlmAdapter(): ModelAdapterFactory {\n  return {\n    name: 'web-llm',\n\n    async create(): Promise<ModelAdapter> {\n      // @ts-expect-error - optional peer dependency, resolved at runtime inside worker\n      const { CreateMLCEngine } = await import('@mlc-ai/web-llm');\n\n      return {\n        name: 'web-llm',\n\n        estimateMemoryMB(_task: string, config: Record<string, unknown>): number {\n          return (config.estimatedMemoryMB as number | undefined) ?? 2000;\n        },\n\n        async load(\n          _task: string,\n          config: Record<string, unknown>,\n          _device: Device,\n          onProgress: (event: LoadProgressEvent) => void,\n        ): Promise<LoadedModel> {\n          const modelId = config.model as string;\n\n          const engine: MLCEngine = await CreateMLCEngine(modelId, {\n            initProgressCallback: (info: { progress: number; text: string }) => {\n              onProgress({\n                loaded: info.progress,\n                phase: info.text,\n                total: 1,\n              });\n            },\n          });\n\n          return {\n            instance: engine,\n            memoryMB: (config.estimatedMemoryMB as number | undefined) ?? 2000,\n          };\n        },\n\n        async run(model: LoadedModel, input: unknown, options?: unknown): Promise<unknown> {\n          const engine = model.instance as MLCEngine;\n          const chatInput = input as ChatInput;\n          const response = await engine.chat.completions.create({\n            ...(options as object ?? {}),\n            messages: chatInput.messages,\n            stream: false,\n          });\n          return response.choices[0]?.message?.content ?? '';\n        },\n\n        async stream(\n          model: LoadedModel,\n          input: unknown,\n          onChunk: (chunk: unknown) => void,\n          options?: unknown,\n        ): Promise<void> {\n          const engine = model.instance as MLCEngine;\n          const chatInput = input as ChatInput;\n\n          const asyncChunks = await engine.chat.completions.create({\n            ...(options as object ?? {}),\n            messages: chatInput.messages,\n            stream: true,\n          });\n\n          for await (const chunk of asyncChunks) {\n            const delta = chunk.choices[0]?.delta?.content;\n            if (delta)\n              onChunk(delta);\n          }\n        },\n\n        async unload(model: LoadedModel): Promise<void> {\n          const engine = model.instance as MLCEngine;\n          await engine.unload?.();\n        },\n      };\n    },\n  };\n}\n"]}