@firebase/ai 1.4.1-canary.f11b55294 → 1.4.1-canary.f18b25f73
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 +34 -26
- package/dist/ai.d.ts +37 -26
- package/dist/esm/{index.esm2017.js → index.esm.js} +170 -93
- package/dist/esm/index.esm.js.map +1 -0
- package/dist/esm/src/requests/schema-builder.d.ts +23 -4
- package/dist/esm/src/types/requests.d.ts +1 -1
- package/dist/esm/src/types/responses.d.ts +0 -14
- package/dist/esm/src/types/schema.d.ts +12 -6
- package/dist/index.cjs.js +169 -91
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.node.cjs.js +169 -91
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +169 -92
- package/dist/index.node.mjs.map +1 -1
- package/dist/src/requests/schema-builder.d.ts +23 -4
- package/dist/src/types/requests.d.ts +1 -1
- package/dist/src/types/responses.d.ts +0 -14
- package/dist/src/types/schema.d.ts +12 -6
- package/package.json +13 -13
- package/dist/esm/index.esm2017.js.map +0 -1
package/dist/index.cjs.js
CHANGED
|
@@ -6,10 +6,9 @@ var app = require('@firebase/app');
|
|
|
6
6
|
var component = require('@firebase/component');
|
|
7
7
|
var util = require('@firebase/util');
|
|
8
8
|
var logger$1 = require('@firebase/logger');
|
|
9
|
-
var tslib = require('tslib');
|
|
10
9
|
|
|
11
10
|
var name = "@firebase/ai";
|
|
12
|
-
var version = "1.4.1-canary.
|
|
11
|
+
var version = "1.4.1-canary.f18b25f73";
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* @license
|
|
@@ -630,8 +629,8 @@ class AIService {
|
|
|
630
629
|
constructor(app, backend, authProvider, appCheckProvider) {
|
|
631
630
|
this.app = app;
|
|
632
631
|
this.backend = backend;
|
|
633
|
-
const appCheck = appCheckProvider
|
|
634
|
-
const auth = authProvider
|
|
632
|
+
const appCheck = appCheckProvider?.getImmediate({ optional: true });
|
|
633
|
+
const auth = authProvider?.getImmediate({ optional: true });
|
|
635
634
|
this.auth = auth || null;
|
|
636
635
|
this.appCheck = appCheck || null;
|
|
637
636
|
if (backend instanceof VertexAIBackend) {
|
|
@@ -803,14 +802,13 @@ class AIModel {
|
|
|
803
802
|
* @internal
|
|
804
803
|
*/
|
|
805
804
|
constructor(ai, modelName) {
|
|
806
|
-
|
|
807
|
-
if (!((_b = (_a = ai.app) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.apiKey)) {
|
|
805
|
+
if (!ai.app?.options?.apiKey) {
|
|
808
806
|
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.`);
|
|
809
807
|
}
|
|
810
|
-
else if (!
|
|
808
|
+
else if (!ai.app?.options?.projectId) {
|
|
811
809
|
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.`);
|
|
812
810
|
}
|
|
813
|
-
else if (!
|
|
811
|
+
else if (!ai.app?.options?.appId) {
|
|
814
812
|
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.`);
|
|
815
813
|
}
|
|
816
814
|
else {
|
|
@@ -938,8 +936,7 @@ class RequestUrl {
|
|
|
938
936
|
return url.toString();
|
|
939
937
|
}
|
|
940
938
|
get baseUrl() {
|
|
941
|
-
|
|
942
|
-
return ((_a = this.requestOptions) === null || _a === void 0 ? void 0 : _a.baseUrl) || DEFAULT_BASE_URL;
|
|
939
|
+
return this.requestOptions?.baseUrl || DEFAULT_BASE_URL;
|
|
943
940
|
}
|
|
944
941
|
get apiVersion() {
|
|
945
942
|
return DEFAULT_API_VERSION; // TODO: allow user-set options if that feature becomes available
|
|
@@ -1015,7 +1012,7 @@ async function makeRequest(model, task, apiSettings, stream, body, requestOption
|
|
|
1015
1012
|
try {
|
|
1016
1013
|
const request = await constructRequest(model, task, apiSettings, stream, body, requestOptions);
|
|
1017
1014
|
// Timeout is 180s by default
|
|
1018
|
-
const timeoutMillis =
|
|
1015
|
+
const timeoutMillis = requestOptions?.timeout != null && requestOptions.timeout >= 0
|
|
1019
1016
|
? requestOptions.timeout
|
|
1020
1017
|
: DEFAULT_FETCH_TIMEOUT_MS;
|
|
1021
1018
|
const abortController = new AbortController();
|
|
@@ -1039,10 +1036,7 @@ async function makeRequest(model, task, apiSettings, stream, body, requestOption
|
|
|
1039
1036
|
if (response.status === 403 &&
|
|
1040
1037
|
errorDetails &&
|
|
1041
1038
|
errorDetails.some((detail) => detail.reason === 'SERVICE_DISABLED') &&
|
|
1042
|
-
errorDetails.some((detail) => {
|
|
1043
|
-
var _a, _b;
|
|
1044
|
-
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');
|
|
1045
|
-
})) {
|
|
1039
|
+
errorDetails.some((detail) => detail.links?.[0]?.description.includes('Google developers console API activation'))) {
|
|
1046
1040
|
throw new AIError(AIErrorCode.API_NOT_ENABLED, `The Firebase AI SDK requires the Firebase AI ` +
|
|
1047
1041
|
`API ('firebasevertexai.googleapis.com') to be enabled in your ` +
|
|
1048
1042
|
`Firebase project. Enable this API by visiting the Firebase Console ` +
|
|
@@ -1187,10 +1181,9 @@ function addHelpers(response) {
|
|
|
1187
1181
|
* Returns all text found in all parts of first candidate.
|
|
1188
1182
|
*/
|
|
1189
1183
|
function getText(response) {
|
|
1190
|
-
var _a, _b, _c, _d;
|
|
1191
1184
|
const textStrings = [];
|
|
1192
|
-
if (
|
|
1193
|
-
for (const part of
|
|
1185
|
+
if (response.candidates?.[0].content?.parts) {
|
|
1186
|
+
for (const part of response.candidates?.[0].content?.parts) {
|
|
1194
1187
|
if (part.text) {
|
|
1195
1188
|
textStrings.push(part.text);
|
|
1196
1189
|
}
|
|
@@ -1207,10 +1200,9 @@ function getText(response) {
|
|
|
1207
1200
|
* Returns {@link FunctionCall}s associated with first candidate.
|
|
1208
1201
|
*/
|
|
1209
1202
|
function getFunctionCalls(response) {
|
|
1210
|
-
var _a, _b, _c, _d;
|
|
1211
1203
|
const functionCalls = [];
|
|
1212
|
-
if (
|
|
1213
|
-
for (const part of
|
|
1204
|
+
if (response.candidates?.[0].content?.parts) {
|
|
1205
|
+
for (const part of response.candidates?.[0].content?.parts) {
|
|
1214
1206
|
if (part.functionCall) {
|
|
1215
1207
|
functionCalls.push(part.functionCall);
|
|
1216
1208
|
}
|
|
@@ -1229,10 +1221,9 @@ function getFunctionCalls(response) {
|
|
|
1229
1221
|
* @internal
|
|
1230
1222
|
*/
|
|
1231
1223
|
function getInlineDataParts(response) {
|
|
1232
|
-
var _a, _b, _c, _d;
|
|
1233
1224
|
const data = [];
|
|
1234
|
-
if (
|
|
1235
|
-
for (const part of
|
|
1225
|
+
if (response.candidates?.[0].content?.parts) {
|
|
1226
|
+
for (const part of response.candidates?.[0].content?.parts) {
|
|
1236
1227
|
if (part.inlineData) {
|
|
1237
1228
|
data.push(part);
|
|
1238
1229
|
}
|
|
@@ -1251,19 +1242,18 @@ function hadBadFinishReason(candidate) {
|
|
|
1251
1242
|
badFinishReasons.some(reason => reason === candidate.finishReason));
|
|
1252
1243
|
}
|
|
1253
1244
|
function formatBlockErrorMessage(response) {
|
|
1254
|
-
var _a, _b, _c;
|
|
1255
1245
|
let message = '';
|
|
1256
1246
|
if ((!response.candidates || response.candidates.length === 0) &&
|
|
1257
1247
|
response.promptFeedback) {
|
|
1258
1248
|
message += 'Response was blocked';
|
|
1259
|
-
if (
|
|
1249
|
+
if (response.promptFeedback?.blockReason) {
|
|
1260
1250
|
message += ` due to ${response.promptFeedback.blockReason}`;
|
|
1261
1251
|
}
|
|
1262
|
-
if (
|
|
1252
|
+
if (response.promptFeedback?.blockReasonMessage) {
|
|
1263
1253
|
message += `: ${response.promptFeedback.blockReasonMessage}`;
|
|
1264
1254
|
}
|
|
1265
1255
|
}
|
|
1266
|
-
else if (
|
|
1256
|
+
else if (response.candidates?.[0]) {
|
|
1267
1257
|
const firstCandidate = response.candidates[0];
|
|
1268
1258
|
if (hadBadFinishReason(firstCandidate)) {
|
|
1269
1259
|
message += `Candidate was blocked due to ${firstCandidate.finishReason}`;
|
|
@@ -1282,12 +1272,11 @@ function formatBlockErrorMessage(response) {
|
|
|
1282
1272
|
* @internal
|
|
1283
1273
|
*/
|
|
1284
1274
|
async function handlePredictResponse(response) {
|
|
1285
|
-
var _a;
|
|
1286
1275
|
const responseJson = await response.json();
|
|
1287
1276
|
const images = [];
|
|
1288
1277
|
let filteredReason = undefined;
|
|
1289
1278
|
// The backend should always send a non-empty array of predictions if the response was successful.
|
|
1290
|
-
if (!responseJson.predictions ||
|
|
1279
|
+
if (!responseJson.predictions || responseJson.predictions?.length === 0) {
|
|
1291
1280
|
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.');
|
|
1292
1281
|
}
|
|
1293
1282
|
for (const prediction of responseJson.predictions) {
|
|
@@ -1351,13 +1340,12 @@ async function handlePredictResponse(response) {
|
|
|
1351
1340
|
* @internal
|
|
1352
1341
|
*/
|
|
1353
1342
|
function mapGenerateContentRequest(generateContentRequest) {
|
|
1354
|
-
|
|
1355
|
-
(_a = generateContentRequest.safetySettings) === null || _a === void 0 ? void 0 : _a.forEach(safetySetting => {
|
|
1343
|
+
generateContentRequest.safetySettings?.forEach(safetySetting => {
|
|
1356
1344
|
if (safetySetting.method) {
|
|
1357
1345
|
throw new AIError(AIErrorCode.UNSUPPORTED, 'SafetySetting.method is not supported in the the Gemini Developer API. Please remove this property.');
|
|
1358
1346
|
}
|
|
1359
1347
|
});
|
|
1360
|
-
if (
|
|
1348
|
+
if (generateContentRequest.generationConfig?.topK) {
|
|
1361
1349
|
const roundedTopK = Math.round(generateContentRequest.generationConfig.topK);
|
|
1362
1350
|
if (roundedTopK !== generateContentRequest.generationConfig.topK) {
|
|
1363
1351
|
logger.warn('topK in GenerationConfig has been rounded to the nearest integer to match the format for requests to the Gemini Developer API.');
|
|
@@ -1398,7 +1386,10 @@ function mapGenerateContentResponse(googleAIResponse) {
|
|
|
1398
1386
|
*/
|
|
1399
1387
|
function mapCountTokensRequest(countTokensRequest, model) {
|
|
1400
1388
|
const mappedCountTokensRequest = {
|
|
1401
|
-
generateContentRequest:
|
|
1389
|
+
generateContentRequest: {
|
|
1390
|
+
model,
|
|
1391
|
+
...countTokensRequest
|
|
1392
|
+
}
|
|
1402
1393
|
};
|
|
1403
1394
|
return mappedCountTokensRequest;
|
|
1404
1395
|
}
|
|
@@ -1418,7 +1409,6 @@ function mapGenerateContentCandidates(candidates) {
|
|
|
1418
1409
|
let mappedSafetyRatings;
|
|
1419
1410
|
if (mappedCandidates) {
|
|
1420
1411
|
candidates.forEach(candidate => {
|
|
1421
|
-
var _a;
|
|
1422
1412
|
// Map citationSources to citations.
|
|
1423
1413
|
let citationMetadata;
|
|
1424
1414
|
if (candidate.citationMetadata) {
|
|
@@ -1429,14 +1419,18 @@ function mapGenerateContentCandidates(candidates) {
|
|
|
1429
1419
|
// Assign missing candidate SafetyRatings properties to their defaults if undefined.
|
|
1430
1420
|
if (candidate.safetyRatings) {
|
|
1431
1421
|
mappedSafetyRatings = candidate.safetyRatings.map(safetyRating => {
|
|
1432
|
-
|
|
1433
|
-
|
|
1422
|
+
return {
|
|
1423
|
+
...safetyRating,
|
|
1424
|
+
severity: safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,
|
|
1425
|
+
probabilityScore: safetyRating.probabilityScore ?? 0,
|
|
1426
|
+
severityScore: safetyRating.severityScore ?? 0
|
|
1427
|
+
};
|
|
1434
1428
|
});
|
|
1435
1429
|
}
|
|
1436
1430
|
// videoMetadata is not supported.
|
|
1437
1431
|
// Throw early since developers may send a long video as input and only expect to pay
|
|
1438
1432
|
// for inference on a small portion of the video.
|
|
1439
|
-
if (
|
|
1433
|
+
if (candidate.content?.parts.some(part => part?.videoMetadata)) {
|
|
1440
1434
|
throw new AIError(AIErrorCode.UNSUPPORTED, 'Part.videoMetadata is not supported in the Gemini Developer API. Please remove this property.');
|
|
1441
1435
|
}
|
|
1442
1436
|
const mappedCandidate = {
|
|
@@ -1457,13 +1451,12 @@ function mapPromptFeedback(promptFeedback) {
|
|
|
1457
1451
|
// Assign missing SafetyRating properties to their defaults if undefined.
|
|
1458
1452
|
const mappedSafetyRatings = [];
|
|
1459
1453
|
promptFeedback.safetyRatings.forEach(safetyRating => {
|
|
1460
|
-
var _a, _b, _c;
|
|
1461
1454
|
mappedSafetyRatings.push({
|
|
1462
1455
|
category: safetyRating.category,
|
|
1463
1456
|
probability: safetyRating.probability,
|
|
1464
|
-
severity:
|
|
1465
|
-
probabilityScore:
|
|
1466
|
-
severityScore:
|
|
1457
|
+
severity: safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,
|
|
1458
|
+
probabilityScore: safetyRating.probabilityScore ?? 0,
|
|
1459
|
+
severityScore: safetyRating.severityScore ?? 0,
|
|
1467
1460
|
blocked: safetyRating.blocked
|
|
1468
1461
|
});
|
|
1469
1462
|
});
|
|
@@ -1524,24 +1517,22 @@ async function getResponsePromise(stream, apiSettings) {
|
|
|
1524
1517
|
allResponses.push(value);
|
|
1525
1518
|
}
|
|
1526
1519
|
}
|
|
1527
|
-
function generateResponseSequence(stream, apiSettings) {
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
break;
|
|
1534
|
-
}
|
|
1535
|
-
let enhancedResponse;
|
|
1536
|
-
if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
|
|
1537
|
-
enhancedResponse = createEnhancedContentResponse(mapGenerateContentResponse(value));
|
|
1538
|
-
}
|
|
1539
|
-
else {
|
|
1540
|
-
enhancedResponse = createEnhancedContentResponse(value);
|
|
1541
|
-
}
|
|
1542
|
-
yield yield tslib.__await(enhancedResponse);
|
|
1520
|
+
async function* generateResponseSequence(stream, apiSettings) {
|
|
1521
|
+
const reader = stream.getReader();
|
|
1522
|
+
while (true) {
|
|
1523
|
+
const { value, done } = await reader.read();
|
|
1524
|
+
if (done) {
|
|
1525
|
+
break;
|
|
1543
1526
|
}
|
|
1544
|
-
|
|
1527
|
+
let enhancedResponse;
|
|
1528
|
+
if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
|
|
1529
|
+
enhancedResponse = createEnhancedContentResponse(mapGenerateContentResponse(value));
|
|
1530
|
+
}
|
|
1531
|
+
else {
|
|
1532
|
+
enhancedResponse = createEnhancedContentResponse(value);
|
|
1533
|
+
}
|
|
1534
|
+
yield enhancedResponse;
|
|
1535
|
+
}
|
|
1545
1536
|
}
|
|
1546
1537
|
/**
|
|
1547
1538
|
* Reads a raw stream from the fetch response and join incomplete
|
|
@@ -1593,7 +1584,7 @@ function getResponseStream(inputStream) {
|
|
|
1593
1584
|
function aggregateResponses(responses) {
|
|
1594
1585
|
const lastResponse = responses[responses.length - 1];
|
|
1595
1586
|
const aggregatedResponse = {
|
|
1596
|
-
promptFeedback: lastResponse
|
|
1587
|
+
promptFeedback: lastResponse?.promptFeedback
|
|
1597
1588
|
};
|
|
1598
1589
|
for (const response of responses) {
|
|
1599
1590
|
if (response.candidates) {
|
|
@@ -1950,7 +1941,7 @@ class ChatSession {
|
|
|
1950
1941
|
this._history = [];
|
|
1951
1942
|
this._sendPromise = Promise.resolve();
|
|
1952
1943
|
this._apiSettings = apiSettings;
|
|
1953
|
-
if (params
|
|
1944
|
+
if (params?.history) {
|
|
1954
1945
|
validateChatHistory(params.history);
|
|
1955
1946
|
this._history = params.history;
|
|
1956
1947
|
}
|
|
@@ -1969,15 +1960,14 @@ class ChatSession {
|
|
|
1969
1960
|
* {@link GenerateContentResult}
|
|
1970
1961
|
*/
|
|
1971
1962
|
async sendMessage(request) {
|
|
1972
|
-
var _a, _b, _c, _d, _e;
|
|
1973
1963
|
await this._sendPromise;
|
|
1974
1964
|
const newContent = formatNewContent(request);
|
|
1975
1965
|
const generateContentRequest = {
|
|
1976
|
-
safetySettings:
|
|
1977
|
-
generationConfig:
|
|
1978
|
-
tools:
|
|
1979
|
-
toolConfig:
|
|
1980
|
-
systemInstruction:
|
|
1966
|
+
safetySettings: this.params?.safetySettings,
|
|
1967
|
+
generationConfig: this.params?.generationConfig,
|
|
1968
|
+
tools: this.params?.tools,
|
|
1969
|
+
toolConfig: this.params?.toolConfig,
|
|
1970
|
+
systemInstruction: this.params?.systemInstruction,
|
|
1981
1971
|
contents: [...this._history, newContent]
|
|
1982
1972
|
};
|
|
1983
1973
|
let finalResult = {};
|
|
@@ -1985,14 +1975,13 @@ class ChatSession {
|
|
|
1985
1975
|
this._sendPromise = this._sendPromise
|
|
1986
1976
|
.then(() => generateContent(this._apiSettings, this.model, generateContentRequest, this.requestOptions))
|
|
1987
1977
|
.then(result => {
|
|
1988
|
-
var _a, _b;
|
|
1989
1978
|
if (result.response.candidates &&
|
|
1990
1979
|
result.response.candidates.length > 0) {
|
|
1991
1980
|
this._history.push(newContent);
|
|
1992
1981
|
const responseContent = {
|
|
1993
|
-
parts:
|
|
1982
|
+
parts: result.response.candidates?.[0].content.parts || [],
|
|
1994
1983
|
// Response seems to come back without a role set.
|
|
1995
|
-
role:
|
|
1984
|
+
role: result.response.candidates?.[0].content.role || 'model'
|
|
1996
1985
|
};
|
|
1997
1986
|
this._history.push(responseContent);
|
|
1998
1987
|
}
|
|
@@ -2013,15 +2002,14 @@ class ChatSession {
|
|
|
2013
2002
|
* and a response promise.
|
|
2014
2003
|
*/
|
|
2015
2004
|
async sendMessageStream(request) {
|
|
2016
|
-
var _a, _b, _c, _d, _e;
|
|
2017
2005
|
await this._sendPromise;
|
|
2018
2006
|
const newContent = formatNewContent(request);
|
|
2019
2007
|
const generateContentRequest = {
|
|
2020
|
-
safetySettings:
|
|
2021
|
-
generationConfig:
|
|
2022
|
-
tools:
|
|
2023
|
-
toolConfig:
|
|
2024
|
-
systemInstruction:
|
|
2008
|
+
safetySettings: this.params?.safetySettings,
|
|
2009
|
+
generationConfig: this.params?.generationConfig,
|
|
2010
|
+
tools: this.params?.tools,
|
|
2011
|
+
toolConfig: this.params?.toolConfig,
|
|
2012
|
+
systemInstruction: this.params?.systemInstruction,
|
|
2025
2013
|
contents: [...this._history, newContent]
|
|
2026
2014
|
};
|
|
2027
2015
|
const streamPromise = generateContentStream(this._apiSettings, this.model, generateContentRequest, this.requestOptions);
|
|
@@ -2037,7 +2025,7 @@ class ChatSession {
|
|
|
2037
2025
|
.then(response => {
|
|
2038
2026
|
if (response.candidates && response.candidates.length > 0) {
|
|
2039
2027
|
this._history.push(newContent);
|
|
2040
|
-
const responseContent =
|
|
2028
|
+
const responseContent = { ...response.candidates[0].content };
|
|
2041
2029
|
// Response seems to come back without a role set.
|
|
2042
2030
|
if (!responseContent.role) {
|
|
2043
2031
|
responseContent.role = 'model';
|
|
@@ -2130,7 +2118,14 @@ class GenerativeModel extends AIModel {
|
|
|
2130
2118
|
*/
|
|
2131
2119
|
async generateContent(request) {
|
|
2132
2120
|
const formattedParams = formatGenerateContentInput(request);
|
|
2133
|
-
return generateContent(this._apiSettings, this.model,
|
|
2121
|
+
return generateContent(this._apiSettings, this.model, {
|
|
2122
|
+
generationConfig: this.generationConfig,
|
|
2123
|
+
safetySettings: this.safetySettings,
|
|
2124
|
+
tools: this.tools,
|
|
2125
|
+
toolConfig: this.toolConfig,
|
|
2126
|
+
systemInstruction: this.systemInstruction,
|
|
2127
|
+
...formattedParams
|
|
2128
|
+
}, this.requestOptions);
|
|
2134
2129
|
}
|
|
2135
2130
|
/**
|
|
2136
2131
|
* Makes a single streaming call to the model
|
|
@@ -2140,14 +2135,33 @@ class GenerativeModel extends AIModel {
|
|
|
2140
2135
|
*/
|
|
2141
2136
|
async generateContentStream(request) {
|
|
2142
2137
|
const formattedParams = formatGenerateContentInput(request);
|
|
2143
|
-
return generateContentStream(this._apiSettings, this.model,
|
|
2138
|
+
return generateContentStream(this._apiSettings, this.model, {
|
|
2139
|
+
generationConfig: this.generationConfig,
|
|
2140
|
+
safetySettings: this.safetySettings,
|
|
2141
|
+
tools: this.tools,
|
|
2142
|
+
toolConfig: this.toolConfig,
|
|
2143
|
+
systemInstruction: this.systemInstruction,
|
|
2144
|
+
...formattedParams
|
|
2145
|
+
}, this.requestOptions);
|
|
2144
2146
|
}
|
|
2145
2147
|
/**
|
|
2146
2148
|
* Gets a new {@link ChatSession} instance which can be used for
|
|
2147
2149
|
* multi-turn chats.
|
|
2148
2150
|
*/
|
|
2149
2151
|
startChat(startChatParams) {
|
|
2150
|
-
return new ChatSession(this._apiSettings, this.model,
|
|
2152
|
+
return new ChatSession(this._apiSettings, this.model, {
|
|
2153
|
+
tools: this.tools,
|
|
2154
|
+
toolConfig: this.toolConfig,
|
|
2155
|
+
systemInstruction: this.systemInstruction,
|
|
2156
|
+
generationConfig: this.generationConfig,
|
|
2157
|
+
safetySettings: this.safetySettings,
|
|
2158
|
+
/**
|
|
2159
|
+
* Overrides params inherited from GenerativeModel with those explicitly set in the
|
|
2160
|
+
* StartChatParams. For example, if startChatParams.generationConfig is set, it'll override
|
|
2161
|
+
* this.generationConfig.
|
|
2162
|
+
*/
|
|
2163
|
+
...startChatParams
|
|
2164
|
+
}, this.requestOptions);
|
|
2151
2165
|
}
|
|
2152
2166
|
/**
|
|
2153
2167
|
* Counts the tokens in the provided request.
|
|
@@ -2233,7 +2247,10 @@ class ImagenModel extends AIModel {
|
|
|
2233
2247
|
* @beta
|
|
2234
2248
|
*/
|
|
2235
2249
|
async generateImages(prompt) {
|
|
2236
|
-
const body = createPredictRequestBody(prompt,
|
|
2250
|
+
const body = createPredictRequestBody(prompt, {
|
|
2251
|
+
...this.generationConfig,
|
|
2252
|
+
...this.safetySettings
|
|
2253
|
+
});
|
|
2237
2254
|
const response = await makeRequest(this.model, Task.PREDICT, this._apiSettings,
|
|
2238
2255
|
/* stream */ false, JSON.stringify(body), this.requestOptions);
|
|
2239
2256
|
return handlePredictResponse(response);
|
|
@@ -2258,7 +2275,11 @@ class ImagenModel extends AIModel {
|
|
|
2258
2275
|
* If all images are filtered, the `images` array will be empty.
|
|
2259
2276
|
*/
|
|
2260
2277
|
async generateImagesGCS(prompt, gcsURI) {
|
|
2261
|
-
const body = createPredictRequestBody(prompt,
|
|
2278
|
+
const body = createPredictRequestBody(prompt, {
|
|
2279
|
+
gcsURI,
|
|
2280
|
+
...this.generationConfig,
|
|
2281
|
+
...this.safetySettings
|
|
2282
|
+
});
|
|
2262
2283
|
const response = await makeRequest(this.model, Task.PREDICT, this._apiSettings,
|
|
2263
2284
|
/* stream */ false, JSON.stringify(body), this.requestOptions);
|
|
2264
2285
|
return handlePredictResponse(response);
|
|
@@ -2290,12 +2311,19 @@ class ImagenModel extends AIModel {
|
|
|
2290
2311
|
*/
|
|
2291
2312
|
class Schema {
|
|
2292
2313
|
constructor(schemaParams) {
|
|
2314
|
+
// TODO(dlarocque): Enforce this with union types
|
|
2315
|
+
if (!schemaParams.type && !schemaParams.anyOf) {
|
|
2316
|
+
throw new AIError(AIErrorCode.INVALID_SCHEMA, "A schema must have either a 'type' or an 'anyOf' array of sub-schemas.");
|
|
2317
|
+
}
|
|
2293
2318
|
// eslint-disable-next-line guard-for-in
|
|
2294
2319
|
for (const paramKey in schemaParams) {
|
|
2295
2320
|
this[paramKey] = schemaParams[paramKey];
|
|
2296
2321
|
}
|
|
2297
2322
|
// Ensure these are explicitly set to avoid TS errors.
|
|
2298
2323
|
this.type = schemaParams.type;
|
|
2324
|
+
this.format = schemaParams.hasOwnProperty('format')
|
|
2325
|
+
? schemaParams.format
|
|
2326
|
+
: undefined;
|
|
2299
2327
|
this.nullable = schemaParams.hasOwnProperty('nullable')
|
|
2300
2328
|
? !!schemaParams.nullable
|
|
2301
2329
|
: false;
|
|
@@ -2342,6 +2370,9 @@ class Schema {
|
|
|
2342
2370
|
static boolean(booleanParams) {
|
|
2343
2371
|
return new BooleanSchema(booleanParams);
|
|
2344
2372
|
}
|
|
2373
|
+
static anyOf(anyOfParams) {
|
|
2374
|
+
return new AnyOfSchema(anyOfParams);
|
|
2375
|
+
}
|
|
2345
2376
|
}
|
|
2346
2377
|
/**
|
|
2347
2378
|
* Schema class for "integer" types.
|
|
@@ -2349,7 +2380,10 @@ class Schema {
|
|
|
2349
2380
|
*/
|
|
2350
2381
|
class IntegerSchema extends Schema {
|
|
2351
2382
|
constructor(schemaParams) {
|
|
2352
|
-
super(
|
|
2383
|
+
super({
|
|
2384
|
+
type: SchemaType.INTEGER,
|
|
2385
|
+
...schemaParams
|
|
2386
|
+
});
|
|
2353
2387
|
}
|
|
2354
2388
|
}
|
|
2355
2389
|
/**
|
|
@@ -2358,7 +2392,10 @@ class IntegerSchema extends Schema {
|
|
|
2358
2392
|
*/
|
|
2359
2393
|
class NumberSchema extends Schema {
|
|
2360
2394
|
constructor(schemaParams) {
|
|
2361
|
-
super(
|
|
2395
|
+
super({
|
|
2396
|
+
type: SchemaType.NUMBER,
|
|
2397
|
+
...schemaParams
|
|
2398
|
+
});
|
|
2362
2399
|
}
|
|
2363
2400
|
}
|
|
2364
2401
|
/**
|
|
@@ -2367,7 +2404,10 @@ class NumberSchema extends Schema {
|
|
|
2367
2404
|
*/
|
|
2368
2405
|
class BooleanSchema extends Schema {
|
|
2369
2406
|
constructor(schemaParams) {
|
|
2370
|
-
super(
|
|
2407
|
+
super({
|
|
2408
|
+
type: SchemaType.BOOLEAN,
|
|
2409
|
+
...schemaParams
|
|
2410
|
+
});
|
|
2371
2411
|
}
|
|
2372
2412
|
}
|
|
2373
2413
|
/**
|
|
@@ -2377,7 +2417,10 @@ class BooleanSchema extends Schema {
|
|
|
2377
2417
|
*/
|
|
2378
2418
|
class StringSchema extends Schema {
|
|
2379
2419
|
constructor(schemaParams, enumValues) {
|
|
2380
|
-
super(
|
|
2420
|
+
super({
|
|
2421
|
+
type: SchemaType.STRING,
|
|
2422
|
+
...schemaParams
|
|
2423
|
+
});
|
|
2381
2424
|
this.enum = enumValues;
|
|
2382
2425
|
}
|
|
2383
2426
|
/**
|
|
@@ -2399,7 +2442,10 @@ class StringSchema extends Schema {
|
|
|
2399
2442
|
*/
|
|
2400
2443
|
class ArraySchema extends Schema {
|
|
2401
2444
|
constructor(schemaParams, items) {
|
|
2402
|
-
super(
|
|
2445
|
+
super({
|
|
2446
|
+
type: SchemaType.ARRAY,
|
|
2447
|
+
...schemaParams
|
|
2448
|
+
});
|
|
2403
2449
|
this.items = items;
|
|
2404
2450
|
}
|
|
2405
2451
|
/**
|
|
@@ -2418,7 +2464,10 @@ class ArraySchema extends Schema {
|
|
|
2418
2464
|
*/
|
|
2419
2465
|
class ObjectSchema extends Schema {
|
|
2420
2466
|
constructor(schemaParams, properties, optionalProperties = []) {
|
|
2421
|
-
super(
|
|
2467
|
+
super({
|
|
2468
|
+
type: SchemaType.OBJECT,
|
|
2469
|
+
...schemaParams
|
|
2470
|
+
});
|
|
2422
2471
|
this.properties = properties;
|
|
2423
2472
|
this.optionalProperties = optionalProperties;
|
|
2424
2473
|
}
|
|
@@ -2427,7 +2476,7 @@ class ObjectSchema extends Schema {
|
|
|
2427
2476
|
*/
|
|
2428
2477
|
toJSON() {
|
|
2429
2478
|
const obj = super.toJSON();
|
|
2430
|
-
obj.properties =
|
|
2479
|
+
obj.properties = { ...this.properties };
|
|
2431
2480
|
const required = [];
|
|
2432
2481
|
if (this.optionalProperties) {
|
|
2433
2482
|
for (const propertyKey of this.optionalProperties) {
|
|
@@ -2451,6 +2500,34 @@ class ObjectSchema extends Schema {
|
|
|
2451
2500
|
return obj;
|
|
2452
2501
|
}
|
|
2453
2502
|
}
|
|
2503
|
+
/**
|
|
2504
|
+
* Schema class representing a value that can conform to any of the provided sub-schemas. This is
|
|
2505
|
+
* useful when a field can accept multiple distinct types or structures.
|
|
2506
|
+
* @public
|
|
2507
|
+
*/
|
|
2508
|
+
class AnyOfSchema extends Schema {
|
|
2509
|
+
constructor(schemaParams) {
|
|
2510
|
+
if (schemaParams.anyOf.length === 0) {
|
|
2511
|
+
throw new AIError(AIErrorCode.INVALID_SCHEMA, "The 'anyOf' array must not be empty.");
|
|
2512
|
+
}
|
|
2513
|
+
super({
|
|
2514
|
+
...schemaParams,
|
|
2515
|
+
type: undefined // anyOf schemas do not have an explicit type
|
|
2516
|
+
});
|
|
2517
|
+
this.anyOf = schemaParams.anyOf;
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* @internal
|
|
2521
|
+
*/
|
|
2522
|
+
toJSON() {
|
|
2523
|
+
const obj = super.toJSON();
|
|
2524
|
+
// Ensure the 'anyOf' property contains serialized SchemaRequest objects.
|
|
2525
|
+
if (this.anyOf && Array.isArray(this.anyOf)) {
|
|
2526
|
+
obj.anyOf = this.anyOf.map(s => s.toJSON());
|
|
2527
|
+
}
|
|
2528
|
+
return obj;
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2454
2531
|
|
|
2455
2532
|
/**
|
|
2456
2533
|
* @license
|
|
@@ -2620,14 +2697,15 @@ function registerAI() {
|
|
|
2620
2697
|
return new AIService(app, backend, auth, appCheckProvider);
|
|
2621
2698
|
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
2622
2699
|
app.registerVersion(name, version);
|
|
2623
|
-
// BUILD_TARGET will be replaced by values like
|
|
2624
|
-
app.registerVersion(name, version, '
|
|
2700
|
+
// BUILD_TARGET will be replaced by values like esm, cjs, etc during the compilation
|
|
2701
|
+
app.registerVersion(name, version, 'cjs2020');
|
|
2625
2702
|
}
|
|
2626
2703
|
registerAI();
|
|
2627
2704
|
|
|
2628
2705
|
exports.AIError = AIError;
|
|
2629
2706
|
exports.AIErrorCode = AIErrorCode;
|
|
2630
2707
|
exports.AIModel = AIModel;
|
|
2708
|
+
exports.AnyOfSchema = AnyOfSchema;
|
|
2631
2709
|
exports.ArraySchema = ArraySchema;
|
|
2632
2710
|
exports.Backend = Backend;
|
|
2633
2711
|
exports.BackendType = BackendType;
|