@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 +34 -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.js
CHANGED
|
@@ -31,7 +31,8 @@ module.exports = __toCommonJS(index_exports);
|
|
|
31
31
|
var marker = "vercel.ai.error";
|
|
32
32
|
var symbol = Symbol.for(marker);
|
|
33
33
|
var _a;
|
|
34
|
-
var
|
|
34
|
+
var _b;
|
|
35
|
+
var AISDKError = class _AISDKError extends (_b = Error, _a = symbol, _b) {
|
|
35
36
|
/**
|
|
36
37
|
* Creates an AI SDK Error.
|
|
37
38
|
*
|
|
@@ -56,55 +57,172 @@ var _AISDKError = class _AISDKError2 extends Error {
|
|
|
56
57
|
* @returns {boolean} True if the error is an AI SDK Error, false otherwise.
|
|
57
58
|
*/
|
|
58
59
|
static isInstance(error) {
|
|
59
|
-
return
|
|
60
|
+
return _AISDKError.hasMarker(error, marker);
|
|
60
61
|
}
|
|
61
62
|
static hasMarker(error, marker15) {
|
|
62
63
|
const markerSymbol = Symbol.for(marker15);
|
|
63
64
|
return error != null && typeof error === "object" && markerSymbol in error && typeof error[markerSymbol] === "boolean" && error[markerSymbol] === true;
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
|
-
_a = symbol;
|
|
67
|
-
var AISDKError = _AISDKError;
|
|
68
67
|
var name = "AI_APICallError";
|
|
69
68
|
var marker2 = `vercel.ai.error.${name}`;
|
|
70
69
|
var symbol2 = Symbol.for(marker2);
|
|
71
70
|
var _a2;
|
|
72
|
-
|
|
71
|
+
var _b2;
|
|
72
|
+
var APICallError = class extends (_b2 = AISDKError, _a2 = symbol2, _b2) {
|
|
73
|
+
constructor({
|
|
74
|
+
message,
|
|
75
|
+
url,
|
|
76
|
+
requestBodyValues,
|
|
77
|
+
statusCode,
|
|
78
|
+
responseHeaders,
|
|
79
|
+
responseBody,
|
|
80
|
+
cause,
|
|
81
|
+
isRetryable = statusCode != null && (statusCode === 408 || // request timeout
|
|
82
|
+
statusCode === 409 || // conflict
|
|
83
|
+
statusCode === 429 || // too many requests
|
|
84
|
+
statusCode >= 500),
|
|
85
|
+
// server error
|
|
86
|
+
data
|
|
87
|
+
}) {
|
|
88
|
+
super({ name, message, cause });
|
|
89
|
+
this[_a2] = true;
|
|
90
|
+
this.url = url;
|
|
91
|
+
this.requestBodyValues = requestBodyValues;
|
|
92
|
+
this.statusCode = statusCode;
|
|
93
|
+
this.responseHeaders = responseHeaders;
|
|
94
|
+
this.responseBody = responseBody;
|
|
95
|
+
this.isRetryable = isRetryable;
|
|
96
|
+
this.data = data;
|
|
97
|
+
}
|
|
98
|
+
static isInstance(error) {
|
|
99
|
+
return AISDKError.hasMarker(error, marker2);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
73
102
|
var name2 = "AI_EmptyResponseBodyError";
|
|
74
103
|
var marker3 = `vercel.ai.error.${name2}`;
|
|
75
104
|
var symbol3 = Symbol.for(marker3);
|
|
76
105
|
var _a3;
|
|
77
|
-
|
|
106
|
+
var _b3;
|
|
107
|
+
var EmptyResponseBodyError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) {
|
|
108
|
+
// used in isInstance
|
|
109
|
+
constructor({ message = "Empty response body" } = {}) {
|
|
110
|
+
super({ name: name2, message });
|
|
111
|
+
this[_a3] = true;
|
|
112
|
+
}
|
|
113
|
+
static isInstance(error) {
|
|
114
|
+
return AISDKError.hasMarker(error, marker3);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
function getErrorMessage(error) {
|
|
118
|
+
if (error == null) {
|
|
119
|
+
return "unknown error";
|
|
120
|
+
}
|
|
121
|
+
if (typeof error === "string") {
|
|
122
|
+
return error;
|
|
123
|
+
}
|
|
124
|
+
if (error instanceof Error) {
|
|
125
|
+
return error.message;
|
|
126
|
+
}
|
|
127
|
+
return JSON.stringify(error);
|
|
128
|
+
}
|
|
78
129
|
var name3 = "AI_InvalidArgumentError";
|
|
79
130
|
var marker4 = `vercel.ai.error.${name3}`;
|
|
80
131
|
var symbol4 = Symbol.for(marker4);
|
|
81
132
|
var _a4;
|
|
82
|
-
|
|
133
|
+
var _b4;
|
|
134
|
+
var InvalidArgumentError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) {
|
|
135
|
+
constructor({
|
|
136
|
+
message,
|
|
137
|
+
cause,
|
|
138
|
+
argument
|
|
139
|
+
}) {
|
|
140
|
+
super({ name: name3, message, cause });
|
|
141
|
+
this[_a4] = true;
|
|
142
|
+
this.argument = argument;
|
|
143
|
+
}
|
|
144
|
+
static isInstance(error) {
|
|
145
|
+
return AISDKError.hasMarker(error, marker4);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
83
148
|
var name4 = "AI_InvalidPromptError";
|
|
84
149
|
var marker5 = `vercel.ai.error.${name4}`;
|
|
85
150
|
var symbol5 = Symbol.for(marker5);
|
|
86
151
|
var _a5;
|
|
87
|
-
|
|
152
|
+
var _b5;
|
|
153
|
+
var InvalidPromptError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) {
|
|
154
|
+
constructor({
|
|
155
|
+
prompt,
|
|
156
|
+
message,
|
|
157
|
+
cause
|
|
158
|
+
}) {
|
|
159
|
+
super({ name: name4, message: `Invalid prompt: ${message}`, cause });
|
|
160
|
+
this[_a5] = true;
|
|
161
|
+
this.prompt = prompt;
|
|
162
|
+
}
|
|
163
|
+
static isInstance(error) {
|
|
164
|
+
return AISDKError.hasMarker(error, marker5);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
88
167
|
var name5 = "AI_InvalidResponseDataError";
|
|
89
168
|
var marker6 = `vercel.ai.error.${name5}`;
|
|
90
169
|
var symbol6 = Symbol.for(marker6);
|
|
91
170
|
var _a6;
|
|
92
|
-
|
|
171
|
+
var _b6;
|
|
172
|
+
var InvalidResponseDataError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) {
|
|
173
|
+
constructor({
|
|
174
|
+
data,
|
|
175
|
+
message = `Invalid response data: ${JSON.stringify(data)}.`
|
|
176
|
+
}) {
|
|
177
|
+
super({ name: name5, message });
|
|
178
|
+
this[_a6] = true;
|
|
179
|
+
this.data = data;
|
|
180
|
+
}
|
|
181
|
+
static isInstance(error) {
|
|
182
|
+
return AISDKError.hasMarker(error, marker6);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
93
185
|
var name6 = "AI_JSONParseError";
|
|
94
186
|
var marker7 = `vercel.ai.error.${name6}`;
|
|
95
187
|
var symbol7 = Symbol.for(marker7);
|
|
96
188
|
var _a7;
|
|
97
|
-
|
|
189
|
+
var _b7;
|
|
190
|
+
var JSONParseError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) {
|
|
191
|
+
constructor({ text, cause }) {
|
|
192
|
+
super({
|
|
193
|
+
name: name6,
|
|
194
|
+
message: `JSON parsing failed: Text: ${text}.
|
|
195
|
+
Error message: ${getErrorMessage(cause)}`,
|
|
196
|
+
cause
|
|
197
|
+
});
|
|
198
|
+
this[_a7] = true;
|
|
199
|
+
this.text = text;
|
|
200
|
+
}
|
|
201
|
+
static isInstance(error) {
|
|
202
|
+
return AISDKError.hasMarker(error, marker7);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
98
205
|
var name7 = "AI_LoadAPIKeyError";
|
|
99
206
|
var marker8 = `vercel.ai.error.${name7}`;
|
|
100
207
|
var symbol8 = Symbol.for(marker8);
|
|
101
208
|
var _a8;
|
|
102
|
-
|
|
209
|
+
var _b8;
|
|
210
|
+
var LoadAPIKeyError = class extends (_b8 = AISDKError, _a8 = symbol8, _b8) {
|
|
211
|
+
// used in isInstance
|
|
212
|
+
constructor({ message }) {
|
|
213
|
+
super({ name: name7, message });
|
|
214
|
+
this[_a8] = true;
|
|
215
|
+
}
|
|
216
|
+
static isInstance(error) {
|
|
217
|
+
return AISDKError.hasMarker(error, marker8);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
103
220
|
var name8 = "AI_LoadSettingError";
|
|
104
221
|
var marker9 = `vercel.ai.error.${name8}`;
|
|
105
222
|
var symbol9 = Symbol.for(marker9);
|
|
106
223
|
var _a9;
|
|
107
|
-
var
|
|
224
|
+
var _b9;
|
|
225
|
+
var LoadSettingError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) {
|
|
108
226
|
// used in isInstance
|
|
109
227
|
constructor({ message }) {
|
|
110
228
|
super({ name: name8, message });
|
|
@@ -114,32 +232,107 @@ var LoadSettingError = class extends AISDKError {
|
|
|
114
232
|
return AISDKError.hasMarker(error, marker9);
|
|
115
233
|
}
|
|
116
234
|
};
|
|
117
|
-
_a9 = symbol9;
|
|
118
235
|
var name9 = "AI_NoContentGeneratedError";
|
|
119
236
|
var marker10 = `vercel.ai.error.${name9}`;
|
|
120
237
|
var symbol10 = Symbol.for(marker10);
|
|
121
238
|
var _a10;
|
|
122
|
-
|
|
239
|
+
var _b10;
|
|
240
|
+
var NoContentGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) {
|
|
241
|
+
// used in isInstance
|
|
242
|
+
constructor({
|
|
243
|
+
message = "No content generated."
|
|
244
|
+
} = {}) {
|
|
245
|
+
super({ name: name9, message });
|
|
246
|
+
this[_a10] = true;
|
|
247
|
+
}
|
|
248
|
+
static isInstance(error) {
|
|
249
|
+
return AISDKError.hasMarker(error, marker10);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
123
252
|
var name10 = "AI_NoSuchModelError";
|
|
124
253
|
var marker11 = `vercel.ai.error.${name10}`;
|
|
125
254
|
var symbol11 = Symbol.for(marker11);
|
|
126
255
|
var _a11;
|
|
127
|
-
|
|
256
|
+
var _b11;
|
|
257
|
+
var NoSuchModelError = class extends (_b11 = AISDKError, _a11 = symbol11, _b11) {
|
|
258
|
+
constructor({
|
|
259
|
+
errorName = name10,
|
|
260
|
+
modelId,
|
|
261
|
+
modelType,
|
|
262
|
+
message = `No such ${modelType}: ${modelId}`
|
|
263
|
+
}) {
|
|
264
|
+
super({ name: errorName, message });
|
|
265
|
+
this[_a11] = true;
|
|
266
|
+
this.modelId = modelId;
|
|
267
|
+
this.modelType = modelType;
|
|
268
|
+
}
|
|
269
|
+
static isInstance(error) {
|
|
270
|
+
return AISDKError.hasMarker(error, marker11);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
128
273
|
var name11 = "AI_TooManyEmbeddingValuesForCallError";
|
|
129
274
|
var marker12 = `vercel.ai.error.${name11}`;
|
|
130
275
|
var symbol12 = Symbol.for(marker12);
|
|
131
276
|
var _a12;
|
|
132
|
-
|
|
277
|
+
var _b12;
|
|
278
|
+
var TooManyEmbeddingValuesForCallError = class extends (_b12 = AISDKError, _a12 = symbol12, _b12) {
|
|
279
|
+
constructor(options) {
|
|
280
|
+
super({
|
|
281
|
+
name: name11,
|
|
282
|
+
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.`
|
|
283
|
+
});
|
|
284
|
+
this[_a12] = true;
|
|
285
|
+
this.provider = options.provider;
|
|
286
|
+
this.modelId = options.modelId;
|
|
287
|
+
this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;
|
|
288
|
+
this.values = options.values;
|
|
289
|
+
}
|
|
290
|
+
static isInstance(error) {
|
|
291
|
+
return AISDKError.hasMarker(error, marker12);
|
|
292
|
+
}
|
|
293
|
+
};
|
|
133
294
|
var name12 = "AI_TypeValidationError";
|
|
134
295
|
var marker13 = `vercel.ai.error.${name12}`;
|
|
135
296
|
var symbol13 = Symbol.for(marker13);
|
|
136
297
|
var _a13;
|
|
137
|
-
|
|
298
|
+
var _b13;
|
|
299
|
+
var TypeValidationError = class _TypeValidationError extends (_b13 = AISDKError, _a13 = symbol13, _b13) {
|
|
300
|
+
constructor({ value, cause }) {
|
|
301
|
+
super({
|
|
302
|
+
name: name12,
|
|
303
|
+
message: `Type validation failed: Value: ${JSON.stringify(value)}.
|
|
304
|
+
Error message: ${getErrorMessage(cause)}`,
|
|
305
|
+
cause
|
|
306
|
+
});
|
|
307
|
+
this[_a13] = true;
|
|
308
|
+
this.value = value;
|
|
309
|
+
}
|
|
310
|
+
static isInstance(error) {
|
|
311
|
+
return AISDKError.hasMarker(error, marker13);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Wraps an error into a TypeValidationError.
|
|
315
|
+
* If the cause is already a TypeValidationError with the same value, it returns the cause.
|
|
316
|
+
* Otherwise, it creates a new TypeValidationError.
|
|
317
|
+
*
|
|
318
|
+
* @param {Object} params - The parameters for wrapping the error.
|
|
319
|
+
* @param {unknown} params.value - The value that failed validation.
|
|
320
|
+
* @param {unknown} params.cause - The original error or cause of the validation failure.
|
|
321
|
+
* @returns {TypeValidationError} A TypeValidationError instance.
|
|
322
|
+
*/
|
|
323
|
+
static wrap({
|
|
324
|
+
value,
|
|
325
|
+
cause
|
|
326
|
+
}) {
|
|
327
|
+
return _TypeValidationError.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError({ value, cause });
|
|
328
|
+
}
|
|
329
|
+
};
|
|
138
330
|
var name13 = "AI_UnsupportedFunctionalityError";
|
|
139
331
|
var marker14 = `vercel.ai.error.${name13}`;
|
|
140
332
|
var symbol14 = Symbol.for(marker14);
|
|
141
333
|
var _a14;
|
|
142
|
-
var
|
|
334
|
+
var _b14;
|
|
335
|
+
var UnsupportedFunctionalityError = class extends (_b14 = AISDKError, _a14 = symbol14, _b14) {
|
|
143
336
|
constructor({
|
|
144
337
|
functionality,
|
|
145
338
|
message = `'${functionality}' functionality not supported.`
|
|
@@ -152,7 +345,6 @@ var UnsupportedFunctionalityError = class extends AISDKError {
|
|
|
152
345
|
return AISDKError.hasMarker(error, marker14);
|
|
153
346
|
}
|
|
154
347
|
};
|
|
155
|
-
_a14 = symbol14;
|
|
156
348
|
|
|
157
349
|
// src/tool-calling/build-json-system-prompt.ts
|
|
158
350
|
function buildJsonToolSystemPrompt(originalSystemPrompt, tools, options) {
|
|
@@ -296,6 +488,8 @@ function convertToolResultOutput(output) {
|
|
|
296
488
|
return { value: output.value, isError: true };
|
|
297
489
|
case "content":
|
|
298
490
|
return { value: output.value, isError: false };
|
|
491
|
+
case "execution-denied":
|
|
492
|
+
return { value: output.reason, isError: true };
|
|
299
493
|
default: {
|
|
300
494
|
const exhaustiveCheck = output;
|
|
301
495
|
return { value: exhaustiveCheck, isError: false };
|
|
@@ -408,7 +602,7 @@ function convertToWebLLMMessages(prompt) {
|
|
|
408
602
|
}
|
|
409
603
|
break;
|
|
410
604
|
case "tool":
|
|
411
|
-
const toolResults = message.content.map(toToolResult);
|
|
605
|
+
const toolResults = message.content.filter((part) => part.type === "tool-result").map(toToolResult);
|
|
412
606
|
const formattedResults = formatToolResults(toolResults);
|
|
413
607
|
messages.push({
|
|
414
608
|
role: "user",
|
|
@@ -424,17 +618,17 @@ function convertToWebLLMMessages(prompt) {
|
|
|
424
618
|
var import_web_llm = require("@mlc-ai/web-llm");
|
|
425
619
|
|
|
426
620
|
// src/utils/warnings.ts
|
|
427
|
-
function createUnsupportedSettingWarning(
|
|
621
|
+
function createUnsupportedSettingWarning(feature, details) {
|
|
428
622
|
return {
|
|
429
|
-
type: "unsupported
|
|
430
|
-
|
|
623
|
+
type: "unsupported",
|
|
624
|
+
feature,
|
|
431
625
|
details
|
|
432
626
|
};
|
|
433
627
|
}
|
|
434
628
|
function createUnsupportedToolWarning(tool, details) {
|
|
435
629
|
return {
|
|
436
|
-
type: "unsupported
|
|
437
|
-
tool
|
|
630
|
+
type: "unsupported",
|
|
631
|
+
feature: `tool:${tool.name}`,
|
|
438
632
|
details
|
|
439
633
|
};
|
|
440
634
|
}
|
|
@@ -684,8 +878,21 @@ ${this.FENCE_END}`;
|
|
|
684
878
|
};
|
|
685
879
|
|
|
686
880
|
// src/web-llm-language-model.ts
|
|
881
|
+
function isMobile() {
|
|
882
|
+
if (typeof navigator === "undefined") return false;
|
|
883
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
884
|
+
navigator.userAgent
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
function checkWebGPU() {
|
|
888
|
+
try {
|
|
889
|
+
return !!globalThis?.navigator?.gpu;
|
|
890
|
+
} catch {
|
|
891
|
+
return false;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
687
894
|
function doesBrowserSupportWebLLM() {
|
|
688
|
-
return
|
|
895
|
+
return checkWebGPU();
|
|
689
896
|
}
|
|
690
897
|
function extractToolName(content) {
|
|
691
898
|
const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
|
|
@@ -746,7 +953,7 @@ function extractArgumentsContent(content) {
|
|
|
746
953
|
}
|
|
747
954
|
var WebLLMLanguageModel = class {
|
|
748
955
|
constructor(modelId, options = {}) {
|
|
749
|
-
this.specificationVersion = "
|
|
956
|
+
this.specificationVersion = "v3";
|
|
750
957
|
this.provider = "web-llm";
|
|
751
958
|
this.isInitialized = false;
|
|
752
959
|
this.supportedUrls = {
|
|
@@ -970,11 +1177,19 @@ var WebLLMLanguageModel = class {
|
|
|
970
1177
|
}
|
|
971
1178
|
return {
|
|
972
1179
|
content: parts,
|
|
973
|
-
finishReason: "tool-calls",
|
|
1180
|
+
finishReason: { unified: "tool-calls", raw: "tool-calls" },
|
|
974
1181
|
usage: {
|
|
975
|
-
inputTokens:
|
|
976
|
-
|
|
977
|
-
|
|
1182
|
+
inputTokens: {
|
|
1183
|
+
total: response.usage?.prompt_tokens,
|
|
1184
|
+
noCache: void 0,
|
|
1185
|
+
cacheRead: void 0,
|
|
1186
|
+
cacheWrite: void 0
|
|
1187
|
+
},
|
|
1188
|
+
outputTokens: {
|
|
1189
|
+
total: response.usage?.completion_tokens,
|
|
1190
|
+
text: void 0,
|
|
1191
|
+
reasoning: void 0
|
|
1192
|
+
}
|
|
978
1193
|
},
|
|
979
1194
|
request: { body: { messages: promptMessages, ...requestOptions } },
|
|
980
1195
|
warnings
|
|
@@ -986,17 +1201,31 @@ var WebLLMLanguageModel = class {
|
|
|
986
1201
|
text: textContent || rawResponse
|
|
987
1202
|
}
|
|
988
1203
|
];
|
|
989
|
-
let finishReason =
|
|
1204
|
+
let finishReason = {
|
|
1205
|
+
unified: "stop",
|
|
1206
|
+
raw: choice.finish_reason
|
|
1207
|
+
};
|
|
990
1208
|
if (choice.finish_reason === "abort") {
|
|
991
|
-
finishReason = "other";
|
|
1209
|
+
finishReason = { unified: "other", raw: choice.finish_reason };
|
|
992
1210
|
}
|
|
993
1211
|
return {
|
|
994
1212
|
content,
|
|
995
1213
|
finishReason,
|
|
996
1214
|
usage: {
|
|
997
|
-
inputTokens:
|
|
998
|
-
|
|
999
|
-
|
|
1215
|
+
inputTokens: {
|
|
1216
|
+
total: response.usage?.prompt_tokens,
|
|
1217
|
+
noCache: void 0,
|
|
1218
|
+
cacheRead: void 0,
|
|
1219
|
+
cacheWrite: void 0
|
|
1220
|
+
},
|
|
1221
|
+
outputTokens: {
|
|
1222
|
+
total: response.usage?.completion_tokens,
|
|
1223
|
+
text: void 0,
|
|
1224
|
+
reasoning: void 0
|
|
1225
|
+
},
|
|
1226
|
+
raw: {
|
|
1227
|
+
total: response.usage?.total_tokens
|
|
1228
|
+
}
|
|
1000
1229
|
},
|
|
1001
1230
|
request: { body: { messages: promptMessages, ...requestOptions } },
|
|
1002
1231
|
warnings
|
|
@@ -1012,17 +1241,20 @@ var WebLLMLanguageModel = class {
|
|
|
1012
1241
|
}
|
|
1013
1242
|
}
|
|
1014
1243
|
/**
|
|
1015
|
-
* Check the availability of the WebLLM model
|
|
1016
|
-
*
|
|
1244
|
+
* Check the availability of the WebLLM model.
|
|
1245
|
+
* Note: On mobile devices with a worker, WebGPU detection is skipped since it
|
|
1246
|
+
* can't be done reliably. The actual availability will be determined at init.
|
|
1247
|
+
* @returns Promise resolving to "unavailable", "available", or "downloadable"
|
|
1017
1248
|
*/
|
|
1018
1249
|
async availability() {
|
|
1019
|
-
if (!doesBrowserSupportWebLLM()) {
|
|
1020
|
-
return "unavailable";
|
|
1021
|
-
}
|
|
1022
1250
|
if (this.isInitialized) {
|
|
1023
1251
|
return "available";
|
|
1024
1252
|
}
|
|
1025
|
-
|
|
1253
|
+
if (this.config.options.worker && isMobile()) {
|
|
1254
|
+
return "downloadable";
|
|
1255
|
+
}
|
|
1256
|
+
const supported = checkWebGPU();
|
|
1257
|
+
return supported ? "downloadable" : "unavailable";
|
|
1026
1258
|
}
|
|
1027
1259
|
/**
|
|
1028
1260
|
* Creates an engine session with download progress monitoring.
|
|
@@ -1119,9 +1351,20 @@ var WebLLMLanguageModel = class {
|
|
|
1119
1351
|
type: "finish",
|
|
1120
1352
|
finishReason,
|
|
1121
1353
|
usage: {
|
|
1122
|
-
inputTokens:
|
|
1123
|
-
|
|
1124
|
-
|
|
1354
|
+
inputTokens: {
|
|
1355
|
+
total: usage?.prompt_tokens,
|
|
1356
|
+
noCache: void 0,
|
|
1357
|
+
cacheRead: void 0,
|
|
1358
|
+
cacheWrite: void 0
|
|
1359
|
+
},
|
|
1360
|
+
outputTokens: {
|
|
1361
|
+
total: usage?.completion_tokens,
|
|
1362
|
+
text: void 0,
|
|
1363
|
+
reasoning: void 0
|
|
1364
|
+
},
|
|
1365
|
+
raw: {
|
|
1366
|
+
total: usage?.total_tokens
|
|
1367
|
+
}
|
|
1125
1368
|
}
|
|
1126
1369
|
});
|
|
1127
1370
|
controller.close();
|
|
@@ -1319,20 +1562,23 @@ var WebLLMLanguageModel = class {
|
|
|
1319
1562
|
emitTextDelta(fenceDetector.getBuffer());
|
|
1320
1563
|
fenceDetector.clearBuffer();
|
|
1321
1564
|
}
|
|
1322
|
-
let finishReason =
|
|
1565
|
+
let finishReason = {
|
|
1566
|
+
unified: "stop",
|
|
1567
|
+
raw: "stop"
|
|
1568
|
+
};
|
|
1323
1569
|
if (choice.finish_reason === "abort") {
|
|
1324
|
-
finishReason = "other";
|
|
1570
|
+
finishReason = { unified: "other", raw: "abort" };
|
|
1325
1571
|
} else {
|
|
1326
1572
|
const { toolCalls } = parseJsonFunctionCalls(accumulatedText);
|
|
1327
1573
|
if (toolCalls.length > 0) {
|
|
1328
|
-
finishReason = "tool-calls";
|
|
1574
|
+
finishReason = { unified: "tool-calls", raw: "tool-calls" };
|
|
1329
1575
|
}
|
|
1330
1576
|
}
|
|
1331
1577
|
finishStream(finishReason, chunk.usage);
|
|
1332
1578
|
}
|
|
1333
1579
|
}
|
|
1334
1580
|
if (!finished) {
|
|
1335
|
-
finishStream("stop");
|
|
1581
|
+
finishStream({ unified: "stop", raw: "stop" });
|
|
1336
1582
|
}
|
|
1337
1583
|
} catch (error) {
|
|
1338
1584
|
controller.error(error);
|