@firebase/ai 1.4.0 → 1.4.1-canary.25b60fdaa
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 +462 -213
- package/dist/ai.d.ts +465 -213
- package/dist/esm/{index.esm2017.js → index.esm.js} +349 -276
- package/dist/esm/index.esm.js.map +1 -0
- package/dist/esm/src/api.d.ts +2 -38
- package/dist/esm/src/errors.d.ts +1 -1
- package/dist/esm/src/public-types.d.ts +0 -18
- package/dist/esm/src/requests/schema-builder.d.ts +25 -6
- package/dist/esm/src/types/enums.d.ts +102 -60
- package/dist/esm/src/types/error.d.ts +21 -15
- package/dist/esm/src/types/imagen/requests.d.ts +53 -19
- package/dist/esm/src/types/imagen/responses.d.ts +2 -2
- package/dist/esm/src/types/requests.d.ts +69 -7
- package/dist/esm/src/types/responses.d.ts +135 -12
- package/dist/esm/src/types/schema.d.ts +41 -20
- package/dist/index.cjs.js +364 -279
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.node.cjs.js +364 -279
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +348 -275
- package/dist/index.node.mjs.map +1 -1
- package/dist/src/api.d.ts +2 -38
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/public-types.d.ts +0 -18
- package/dist/src/requests/schema-builder.d.ts +25 -6
- package/dist/src/types/enums.d.ts +102 -60
- package/dist/src/types/error.d.ts +21 -15
- package/dist/src/types/imagen/requests.d.ts +53 -19
- package/dist/src/types/imagen/responses.d.ts +2 -2
- package/dist/src/types/requests.d.ts +69 -7
- package/dist/src/types/responses.d.ts +135 -12
- package/dist/src/types/schema.d.ts +41 -20
- package/package.json +14 -13
- package/dist/esm/index.esm2017.js.map +0 -1
package/dist/index.node.mjs
CHANGED
|
@@ -2,10 +2,9 @@ import { _isFirebaseServerApp, _getProvider, getApp, _registerComponent, registe
|
|
|
2
2
|
import { Component } from '@firebase/component';
|
|
3
3
|
import { FirebaseError, getModularInstance } from '@firebase/util';
|
|
4
4
|
import { Logger } from '@firebase/logger';
|
|
5
|
-
import { __asyncGenerator, __await } from 'tslib';
|
|
6
5
|
|
|
7
6
|
var name = "@firebase/ai";
|
|
8
|
-
var version = "1.4.
|
|
7
|
+
var version = "1.4.1-canary.25b60fdaa";
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* @license
|
|
@@ -56,230 +55,221 @@ const POSSIBLE_ROLES = ['user', 'model', 'function', 'system'];
|
|
|
56
55
|
* Harm categories that would cause prompts or candidates to be blocked.
|
|
57
56
|
* @public
|
|
58
57
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
})(HarmCategory || (HarmCategory = {}));
|
|
58
|
+
const HarmCategory = {
|
|
59
|
+
HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH',
|
|
60
|
+
HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
|
|
61
|
+
HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT',
|
|
62
|
+
HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT'
|
|
63
|
+
};
|
|
66
64
|
/**
|
|
67
65
|
* Threshold above which a prompt or candidate will be blocked.
|
|
68
66
|
* @public
|
|
69
67
|
*/
|
|
70
|
-
|
|
71
|
-
(function (HarmBlockThreshold) {
|
|
68
|
+
const HarmBlockThreshold = {
|
|
72
69
|
/**
|
|
73
70
|
* Content with `NEGLIGIBLE` will be allowed.
|
|
74
71
|
*/
|
|
75
|
-
|
|
72
|
+
BLOCK_LOW_AND_ABOVE: 'BLOCK_LOW_AND_ABOVE',
|
|
76
73
|
/**
|
|
77
74
|
* Content with `NEGLIGIBLE` and `LOW` will be allowed.
|
|
78
75
|
*/
|
|
79
|
-
|
|
76
|
+
BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE',
|
|
80
77
|
/**
|
|
81
78
|
* Content with `NEGLIGIBLE`, `LOW`, and `MEDIUM` will be allowed.
|
|
82
79
|
*/
|
|
83
|
-
|
|
80
|
+
BLOCK_ONLY_HIGH: 'BLOCK_ONLY_HIGH',
|
|
84
81
|
/**
|
|
85
82
|
* All content will be allowed.
|
|
86
83
|
*/
|
|
87
|
-
|
|
84
|
+
BLOCK_NONE: 'BLOCK_NONE',
|
|
88
85
|
/**
|
|
89
86
|
* All content will be allowed. This is the same as `BLOCK_NONE`, but the metadata corresponding
|
|
90
87
|
* to the {@link HarmCategory} will not be present in the response.
|
|
91
88
|
*/
|
|
92
|
-
|
|
93
|
-
}
|
|
89
|
+
OFF: 'OFF'
|
|
90
|
+
};
|
|
94
91
|
/**
|
|
95
92
|
* This property is not supported in the Gemini Developer API ({@link GoogleAIBackend}).
|
|
96
93
|
*
|
|
97
94
|
* @public
|
|
98
95
|
*/
|
|
99
|
-
|
|
100
|
-
(function (HarmBlockMethod) {
|
|
96
|
+
const HarmBlockMethod = {
|
|
101
97
|
/**
|
|
102
98
|
* The harm block method uses both probability and severity scores.
|
|
103
99
|
*/
|
|
104
|
-
|
|
100
|
+
SEVERITY: 'SEVERITY',
|
|
105
101
|
/**
|
|
106
102
|
* The harm block method uses the probability score.
|
|
107
103
|
*/
|
|
108
|
-
|
|
109
|
-
}
|
|
104
|
+
PROBABILITY: 'PROBABILITY'
|
|
105
|
+
};
|
|
110
106
|
/**
|
|
111
107
|
* Probability that a prompt or candidate matches a harm category.
|
|
112
108
|
* @public
|
|
113
109
|
*/
|
|
114
|
-
|
|
115
|
-
(function (HarmProbability) {
|
|
110
|
+
const HarmProbability = {
|
|
116
111
|
/**
|
|
117
112
|
* Content has a negligible chance of being unsafe.
|
|
118
113
|
*/
|
|
119
|
-
|
|
114
|
+
NEGLIGIBLE: 'NEGLIGIBLE',
|
|
120
115
|
/**
|
|
121
116
|
* Content has a low chance of being unsafe.
|
|
122
117
|
*/
|
|
123
|
-
|
|
118
|
+
LOW: 'LOW',
|
|
124
119
|
/**
|
|
125
120
|
* Content has a medium chance of being unsafe.
|
|
126
121
|
*/
|
|
127
|
-
|
|
122
|
+
MEDIUM: 'MEDIUM',
|
|
128
123
|
/**
|
|
129
124
|
* Content has a high chance of being unsafe.
|
|
130
125
|
*/
|
|
131
|
-
|
|
132
|
-
}
|
|
126
|
+
HIGH: 'HIGH'
|
|
127
|
+
};
|
|
133
128
|
/**
|
|
134
129
|
* Harm severity levels.
|
|
135
130
|
* @public
|
|
136
131
|
*/
|
|
137
|
-
|
|
138
|
-
(function (HarmSeverity) {
|
|
132
|
+
const HarmSeverity = {
|
|
139
133
|
/**
|
|
140
134
|
* Negligible level of harm severity.
|
|
141
135
|
*/
|
|
142
|
-
|
|
136
|
+
HARM_SEVERITY_NEGLIGIBLE: 'HARM_SEVERITY_NEGLIGIBLE',
|
|
143
137
|
/**
|
|
144
138
|
* Low level of harm severity.
|
|
145
139
|
*/
|
|
146
|
-
|
|
140
|
+
HARM_SEVERITY_LOW: 'HARM_SEVERITY_LOW',
|
|
147
141
|
/**
|
|
148
142
|
* Medium level of harm severity.
|
|
149
143
|
*/
|
|
150
|
-
|
|
144
|
+
HARM_SEVERITY_MEDIUM: 'HARM_SEVERITY_MEDIUM',
|
|
151
145
|
/**
|
|
152
146
|
* High level of harm severity.
|
|
153
147
|
*/
|
|
154
|
-
|
|
148
|
+
HARM_SEVERITY_HIGH: 'HARM_SEVERITY_HIGH',
|
|
155
149
|
/**
|
|
156
150
|
* Harm severity is not supported.
|
|
157
151
|
*
|
|
158
152
|
* @remarks
|
|
159
153
|
* The GoogleAI backend does not support `HarmSeverity`, so this value is used as a fallback.
|
|
160
154
|
*/
|
|
161
|
-
|
|
162
|
-
}
|
|
155
|
+
HARM_SEVERITY_UNSUPPORTED: 'HARM_SEVERITY_UNSUPPORTED'
|
|
156
|
+
};
|
|
163
157
|
/**
|
|
164
158
|
* Reason that a prompt was blocked.
|
|
165
159
|
* @public
|
|
166
160
|
*/
|
|
167
|
-
|
|
168
|
-
(function (BlockReason) {
|
|
161
|
+
const BlockReason = {
|
|
169
162
|
/**
|
|
170
163
|
* Content was blocked by safety settings.
|
|
171
164
|
*/
|
|
172
|
-
|
|
165
|
+
SAFETY: 'SAFETY',
|
|
173
166
|
/**
|
|
174
167
|
* Content was blocked, but the reason is uncategorized.
|
|
175
168
|
*/
|
|
176
|
-
|
|
169
|
+
OTHER: 'OTHER',
|
|
177
170
|
/**
|
|
178
171
|
* Content was blocked because it contained terms from the terminology blocklist.
|
|
179
172
|
*/
|
|
180
|
-
|
|
173
|
+
BLOCKLIST: 'BLOCKLIST',
|
|
181
174
|
/**
|
|
182
175
|
* Content was blocked due to prohibited content.
|
|
183
176
|
*/
|
|
184
|
-
|
|
185
|
-
}
|
|
177
|
+
PROHIBITED_CONTENT: 'PROHIBITED_CONTENT'
|
|
178
|
+
};
|
|
186
179
|
/**
|
|
187
180
|
* Reason that a candidate finished.
|
|
188
181
|
* @public
|
|
189
182
|
*/
|
|
190
|
-
|
|
191
|
-
(function (FinishReason) {
|
|
183
|
+
const FinishReason = {
|
|
192
184
|
/**
|
|
193
185
|
* Natural stop point of the model or provided stop sequence.
|
|
194
186
|
*/
|
|
195
|
-
|
|
187
|
+
STOP: 'STOP',
|
|
196
188
|
/**
|
|
197
189
|
* The maximum number of tokens as specified in the request was reached.
|
|
198
190
|
*/
|
|
199
|
-
|
|
191
|
+
MAX_TOKENS: 'MAX_TOKENS',
|
|
200
192
|
/**
|
|
201
193
|
* The candidate content was flagged for safety reasons.
|
|
202
194
|
*/
|
|
203
|
-
|
|
195
|
+
SAFETY: 'SAFETY',
|
|
204
196
|
/**
|
|
205
197
|
* The candidate content was flagged for recitation reasons.
|
|
206
198
|
*/
|
|
207
|
-
|
|
199
|
+
RECITATION: 'RECITATION',
|
|
208
200
|
/**
|
|
209
201
|
* Unknown reason.
|
|
210
202
|
*/
|
|
211
|
-
|
|
203
|
+
OTHER: 'OTHER',
|
|
212
204
|
/**
|
|
213
205
|
* The candidate content contained forbidden terms.
|
|
214
206
|
*/
|
|
215
|
-
|
|
207
|
+
BLOCKLIST: 'BLOCKLIST',
|
|
216
208
|
/**
|
|
217
209
|
* The candidate content potentially contained prohibited content.
|
|
218
210
|
*/
|
|
219
|
-
|
|
211
|
+
PROHIBITED_CONTENT: 'PROHIBITED_CONTENT',
|
|
220
212
|
/**
|
|
221
213
|
* The candidate content potentially contained Sensitive Personally Identifiable Information (SPII).
|
|
222
214
|
*/
|
|
223
|
-
|
|
215
|
+
SPII: 'SPII',
|
|
224
216
|
/**
|
|
225
217
|
* The function call generated by the model was invalid.
|
|
226
218
|
*/
|
|
227
|
-
|
|
228
|
-
}
|
|
219
|
+
MALFORMED_FUNCTION_CALL: 'MALFORMED_FUNCTION_CALL'
|
|
220
|
+
};
|
|
229
221
|
/**
|
|
230
222
|
* @public
|
|
231
223
|
*/
|
|
232
|
-
|
|
233
|
-
(function (FunctionCallingMode) {
|
|
224
|
+
const FunctionCallingMode = {
|
|
234
225
|
/**
|
|
235
226
|
* Default model behavior; model decides to predict either a function call
|
|
236
227
|
* or a natural language response.
|
|
237
228
|
*/
|
|
238
|
-
|
|
229
|
+
AUTO: 'AUTO',
|
|
239
230
|
/**
|
|
240
231
|
* Model is constrained to always predicting a function call only.
|
|
241
232
|
* If `allowed_function_names` is set, the predicted function call will be
|
|
242
233
|
* limited to any one of `allowed_function_names`, else the predicted
|
|
243
234
|
* function call will be any one of the provided `function_declarations`.
|
|
244
235
|
*/
|
|
245
|
-
|
|
236
|
+
ANY: 'ANY',
|
|
246
237
|
/**
|
|
247
238
|
* Model will not predict any function call. Model behavior is same as when
|
|
248
239
|
* not passing any function declarations.
|
|
249
240
|
*/
|
|
250
|
-
|
|
251
|
-
}
|
|
241
|
+
NONE: 'NONE'
|
|
242
|
+
};
|
|
252
243
|
/**
|
|
253
244
|
* Content part modality.
|
|
254
245
|
* @public
|
|
255
246
|
*/
|
|
256
|
-
|
|
257
|
-
(function (Modality) {
|
|
247
|
+
const Modality = {
|
|
258
248
|
/**
|
|
259
249
|
* Unspecified modality.
|
|
260
250
|
*/
|
|
261
|
-
|
|
251
|
+
MODALITY_UNSPECIFIED: 'MODALITY_UNSPECIFIED',
|
|
262
252
|
/**
|
|
263
253
|
* Plain text.
|
|
264
254
|
*/
|
|
265
|
-
|
|
255
|
+
TEXT: 'TEXT',
|
|
266
256
|
/**
|
|
267
257
|
* Image.
|
|
268
258
|
*/
|
|
269
|
-
|
|
259
|
+
IMAGE: 'IMAGE',
|
|
270
260
|
/**
|
|
271
261
|
* Video.
|
|
272
262
|
*/
|
|
273
|
-
|
|
263
|
+
VIDEO: 'VIDEO',
|
|
274
264
|
/**
|
|
275
265
|
* Audio.
|
|
276
266
|
*/
|
|
277
|
-
|
|
267
|
+
AUDIO: 'AUDIO',
|
|
278
268
|
/**
|
|
279
269
|
* Document (for example, PDF).
|
|
280
270
|
*/
|
|
281
|
-
|
|
282
|
-
}
|
|
271
|
+
DOCUMENT: 'DOCUMENT'
|
|
272
|
+
};
|
|
283
273
|
/**
|
|
284
274
|
* Generation modalities to be returned in generation responses.
|
|
285
275
|
*
|
|
@@ -298,6 +288,56 @@ const ResponseModality = {
|
|
|
298
288
|
IMAGE: 'IMAGE'
|
|
299
289
|
};
|
|
300
290
|
|
|
291
|
+
/**
|
|
292
|
+
* @license
|
|
293
|
+
* Copyright 2024 Google LLC
|
|
294
|
+
*
|
|
295
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
296
|
+
* you may not use this file except in compliance with the License.
|
|
297
|
+
* You may obtain a copy of the License at
|
|
298
|
+
*
|
|
299
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
300
|
+
*
|
|
301
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
302
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
303
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
304
|
+
* See the License for the specific language governing permissions and
|
|
305
|
+
* limitations under the License.
|
|
306
|
+
*/
|
|
307
|
+
/**
|
|
308
|
+
* Standardized error codes that {@link AIError} can have.
|
|
309
|
+
*
|
|
310
|
+
* @public
|
|
311
|
+
*/
|
|
312
|
+
const AIErrorCode = {
|
|
313
|
+
/** A generic error occurred. */
|
|
314
|
+
ERROR: 'error',
|
|
315
|
+
/** An error occurred in a request. */
|
|
316
|
+
REQUEST_ERROR: 'request-error',
|
|
317
|
+
/** An error occurred in a response. */
|
|
318
|
+
RESPONSE_ERROR: 'response-error',
|
|
319
|
+
/** An error occurred while performing a fetch. */
|
|
320
|
+
FETCH_ERROR: 'fetch-error',
|
|
321
|
+
/** An error associated with a Content object. */
|
|
322
|
+
INVALID_CONTENT: 'invalid-content',
|
|
323
|
+
/** An error due to the Firebase API not being enabled in the Console. */
|
|
324
|
+
API_NOT_ENABLED: 'api-not-enabled',
|
|
325
|
+
/** An error due to invalid Schema input. */
|
|
326
|
+
INVALID_SCHEMA: 'invalid-schema',
|
|
327
|
+
/** An error occurred due to a missing Firebase API key. */
|
|
328
|
+
NO_API_KEY: 'no-api-key',
|
|
329
|
+
/** An error occurred due to a missing Firebase app ID. */
|
|
330
|
+
NO_APP_ID: 'no-app-id',
|
|
331
|
+
/** An error occurred due to a model name not being specified during initialization. */
|
|
332
|
+
NO_MODEL: 'no-model',
|
|
333
|
+
/** An error occurred due to a missing project ID. */
|
|
334
|
+
NO_PROJECT_ID: 'no-project-id',
|
|
335
|
+
/** An error occurred while parsing. */
|
|
336
|
+
PARSE_FAILED: 'parse-failed',
|
|
337
|
+
/** An error occurred due an attempt to use an unsupported feature. */
|
|
338
|
+
UNSUPPORTED: 'unsupported'
|
|
339
|
+
};
|
|
340
|
+
|
|
301
341
|
/**
|
|
302
342
|
* @license
|
|
303
343
|
* Copyright 2024 Google LLC
|
|
@@ -320,21 +360,20 @@ const ResponseModality = {
|
|
|
320
360
|
* {@link https://swagger.io/docs/specification/data-models/data-types/ | OpenAPI specification}
|
|
321
361
|
* @public
|
|
322
362
|
*/
|
|
323
|
-
|
|
324
|
-
(function (SchemaType) {
|
|
363
|
+
const SchemaType = {
|
|
325
364
|
/** String type. */
|
|
326
|
-
|
|
365
|
+
STRING: 'string',
|
|
327
366
|
/** Number type. */
|
|
328
|
-
|
|
367
|
+
NUMBER: 'number',
|
|
329
368
|
/** Integer type. */
|
|
330
|
-
|
|
369
|
+
INTEGER: 'integer',
|
|
331
370
|
/** Boolean type. */
|
|
332
|
-
|
|
371
|
+
BOOLEAN: 'boolean',
|
|
333
372
|
/** Array type. */
|
|
334
|
-
|
|
373
|
+
ARRAY: 'array',
|
|
335
374
|
/** Object type. */
|
|
336
|
-
|
|
337
|
-
}
|
|
375
|
+
OBJECT: 'object'
|
|
376
|
+
};
|
|
338
377
|
|
|
339
378
|
/**
|
|
340
379
|
* @license
|
|
@@ -364,28 +403,27 @@ var SchemaType;
|
|
|
364
403
|
*
|
|
365
404
|
* @beta
|
|
366
405
|
*/
|
|
367
|
-
|
|
368
|
-
(function (ImagenSafetyFilterLevel) {
|
|
406
|
+
const ImagenSafetyFilterLevel = {
|
|
369
407
|
/**
|
|
370
408
|
* The most aggressive filtering level; most strict blocking.
|
|
371
409
|
*/
|
|
372
|
-
|
|
410
|
+
BLOCK_LOW_AND_ABOVE: 'block_low_and_above',
|
|
373
411
|
/**
|
|
374
412
|
* Blocks some sensitive prompts and responses.
|
|
375
413
|
*/
|
|
376
|
-
|
|
414
|
+
BLOCK_MEDIUM_AND_ABOVE: 'block_medium_and_above',
|
|
377
415
|
/**
|
|
378
416
|
* Blocks few sensitive prompts and responses.
|
|
379
417
|
*/
|
|
380
|
-
|
|
418
|
+
BLOCK_ONLY_HIGH: 'block_only_high',
|
|
381
419
|
/**
|
|
382
420
|
* The least aggressive filtering level; blocks very few sensitive prompts and responses.
|
|
383
421
|
*
|
|
384
422
|
* Access to this feature is restricted and may require your case to be reviewed and approved by
|
|
385
423
|
* Cloud support.
|
|
386
424
|
*/
|
|
387
|
-
|
|
388
|
-
}
|
|
425
|
+
BLOCK_NONE: 'block_none'
|
|
426
|
+
};
|
|
389
427
|
/**
|
|
390
428
|
* A filter level controlling whether generation of images containing people or faces is allowed.
|
|
391
429
|
*
|
|
@@ -394,12 +432,11 @@ var ImagenSafetyFilterLevel;
|
|
|
394
432
|
*
|
|
395
433
|
* @beta
|
|
396
434
|
*/
|
|
397
|
-
|
|
398
|
-
(function (ImagenPersonFilterLevel) {
|
|
435
|
+
const ImagenPersonFilterLevel = {
|
|
399
436
|
/**
|
|
400
437
|
* Disallow generation of images containing people or faces; images of people are filtered out.
|
|
401
438
|
*/
|
|
402
|
-
|
|
439
|
+
BLOCK_ALL: 'dont_allow',
|
|
403
440
|
/**
|
|
404
441
|
* Allow generation of images containing adults only; images of children are filtered out.
|
|
405
442
|
*
|
|
@@ -407,7 +444,7 @@ var ImagenPersonFilterLevel;
|
|
|
407
444
|
* reviewed and approved by Cloud support; see the {@link https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#person-face-gen | Responsible AI and usage guidelines}
|
|
408
445
|
* for more details.
|
|
409
446
|
*/
|
|
410
|
-
|
|
447
|
+
ALLOW_ADULT: 'allow_adult',
|
|
411
448
|
/**
|
|
412
449
|
* Allow generation of images containing adults only; images of children are filtered out.
|
|
413
450
|
*
|
|
@@ -415,8 +452,8 @@ var ImagenPersonFilterLevel;
|
|
|
415
452
|
* reviewed and approved by Cloud support; see the {@link https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#person-face-gen | Responsible AI and usage guidelines}
|
|
416
453
|
* for more details.
|
|
417
454
|
*/
|
|
418
|
-
|
|
419
|
-
}
|
|
455
|
+
ALLOW_ALL: 'allow_all'
|
|
456
|
+
};
|
|
420
457
|
/**
|
|
421
458
|
* Aspect ratios for Imagen images.
|
|
422
459
|
*
|
|
@@ -428,29 +465,28 @@ var ImagenPersonFilterLevel;
|
|
|
428
465
|
*
|
|
429
466
|
* @beta
|
|
430
467
|
*/
|
|
431
|
-
|
|
432
|
-
(function (ImagenAspectRatio) {
|
|
468
|
+
const ImagenAspectRatio = {
|
|
433
469
|
/**
|
|
434
470
|
* Square (1:1) aspect ratio.
|
|
435
471
|
*/
|
|
436
|
-
|
|
472
|
+
'SQUARE': '1:1',
|
|
437
473
|
/**
|
|
438
474
|
* Landscape (3:4) aspect ratio.
|
|
439
475
|
*/
|
|
440
|
-
|
|
476
|
+
'LANDSCAPE_3x4': '3:4',
|
|
441
477
|
/**
|
|
442
478
|
* Portrait (4:3) aspect ratio.
|
|
443
479
|
*/
|
|
444
|
-
|
|
480
|
+
'PORTRAIT_4x3': '4:3',
|
|
445
481
|
/**
|
|
446
482
|
* Landscape (16:9) aspect ratio.
|
|
447
483
|
*/
|
|
448
|
-
|
|
484
|
+
'LANDSCAPE_16x9': '16:9',
|
|
449
485
|
/**
|
|
450
486
|
* Portrait (9:16) aspect ratio.
|
|
451
487
|
*/
|
|
452
|
-
|
|
453
|
-
}
|
|
488
|
+
'PORTRAIT_9x16': '9:16'
|
|
489
|
+
};
|
|
454
490
|
|
|
455
491
|
/**
|
|
456
492
|
* @license
|
|
@@ -589,8 +625,8 @@ class AIService {
|
|
|
589
625
|
constructor(app, backend, authProvider, appCheckProvider) {
|
|
590
626
|
this.app = app;
|
|
591
627
|
this.backend = backend;
|
|
592
|
-
const appCheck = appCheckProvider
|
|
593
|
-
const auth = authProvider
|
|
628
|
+
const appCheck = appCheckProvider?.getImmediate({ optional: true });
|
|
629
|
+
const auth = authProvider?.getImmediate({ optional: true });
|
|
594
630
|
this.auth = auth || null;
|
|
595
631
|
this.appCheck = appCheck || null;
|
|
596
632
|
if (backend instanceof VertexAIBackend) {
|
|
@@ -630,7 +666,7 @@ class AIError extends FirebaseError {
|
|
|
630
666
|
/**
|
|
631
667
|
* Constructs a new instance of the `AIError` class.
|
|
632
668
|
*
|
|
633
|
-
* @param code - The error code from {@link AIErrorCode}.
|
|
669
|
+
* @param code - The error code from {@link (AIErrorCode:type)}.
|
|
634
670
|
* @param message - A human-readable message describing the error.
|
|
635
671
|
* @param customErrorData - Optional error data.
|
|
636
672
|
*/
|
|
@@ -691,7 +727,7 @@ function encodeInstanceIdentifier(backend) {
|
|
|
691
727
|
return `${AI_TYPE}/vertexai/${backend.location}`;
|
|
692
728
|
}
|
|
693
729
|
else {
|
|
694
|
-
throw new AIError(
|
|
730
|
+
throw new AIError(AIErrorCode.ERROR, `Invalid backend: ${JSON.stringify(backend.backendType)}`);
|
|
695
731
|
}
|
|
696
732
|
}
|
|
697
733
|
/**
|
|
@@ -702,20 +738,20 @@ function encodeInstanceIdentifier(backend) {
|
|
|
702
738
|
function decodeInstanceIdentifier(instanceIdentifier) {
|
|
703
739
|
const identifierParts = instanceIdentifier.split('/');
|
|
704
740
|
if (identifierParts[0] !== AI_TYPE) {
|
|
705
|
-
throw new AIError(
|
|
741
|
+
throw new AIError(AIErrorCode.ERROR, `Invalid instance identifier, unknown prefix '${identifierParts[0]}'`);
|
|
706
742
|
}
|
|
707
743
|
const backendType = identifierParts[1];
|
|
708
744
|
switch (backendType) {
|
|
709
745
|
case 'vertexai':
|
|
710
746
|
const location = identifierParts[2];
|
|
711
747
|
if (!location) {
|
|
712
|
-
throw new AIError(
|
|
748
|
+
throw new AIError(AIErrorCode.ERROR, `Invalid instance identifier, unknown location '${instanceIdentifier}'`);
|
|
713
749
|
}
|
|
714
750
|
return new VertexAIBackend(location);
|
|
715
751
|
case 'googleai':
|
|
716
752
|
return new GoogleAIBackend();
|
|
717
753
|
default:
|
|
718
|
-
throw new AIError(
|
|
754
|
+
throw new AIError(AIErrorCode.ERROR, `Invalid instance identifier string: '${instanceIdentifier}'`);
|
|
719
755
|
}
|
|
720
756
|
}
|
|
721
757
|
|
|
@@ -762,15 +798,14 @@ class AIModel {
|
|
|
762
798
|
* @internal
|
|
763
799
|
*/
|
|
764
800
|
constructor(ai, modelName) {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
throw new AIError("no-api-key" /* AIErrorCode.NO_API_KEY */, `The "apiKey" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid API key.`);
|
|
801
|
+
if (!ai.app?.options?.apiKey) {
|
|
802
|
+
throw new AIError(AIErrorCode.NO_API_KEY, `The "apiKey" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid API key.`);
|
|
768
803
|
}
|
|
769
|
-
else if (!
|
|
770
|
-
throw new AIError(
|
|
804
|
+
else if (!ai.app?.options?.projectId) {
|
|
805
|
+
throw new AIError(AIErrorCode.NO_PROJECT_ID, `The "projectId" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid project ID.`);
|
|
771
806
|
}
|
|
772
|
-
else if (!
|
|
773
|
-
throw new AIError(
|
|
807
|
+
else if (!ai.app?.options?.appId) {
|
|
808
|
+
throw new AIError(AIErrorCode.NO_APP_ID, `The "appId" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid app ID.`);
|
|
774
809
|
}
|
|
775
810
|
else {
|
|
776
811
|
this._apiSettings = {
|
|
@@ -897,8 +932,7 @@ class RequestUrl {
|
|
|
897
932
|
return url.toString();
|
|
898
933
|
}
|
|
899
934
|
get baseUrl() {
|
|
900
|
-
|
|
901
|
-
return ((_a = this.requestOptions) === null || _a === void 0 ? void 0 : _a.baseUrl) || DEFAULT_BASE_URL;
|
|
935
|
+
return this.requestOptions?.baseUrl || DEFAULT_BASE_URL;
|
|
902
936
|
}
|
|
903
937
|
get apiVersion() {
|
|
904
938
|
return DEFAULT_API_VERSION; // TODO: allow user-set options if that feature becomes available
|
|
@@ -911,7 +945,7 @@ class RequestUrl {
|
|
|
911
945
|
return `projects/${this.apiSettings.project}/locations/${this.apiSettings.backend.location}/${this.model}`;
|
|
912
946
|
}
|
|
913
947
|
else {
|
|
914
|
-
throw new AIError(
|
|
948
|
+
throw new AIError(AIErrorCode.ERROR, `Invalid backend: ${JSON.stringify(this.apiSettings.backend)}`);
|
|
915
949
|
}
|
|
916
950
|
}
|
|
917
951
|
get queryParams() {
|
|
@@ -974,7 +1008,7 @@ async function makeRequest(model, task, apiSettings, stream, body, requestOption
|
|
|
974
1008
|
try {
|
|
975
1009
|
const request = await constructRequest(model, task, apiSettings, stream, body, requestOptions);
|
|
976
1010
|
// Timeout is 180s by default
|
|
977
|
-
const timeoutMillis =
|
|
1011
|
+
const timeoutMillis = requestOptions?.timeout != null && requestOptions.timeout >= 0
|
|
978
1012
|
? requestOptions.timeout
|
|
979
1013
|
: DEFAULT_FETCH_TIMEOUT_MS;
|
|
980
1014
|
const abortController = new AbortController();
|
|
@@ -996,12 +1030,10 @@ async function makeRequest(model, task, apiSettings, stream, body, requestOption
|
|
|
996
1030
|
// ignored
|
|
997
1031
|
}
|
|
998
1032
|
if (response.status === 403 &&
|
|
1033
|
+
errorDetails &&
|
|
999
1034
|
errorDetails.some((detail) => detail.reason === 'SERVICE_DISABLED') &&
|
|
1000
|
-
errorDetails.some((detail) => {
|
|
1001
|
-
|
|
1002
|
-
return (_b = (_a = detail.links) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.description.includes('Google developers console API activation');
|
|
1003
|
-
})) {
|
|
1004
|
-
throw new AIError("api-not-enabled" /* AIErrorCode.API_NOT_ENABLED */, `The Firebase AI SDK requires the Firebase AI ` +
|
|
1035
|
+
errorDetails.some((detail) => detail.links?.[0]?.description.includes('Google developers console API activation'))) {
|
|
1036
|
+
throw new AIError(AIErrorCode.API_NOT_ENABLED, `The Firebase AI SDK requires the Firebase AI ` +
|
|
1005
1037
|
`API ('firebasevertexai.googleapis.com') to be enabled in your ` +
|
|
1006
1038
|
`Firebase project. Enable this API by visiting the Firebase Console ` +
|
|
1007
1039
|
`at https://console.firebase.google.com/project/${url.apiSettings.project}/genai/ ` +
|
|
@@ -1013,7 +1045,7 @@ async function makeRequest(model, task, apiSettings, stream, body, requestOption
|
|
|
1013
1045
|
errorDetails
|
|
1014
1046
|
});
|
|
1015
1047
|
}
|
|
1016
|
-
throw new AIError(
|
|
1048
|
+
throw new AIError(AIErrorCode.FETCH_ERROR, `Error fetching from ${url}: [${response.status} ${response.statusText}] ${message}`, {
|
|
1017
1049
|
status: response.status,
|
|
1018
1050
|
statusText: response.statusText,
|
|
1019
1051
|
errorDetails
|
|
@@ -1022,10 +1054,10 @@ async function makeRequest(model, task, apiSettings, stream, body, requestOption
|
|
|
1022
1054
|
}
|
|
1023
1055
|
catch (e) {
|
|
1024
1056
|
let err = e;
|
|
1025
|
-
if (e.code !==
|
|
1026
|
-
e.code !==
|
|
1057
|
+
if (e.code !== AIErrorCode.FETCH_ERROR &&
|
|
1058
|
+
e.code !== AIErrorCode.API_NOT_ENABLED &&
|
|
1027
1059
|
e instanceof Error) {
|
|
1028
|
-
err = new AIError(
|
|
1060
|
+
err = new AIError(AIErrorCode.ERROR, `Error fetching from ${url.toString()}: ${e.message}`);
|
|
1029
1061
|
err.stack = e.stack;
|
|
1030
1062
|
}
|
|
1031
1063
|
throw err;
|
|
@@ -1084,14 +1116,14 @@ function addHelpers(response) {
|
|
|
1084
1116
|
`Access response.candidates directly to use the other candidates.`);
|
|
1085
1117
|
}
|
|
1086
1118
|
if (hadBadFinishReason(response.candidates[0])) {
|
|
1087
|
-
throw new AIError(
|
|
1119
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Response error: ${formatBlockErrorMessage(response)}. Response body stored in error.response`, {
|
|
1088
1120
|
response
|
|
1089
1121
|
});
|
|
1090
1122
|
}
|
|
1091
1123
|
return getText(response);
|
|
1092
1124
|
}
|
|
1093
1125
|
else if (response.promptFeedback) {
|
|
1094
|
-
throw new AIError(
|
|
1126
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Text not available. ${formatBlockErrorMessage(response)}`, {
|
|
1095
1127
|
response
|
|
1096
1128
|
});
|
|
1097
1129
|
}
|
|
@@ -1105,14 +1137,14 @@ function addHelpers(response) {
|
|
|
1105
1137
|
`Access response.candidates directly to use the other candidates.`);
|
|
1106
1138
|
}
|
|
1107
1139
|
if (hadBadFinishReason(response.candidates[0])) {
|
|
1108
|
-
throw new AIError(
|
|
1140
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Response error: ${formatBlockErrorMessage(response)}. Response body stored in error.response`, {
|
|
1109
1141
|
response
|
|
1110
1142
|
});
|
|
1111
1143
|
}
|
|
1112
1144
|
return getInlineDataParts(response);
|
|
1113
1145
|
}
|
|
1114
1146
|
else if (response.promptFeedback) {
|
|
1115
|
-
throw new AIError(
|
|
1147
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Data not available. ${formatBlockErrorMessage(response)}`, {
|
|
1116
1148
|
response
|
|
1117
1149
|
});
|
|
1118
1150
|
}
|
|
@@ -1126,14 +1158,14 @@ function addHelpers(response) {
|
|
|
1126
1158
|
`Access response.candidates directly to use the other candidates.`);
|
|
1127
1159
|
}
|
|
1128
1160
|
if (hadBadFinishReason(response.candidates[0])) {
|
|
1129
|
-
throw new AIError(
|
|
1161
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Response error: ${formatBlockErrorMessage(response)}. Response body stored in error.response`, {
|
|
1130
1162
|
response
|
|
1131
1163
|
});
|
|
1132
1164
|
}
|
|
1133
1165
|
return getFunctionCalls(response);
|
|
1134
1166
|
}
|
|
1135
1167
|
else if (response.promptFeedback) {
|
|
1136
|
-
throw new AIError(
|
|
1168
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Function call not available. ${formatBlockErrorMessage(response)}`, {
|
|
1137
1169
|
response
|
|
1138
1170
|
});
|
|
1139
1171
|
}
|
|
@@ -1145,10 +1177,9 @@ function addHelpers(response) {
|
|
|
1145
1177
|
* Returns all text found in all parts of first candidate.
|
|
1146
1178
|
*/
|
|
1147
1179
|
function getText(response) {
|
|
1148
|
-
var _a, _b, _c, _d;
|
|
1149
1180
|
const textStrings = [];
|
|
1150
|
-
if (
|
|
1151
|
-
for (const part of
|
|
1181
|
+
if (response.candidates?.[0].content?.parts) {
|
|
1182
|
+
for (const part of response.candidates?.[0].content?.parts) {
|
|
1152
1183
|
if (part.text) {
|
|
1153
1184
|
textStrings.push(part.text);
|
|
1154
1185
|
}
|
|
@@ -1165,10 +1196,9 @@ function getText(response) {
|
|
|
1165
1196
|
* Returns {@link FunctionCall}s associated with first candidate.
|
|
1166
1197
|
*/
|
|
1167
1198
|
function getFunctionCalls(response) {
|
|
1168
|
-
var _a, _b, _c, _d;
|
|
1169
1199
|
const functionCalls = [];
|
|
1170
|
-
if (
|
|
1171
|
-
for (const part of
|
|
1200
|
+
if (response.candidates?.[0].content?.parts) {
|
|
1201
|
+
for (const part of response.candidates?.[0].content?.parts) {
|
|
1172
1202
|
if (part.functionCall) {
|
|
1173
1203
|
functionCalls.push(part.functionCall);
|
|
1174
1204
|
}
|
|
@@ -1187,10 +1217,9 @@ function getFunctionCalls(response) {
|
|
|
1187
1217
|
* @internal
|
|
1188
1218
|
*/
|
|
1189
1219
|
function getInlineDataParts(response) {
|
|
1190
|
-
var _a, _b, _c, _d;
|
|
1191
1220
|
const data = [];
|
|
1192
|
-
if (
|
|
1193
|
-
for (const part of
|
|
1221
|
+
if (response.candidates?.[0].content?.parts) {
|
|
1222
|
+
for (const part of response.candidates?.[0].content?.parts) {
|
|
1194
1223
|
if (part.inlineData) {
|
|
1195
1224
|
data.push(part);
|
|
1196
1225
|
}
|
|
@@ -1206,22 +1235,21 @@ function getInlineDataParts(response) {
|
|
|
1206
1235
|
const badFinishReasons = [FinishReason.RECITATION, FinishReason.SAFETY];
|
|
1207
1236
|
function hadBadFinishReason(candidate) {
|
|
1208
1237
|
return (!!candidate.finishReason &&
|
|
1209
|
-
badFinishReasons.
|
|
1238
|
+
badFinishReasons.some(reason => reason === candidate.finishReason));
|
|
1210
1239
|
}
|
|
1211
1240
|
function formatBlockErrorMessage(response) {
|
|
1212
|
-
var _a, _b, _c;
|
|
1213
1241
|
let message = '';
|
|
1214
1242
|
if ((!response.candidates || response.candidates.length === 0) &&
|
|
1215
1243
|
response.promptFeedback) {
|
|
1216
1244
|
message += 'Response was blocked';
|
|
1217
|
-
if (
|
|
1245
|
+
if (response.promptFeedback?.blockReason) {
|
|
1218
1246
|
message += ` due to ${response.promptFeedback.blockReason}`;
|
|
1219
1247
|
}
|
|
1220
|
-
if (
|
|
1248
|
+
if (response.promptFeedback?.blockReasonMessage) {
|
|
1221
1249
|
message += `: ${response.promptFeedback.blockReasonMessage}`;
|
|
1222
1250
|
}
|
|
1223
1251
|
}
|
|
1224
|
-
else if (
|
|
1252
|
+
else if (response.candidates?.[0]) {
|
|
1225
1253
|
const firstCandidate = response.candidates[0];
|
|
1226
1254
|
if (hadBadFinishReason(firstCandidate)) {
|
|
1227
1255
|
message += `Candidate was blocked due to ${firstCandidate.finishReason}`;
|
|
@@ -1240,13 +1268,12 @@ function formatBlockErrorMessage(response) {
|
|
|
1240
1268
|
* @internal
|
|
1241
1269
|
*/
|
|
1242
1270
|
async function handlePredictResponse(response) {
|
|
1243
|
-
var _a;
|
|
1244
1271
|
const responseJson = await response.json();
|
|
1245
1272
|
const images = [];
|
|
1246
1273
|
let filteredReason = undefined;
|
|
1247
1274
|
// The backend should always send a non-empty array of predictions if the response was successful.
|
|
1248
|
-
if (!responseJson.predictions ||
|
|
1249
|
-
throw new AIError(
|
|
1275
|
+
if (!responseJson.predictions || responseJson.predictions?.length === 0) {
|
|
1276
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, 'No predictions or filtered reason received from Vertex AI. Please report this issue with the full error details at https://github.com/firebase/firebase-js-sdk/issues.');
|
|
1250
1277
|
}
|
|
1251
1278
|
for (const prediction of responseJson.predictions) {
|
|
1252
1279
|
if (prediction.raiFilteredReason) {
|
|
@@ -1265,7 +1292,7 @@ async function handlePredictResponse(response) {
|
|
|
1265
1292
|
});
|
|
1266
1293
|
}
|
|
1267
1294
|
else {
|
|
1268
|
-
throw new AIError(
|
|
1295
|
+
throw new AIError(AIErrorCode.RESPONSE_ERROR, `Predictions array in response has missing properties. Response: ${JSON.stringify(responseJson)}`);
|
|
1269
1296
|
}
|
|
1270
1297
|
}
|
|
1271
1298
|
return { images, filteredReason };
|
|
@@ -1309,13 +1336,12 @@ async function handlePredictResponse(response) {
|
|
|
1309
1336
|
* @internal
|
|
1310
1337
|
*/
|
|
1311
1338
|
function mapGenerateContentRequest(generateContentRequest) {
|
|
1312
|
-
|
|
1313
|
-
(_a = generateContentRequest.safetySettings) === null || _a === void 0 ? void 0 : _a.forEach(safetySetting => {
|
|
1339
|
+
generateContentRequest.safetySettings?.forEach(safetySetting => {
|
|
1314
1340
|
if (safetySetting.method) {
|
|
1315
|
-
throw new AIError(
|
|
1341
|
+
throw new AIError(AIErrorCode.UNSUPPORTED, 'SafetySetting.method is not supported in the the Gemini Developer API. Please remove this property.');
|
|
1316
1342
|
}
|
|
1317
1343
|
});
|
|
1318
|
-
if (
|
|
1344
|
+
if (generateContentRequest.generationConfig?.topK) {
|
|
1319
1345
|
const roundedTopK = Math.round(generateContentRequest.generationConfig.topK);
|
|
1320
1346
|
if (roundedTopK !== generateContentRequest.generationConfig.topK) {
|
|
1321
1347
|
logger.warn('topK in GenerationConfig has been rounded to the nearest integer to match the format for requests to the Gemini Developer API.');
|
|
@@ -1356,7 +1382,10 @@ function mapGenerateContentResponse(googleAIResponse) {
|
|
|
1356
1382
|
*/
|
|
1357
1383
|
function mapCountTokensRequest(countTokensRequest, model) {
|
|
1358
1384
|
const mappedCountTokensRequest = {
|
|
1359
|
-
generateContentRequest:
|
|
1385
|
+
generateContentRequest: {
|
|
1386
|
+
model,
|
|
1387
|
+
...countTokensRequest
|
|
1388
|
+
}
|
|
1360
1389
|
};
|
|
1361
1390
|
return mappedCountTokensRequest;
|
|
1362
1391
|
}
|
|
@@ -1376,7 +1405,6 @@ function mapGenerateContentCandidates(candidates) {
|
|
|
1376
1405
|
let mappedSafetyRatings;
|
|
1377
1406
|
if (mappedCandidates) {
|
|
1378
1407
|
candidates.forEach(candidate => {
|
|
1379
|
-
var _a;
|
|
1380
1408
|
// Map citationSources to citations.
|
|
1381
1409
|
let citationMetadata;
|
|
1382
1410
|
if (candidate.citationMetadata) {
|
|
@@ -1387,15 +1415,19 @@ function mapGenerateContentCandidates(candidates) {
|
|
|
1387
1415
|
// Assign missing candidate SafetyRatings properties to their defaults if undefined.
|
|
1388
1416
|
if (candidate.safetyRatings) {
|
|
1389
1417
|
mappedSafetyRatings = candidate.safetyRatings.map(safetyRating => {
|
|
1390
|
-
|
|
1391
|
-
|
|
1418
|
+
return {
|
|
1419
|
+
...safetyRating,
|
|
1420
|
+
severity: safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,
|
|
1421
|
+
probabilityScore: safetyRating.probabilityScore ?? 0,
|
|
1422
|
+
severityScore: safetyRating.severityScore ?? 0
|
|
1423
|
+
};
|
|
1392
1424
|
});
|
|
1393
1425
|
}
|
|
1394
1426
|
// videoMetadata is not supported.
|
|
1395
1427
|
// Throw early since developers may send a long video as input and only expect to pay
|
|
1396
1428
|
// for inference on a small portion of the video.
|
|
1397
|
-
if (
|
|
1398
|
-
throw new AIError(
|
|
1429
|
+
if (candidate.content?.parts.some(part => part?.videoMetadata)) {
|
|
1430
|
+
throw new AIError(AIErrorCode.UNSUPPORTED, 'Part.videoMetadata is not supported in the Gemini Developer API. Please remove this property.');
|
|
1399
1431
|
}
|
|
1400
1432
|
const mappedCandidate = {
|
|
1401
1433
|
index: candidate.index,
|
|
@@ -1415,13 +1447,12 @@ function mapPromptFeedback(promptFeedback) {
|
|
|
1415
1447
|
// Assign missing SafetyRating properties to their defaults if undefined.
|
|
1416
1448
|
const mappedSafetyRatings = [];
|
|
1417
1449
|
promptFeedback.safetyRatings.forEach(safetyRating => {
|
|
1418
|
-
var _a, _b, _c;
|
|
1419
1450
|
mappedSafetyRatings.push({
|
|
1420
1451
|
category: safetyRating.category,
|
|
1421
1452
|
probability: safetyRating.probability,
|
|
1422
|
-
severity:
|
|
1423
|
-
probabilityScore:
|
|
1424
|
-
severityScore:
|
|
1453
|
+
severity: safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,
|
|
1454
|
+
probabilityScore: safetyRating.probabilityScore ?? 0,
|
|
1455
|
+
severityScore: safetyRating.severityScore ?? 0,
|
|
1425
1456
|
blocked: safetyRating.blocked
|
|
1426
1457
|
});
|
|
1427
1458
|
});
|
|
@@ -1482,24 +1513,22 @@ async function getResponsePromise(stream, apiSettings) {
|
|
|
1482
1513
|
allResponses.push(value);
|
|
1483
1514
|
}
|
|
1484
1515
|
}
|
|
1485
|
-
function generateResponseSequence(stream, apiSettings) {
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
break;
|
|
1492
|
-
}
|
|
1493
|
-
let enhancedResponse;
|
|
1494
|
-
if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
|
|
1495
|
-
enhancedResponse = createEnhancedContentResponse(mapGenerateContentResponse(value));
|
|
1496
|
-
}
|
|
1497
|
-
else {
|
|
1498
|
-
enhancedResponse = createEnhancedContentResponse(value);
|
|
1499
|
-
}
|
|
1500
|
-
yield yield __await(enhancedResponse);
|
|
1516
|
+
async function* generateResponseSequence(stream, apiSettings) {
|
|
1517
|
+
const reader = stream.getReader();
|
|
1518
|
+
while (true) {
|
|
1519
|
+
const { value, done } = await reader.read();
|
|
1520
|
+
if (done) {
|
|
1521
|
+
break;
|
|
1501
1522
|
}
|
|
1502
|
-
|
|
1523
|
+
let enhancedResponse;
|
|
1524
|
+
if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
|
|
1525
|
+
enhancedResponse = createEnhancedContentResponse(mapGenerateContentResponse(value));
|
|
1526
|
+
}
|
|
1527
|
+
else {
|
|
1528
|
+
enhancedResponse = createEnhancedContentResponse(value);
|
|
1529
|
+
}
|
|
1530
|
+
yield enhancedResponse;
|
|
1531
|
+
}
|
|
1503
1532
|
}
|
|
1504
1533
|
/**
|
|
1505
1534
|
* Reads a raw stream from the fetch response and join incomplete
|
|
@@ -1516,7 +1545,7 @@ function getResponseStream(inputStream) {
|
|
|
1516
1545
|
return reader.read().then(({ value, done }) => {
|
|
1517
1546
|
if (done) {
|
|
1518
1547
|
if (currentText.trim()) {
|
|
1519
|
-
controller.error(new AIError(
|
|
1548
|
+
controller.error(new AIError(AIErrorCode.PARSE_FAILED, 'Failed to parse stream'));
|
|
1520
1549
|
return;
|
|
1521
1550
|
}
|
|
1522
1551
|
controller.close();
|
|
@@ -1530,7 +1559,7 @@ function getResponseStream(inputStream) {
|
|
|
1530
1559
|
parsedResponse = JSON.parse(match[1]);
|
|
1531
1560
|
}
|
|
1532
1561
|
catch (e) {
|
|
1533
|
-
controller.error(new AIError(
|
|
1562
|
+
controller.error(new AIError(AIErrorCode.PARSE_FAILED, `Error parsing JSON response: "${match[1]}`));
|
|
1534
1563
|
return;
|
|
1535
1564
|
}
|
|
1536
1565
|
controller.enqueue(parsedResponse);
|
|
@@ -1551,7 +1580,7 @@ function getResponseStream(inputStream) {
|
|
|
1551
1580
|
function aggregateResponses(responses) {
|
|
1552
1581
|
const lastResponse = responses[responses.length - 1];
|
|
1553
1582
|
const aggregatedResponse = {
|
|
1554
|
-
promptFeedback: lastResponse
|
|
1583
|
+
promptFeedback: lastResponse?.promptFeedback
|
|
1555
1584
|
};
|
|
1556
1585
|
for (const response of responses) {
|
|
1557
1586
|
if (response.candidates) {
|
|
@@ -1575,6 +1604,8 @@ function aggregateResponses(responses) {
|
|
|
1575
1604
|
candidate.finishMessage;
|
|
1576
1605
|
aggregatedResponse.candidates[i].safetyRatings =
|
|
1577
1606
|
candidate.safetyRatings;
|
|
1607
|
+
aggregatedResponse.candidates[i].groundingMetadata =
|
|
1608
|
+
candidate.groundingMetadata;
|
|
1578
1609
|
/**
|
|
1579
1610
|
* Candidates should always have content and parts, but this handles
|
|
1580
1611
|
* possible malformed responses.
|
|
@@ -1601,7 +1632,7 @@ function aggregateResponses(responses) {
|
|
|
1601
1632
|
newPart.functionCall = part.functionCall;
|
|
1602
1633
|
}
|
|
1603
1634
|
if (Object.keys(newPart).length === 0) {
|
|
1604
|
-
throw new AIError(
|
|
1635
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, 'Part should have at least one property, but there are none. This is likely caused ' +
|
|
1605
1636
|
'by a malformed response from the backend.');
|
|
1606
1637
|
}
|
|
1607
1638
|
aggregatedResponse.candidates[i].content.parts.push(newPart);
|
|
@@ -1736,10 +1767,10 @@ function assignRoleToPartsAndValidateSendMessageRequest(parts) {
|
|
|
1736
1767
|
}
|
|
1737
1768
|
}
|
|
1738
1769
|
if (hasUserContent && hasFunctionContent) {
|
|
1739
|
-
throw new AIError(
|
|
1770
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, 'Within a single message, FunctionResponse cannot be mixed with other type of Part in the request for sending chat message.');
|
|
1740
1771
|
}
|
|
1741
1772
|
if (!hasUserContent && !hasFunctionContent) {
|
|
1742
|
-
throw new AIError(
|
|
1773
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, 'No Content is provided for sending chat message.');
|
|
1743
1774
|
}
|
|
1744
1775
|
if (hasUserContent) {
|
|
1745
1776
|
return userContent;
|
|
@@ -1832,16 +1863,16 @@ function validateChatHistory(history) {
|
|
|
1832
1863
|
for (const currContent of history) {
|
|
1833
1864
|
const { role, parts } = currContent;
|
|
1834
1865
|
if (!prevContent && role !== 'user') {
|
|
1835
|
-
throw new AIError(
|
|
1866
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, `First Content should be with role 'user', got ${role}`);
|
|
1836
1867
|
}
|
|
1837
1868
|
if (!POSSIBLE_ROLES.includes(role)) {
|
|
1838
|
-
throw new AIError(
|
|
1869
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, `Each item should include role field. Got ${role} but valid roles are: ${JSON.stringify(POSSIBLE_ROLES)}`);
|
|
1839
1870
|
}
|
|
1840
1871
|
if (!Array.isArray(parts)) {
|
|
1841
|
-
throw new AIError(
|
|
1872
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, `Content should have 'parts' but property with an array of Parts`);
|
|
1842
1873
|
}
|
|
1843
1874
|
if (parts.length === 0) {
|
|
1844
|
-
throw new AIError(
|
|
1875
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, `Each Content should have at least one part`);
|
|
1845
1876
|
}
|
|
1846
1877
|
const countFields = {
|
|
1847
1878
|
text: 0,
|
|
@@ -1859,13 +1890,13 @@ function validateChatHistory(history) {
|
|
|
1859
1890
|
const validParts = VALID_PARTS_PER_ROLE[role];
|
|
1860
1891
|
for (const key of VALID_PART_FIELDS) {
|
|
1861
1892
|
if (!validParts.includes(key) && countFields[key] > 0) {
|
|
1862
|
-
throw new AIError(
|
|
1893
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, `Content with role '${role}' can't contain '${key}' part`);
|
|
1863
1894
|
}
|
|
1864
1895
|
}
|
|
1865
1896
|
if (prevContent) {
|
|
1866
1897
|
const validPreviousContentRoles = VALID_PREVIOUS_CONTENT_ROLES[role];
|
|
1867
1898
|
if (!validPreviousContentRoles.includes(prevContent.role)) {
|
|
1868
|
-
throw new AIError(
|
|
1899
|
+
throw new AIError(AIErrorCode.INVALID_CONTENT, `Content with role '${role}' can't follow '${prevContent.role}'. Valid previous roles: ${JSON.stringify(VALID_PREVIOUS_CONTENT_ROLES)}`);
|
|
1869
1900
|
}
|
|
1870
1901
|
}
|
|
1871
1902
|
prevContent = currContent;
|
|
@@ -1906,7 +1937,7 @@ class ChatSession {
|
|
|
1906
1937
|
this._history = [];
|
|
1907
1938
|
this._sendPromise = Promise.resolve();
|
|
1908
1939
|
this._apiSettings = apiSettings;
|
|
1909
|
-
if (params
|
|
1940
|
+
if (params?.history) {
|
|
1910
1941
|
validateChatHistory(params.history);
|
|
1911
1942
|
this._history = params.history;
|
|
1912
1943
|
}
|
|
@@ -1925,15 +1956,14 @@ class ChatSession {
|
|
|
1925
1956
|
* {@link GenerateContentResult}
|
|
1926
1957
|
*/
|
|
1927
1958
|
async sendMessage(request) {
|
|
1928
|
-
var _a, _b, _c, _d, _e;
|
|
1929
1959
|
await this._sendPromise;
|
|
1930
1960
|
const newContent = formatNewContent(request);
|
|
1931
1961
|
const generateContentRequest = {
|
|
1932
|
-
safetySettings:
|
|
1933
|
-
generationConfig:
|
|
1934
|
-
tools:
|
|
1935
|
-
toolConfig:
|
|
1936
|
-
systemInstruction:
|
|
1962
|
+
safetySettings: this.params?.safetySettings,
|
|
1963
|
+
generationConfig: this.params?.generationConfig,
|
|
1964
|
+
tools: this.params?.tools,
|
|
1965
|
+
toolConfig: this.params?.toolConfig,
|
|
1966
|
+
systemInstruction: this.params?.systemInstruction,
|
|
1937
1967
|
contents: [...this._history, newContent]
|
|
1938
1968
|
};
|
|
1939
1969
|
let finalResult = {};
|
|
@@ -1941,14 +1971,13 @@ class ChatSession {
|
|
|
1941
1971
|
this._sendPromise = this._sendPromise
|
|
1942
1972
|
.then(() => generateContent(this._apiSettings, this.model, generateContentRequest, this.requestOptions))
|
|
1943
1973
|
.then(result => {
|
|
1944
|
-
var _a, _b;
|
|
1945
1974
|
if (result.response.candidates &&
|
|
1946
1975
|
result.response.candidates.length > 0) {
|
|
1947
1976
|
this._history.push(newContent);
|
|
1948
1977
|
const responseContent = {
|
|
1949
|
-
parts:
|
|
1978
|
+
parts: result.response.candidates?.[0].content.parts || [],
|
|
1950
1979
|
// Response seems to come back without a role set.
|
|
1951
|
-
role:
|
|
1980
|
+
role: result.response.candidates?.[0].content.role || 'model'
|
|
1952
1981
|
};
|
|
1953
1982
|
this._history.push(responseContent);
|
|
1954
1983
|
}
|
|
@@ -1969,15 +1998,14 @@ class ChatSession {
|
|
|
1969
1998
|
* and a response promise.
|
|
1970
1999
|
*/
|
|
1971
2000
|
async sendMessageStream(request) {
|
|
1972
|
-
var _a, _b, _c, _d, _e;
|
|
1973
2001
|
await this._sendPromise;
|
|
1974
2002
|
const newContent = formatNewContent(request);
|
|
1975
2003
|
const generateContentRequest = {
|
|
1976
|
-
safetySettings:
|
|
1977
|
-
generationConfig:
|
|
1978
|
-
tools:
|
|
1979
|
-
toolConfig:
|
|
1980
|
-
systemInstruction:
|
|
2004
|
+
safetySettings: this.params?.safetySettings,
|
|
2005
|
+
generationConfig: this.params?.generationConfig,
|
|
2006
|
+
tools: this.params?.tools,
|
|
2007
|
+
toolConfig: this.params?.toolConfig,
|
|
2008
|
+
systemInstruction: this.params?.systemInstruction,
|
|
1981
2009
|
contents: [...this._history, newContent]
|
|
1982
2010
|
};
|
|
1983
2011
|
const streamPromise = generateContentStream(this._apiSettings, this.model, generateContentRequest, this.requestOptions);
|
|
@@ -1993,7 +2021,7 @@ class ChatSession {
|
|
|
1993
2021
|
.then(response => {
|
|
1994
2022
|
if (response.candidates && response.candidates.length > 0) {
|
|
1995
2023
|
this._history.push(newContent);
|
|
1996
|
-
const responseContent =
|
|
2024
|
+
const responseContent = { ...response.candidates[0].content };
|
|
1997
2025
|
// Response seems to come back without a role set.
|
|
1998
2026
|
if (!responseContent.role) {
|
|
1999
2027
|
responseContent.role = 'model';
|
|
@@ -2086,7 +2114,14 @@ class GenerativeModel extends AIModel {
|
|
|
2086
2114
|
*/
|
|
2087
2115
|
async generateContent(request) {
|
|
2088
2116
|
const formattedParams = formatGenerateContentInput(request);
|
|
2089
|
-
return generateContent(this._apiSettings, this.model,
|
|
2117
|
+
return generateContent(this._apiSettings, this.model, {
|
|
2118
|
+
generationConfig: this.generationConfig,
|
|
2119
|
+
safetySettings: this.safetySettings,
|
|
2120
|
+
tools: this.tools,
|
|
2121
|
+
toolConfig: this.toolConfig,
|
|
2122
|
+
systemInstruction: this.systemInstruction,
|
|
2123
|
+
...formattedParams
|
|
2124
|
+
}, this.requestOptions);
|
|
2090
2125
|
}
|
|
2091
2126
|
/**
|
|
2092
2127
|
* Makes a single streaming call to the model
|
|
@@ -2096,14 +2131,33 @@ class GenerativeModel extends AIModel {
|
|
|
2096
2131
|
*/
|
|
2097
2132
|
async generateContentStream(request) {
|
|
2098
2133
|
const formattedParams = formatGenerateContentInput(request);
|
|
2099
|
-
return generateContentStream(this._apiSettings, this.model,
|
|
2134
|
+
return generateContentStream(this._apiSettings, this.model, {
|
|
2135
|
+
generationConfig: this.generationConfig,
|
|
2136
|
+
safetySettings: this.safetySettings,
|
|
2137
|
+
tools: this.tools,
|
|
2138
|
+
toolConfig: this.toolConfig,
|
|
2139
|
+
systemInstruction: this.systemInstruction,
|
|
2140
|
+
...formattedParams
|
|
2141
|
+
}, this.requestOptions);
|
|
2100
2142
|
}
|
|
2101
2143
|
/**
|
|
2102
2144
|
* Gets a new {@link ChatSession} instance which can be used for
|
|
2103
2145
|
* multi-turn chats.
|
|
2104
2146
|
*/
|
|
2105
2147
|
startChat(startChatParams) {
|
|
2106
|
-
return new ChatSession(this._apiSettings, this.model,
|
|
2148
|
+
return new ChatSession(this._apiSettings, this.model, {
|
|
2149
|
+
tools: this.tools,
|
|
2150
|
+
toolConfig: this.toolConfig,
|
|
2151
|
+
systemInstruction: this.systemInstruction,
|
|
2152
|
+
generationConfig: this.generationConfig,
|
|
2153
|
+
safetySettings: this.safetySettings,
|
|
2154
|
+
/**
|
|
2155
|
+
* Overrides params inherited from GenerativeModel with those explicitly set in the
|
|
2156
|
+
* StartChatParams. For example, if startChatParams.generationConfig is set, it'll override
|
|
2157
|
+
* this.generationConfig.
|
|
2158
|
+
*/
|
|
2159
|
+
...startChatParams
|
|
2160
|
+
}, this.requestOptions);
|
|
2107
2161
|
}
|
|
2108
2162
|
/**
|
|
2109
2163
|
* Counts the tokens in the provided request.
|
|
@@ -2189,7 +2243,10 @@ class ImagenModel extends AIModel {
|
|
|
2189
2243
|
* @beta
|
|
2190
2244
|
*/
|
|
2191
2245
|
async generateImages(prompt) {
|
|
2192
|
-
const body = createPredictRequestBody(prompt,
|
|
2246
|
+
const body = createPredictRequestBody(prompt, {
|
|
2247
|
+
...this.generationConfig,
|
|
2248
|
+
...this.safetySettings
|
|
2249
|
+
});
|
|
2193
2250
|
const response = await makeRequest(this.model, Task.PREDICT, this._apiSettings,
|
|
2194
2251
|
/* stream */ false, JSON.stringify(body), this.requestOptions);
|
|
2195
2252
|
return handlePredictResponse(response);
|
|
@@ -2214,7 +2271,11 @@ class ImagenModel extends AIModel {
|
|
|
2214
2271
|
* If all images are filtered, the `images` array will be empty.
|
|
2215
2272
|
*/
|
|
2216
2273
|
async generateImagesGCS(prompt, gcsURI) {
|
|
2217
|
-
const body = createPredictRequestBody(prompt,
|
|
2274
|
+
const body = createPredictRequestBody(prompt, {
|
|
2275
|
+
gcsURI,
|
|
2276
|
+
...this.generationConfig,
|
|
2277
|
+
...this.safetySettings
|
|
2278
|
+
});
|
|
2218
2279
|
const response = await makeRequest(this.model, Task.PREDICT, this._apiSettings,
|
|
2219
2280
|
/* stream */ false, JSON.stringify(body), this.requestOptions);
|
|
2220
2281
|
return handlePredictResponse(response);
|
|
@@ -2246,12 +2307,19 @@ class ImagenModel extends AIModel {
|
|
|
2246
2307
|
*/
|
|
2247
2308
|
class Schema {
|
|
2248
2309
|
constructor(schemaParams) {
|
|
2310
|
+
// TODO(dlarocque): Enforce this with union types
|
|
2311
|
+
if (!schemaParams.type && !schemaParams.anyOf) {
|
|
2312
|
+
throw new AIError(AIErrorCode.INVALID_SCHEMA, "A schema must have either a 'type' or an 'anyOf' array of sub-schemas.");
|
|
2313
|
+
}
|
|
2249
2314
|
// eslint-disable-next-line guard-for-in
|
|
2250
2315
|
for (const paramKey in schemaParams) {
|
|
2251
2316
|
this[paramKey] = schemaParams[paramKey];
|
|
2252
2317
|
}
|
|
2253
2318
|
// Ensure these are explicitly set to avoid TS errors.
|
|
2254
2319
|
this.type = schemaParams.type;
|
|
2320
|
+
this.format = schemaParams.hasOwnProperty('format')
|
|
2321
|
+
? schemaParams.format
|
|
2322
|
+
: undefined;
|
|
2255
2323
|
this.nullable = schemaParams.hasOwnProperty('nullable')
|
|
2256
2324
|
? !!schemaParams.nullable
|
|
2257
2325
|
: false;
|
|
@@ -2298,6 +2366,9 @@ class Schema {
|
|
|
2298
2366
|
static boolean(booleanParams) {
|
|
2299
2367
|
return new BooleanSchema(booleanParams);
|
|
2300
2368
|
}
|
|
2369
|
+
static anyOf(anyOfParams) {
|
|
2370
|
+
return new AnyOfSchema(anyOfParams);
|
|
2371
|
+
}
|
|
2301
2372
|
}
|
|
2302
2373
|
/**
|
|
2303
2374
|
* Schema class for "integer" types.
|
|
@@ -2305,7 +2376,10 @@ class Schema {
|
|
|
2305
2376
|
*/
|
|
2306
2377
|
class IntegerSchema extends Schema {
|
|
2307
2378
|
constructor(schemaParams) {
|
|
2308
|
-
super(
|
|
2379
|
+
super({
|
|
2380
|
+
type: SchemaType.INTEGER,
|
|
2381
|
+
...schemaParams
|
|
2382
|
+
});
|
|
2309
2383
|
}
|
|
2310
2384
|
}
|
|
2311
2385
|
/**
|
|
@@ -2314,7 +2388,10 @@ class IntegerSchema extends Schema {
|
|
|
2314
2388
|
*/
|
|
2315
2389
|
class NumberSchema extends Schema {
|
|
2316
2390
|
constructor(schemaParams) {
|
|
2317
|
-
super(
|
|
2391
|
+
super({
|
|
2392
|
+
type: SchemaType.NUMBER,
|
|
2393
|
+
...schemaParams
|
|
2394
|
+
});
|
|
2318
2395
|
}
|
|
2319
2396
|
}
|
|
2320
2397
|
/**
|
|
@@ -2323,7 +2400,10 @@ class NumberSchema extends Schema {
|
|
|
2323
2400
|
*/
|
|
2324
2401
|
class BooleanSchema extends Schema {
|
|
2325
2402
|
constructor(schemaParams) {
|
|
2326
|
-
super(
|
|
2403
|
+
super({
|
|
2404
|
+
type: SchemaType.BOOLEAN,
|
|
2405
|
+
...schemaParams
|
|
2406
|
+
});
|
|
2327
2407
|
}
|
|
2328
2408
|
}
|
|
2329
2409
|
/**
|
|
@@ -2333,7 +2413,10 @@ class BooleanSchema extends Schema {
|
|
|
2333
2413
|
*/
|
|
2334
2414
|
class StringSchema extends Schema {
|
|
2335
2415
|
constructor(schemaParams, enumValues) {
|
|
2336
|
-
super(
|
|
2416
|
+
super({
|
|
2417
|
+
type: SchemaType.STRING,
|
|
2418
|
+
...schemaParams
|
|
2419
|
+
});
|
|
2337
2420
|
this.enum = enumValues;
|
|
2338
2421
|
}
|
|
2339
2422
|
/**
|
|
@@ -2355,7 +2438,10 @@ class StringSchema extends Schema {
|
|
|
2355
2438
|
*/
|
|
2356
2439
|
class ArraySchema extends Schema {
|
|
2357
2440
|
constructor(schemaParams, items) {
|
|
2358
|
-
super(
|
|
2441
|
+
super({
|
|
2442
|
+
type: SchemaType.ARRAY,
|
|
2443
|
+
...schemaParams
|
|
2444
|
+
});
|
|
2359
2445
|
this.items = items;
|
|
2360
2446
|
}
|
|
2361
2447
|
/**
|
|
@@ -2374,7 +2460,10 @@ class ArraySchema extends Schema {
|
|
|
2374
2460
|
*/
|
|
2375
2461
|
class ObjectSchema extends Schema {
|
|
2376
2462
|
constructor(schemaParams, properties, optionalProperties = []) {
|
|
2377
|
-
super(
|
|
2463
|
+
super({
|
|
2464
|
+
type: SchemaType.OBJECT,
|
|
2465
|
+
...schemaParams
|
|
2466
|
+
});
|
|
2378
2467
|
this.properties = properties;
|
|
2379
2468
|
this.optionalProperties = optionalProperties;
|
|
2380
2469
|
}
|
|
@@ -2383,12 +2472,12 @@ class ObjectSchema extends Schema {
|
|
|
2383
2472
|
*/
|
|
2384
2473
|
toJSON() {
|
|
2385
2474
|
const obj = super.toJSON();
|
|
2386
|
-
obj.properties =
|
|
2475
|
+
obj.properties = { ...this.properties };
|
|
2387
2476
|
const required = [];
|
|
2388
2477
|
if (this.optionalProperties) {
|
|
2389
2478
|
for (const propertyKey of this.optionalProperties) {
|
|
2390
2479
|
if (!this.properties.hasOwnProperty(propertyKey)) {
|
|
2391
|
-
throw new AIError(
|
|
2480
|
+
throw new AIError(AIErrorCode.INVALID_SCHEMA, `Property "${propertyKey}" specified in "optionalProperties" does not exist.`);
|
|
2392
2481
|
}
|
|
2393
2482
|
}
|
|
2394
2483
|
}
|
|
@@ -2407,6 +2496,34 @@ class ObjectSchema extends Schema {
|
|
|
2407
2496
|
return obj;
|
|
2408
2497
|
}
|
|
2409
2498
|
}
|
|
2499
|
+
/**
|
|
2500
|
+
* Schema class representing a value that can conform to any of the provided sub-schemas. This is
|
|
2501
|
+
* useful when a field can accept multiple distinct types or structures.
|
|
2502
|
+
* @public
|
|
2503
|
+
*/
|
|
2504
|
+
class AnyOfSchema extends Schema {
|
|
2505
|
+
constructor(schemaParams) {
|
|
2506
|
+
if (schemaParams.anyOf.length === 0) {
|
|
2507
|
+
throw new AIError(AIErrorCode.INVALID_SCHEMA, "The 'anyOf' array must not be empty.");
|
|
2508
|
+
}
|
|
2509
|
+
super({
|
|
2510
|
+
...schemaParams,
|
|
2511
|
+
type: undefined // anyOf schemas do not have an explicit type
|
|
2512
|
+
});
|
|
2513
|
+
this.anyOf = schemaParams.anyOf;
|
|
2514
|
+
}
|
|
2515
|
+
/**
|
|
2516
|
+
* @internal
|
|
2517
|
+
*/
|
|
2518
|
+
toJSON() {
|
|
2519
|
+
const obj = super.toJSON();
|
|
2520
|
+
// Ensure the 'anyOf' property contains serialized SchemaRequest objects.
|
|
2521
|
+
if (this.anyOf && Array.isArray(this.anyOf)) {
|
|
2522
|
+
obj.anyOf = this.anyOf.map(s => s.toJSON());
|
|
2523
|
+
}
|
|
2524
|
+
return obj;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2410
2527
|
|
|
2411
2528
|
/**
|
|
2412
2529
|
* @license
|
|
@@ -2488,50 +2605,6 @@ class ImagenImageFormat {
|
|
|
2488
2605
|
* See the License for the specific language governing permissions and
|
|
2489
2606
|
* limitations under the License.
|
|
2490
2607
|
*/
|
|
2491
|
-
/**
|
|
2492
|
-
* @deprecated Use the new {@link AIModel} instead. The Vertex AI in Firebase SDK has been
|
|
2493
|
-
* replaced with the Firebase AI SDK to accommodate the evolving set of supported features and
|
|
2494
|
-
* services. For migration details, see the {@link https://firebase.google.com/docs/vertex-ai/migrate-to-latest-sdk | migration guide}.
|
|
2495
|
-
*
|
|
2496
|
-
* Base class for Firebase AI model APIs.
|
|
2497
|
-
*
|
|
2498
|
-
* @public
|
|
2499
|
-
*/
|
|
2500
|
-
const VertexAIModel = AIModel;
|
|
2501
|
-
/**
|
|
2502
|
-
* @deprecated Use the new {@link AIError} instead. The Vertex AI in Firebase SDK has been
|
|
2503
|
-
* replaced with the Firebase AI SDK to accommodate the evolving set of supported features and
|
|
2504
|
-
* services. For migration details, see the {@link https://firebase.google.com/docs/vertex-ai/migrate-to-latest-sdk | migration guide}.
|
|
2505
|
-
*
|
|
2506
|
-
* Error class for the Firebase AI SDK.
|
|
2507
|
-
*
|
|
2508
|
-
* @public
|
|
2509
|
-
*/
|
|
2510
|
-
const VertexAIError = AIError;
|
|
2511
|
-
/**
|
|
2512
|
-
* @deprecated Use the new {@link getAI | getAI()} instead. The Vertex AI in Firebase SDK has been
|
|
2513
|
-
* replaced with the Firebase AI SDK to accommodate the evolving set of supported features and
|
|
2514
|
-
* services. For migration details, see the {@link https://firebase.google.com/docs/vertex-ai/migrate-to-latest-sdk | migration guide}.
|
|
2515
|
-
*
|
|
2516
|
-
* Returns a {@link VertexAI} instance for the given app, configured to use the
|
|
2517
|
-
* Vertex AI Gemini API. This instance will be
|
|
2518
|
-
* configured to use the Vertex AI Gemini API.
|
|
2519
|
-
*
|
|
2520
|
-
* @param app - The {@link @firebase/app#FirebaseApp} to use.
|
|
2521
|
-
* @param options - Options to configure the Vertex AI instance, including the location.
|
|
2522
|
-
*
|
|
2523
|
-
* @public
|
|
2524
|
-
*/
|
|
2525
|
-
function getVertexAI(app = getApp(), options) {
|
|
2526
|
-
app = getModularInstance(app);
|
|
2527
|
-
// Dependencies
|
|
2528
|
-
const AIProvider = _getProvider(app, AI_TYPE);
|
|
2529
|
-
const backend = new VertexAIBackend(options === null || options === void 0 ? void 0 : options.location);
|
|
2530
|
-
const identifier = encodeInstanceIdentifier(backend);
|
|
2531
|
-
return AIProvider.getImmediate({
|
|
2532
|
-
identifier
|
|
2533
|
-
});
|
|
2534
|
-
}
|
|
2535
2608
|
/**
|
|
2536
2609
|
* Returns the default {@link AI} instance that is associated with the provided
|
|
2537
2610
|
* {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new instance with the
|
|
@@ -2577,7 +2650,7 @@ function getAI(app = getApp(), options = { backend: new GoogleAIBackend() }) {
|
|
|
2577
2650
|
*/
|
|
2578
2651
|
function getGenerativeModel(ai, modelParams, requestOptions) {
|
|
2579
2652
|
if (!modelParams.model) {
|
|
2580
|
-
throw new AIError(
|
|
2653
|
+
throw new AIError(AIErrorCode.NO_MODEL, `Must provide a model name. Example: getGenerativeModel({ model: 'my-model-name' })`);
|
|
2581
2654
|
}
|
|
2582
2655
|
return new GenerativeModel(ai, modelParams, requestOptions);
|
|
2583
2656
|
}
|
|
@@ -2597,7 +2670,7 @@ function getGenerativeModel(ai, modelParams, requestOptions) {
|
|
|
2597
2670
|
*/
|
|
2598
2671
|
function getImagenModel(ai, modelParams, requestOptions) {
|
|
2599
2672
|
if (!modelParams.model) {
|
|
2600
|
-
throw new AIError(
|
|
2673
|
+
throw new AIError(AIErrorCode.NO_MODEL, `Must provide a model name. Example: getImagenModel({ model: 'my-model-name' })`);
|
|
2601
2674
|
}
|
|
2602
2675
|
return new ImagenModel(ai, modelParams, requestOptions);
|
|
2603
2676
|
}
|
|
@@ -2610,7 +2683,7 @@ function getImagenModel(ai, modelParams, requestOptions) {
|
|
|
2610
2683
|
function registerAI() {
|
|
2611
2684
|
_registerComponent(new Component(AI_TYPE, (container, { instanceIdentifier }) => {
|
|
2612
2685
|
if (!instanceIdentifier) {
|
|
2613
|
-
throw new AIError(
|
|
2686
|
+
throw new AIError(AIErrorCode.ERROR, 'AIService instance identifier is undefined.');
|
|
2614
2687
|
}
|
|
2615
2688
|
const backend = decodeInstanceIdentifier(instanceIdentifier);
|
|
2616
2689
|
// getImmediate for FirebaseApp will always succeed
|
|
@@ -2620,10 +2693,10 @@ function registerAI() {
|
|
|
2620
2693
|
return new AIService(app, backend, auth, appCheckProvider);
|
|
2621
2694
|
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
2622
2695
|
registerVersion(name, version, 'node');
|
|
2623
|
-
// BUILD_TARGET will be replaced by values like
|
|
2624
|
-
registerVersion(name, version, '
|
|
2696
|
+
// BUILD_TARGET will be replaced by values like esm, cjs, etc during the compilation
|
|
2697
|
+
registerVersion(name, version, 'esm2020');
|
|
2625
2698
|
}
|
|
2626
2699
|
registerAI();
|
|
2627
2700
|
|
|
2628
|
-
export { AIError, AIModel, ArraySchema, Backend, BackendType, BlockReason, BooleanSchema, ChatSession, FinishReason, FunctionCallingMode, GenerativeModel, GoogleAIBackend, HarmBlockMethod, HarmBlockThreshold, HarmCategory, HarmProbability, HarmSeverity, ImagenAspectRatio, ImagenImageFormat, ImagenModel, ImagenPersonFilterLevel, ImagenSafetyFilterLevel, IntegerSchema, Modality, NumberSchema, ObjectSchema, POSSIBLE_ROLES, ResponseModality, Schema, SchemaType, StringSchema, VertexAIBackend,
|
|
2701
|
+
export { AIError, AIErrorCode, AIModel, AnyOfSchema, ArraySchema, Backend, BackendType, BlockReason, BooleanSchema, ChatSession, FinishReason, FunctionCallingMode, GenerativeModel, GoogleAIBackend, HarmBlockMethod, HarmBlockThreshold, HarmCategory, HarmProbability, HarmSeverity, ImagenAspectRatio, ImagenImageFormat, ImagenModel, ImagenPersonFilterLevel, ImagenSafetyFilterLevel, IntegerSchema, Modality, NumberSchema, ObjectSchema, POSSIBLE_ROLES, ResponseModality, Schema, SchemaType, StringSchema, VertexAIBackend, getAI, getGenerativeModel, getImagenModel };
|
|
2629
2702
|
//# sourceMappingURL=index.node.mjs.map
|