@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.
@@ -16,7 +16,9 @@
16
16
  */
17
17
  import { CountTokensRequest, GenerateContentRequest, InferenceMode, OnDeviceParams } from '../types';
18
18
  import { ChromeAdapter } from '../types/chrome-adapter';
19
- import { LanguageModel } from '../types/language-model';
19
+ import { Availability, LanguageModel, LanguageModelExpected } from '../types/language-model';
20
+ export declare const defaultExpectedInputs: LanguageModelExpected[];
21
+ export declare const defaultExpectedOutputs: LanguageModelExpected[];
20
22
  /**
21
23
  * Defines an inference "backend" that uses Chrome's on-device model,
22
24
  * and encapsulates logic for detecting when on-device inference is
@@ -26,8 +28,7 @@ export declare class ChromeAdapterImpl implements ChromeAdapter {
26
28
  languageModelProvider: LanguageModel;
27
29
  mode: InferenceMode;
28
30
  static SUPPORTED_MIME_TYPES: string[];
29
- private isDownloading;
30
- private downloadPromise;
31
+ downloadPromise: Promise<LanguageModel | void> | null;
31
32
  private oldSession;
32
33
  onDeviceParams: OnDeviceParams;
33
34
  constructor(languageModelProvider: LanguageModel, mode: InferenceMode, onDeviceParams?: OnDeviceParams);
@@ -38,7 +39,7 @@ export declare class ChromeAdapterImpl implements ChromeAdapter {
38
39
  * the mode
39
40
  * API existence
40
41
  * prompt formatting
41
- * model availability, including triggering download if necessary
42
+ * model availability
42
43
  *
43
44
  *
44
45
  * Pros: callers needn't be concerned with details of on-device availability.</p>
@@ -75,12 +76,12 @@ export declare class ChromeAdapterImpl implements ChromeAdapter {
75
76
  /**
76
77
  * Encapsulates logic to get availability and download a model if one is downloadable.
77
78
  */
78
- private downloadIfAvailable;
79
+ downloadIfAvailable(onDownloadProgress?: (progressValue: number) => void): Promise<Availability | undefined>;
79
80
  /**
80
81
  * Triggers out-of-band download of an on-device model.
81
82
  *
82
- * Chrome only downloads models as needed. Chrome knows a model is needed when code calls
83
- * LanguageModel.create.
83
+ * Chrome may automatically begin a download on startup or
84
+ * it may trigger a download when code calls LanguageModel.create.
84
85
  *
85
86
  * Since Chrome manages the download, the SDK can only avoid redundant download requests by
86
87
  * tracking if a download has previously been requested.
@@ -32,6 +32,35 @@ export declare class GenerativeModel extends AIModel {
32
32
  toolConfig?: ToolConfig;
33
33
  systemInstruction?: Content;
34
34
  constructor(ai: AI, modelParams: ModelParams, requestOptions?: RequestOptions, chromeAdapter?: ChromeAdapter | undefined);
35
+ /**
36
+ * Initializes on-device models.
37
+ *
38
+ * @remarks
39
+ * This may trigger a download on first
40
+ * use. Wait for this promise to complete before calling inference
41
+ * methods if you want to ensure the device models are ready before
42
+ * any calls. Calling inference methods before the device is ready
43
+ * will result in a cloud fallback if `inferenceMode` is set to
44
+ * `PREFER_ON_DEVICE`, and an error if set to `ONLY_ON_DEVICE`.
45
+ *
46
+ * IMPORTANT: This call must be made on or after a user has interacted
47
+ * with the page (for example, through a button click or key press).
48
+ * If it is called without a user interaction, and it requires a download,
49
+ * this will cause an error.
50
+ *
51
+ * See the
52
+ * {@link https://developer.chrome.com/docs/ai/prompt-api#use_the_prompt_api | Prompt API docs }
53
+ * for more details on this requirement.
54
+ *
55
+ * @param onDownloadProgress A callback called repeatedly as the
56
+ * download progresses that provides a `progressValue` between 0
57
+ * and 1 representing how much of the download is complete. This
58
+ * will be ignored if `monitor` was populated in
59
+ * {@link LanguageModelCreateOptions}.
60
+ *
61
+ * @public
62
+ */
63
+ initializeDeviceModel(onDownloadProgress?: (progressValue: number) => void): Promise<void>;
35
64
  /**
36
65
  * Makes a single non-streaming call to the model
37
66
  * and returns an object containing a single {@link GenerateContentResponse}.
@@ -23,7 +23,7 @@ import { CountTokensRequest, GenerateContentRequest } from './requests';
23
23
  *
24
24
  * These methods should not be called directly by the user.
25
25
  *
26
- * @beta
26
+ * @public
27
27
  */
