@browser-ai/web-llm 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -271
- package/dist/index.d.mts +14 -29
- package/dist/index.d.ts +14 -29
- package/dist/index.js +295 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +295 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +71 -70
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
var marker = "vercel.ai.error";
|
|
3
3
|
var symbol = Symbol.for(marker);
|
|
4
4
|
var _a;
|
|
5
|
-
var
|
|
5
|
+
var _b;
|
|
6
|
+
var AISDKError = class _AISDKError extends (_b = Error, _a = symbol, _b) {
|
|
6
7
|
/**
|
|
7
8
|
* Creates an AI SDK Error.
|
|
8
9
|
*
|
|
@@ -27,55 +28,172 @@ var _AISDKError = class _AISDKError2 extends Error {
|
|
|
27
28
|
* @returns {boolean} True if the error is an AI SDK Error, false otherwise.
|
|
28
29
|
*/
|
|
29
30
|
static isInstance(error) {
|
|
30
|
-
return
|
|
31
|
+
return _AISDKError.hasMarker(error, marker);
|
|
31
32
|
}
|
|
32
33
|
static hasMarker(error, marker15) {
|
|
33
34
|
const markerSymbol = Symbol.for(marker15);
|
|
34
35
|
return error != null && typeof error === "object" && markerSymbol in error && typeof error[markerSymbol] === "boolean" && error[markerSymbol] === true;
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
|
-
_a = symbol;
|
|
38
|
-
var AISDKError = _AISDKError;
|
|
39
38
|
var name = "AI_APICallError";
|
|
40
39
|
var marker2 = `vercel.ai.error.${name}`;
|
|
41
40
|
var symbol2 = Symbol.for(marker2);
|
|
42
41
|
var _a2;
|
|
43
|
-
|
|
42
|
+
var _b2;
|
|
43
|
+
var APICallError = class extends (_b2 = AISDKError, _a2 = symbol2, _b2) {
|
|
44
|
+
constructor({
|
|
45
|
+
message,
|
|
46
|
+
url,
|
|
47
|
+
requestBodyValues,
|
|
48
|
+
statusCode,
|
|
49
|
+
responseHeaders,
|
|
50
|
+
responseBody,
|
|
51
|
+
cause,
|
|
52
|
+
isRetryable = statusCode != null && (statusCode === 408 || // request timeout
|
|
53
|
+
statusCode === 409 || // conflict
|
|
54
|
+
statusCode === 429 || // too many requests
|
|
55
|
+
statusCode >= 500),
|
|
56
|
+
// server error
|
|
57
|
+
data
|
|
58
|
+
}) {
|
|
59
|
+
super({ name, message, cause });
|
|
60
|
+
this[_a2] = true;
|
|
61
|
+
this.url = url;
|
|
62
|
+
this.requestBodyValues = requestBodyValues;
|
|
63
|
+
this.statusCode = statusCode;
|
|
64
|
+
this.responseHeaders = responseHeaders;
|
|
65
|
+
this.responseBody = responseBody;
|
|
66
|
+
this.isRetryable = isRetryable;
|
|
67
|
+
this.data = data;
|
|
68
|
+
}
|
|
69
|
+
static isInstance(error) {
|
|
70
|
+
return AISDKError.hasMarker(error, marker2);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
44
73
|
var name2 = "AI_EmptyResponseBodyError";
|
|
45
74
|
var marker3 = `vercel.ai.error.${name2}`;
|
|
46
75
|
var symbol3 = Symbol.for(marker3);
|
|
47
76
|
var _a3;
|
|
48
|
-
|
|
77
|
+
var _b3;
|
|
78
|
+
var EmptyResponseBodyError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) {
|
|
79
|
+
// used in isInstance
|
|
80
|
+
constructor({ message = "Empty response body" } = {}) {
|
|
81
|
+
super({ name: name2, message });
|
|
82
|
+
this[_a3] = true;
|
|
83
|
+
}
|
|
84
|
+
static isInstance(error) {
|
|
85
|
+
return AISDKError.hasMarker(error, marker3);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
function getErrorMessage(error) {
|
|
89
|
+
if (error == null) {
|
|
90
|
+
return "unknown error";
|
|
91
|
+
}
|
|
92
|
+
if (typeof error === "string") {
|
|
93
|
+
return error;
|
|
94
|
+
}
|
|
95
|
+
if (error instanceof Error) {
|
|
96
|
+
return error.message;
|
|
97
|
+
}
|
|
98
|
+
return JSON.stringify(error);
|
|
99
|
+
}
|
|
49
100
|
var name3 = "AI_InvalidArgumentError";
|
|
50
101
|
var marker4 = `vercel.ai.error.${name3}`;
|
|
51
102
|
var symbol4 = Symbol.for(marker4);
|
|
52
103
|
var _a4;
|
|
53
|
-
|
|
104
|
+
var _b4;
|
|
105
|
+
var InvalidArgumentError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) {
|
|
106
|
+
constructor({
|
|
107
|
+
message,
|
|
108
|
+
cause,
|
|
109
|
+
argument
|
|
110
|
+
}) {
|
|
111
|
+
super({ name: name3, message, cause });
|
|
112
|
+
this[_a4] = true;
|
|
113
|
+
this.argument = argument;
|
|
114
|
+
}
|
|
115
|
+
static isInstance(error) {
|
|
116
|
+
return AISDKError.hasMarker(error, marker4);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
54
119
|
var name4 = "AI_InvalidPromptError";
|
|
55
120
|
var marker5 = `vercel.ai.error.${name4}`;
|
|
56
121
|
var symbol5 = Symbol.for(marker5);
|
|
57
122
|
var _a5;
|
|
58
|
-
|
|
123
|
+
var _b5;
|
|
124
|
+
var InvalidPromptError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) {
|
|
125
|
+
constructor({
|
|
126
|
+
prompt,
|
|
127
|
+
message,
|
|
128
|
+
cause
|
|
129
|
+
}) {
|
|
130
|
+
super({ name: name4, message: `Invalid prompt: ${message}`, cause });
|
|
131
|
+
this[_a5] = true;
|
|
132
|
+
this.prompt = prompt;
|
|
133
|
+
}
|
|
134
|
+
static isInstance(error) {
|
|
135
|
+
return AISDKError.hasMarker(error, marker5);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
59
138
|
var name5 = "AI_InvalidResponseDataError";
|
|
60
139
|
var marker6 = `vercel.ai.error.${name5}`;
|
|
61
140
|
var symbol6 = Symbol.for(marker6);
|
|
62
141
|
var _a6;
|
|
63
|
-
|
|
142
|
+
var _b6;
|
|
143
|
+
var InvalidResponseDataError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) {
|
|
144
|
+
constructor({
|
|
145
|
+
data,
|
|
146
|
+
message = `Invalid response data: ${JSON.stringify(data)}.`
|
|
147
|
+
}) {
|
|
148
|
+
super({ name: name5, message });
|
|
149
|
+
this[_a6] = true;
|
|
150
|
+
this.data = data;
|
|
151
|
+
}
|
|
152
|
+
static isInstance(error) {
|
|
153
|
+
return AISDKError.hasMarker(error, marker6);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
64
156
|
var name6 = "AI_JSONParseError";
|
|
65
157
|
var marker7 = `vercel.ai.error.${name6}`;
|
|
66
158
|
var symbol7 = Symbol.for(marker7);
|
|
67
159
|
var _a7;
|
|
68
|
-
|
|
160
|
+
var _b7;
|
|
161
|
+
var JSONParseError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) {
|
|
162
|
+
constructor({ text, cause }) {
|
|
163
|
+
super({
|
|
164
|
+
name: name6,
|
|
165
|
+
message: `JSON parsing failed: Text: ${text}.
|
|
166
|
+
Error message: ${getErrorMessage(cause)}`,
|
|
167
|
+
cause
|
|
168
|
+
});
|
|
169
|
+
this[_a7] = true;
|
|
170
|
+
this.text = text;
|
|
171
|
+
}
|
|
172
|
+
static isInstance(error) {
|
|
173
|
+
return AISDKError.hasMarker(error, marker7);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
69
176
|
var name7 = "AI_LoadAPIKeyError";
|
|
70
177
|
var marker8 = `vercel.ai.error.${name7}`;
|
|
71
178
|
var symbol8 = Symbol.for(marker8);
|
|
72
179
|
var _a8;
|
|
73
|
-
|
|
180
|
+
var _b8;
|
|
181
|
+
var LoadAPIKeyError = class extends (_b8 = AISDKError, _a8 = symbol8, _b8) {
|
|
182
|
+
// used in isInstance
|
|
183
|
+
constructor({ message }) {
|
|
184
|
+
super({ name: name7, message });
|
|
185
|
+
this[_a8] = true;
|
|
186
|
+
}
|
|
187
|
+
static isInstance(error) {
|
|
188
|
+
return AISDKError.hasMarker(error, marker8);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
74
191
|
var name8 = "AI_LoadSettingError";
|
|
75
192
|
var marker9 = `vercel.ai.error.${name8}`;
|
|
76
193
|
var symbol9 = Symbol.for(marker9);
|
|
77
194
|
var _a9;
|
|
78
|
-
var
|
|
195
|
+
var _b9;
|
|
196
|
+
var LoadSettingError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) {
|
|
79
197
|
// used in isInstance
|
|
80
198
|
constructor({ message }) {
|
|
81
199
|
super({ name: name8, message });
|
|
@@ -85,32 +203,107 @@ var LoadSettingError = class extends AISDKError {
|
|
|
85
203
|
return AISDKError.hasMarker(error, marker9);
|
|
86
204
|
}
|
|
87
205
|
};
|
|
88
|
-
_a9 = symbol9;
|
|
89
206
|
var name9 = "AI_NoContentGeneratedError";
|
|
90
207
|
var marker10 = `vercel.ai.error.${name9}`;
|
|
91
208
|
var symbol10 = Symbol.for(marker10);
|
|
92
209
|
var _a10;
|
|
93
|
-
|
|
210
|
+
var _b10;
|
|
211
|
+
var NoContentGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) {
|
|
212
|
+
// used in isInstance
|
|
213
|
+
constructor({
|
|
214
|
+
message = "No content generated."
|
|
215
|
+
} = {}) {
|
|
216
|
+
super({ name: name9, message });
|
|
217
|
+
this[_a10] = true;
|
|
218
|
+
}
|
|
219
|
+
static isInstance(error) {
|
|
220
|
+
return AISDKError.hasMarker(error, marker10);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
94
223
|
var name10 = "AI_NoSuchModelError";
|
|
95
224
|
var marker11 = `vercel.ai.error.${name10}`;
|
|
96
225
|
var symbol11 = Symbol.for(marker11);
|
|
97
226
|
var _a11;
|
|
98
|
-
|
|
227
|
+
var _b11;
|
|
228
|
+
var NoSuchModelError = class extends (_b11 = AISDKError, _a11 = symbol11, _b11) {
|
|
229
|
+
constructor({
|
|
230
|
+
errorName = name10,
|
|
231
|
+
modelId,
|
|
232
|
+
modelType,
|
|
233
|
+
message = `No such ${modelType}: ${modelId}`
|
|
234
|
+
}) {
|
|
235
|
+
super({ name: errorName, message });
|
|
236
|
+
this[_a11] = true;
|
|
237
|
+
this.modelId = modelId;
|
|
238
|
+
this.modelType = modelType;
|
|
239
|
+
}
|
|
240
|
+
static isInstance(error) {
|
|
241
|
+
return AISDKError.hasMarker(error, marker11);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
99
244
|
var name11 = "AI_TooManyEmbeddingValuesForCallError";
|
|
100
245
|
var marker12 = `vercel.ai.error.${name11}`;
|
|
101
246
|
var symbol12 = Symbol.for(marker12);
|
|
102
247
|
var _a12;
|
|
103
|
-
|
|
248
|
+
var _b12;
|
|
249
|
+
var TooManyEmbeddingValuesForCallError = class extends (_b12 = AISDKError, _a12 = symbol12, _b12) {
|
|
250
|
+
constructor(options) {
|
|
251
|
+
super({
|
|
252
|
+
name: name11,
|
|
253
|
+
message: `Too many values for a single embedding call. The ${options.provider} model "${options.modelId}" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`
|
|
254
|
+
});
|
|
255
|
+
this[_a12] = true;
|
|
256
|
+
this.provider = options.provider;
|
|
257
|
+
this.modelId = options.modelId;
|
|
258
|
+
this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;
|
|
259
|
+
this.values = options.values;
|
|
260
|
+
}
|
|
261
|
+
static isInstance(error) {
|
|
262
|
+
return AISDKError.hasMarker(error, marker12);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
104
265
|
var name12 = "AI_TypeValidationError";
|
|
105
266
|
var marker13 = `vercel.ai.error.${name12}`;
|
|
106
267
|
var symbol13 = Symbol.for(marker13);
|
|
107
268
|
var _a13;
|
|
108
|
-
|
|
269
|
+
var _b13;
|
|
270
|
+
var TypeValidationError = class _TypeValidationError extends (_b13 = AISDKError, _a13 = symbol13, _b13) {
|
|
271
|
+
constructor({ value, cause }) {
|
|
272
|
+
super({
|
|
273
|
+
name: name12,
|
|
274
|
+
message: `Type validation failed: Value: ${JSON.stringify(value)}.
|
|
275
|
+
Error message: ${getErrorMessage(cause)}`,
|
|
276
|
+
cause
|
|
277
|
+
});
|
|
278
|
+
this[_a13] = true;
|
|
279
|
+
this.value = value;
|
|
280
|
+
}
|
|
281
|
+
static isInstance(error) {
|
|
282
|
+
return AISDKError.hasMarker(error, marker13);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Wraps an error into a TypeValidationError.
|
|
286
|
+
* If the cause is already a TypeValidationError with the same value, it returns the cause.
|
|
287
|
+
* Otherwise, it creates a new TypeValidationError.
|
|
288
|
+
*
|
|
289
|
+
* @param {Object} params - The parameters for wrapping the error.
|
|
290
|
+
* @param {unknown} params.value - The value that failed validation.
|
|
291
|
+
* @param {unknown} params.cause - The original error or cause of the validation failure.
|
|
292
|
+
* @returns {TypeValidationError} A TypeValidationError instance.
|
|
293
|
+
*/
|
|
294
|
+
static wrap({
|
|
295
|
+
value,
|
|
296
|
+
cause
|
|
297
|
+
}) {
|
|
298
|
+
return _TypeValidationError.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError({ value, cause });
|
|
299
|
+
}
|
|
300
|
+
};
|
|
109
301
|
var name13 = "AI_UnsupportedFunctionalityError";
|
|
110
302
|
var marker14 = `vercel.ai.error.${name13}`;
|
|
111
303
|
var symbol14 = Symbol.for(marker14);
|
|
112
304
|
var _a14;
|
|
113
|
-
var
|
|
305
|
+
var _b14;
|
|
306
|
+
var UnsupportedFunctionalityError = class extends (_b14 = AISDKError, _a14 = symbol14, _b14) {
|
|
114
307
|
constructor({
|
|
115
308
|
functionality,
|
|
116
309
|
message = `'${functionality}' functionality not supported.`
|
|
@@ -123,7 +316,6 @@ var UnsupportedFunctionalityError = class extends AISDKError {
|
|
|
123
316
|
return AISDKError.hasMarker(error, marker14);
|
|
124
317
|
}
|
|
125
318
|
};
|
|
126
|
-
_a14 = symbol14;
|
|
127
319
|
|
|
128
320
|
// src/tool-calling/build-json-system-prompt.ts
|
|
129
321
|
function buildJsonToolSystemPrompt(originalSystemPrompt, tools, options) {
|
|
@@ -267,6 +459,8 @@ function convertToolResultOutput(output) {
|
|
|
267
459
|
return { value: output.value, isError: true };
|
|
268
460
|
case "content":
|
|
269
461
|
return { value: output.value, isError: false };
|
|
462
|
+
case "execution-denied":
|
|
463
|
+
return { value: output.reason, isError: true };
|
|
270
464
|
default: {
|
|
271
465
|
const exhaustiveCheck = output;
|
|
272
466
|
return { value: exhaustiveCheck, isError: false };
|
|
@@ -379,7 +573,7 @@ function convertToWebLLMMessages(prompt) {
|
|
|
379
573
|
}
|
|
380
574
|
break;
|
|
381
575
|
case "tool":
|
|
382
|
-
const toolResults = message.content.map(toToolResult);
|
|
576
|
+
const toolResults = message.content.filter((part) => part.type === "tool-result").map(toToolResult);
|
|
383
577
|
const formattedResults = formatToolResults(toolResults);
|
|
384
578
|
messages.push({
|
|
385
579
|
role: "user",
|
|
@@ -398,17 +592,17 @@ import {
|
|
|
398
592
|
} from "@mlc-ai/web-llm";
|
|
399
593
|
|
|
400
594
|
// src/utils/warnings.ts
|
|
401
|
-
function createUnsupportedSettingWarning(
|
|
595
|
+
function createUnsupportedSettingWarning(feature, details) {
|
|
402
596
|
return {
|
|
403
|
-
type: "unsupported
|
|
404
|
-
|
|
597
|
+
type: "unsupported",
|
|
598
|
+
feature,
|
|
405
599
|
details
|
|
406
600
|
};
|
|
407
601
|
}
|
|
408
602
|
function createUnsupportedToolWarning(tool, details) {
|
|
409
603
|
return {
|
|
410
|
-
type: "unsupported
|
|
411
|
-
tool
|
|
604
|
+
type: "unsupported",
|
|
605
|
+
feature: `tool:${tool.name}`,
|
|
412
606
|
details
|
|
413
607
|
};
|
|
414
608
|
}
|
|
@@ -658,8 +852,21 @@ ${this.FENCE_END}`;
|
|
|
658
852
|
};
|
|
659
853
|
|
|
660
854
|
// src/web-llm-language-model.ts
|
|
855
|
+
function isMobile() {
|
|
856
|
+
if (typeof navigator === "undefined") return false;
|
|
857
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
858
|
+
navigator.userAgent
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
function checkWebGPU() {
|
|
862
|
+
try {
|
|
863
|
+
return !!globalThis?.navigator?.gpu;
|
|
864
|
+
} catch {
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
661
868
|
function doesBrowserSupportWebLLM() {
|
|
662
|
-
return
|
|
869
|
+
return checkWebGPU();
|
|
663
870
|
}
|
|
664
871
|
function extractToolName(content) {
|
|
665
872
|
const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
|
|
@@ -720,7 +927,7 @@ function extractArgumentsContent(content) {
|
|
|
720
927
|
}
|
|
721
928
|
var WebLLMLanguageModel = class {
|
|
722
929
|
constructor(modelId, options = {}) {
|
|
723
|
-
this.specificationVersion = "
|
|
930
|
+
this.specificationVersion = "v3";
|
|
724
931
|
this.provider = "web-llm";
|
|
725
932
|
this.isInitialized = false;
|
|
726
933
|
this.supportedUrls = {
|
|
@@ -944,11 +1151,19 @@ var WebLLMLanguageModel = class {
|
|
|
944
1151
|
}
|
|
945
1152
|
return {
|
|
946
1153
|
content: parts,
|
|
947
|
-
finishReason: "tool-calls",
|
|
1154
|
+
finishReason: { unified: "tool-calls", raw: "tool-calls" },
|
|
948
1155
|
usage: {
|
|
949
|
-
inputTokens:
|
|
950
|
-
|
|
951
|
-
|
|
1156
|
+
inputTokens: {
|
|
1157
|
+
total: response.usage?.prompt_tokens,
|
|
1158
|
+
noCache: void 0,
|
|
1159
|
+
cacheRead: void 0,
|
|
1160
|
+
cacheWrite: void 0
|
|
1161
|
+
},
|
|
1162
|
+
outputTokens: {
|
|
1163
|
+
total: response.usage?.completion_tokens,
|
|
1164
|
+
text: void 0,
|
|
1165
|
+
reasoning: void 0
|
|
1166
|
+
}
|
|
952
1167
|
},
|
|
953
1168
|
request: { body: { messages: promptMessages, ...requestOptions } },
|
|
954
1169
|
warnings
|
|
@@ -960,17 +1175,31 @@ var WebLLMLanguageModel = class {
|
|
|
960
1175
|
text: textContent || rawResponse
|
|
961
1176
|
}
|
|
962
1177
|
];
|
|
963
|
-
let finishReason =
|
|
1178
|
+
let finishReason = {
|
|
1179
|
+
unified: "stop",
|
|
1180
|
+
raw: choice.finish_reason
|
|
1181
|
+
};
|
|
964
1182
|
if (choice.finish_reason === "abort") {
|
|
965
|
-
finishReason = "other";
|
|
1183
|
+
finishReason = { unified: "other", raw: choice.finish_reason };
|
|
966
1184
|
}
|
|
967
1185
|
return {
|
|
968
1186
|
content,
|
|
969
1187
|
finishReason,
|
|
970
1188
|
usage: {
|
|
971
|
-
inputTokens:
|
|
972
|
-
|
|
973
|
-
|
|
1189
|
+
inputTokens: {
|
|
1190
|
+
total: response.usage?.prompt_tokens,
|
|
1191
|
+
noCache: void 0,
|
|
1192
|
+
cacheRead: void 0,
|
|
1193
|
+
cacheWrite: void 0
|
|
1194
|
+
},
|
|
1195
|
+
outputTokens: {
|
|
1196
|
+
total: response.usage?.completion_tokens,
|
|
1197
|
+
text: void 0,
|
|
1198
|
+
reasoning: void 0
|
|
1199
|
+
},
|
|
1200
|
+
raw: {
|
|
1201
|
+
total: response.usage?.total_tokens
|
|
1202
|
+
}
|
|
974
1203
|
},
|
|
975
1204
|
request: { body: { messages: promptMessages, ...requestOptions } },
|
|
976
1205
|
warnings
|
|
@@ -986,17 +1215,20 @@ var WebLLMLanguageModel = class {
|
|
|
986
1215
|
}
|
|
987
1216
|
}
|
|
988
1217
|
/**
|
|
989
|
-
* Check the availability of the WebLLM model
|
|
990
|
-
*
|
|
1218
|
+
* Check the availability of the WebLLM model.
|
|
1219
|
+
* Note: On mobile devices with a worker, WebGPU detection is skipped since it
|
|
1220
|
+
* can't be done reliably. The actual availability will be determined at init.
|
|
1221
|
+
* @returns Promise resolving to "unavailable", "available", or "downloadable"
|
|
991
1222
|
*/
|
|
992
1223
|
async availability() {
|
|
993
|
-
if (!doesBrowserSupportWebLLM()) {
|
|
994
|
-
return "unavailable";
|
|
995
|
-
}
|
|
996
1224
|
if (this.isInitialized) {
|
|
997
1225
|
return "available";
|
|
998
1226
|
}
|
|
999
|
-
|
|
1227
|
+
if (this.config.options.worker && isMobile()) {
|
|
1228
|
+
return "downloadable";
|
|
1229
|
+
}
|
|
1230
|
+
const supported = checkWebGPU();
|
|
1231
|
+
return supported ? "downloadable" : "unavailable";
|
|
1000
1232
|
}
|
|
1001
1233
|
/**
|
|
1002
1234
|
* Creates an engine session with download progress monitoring.
|
|
@@ -1093,9 +1325,20 @@ var WebLLMLanguageModel = class {
|
|
|
1093
1325
|
type: "finish",
|
|
1094
1326
|
finishReason,
|
|
1095
1327
|
usage: {
|
|
1096
|
-
inputTokens:
|
|
1097
|
-
|
|
1098
|
-
|
|
1328
|
+
inputTokens: {
|
|
1329
|
+
total: usage?.prompt_tokens,
|
|
1330
|
+
noCache: void 0,
|
|
1331
|
+
cacheRead: void 0,
|
|
1332
|
+
cacheWrite: void 0
|
|
1333
|
+
},
|
|
1334
|
+
outputTokens: {
|
|
1335
|
+
total: usage?.completion_tokens,
|
|
1336
|
+
text: void 0,
|
|
1337
|
+
reasoning: void 0
|
|
1338
|
+
},
|
|
1339
|
+
raw: {
|
|
1340
|
+
total: usage?.total_tokens
|
|
1341
|
+
}
|
|
1099
1342
|
}
|
|
1100
1343
|
});
|
|
1101
1344
|
controller.close();
|
|
@@ -1293,20 +1536,23 @@ var WebLLMLanguageModel = class {
|
|
|
1293
1536
|
emitTextDelta(fenceDetector.getBuffer());
|
|
1294
1537
|
fenceDetector.clearBuffer();
|
|
1295
1538
|
}
|
|
1296
|
-
let finishReason =
|
|
1539
|
+
let finishReason = {
|
|
1540
|
+
unified: "stop",
|
|
1541
|
+
raw: "stop"
|
|
1542
|
+
};
|
|
1297
1543
|
if (choice.finish_reason === "abort") {
|
|
1298
|
-
finishReason = "other";
|
|
1544
|
+
finishReason = { unified: "other", raw: "abort" };
|
|
1299
1545
|
} else {
|
|
1300
1546
|
const { toolCalls } = parseJsonFunctionCalls(accumulatedText);
|
|
1301
1547
|
if (toolCalls.length > 0) {
|
|
1302
|
-
finishReason = "tool-calls";
|
|
1548
|
+
finishReason = { unified: "tool-calls", raw: "tool-calls" };
|
|
1303
1549
|
}
|
|
1304
1550
|
}
|
|
1305
1551
|
finishStream(finishReason, chunk.usage);
|
|
1306
1552
|
}
|
|
1307
1553
|
}
|
|
1308
1554
|
if (!finished) {
|
|
1309
|
-
finishStream("stop");
|
|
1555
|
+
finishStream({ unified: "stop", raw: "stop" });
|
|
1310
1556
|
}
|
|
1311
1557
|
} catch (error) {
|
|
1312
1558
|
controller.error(error);
|