@browser-ai/web-llm 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,271 +1,34 @@
1
- # WebLLM provider for Vercel AI SDK
2
-
3
- <div align="center">
4
- <img src="./hero.png">
5
- </div>
6
-
7
- <div align="center">
8
-
9
- [![NPM Version](https://img.shields.io/npm/v/%40built-in-ai%2Fweb-llm)](https://www.npmjs.com/package/@built-in-ai/web-llm)
10
- [![NPM Downloads](https://img.shields.io/npm/dm/%40built-in-ai%2Fweb-llm)](https://www.npmjs.com/package/@built-in-ai/web-llm)
11
-
12
- > [!NOTE]
13
- > This library is still in a very early state where updates might come quite frequently.
14
-
15
- </div>
16
-
17
- [WebLLM](https://github.com/mlc-ai/web-llm) model provider for [Vercel AI SDK](https://ai-sdk.dev/). This library enables you to easily use the AI SDK with popular open-source models running directly in your web browser.
18
-
19
- ## Installation
20
-
21
- ```bash
22
- npm i @built-in-ai/web-llm
23
- ```
24
-
25
- The `@built-in-ai/web-llm` package is the AI SDK provider for open-source built-in AI models leveraging the [WebLLM](https://github.com/mlc-ai/web-llm) inference engine.
26
-
27
- ## Browser Requirements
28
-
29
- A WebGPU-compatible browser is needed to run these models. Check out the [API](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) for more information.
30
-
31
- ## Usage
32
-
33
- ### Basic Usage
34
-
35
- ```typescript
36
- import { streamText } from "ai";
37
- import { webLLM } from "@built-in-ai/web-llm";
38
-
39
- const result = streamText({
40
- // or generateText
41
- model: webLLM("Llama-3.2-3B-Instruct-q4f16_1-MLC"),
42
- messages: [{ role: "user", content: "Hello, how are you?" }],
43
- });
44
-
45
- for await (const chunk of result.textStream) {
46
- console.log(chunk);
47
- }
48
- ```
49
-
50
- ### Advanced Usage
51
-
52
- If you're already familiar with the WebLLM engine library (or in general inference with models in the browser), you'll know that to make it run effeciently, you probably know that you need to use [web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) to offload the heavy model computation to a different thread than the UI. You can check out WebLLM's official [docs](https://webllm.mlc.ai/docs/user/advanced_usage.html) for more information.
53
-
54
- 1. Create your `worker.ts` file:
55
-
56
- ```typescript
57
- import { WebWorkerMLCEngineHandler } from "@built-in-ai/web-llm";
58
-
59
- const handler = new WebWorkerMLCEngineHandler();
60
- self.onmessage = (msg: MessageEvent) => {
61
- handler.onmessage(msg);
62
- };
63
- ```
64
-
65
- 2. Provide it in the model instance:
66
-
67
- ```typescript
68
- import { streamText } from "ai";
69
- import { webLLM } from "@built-in-ai/web-llm";
70
-
71
- const result = streamText({ // or generateText
72
- model: webLLM('Qwen3-0.6B-q0f16-MLC', {
73
- worker: new Worker(new URL("./worker.ts", import.meta.url), {
74
- type: "module",
75
- }),
76
- });,
77
- messages: [{ role: "user", content: "Hello, how are you?" }],
78
- });
79
-
80
- for await (const chunk of result.textStream) {
81
- console.log(chunk);
82
- }
83
- ```
84
-
85
- ## Download Progress Tracking
86
-
87
- When using the open-source models for the first time, the model needs to be downloaded before use.
88
-
89
- You'll probably want to show download progress in your applications to improve UX.
90
-
91
- ### Basic Progress Monitoring
92
-
93
- ```typescript
94
- import { streamText } from "ai";
95
- import { webLLM } from "@built-in-ai/web-llm";
96
-
97
- const model = webLLM("Llama-3.2-3B-Instruct-q4f16_1-MLC");
98
- const availability = await model.availability();
99
-
100
- if (availability === "unavailable") {
101
- console.log("Browser doesn't support built-in AI models");
102
- return;
103
- }
104
-
105
- if (availability === "downloadable") {
106
- await model.createSessionWithProgress((progress) => {
107
- console.log(`Download progress: ${Math.round(progress * 100)}%`);
108
- });
109
- }
110
-
111
- // Model is ready
112
- const result = streamText({
113
- model,
114
- messages: [{ role: "user", content: "Hello!" }],
115
- });
116
- ```
117
-
118
- ### Tool calling
119
-
120
- > Be aware that some models might struggle with this.
121
- > If you want to try it out with best succes, I suggest using a reasoning model (Qwen3).
122
-
123
- ```ts
124
- const result = streamText({
125
- model: webLLM("Qwen3-1.7B-q4f16_1-MLC"),
126
- tools: {
127
- weather: tool({
128
- description: "Get the weather in a location",
129
- inputSchema: z.object({
130
- location: z.string().describe("The location to get the weather for"),
131
- }),
132
- execute: async ({ location }) => ({
133
- location,
134
- temperature: 72 + Math.floor(Math.random() * 21) - 10,
135
- }),
136
- }),
137
- },
138
- stopWhen: stepCountIs(5),
139
- prompt: "What is the weather in San Francisco?",
140
- });
141
- ```
142
-
143
- And then in your useChat use `sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls`.
144
-
145
- ## Integration with useChat Hook
146
-
147
- When using this library with the `useChat` hook, you'll need to create a [custom transport](https://v5.ai-sdk.dev/docs/ai-sdk-ui/transport#transport) implementation to handle client-side AI with download progress.
148
-
149
- You can do this by importing `WebLLMUIMessage` from `@built-in-ai/web-llm` that extends `UIMessage` to include [data parts](https://v5.ai-sdk.dev/docs/ai-sdk-ui/streaming-data) such as download progress.
150
-
151
- See the complete working example: **[`/examples/next-hybrid/app/web-llm/util/web-llm-chat-transport.ts`](../../examples/next-hybrid/app/web-llm/util/web-llm-chat-transport.ts)** and the **[`/examples/next-hybrid/app/web-llm/page.tsx`](../../examples/next-hybrid/app/web-llm/page.tsx)** components.
152
-
153
- This example includes:
154
-
155
- - Download progress with UI progress bar and status message updates
156
- - Hybrid client/server architecture with fallback
157
- - Error handling and notifications
158
- - Full integration with `useChat` hook
159
-
160
- ## API Reference
161
-
162
- ### `webLLM(modelId, settings?)`
163
-
164
- Creates a WebLLM model instance.
165
-
166
- **Parameters:**
167
-
168
- - `modelId`: The model identifier from the [supported list of models](https://github.com/mlc-ai/web-llm/blob/main/src/config.ts)
169
- - `settings` (optional): Configuration options for the WebLLM model
170
- - `appConfig?: AppConfig` - Custom app configuration for WebLLM
171
- - `initProgressCallback?: (progress: WebLLMProgress) => void` - Progress callback for model initialization
172
- - `engineConfig?: MLCEngineConfig` - Engine configuration options
173
- - `worker?: Worker` - A web worker instance to run the model in for better performance
174
-
175
- **Returns:** `WebLLMLanguageModel` instance
176
-
177
- ### `doesBrowserSupportWebLLM(): boolean`
178
-
179
- Quick check if the browser supports the WebLLM. Useful for component-level decisions and feature flags.
180
-
181
- **Returns:** `boolean` - `true` if browser supports WebLLM, `false` otherwise
182
-
183
- **Example:**
184
-
185
- ```typescript
186
- import { doesBrowserSupportWebLLM } from "@built-in-ai/web-llm";
187
-
188
- if (doesBrowserSupportWebLLM()) {
189
- // Show built-in AI option in UI
190
- } else {
191
- // Show server-side option only
192
- }
193
- ```
194
-
195
- ### `WebLLMUIMessage`
196
-
197
- Extended UI message type for use with the `useChat` hook that includes custom data parts for WebLLM functionality.
198
-
199
- **Type Definition:**
200
-
201
- ```typescript
202
- type WebLLMUIMessage = UIMessage<
203
- never,
204
- {
205
- modelDownloadProgress: {
206
- status: "downloading" | "complete" | "error";
207
- progress?: number;
208
- message: string;
209
- };
210
- notification: {
211
- message: string;
212
- level: "info" | "warning" | "error";
213
- };
214
- }
215
- >;
216
- ```
217
-
218
- **Data Parts:**
219
-
220
- - `modelDownloadProgress` - Tracks browser AI model download status and progress
221
- - `notification` - Displays temporary messages and alerts to users
222
-
223
- ### `WebLLMLanguageModel.createSessionWithProgress(onDownloadProgress?)`
224
-
225
- Creates a language model session with optional download progress monitoring.
226
-
227
- **Parameters:**
228
-
229
- - `onDownloadProgress?: (progress: WebLLMProgress) => void` - Optional callback that receives progress reports during model download
230
-
231
- **Returns:** `Promise<MLCEngineInterface>` - The configured language model session
232
-
233
- **Example:**
234
-
235
- ```typescript
236
- const model = webLLM("Llama-3.2-3B-Instruct-q4f16_1-MLC");
237
- await model.createSessionWithProgress((report) => {
238
- console.log(`Download: ${report.text}`);
239
- });
240
- ```
241
-
242
- ### `WebLLMLanguageModel.availability()`
243
-
244
- Checks the current availability status of the WebLLM model.
245
-
246
- **Returns:** `Promise<"unavailable" | "downloadable" | "downloading" | "available">`
247
-
248
- - `"unavailable"` - Model is not supported in the browser
249
- - `"downloadable"` - Model is supported but needs to be downloaded first
250
- - `"downloading"` - Model is currently being downloaded
251
- - `"available"` - Model is ready to use
252
-
253
- ### `WebLLMProgress`
254
-
255
- The progress report type returned during model initialization.
256
-
257
- ```typescript
258
- interface InitProgressReport {
259
- progress: number; // 0-1
260
- timeElapsed: number; // in ms
261
- text: string; // progress text
262
- }
263
- ```
264
-
265
- ## Author
266
-
267
- 2025 © Jakob Hoeg Mørk
268
-
269
- ## Credits
270
-
271
- The WebLLM & Vercel teams
1
+ # WebLLM provider for Vercel AI SDK
2
+
3
+ <div align="center">
4
+ <img src="./hero.png">
5
+ </div>
6
+
7
+ <div align="center">
8
+
9
+ [![NPM Version](https://img.shields.io/npm/v/%40browser-ai%2Fweb-llm)](https://www.npmjs.com/package/@browser-ai/web-llm)
10
+ [![NPM Downloads](https://img.shields.io/npm/dm/%40browser-ai%2Fweb-llm)](https://www.npmjs.com/package/@browser-ai/web-llm)
11
+
12
+ </div>
13
+
14
+ [WebLLM](https://github.com/mlc-ai/web-llm) model provider for [Vercel AI SDK](https://ai-sdk.dev/). This library enables you to easily use the AI SDK with popular open-source models running directly in your web browser.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm i @browser-ai/web-llm
20
+ ```
21
+
22
+ The `@browser-ai/web-llm` package is the AI SDK provider for open-source built-in browser AI models leveraging the [WebLLM](https://github.com/mlc-ai/web-llm) inference engine.
23
+
24
+ ## Documentation
25
+
26
+ For a complete documentation including examples, refer to [this](https://www.browser-ai.dev/docs/ai-sdk-v6/web-llm) site.
27
+
28
+ ## Author
29
+
30
+ 2025 © Jakob Hoeg Mørk
31
+
32
+ ## Credits
33
+
34
+ The WebLLM & Vercel teams
package/dist/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2CallWarning, LanguageModelV2StreamPart } from '@ai-sdk/provider';
1
+ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult } from '@ai-sdk/provider';
2
2
  import { AppConfig, InitProgressReport, MLCEngineConfig, MLCEngineInterface } from '@mlc-ai/web-llm';
3
3
  export { InitProgressReport as WebLLMProgress, WebWorkerMLCEngineHandler } from '@mlc-ai/web-llm';
4
4
  import { UIMessage } from 'ai';
5
5
 
6
6
  /**
7
- * UI message type for built-in AI features with custom data parts.
7
+ * UI message type for Browser AI features with custom data parts.
8
8
  *
9
9
  * Extends base UIMessage to include specific data part schemas
10
10
  * such as model download progress
@@ -13,7 +13,7 @@ import { UIMessage } from 'ai';
13
13
  * // Import and use with useChat hook from @ai-sdk/react
14
14
  * ```typescript
15
15
  * import { useChat } from "@ai-sdk/react";
16
- * import { WebLLMUIMessage } from "@built-in-ai/web-llm";
16
+ * import { WebLLMUIMessage } from "@browser-ai/web-llm";
17
17
  *
18
18
  * const { messages, sendMessage } = useChat<WebLLMUIMessage>({
19
19
  * onData: (dataPart) => {
@@ -66,7 +66,7 @@ type Availability =
66
66
 
67
67
  declare global {
68
68
  interface Navigator {
69
- gpu?: unknown;
69
+ gpu?: GPU;
70
70
  }
71
71
  }
72
72
  type WebLLMModelId = string;
@@ -92,12 +92,12 @@ interface WebLLMSettings {
92
92
  worker?: Worker;
93
93
  }
94
94
  /**
95
- * Check if the browser supports WebLLM
96
- * @returns true if the browser supports WebLLM, false otherwise
95
+ * Check if the browser supports WebGPU (required for WebLLM).
96
+ * @returns boolean - true if WebGPU API is available
97
97
  */
98
98
  declare function doesBrowserSupportWebLLM(): boolean;
99
- declare class WebLLMLanguageModel implements LanguageModelV2 {
100
- readonly specificationVersion = "v2";
99
+ declare class WebLLMLanguageModel implements LanguageModelV3 {
100
+ readonly specificationVersion = "v3";
101
101
  readonly modelId: WebLLMModelId;
102
102
  readonly provider = "web-llm";
103
103
  private readonly config;
@@ -121,22 +121,12 @@ declare class WebLLMLanguageModel implements LanguageModelV2 {
121
121
  * @throws {LoadSettingError} When WebLLM is not available or model needs to be downloaded
122
122
  * @throws {UnsupportedFunctionalityError} When unsupported features like file input are used
123
123
  */
124
- doGenerate(options: LanguageModelV2CallOptions): Promise<{
125
- content: LanguageModelV2Content[];
126
- finishReason: LanguageModelV2FinishReason;
127
- usage: {
128
- inputTokens: number | undefined;
129
- outputTokens: number | undefined;
130
- totalTokens: number | undefined;
131
- };
132
- request: {
133
- body: any;
134
- };
135
- warnings: LanguageModelV2CallWarning[];
136
- }>;
124
+ doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult>;
137
125
  /**
138
- * Check the availability of the WebLLM model
139
- * @returns Promise resolving to "unavailable", "available", or "available-after-download"
126
+ * Check the availability of the WebLLM model.
127
+ * Note: On mobile devices with a worker, WebGPU detection is skipped since it
128
+ * can't be done reliably. The actual availability will be determined at init.
129
+ * @returns Promise resolving to "unavailable", "available", or "downloadable"
140
130
  */
141
131
  availability(): Promise<Availability>;
142
132
  /**
@@ -163,12 +153,7 @@ declare class WebLLMLanguageModel implements LanguageModelV2 {
163
153
  * @throws {LoadSettingError} When WebLLM is not available or model needs to be downloaded
164
154
  * @throws {UnsupportedFunctionalityError} When unsupported features like file input are used
165
155
  */
166
- doStream(options: LanguageModelV2CallOptions): Promise<{
167
- stream: ReadableStream<LanguageModelV2StreamPart>;
168
- request: {
169
- body: any;
170
- };
171
- }>;
156
+ doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
172
157
  }
173
158
 
174
159
  /**
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2CallWarning, LanguageModelV2StreamPart } from '@ai-sdk/provider';
1
+ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult } from '@ai-sdk/provider';
2
2
  import { AppConfig, InitProgressReport, MLCEngineConfig, MLCEngineInterface } from '@mlc-ai/web-llm';
3
3
  export { InitProgressReport as WebLLMProgress, WebWorkerMLCEngineHandler } from '@mlc-ai/web-llm';
4
4
  import { UIMessage } from 'ai';
5
5
 
6
6
  /**
7
- * UI message type for built-in AI features with custom data parts.
7
+ * UI message type for Browser AI features with custom data parts.
8
8
  *
9
9
  * Extends base UIMessage to include specific data part schemas
10
10
  * such as model download progress
@@ -13,7 +13,7 @@ import { UIMessage } from 'ai';
13
13
  * // Import and use with useChat hook from @ai-sdk/react
14
14
  * ```typescript
15
15
  * import { useChat } from "@ai-sdk/react";
16
- * import { WebLLMUIMessage } from "@built-in-ai/web-llm";
16
+ * import { WebLLMUIMessage } from "@browser-ai/web-llm";
17
17
  *
18
18
  * const { messages, sendMessage } = useChat<WebLLMUIMessage>({
19
19
  * onData: (dataPart) => {
@@ -66,7 +66,7 @@ type Availability =
66
66
 
67
67
  declare global {
68
68
  interface Navigator {
69
- gpu?: unknown;
69
+ gpu?: GPU;
70
70
  }
71
71
  }
72
72
  type WebLLMModelId = string;
@@ -92,12 +92,12 @@ interface WebLLMSettings {
92
92
  worker?: Worker;
93
93
  }
94
94
  /**
95
- * Check if the browser supports WebLLM
96
- * @returns true if the browser supports WebLLM, false otherwise
95
+ * Check if the browser supports WebGPU (required for WebLLM).
96
+ * @returns boolean - true if WebGPU API is available
97
97
  */
98
98
  declare function doesBrowserSupportWebLLM(): boolean;
99
- declare class WebLLMLanguageModel implements LanguageModelV2 {
100
- readonly specificationVersion = "v2";
99
+ declare class WebLLMLanguageModel implements LanguageModelV3 {
100
+ readonly specificationVersion = "v3";
101
101
  readonly modelId: WebLLMModelId;
102
102
  readonly provider = "web-llm";
103
103
  private readonly config;
@@ -121,22 +121,12 @@ declare class WebLLMLanguageModel implements LanguageModelV2 {
121
121
  * @throws {LoadSettingError} When WebLLM is not available or model needs to be downloaded
122
122
  * @throws {UnsupportedFunctionalityError} When unsupported features like file input are used
123
123
  */
124
- doGenerate(options: LanguageModelV2CallOptions): Promise<{
125
- content: LanguageModelV2Content[];
126
- finishReason: LanguageModelV2FinishReason;
127
- usage: {
128
- inputTokens: number | undefined;
129
- outputTokens: number | undefined;
130
- totalTokens: number | undefined;
131
- };
132
- request: {
133
- body: any;
134
- };
135
- warnings: LanguageModelV2CallWarning[];
136
- }>;
124
+ doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult>;
137
125
  /**
138
- * Check the availability of the WebLLM model
139
- * @returns Promise resolving to "unavailable", "available", or "available-after-download"
126
+ * Check the availability of the WebLLM model.
127
+ * Note: On mobile devices with a worker, WebGPU detection is skipped since it
128
+ * can't be done reliably. The actual availability will be determined at init.
129
+ * @returns Promise resolving to "unavailable", "available", or "downloadable"
140
130
  */
141
131
  availability(): Promise<Availability>;
142
132
  /**
@@ -163,12 +153,7 @@ declare class WebLLMLanguageModel implements LanguageModelV2 {
163
153
  * @throws {LoadSettingError} When WebLLM is not available or model needs to be downloaded
164
154
  * @throws {UnsupportedFunctionalityError} When unsupported features like file input are used
165
155
  */
166
- doStream(options: LanguageModelV2CallOptions): Promise<{
167
- stream: ReadableStream<LanguageModelV2StreamPart>;
168
- request: {
169
- body: any;
170
- };
171
- }>;
156
+ doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
172
157
  }
173
158
 
174
159
  /**