28
28
  export interface ChromeAdapter {
29
29
  /**
@@ -415,7 +415,7 @@ export type ResponseModality = (typeof ResponseModality)[keyof typeof ResponseMo
415
415
  * cloud-hosted model. If not available, the SDK will fall back to an
416
416
  * on-device model.
417
417
  *
418
- * @beta
418
+ * @public
419
419
  */
420
420
  export declare const InferenceMode: {
421
421
  readonly PREFER_ON_DEVICE: "prefer_on_device";
@@ -426,13 +426,13 @@ export declare const InferenceMode: {
426
426
  /**
427
427
  * Determines whether inference happens on-device or in-cloud.
428
428
  *
429
- * @beta
429
+ * @public
430
430
  */
431
431
  export type InferenceMode = (typeof InferenceMode)[keyof typeof InferenceMode];
432
432
  /**
433
433
  * Indicates whether inference happened on-device or in-cloud.
434
434
  *
435
- * @beta
435
+ * @public
436
436
  */
437
437
  export declare const InferenceSource: {
438
438
  readonly ON_DEVICE: "on_device";
@@ -441,7 +441,7 @@ export declare const InferenceSource: {
441
441
  /**
442
442
  * Indicates whether inference happened on-device or in-cloud.
443
443
  *
444
- * @beta
444
+ * @public
445
445
  */
446
446
  export type InferenceSource = (typeof InferenceSource)[keyof typeof InferenceSource];
447
447
  /**
@@ -22,5 +22,5 @@ export * from './error';
22
22
  export * from './schema';
23
23
  export * from './imagen';
24
24
  export * from './googleai';
25
- export { LanguageModelCreateOptions, LanguageModelCreateCoreOptions, LanguageModelExpected, LanguageModelMessage, LanguageModelMessageContent, LanguageModelMessageContentValue, LanguageModelMessageRole, LanguageModelMessageType, LanguageModelPromptOptions } from './language-model';
25
+ export { LanguageModelCreateOptions, LanguageModelCreateCoreOptions, LanguageModelExpected, LanguageModelMessage, LanguageModelMessageContent, LanguageModelMessageContentValue, LanguageModelMessageRole, LanguageModelMessageType, LanguageModelPromptOptions, LanguageModelDownloadMonitor } from './language-model';
26
26
  export * from './chrome-adapter';
@@ -40,7 +40,7 @@ export declare enum Availability {
40
40
  }
41
41
  /**
42
42
  * Configures the creation of an on-device language model session.
43
- * @beta
43
+ * @public
44
44
  */
45
45
  export interface LanguageModelCreateCoreOptions {
46
46
  /**
@@ -51,11 +51,41 @@ export interface LanguageModelCreateCoreOptions {
51
51
  * @deprecated
52
52
  */
53
53
  temperature?: number;
54
+ /**
55
+ * Defaults to image input and English text input
56
+ * if not overriden.
57
+ */
54
58
  expectedInputs?: LanguageModelExpected[];
59
+ /**
60
+ * Defaults to English text output if not overriden.
61
+ */
62
+ expectedOutputs?: LanguageModelExpected[];
63
+ /**
64
+ * The native download monitor provided by the Chrome API.
65
+ * This provides direct access to the monitor object and is
66
+ * only needed for advanced cases. For
67
+ * a simpler download monitoring interface, provide an
68
+ * `onDownloadProgress` callback
69
+ * to {@link GenerativeModel.initializeDeviceModel} instead.
70
+ */
71
+ monitor?: (monitor: LanguageModelDownloadMonitor) => void;
72
+ }
73
+ /**
74
+ * Interface representing the Chrome Prompt API's native
75
+ * download monitor object.
76
+ * @public
77
+ */
78
+ export interface LanguageModelDownloadMonitor {
79
+ addEventListener: (eventType: 'downloadprogress', eventListener: (e: {
80
+ loaded: number;
81
+ }) => void) => void;
82
+ removeEventListener: (eventType: 'downloadprogress', eventListener: (e: {
83
+ loaded: number;
84
+ }) => void) => void;
55
85
  }
56
86
  /**
57
87
  * Configures the creation of an on-device language model session.
58
- * @beta
88
+ * @public
59
89
  */
60
90
  export interface LanguageModelCreateOptions extends LanguageModelCreateCoreOptions {
61
91
  signal?: AbortSignal;
@@ -63,26 +93,26 @@ export interface LanguageModelCreateOptions extends LanguageModelCreateCoreOptio
63
93
  }
64
94
  /**
65
95
  * Options for an on-device language model prompt.
66
- * @beta
96
+ * @public
67
97
  */
68
98
  export interface LanguageModelPromptOptions {
69
99
  responseConstraint?: object;
70
100
  }
71
101
  /**
72
102
  * Options for the expected inputs for an on-device language model.
73
- * @beta
103
+ * @public
74
104
  */ export interface LanguageModelExpected {
75
105
  type: LanguageModelMessageType;
76
106
  languages?: string[];
77
107
  }
78
108
  /**
79
109
  * An on-device language model prompt.
80
- * @beta
110
+ * @public
81
111
  */
82
112
  export type LanguageModelPrompt = LanguageModelMessage[];
83
113
  /**
84
114
  * An on-device language model message.
85
- * @beta
115
+ * @public
86
116
  */
87
117
  export interface LanguageModelMessage {
88
118
  role: LanguageModelMessageRole;
@@ -90,7 +120,7 @@ export interface LanguageModelMessage {
90
120
  }
91
121
  /**
92
122
  * An on-device language model content object.
93
- * @beta
123
+ * @public
94
124
  */
95
125
  export interface LanguageModelMessageContent {
96
126
  type: LanguageModelMessageType;
@@ -98,16 +128,16 @@ export interface LanguageModelMessageContent {
98
128
  }
99
129
  /**
100
130
  * Allowable roles for on-device language model usage.
101
- * @beta
131
+ * @public
102
132
  */
103
133
  export type LanguageModelMessageRole = 'system' | 'user' | 'assistant';
104
134
  /**
105
135
  * Allowable types for on-device language model messages.
106
- * @beta
136
+ * @public
107
137
  */
108
138
  export type LanguageModelMessageType = 'text' | 'image' | 'audio';
109
139
  /**
110
140
  * Content formats that can be provided as on-device message content.
111
- * @beta
141
+ * @public
112
142
  */
113
143
  export type LanguageModelMessageContentValue = ImageBitmapSource | AudioBuffer | BufferSource | string;
@@ -673,7 +673,7 @@ export interface RetrievalConfig {
673
673
  /**
674
674
  * Encapsulates configuration for on-device inference.
675
675
  *
676
- * @beta
676
+ * @public
677
677
  */
678
678
  export interface OnDeviceParams {
679
679
  createOptions?: LanguageModelCreateOptions;
@@ -681,7 +681,7 @@ export interface OnDeviceParams {
681
681
  }
682
682
  /**
683
683
  * Configures hybrid inference.
684
- * @beta
684
+ * @public
685
685
  */
686
686
  export interface HybridParams {
687
687
  /**
@@ -79,7 +79,7 @@ export interface EnhancedGenerateContentResponse extends GenerateContentResponse
79
79
  /**
80
80
  * Indicates whether inference happened on-device or in-cloud.
81
81
  *
82
- * @beta
82
+ * @public
83
83
  */
84
84
  inferenceSource?: InferenceSource;
85
85
  }
package/dist/index.cjs.js CHANGED
@@ -8,7 +8,7 @@ var util = require('@firebase/util');
8
8
  var logger$1 = require('@firebase/logger');
9
9
 
10
10
  var name = "@firebase/ai";
11
- var version = "2.12.0";
11
+ var version = "2.13.0-20260526192810";
12
12
 
13
13
  /**
14
14
  * @license
@@ -447,7 +447,7 @@ const ResponseModality = {
447
447
  * cloud-hosted model. If not available, the SDK will fall back to an
448
448
  * on-device model.
449
449
  *
450
- * @beta
450
+ * @public
451
451
  */
452
452
  const InferenceMode = {
453
453
  'PREFER_ON_DEVICE': 'prefer_on_device',
@@ -458,7 +458,7 @@ const InferenceMode = {
458
458
  /**
459
459
  * Indicates whether inference happened on-device or in-cloud.
460
460
  *
461
- * @beta
461
+ * @public
462
462
  */
463
463
  const InferenceSource = {
464
464
  'ON_DEVICE': 'on_device',
@@ -1027,8 +1027,18 @@ var Availability;
1027
1027
  * See the License for the specific language governing permissions and
1028
1028
  * limitations under the License.
1029
1029
  */
1030
- // Defaults to support image inputs for convenience.
1031
- const defaultExpectedInputs = [{ type: 'image' }];
1030
+ // Defaults to English text. This can be overriden by user config.
1031
+ const defaultExpectedText = {
1032
+ type: 'text',
1033
+ languages: ['en']
1034
+ };
1035
+ const defaultExpectedInputs = [
1036
+ defaultExpectedText,
1037
+ { type: 'image' }
1038
+ ];
1039
+ const defaultExpectedOutputs = [
1040
+ defaultExpectedText
1041
+ ];
1032
1042
  /**
1033
1043
  * Defines an inference "backend" that uses Chrome's on-device model,
1034
1044
  * and encapsulates logic for detecting when on-device inference is
@@ -1038,22 +1048,31 @@ class ChromeAdapterImpl {
1038
1048
  constructor(languageModelProvider, mode, onDeviceParams) {
1039
1049
  this.languageModelProvider = languageModelProvider;
1040
1050
  this.mode = mode;
1041
- this.isDownloading = false;
1051
+ // Promise for on-device model download completion
1052
+ this.downloadPromise = null;
1042
1053
  this.onDeviceParams = {
1043
1054
  createOptions: {
1044
- expectedInputs: defaultExpectedInputs
1055
+ expectedInputs: defaultExpectedInputs,
1056
+ expectedOutputs: defaultExpectedOutputs
1045
1057
  }
1046
1058
  };
1047
1059
  if (onDeviceParams) {
1048
1060
  this.onDeviceParams = onDeviceParams;
1049
1061
  if (!this.onDeviceParams.createOptions) {
1050
1062
  this.onDeviceParams.createOptions = {
1051
- expectedInputs: defaultExpectedInputs
1063
+ expectedInputs: defaultExpectedInputs,
1064
+ expectedOutputs: defaultExpectedOutputs
1052
1065
  };
1053
1066
  }
1054
- else if (!this.onDeviceParams.createOptions.expectedInputs) {
1055
- this.onDeviceParams.createOptions.expectedInputs =
1056
- defaultExpectedInputs;
1067
+ else {
1068
+ if (!this.onDeviceParams.createOptions.expectedInputs) {
1069
+ this.onDeviceParams.createOptions.expectedInputs =
1070
+ defaultExpectedInputs;
1071
+ }
1072
+ if (!this.onDeviceParams.createOptions.expectedOutputs) {
1073
+ this.onDeviceParams.createOptions.expectedOutputs =
1074
+ defaultExpectedOutputs;
1075
+ }
1057
1076
  }
1058
1077
  }
1059
1078
  }
@@ -1064,7 +1083,7 @@ class ChromeAdapterImpl {
1064
1083
  * the mode
1065
1084
  * API existence
1066
1085
  * prompt formatting
1067
- * model availability, including triggering download if necessary
1086
+ * model availability
1068
1087
  *
1069
1088
  *
1070
1089
  * Pros: callers needn't be concerned with details of on-device availability.</p>
@@ -1081,8 +1100,7 @@ class ChromeAdapterImpl {
1081
1100
  logger.debug(`On-device inference unavailable because mode is "only_in_cloud".`);
1082
1101
  return false;
1083
1102
  }
1084
- // Triggers out-of-band download so model will eventually become available.
1085
- const availability = await this.downloadIfAvailable();
1103
+ const availability = await this.languageModelProvider?.availability(this.onDeviceParams.createOptions);
1086
1104
  if (this.mode === InferenceMode.ONLY_ON_DEVICE) {
1087
1105
  // If it will never be available due to API inavailability, throw.
1088
1106
  if (availability === Availability.UNAVAILABLE) {
@@ -1090,9 +1108,13 @@ class ChromeAdapterImpl {
1090
1108
  }
1091
1109
  else if (availability === Availability.DOWNLOADABLE ||
1092
1110
  availability === Availability.DOWNLOADING) {
1093
- // TODO(chholland): Better user experience during download - progress?
1094
1111
  logger.debug(`Waiting for download of LanguageModel to complete.`);
1095
- await this.downloadPromise;
1112
+ try {
1113
+ await this.downloadPromise;
1114
+ }
1115
+ catch (e) {
1116
+ throw new AIError(AIErrorCode.ERROR, e.message);
1117
+ }
1096
1118
  return true;
1097
1119
  }
1098
1120
  return true;
@@ -1169,31 +1191,44 @@ class ChromeAdapterImpl {
1169
1191
  /**
1170
1192
  * Encapsulates logic to get availability and download a model if one is downloadable.
1171
1193
  */
1172
- async downloadIfAvailable() {
1194
+ async downloadIfAvailable(onDownloadProgress) {
1173
1195
  const availability = await this.languageModelProvider?.availability(this.onDeviceParams.createOptions);
1174
- if (availability === Availability.DOWNLOADABLE) {
1175
- this.download();
1196
+ /**
1197
+ * Download may have been automatically started by Chrome or other
1198
+ * code, in which case we should still call create() to get a promise
1199
+ * for when the download completes.
1200
+ */
1201
+ if (availability === Availability.DOWNLOADABLE ||
1202
+ availability === Availability.DOWNLOADING) {
1203
+ this.download(onDownloadProgress);
1176
1204
  }
1177
1205
  return availability;
1178
1206
  }
1179
1207
  /**
1180
1208
  * Triggers out-of-band download of an on-device model.
1181
1209
  *
1182
- * Chrome only downloads models as needed. Chrome knows a model is needed when code calls
1183
- * LanguageModel.create.
1210
+ * Chrome may automatically begin a download on startup or
1211
+ * it may trigger a download when code calls LanguageModel.create.
1184
1212
  *
1185
1213
  * Since Chrome manages the download, the SDK can only avoid redundant download requests by
1186
1214
  * tracking if a download has previously been requested.
1187
1215
  */
1188
- download() {
1189
- if (this.isDownloading) {
1216
+ download(onDownloadProgress) {
1217
+ if (this.downloadPromise) {
1190
1218
  return;
1191
1219
  }
1192
- this.isDownloading = true;
1220
+ const options = { ...this.onDeviceParams.createOptions };
1221
+ if (options && !options.monitor && onDownloadProgress) {
1222
+ options.monitor = m => {
1223
+ m.addEventListener('downloadprogress', e => {
1224
+ onDownloadProgress(e.loaded);
1225
+ });
1226
+ };
1227
+ }
1193
1228
  this.downloadPromise = this.languageModelProvider
1194
- ?.create(this.onDeviceParams.createOptions)
1229
+ ?.create(options)
1195
1230
  .finally(() => {
1196
- this.isDownloading = false;
1231
+ this.downloadPromise = null;
1197
1232
  });
1198
1233
  }
1199
1234
  /**
@@ -1248,6 +1283,13 @@ class ChromeAdapterImpl {
1248
1283
  if (!this.languageModelProvider) {
1249
1284
  throw new AIError(AIErrorCode.UNSUPPORTED, 'Chrome AI requested for unsupported browser version.');
1250
1285
  }
1286
+ /**
1287
+ * Note: `create()` will trigger a download as a side effect if
1288
+ * a model is not downloaded or downloading, but this specific
1289
+ * create() call should not be relied on for the download. The download
1290
+ * should be triggered explicitly by the user in
1291
+ * GenerativeModel.initializeDeviceModel().
1292
+ */
1251
1293
  const newSession = await this.languageModelProvider.create(this.onDeviceParams.createOptions);
1252
1294
  if (this.oldSession) {
1253
1295
  this.oldSession.destroy();
@@ -2439,7 +2481,9 @@ async function callCloudOrDevice(request, chromeAdapter, onDeviceCall, inCloudCa
2439
2481
  };
2440
2482
  }
2441
2483
  catch (e) {
2442
- if (e instanceof AIError && errorsCausingFallback.includes(e.code)) {
2484
+ if (e instanceof AIError &&
2485
+ errorsCausingFallback.includes(e.code) &&
2486
+ (await chromeAdapter.isAvailable(request))) {
2443
2487
  return {
2444
2488
  response: await onDeviceCall(),
2445
2489
  inferenceSource: InferenceSource.ON_DEVICE
@@ -2766,7 +2810,9 @@ class ChatSessionBase {
2766
2810
  else {
2767
2811
  formattedContent = formatNewContent(request);
2768
2812
  }
2769
- const formattedRequest = this._formatRequest(formattedContent, tempHistory);
2813
+ const formattedRequest = this._formatRequest(formattedContent, [
2814
+ ...tempHistory
2815
+ ]);
2770
2816
  tempHistory.push(formattedContent);
2771
2817
  const result = await this._callGenerateContent(formattedRequest, singleRequestOptions);
2772
2818
  if (result) {
@@ -2836,8 +2882,10 @@ class ChatSessionBase {
2836
2882
  else {
2837
2883
  formattedContent = formatNewContent(request);
2838
2884
  }
2885
+ const formattedRequest = this._formatRequest(formattedContent, [
2886
+ ...tempHistory
2887
+ ]);
2839
2888
  tempHistory.push(formattedContent);
2840
- const formattedRequest = this._formatRequest(formattedContent, tempHistory);
2841
2889
  result = await this._callGenerateContentStream(formattedRequest, singleRequestOptions);
2842
2890
  functionCalls = this._getCallableFunctionCalls(result.firstValue);
2843
2891
  if (functionCalls &&
@@ -3225,6 +3273,52 @@ class GenerativeModel extends AIModel {
3225
3273
  this.systemInstruction = formatSystemInstruction(modelParams.systemInstruction);
3226
3274
  this.requestOptions = requestOptions || {};
3227
3275
  }
3276
+ /**
3277
+ * Initializes on-device models.
3278
+ *
3279
+ * @remarks
3280
+ * This may trigger a download on first
3281
+ * use. Wait for this promise to complete before calling inference
3282
+ * methods if you want to ensure the device models are ready before
3283
+ * any calls. Calling inference methods before the device is ready
3284
+ * will result in a cloud fallback if `inferenceMode` is set to
3285
+ * `PREFER_ON_DEVICE`, and an error if set to `ONLY_ON_DEVICE`.
3286
+ *
3287
+ * IMPORTANT: This call must be made on or after a user has interacted
3288
+ * with the page (for example, through a button click or key press).
3289
+ * If it is called without a user interaction, and it requires a download,
3290
+ * this will cause an error.
3291
+ *
3292
+ * See the
3293
+ * {@link https://developer.chrome.com/docs/ai/prompt-api#use_the_prompt_api | Prompt API docs }
3294
+ * for more details on this requirement.
3295
+ *
3296
+ * @param onDownloadProgress A callback called repeatedly as the
3297
+ * download progresses that provides a `progressValue` between 0
3298
+ * and 1 representing how much of the download is complete. This
3299
+ * will be ignored if `monitor` was populated in
3300
+ * {@link LanguageModelCreateOptions}.
3301
+ *
3302
+ * @public
3303
+ */
3304
+ async initializeDeviceModel(onDownloadProgress) {
3305
+ if (!this.chromeAdapter ||
3306
+ this.chromeAdapter.mode === InferenceMode.ONLY_IN_CLOUD) {
3307
+ return;
3308
+ }
3309
+ const availability = await this.chromeAdapter.downloadIfAvailable(onDownloadProgress);
3310
+ if (availability === Availability.UNAVAILABLE) {
3311
+ const notEnabledError = new AIError(AIErrorCode.API_NOT_ENABLED, 'Local LanguageModel API not available in this environment.');
3312
+ if (this.chromeAdapter.mode === InferenceMode.ONLY_ON_DEVICE) {
3313
+ throw notEnabledError;
3314
+ }
3315
+ else {
3316
+ // No reason to throw if not in ONLY_ON_DEVICE mode.
3317
+ logger.debug(notEnabledError.message);
3318
+ }
3319
+ }
3320
+ await this.chromeAdapter.downloadPromise;
3321
+ }
3228
3322
  /**
3229
3323
  * Makes a single non-streaming call to the model
3230
3324
  * and returns an object containing a single {@link GenerateContentResponse}.