@browser-ai/core 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 +30 -379
- package/dist/index.d.mts +41 -70
- package/dist/index.d.ts +41 -70
- package/dist/index.js +98 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +72 -72
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/convert-to-
|
|
1
|
+
// src/convert-to-browser-ai-messages.ts
|
|
2
2
|
import {
|
|
3
3
|
UnsupportedFunctionalityError
|
|
4
4
|
} from "@ai-sdk/provider";
|
|
@@ -27,7 +27,7 @@ ${payloads.join("\n")}
|
|
|
27
27
|
\`\`\``;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// src/convert-to-
|
|
30
|
+
// src/convert-to-browser-ai-messages.ts
|
|
31
31
|
function convertBase64ToUint8Array(base64) {
|
|
32
32
|
try {
|
|
33
33
|
const binaryString = atob(base64);
|
|
@@ -96,6 +96,8 @@ function convertToolResultOutput(output) {
|
|
|
96
96
|
return { value: output.value, isError: true };
|
|
97
97
|
case "content":
|
|
98
98
|
return { value: output.value, isError: false };
|
|
99
|
+
case "execution-denied":
|
|
100
|
+
return { value: output.reason, isError: true };
|
|
99
101
|
default: {
|
|
100
102
|
const exhaustiveCheck = output;
|
|
101
103
|
return { value: exhaustiveCheck, isError: false };
|
|
@@ -111,7 +113,7 @@ function toToolResult(part) {
|
|
|
111
113
|
isError
|
|
112
114
|
};
|
|
113
115
|
}
|
|
114
|
-
function
|
|
116
|
+
function convertToBrowserAIMessages(prompt) {
|
|
115
117
|
const normalizedPrompt = prompt.slice();
|
|
116
118
|
let systemMessage;
|
|
117
119
|
const messages = [];
|
|
@@ -347,17 +349,17 @@ function parseJsonFunctionCalls(response) {
|
|
|
347
349
|
}
|
|
348
350
|
|
|
349
351
|
// src/utils/warnings.ts
|
|
350
|
-
function createUnsupportedSettingWarning(
|
|
352
|
+
function createUnsupportedSettingWarning(feature, details) {
|
|
351
353
|
return {
|
|
352
|
-
type: "unsupported
|
|
353
|
-
|
|
354
|
+
type: "unsupported",
|
|
355
|
+
feature,
|
|
354
356
|
details
|
|
355
357
|
};
|
|
356
358
|
}
|
|
357
359
|
function createUnsupportedToolWarning(tool, details) {
|
|
358
360
|
return {
|
|
359
|
-
type: "unsupported
|
|
360
|
-
tool
|
|
361
|
+
type: "unsupported",
|
|
362
|
+
feature: `tool:${tool.name}`,
|
|
361
363
|
details
|
|
362
364
|
};
|
|
363
365
|
}
|
|
@@ -529,7 +531,7 @@ var SessionManager = class {
|
|
|
529
531
|
async getSession(options) {
|
|
530
532
|
if (typeof LanguageModel === "undefined") {
|
|
531
533
|
throw new LoadSettingError({
|
|
532
|
-
message: "Prompt API is not available. This library requires Chrome or Edge browser with
|
|
534
|
+
message: "Prompt API is not available. This library requires Chrome or Edge browser with browser AI capabilities."
|
|
533
535
|
});
|
|
534
536
|
}
|
|
535
537
|
if (this.session) {
|
|
@@ -543,6 +545,16 @@ var SessionManager = class {
|
|
|
543
545
|
}
|
|
544
546
|
const sessionOptions = this.prepareSessionOptions(options);
|
|
545
547
|
this.session = await LanguageModel.create(sessionOptions);
|
|
548
|
+
const onQuotaOverflow = options?.onQuotaOverflow || this.baseOptions.onQuotaOverflow;
|
|
549
|
+
if (onQuotaOverflow) {
|
|
550
|
+
this.session.addEventListener("quotaoverflow", onQuotaOverflow);
|
|
551
|
+
} else {
|
|
552
|
+
this.session.addEventListener("quotaoverflow", () => {
|
|
553
|
+
console.warn(
|
|
554
|
+
"Model quota exceeded. Consider handling 'quotaoverflow' event."
|
|
555
|
+
);
|
|
556
|
+
});
|
|
557
|
+
}
|
|
546
558
|
return this.session;
|
|
547
559
|
}
|
|
548
560
|
/**
|
|
@@ -567,7 +579,7 @@ var SessionManager = class {
|
|
|
567
579
|
return this.getSession({ onDownloadProgress });
|
|
568
580
|
}
|
|
569
581
|
/**
|
|
570
|
-
* Checks the availability status of the
|
|
582
|
+
* Checks the availability status of the browser AI model
|
|
571
583
|
*
|
|
572
584
|
* @returns Promise resolving to availability status
|
|
573
585
|
* - "unavailable": Model is not supported
|
|
@@ -623,6 +635,7 @@ var SessionManager = class {
|
|
|
623
635
|
systemMessage,
|
|
624
636
|
expectedInputs,
|
|
625
637
|
onDownloadProgress,
|
|
638
|
+
onQuotaOverflow,
|
|
626
639
|
...createOptions
|
|
627
640
|
} = options;
|
|
628
641
|
Object.assign(mergedOptions, createOptions);
|
|
@@ -907,11 +920,8 @@ ${this.FENCE_END}`;
|
|
|
907
920
|
}
|
|
908
921
|
};
|
|
909
922
|
|
|
910
|
-
// src/
|
|
911
|
-
function
|
|
912
|
-
return typeof LanguageModel !== "undefined";
|
|
913
|
-
}
|
|
914
|
-
function isBuiltInAIModelAvailable() {
|
|
923
|
+
// src/browser-ai-language-model.ts
|
|
924
|
+
function doesBrowserSupportBrowserAI() {
|
|
915
925
|
return typeof LanguageModel !== "undefined";
|
|
916
926
|
}
|
|
917
927
|
function extractToolName(content) {
|
|
@@ -971,9 +981,9 @@ function extractArgumentsContent(content) {
|
|
|
971
981
|
}
|
|
972
982
|
return result;
|
|
973
983
|
}
|
|
974
|
-
var
|
|
984
|
+
var BrowserAIChatLanguageModel = class {
|
|
975
985
|
constructor(modelId, options = {}) {
|
|
976
|
-
this.specificationVersion = "
|
|
986
|
+
this.specificationVersion = "v3";
|
|
977
987
|
this.provider = "browser-ai";
|
|
978
988
|
this.supportedUrls = {
|
|
979
989
|
"image/*": [/^https?:\/\/.+$/],
|
|
@@ -1041,7 +1051,7 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1041
1051
|
);
|
|
1042
1052
|
}
|
|
1043
1053
|
const hasMultiModalInput = hasMultimodalContent(prompt);
|
|
1044
|
-
const { systemMessage, messages } =
|
|
1054
|
+
const { systemMessage, messages } = convertToBrowserAIMessages(prompt);
|
|
1045
1055
|
const promptOptions = {};
|
|
1046
1056
|
if (responseFormat?.type === "json") {
|
|
1047
1057
|
promptOptions.responseConstraint = responseFormat.schema;
|
|
@@ -1112,11 +1122,19 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1112
1122
|
}
|
|
1113
1123
|
return {
|
|
1114
1124
|
content: parts,
|
|
1115
|
-
finishReason: "tool-calls",
|
|
1125
|
+
finishReason: { unified: "tool-calls", raw: "tool-calls" },
|
|
1116
1126
|
usage: {
|
|
1117
|
-
inputTokens:
|
|
1118
|
-
|
|
1119
|
-
|
|
1127
|
+
inputTokens: {
|
|
1128
|
+
total: void 0,
|
|
1129
|
+
noCache: void 0,
|
|
1130
|
+
cacheRead: void 0,
|
|
1131
|
+
cacheWrite: void 0
|
|
1132
|
+
},
|
|
1133
|
+
outputTokens: {
|
|
1134
|
+
total: void 0,
|
|
1135
|
+
text: void 0,
|
|
1136
|
+
reasoning: void 0
|
|
1137
|
+
}
|
|
1120
1138
|
},
|
|
1121
1139
|
request: { body: { messages: promptMessages, options: promptOptions } },
|
|
1122
1140
|
warnings
|
|
@@ -1130,18 +1148,26 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1130
1148
|
];
|
|
1131
1149
|
return {
|
|
1132
1150
|
content,
|
|
1133
|
-
finishReason: "stop",
|
|
1151
|
+
finishReason: { unified: "stop", raw: "stop" },
|
|
1134
1152
|
usage: {
|
|
1135
|
-
inputTokens:
|
|
1136
|
-
|
|
1137
|
-
|
|
1153
|
+
inputTokens: {
|
|
1154
|
+
total: void 0,
|
|
1155
|
+
noCache: void 0,
|
|
1156
|
+
cacheRead: void 0,
|
|
1157
|
+
cacheWrite: void 0
|
|
1158
|
+
},
|
|
1159
|
+
outputTokens: {
|
|
1160
|
+
total: void 0,
|
|
1161
|
+
text: void 0,
|
|
1162
|
+
reasoning: void 0
|
|
1163
|
+
}
|
|
1138
1164
|
},
|
|
1139
1165
|
request: { body: { messages: promptMessages, options: promptOptions } },
|
|
1140
1166
|
warnings
|
|
1141
1167
|
};
|
|
1142
1168
|
}
|
|
1143
1169
|
/**
|
|
1144
|
-
* Check the availability of the
|
|
1170
|
+
* Check the availability of the browser AI model
|
|
1145
1171
|
* @returns Promise resolving to "unavailable", "available", or "available-after-download"
|
|
1146
1172
|
*/
|
|
1147
1173
|
async availability() {
|
|
@@ -1245,9 +1271,17 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1245
1271
|
type: "finish",
|
|
1246
1272
|
finishReason,
|
|
1247
1273
|
usage: {
|
|
1248
|
-
inputTokens:
|
|
1249
|
-
|
|
1250
|
-
|
|
1274
|
+
inputTokens: {
|
|
1275
|
+
total: session.inputUsage,
|
|
1276
|
+
noCache: void 0,
|
|
1277
|
+
cacheRead: void 0,
|
|
1278
|
+
cacheWrite: void 0
|
|
1279
|
+
},
|
|
1280
|
+
outputTokens: {
|
|
1281
|
+
total: void 0,
|
|
1282
|
+
text: void 0,
|
|
1283
|
+
reasoning: void 0
|
|
1284
|
+
}
|
|
1251
1285
|
}
|
|
1252
1286
|
});
|
|
1253
1287
|
controller.close();
|
|
@@ -1260,7 +1294,7 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1260
1294
|
if (currentReader) {
|
|
1261
1295
|
currentReader.cancel().catch(() => void 0);
|
|
1262
1296
|
}
|
|
1263
|
-
finishStream("stop");
|
|
1297
|
+
finishStream({ unified: "stop", raw: "aborted" });
|
|
1264
1298
|
};
|
|
1265
1299
|
if (options.abortSignal) {
|
|
1266
1300
|
options.abortSignal.addEventListener("abort", abortHandler);
|
|
@@ -1473,17 +1507,17 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1473
1507
|
fenceDetector.clearBuffer();
|
|
1474
1508
|
}
|
|
1475
1509
|
if (!toolBlockDetected || toolCalls.length === 0) {
|
|
1476
|
-
finishStream("stop");
|
|
1510
|
+
finishStream({ unified: "stop", raw: "stop" });
|
|
1477
1511
|
return;
|
|
1478
1512
|
}
|
|
1479
1513
|
if (trailingTextAfterBlock) {
|
|
1480
1514
|
emitTextDelta(trailingTextAfterBlock);
|
|
1481
1515
|
}
|
|
1482
|
-
finishStream("tool-calls");
|
|
1516
|
+
finishStream({ unified: "tool-calls", raw: "tool-calls" });
|
|
1483
1517
|
return;
|
|
1484
1518
|
}
|
|
1485
1519
|
if (!finished && !aborted) {
|
|
1486
|
-
finishStream("other");
|
|
1520
|
+
finishStream({ unified: "other", raw: "other" });
|
|
1487
1521
|
}
|
|
1488
1522
|
} catch (error) {
|
|
1489
1523
|
controller.enqueue({ type: "error", error });
|
|
@@ -1502,11 +1536,11 @@ var BuiltInAIChatLanguageModel = class {
|
|
|
1502
1536
|
}
|
|
1503
1537
|
};
|
|
1504
1538
|
|
|
1505
|
-
// src/
|
|
1539
|
+
// src/browser-ai-embedding-model.ts
|
|
1506
1540
|
import { TextEmbedder } from "@mediapipe/tasks-text";
|
|
1507
|
-
var
|
|
1541
|
+
var BrowserAIEmbeddingModel = class {
|
|
1508
1542
|
constructor(settings = {}) {
|
|
1509
|
-
this.specificationVersion = "
|
|
1543
|
+
this.specificationVersion = "v3";
|
|
1510
1544
|
this.provider = "google-mediapipe";
|
|
1511
1545
|
this.modelId = "embedding";
|
|
1512
1546
|
this.supportsParallelCalls = true;
|
|
@@ -1546,11 +1580,14 @@ var BuiltInAIEmbeddingModel = class {
|
|
|
1546
1580
|
});
|
|
1547
1581
|
return {
|
|
1548
1582
|
embeddings,
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1583
|
+
providerMetadata: {
|
|
1584
|
+
mediapipe: {
|
|
1585
|
+
model: "universal_sentence_encoder",
|
|
1586
|
+
provider: "google-mediapipe",
|
|
1587
|
+
processed_texts: options.values.length
|
|
1588
|
+
}
|
|
1589
|
+
},
|
|
1590
|
+
warnings: []
|
|
1554
1591
|
};
|
|
1555
1592
|
};
|
|
1556
1593
|
this.settings = { ...this.settings, ...settings };
|
|
@@ -1561,29 +1598,30 @@ var BuiltInAIEmbeddingModel = class {
|
|
|
1561
1598
|
}
|
|
1562
1599
|
};
|
|
1563
1600
|
|
|
1564
|
-
// src/
|
|
1601
|
+
// src/browser-ai-provider.ts
|
|
1565
1602
|
import {
|
|
1566
1603
|
NoSuchModelError
|
|
1567
1604
|
} from "@ai-sdk/provider";
|
|
1568
|
-
function
|
|
1605
|
+
function createBrowserAI(options = {}) {
|
|
1569
1606
|
const createChatModel = (modelId, settings) => {
|
|
1570
|
-
return new
|
|
1607
|
+
return new BrowserAIChatLanguageModel(modelId, settings);
|
|
1571
1608
|
};
|
|
1572
1609
|
const createEmbeddingModel = (modelId, settings) => {
|
|
1573
|
-
return new
|
|
1610
|
+
return new BrowserAIEmbeddingModel(settings);
|
|
1574
1611
|
};
|
|
1575
1612
|
const provider = function(modelId = "text", settings) {
|
|
1576
1613
|
if (new.target) {
|
|
1577
1614
|
throw new Error(
|
|
1578
|
-
"The
|
|
1615
|
+
"The BrowserAI model function cannot be called with the new keyword."
|
|
1579
1616
|
);
|
|
1580
1617
|
}
|
|
1581
1618
|
return createChatModel(modelId, settings);
|
|
1582
1619
|
};
|
|
1620
|
+
provider.specificationVersion = "v3";
|
|
1583
1621
|
provider.languageModel = createChatModel;
|
|
1584
1622
|
provider.chat = createChatModel;
|
|
1585
|
-
provider.
|
|
1586
|
-
provider.
|
|
1623
|
+
provider.embedding = createEmbeddingModel;
|
|
1624
|
+
provider.embeddingModel = createEmbeddingModel;
|
|
1587
1625
|
provider.imageModel = (modelId) => {
|
|
1588
1626
|
throw new NoSuchModelError({ modelId, modelType: "imageModel" });
|
|
1589
1627
|
};
|
|
@@ -1595,13 +1633,12 @@ function createBuiltInAI(options = {}) {
|
|
|
1595
1633
|
};
|
|
1596
1634
|
return provider;
|
|
1597
1635
|
}
|
|
1598
|
-
var
|
|
1636
|
+
var browserAI = createBrowserAI();
|
|
1599
1637
|
export {
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
isBuiltInAIModelAvailable
|
|
1638
|
+
BrowserAIChatLanguageModel,
|
|
1639
|
+
BrowserAIEmbeddingModel,
|
|
1640
|
+
browserAI,
|
|
1641
|
+
createBrowserAI,
|
|
1642
|
+
doesBrowserSupportBrowserAI
|
|
1606
1643
|
};
|
|
1607
1644
|
//# sourceMappingURL=index.mjs.map
|