@firebase/ai 2.12.0 → 2.13.0-20260526192810
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/dist/ai-public.d.ts +77 -17
- package/dist/ai.d.ts +77 -17
- package/dist/esm/index.esm.js +123 -29
- package/dist/esm/index.esm.js.map +1 -1
- package/dist/esm/src/methods/chrome-adapter.d.ts +8 -7
- package/dist/esm/src/models/generative-model.d.ts +29 -0
- package/dist/esm/src/types/chrome-adapter.d.ts +1 -1
- package/dist/esm/src/types/enums.d.ts +4 -4
- package/dist/esm/src/types/index.d.ts +1 -1
- package/dist/esm/src/types/language-model.d.ts +40 -10
- package/dist/esm/src/types/requests.d.ts +2 -2
- package/dist/esm/src/types/responses.d.ts +1 -1
- package/dist/index.cjs.js +123 -29
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.node.cjs.js +69 -6
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +69 -6
- package/dist/index.node.mjs.map +1 -1
- package/dist/src/methods/chrome-adapter.d.ts +8 -7
- package/dist/src/models/generative-model.d.ts +29 -0
- package/dist/src/types/chrome-adapter.d.ts +1 -1
- package/dist/src/types/enums.d.ts +4 -4
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/language-model.d.ts +40 -10
- package/dist/src/types/requests.d.ts +2 -2
- package/dist/src/types/responses.d.ts +1 -1
- package/package.json +1 -1
package/dist/esm/index.esm.js
CHANGED
|
@@ -4,7 +4,7 @@ import { FirebaseError, Deferred, getModularInstance } from '@firebase/util';
|
|
|
4
4
|
import { Logger } from '@firebase/logger';
|
|
5
5
|
|
|
6
6
|
var name = "@firebase/ai";
|
|
7
|
-
var version = "2.
|
|
7
|
+
var version = "2.13.0-20260526192810";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @license
|
|
@@ -443,7 +443,7 @@ const ResponseModality = {
|
|
|
443
443
|
* cloud-hosted model. If not available, the SDK will fall back to an
|
|
444
444
|
* on-device model.
|
|
445
445
|
*
|
|
446
|
-
* @
|
|
446
|
+
* @public
|
|
447
447
|
*/
|
|
448
448
|
const InferenceMode = {
|
|
449
449
|
'PREFER_ON_DEVICE': 'prefer_on_device',
|
|
@@ -454,7 +454,7 @@ const InferenceMode = {
|
|
|
454
454
|
/**
|
|
455
455
|
* Indicates whether inference happened on-device or in-cloud.
|
|
456
456
|
*
|
|
457
|
-
* @
|
|
457
|
+
* @public
|
|
458
458
|
*/
|
|
459
459
|
const InferenceSource = {
|
|
460
460
|
'ON_DEVICE': 'on_device',
|
|
@@ -1023,8 +1023,18 @@ var Availability;
|
|
|
1023
1023
|
* See the License for the specific language governing permissions and
|
|
1024
1024
|
* limitations under the License.
|
|
1025
1025
|
*/
|
|
1026
|
-
// Defaults to
|
|
1027
|
-
const
|
|
1026
|
+
// Defaults to English text. This can be overriden by user config.
|
|
1027
|
+
const defaultExpectedText = {
|
|
1028
|
+
type: 'text',
|
|
1029
|
+
languages: ['en']
|
|
1030
|
+
};
|
|
1031
|
+
const defaultExpectedInputs = [
|
|
1032
|
+
defaultExpectedText,
|
|
1033
|
+
{ type: 'image' }
|
|
1034
|
+
];
|
|
1035
|
+
const defaultExpectedOutputs = [
|
|
1036
|
+
defaultExpectedText
|
|
1037
|
+
];
|
|
1028
1038
|
/**
|
|
1029
1039
|
* Defines an inference "backend" that uses Chrome's on-device model,
|
|
1030
1040
|
* and encapsulates logic for detecting when on-device inference is
|
|
@@ -1034,22 +1044,31 @@ class ChromeAdapterImpl {
|
|
|
1034
1044
|
constructor(languageModelProvider, mode, onDeviceParams) {
|
|
1035
1045
|
this.languageModelProvider = languageModelProvider;
|
|
1036
1046
|
this.mode = mode;
|
|
1037
|
-
|
|
1047
|
+
// Promise for on-device model download completion
|
|
1048
|
+
this.downloadPromise = null;
|
|
1038
1049
|
this.onDeviceParams = {
|
|
1039
1050
|
createOptions: {
|
|
1040
|
-
expectedInputs: defaultExpectedInputs
|
|
1051
|
+
expectedInputs: defaultExpectedInputs,
|
|
1052
|
+
expectedOutputs: defaultExpectedOutputs
|
|
1041
1053
|
}
|
|
1042
1054
|
};
|
|
1043
1055
|
if (onDeviceParams) {
|
|
1044
1056
|
this.onDeviceParams = onDeviceParams;
|
|
1045
1057
|
if (!this.onDeviceParams.createOptions) {
|
|
1046
1058
|
this.onDeviceParams.createOptions = {
|
|
1047
|
-
expectedInputs: defaultExpectedInputs
|
|
1059
|
+
expectedInputs: defaultExpectedInputs,
|
|
1060
|
+
expectedOutputs: defaultExpectedOutputs
|
|
1048
1061
|
};
|
|
1049
1062
|
}
|
|
1050
|
-
else
|
|
1051
|
-
this.onDeviceParams.createOptions.expectedInputs
|
|
1052
|
-
|
|
1063
|
+
else {
|
|
1064
|
+
if (!this.onDeviceParams.createOptions.expectedInputs) {
|
|
1065
|
+
this.onDeviceParams.createOptions.expectedInputs =
|
|
1066
|
+
defaultExpectedInputs;
|
|
1067
|
+
}
|
|
1068
|
+
if (!this.onDeviceParams.createOptions.expectedOutputs) {
|
|
1069
|
+
this.onDeviceParams.createOptions.expectedOutputs =
|
|
1070
|
+
defaultExpectedOutputs;
|
|
1071
|
+
}
|
|
1053
1072
|
}
|
|
1054
1073
|
}
|
|
1055
1074
|
}
|
|
@@ -1060,7 +1079,7 @@ class ChromeAdapterImpl {
|
|
|
1060
1079
|
* the mode
|
|
1061
1080
|
* API existence
|
|
1062
1081
|
* prompt formatting
|
|
1063
|
-
* model availability
|
|
1082
|
+
* model availability
|
|
1064
1083
|
*
|
|
1065
1084
|
*
|
|
1066
1085
|
* Pros: callers needn't be concerned with details of on-device availability.</p>
|
|
@@ -1077,8 +1096,7 @@ class ChromeAdapterImpl {
|
|
|
1077
1096
|
logger.debug(`On-device inference unavailable because mode is "only_in_cloud".`);
|
|
1078
1097
|
return false;
|
|
1079
1098
|
}
|
|
1080
|
-
|
|
1081
|
-
const availability = await this.downloadIfAvailable();
|
|
1099
|
+
const availability = await this.languageModelProvider?.availability(this.onDeviceParams.createOptions);
|
|
1082
1100
|
if (this.mode === InferenceMode.ONLY_ON_DEVICE) {
|
|
1083
1101
|
// If it will never be available due to API inavailability, throw.
|
|
1084
1102
|
if (availability === Availability.UNAVAILABLE) {
|
|
@@ -1086,9 +1104,13 @@ class ChromeAdapterImpl {
|
|
|
1086
1104
|
}
|
|
1087
1105
|
else if (availability === Availability.DOWNLOADABLE ||
|
|
1088
1106
|
availability === Availability.DOWNLOADING) {
|
|
1089
|
-
// TODO(chholland): Better user experience during download - progress?
|
|
1090
1107
|
logger.debug(`Waiting for download of LanguageModel to complete.`);
|
|
1091
|
-
|
|
1108
|
+
try {
|
|
1109
|
+
await this.downloadPromise;
|
|
1110
|
+
}
|
|
1111
|
+
catch (e) {
|
|
1112
|
+
throw new AIError(AIErrorCode.ERROR, e.message);
|
|
1113
|
+
}
|
|
1092
1114
|
return true;
|
|
1093
1115
|
}
|
|
1094
1116
|
return true;
|
|
@@ -1165,31 +1187,44 @@ class ChromeAdapterImpl {
|
|
|
1165
1187
|
/**
|
|
1166
1188
|
* Encapsulates logic to get availability and download a model if one is downloadable.
|
|
1167
1189
|
*/
|
|
1168
|
-
async downloadIfAvailable() {
|
|
1190
|
+
async downloadIfAvailable(onDownloadProgress) {
|
|
1169
1191
|
const availability = await this.languageModelProvider?.availability(this.onDeviceParams.createOptions);
|
|
1170
|
-
|
|
1171
|
-
|
|
1192
|
+
/**
|
|
1193
|
+
* Download may have been automatically started by Chrome or other
|
|
1194
|
+
* code, in which case we should still call create() to get a promise
|
|
1195
|
+
* for when the download completes.
|
|
1196
|
+
*/
|
|
1197
|
+
if (availability === Availability.DOWNLOADABLE ||
|
|
1198
|
+
availability === Availability.DOWNLOADING) {
|
|
1199
|
+
this.download(onDownloadProgress);
|
|
1172
1200
|
}
|
|
1173
1201
|
return availability;
|
|
1174
1202
|
}
|
|
1175
1203
|
/**
|
|
1176
1204
|
* Triggers out-of-band download of an on-device model.
|
|
1177
1205
|
*
|
|
1178
|
-
* Chrome
|
|
1179
|
-
* LanguageModel.create.
|
|
1206
|
+
* Chrome may automatically begin a download on startup or
|
|
1207
|
+
* it may trigger a download when code calls LanguageModel.create.
|
|
1180
1208
|
*
|
|
1181
1209
|
* Since Chrome manages the download, the SDK can only avoid redundant download requests by
|
|
1182
1210
|
* tracking if a download has previously been requested.
|
|
1183
1211
|
*/
|
|
1184
|
-
download() {
|
|
1185
|
-
if (this.
|
|
1212
|
+
download(onDownloadProgress) {
|
|
1213
|
+
if (this.downloadPromise) {
|
|
1186
1214
|
return;
|
|
1187
1215
|
}
|
|
1188
|
-
this.
|
|
1216
|
+
const options = { ...this.onDeviceParams.createOptions };
|
|
1217
|
+
if (options && !options.monitor && onDownloadProgress) {
|
|
1218
|
+
options.monitor = m => {
|
|
1219
|
+
m.addEventListener('downloadprogress', e => {
|
|
1220
|
+
onDownloadProgress(e.loaded);
|
|
1221
|
+
});
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1189
1224
|
this.downloadPromise = this.languageModelProvider
|
|
1190
|
-
?.create(
|
|
1225
|
+
?.create(options)
|
|
1191
1226
|
.finally(() => {
|
|
1192
|
-
this.
|
|
1227
|
+
this.downloadPromise = null;
|
|
1193
1228
|
});
|
|
1194
1229
|
}
|
|
1195
1230
|
/**
|
|
@@ -1244,6 +1279,13 @@ class ChromeAdapterImpl {
|
|
|
1244
1279
|
if (!this.languageModelProvider) {
|
|
1245
1280
|
throw new AIError(AIErrorCode.UNSUPPORTED, 'Chrome AI requested for unsupported browser version.');
|
|
1246
1281
|
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Note: `create()` will trigger a download as a side effect if
|
|
1284
|
+
* a model is not downloaded or downloading, but this specific
|
|
1285
|
+
* create() call should not be relied on for the download. The download
|
|
1286
|
+
* should be triggered explicitly by the user in
|
|
1287
|
+
* GenerativeModel.initializeDeviceModel().
|
|
1288
|
+
*/
|
|
1247
1289
|
const newSession = await this.languageModelProvider.create(this.onDeviceParams.createOptions);
|
|
1248
1290
|
if (this.oldSession) {
|
|
1249
1291
|
this.oldSession.destroy();
|
|
@@ -2435,7 +2477,9 @@ async function callCloudOrDevice(request, chromeAdapter, onDeviceCall, inCloudCa
|
|
|
2435
2477
|
};
|
|
2436
2478
|
}
|
|
2437
2479
|
catch (e) {
|
|
2438
|
-
if (e instanceof AIError &&
|
|
2480
|
+
if (e instanceof AIError &&
|
|
2481
|
+
errorsCausingFallback.includes(e.code) &&
|
|
2482
|
+
(await chromeAdapter.isAvailable(request))) {
|
|
2439
2483
|
return {
|
|
2440
2484
|
response: await onDeviceCall(),
|
|
2441
2485
|
inferenceSource: InferenceSource.ON_DEVICE
|
|
@@ -2762,7 +2806,9 @@ class ChatSessionBase {
|
|
|
2762
2806
|
else {
|
|
2763
2807
|
formattedContent = formatNewContent(request);
|
|
2764
2808
|
}
|
|
2765
|
-
const formattedRequest = this._formatRequest(formattedContent,
|
|
2809
|
+
const formattedRequest = this._formatRequest(formattedContent, [
|
|
2810
|
+
...tempHistory
|
|
2811
|
+
]);
|
|
2766
2812
|
tempHistory.push(formattedContent);
|
|
2767
2813
|
const result = await this._callGenerateContent(formattedRequest, singleRequestOptions);
|
|
2768
2814
|
if (result) {
|
|
@@ -2832,8 +2878,10 @@ class ChatSessionBase {
|
|
|
2832
2878
|
else {
|
|
2833
2879
|
formattedContent = formatNewContent(request);
|
|
2834
2880
|
}
|
|
2881
|
+
const formattedRequest = this._formatRequest(formattedContent, [
|
|
2882
|
+
...tempHistory
|
|
2883
|
+
]);
|
|
2835
2884
|
tempHistory.push(formattedContent);
|
|
2836
|
-
const formattedRequest = this._formatRequest(formattedContent, tempHistory);
|
|
2837
2885
|
result = await this._callGenerateContentStream(formattedRequest, singleRequestOptions);
|
|
2838
2886
|
functionCalls = this._getCallableFunctionCalls(result.firstValue);
|
|
2839
2887
|
if (functionCalls &&
|
|
@@ -3221,6 +3269,52 @@ class GenerativeModel extends AIModel {
|
|
|
3221
3269
|
this.systemInstruction = formatSystemInstruction(modelParams.systemInstruction);
|
|
3222
3270
|
this.requestOptions = requestOptions || {};
|
|
3223
3271
|
}
|
|
3272
|
+
/**
|
|
3273
|
+
* Initializes on-device models.
|
|
3274
|
+
*
|
|
3275
|
+
* @remarks
|
|
3276
|
+
* This may trigger a download on first
|
|
3277
|
+
* use. Wait for this promise to complete before calling inference
|
|
3278
|
+
* methods if you want to ensure the device models are ready before
|
|
3279
|
+
* any calls. Calling inference methods before the device is ready
|
|
3280
|
+
* will result in a cloud fallback if `inferenceMode` is set to
|
|
3281
|
+
* `PREFER_ON_DEVICE`, and an error if set to `ONLY_ON_DEVICE`.
|
|
3282
|
+
*
|
|
3283
|
+
* IMPORTANT: This call must be made on or after a user has interacted
|
|
3284
|
+
* with the page (for example, through a button click or key press).
|
|
3285
|
+
* If it is called without a user interaction, and it requires a download,
|
|
3286
|
+
* this will cause an error.
|
|
3287
|
+
*
|
|
3288
|
+
* See the
|
|
3289
|
+
* {@link https://developer.chrome.com/docs/ai/prompt-api#use_the_prompt_api | Prompt API docs }
|
|
3290
|
+
* for more details on this requirement.
|
|
3291
|
+
*
|
|
3292
|
+
* @param onDownloadProgress A callback called repeatedly as the
|
|
3293
|
+
* download progresses that provides a `progressValue` between 0
|
|
3294
|
+
* and 1 representing how much of the download is complete. This
|
|
3295
|
+
* will be ignored if `monitor` was populated in
|
|
3296
|
+
* {@link LanguageModelCreateOptions}.
|
|
3297
|
+
*
|
|
3298
|
+
* @public
|
|
3299
|
+
*/
|
|
3300
|
+
async initializeDeviceModel(onDownloadProgress) {
|
|
3301
|
+
if (!this.chromeAdapter ||
|
|
3302
|
+
this.chromeAdapter.mode === InferenceMode.ONLY_IN_CLOUD) {
|
|
3303
|
+
return;
|
|
3304
|
+
}
|
|
3305
|
+
const availability = await this.chromeAdapter.downloadIfAvailable(onDownloadProgress);
|
|
3306
|
+
if (availability === Availability.UNAVAILABLE) {
|
|
3307
|
+
const notEnabledError = new AIError(AIErrorCode.API_NOT_ENABLED, 'Local LanguageModel API not available in this environment.');
|
|
3308
|
+
if (this.chromeAdapter.mode === InferenceMode.ONLY_ON_DEVICE) {
|
|
3309
|
+
throw notEnabledError;
|
|
3310
|
+
}
|
|
3311
|
+
else {
|
|
3312
|
+
// No reason to throw if not in ONLY_ON_DEVICE mode.
|
|
3313
|
+
logger.debug(notEnabledError.message);
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
await this.chromeAdapter.downloadPromise;
|
|
3317
|
+
}
|
|
3224
3318
|
/**
|
|
3225
3319
|
* Makes a single non-streaming call to the model
|
|
3226
3320
|
* and returns an object containing a single {@link GenerateContentResponse}.
|