firebase 12.0.0 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/dist/esm/index.esm.js +1 -1
- package/app/dist/index.cjs.js +1 -1
- package/app/dist/index.mjs +1 -1
- package/compat/app/dist/esm/index.esm.js +1 -1
- package/compat/app/dist/index.cjs.js +1 -1
- package/compat/app/dist/index.mjs +1 -1
- package/compat/dist/esm/index.esm.js +2 -2
- package/compat/dist/index.node.cjs +2 -2
- package/compat/dist/index.rn.cjs.js +2 -2
- package/firebase-ai.js +1 -1
- package/firebase-ai.js.map +1 -1
- package/firebase-analytics.js +1 -1
- package/firebase-app-check-compat.js +1 -1
- package/firebase-app-check-compat.js.map +1 -1
- package/firebase-app-check.js +1 -1
- package/firebase-app-check.js.map +1 -1
- package/firebase-app-compat.js +2 -2
- package/firebase-app-compat.js.map +1 -1
- package/firebase-app.js +5 -5
- package/firebase-app.js.map +1 -1
- package/firebase-auth-cordova.js +1 -1
- package/firebase-auth-web-extension.js +1 -1
- package/firebase-auth.js +1 -1
- package/firebase-compat.js +5 -5
- package/firebase-compat.js.map +1 -1
- package/firebase-data-connect.js +1 -1
- package/firebase-database.js +1 -1
- package/firebase-firestore-compat.js +1 -1
- package/firebase-firestore-compat.js.map +1 -1
- package/firebase-firestore-lite.js +1 -1
- package/firebase-firestore.js +1 -1
- package/firebase-firestore.js.map +1 -1
- package/firebase-functions.js +1 -1
- package/firebase-installations.js +1 -1
- package/firebase-messaging-sw.js +1 -1
- package/firebase-messaging.js +1 -1
- package/firebase-performance-compat.js +1 -1
- package/firebase-performance-compat.js.map +1 -1
- package/firebase-performance-standalone-compat.js +15 -15
- package/firebase-performance-standalone-compat.js.map +1 -1
- package/firebase-performance.js +1 -1
- package/firebase-performance.js.map +1 -1
- package/firebase-remote-config.js +1 -1
- package/firebase-storage.js +1 -1
- package/package.json +6 -6
package/firebase-ai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firebase-ai.js","sources":["../util/src/errors.ts","../component/src/component.ts","../logger/src/logger.ts","../ai/src/constants.ts","../ai/src/types/enums.ts","../ai/src/types/error.ts","../ai/src/types/schema.ts","../ai/src/types/imagen/requests.ts","../ai/src/public-types.ts","../ai/src/backend.ts","../ai/src/service.ts","../ai/src/errors.ts","../ai/src/models/ai-model.ts","../ai/src/logger.ts","../ai/src/requests/request.ts","../ai/src/requests/response-helpers.ts","../ai/src/googleai-mappers.ts","../ai/src/requests/stream-reader.ts","../ai/src/methods/generate-content.ts","../ai/src/requests/request-helpers.ts","../ai/src/methods/chat-session-helpers.ts","../ai/src/methods/chat-session.ts","../ai/src/models/generative-model.ts","../ai/src/methods/count-tokens.ts","../ai/src/models/imagen-model.ts","../ai/src/requests/schema-builder.ts","../ai/src/requests/imagen-image-format.ts","../ai/src/api.ts","../util/src/compat.ts","../ai/src/helpers.ts","../ai/src/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // TypeScript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map<Err, string> = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory<Err>('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap<ErrorCode extends string> = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record<string, unknown>\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget\n // which we can now use since we no longer target ES5.\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap<ErrorCode>\n ) {}\n\n create<K extends ErrorCode>(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component<T extends Name = Name> {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback<T> | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory<T>,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback<T>): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../package.json';\n\nexport const AI_TYPE = 'AI';\n\nexport const DEFAULT_LOCATION = 'us-central1';\n\nexport const DEFAULT_BASE_URL = 'https://firebasevertexai.googleapis.com';\n\nexport const DEFAULT_API_VERSION = 'v1beta';\n\nexport const PACKAGE_VERSION = version;\n\nexport const LANGUAGE_TAG = 'gl-js';\n\nexport const DEFAULT_FETCH_TIMEOUT_MS = 180 * 1000;\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Role is the producer of the content.\n * @public\n */\nexport type Role = (typeof POSSIBLE_ROLES)[number];\n\n/**\n * Possible roles.\n * @public\n */\nexport const POSSIBLE_ROLES = ['user', 'model', 'function', 'system'] as const;\n\n/**\n * Harm categories that would cause prompts or candidates to be blocked.\n * @public\n */\nexport const HarmCategory = {\n HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH',\n HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT',\n HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT'\n} as const;\n\n/**\n * Harm categories that would cause prompts or candidates to be blocked.\n * @public\n */\nexport type HarmCategory = (typeof HarmCategory)[keyof typeof HarmCategory];\n\n/**\n * Threshold above which a prompt or candidate will be blocked.\n * @public\n */\nexport const HarmBlockThreshold = {\n /**\n * Content with `NEGLIGIBLE` will be allowed.\n */\n BLOCK_LOW_AND_ABOVE: 'BLOCK_LOW_AND_ABOVE',\n /**\n * Content with `NEGLIGIBLE` and `LOW` will be allowed.\n */\n BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE',\n /**\n * Content with `NEGLIGIBLE`, `LOW`, and `MEDIUM` will be allowed.\n */\n BLOCK_ONLY_HIGH: 'BLOCK_ONLY_HIGH',\n /**\n * All content will be allowed.\n */\n BLOCK_NONE: 'BLOCK_NONE',\n /**\n * All content will be allowed. This is the same as `BLOCK_NONE`, but the metadata corresponding\n * to the {@link HarmCategory} will not be present in the response.\n */\n OFF: 'OFF'\n} as const;\n\n/**\n * Threshold above which a prompt or candidate will be blocked.\n * @public\n */\nexport type HarmBlockThreshold =\n (typeof HarmBlockThreshold)[keyof typeof HarmBlockThreshold];\n\n/**\n * This property is not supported in the Gemini Developer API ({@link GoogleAIBackend}).\n *\n * @public\n */\nexport const HarmBlockMethod = {\n /**\n * The harm block method uses both probability and severity scores.\n */\n SEVERITY: 'SEVERITY',\n /**\n * The harm block method uses the probability score.\n */\n PROBABILITY: 'PROBABILITY'\n} as const;\n\n/**\n * This property is not supported in the Gemini Developer API ({@link GoogleAIBackend}).\n *\n * @public\n */\nexport type HarmBlockMethod =\n (typeof HarmBlockMethod)[keyof typeof HarmBlockMethod];\n\n/**\n * Probability that a prompt or candidate matches a harm category.\n * @public\n */\nexport const HarmProbability = {\n /**\n * Content has a negligible chance of being unsafe.\n */\n NEGLIGIBLE: 'NEGLIGIBLE',\n /**\n * Content has a low chance of being unsafe.\n */\n LOW: 'LOW',\n /**\n * Content has a medium chance of being unsafe.\n */\n MEDIUM: 'MEDIUM',\n /**\n * Content has a high chance of being unsafe.\n */\n HIGH: 'HIGH'\n} as const;\n\n/**\n * Probability that a prompt or candidate matches a harm category.\n * @public\n */\nexport type HarmProbability =\n (typeof HarmProbability)[keyof typeof HarmProbability];\n\n/**\n * Harm severity levels.\n * @public\n */\nexport const HarmSeverity = {\n /**\n * Negligible level of harm severity.\n */\n HARM_SEVERITY_NEGLIGIBLE: 'HARM_SEVERITY_NEGLIGIBLE',\n /**\n * Low level of harm severity.\n */\n HARM_SEVERITY_LOW: 'HARM_SEVERITY_LOW',\n /**\n * Medium level of harm severity.\n */\n HARM_SEVERITY_MEDIUM: 'HARM_SEVERITY_MEDIUM',\n /**\n * High level of harm severity.\n */\n HARM_SEVERITY_HIGH: 'HARM_SEVERITY_HIGH',\n /**\n * Harm severity is not supported.\n *\n * @remarks\n * The GoogleAI backend does not support `HarmSeverity`, so this value is used as a fallback.\n */\n HARM_SEVERITY_UNSUPPORTED: 'HARM_SEVERITY_UNSUPPORTED'\n} as const;\n\n/**\n * Harm severity levels.\n * @public\n */\nexport type HarmSeverity = (typeof HarmSeverity)[keyof typeof HarmSeverity];\n\n/**\n * Reason that a prompt was blocked.\n * @public\n */\nexport const BlockReason = {\n /**\n * Content was blocked by safety settings.\n */\n SAFETY: 'SAFETY',\n /**\n * Content was blocked, but the reason is uncategorized.\n */\n OTHER: 'OTHER',\n /**\n * Content was blocked because it contained terms from the terminology blocklist.\n */\n BLOCKLIST: 'BLOCKLIST',\n /**\n * Content was blocked due to prohibited content.\n */\n PROHIBITED_CONTENT: 'PROHIBITED_CONTENT'\n} as const;\n\n/**\n * Reason that a prompt was blocked.\n * @public\n */\nexport type BlockReason = (typeof BlockReason)[keyof typeof BlockReason];\n\n/**\n * Reason that a candidate finished.\n * @public\n */\nexport const FinishReason = {\n /**\n * Natural stop point of the model or provided stop sequence.\n */\n STOP: 'STOP',\n /**\n * The maximum number of tokens as specified in the request was reached.\n */\n MAX_TOKENS: 'MAX_TOKENS',\n /**\n * The candidate content was flagged for safety reasons.\n */\n SAFETY: 'SAFETY',\n /**\n * The candidate content was flagged for recitation reasons.\n */\n RECITATION: 'RECITATION',\n /**\n * Unknown reason.\n */\n OTHER: 'OTHER',\n /**\n * The candidate content contained forbidden terms.\n */\n BLOCKLIST: 'BLOCKLIST',\n /**\n * The candidate content potentially contained prohibited content.\n */\n PROHIBITED_CONTENT: 'PROHIBITED_CONTENT',\n /**\n * The candidate content potentially contained Sensitive Personally Identifiable Information (SPII).\n */\n SPII: 'SPII',\n /**\n * The function call generated by the model was invalid.\n */\n MALFORMED_FUNCTION_CALL: 'MALFORMED_FUNCTION_CALL'\n} as const;\n\n/**\n * Reason that a candidate finished.\n * @public\n */\nexport type FinishReason = (typeof FinishReason)[keyof typeof FinishReason];\n\n/**\n * @public\n */\nexport const FunctionCallingMode = {\n /**\n * Default model behavior; model decides to predict either a function call\n * or a natural language response.\n */\n AUTO: 'AUTO',\n /**\n * Model is constrained to always predicting a function call only.\n * If `allowed_function_names` is set, the predicted function call will be\n * limited to any one of `allowed_function_names`, else the predicted\n * function call will be any one of the provided `function_declarations`.\n */\n ANY: 'ANY',\n /**\n * Model will not predict any function call. Model behavior is same as when\n * not passing any function declarations.\n */\n NONE: 'NONE'\n} as const;\n\nexport type FunctionCallingMode =\n (typeof FunctionCallingMode)[keyof typeof FunctionCallingMode];\n\n/**\n * Content part modality.\n * @public\n */\nexport const Modality = {\n /**\n * Unspecified modality.\n */\n MODALITY_UNSPECIFIED: 'MODALITY_UNSPECIFIED',\n /**\n * Plain text.\n */\n TEXT: 'TEXT',\n /**\n * Image.\n */\n IMAGE: 'IMAGE',\n /**\n * Video.\n */\n VIDEO: 'VIDEO',\n /**\n * Audio.\n */\n AUDIO: 'AUDIO',\n /**\n * Document (for example, PDF).\n */\n DOCUMENT: 'DOCUMENT'\n} as const;\n\n/**\n * Content part modality.\n * @public\n */\nexport type Modality = (typeof Modality)[keyof typeof Modality];\n\n/**\n * Generation modalities to be returned in generation responses.\n *\n * @beta\n */\nexport const ResponseModality = {\n /**\n * Text.\n * @beta\n */\n TEXT: 'TEXT',\n /**\n * Image.\n * @beta\n */\n IMAGE: 'IMAGE'\n} as const;\n\n/**\n * Generation modalities to be returned in generation responses.\n *\n * @beta\n */\nexport type ResponseModality =\n (typeof ResponseModality)[keyof typeof ResponseModality];\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateContentResponse } from './responses';\n\n/**\n * Details object that may be included in an error response.\n *\n * @public\n */\nexport interface ErrorDetails {\n '@type'?: string;\n\n /** The reason for the error. */\n reason?: string;\n\n /** The domain where the error occurred. */\n domain?: string;\n\n /** Additional metadata about the error. */\n metadata?: Record<string, unknown>;\n\n /** Any other relevant information about the error. */\n [key: string]: unknown;\n}\n\n/**\n * Details object that contains data originating from a bad HTTP response.\n *\n * @public\n */\nexport interface CustomErrorData {\n /** HTTP status code of the error response. */\n status?: number;\n\n /** HTTP status text of the error response. */\n statusText?: string;\n\n /** Response from a {@link GenerateContentRequest} */\n response?: GenerateContentResponse;\n\n /** Optional additional details about the error. */\n errorDetails?: ErrorDetails[];\n}\n\n/**\n * Standardized error codes that {@link AIError} can have.\n *\n * @public\n */\nexport const AIErrorCode = {\n /** A generic error occurred. */\n ERROR: 'error',\n\n /** An error occurred in a request. */\n REQUEST_ERROR: 'request-error',\n\n /** An error occurred in a response. */\n RESPONSE_ERROR: 'response-error',\n\n /** An error occurred while performing a fetch. */\n FETCH_ERROR: 'fetch-error',\n\n /** An error associated with a Content object. */\n INVALID_CONTENT: 'invalid-content',\n\n /** An error due to the Firebase API not being enabled in the Console. */\n API_NOT_ENABLED: 'api-not-enabled',\n\n /** An error due to invalid Schema input. */\n INVALID_SCHEMA: 'invalid-schema',\n\n /** An error occurred due to a missing Firebase API key. */\n NO_API_KEY: 'no-api-key',\n\n /** An error occurred due to a missing Firebase app ID. */\n NO_APP_ID: 'no-app-id',\n\n /** An error occurred due to a model name not being specified during initialization. */\n NO_MODEL: 'no-model',\n\n /** An error occurred due to a missing project ID. */\n NO_PROJECT_ID: 'no-project-id',\n\n /** An error occurred while parsing. */\n PARSE_FAILED: 'parse-failed',\n\n /** An error occurred due an attempt to use an unsupported feature. */\n UNSUPPORTED: 'unsupported'\n} as const;\n\n/**\n * Standardized error codes that {@link AIError} can have.\n *\n * @public\n */\nexport type AIErrorCode = (typeof AIErrorCode)[keyof typeof AIErrorCode];\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Contains the list of OpenAPI data types\n * as defined by the\n * {@link https://swagger.io/docs/specification/data-models/data-types/ | OpenAPI specification}\n * @public\n */\nexport const SchemaType = {\n /** String type. */\n STRING: 'string',\n /** Number type. */\n NUMBER: 'number',\n /** Integer type. */\n INTEGER: 'integer',\n /** Boolean type. */\n BOOLEAN: 'boolean',\n /** Array type. */\n ARRAY: 'array',\n /** Object type. */\n OBJECT: 'object'\n} as const;\n\n/**\n * Contains the list of OpenAPI data types\n * as defined by the\n * {@link https://swagger.io/docs/specification/data-models/data-types/ | OpenAPI specification}\n * @public\n */\nexport type SchemaType = (typeof SchemaType)[keyof typeof SchemaType];\n\n/**\n * Basic {@link Schema} properties shared across several Schema-related\n * types.\n * @public\n */\nexport interface SchemaShared<T> {\n /**\n * An array of {@link Schema}. The generated data must be valid against any of the schemas\n * listed in this array. This allows specifying multiple possible structures or types for a\n * single field.\n */\n anyOf?: T[];\n /** Optional. The format of the property.\n * When using the Gemini Developer API ({@link GoogleAIBackend}), this must be either `'enum'` or\n * `'date-time'`, otherwise requests will fail.\n */\n format?: string;\n /** Optional. The description of the property. */\n description?: string;\n /**\n * The title of the property. This helps document the schema's purpose but does not typically\n * constrain the generated value. It can subtly guide the model by clarifying the intent of a\n * field.\n */\n title?: string;\n /** Optional. The items of the property. */\n items?: T;\n /** The minimum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n minItems?: number;\n /** The maximum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n maxItems?: number;\n /** Optional. Map of `Schema` objects. */\n properties?: {\n [k: string]: T;\n };\n /** A hint suggesting the order in which the keys should appear in the generated JSON string. */\n propertyOrdering?: string[];\n /** Optional. The enum of the property. */\n enum?: string[];\n /** Optional. The example of the property. */\n example?: unknown;\n /** Optional. Whether the property is nullable. */\n nullable?: boolean;\n /** The minimum value of a numeric type. */\n minimum?: number;\n /** The maximum value of a numeric type. */\n maximum?: number;\n [key: string]: unknown;\n}\n\n/**\n * Params passed to {@link Schema} static methods to create specific\n * {@link Schema} classes.\n * @public\n */\nexport interface SchemaParams extends SchemaShared<SchemaInterface> {}\n\n/**\n * Final format for {@link Schema} params passed to backend requests.\n * @public\n */\nexport interface SchemaRequest extends SchemaShared<SchemaRequest> {\n /**\n * The type of the property. this can only be undefined when using `anyOf` schemas,\n * which do not have an explicit type in the {@link https://swagger.io/docs/specification/v3_0/data-models/data-types/#any-type | OpenAPI specification }.\n */\n type?: SchemaType;\n /** Optional. Array of required property. */\n required?: string[];\n}\n\n/**\n * Interface for {@link Schema} class.\n * @public\n */\nexport interface SchemaInterface extends SchemaShared<SchemaInterface> {\n /**\n * The type of the property. this can only be undefined when using `anyof` schemas,\n * which do not have an explicit type in the {@link https://swagger.io/docs/specification/v3_0/data-models/data-types/#any-type | OpenAPI Specification}.\n */\n type?: SchemaType;\n}\n\n/**\n * Interface for JSON parameters in a schema of {@link SchemaType}\n * \"object\" when not using the `Schema.object()` helper.\n * @public\n */\nexport interface ObjectSchemaRequest extends SchemaRequest {\n type: 'object';\n /**\n * This is not a property accepted in the final request to the backend, but is\n * a client-side convenience property that is only usable by constructing\n * a schema through the `Schema.object()` helper method. Populating this\n * property will cause response errors if the object is not wrapped with\n * `Schema.object()`.\n */\n optionalProperties?: never;\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ImagenImageFormat } from '../../requests/imagen-image-format';\n\n/**\n * Parameters for configuring an {@link ImagenModel}.\n *\n * @beta\n */\nexport interface ImagenModelParams {\n /**\n * The Imagen model to use for generating images.\n * For example: `imagen-3.0-generate-002`.\n *\n * Only Imagen 3 models (named `imagen-3.0-*`) are supported.\n *\n * See {@link https://firebase.google.com/docs/vertex-ai/models | model versions}\n * for a full list of supported Imagen 3 models.\n */\n model: string;\n /**\n * Configuration options for generating images with Imagen.\n */\n generationConfig?: ImagenGenerationConfig;\n /**\n * Safety settings for filtering potentially inappropriate content.\n */\n safetySettings?: ImagenSafetySettings;\n}\n\n/**\n * Configuration options for generating images with Imagen.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/generate-images-imagen | documentation} for\n * more details.\n *\n * @beta\n */\nexport interface ImagenGenerationConfig {\n /**\n * A description of what should be omitted from the generated images.\n *\n * Support for negative prompts depends on the Imagen model.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/model-parameters#imagen | documentation} for more details.\n *\n * This is no longer supported in the Gemini Developer API ({@link GoogleAIBackend}) in versions\n * greater than `imagen-3.0-generate-002`.\n */\n negativePrompt?: string;\n /**\n * The number of images to generate. The default value is 1.\n *\n * The number of sample images that may be generated in each request depends on the model\n * (typically up to 4); see the <a href=\"http://firebase.google.com/docs/vertex-ai/model-parameters#imagen\">sampleCount</a>\n * documentation for more details.\n */\n numberOfImages?: number;\n /**\n * The aspect ratio of the generated images. The default value is square 1:1.\n * Supported aspect ratios depend on the Imagen model, see {@link (ImagenAspectRatio:type)}\n * for more details.\n */\n aspectRatio?: ImagenAspectRatio;\n /**\n * The image format of the generated images. The default is PNG.\n *\n * See {@link ImagenImageFormat} for more details.\n */\n imageFormat?: ImagenImageFormat;\n /**\n * Whether to add an invisible watermark to generated images.\n *\n * If set to `true`, an invisible SynthID watermark is embedded in generated images to indicate\n * that they are AI generated. If set to `false`, watermarking will be disabled.\n *\n * For Imagen 3 models, the default value is `true`; see the <a href=\"http://firebase.google.com/docs/vertex-ai/model-parameters#imagen\">addWatermark</a>\n * documentation for more details.\n *\n * When using the Gemini Developer API ({@link GoogleAIBackend}), this will default to true,\n * and cannot be turned off.\n */\n addWatermark?: boolean;\n}\n\n/**\n * A filter level controlling how aggressively to filter sensitive content.\n *\n * Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI\n * are assessed against a list of safety filters, which include 'harmful categories' (for example,\n * `violence`, `sexual`, `derogatory`, and `toxic`). This filter level controls how aggressively to\n * filter out potentially harmful content from responses. See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * and the {@link https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters | Responsible AI and usage guidelines}\n * for more details.\n *\n * @beta\n */\nexport const ImagenSafetyFilterLevel = {\n /**\n * The most aggressive filtering level; most strict blocking.\n */\n BLOCK_LOW_AND_ABOVE: 'block_low_and_above',\n /**\n * Blocks some sensitive prompts and responses.\n */\n BLOCK_MEDIUM_AND_ABOVE: 'block_medium_and_above',\n /**\n * Blocks few sensitive prompts and responses.\n */\n BLOCK_ONLY_HIGH: 'block_only_high',\n /**\n * The least aggressive filtering level; blocks very few sensitive prompts and responses.\n *\n * Access to this feature is restricted and may require your case to be reviewed and approved by\n * Cloud support.\n */\n BLOCK_NONE: 'block_none'\n} as const;\n\n/**\n * A filter level controlling how aggressively to filter sensitive content.\n *\n * Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI\n * are assessed against a list of safety filters, which include 'harmful categories' (for example,\n * `violence`, `sexual`, `derogatory`, and `toxic`). This filter level controls how aggressively to\n * filter out potentially harmful content from responses. See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * and the {@link https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters | Responsible AI and usage guidelines}\n * for more details.\n *\n * @beta\n */\nexport type ImagenSafetyFilterLevel =\n (typeof ImagenSafetyFilterLevel)[keyof typeof ImagenSafetyFilterLevel];\n\n/**\n * A filter level controlling whether generation of images containing people or faces is allowed.\n *\n * See the <a href=\"http://firebase.google.com/docs/vertex-ai/generate-images\">personGeneration</a>\n * documentation for more details.\n *\n * @beta\n */\nexport const ImagenPersonFilterLevel = {\n /**\n * Disallow generation of images containing people or faces; images of people are filtered out.\n */\n BLOCK_ALL: 'dont_allow',\n /**\n * Allow generation of images containing adults only; images of children are filtered out.\n *\n * Generation of images containing people or faces may require your use case to be\n * 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}\n * for more details.\n */\n ALLOW_ADULT: 'allow_adult',\n /**\n * Allow generation of images containing adults only; images of children are filtered out.\n *\n * Generation of images containing people or faces may require your use case to be\n * 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}\n * for more details.\n */\n ALLOW_ALL: 'allow_all'\n} as const;\n\n/**\n * A filter level controlling whether generation of images containing people or faces is allowed.\n *\n * See the <a href=\"http://firebase.google.com/docs/vertex-ai/generate-images\">personGeneration</a>\n * documentation for more details.\n *\n * @beta\n */\nexport type ImagenPersonFilterLevel =\n (typeof ImagenPersonFilterLevel)[keyof typeof ImagenPersonFilterLevel];\n\n/**\n * Settings for controlling the aggressiveness of filtering out sensitive content.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * for more details.\n *\n * @beta\n */\nexport interface ImagenSafetySettings {\n /**\n * A filter level controlling how aggressive to filter out sensitive content from generated\n * images.\n */\n safetyFilterLevel?: ImagenSafetyFilterLevel;\n /**\n * A filter level controlling whether generation of images containing people or faces is allowed.\n */\n personFilterLevel?: ImagenPersonFilterLevel;\n}\n\n/**\n * Aspect ratios for Imagen images.\n *\n * To specify an aspect ratio for generated images, set the `aspectRatio` property in your\n * {@link ImagenGenerationConfig}.\n *\n * See the the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * for more details and examples of the supported aspect ratios.\n *\n * @beta\n */\nexport const ImagenAspectRatio = {\n /**\n * Square (1:1) aspect ratio.\n */\n 'SQUARE': '1:1',\n /**\n * Landscape (3:4) aspect ratio.\n */\n 'LANDSCAPE_3x4': '3:4',\n /**\n * Portrait (4:3) aspect ratio.\n */\n 'PORTRAIT_4x3': '4:3',\n /**\n * Landscape (16:9) aspect ratio.\n */\n 'LANDSCAPE_16x9': '16:9',\n /**\n * Portrait (9:16) aspect ratio.\n */\n 'PORTRAIT_9x16': '9:16'\n} as const;\n\n/**\n * Aspect ratios for Imagen images.\n *\n * To specify an aspect ratio for generated images, set the `aspectRatio` property in your\n * {@link ImagenGenerationConfig}.\n *\n * See the the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * for more details and examples of the supported aspect ratios.\n *\n * @beta\n */\nexport type ImagenAspectRatio =\n (typeof ImagenAspectRatio)[keyof typeof ImagenAspectRatio];\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from '@firebase/app';\nimport { Backend } from './backend';\n\nexport * from './types';\n\n/**\n * An instance of the Firebase AI SDK.\n *\n * Do not create this instance directly. Instead, use {@link getAI | getAI()}.\n *\n * @public\n */\nexport interface AI {\n /**\n * The {@link @firebase/app#FirebaseApp} this {@link AI} instance is associated with.\n */\n app: FirebaseApp;\n /**\n * A {@link Backend} instance that specifies the configuration for the target backend,\n * either the Gemini Developer API (using {@link GoogleAIBackend}) or the\n * Vertex AI Gemini API (using {@link VertexAIBackend}).\n */\n backend: Backend;\n /**\n * @deprecated use `AI.backend.location` instead.\n *\n * The location configured for this AI service instance, relevant for Vertex AI backends.\n */\n location: string;\n}\n\n/**\n * An enum-like object containing constants that represent the supported backends\n * for the Firebase AI SDK.\n * This determines which backend service (Vertex AI Gemini API or Gemini Developer API)\n * the SDK will communicate with.\n *\n * These values are assigned to the `backendType` property within the specific backend\n * configuration objects ({@link GoogleAIBackend} or {@link VertexAIBackend}) to identify\n * which service to target.\n *\n * @public\n */\nexport const BackendType = {\n /**\n * Identifies the backend service for the Vertex AI Gemini API provided through Google Cloud.\n * Use this constant when creating a {@link VertexAIBackend} configuration.\n */\n VERTEX_AI: 'VERTEX_AI',\n\n /**\n * Identifies the backend service for the Gemini Developer API ({@link https://ai.google/ | Google AI}).\n * Use this constant when creating a {@link GoogleAIBackend} configuration.\n */\n GOOGLE_AI: 'GOOGLE_AI'\n} as const; // Using 'as const' makes the string values literal types\n\n/**\n * Type alias representing valid backend types.\n * It can be either `'VERTEX_AI'` or `'GOOGLE_AI'`.\n *\n * @public\n */\nexport type BackendType = (typeof BackendType)[keyof typeof BackendType];\n\n/**\n * Options for initializing the AI service using {@link getAI | getAI()}.\n * This allows specifying which backend to use (Vertex AI Gemini API or Gemini Developer API)\n * and configuring its specific options (like location for Vertex AI).\n *\n * @public\n */\nexport interface AIOptions {\n /**\n * The backend configuration to use for the AI service instance.\n */\n backend: Backend;\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_LOCATION } from './constants';\nimport { BackendType } from './public-types';\n\n/**\n * Abstract base class representing the configuration for an AI service backend.\n * This class should not be instantiated directly. Use its subclasses; {@link GoogleAIBackend} for\n * the Gemini Developer API (via {@link https://ai.google/ | Google AI}), and\n * {@link VertexAIBackend} for the Vertex AI Gemini API.\n *\n * @public\n */\nexport abstract class Backend {\n /**\n * Specifies the backend type.\n */\n readonly backendType: BackendType;\n\n /**\n * Protected constructor for use by subclasses.\n * @param type - The backend type.\n */\n protected constructor(type: BackendType) {\n this.backendType = type;\n }\n}\n\n/**\n * Configuration class for the Gemini Developer API.\n *\n * Use this with {@link AIOptions} when initializing the AI service via\n * {@link getAI | getAI()} to specify the Gemini Developer API as the backend.\n *\n * @public\n */\nexport class GoogleAIBackend extends Backend {\n /**\n * Creates a configuration object for the Gemini Developer API backend.\n */\n constructor() {\n super(BackendType.GOOGLE_AI);\n }\n}\n\n/**\n * Configuration class for the Vertex AI Gemini API.\n *\n * Use this with {@link AIOptions} when initializing the AI service via\n * {@link getAI | getAI()} to specify the Vertex AI Gemini API as the backend.\n *\n * @public\n */\nexport class VertexAIBackend extends Backend {\n /**\n * The region identifier.\n * See {@link https://firebase.google.com/docs/vertex-ai/locations#available-locations | Vertex AI locations}\n * for a list of supported locations.\n */\n readonly location: string;\n\n /**\n * Creates a configuration object for the Vertex AI backend.\n *\n * @param location - The region identifier, defaulting to `us-central1`;\n * see {@link https://firebase.google.com/docs/vertex-ai/locations#available-locations | Vertex AI locations}\n * for a list of supported locations.\n */\n constructor(location: string = DEFAULT_LOCATION) {\n super(BackendType.VERTEX_AI);\n if (!location) {\n this.location = DEFAULT_LOCATION;\n } else {\n this.location = location;\n }\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _FirebaseService } from '@firebase/app';\nimport { AI } from './public-types';\nimport {\n AppCheckInternalComponentName,\n FirebaseAppCheckInternal\n} from '@firebase/app-check-interop-types';\nimport { Provider } from '@firebase/component';\nimport {\n FirebaseAuthInternal,\n FirebaseAuthInternalName\n} from '@firebase/auth-interop-types';\nimport { Backend, VertexAIBackend } from './backend';\n\nexport class AIService implements AI, _FirebaseService {\n auth: FirebaseAuthInternal | null;\n appCheck: FirebaseAppCheckInternal | null;\n location: string; // This is here for backwards-compatibility\n\n constructor(\n public app: FirebaseApp,\n public backend: Backend,\n authProvider?: Provider<FirebaseAuthInternalName>,\n appCheckProvider?: Provider<AppCheckInternalComponentName>\n ) {\n const appCheck = appCheckProvider?.getImmediate({ optional: true });\n const auth = authProvider?.getImmediate({ optional: true });\n this.auth = auth || null;\n this.appCheck = appCheck || null;\n\n if (backend instanceof VertexAIBackend) {\n this.location = backend.location;\n } else {\n this.location = '';\n }\n }\n\n _delete(): Promise<void> {\n return Promise.resolve();\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { AIErrorCode, CustomErrorData } from './types';\nimport { AI_TYPE } from './constants';\n\n/**\n * Error class for the Firebase AI SDK.\n *\n * @public\n */\nexport class AIError extends FirebaseError {\n /**\n * Constructs a new instance of the `AIError` class.\n *\n * @param code - The error code from {@link (AIErrorCode:type)}.\n * @param message - A human-readable message describing the error.\n * @param customErrorData - Optional error data.\n */\n constructor(\n readonly code: AIErrorCode,\n message: string,\n readonly customErrorData?: CustomErrorData\n ) {\n // Match error format used by FirebaseError from ErrorFactory\n const service = AI_TYPE;\n const fullCode = `${service}/${code}`;\n const fullMessage = `${service}: ${message} (${fullCode})`;\n super(code, fullMessage);\n\n // FirebaseError initializes a stack trace, but it assumes the error is created from the error\n // factory. Since we break this assumption, we set the stack trace to be originating from this\n // constructor.\n // This is only supported in V8.\n if (Error.captureStackTrace) {\n // Allows us to initialize the stack trace without including the constructor itself at the\n // top level of the stack trace.\n Error.captureStackTrace(this, AIError);\n }\n\n // Allows instanceof AIError in ES5/ES6\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget\n // which we can now use since we no longer target ES5.\n Object.setPrototypeOf(this, AIError.prototype);\n\n // Since Error is an interface, we don't inherit toString and so we define it ourselves.\n this.toString = () => fullMessage;\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from '../errors';\nimport { AIErrorCode, AI, BackendType } from '../public-types';\nimport { AIService } from '../service';\nimport { ApiSettings } from '../types/internal';\nimport { _isFirebaseServerApp } from '@firebase/app';\n\n/**\n * Base class for Firebase AI model APIs.\n *\n * Instances of this class are associated with a specific Firebase AI {@link Backend}\n * and provide methods for interacting with the configured generative model.\n *\n * @public\n */\nexport abstract class AIModel {\n /**\n * The fully qualified model resource name to use for generating images\n * (for example, `publishers/google/models/imagen-3.0-generate-002`).\n */\n readonly model: string;\n\n /**\n * @internal\n */\n protected _apiSettings: ApiSettings;\n\n /**\n * Constructs a new instance of the {@link AIModel} class.\n *\n * This constructor should only be called from subclasses that provide\n * a model API.\n *\n * @param ai - an {@link AI} instance.\n * @param modelName - The name of the model being used. It can be in one of the following formats:\n * - `my-model` (short name, will resolve to `publishers/google/models/my-model`)\n * - `models/my-model` (will resolve to `publishers/google/models/my-model`)\n * - `publishers/my-publisher/models/my-model` (fully qualified model name)\n *\n * @throws If the `apiKey` or `projectId` fields are missing in your\n * Firebase config.\n *\n * @internal\n */\n protected constructor(ai: AI, modelName: string) {\n if (!ai.app?.options?.apiKey) {\n throw new AIError(\n AIErrorCode.NO_API_KEY,\n `The \"apiKey\" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid API key.`\n );\n } else if (!ai.app?.options?.projectId) {\n throw new AIError(\n AIErrorCode.NO_PROJECT_ID,\n `The \"projectId\" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid project ID.`\n );\n } else if (!ai.app?.options?.appId) {\n throw new AIError(\n AIErrorCode.NO_APP_ID,\n `The \"appId\" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid app ID.`\n );\n } else {\n this._apiSettings = {\n apiKey: ai.app.options.apiKey,\n project: ai.app.options.projectId,\n appId: ai.app.options.appId,\n automaticDataCollectionEnabled: ai.app.automaticDataCollectionEnabled,\n location: ai.location,\n backend: ai.backend\n };\n\n if (_isFirebaseServerApp(ai.app) && ai.app.settings.appCheckToken) {\n const token = ai.app.settings.appCheckToken;\n this._apiSettings.getAppCheckToken = () => {\n return Promise.resolve({ token });\n };\n } else if ((ai as AIService).appCheck) {\n this._apiSettings.getAppCheckToken = () =>\n (ai as AIService).appCheck!.getToken();\n }\n\n if ((ai as AIService).auth) {\n this._apiSettings.getAuthToken = () =>\n (ai as AIService).auth!.getToken();\n }\n\n this.model = AIModel.normalizeModelName(\n modelName,\n this._apiSettings.backend.backendType\n );\n }\n }\n\n /**\n * Normalizes the given model name to a fully qualified model resource name.\n *\n * @param modelName - The model name to normalize.\n * @returns The fully qualified model resource name.\n *\n * @internal\n */\n static normalizeModelName(\n modelName: string,\n backendType: BackendType\n ): string {\n if (backendType === BackendType.GOOGLE_AI) {\n return AIModel.normalizeGoogleAIModelName(modelName);\n } else {\n return AIModel.normalizeVertexAIModelName(modelName);\n }\n }\n\n /**\n * @internal\n */\n private static normalizeGoogleAIModelName(modelName: string): string {\n return `models/${modelName}`;\n }\n\n /**\n * @internal\n */\n private static normalizeVertexAIModelName(modelName: string): string {\n let model: string;\n if (modelName.includes('/')) {\n if (modelName.startsWith('models/')) {\n // Add 'publishers/google' if the user is only passing in 'models/model-name'.\n model = `publishers/google/${modelName}`;\n } else {\n // Any other custom format (e.g. tuned models) must be passed in correctly.\n model = modelName;\n }\n } else {\n // If path is not included, assume it's a non-tuned model.\n model = `publishers/google/models/${modelName}`;\n }\n\n return model;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/vertexai');\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorDetails, RequestOptions, AIErrorCode } from '../types';\nimport { AIError } from '../errors';\nimport { ApiSettings } from '../types/internal';\nimport {\n DEFAULT_API_VERSION,\n DEFAULT_BASE_URL,\n DEFAULT_FETCH_TIMEOUT_MS,\n LANGUAGE_TAG,\n PACKAGE_VERSION\n} from '../constants';\nimport { logger } from '../logger';\nimport { GoogleAIBackend, VertexAIBackend } from '../backend';\n\nexport enum Task {\n GENERATE_CONTENT = 'generateContent',\n STREAM_GENERATE_CONTENT = 'streamGenerateContent',\n COUNT_TOKENS = 'countTokens',\n PREDICT = 'predict'\n}\n\nexport class RequestUrl {\n constructor(\n public model: string,\n public task: Task,\n public apiSettings: ApiSettings,\n public stream: boolean,\n public requestOptions?: RequestOptions\n ) {}\n toString(): string {\n const url = new URL(this.baseUrl); // Throws if the URL is invalid\n url.pathname = `/${this.apiVersion}/${this.modelPath}:${this.task}`;\n url.search = this.queryParams.toString();\n return url.toString();\n }\n\n private get baseUrl(): string {\n return this.requestOptions?.baseUrl || DEFAULT_BASE_URL;\n }\n\n private get apiVersion(): string {\n return DEFAULT_API_VERSION; // TODO: allow user-set options if that feature becomes available\n }\n\n private get modelPath(): string {\n if (this.apiSettings.backend instanceof GoogleAIBackend) {\n return `projects/${this.apiSettings.project}/${this.model}`;\n } else if (this.apiSettings.backend instanceof VertexAIBackend) {\n return `projects/${this.apiSettings.project}/locations/${this.apiSettings.backend.location}/${this.model}`;\n } else {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid backend: ${JSON.stringify(this.apiSettings.backend)}`\n );\n }\n }\n\n private get queryParams(): URLSearchParams {\n const params = new URLSearchParams();\n if (this.stream) {\n params.set('alt', 'sse');\n }\n\n return params;\n }\n}\n\n/**\n * Log language and \"fire/version\" to x-goog-api-client\n */\nfunction getClientHeaders(): string {\n const loggingTags = [];\n loggingTags.push(`${LANGUAGE_TAG}/${PACKAGE_VERSION}`);\n loggingTags.push(`fire/${PACKAGE_VERSION}`);\n return loggingTags.join(' ');\n}\n\nexport async function getHeaders(url: RequestUrl): Promise<Headers> {\n const headers = new Headers();\n headers.append('Content-Type', 'application/json');\n headers.append('x-goog-api-client', getClientHeaders());\n headers.append('x-goog-api-key', url.apiSettings.apiKey);\n if (url.apiSettings.automaticDataCollectionEnabled) {\n headers.append('X-Firebase-Appid', url.apiSettings.appId);\n }\n if (url.apiSettings.getAppCheckToken) {\n const appCheckToken = await url.apiSettings.getAppCheckToken();\n if (appCheckToken) {\n headers.append('X-Firebase-AppCheck', appCheckToken.token);\n if (appCheckToken.error) {\n logger.warn(\n `Unable to obtain a valid App Check token: ${appCheckToken.error.message}`\n );\n }\n }\n }\n\n if (url.apiSettings.getAuthToken) {\n const authToken = await url.apiSettings.getAuthToken();\n if (authToken) {\n headers.append('Authorization', `Firebase ${authToken.accessToken}`);\n }\n }\n\n return headers;\n}\n\nexport async function constructRequest(\n model: string,\n task: Task,\n apiSettings: ApiSettings,\n stream: boolean,\n body: string,\n requestOptions?: RequestOptions\n): Promise<{ url: string; fetchOptions: RequestInit }> {\n const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);\n return {\n url: url.toString(),\n fetchOptions: {\n method: 'POST',\n headers: await getHeaders(url),\n body\n }\n };\n}\n\nexport async function makeRequest(\n model: string,\n task: Task,\n apiSettings: ApiSettings,\n stream: boolean,\n body: string,\n requestOptions?: RequestOptions\n): Promise<Response> {\n const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);\n let response;\n let fetchTimeoutId: string | number | NodeJS.Timeout | undefined;\n try {\n const request = await constructRequest(\n model,\n task,\n apiSettings,\n stream,\n body,\n requestOptions\n );\n // Timeout is 180s by default\n const timeoutMillis =\n requestOptions?.timeout != null && requestOptions.timeout >= 0\n ? requestOptions.timeout\n : DEFAULT_FETCH_TIMEOUT_MS;\n const abortController = new AbortController();\n fetchTimeoutId = setTimeout(() => abortController.abort(), timeoutMillis);\n request.fetchOptions.signal = abortController.signal;\n\n response = await fetch(request.url, request.fetchOptions);\n if (!response.ok) {\n let message = '';\n let errorDetails;\n try {\n const json = await response.json();\n message = json.error.message;\n if (json.error.details) {\n message += ` ${JSON.stringify(json.error.details)}`;\n errorDetails = json.error.details;\n }\n } catch (e) {\n // ignored\n }\n if (\n response.status === 403 &&\n errorDetails &&\n errorDetails.some(\n (detail: ErrorDetails) => detail.reason === 'SERVICE_DISABLED'\n ) &&\n errorDetails.some((detail: ErrorDetails) =>\n (\n detail.links as Array<Record<string, string>>\n )?.[0]?.description.includes(\n 'Google developers console API activation'\n )\n )\n ) {\n throw new AIError(\n AIErrorCode.API_NOT_ENABLED,\n `The Firebase AI SDK requires the Firebase AI ` +\n `API ('firebasevertexai.googleapis.com') to be enabled in your ` +\n `Firebase project. Enable this API by visiting the Firebase Console ` +\n `at https://console.firebase.google.com/project/${url.apiSettings.project}/genai/ ` +\n `and clicking \"Get started\". If you enabled this API recently, ` +\n `wait a few minutes for the action to propagate to our systems and ` +\n `then retry.`,\n {\n status: response.status,\n statusText: response.statusText,\n errorDetails\n }\n );\n }\n throw new AIError(\n AIErrorCode.FETCH_ERROR,\n `Error fetching from ${url}: [${response.status} ${response.statusText}] ${message}`,\n {\n status: response.status,\n statusText: response.statusText,\n errorDetails\n }\n );\n }\n } catch (e) {\n let err = e as Error;\n if (\n (e as AIError).code !== AIErrorCode.FETCH_ERROR &&\n (e as AIError).code !== AIErrorCode.API_NOT_ENABLED &&\n e instanceof Error\n ) {\n err = new AIError(\n AIErrorCode.ERROR,\n `Error fetching from ${url.toString()}: ${e.message}`\n );\n err.stack = e.stack;\n }\n\n throw err;\n } finally {\n if (fetchTimeoutId) {\n clearTimeout(fetchTimeoutId);\n }\n }\n return response;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EnhancedGenerateContentResponse,\n FinishReason,\n FunctionCall,\n GenerateContentCandidate,\n GenerateContentResponse,\n ImagenGCSImage,\n ImagenInlineImage,\n AIErrorCode,\n InlineDataPart\n} from '../types';\nimport { AIError } from '../errors';\nimport { logger } from '../logger';\nimport { ImagenResponseInternal } from '../types/internal';\n\n/**\n * Creates an EnhancedGenerateContentResponse object that has helper functions and\n * other modifications that improve usability.\n */\nexport function createEnhancedContentResponse(\n response: GenerateContentResponse\n): EnhancedGenerateContentResponse {\n /**\n * The Vertex AI backend omits default values.\n * This causes the `index` property to be omitted from the first candidate in the\n * response, since it has index 0, and 0 is a default value.\n * See: https://github.com/firebase/firebase-js-sdk/issues/8566\n */\n if (response.candidates && !response.candidates[0].hasOwnProperty('index')) {\n response.candidates[0].index = 0;\n }\n\n const responseWithHelpers = addHelpers(response);\n return responseWithHelpers;\n}\n\n/**\n * Adds convenience helper methods to a response object, including stream\n * chunks (as long as each chunk is a complete GenerateContentResponse JSON).\n */\nexport function addHelpers(\n response: GenerateContentResponse\n): EnhancedGenerateContentResponse {\n (response as EnhancedGenerateContentResponse).text = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n logger.warn(\n `This response had ${response.candidates.length} ` +\n `candidates. Returning text from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`\n );\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Response error: ${formatBlockErrorMessage(\n response\n )}. Response body stored in error.response`,\n {\n response\n }\n );\n }\n return getText(response);\n } else if (response.promptFeedback) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Text not available. ${formatBlockErrorMessage(response)}`,\n {\n response\n }\n );\n }\n return '';\n };\n (response as EnhancedGenerateContentResponse).inlineDataParts = ():\n | InlineDataPart[]\n | undefined => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n logger.warn(\n `This response had ${response.candidates.length} ` +\n `candidates. Returning data from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`\n );\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Response error: ${formatBlockErrorMessage(\n response\n )}. Response body stored in error.response`,\n {\n response\n }\n );\n }\n return getInlineDataParts(response);\n } else if (response.promptFeedback) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Data not available. ${formatBlockErrorMessage(response)}`,\n {\n response\n }\n );\n }\n return undefined;\n };\n (response as EnhancedGenerateContentResponse).functionCalls = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n logger.warn(\n `This response had ${response.candidates.length} ` +\n `candidates. Returning function calls from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`\n );\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Response error: ${formatBlockErrorMessage(\n response\n )}. Response body stored in error.response`,\n {\n response\n }\n );\n }\n return getFunctionCalls(response);\n } else if (response.promptFeedback) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Function call not available. ${formatBlockErrorMessage(response)}`,\n {\n response\n }\n );\n }\n return undefined;\n };\n return response as EnhancedGenerateContentResponse;\n}\n\n/**\n * Returns all text found in all parts of first candidate.\n */\nexport function getText(response: GenerateContentResponse): string {\n const textStrings = [];\n if (response.candidates?.[0].content?.parts) {\n for (const part of response.candidates?.[0].content?.parts) {\n if (part.text) {\n textStrings.push(part.text);\n }\n }\n }\n if (textStrings.length > 0) {\n return textStrings.join('');\n } else {\n return '';\n }\n}\n\n/**\n * Returns {@link FunctionCall}s associated with first candidate.\n */\nexport function getFunctionCalls(\n response: GenerateContentResponse\n): FunctionCall[] | undefined {\n const functionCalls: FunctionCall[] = [];\n if (response.candidates?.[0].content?.parts) {\n for (const part of response.candidates?.[0].content?.parts) {\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n }\n if (functionCalls.length > 0) {\n return functionCalls;\n } else {\n return undefined;\n }\n}\n\n/**\n * Returns {@link InlineDataPart}s in the first candidate if present.\n *\n * @internal\n */\nexport function getInlineDataParts(\n response: GenerateContentResponse\n): InlineDataPart[] | undefined {\n const data: InlineDataPart[] = [];\n\n if (response.candidates?.[0].content?.parts) {\n for (const part of response.candidates?.[0].content?.parts) {\n if (part.inlineData) {\n data.push(part);\n }\n }\n }\n\n if (data.length > 0) {\n return data;\n } else {\n return undefined;\n }\n}\n\nconst badFinishReasons = [FinishReason.RECITATION, FinishReason.SAFETY];\n\nfunction hadBadFinishReason(candidate: GenerateContentCandidate): boolean {\n return (\n !!candidate.finishReason &&\n badFinishReasons.some(reason => reason === candidate.finishReason)\n );\n}\n\nexport function formatBlockErrorMessage(\n response: GenerateContentResponse\n): string {\n let message = '';\n if (\n (!response.candidates || response.candidates.length === 0) &&\n response.promptFeedback\n ) {\n message += 'Response was blocked';\n if (response.promptFeedback?.blockReason) {\n message += ` due to ${response.promptFeedback.blockReason}`;\n }\n if (response.promptFeedback?.blockReasonMessage) {\n message += `: ${response.promptFeedback.blockReasonMessage}`;\n }\n } else if (response.candidates?.[0]) {\n const firstCandidate = response.candidates[0];\n if (hadBadFinishReason(firstCandidate)) {\n message += `Candidate was blocked due to ${firstCandidate.finishReason}`;\n if (firstCandidate.finishMessage) {\n message += `: ${firstCandidate.finishMessage}`;\n }\n }\n }\n return message;\n}\n\n/**\n * Convert a generic successful fetch response body to an Imagen response object\n * that can be returned to the user. This converts the REST APIs response format to our\n * APIs representation of a response.\n *\n * @internal\n */\nexport async function handlePredictResponse<\n T extends ImagenInlineImage | ImagenGCSImage\n>(response: Response): Promise<{ images: T[]; filteredReason?: string }> {\n const responseJson: ImagenResponseInternal = await response.json();\n\n const images: T[] = [];\n let filteredReason: string | undefined = undefined;\n\n // The backend should always send a non-empty array of predictions if the response was successful.\n if (!responseJson.predictions || responseJson.predictions?.length === 0) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n '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.'\n );\n }\n\n for (const prediction of responseJson.predictions) {\n if (prediction.raiFilteredReason) {\n filteredReason = prediction.raiFilteredReason;\n } else if (prediction.mimeType && prediction.bytesBase64Encoded) {\n images.push({\n mimeType: prediction.mimeType,\n bytesBase64Encoded: prediction.bytesBase64Encoded\n } as T);\n } else if (prediction.mimeType && prediction.gcsUri) {\n images.push({\n mimeType: prediction.mimeType,\n gcsURI: prediction.gcsUri\n } as T);\n } else {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Predictions array in response has missing properties. Response: ${JSON.stringify(\n responseJson\n )}`\n );\n }\n }\n\n return { images, filteredReason };\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from './errors';\nimport { logger } from './logger';\nimport {\n CitationMetadata,\n CountTokensRequest,\n GenerateContentCandidate,\n GenerateContentRequest,\n GenerateContentResponse,\n HarmSeverity,\n InlineDataPart,\n PromptFeedback,\n SafetyRating,\n AIErrorCode\n} from './types';\nimport {\n GoogleAIGenerateContentResponse,\n GoogleAIGenerateContentCandidate,\n GoogleAICountTokensRequest\n} from './types/googleai';\n\n/**\n * This SDK supports both the Vertex AI Gemini API and the Gemini Developer API (using Google AI).\n * The public API prioritizes the format used by the Vertex AI Gemini API.\n * We avoid having two sets of types by translating requests and responses between the two API formats.\n * This translation allows developers to switch between the Vertex AI Gemini API and the Gemini Developer API\n * with minimal code changes.\n *\n * In here are functions that map requests and responses between the two API formats.\n * Requests in the Vertex AI format are mapped to the Google AI format before being sent.\n * Responses from the Google AI backend are mapped back to the Vertex AI format before being returned to the user.\n */\n\n/**\n * Maps a Vertex AI {@link GenerateContentRequest} to a format that can be sent to Google AI.\n *\n * @param generateContentRequest The {@link GenerateContentRequest} to map.\n * @returns A {@link GenerateContentResponse} that conforms to the Google AI format.\n *\n * @throws If the request contains properties that are unsupported by Google AI.\n *\n * @internal\n */\nexport function mapGenerateContentRequest(\n generateContentRequest: GenerateContentRequest\n): GenerateContentRequest {\n generateContentRequest.safetySettings?.forEach(safetySetting => {\n if (safetySetting.method) {\n throw new AIError(\n AIErrorCode.UNSUPPORTED,\n 'SafetySetting.method is not supported in the the Gemini Developer API. Please remove this property.'\n );\n }\n });\n\n if (generateContentRequest.generationConfig?.topK) {\n const roundedTopK = Math.round(\n generateContentRequest.generationConfig.topK\n );\n\n if (roundedTopK !== generateContentRequest.generationConfig.topK) {\n logger.warn(\n 'topK in GenerationConfig has been rounded to the nearest integer to match the format for requests to the Gemini Developer API.'\n );\n generateContentRequest.generationConfig.topK = roundedTopK;\n }\n }\n\n return generateContentRequest;\n}\n\n/**\n * Maps a {@link GenerateContentResponse} from Google AI to the format of the\n * {@link GenerateContentResponse} that we get from VertexAI that is exposed in the public API.\n *\n * @param googleAIResponse The {@link GenerateContentResponse} from Google AI.\n * @returns A {@link GenerateContentResponse} that conforms to the public API's format.\n *\n * @internal\n */\nexport function mapGenerateContentResponse(\n googleAIResponse: GoogleAIGenerateContentResponse\n): GenerateContentResponse {\n const generateContentResponse = {\n candidates: googleAIResponse.candidates\n ? mapGenerateContentCandidates(googleAIResponse.candidates)\n : undefined,\n prompt: googleAIResponse.promptFeedback\n ? mapPromptFeedback(googleAIResponse.promptFeedback)\n : undefined,\n usageMetadata: googleAIResponse.usageMetadata\n };\n\n return generateContentResponse;\n}\n\n/**\n * Maps a Vertex AI {@link CountTokensRequest} to a format that can be sent to Google AI.\n *\n * @param countTokensRequest The {@link CountTokensRequest} to map.\n * @param model The model to count tokens with.\n * @returns A {@link CountTokensRequest} that conforms to the Google AI format.\n *\n * @internal\n */\nexport function mapCountTokensRequest(\n countTokensRequest: CountTokensRequest,\n model: string\n): GoogleAICountTokensRequest {\n const mappedCountTokensRequest: GoogleAICountTokensRequest = {\n generateContentRequest: {\n model,\n ...countTokensRequest\n }\n };\n\n return mappedCountTokensRequest;\n}\n\n/**\n * Maps a Google AI {@link GoogleAIGenerateContentCandidate} to a format that conforms\n * to the Vertex AI API format.\n *\n * @param candidates The {@link GoogleAIGenerateContentCandidate} to map.\n * @returns A {@link GenerateContentCandidate} that conforms to the Vertex AI format.\n *\n * @throws If any {@link Part} in the candidates has a `videoMetadata` property.\n *\n * @internal\n */\nexport function mapGenerateContentCandidates(\n candidates: GoogleAIGenerateContentCandidate[]\n): GenerateContentCandidate[] {\n const mappedCandidates: GenerateContentCandidate[] = [];\n let mappedSafetyRatings: SafetyRating[];\n if (mappedCandidates) {\n candidates.forEach(candidate => {\n // Map citationSources to citations.\n let citationMetadata: CitationMetadata | undefined;\n if (candidate.citationMetadata) {\n citationMetadata = {\n citations: candidate.citationMetadata.citationSources\n };\n }\n\n // Assign missing candidate SafetyRatings properties to their defaults if undefined.\n if (candidate.safetyRatings) {\n mappedSafetyRatings = candidate.safetyRatings.map(safetyRating => {\n return {\n ...safetyRating,\n severity:\n safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,\n probabilityScore: safetyRating.probabilityScore ?? 0,\n severityScore: safetyRating.severityScore ?? 0\n };\n });\n }\n\n // videoMetadata is not supported.\n // Throw early since developers may send a long video as input and only expect to pay\n // for inference on a small portion of the video.\n if (\n candidate.content?.parts.some(\n part => (part as InlineDataPart)?.videoMetadata\n )\n ) {\n throw new AIError(\n AIErrorCode.UNSUPPORTED,\n 'Part.videoMetadata is not supported in the Gemini Developer API. Please remove this property.'\n );\n }\n\n const mappedCandidate = {\n index: candidate.index,\n content: candidate.content,\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n safetyRatings: mappedSafetyRatings,\n citationMetadata,\n groundingMetadata: candidate.groundingMetadata\n };\n mappedCandidates.push(mappedCandidate);\n });\n }\n\n return mappedCandidates;\n}\n\nexport function mapPromptFeedback(\n promptFeedback: PromptFeedback\n): PromptFeedback {\n // Assign missing SafetyRating properties to their defaults if undefined.\n const mappedSafetyRatings: SafetyRating[] = [];\n promptFeedback.safetyRatings.forEach(safetyRating => {\n mappedSafetyRatings.push({\n category: safetyRating.category,\n probability: safetyRating.probability,\n severity: safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,\n probabilityScore: safetyRating.probabilityScore ?? 0,\n severityScore: safetyRating.severityScore ?? 0,\n blocked: safetyRating.blocked\n });\n });\n\n const mappedPromptFeedback: PromptFeedback = {\n blockReason: promptFeedback.blockReason,\n safetyRatings: mappedSafetyRatings,\n blockReasonMessage: promptFeedback.blockReasonMessage\n };\n return mappedPromptFeedback;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EnhancedGenerateContentResponse,\n GenerateContentCandidate,\n GenerateContentResponse,\n GenerateContentStreamResult,\n Part,\n AIErrorCode\n} from '../types';\nimport { AIError } from '../errors';\nimport { createEnhancedContentResponse } from './response-helpers';\nimport * as GoogleAIMapper from '../googleai-mappers';\nimport { GoogleAIGenerateContentResponse } from '../types/googleai';\nimport { ApiSettings } from '../types/internal';\nimport { BackendType } from '../public-types';\n\nconst responseLineRE = /^data\\: (.*)(?:\\n\\n|\\r\\r|\\r\\n\\r\\n)/;\n\n/**\n * Process a response.body stream from the backend and return an\n * iterator that provides one complete GenerateContentResponse at a time\n * and a promise that resolves with a single aggregated\n * GenerateContentResponse.\n *\n * @param response - Response from a fetch call\n */\nexport function processStream(\n response: Response,\n apiSettings: ApiSettings\n): GenerateContentStreamResult {\n const inputStream = response.body!.pipeThrough(\n new TextDecoderStream('utf8', { fatal: true })\n );\n const responseStream =\n getResponseStream<GenerateContentResponse>(inputStream);\n const [stream1, stream2] = responseStream.tee();\n return {\n stream: generateResponseSequence(stream1, apiSettings),\n response: getResponsePromise(stream2, apiSettings)\n };\n}\n\nasync function getResponsePromise(\n stream: ReadableStream<GenerateContentResponse>,\n apiSettings: ApiSettings\n): Promise<EnhancedGenerateContentResponse> {\n const allResponses: GenerateContentResponse[] = [];\n const reader = stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n let generateContentResponse = aggregateResponses(allResponses);\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n generateContentResponse = GoogleAIMapper.mapGenerateContentResponse(\n generateContentResponse as GoogleAIGenerateContentResponse\n );\n }\n return createEnhancedContentResponse(generateContentResponse);\n }\n\n allResponses.push(value);\n }\n}\n\nasync function* generateResponseSequence(\n stream: ReadableStream<GenerateContentResponse>,\n apiSettings: ApiSettings\n): AsyncGenerator<EnhancedGenerateContentResponse> {\n const reader = stream.getReader();\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n break;\n }\n\n let enhancedResponse: EnhancedGenerateContentResponse;\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n enhancedResponse = createEnhancedContentResponse(\n GoogleAIMapper.mapGenerateContentResponse(\n value as GoogleAIGenerateContentResponse\n )\n );\n } else {\n enhancedResponse = createEnhancedContentResponse(value);\n }\n\n yield enhancedResponse;\n }\n}\n\n/**\n * Reads a raw stream from the fetch response and join incomplete\n * chunks, returning a new stream that provides a single complete\n * GenerateContentResponse in each iteration.\n */\nexport function getResponseStream<T>(\n inputStream: ReadableStream<string>\n): ReadableStream<T> {\n const reader = inputStream.getReader();\n const stream = new ReadableStream<T>({\n start(controller) {\n let currentText = '';\n return pump();\n function pump(): Promise<(() => Promise<void>) | undefined> {\n return reader.read().then(({ value, done }) => {\n if (done) {\n if (currentText.trim()) {\n controller.error(\n new AIError(AIErrorCode.PARSE_FAILED, 'Failed to parse stream')\n );\n return;\n }\n controller.close();\n return;\n }\n\n currentText += value;\n let match = currentText.match(responseLineRE);\n let parsedResponse: T;\n while (match) {\n try {\n parsedResponse = JSON.parse(match[1]);\n } catch (e) {\n controller.error(\n new AIError(\n AIErrorCode.PARSE_FAILED,\n `Error parsing JSON response: \"${match[1]}`\n )\n );\n return;\n }\n controller.enqueue(parsedResponse);\n currentText = currentText.substring(match[0].length);\n match = currentText.match(responseLineRE);\n }\n return pump();\n });\n }\n }\n });\n return stream;\n}\n\n/**\n * Aggregates an array of `GenerateContentResponse`s into a single\n * GenerateContentResponse.\n */\nexport function aggregateResponses(\n responses: GenerateContentResponse[]\n): GenerateContentResponse {\n const lastResponse = responses[responses.length - 1];\n const aggregatedResponse: GenerateContentResponse = {\n promptFeedback: lastResponse?.promptFeedback\n };\n for (const response of responses) {\n if (response.candidates) {\n for (const candidate of response.candidates) {\n // Index will be undefined if it's the first index (0), so we should use 0 if it's undefined.\n // See: https://github.com/firebase/firebase-js-sdk/issues/8566\n const i = candidate.index || 0;\n if (!aggregatedResponse.candidates) {\n aggregatedResponse.candidates = [];\n }\n if (!aggregatedResponse.candidates[i]) {\n aggregatedResponse.candidates[i] = {\n index: candidate.index\n } as GenerateContentCandidate;\n }\n // Keep overwriting, the last one will be final\n aggregatedResponse.candidates[i].citationMetadata =\n candidate.citationMetadata;\n aggregatedResponse.candidates[i].finishReason = candidate.finishReason;\n aggregatedResponse.candidates[i].finishMessage =\n candidate.finishMessage;\n aggregatedResponse.candidates[i].safetyRatings =\n candidate.safetyRatings;\n aggregatedResponse.candidates[i].groundingMetadata =\n candidate.groundingMetadata;\n\n /**\n * Candidates should always have content and parts, but this handles\n * possible malformed responses.\n */\n if (candidate.content && candidate.content.parts) {\n if (!aggregatedResponse.candidates[i].content) {\n aggregatedResponse.candidates[i].content = {\n role: candidate.content.role || 'user',\n parts: []\n };\n }\n const newPart: Partial<Part> = {};\n for (const part of candidate.content.parts) {\n if (part.text !== undefined) {\n // The backend can send empty text parts. If these are sent back\n // (e.g. in chat history), the backend will respond with an error.\n // To prevent this, ignore empty text parts.\n if (part.text === '') {\n continue;\n }\n newPart.text = part.text;\n }\n if (part.functionCall) {\n newPart.functionCall = part.functionCall;\n }\n if (Object.keys(newPart).length === 0) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n 'Part should have at least one property, but there are none. This is likely caused ' +\n 'by a malformed response from the backend.'\n );\n }\n aggregatedResponse.candidates[i].content.parts.push(\n newPart as Part\n );\n }\n }\n }\n }\n }\n return aggregatedResponse;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GenerateContentRequest,\n GenerateContentResponse,\n GenerateContentResult,\n GenerateContentStreamResult,\n RequestOptions\n} from '../types';\nimport { Task, makeRequest } from '../requests/request';\nimport { createEnhancedContentResponse } from '../requests/response-helpers';\nimport { processStream } from '../requests/stream-reader';\nimport { ApiSettings } from '../types/internal';\nimport * as GoogleAIMapper from '../googleai-mappers';\nimport { BackendType } from '../public-types';\n\nexport async function generateContentStream(\n apiSettings: ApiSettings,\n model: string,\n params: GenerateContentRequest,\n requestOptions?: RequestOptions\n): Promise<GenerateContentStreamResult> {\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n params = GoogleAIMapper.mapGenerateContentRequest(params);\n }\n const response = await makeRequest(\n model,\n Task.STREAM_GENERATE_CONTENT,\n apiSettings,\n /* stream */ true,\n JSON.stringify(params),\n requestOptions\n );\n return processStream(response, apiSettings); // TODO: Map streaming responses\n}\n\nexport async function generateContent(\n apiSettings: ApiSettings,\n model: string,\n params: GenerateContentRequest,\n requestOptions?: RequestOptions\n): Promise<GenerateContentResult> {\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n params = GoogleAIMapper.mapGenerateContentRequest(params);\n }\n const response = await makeRequest(\n model,\n Task.GENERATE_CONTENT,\n apiSettings,\n /* stream */ false,\n JSON.stringify(params),\n requestOptions\n );\n const generateContentResponse = await processGenerateContentResponse(\n response,\n apiSettings\n );\n const enhancedResponse = createEnhancedContentResponse(\n generateContentResponse\n );\n return {\n response: enhancedResponse\n };\n}\n\nasync function processGenerateContentResponse(\n response: Response,\n apiSettings: ApiSettings\n): Promise<GenerateContentResponse> {\n const responseJson = await response.json();\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n return GoogleAIMapper.mapGenerateContentResponse(responseJson);\n } else {\n return responseJson;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Content, GenerateContentRequest, Part, AIErrorCode } from '../types';\nimport { AIError } from '../errors';\nimport { ImagenGenerationParams, PredictRequestBody } from '../types/internal';\n\nexport function formatSystemInstruction(\n input?: string | Part | Content\n): Content | undefined {\n // null or undefined\n if (input == null) {\n return undefined;\n } else if (typeof input === 'string') {\n return { role: 'system', parts: [{ text: input }] } as Content;\n } else if ((input as Part).text) {\n return { role: 'system', parts: [input as Part] };\n } else if ((input as Content).parts) {\n if (!(input as Content).role) {\n return { role: 'system', parts: (input as Content).parts };\n } else {\n return input as Content;\n }\n }\n}\n\nexport function formatNewContent(\n request: string | Array<string | Part>\n): Content {\n let newParts: Part[] = [];\n if (typeof request === 'string') {\n newParts = [{ text: request }];\n } else {\n for (const partOrString of request) {\n if (typeof partOrString === 'string') {\n newParts.push({ text: partOrString });\n } else {\n newParts.push(partOrString);\n }\n }\n }\n return assignRoleToPartsAndValidateSendMessageRequest(newParts);\n}\n\n/**\n * When multiple Part types (i.e. FunctionResponsePart and TextPart) are\n * passed in a single Part array, we may need to assign different roles to each\n * part. Currently only FunctionResponsePart requires a role other than 'user'.\n * @private\n * @param parts Array of parts to pass to the model\n * @returns Array of content items\n */\nfunction assignRoleToPartsAndValidateSendMessageRequest(\n parts: Part[]\n): Content {\n const userContent: Content = { role: 'user', parts: [] };\n const functionContent: Content = { role: 'function', parts: [] };\n let hasUserContent = false;\n let hasFunctionContent = false;\n for (const part of parts) {\n if ('functionResponse' in part) {\n functionContent.parts.push(part);\n hasFunctionContent = true;\n } else {\n userContent.parts.push(part);\n hasUserContent = true;\n }\n }\n\n if (hasUserContent && hasFunctionContent) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n 'Within a single message, FunctionResponse cannot be mixed with other type of Part in the request for sending chat message.'\n );\n }\n\n if (!hasUserContent && !hasFunctionContent) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n 'No Content is provided for sending chat message.'\n );\n }\n\n if (hasUserContent) {\n return userContent;\n }\n\n return functionContent;\n}\n\nexport function formatGenerateContentInput(\n params: GenerateContentRequest | string | Array<string | Part>\n): GenerateContentRequest {\n let formattedRequest: GenerateContentRequest;\n if ((params as GenerateContentRequest).contents) {\n formattedRequest = params as GenerateContentRequest;\n } else {\n // Array or string\n const content = formatNewContent(params as string | Array<string | Part>);\n formattedRequest = { contents: [content] };\n }\n if ((params as GenerateContentRequest).systemInstruction) {\n formattedRequest.systemInstruction = formatSystemInstruction(\n (params as GenerateContentRequest).systemInstruction\n );\n }\n return formattedRequest;\n}\n\n/**\n * Convert the user-defined parameters in {@link ImagenGenerationParams} to the format\n * that is expected from the REST API.\n *\n * @internal\n */\nexport function createPredictRequestBody(\n prompt: string,\n {\n gcsURI,\n imageFormat,\n addWatermark,\n numberOfImages = 1,\n negativePrompt,\n aspectRatio,\n safetyFilterLevel,\n personFilterLevel\n }: ImagenGenerationParams\n): PredictRequestBody {\n // Properties that are undefined will be omitted from the JSON string that is sent in the request.\n const body: PredictRequestBody = {\n instances: [\n {\n prompt\n }\n ],\n parameters: {\n storageUri: gcsURI,\n negativePrompt,\n sampleCount: numberOfImages,\n aspectRatio,\n outputOptions: imageFormat,\n addWatermark,\n safetyFilterLevel,\n personGeneration: personFilterLevel,\n includeRaiReason: true\n }\n };\n return body;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Content, POSSIBLE_ROLES, Part, Role, AIErrorCode } from '../types';\nimport { AIError } from '../errors';\n\n// https://ai.google.dev/api/rest/v1beta/Content#part\n\nconst VALID_PART_FIELDS: Array<keyof Part> = [\n 'text',\n 'inlineData',\n 'functionCall',\n 'functionResponse'\n];\n\nconst VALID_PARTS_PER_ROLE: { [key in Role]: Array<keyof Part> } = {\n user: ['text', 'inlineData'],\n function: ['functionResponse'],\n model: ['text', 'functionCall'],\n // System instructions shouldn't be in history anyway.\n system: ['text']\n};\n\nconst VALID_PREVIOUS_CONTENT_ROLES: { [key in Role]: Role[] } = {\n user: ['model'],\n function: ['model'],\n model: ['user', 'function'],\n // System instructions shouldn't be in history.\n system: []\n};\n\nexport function validateChatHistory(history: Content[]): void {\n let prevContent: Content | null = null;\n for (const currContent of history) {\n const { role, parts } = currContent;\n if (!prevContent && role !== 'user') {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `First Content should be with role 'user', got ${role}`\n );\n }\n if (!POSSIBLE_ROLES.includes(role)) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Each item should include role field. Got ${role} but valid roles are: ${JSON.stringify(\n POSSIBLE_ROLES\n )}`\n );\n }\n\n if (!Array.isArray(parts)) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Content should have 'parts' but property with an array of Parts`\n );\n }\n\n if (parts.length === 0) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Each Content should have at least one part`\n );\n }\n\n const countFields: Record<keyof Part, number> = {\n text: 0,\n inlineData: 0,\n functionCall: 0,\n functionResponse: 0\n };\n\n for (const part of parts) {\n for (const key of VALID_PART_FIELDS) {\n if (key in part) {\n countFields[key] += 1;\n }\n }\n }\n const validParts = VALID_PARTS_PER_ROLE[role];\n for (const key of VALID_PART_FIELDS) {\n if (!validParts.includes(key) && countFields[key] > 0) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Content with role '${role}' can't contain '${key}' part`\n );\n }\n }\n\n if (prevContent) {\n const validPreviousContentRoles = VALID_PREVIOUS_CONTENT_ROLES[role];\n if (!validPreviousContentRoles.includes(prevContent.role)) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Content with role '${role}' can't follow '${\n prevContent.role\n }'. Valid previous roles: ${JSON.stringify(\n VALID_PREVIOUS_CONTENT_ROLES\n )}`\n );\n }\n }\n prevContent = currContent;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n GenerateContentRequest,\n GenerateContentResult,\n GenerateContentStreamResult,\n Part,\n RequestOptions,\n StartChatParams\n} from '../types';\nimport { formatNewContent } from '../requests/request-helpers';\nimport { formatBlockErrorMessage } from '../requests/response-helpers';\nimport { validateChatHistory } from './chat-session-helpers';\nimport { generateContent, generateContentStream } from './generate-content';\nimport { ApiSettings } from '../types/internal';\nimport { logger } from '../logger';\n\n/**\n * Do not log a message for this error.\n */\nconst SILENT_ERROR = 'SILENT_ERROR';\n\n/**\n * ChatSession class that enables sending chat messages and stores\n * history of sent and received messages so far.\n *\n * @public\n */\nexport class ChatSession {\n private _apiSettings: ApiSettings;\n private _history: Content[] = [];\n private _sendPromise: Promise<void> = Promise.resolve();\n\n constructor(\n apiSettings: ApiSettings,\n public model: string,\n public params?: StartChatParams,\n public requestOptions?: RequestOptions\n ) {\n this._apiSettings = apiSettings;\n if (params?.history) {\n validateChatHistory(params.history);\n this._history = params.history;\n }\n }\n\n /**\n * Gets the chat history so far. Blocked prompts are not added to history.\n * Neither blocked candidates nor the prompts that generated them are added\n * to history.\n */\n async getHistory(): Promise<Content[]> {\n await this._sendPromise;\n return this._history;\n }\n\n /**\n * Sends a chat message and receives a non-streaming\n * {@link GenerateContentResult}\n */\n async sendMessage(\n request: string | Array<string | Part>\n ): Promise<GenerateContentResult> {\n await this._sendPromise;\n const newContent = formatNewContent(request);\n const generateContentRequest: GenerateContentRequest = {\n safetySettings: this.params?.safetySettings,\n generationConfig: this.params?.generationConfig,\n tools: this.params?.tools,\n toolConfig: this.params?.toolConfig,\n systemInstruction: this.params?.systemInstruction,\n contents: [...this._history, newContent]\n };\n let finalResult = {} as GenerateContentResult;\n // Add onto the chain.\n this._sendPromise = this._sendPromise\n .then(() =>\n generateContent(\n this._apiSettings,\n this.model,\n generateContentRequest,\n this.requestOptions\n )\n )\n .then(result => {\n if (\n result.response.candidates &&\n result.response.candidates.length > 0\n ) {\n this._history.push(newContent);\n const responseContent: Content = {\n parts: result.response.candidates?.[0].content.parts || [],\n // Response seems to come back without a role set.\n role: result.response.candidates?.[0].content.role || 'model'\n };\n this._history.push(responseContent);\n } else {\n const blockErrorMessage = formatBlockErrorMessage(result.response);\n if (blockErrorMessage) {\n logger.warn(\n `sendMessage() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`\n );\n }\n }\n finalResult = result;\n });\n await this._sendPromise;\n return finalResult;\n }\n\n /**\n * Sends a chat message and receives the response as a\n * {@link GenerateContentStreamResult} containing an iterable stream\n * and a response promise.\n */\n async sendMessageStream(\n request: string | Array<string | Part>\n ): Promise<GenerateContentStreamResult> {\n await this._sendPromise;\n const newContent = formatNewContent(request);\n const generateContentRequest: GenerateContentRequest = {\n safetySettings: this.params?.safetySettings,\n generationConfig: this.params?.generationConfig,\n tools: this.params?.tools,\n toolConfig: this.params?.toolConfig,\n systemInstruction: this.params?.systemInstruction,\n contents: [...this._history, newContent]\n };\n const streamPromise = generateContentStream(\n this._apiSettings,\n this.model,\n generateContentRequest,\n this.requestOptions\n );\n\n // Add onto the chain.\n this._sendPromise = this._sendPromise\n .then(() => streamPromise)\n // This must be handled to avoid unhandled rejection, but jump\n // to the final catch block with a label to not log this error.\n .catch(_ignored => {\n throw new Error(SILENT_ERROR);\n })\n .then(streamResult => streamResult.response)\n .then(response => {\n if (response.candidates && response.candidates.length > 0) {\n this._history.push(newContent);\n const responseContent = { ...response.candidates[0].content };\n // Response seems to come back without a role set.\n if (!responseContent.role) {\n responseContent.role = 'model';\n }\n this._history.push(responseContent);\n } else {\n const blockErrorMessage = formatBlockErrorMessage(response);\n if (blockErrorMessage) {\n logger.warn(\n `sendMessageStream() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`\n );\n }\n }\n })\n .catch(e => {\n // Errors in streamPromise are already catchable by the user as\n // streamPromise is returned.\n // Avoid duplicating the error message in logs.\n if (e.message !== SILENT_ERROR) {\n // Users do not have access to _sendPromise to catch errors\n // downstream from streamPromise, so they should not throw.\n logger.error(e);\n }\n });\n return streamPromise;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n generateContent,\n generateContentStream\n} from '../methods/generate-content';\nimport {\n Content,\n CountTokensRequest,\n CountTokensResponse,\n GenerateContentRequest,\n GenerateContentResult,\n GenerateContentStreamResult,\n GenerationConfig,\n ModelParams,\n Part,\n RequestOptions,\n SafetySetting,\n StartChatParams,\n Tool,\n ToolConfig\n} from '../types';\nimport { ChatSession } from '../methods/chat-session';\nimport { countTokens } from '../methods/count-tokens';\nimport {\n formatGenerateContentInput,\n formatSystemInstruction\n} from '../requests/request-helpers';\nimport { AI } from '../public-types';\nimport { AIModel } from './ai-model';\n\n/**\n * Class for generative model APIs.\n * @public\n */\nexport class GenerativeModel extends AIModel {\n generationConfig: GenerationConfig;\n safetySettings: SafetySetting[];\n requestOptions?: RequestOptions;\n tools?: Tool[];\n toolConfig?: ToolConfig;\n systemInstruction?: Content;\n\n constructor(\n ai: AI,\n modelParams: ModelParams,\n requestOptions?: RequestOptions\n ) {\n super(ai, modelParams.model);\n this.generationConfig = modelParams.generationConfig || {};\n this.safetySettings = modelParams.safetySettings || [];\n this.tools = modelParams.tools;\n this.toolConfig = modelParams.toolConfig;\n this.systemInstruction = formatSystemInstruction(\n modelParams.systemInstruction\n );\n this.requestOptions = requestOptions || {};\n }\n\n /**\n * Makes a single non-streaming call to the model\n * and returns an object containing a single {@link GenerateContentResponse}.\n */\n async generateContent(\n request: GenerateContentRequest | string | Array<string | Part>\n ): Promise<GenerateContentResult> {\n const formattedParams = formatGenerateContentInput(request);\n return generateContent(\n this._apiSettings,\n this.model,\n {\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n ...formattedParams\n },\n this.requestOptions\n );\n }\n\n /**\n * Makes a single streaming call to the model\n * and returns an object containing an iterable stream that iterates\n * over all chunks in the streaming response as well as\n * a promise that returns the final aggregated response.\n */\n async generateContentStream(\n request: GenerateContentRequest | string | Array<string | Part>\n ): Promise<GenerateContentStreamResult> {\n const formattedParams = formatGenerateContentInput(request);\n return generateContentStream(\n this._apiSettings,\n this.model,\n {\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n ...formattedParams\n },\n this.requestOptions\n );\n }\n\n /**\n * Gets a new {@link ChatSession} instance which can be used for\n * multi-turn chats.\n */\n startChat(startChatParams?: StartChatParams): ChatSession {\n return new ChatSession(\n this._apiSettings,\n this.model,\n {\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n /**\n * Overrides params inherited from GenerativeModel with those explicitly set in the\n * StartChatParams. For example, if startChatParams.generationConfig is set, it'll override\n * this.generationConfig.\n */\n ...startChatParams\n },\n this.requestOptions\n );\n }\n\n /**\n * Counts the tokens in the provided request.\n */\n async countTokens(\n request: CountTokensRequest | string | Array<string | Part>\n ): Promise<CountTokensResponse> {\n const formattedParams = formatGenerateContentInput(request);\n return countTokens(this._apiSettings, this.model, formattedParams);\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CountTokensRequest,\n CountTokensResponse,\n RequestOptions\n} from '../types';\nimport { Task, makeRequest } from '../requests/request';\nimport { ApiSettings } from '../types/internal';\nimport * as GoogleAIMapper from '../googleai-mappers';\nimport { BackendType } from '../public-types';\n\nexport async function countTokens(\n apiSettings: ApiSettings,\n model: string,\n params: CountTokensRequest,\n requestOptions?: RequestOptions\n): Promise<CountTokensResponse> {\n let body: string = '';\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n const mappedParams = GoogleAIMapper.mapCountTokensRequest(params, model);\n body = JSON.stringify(mappedParams);\n } else {\n body = JSON.stringify(params);\n }\n const response = await makeRequest(\n model,\n Task.COUNT_TOKENS,\n apiSettings,\n false,\n body,\n requestOptions\n );\n return response.json();\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AI } from '../public-types';\nimport { Task, makeRequest } from '../requests/request';\nimport { createPredictRequestBody } from '../requests/request-helpers';\nimport { handlePredictResponse } from '../requests/response-helpers';\nimport {\n ImagenGCSImage,\n ImagenGenerationConfig,\n ImagenInlineImage,\n RequestOptions,\n ImagenModelParams,\n ImagenGenerationResponse,\n ImagenSafetySettings\n} from '../types';\nimport { AIModel } from './ai-model';\n\n/**\n * Class for Imagen model APIs.\n *\n * This class provides methods for generating images using the Imagen model.\n *\n * @example\n * ```javascript\n * const imagen = new ImagenModel(\n * ai,\n * {\n * model: 'imagen-3.0-generate-002'\n * }\n * );\n *\n * const response = await imagen.generateImages('A photo of a cat');\n * if (response.images.length > 0) {\n * console.log(response.images[0].bytesBase64Encoded);\n * }\n * ```\n *\n * @beta\n */\nexport class ImagenModel extends AIModel {\n /**\n * The Imagen generation configuration.\n */\n generationConfig?: ImagenGenerationConfig;\n /**\n * Safety settings for filtering inappropriate content.\n */\n safetySettings?: ImagenSafetySettings;\n\n /**\n * Constructs a new instance of the {@link ImagenModel} class.\n *\n * @param ai - an {@link AI} instance.\n * @param modelParams - Parameters to use when making requests to Imagen.\n * @param requestOptions - Additional options to use when making requests.\n *\n * @throws If the `apiKey` or `projectId` fields are missing in your\n * Firebase config.\n */\n constructor(\n ai: AI,\n modelParams: ImagenModelParams,\n public requestOptions?: RequestOptions\n ) {\n const { model, generationConfig, safetySettings } = modelParams;\n super(ai, model);\n this.generationConfig = generationConfig;\n this.safetySettings = safetySettings;\n }\n\n /**\n * Generates images using the Imagen model and returns them as\n * base64-encoded strings.\n *\n * @param prompt - A text prompt describing the image(s) to generate.\n * @returns A promise that resolves to an {@link ImagenGenerationResponse}\n * object containing the generated images.\n *\n * @throws If the request to generate images fails. This happens if the\n * prompt is blocked.\n *\n * @remarks\n * If the prompt was not blocked, but one or more of the generated images were filtered, the\n * returned object will have a `filteredReason` property.\n * If all images are filtered, the `images` array will be empty.\n *\n * @beta\n */\n async generateImages(\n prompt: string\n ): Promise<ImagenGenerationResponse<ImagenInlineImage>> {\n const body = createPredictRequestBody(prompt, {\n ...this.generationConfig,\n ...this.safetySettings\n });\n const response = await makeRequest(\n this.model,\n Task.PREDICT,\n this._apiSettings,\n /* stream */ false,\n JSON.stringify(body),\n this.requestOptions\n );\n return handlePredictResponse<ImagenInlineImage>(response);\n }\n\n /**\n * Generates images to Cloud Storage for Firebase using the Imagen model.\n *\n * @internal This method is temporarily internal.\n *\n * @param prompt - A text prompt describing the image(s) to generate.\n * @param gcsURI - The URI of file stored in a Cloud Storage for Firebase bucket.\n * This should be a directory. For example, `gs://my-bucket/my-directory/`.\n * @returns A promise that resolves to an {@link ImagenGenerationResponse}\n * object containing the URLs of the generated images.\n *\n * @throws If the request fails to generate images fails. This happens if\n * the prompt is blocked.\n *\n * @remarks\n * If the prompt was not blocked, but one or more of the generated images were filtered, the\n * returned object will have a `filteredReason` property.\n * If all images are filtered, the `images` array will be empty.\n */\n async generateImagesGCS(\n prompt: string,\n gcsURI: string\n ): Promise<ImagenGenerationResponse<ImagenGCSImage>> {\n const body = createPredictRequestBody(prompt, {\n gcsURI,\n ...this.generationConfig,\n ...this.safetySettings\n });\n const response = await makeRequest(\n this.model,\n Task.PREDICT,\n this._apiSettings,\n /* stream */ false,\n JSON.stringify(body),\n this.requestOptions\n );\n return handlePredictResponse<ImagenGCSImage>(response);\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from '../errors';\nimport { AIErrorCode } from '../types';\nimport {\n SchemaInterface,\n SchemaType,\n SchemaParams,\n SchemaRequest\n} from '../types/schema';\n\n/**\n * Parent class encompassing all Schema types, with static methods that\n * allow building specific Schema types. This class can be converted with\n * `JSON.stringify()` into a JSON string accepted by Vertex AI REST endpoints.\n * (This string conversion is automatically done when calling SDK methods.)\n * @public\n */\nexport abstract class Schema implements SchemaInterface {\n /**\n * Optional. The type of the property.\n * This can only be undefined when using `anyOf` schemas, which do not have an\n * explicit type in the {@link https://swagger.io/docs/specification/v3_0/data-models/data-types/#any-type | OpenAPI specification}.\n */\n type?: SchemaType;\n /** Optional. The format of the property.\n * Supported formats:<br/>\n * <ul>\n * <li>for NUMBER type: \"float\", \"double\"</li>\n * <li>for INTEGER type: \"int32\", \"int64\"</li>\n * <li>for STRING type: \"email\", \"byte\", etc</li>\n * </ul>\n */\n format?: string;\n /** Optional. The description of the property. */\n description?: string;\n /** Optional. The items of the property. */\n items?: SchemaInterface;\n /** The minimum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n minItems?: number;\n /** The maximum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n maxItems?: number;\n /** Optional. Whether the property is nullable. Defaults to false. */\n nullable: boolean;\n /** Optional. The example of the property. */\n example?: unknown;\n /**\n * Allows user to add other schema properties that have not yet\n * been officially added to the SDK.\n */\n [key: string]: unknown;\n\n constructor(schemaParams: SchemaInterface) {\n // TODO(dlarocque): Enforce this with union types\n if (!schemaParams.type && !schemaParams.anyOf) {\n throw new AIError(\n AIErrorCode.INVALID_SCHEMA,\n \"A schema must have either a 'type' or an 'anyOf' array of sub-schemas.\"\n );\n }\n // eslint-disable-next-line guard-for-in\n for (const paramKey in schemaParams) {\n this[paramKey] = schemaParams[paramKey];\n }\n // Ensure these are explicitly set to avoid TS errors.\n this.type = schemaParams.type;\n this.format = schemaParams.hasOwnProperty('format')\n ? schemaParams.format\n : undefined;\n this.nullable = schemaParams.hasOwnProperty('nullable')\n ? !!schemaParams.nullable\n : false;\n }\n\n /**\n * Defines how this Schema should be serialized as JSON.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj: { type?: SchemaType; [key: string]: unknown } = {\n type: this.type\n };\n for (const prop in this) {\n if (this.hasOwnProperty(prop) && this[prop] !== undefined) {\n if (prop !== 'required' || this.type === SchemaType.OBJECT) {\n obj[prop] = this[prop];\n }\n }\n }\n return obj as SchemaRequest;\n }\n\n static array(arrayParams: SchemaParams & { items: Schema }): ArraySchema {\n return new ArraySchema(arrayParams, arrayParams.items);\n }\n\n static object(\n objectParams: SchemaParams & {\n properties: {\n [k: string]: Schema;\n };\n optionalProperties?: string[];\n }\n ): ObjectSchema {\n return new ObjectSchema(\n objectParams,\n objectParams.properties,\n objectParams.optionalProperties\n );\n }\n\n // eslint-disable-next-line id-blacklist\n static string(stringParams?: SchemaParams): StringSchema {\n return new StringSchema(stringParams);\n }\n\n static enumString(\n stringParams: SchemaParams & { enum: string[] }\n ): StringSchema {\n return new StringSchema(stringParams, stringParams.enum);\n }\n\n static integer(integerParams?: SchemaParams): IntegerSchema {\n return new IntegerSchema(integerParams);\n }\n\n // eslint-disable-next-line id-blacklist\n static number(numberParams?: SchemaParams): NumberSchema {\n return new NumberSchema(numberParams);\n }\n\n // eslint-disable-next-line id-blacklist\n static boolean(booleanParams?: SchemaParams): BooleanSchema {\n return new BooleanSchema(booleanParams);\n }\n\n static anyOf(\n anyOfParams: SchemaParams & { anyOf: TypedSchema[] }\n ): AnyOfSchema {\n return new AnyOfSchema(anyOfParams);\n }\n}\n\n/**\n * A type that includes all specific Schema types.\n * @public\n */\nexport type TypedSchema =\n | IntegerSchema\n | NumberSchema\n | StringSchema\n | BooleanSchema\n | ObjectSchema\n | ArraySchema\n | AnyOfSchema;\n\n/**\n * Schema class for \"integer\" types.\n * @public\n */\nexport class IntegerSchema extends Schema {\n constructor(schemaParams?: SchemaParams) {\n super({\n type: SchemaType.INTEGER,\n ...schemaParams\n });\n }\n}\n\n/**\n * Schema class for \"number\" types.\n * @public\n */\nexport class NumberSchema extends Schema {\n constructor(schemaParams?: SchemaParams) {\n super({\n type: SchemaType.NUMBER,\n ...schemaParams\n });\n }\n}\n\n/**\n * Schema class for \"boolean\" types.\n * @public\n */\nexport class BooleanSchema extends Schema {\n constructor(schemaParams?: SchemaParams) {\n super({\n type: SchemaType.BOOLEAN,\n ...schemaParams\n });\n }\n}\n\n/**\n * Schema class for \"string\" types. Can be used with or without\n * enum values.\n * @public\n */\nexport class StringSchema extends Schema {\n enum?: string[];\n constructor(schemaParams?: SchemaParams, enumValues?: string[]) {\n super({\n type: SchemaType.STRING,\n ...schemaParams\n });\n this.enum = enumValues;\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n if (this.enum) {\n obj['enum'] = this.enum;\n }\n return obj as SchemaRequest;\n }\n}\n\n/**\n * Schema class for \"array\" types.\n * The `items` param should refer to the type of item that can be a member\n * of the array.\n * @public\n */\nexport class ArraySchema extends Schema {\n constructor(schemaParams: SchemaParams, public items: TypedSchema) {\n super({\n type: SchemaType.ARRAY,\n ...schemaParams\n });\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n obj.items = this.items.toJSON();\n return obj;\n }\n}\n\n/**\n * Schema class for \"object\" types.\n * The `properties` param must be a map of `Schema` objects.\n * @public\n */\nexport class ObjectSchema extends Schema {\n constructor(\n schemaParams: SchemaParams,\n public properties: {\n [k: string]: TypedSchema;\n },\n public optionalProperties: string[] = []\n ) {\n super({\n type: SchemaType.OBJECT,\n ...schemaParams\n });\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n obj.properties = { ...this.properties };\n const required = [];\n if (this.optionalProperties) {\n for (const propertyKey of this.optionalProperties) {\n if (!this.properties.hasOwnProperty(propertyKey)) {\n throw new AIError(\n AIErrorCode.INVALID_SCHEMA,\n `Property \"${propertyKey}\" specified in \"optionalProperties\" does not exist.`\n );\n }\n }\n }\n for (const propertyKey in this.properties) {\n if (this.properties.hasOwnProperty(propertyKey)) {\n obj.properties[propertyKey] = this.properties[\n propertyKey\n ].toJSON() as SchemaRequest;\n if (!this.optionalProperties.includes(propertyKey)) {\n required.push(propertyKey);\n }\n }\n }\n if (required.length > 0) {\n obj.required = required;\n }\n delete obj.optionalProperties;\n return obj as SchemaRequest;\n }\n}\n\n/**\n * Schema class representing a value that can conform to any of the provided sub-schemas. This is\n * useful when a field can accept multiple distinct types or structures.\n * @public\n */\nexport class AnyOfSchema extends Schema {\n anyOf: TypedSchema[]; // Re-define field to narrow to required type\n constructor(schemaParams: SchemaParams & { anyOf: TypedSchema[] }) {\n if (schemaParams.anyOf.length === 0) {\n throw new AIError(\n AIErrorCode.INVALID_SCHEMA,\n \"The 'anyOf' array must not be empty.\"\n );\n }\n super({\n ...schemaParams,\n type: undefined // anyOf schemas do not have an explicit type\n });\n this.anyOf = schemaParams.anyOf;\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n // Ensure the 'anyOf' property contains serialized SchemaRequest objects.\n if (this.anyOf && Array.isArray(this.anyOf)) {\n obj.anyOf = (this.anyOf as TypedSchema[]).map(s => s.toJSON());\n }\n return obj;\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { logger } from '../logger';\n\n/**\n * Defines the image format for images generated by Imagen.\n *\n * Use this class to specify the desired format (JPEG or PNG) and compression quality\n * for images generated by Imagen. This is typically included as part of\n * {@link ImagenModelParams}.\n *\n * @example\n * ```javascript\n * const imagenModelParams = {\n * // ... other ImagenModelParams\n * imageFormat: ImagenImageFormat.jpeg(75) // JPEG with a compression level of 75.\n * }\n * ```\n *\n * @beta\n */\nexport class ImagenImageFormat {\n /**\n * The MIME type.\n */\n mimeType: string;\n /**\n * The level of compression (a number between 0 and 100).\n */\n compressionQuality?: number;\n\n private constructor() {\n this.mimeType = 'image/png';\n }\n\n /**\n * Creates an {@link ImagenImageFormat} for a JPEG image.\n *\n * @param compressionQuality - The level of compression (a number between 0 and 100).\n * @returns An {@link ImagenImageFormat} object for a JPEG image.\n *\n * @beta\n */\n static jpeg(compressionQuality?: number): ImagenImageFormat {\n if (\n compressionQuality &&\n (compressionQuality < 0 || compressionQuality > 100)\n ) {\n logger.warn(\n `Invalid JPEG compression quality of ${compressionQuality} specified; the supported range is [0, 100].`\n );\n }\n return { mimeType: 'image/jpeg', compressionQuality };\n }\n\n /**\n * Creates an {@link ImagenImageFormat} for a PNG image.\n *\n * @returns An {@link ImagenImageFormat} object for a PNG image.\n *\n * @beta\n */\n static png(): ImagenImageFormat {\n return { mimeType: 'image/png' };\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, getApp, _getProvider } from '@firebase/app';\nimport { Provider } from '@firebase/component';\nimport { getModularInstance } from '@firebase/util';\nimport { AI_TYPE } from './constants';\nimport { AIService } from './service';\nimport { AI, AIOptions } from './public-types';\nimport {\n ImagenModelParams,\n ModelParams,\n RequestOptions,\n AIErrorCode\n} from './types';\nimport { AIError } from './errors';\nimport { AIModel, GenerativeModel, ImagenModel } from './models';\nimport { encodeInstanceIdentifier } from './helpers';\nimport { GoogleAIBackend } from './backend';\n\nexport { ChatSession } from './methods/chat-session';\nexport * from './requests/schema-builder';\nexport { ImagenImageFormat } from './requests/imagen-image-format';\nexport { AIModel, GenerativeModel, ImagenModel, AIError };\nexport { Backend, VertexAIBackend, GoogleAIBackend } from './backend';\n\ndeclare module '@firebase/component' {\n interface NameServiceMapping {\n [AI_TYPE]: AIService;\n }\n}\n\n/**\n * Returns the default {@link AI} instance that is associated with the provided\n * {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new instance with the\n * default settings.\n *\n * @example\n * ```javascript\n * const ai = getAI(app);\n * ```\n *\n * @example\n * ```javascript\n * // Get an AI instance configured to use the Gemini Developer API (via Google AI).\n * const ai = getAI(app, { backend: new GoogleAIBackend() });\n * ```\n *\n * @example\n * ```javascript\n * // Get an AI instance configured to use the Vertex AI Gemini API.\n * const ai = getAI(app, { backend: new VertexAIBackend() });\n * ```\n *\n * @param app - The {@link @firebase/app#FirebaseApp} to use.\n * @param options - {@link AIOptions} that configure the AI instance.\n * @returns The default {@link AI} instance for the given {@link @firebase/app#FirebaseApp}.\n *\n * @public\n */\nexport function getAI(\n app: FirebaseApp = getApp(),\n options: AIOptions = { backend: new GoogleAIBackend() }\n): AI {\n app = getModularInstance(app);\n // Dependencies\n const AIProvider: Provider<'AI'> = _getProvider(app, AI_TYPE);\n\n const identifier = encodeInstanceIdentifier(options.backend);\n return AIProvider.getImmediate({\n identifier\n });\n}\n\n/**\n * Returns a {@link GenerativeModel} class with methods for inference\n * and other functionality.\n *\n * @public\n */\nexport function getGenerativeModel(\n ai: AI,\n modelParams: ModelParams,\n requestOptions?: RequestOptions\n): GenerativeModel {\n if (!modelParams.model) {\n throw new AIError(\n AIErrorCode.NO_MODEL,\n `Must provide a model name. Example: getGenerativeModel({ model: 'my-model-name' })`\n );\n }\n return new GenerativeModel(ai, modelParams, requestOptions);\n}\n\n/**\n * Returns an {@link ImagenModel} class with methods for using Imagen.\n *\n * Only Imagen 3 models (named `imagen-3.0-*`) are supported.\n *\n * @param ai - An {@link AI} instance.\n * @param modelParams - Parameters to use when making Imagen requests.\n * @param requestOptions - Additional options to use when making requests.\n *\n * @throws If the `apiKey` or `projectId` fields are missing in your\n * Firebase config.\n *\n * @beta\n */\nexport function getImagenModel(\n ai: AI,\n modelParams: ImagenModelParams,\n requestOptions?: RequestOptions\n): ImagenModel {\n if (!modelParams.model) {\n throw new AIError(\n AIErrorCode.NO_MODEL,\n `Must provide a model name. Example: getImagenModel({ model: 'my-model-name' })`\n );\n }\n return new ImagenModel(ai, modelParams, requestOptions);\n}\n","/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat<T> {\n _delegate: T;\n}\n\nexport function getModularInstance<ExpService>(\n service: Compat<ExpService> | ExpService\n): ExpService {\n if (service && (service as Compat<ExpService>)._delegate) {\n return (service as Compat<ExpService>)._delegate;\n } else {\n return service as ExpService;\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AI_TYPE } from './constants';\nimport { AIError } from './errors';\nimport { AIErrorCode } from './types';\nimport { Backend, GoogleAIBackend, VertexAIBackend } from './backend';\n\n/**\n * Encodes a {@link Backend} into a string that will be used to uniquely identify {@link AI}\n * instances by backend type.\n *\n * @internal\n */\nexport function encodeInstanceIdentifier(backend: Backend): string {\n if (backend instanceof GoogleAIBackend) {\n return `${AI_TYPE}/googleai`;\n } else if (backend instanceof VertexAIBackend) {\n return `${AI_TYPE}/vertexai/${backend.location}`;\n } else {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid backend: ${JSON.stringify(backend.backendType)}`\n );\n }\n}\n\n/**\n * Decodes an instance identifier string into a {@link Backend}.\n *\n * @internal\n */\nexport function decodeInstanceIdentifier(instanceIdentifier: string): Backend {\n const identifierParts = instanceIdentifier.split('/');\n if (identifierParts[0] !== AI_TYPE) {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid instance identifier, unknown prefix '${identifierParts[0]}'`\n );\n }\n const backendType = identifierParts[1];\n switch (backendType) {\n case 'vertexai':\n const location: string | undefined = identifierParts[2];\n if (!location) {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid instance identifier, unknown location '${instanceIdentifier}'`\n );\n }\n return new VertexAIBackend(location);\n case 'googleai':\n return new GoogleAIBackend();\n default:\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid instance identifier string: '${instanceIdentifier}'`\n );\n }\n}\n","/**\n * The Firebase AI Web SDK.\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerVersion, _registerComponent } from '@firebase/app';\nimport { AIService } from './service';\nimport { AI_TYPE } from './constants';\nimport { Component, ComponentType } from '@firebase/component';\nimport { name, version } from '../package.json';\nimport { decodeInstanceIdentifier } from './helpers';\nimport { AIError } from './api';\nimport { AIErrorCode } from './types';\n\ndeclare global {\n interface Window {\n [key: string]: unknown;\n }\n}\n\nfunction registerAI(): void {\n _registerComponent(\n new Component(\n AI_TYPE,\n (container, { instanceIdentifier }) => {\n if (!instanceIdentifier) {\n throw new AIError(\n AIErrorCode.ERROR,\n 'AIService instance identifier is undefined.'\n );\n }\n\n const backend = decodeInstanceIdentifier(instanceIdentifier);\n\n // getImmediate for FirebaseApp will always succeed\n const app = container.getProvider('app').getImmediate();\n const auth = container.getProvider('auth-internal');\n const appCheckProvider = container.getProvider('app-check-internal');\n return new AIService(app, backend, auth, appCheckProvider);\n },\n ComponentType.PUBLIC\n ).setMultipleInstances(true)\n );\n\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm, cjs, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\nregisterAI();\n\nexport * from './api';\nexport * from './public-types';\n"],"names":["FirebaseError","Error","constructor","code","message","customData","super","this","name","Object","setPrototypeOf","prototype","captureStackTrace","ErrorFactory","create","service","serviceName","errors","data","fullCode","template","replaceTemplate","replace","PATTERN","_","key","value","String","fullMessage","Component","instanceFactory","type","multipleInstances","serviceProps","instantiationMode","onInstanceCreated","setInstantiationMode","mode","setMultipleInstances","setServiceProps","props","setInstanceCreatedCallback","callback","LogLevel","levelStringToEnum","debug","DEBUG","verbose","VERBOSE","info","INFO","warn","WARN","error","ERROR","silent","SILENT","defaultLogLevel","ConsoleMethod","defaultLogHandler","instance","logType","args","logLevel","now","Date","toISOString","method","console","AI_TYPE","DEFAULT_LOCATION","PACKAGE_VERSION","version","POSSIBLE_ROLES","HarmCategory","HARM_CATEGORY_HATE_SPEECH","HARM_CATEGORY_SEXUALLY_EXPLICIT","HARM_CATEGORY_HARASSMENT","HARM_CATEGORY_DANGEROUS_CONTENT","HarmBlockThreshold","BLOCK_LOW_AND_ABOVE","BLOCK_MEDIUM_AND_ABOVE","BLOCK_ONLY_HIGH","BLOCK_NONE","OFF","HarmBlockMethod","SEVERITY","PROBABILITY","HarmProbability","NEGLIGIBLE","LOW","MEDIUM","HIGH","HarmSeverity","HARM_SEVERITY_NEGLIGIBLE","HARM_SEVERITY_LOW","HARM_SEVERITY_MEDIUM","HARM_SEVERITY_HIGH","HARM_SEVERITY_UNSUPPORTED","BlockReason","SAFETY","OTHER","BLOCKLIST","PROHIBITED_CONTENT","FinishReason","STOP","MAX_TOKENS","RECITATION","SPII","MALFORMED_FUNCTION_CALL","FunctionCallingMode","AUTO","ANY","NONE","Modality","MODALITY_UNSPECIFIED","TEXT","IMAGE","VIDEO","AUDIO","DOCUMENT","ResponseModality","AIErrorCode","REQUEST_ERROR","RESPONSE_ERROR","FETCH_ERROR","INVALID_CONTENT","API_NOT_ENABLED","INVALID_SCHEMA","NO_API_KEY","NO_APP_ID","NO_MODEL","NO_PROJECT_ID","PARSE_FAILED","UNSUPPORTED","SchemaType","STRING","NUMBER","INTEGER","BOOLEAN","ARRAY","OBJECT","ImagenSafetyFilterLevel","ImagenPersonFilterLevel","BLOCK_ALL","ALLOW_ADULT","ALLOW_ALL","ImagenAspectRatio","SQUARE","LANDSCAPE_3x4","PORTRAIT_4x3","LANDSCAPE_16x9","PORTRAIT_9x16","BackendType","VERTEX_AI","GOOGLE_AI","Backend","backendType","GoogleAIBackend","VertexAIBackend","location","AIService","app","backend","authProvider","appCheckProvider","appCheck","getImmediate","optional","auth","_delete","Promise","resolve","AIError","customErrorData","toString","AIModel","ai","modelName","options","apiKey","projectId","appId","_apiSettings","project","automaticDataCollectionEnabled","_isFirebaseServerApp","settings","appCheckToken","token","getAppCheckToken","getToken","getAuthToken","model","normalizeModelName","normalizeGoogleAIModelName","normalizeVertexAIModelName","includes","startsWith","logger","Logger","_logLevel","_logHandler","_userLogHandler","val","TypeError","setLogLevel","logHandler","userLogHandler","log","Task","RequestUrl","task","apiSettings","stream","requestOptions","url","URL","baseUrl","pathname","apiVersion","modelPath","search","queryParams","JSON","stringify","params","URLSearchParams","set","async","getHeaders","headers","Headers","append","getClientHeaders","loggingTags","push","join","authToken","accessToken","makeRequest","body","response","fetchTimeoutId","request","constructRequest","fetchOptions","timeoutMillis","timeout","abortController","AbortController","setTimeout","abort","signal","fetch","ok","errorDetails","json","details","e","status","some","detail","reason","links","description","statusText","err","stack","clearTimeout","createEnhancedContentResponse","candidates","hasOwnProperty","index","responseWithHelpers","addHelpers","text","length","hadBadFinishReason","formatBlockErrorMessage","getText","textStrings","content","parts","part","promptFeedback","inlineDataParts","getInlineDataParts","inlineData","functionCalls","getFunctionCalls","functionCall","badFinishReasons","candidate","finishReason","firstCandidate","finishMessage","blockReason","blockReasonMessage","handlePredictResponse","responseJson","images","filteredReason","predictions","prediction","raiFilteredReason","mimeType","bytesBase64Encoded","gcsUri","gcsURI","mapGenerateContentRequest","generateContentRequest","safetySettings","forEach","safetySetting","generationConfig","topK","roundedTopK","Math","round","mapGenerateContentResponse","googleAIResponse","mapGenerateContentCandidates","undefined","prompt","mapPromptFeedback","usageMetadata","mappedCandidates","mappedSafetyRatings","citationMetadata","citations","citationSources","safetyRatings","map","safetyRating","severity","probabilityScore","severityScore","videoMetadata","mappedCandidate","groundingMetadata","category","probability","blocked","responseLineRE","processStream","responseStream","getResponseStream","inputStream","reader","getReader","ReadableStream","start","controller","currentText","pump","read","then","done","trim","close","parsedResponse","match","parse","enqueue","substring","pipeThrough","TextDecoderStream","fatal","stream1","stream2","tee","generateResponseSequence","getResponsePromise","allResponses","generateContentResponse","aggregateResponses","GoogleAIMapper.mapGenerateContentResponse","enhancedResponse","responses","lastResponse","aggregatedResponse","i","role","newPart","keys","generateContentStream","GoogleAIMapper.mapGenerateContentRequest","STREAM_GENERATE_CONTENT","generateContent","GENERATE_CONTENT","processGenerateContentResponse","formatSystemInstruction","input","formatNewContent","newParts","partOrString","assignRoleToPartsAndValidateSendMessageRequest","userContent","functionContent","hasUserContent","hasFunctionContent","formatGenerateContentInput","formattedRequest","contents","systemInstruction","createPredictRequestBody","imageFormat","addWatermark","numberOfImages","negativePrompt","aspectRatio","safetyFilterLevel","personFilterLevel","instances","parameters","storageUri","sampleCount","outputOptions","personGeneration","includeRaiReason","VALID_PART_FIELDS","VALID_PARTS_PER_ROLE","user","function","system","VALID_PREVIOUS_CONTENT_ROLES","SILENT_ERROR","ChatSession","_history","_sendPromise","history","validateChatHistory","prevContent","currContent","Array","isArray","countFields","functionResponse","validParts","getHistory","sendMessage","newContent","tools","toolConfig","finalResult","result","responseContent","blockErrorMessage","sendMessageStream","streamPromise","catch","_ignored","streamResult","GenerativeModel","modelParams","formattedParams","startChat","startChatParams","countTokens","mappedParams","mapCountTokensRequest","countTokensRequest","GoogleAIMapper.mapCountTokensRequest","COUNT_TOKENS","ImagenModel","generateImages","PREDICT","generateImagesGCS","Schema","schemaParams","anyOf","paramKey","format","nullable","toJSON","obj","prop","array","arrayParams","ArraySchema","items","object","objectParams","ObjectSchema","properties","optionalProperties","string","stringParams","StringSchema","enumString","enum","integer","integerParams","IntegerSchema","number","numberParams","NumberSchema","boolean","booleanParams","BooleanSchema","anyOfParams","AnyOfSchema","enumValues","required","propertyKey","s","ImagenImageFormat","jpeg","compressionQuality","png","getAI","getApp","getModularInstance","_delegate","AIProvider","_getProvider","identifier","encodeInstanceIdentifier","getGenerativeModel","getImagenModel","registerAI","_registerComponent","container","instanceIdentifier","decodeInstanceIdentifier","identifierParts","split","getProvider","registerVersion"],"mappings":"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","preExistingComment":"firebase-ai.js.map"}
|
|
1
|
+
{"version":3,"file":"firebase-ai.js","sources":["../util/src/errors.ts","../component/src/component.ts","../logger/src/logger.ts","../ai/src/constants.ts","../ai/src/types/enums.ts","../ai/src/types/error.ts","../ai/src/types/schema.ts","../ai/src/types/imagen/requests.ts","../ai/src/public-types.ts","../ai/src/backend.ts","../ai/src/service.ts","../ai/src/errors.ts","../ai/src/models/ai-model.ts","../ai/src/logger.ts","../ai/src/requests/request.ts","../ai/src/requests/response-helpers.ts","../ai/src/googleai-mappers.ts","../ai/src/requests/stream-reader.ts","../ai/src/methods/generate-content.ts","../ai/src/requests/request-helpers.ts","../ai/src/methods/chat-session-helpers.ts","../ai/src/methods/chat-session.ts","../ai/src/methods/count-tokens.ts","../ai/src/models/generative-model.ts","../ai/src/models/imagen-model.ts","../ai/src/types/language-model.ts","../ai/src/methods/chrome-adapter.ts","../ai/src/requests/schema-builder.ts","../ai/src/requests/imagen-image-format.ts","../ai/src/api.ts","../util/src/compat.ts","../ai/src/helpers.ts","../ai/src/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // TypeScript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map<Err, string> = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory<Err>('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap<ErrorCode extends string> = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record<string, unknown>\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget\n // which we can now use since we no longer target ES5.\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap<ErrorCode>\n ) {}\n\n create<K extends ErrorCode>(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component<T extends Name = Name> {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback<T> | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory<T>,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback<T>): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../package.json';\n\nexport const AI_TYPE = 'AI';\n\nexport const DEFAULT_LOCATION = 'us-central1';\n\nexport const DEFAULT_BASE_URL = 'https://firebasevertexai.googleapis.com';\n\nexport const DEFAULT_API_VERSION = 'v1beta';\n\nexport const PACKAGE_VERSION = version;\n\nexport const LANGUAGE_TAG = 'gl-js';\n\nexport const DEFAULT_FETCH_TIMEOUT_MS = 180 * 1000;\n\n/**\n * Defines the name of the default in-cloud model to use for hybrid inference.\n */\nexport const DEFAULT_HYBRID_IN_CLOUD_MODEL = 'gemini-2.0-flash-lite';\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Role is the producer of the content.\n * @public\n */\nexport type Role = (typeof POSSIBLE_ROLES)[number];\n\n/**\n * Possible roles.\n * @public\n */\nexport const POSSIBLE_ROLES = ['user', 'model', 'function', 'system'] as const;\n\n/**\n * Harm categories that would cause prompts or candidates to be blocked.\n * @public\n */\nexport const HarmCategory = {\n HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH',\n HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT',\n HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT'\n} as const;\n\n/**\n * Harm categories that would cause prompts or candidates to be blocked.\n * @public\n */\nexport type HarmCategory = (typeof HarmCategory)[keyof typeof HarmCategory];\n\n/**\n * Threshold above which a prompt or candidate will be blocked.\n * @public\n */\nexport const HarmBlockThreshold = {\n /**\n * Content with `NEGLIGIBLE` will be allowed.\n */\n BLOCK_LOW_AND_ABOVE: 'BLOCK_LOW_AND_ABOVE',\n /**\n * Content with `NEGLIGIBLE` and `LOW` will be allowed.\n */\n BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE',\n /**\n * Content with `NEGLIGIBLE`, `LOW`, and `MEDIUM` will be allowed.\n */\n BLOCK_ONLY_HIGH: 'BLOCK_ONLY_HIGH',\n /**\n * All content will be allowed.\n */\n BLOCK_NONE: 'BLOCK_NONE',\n /**\n * All content will be allowed. This is the same as `BLOCK_NONE`, but the metadata corresponding\n * to the {@link (HarmCategory:type)} will not be present in the response.\n */\n OFF: 'OFF'\n} as const;\n\n/**\n * Threshold above which a prompt or candidate will be blocked.\n * @public\n */\nexport type HarmBlockThreshold =\n (typeof HarmBlockThreshold)[keyof typeof HarmBlockThreshold];\n\n/**\n * This property is not supported in the Gemini Developer API ({@link GoogleAIBackend}).\n *\n * @public\n */\nexport const HarmBlockMethod = {\n /**\n * The harm block method uses both probability and severity scores.\n */\n SEVERITY: 'SEVERITY',\n /**\n * The harm block method uses the probability score.\n */\n PROBABILITY: 'PROBABILITY'\n} as const;\n\n/**\n * This property is not supported in the Gemini Developer API ({@link GoogleAIBackend}).\n *\n * @public\n */\nexport type HarmBlockMethod =\n (typeof HarmBlockMethod)[keyof typeof HarmBlockMethod];\n\n/**\n * Probability that a prompt or candidate matches a harm category.\n * @public\n */\nexport const HarmProbability = {\n /**\n * Content has a negligible chance of being unsafe.\n */\n NEGLIGIBLE: 'NEGLIGIBLE',\n /**\n * Content has a low chance of being unsafe.\n */\n LOW: 'LOW',\n /**\n * Content has a medium chance of being unsafe.\n */\n MEDIUM: 'MEDIUM',\n /**\n * Content has a high chance of being unsafe.\n */\n HIGH: 'HIGH'\n} as const;\n\n/**\n * Probability that a prompt or candidate matches a harm category.\n * @public\n */\nexport type HarmProbability =\n (typeof HarmProbability)[keyof typeof HarmProbability];\n\n/**\n * Harm severity levels.\n * @public\n */\nexport const HarmSeverity = {\n /**\n * Negligible level of harm severity.\n */\n HARM_SEVERITY_NEGLIGIBLE: 'HARM_SEVERITY_NEGLIGIBLE',\n /**\n * Low level of harm severity.\n */\n HARM_SEVERITY_LOW: 'HARM_SEVERITY_LOW',\n /**\n * Medium level of harm severity.\n */\n HARM_SEVERITY_MEDIUM: 'HARM_SEVERITY_MEDIUM',\n /**\n * High level of harm severity.\n */\n HARM_SEVERITY_HIGH: 'HARM_SEVERITY_HIGH',\n /**\n * Harm severity is not supported.\n *\n * @remarks\n * The GoogleAI backend does not support `HarmSeverity`, so this value is used as a fallback.\n */\n HARM_SEVERITY_UNSUPPORTED: 'HARM_SEVERITY_UNSUPPORTED'\n} as const;\n\n/**\n * Harm severity levels.\n * @public\n */\nexport type HarmSeverity = (typeof HarmSeverity)[keyof typeof HarmSeverity];\n\n/**\n * Reason that a prompt was blocked.\n * @public\n */\nexport const BlockReason = {\n /**\n * Content was blocked by safety settings.\n */\n SAFETY: 'SAFETY',\n /**\n * Content was blocked, but the reason is uncategorized.\n */\n OTHER: 'OTHER',\n /**\n * Content was blocked because it contained terms from the terminology blocklist.\n */\n BLOCKLIST: 'BLOCKLIST',\n /**\n * Content was blocked due to prohibited content.\n */\n PROHIBITED_CONTENT: 'PROHIBITED_CONTENT'\n} as const;\n\n/**\n * Reason that a prompt was blocked.\n * @public\n */\nexport type BlockReason = (typeof BlockReason)[keyof typeof BlockReason];\n\n/**\n * Reason that a candidate finished.\n * @public\n */\nexport const FinishReason = {\n /**\n * Natural stop point of the model or provided stop sequence.\n */\n STOP: 'STOP',\n /**\n * The maximum number of tokens as specified in the request was reached.\n */\n MAX_TOKENS: 'MAX_TOKENS',\n /**\n * The candidate content was flagged for safety reasons.\n */\n SAFETY: 'SAFETY',\n /**\n * The candidate content was flagged for recitation reasons.\n */\n RECITATION: 'RECITATION',\n /**\n * Unknown reason.\n */\n OTHER: 'OTHER',\n /**\n * The candidate content contained forbidden terms.\n */\n BLOCKLIST: 'BLOCKLIST',\n /**\n * The candidate content potentially contained prohibited content.\n */\n PROHIBITED_CONTENT: 'PROHIBITED_CONTENT',\n /**\n * The candidate content potentially contained Sensitive Personally Identifiable Information (SPII).\n */\n SPII: 'SPII',\n /**\n * The function call generated by the model was invalid.\n */\n MALFORMED_FUNCTION_CALL: 'MALFORMED_FUNCTION_CALL'\n} as const;\n\n/**\n * Reason that a candidate finished.\n * @public\n */\nexport type FinishReason = (typeof FinishReason)[keyof typeof FinishReason];\n\n/**\n * @public\n */\nexport const FunctionCallingMode = {\n /**\n * Default model behavior; model decides to predict either a function call\n * or a natural language response.\n */\n AUTO: 'AUTO',\n /**\n * Model is constrained to always predicting a function call only.\n * If `allowed_function_names` is set, the predicted function call will be\n * limited to any one of `allowed_function_names`, else the predicted\n * function call will be any one of the provided `function_declarations`.\n */\n ANY: 'ANY',\n /**\n * Model will not predict any function call. Model behavior is same as when\n * not passing any function declarations.\n */\n NONE: 'NONE'\n} as const;\n\n/**\n * @public\n */\nexport type FunctionCallingMode =\n (typeof FunctionCallingMode)[keyof typeof FunctionCallingMode];\n\n/**\n * Content part modality.\n * @public\n */\nexport const Modality = {\n /**\n * Unspecified modality.\n */\n MODALITY_UNSPECIFIED: 'MODALITY_UNSPECIFIED',\n /**\n * Plain text.\n */\n TEXT: 'TEXT',\n /**\n * Image.\n */\n IMAGE: 'IMAGE',\n /**\n * Video.\n */\n VIDEO: 'VIDEO',\n /**\n * Audio.\n */\n AUDIO: 'AUDIO',\n /**\n * Document (for example, PDF).\n */\n DOCUMENT: 'DOCUMENT'\n} as const;\n\n/**\n * Content part modality.\n * @public\n */\nexport type Modality = (typeof Modality)[keyof typeof Modality];\n\n/**\n * Generation modalities to be returned in generation responses.\n *\n * @beta\n */\nexport const ResponseModality = {\n /**\n * Text.\n * @beta\n */\n TEXT: 'TEXT',\n /**\n * Image.\n * @beta\n */\n IMAGE: 'IMAGE'\n} as const;\n\n/**\n * Generation modalities to be returned in generation responses.\n *\n * @beta\n */\nexport type ResponseModality =\n (typeof ResponseModality)[keyof typeof ResponseModality];\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Determines whether inference happens on-device or in-cloud.\n * @public\n */\nexport const InferenceMode = {\n 'PREFER_ON_DEVICE': 'prefer_on_device',\n 'ONLY_ON_DEVICE': 'only_on_device',\n 'ONLY_IN_CLOUD': 'only_in_cloud'\n} as const;\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Determines whether inference happens on-device or in-cloud.\n * @public\n */\nexport type InferenceMode = (typeof InferenceMode)[keyof typeof InferenceMode];\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateContentResponse } from './responses';\n\n/**\n * Details object that may be included in an error response.\n *\n * @public\n */\nexport interface ErrorDetails {\n '@type'?: string;\n\n /** The reason for the error. */\n reason?: string;\n\n /** The domain where the error occurred. */\n domain?: string;\n\n /** Additional metadata about the error. */\n metadata?: Record<string, unknown>;\n\n /** Any other relevant information about the error. */\n [key: string]: unknown;\n}\n\n/**\n * Details object that contains data originating from a bad HTTP response.\n *\n * @public\n */\nexport interface CustomErrorData {\n /** HTTP status code of the error response. */\n status?: number;\n\n /** HTTP status text of the error response. */\n statusText?: string;\n\n /** Response from a {@link GenerateContentRequest} */\n response?: GenerateContentResponse;\n\n /** Optional additional details about the error. */\n errorDetails?: ErrorDetails[];\n}\n\n/**\n * Standardized error codes that {@link AIError} can have.\n *\n * @public\n */\nexport const AIErrorCode = {\n /** A generic error occurred. */\n ERROR: 'error',\n\n /** An error occurred in a request. */\n REQUEST_ERROR: 'request-error',\n\n /** An error occurred in a response. */\n RESPONSE_ERROR: 'response-error',\n\n /** An error occurred while performing a fetch. */\n FETCH_ERROR: 'fetch-error',\n\n /** An error associated with a Content object. */\n INVALID_CONTENT: 'invalid-content',\n\n /** An error due to the Firebase API not being enabled in the Console. */\n API_NOT_ENABLED: 'api-not-enabled',\n\n /** An error due to invalid Schema input. */\n INVALID_SCHEMA: 'invalid-schema',\n\n /** An error occurred due to a missing Firebase API key. */\n NO_API_KEY: 'no-api-key',\n\n /** An error occurred due to a missing Firebase app ID. */\n NO_APP_ID: 'no-app-id',\n\n /** An error occurred due to a model name not being specified during initialization. */\n NO_MODEL: 'no-model',\n\n /** An error occurred due to a missing project ID. */\n NO_PROJECT_ID: 'no-project-id',\n\n /** An error occurred while parsing. */\n PARSE_FAILED: 'parse-failed',\n\n /** An error occurred due an attempt to use an unsupported feature. */\n UNSUPPORTED: 'unsupported'\n} as const;\n\n/**\n * Standardized error codes that {@link AIError} can have.\n *\n * @public\n */\nexport type AIErrorCode = (typeof AIErrorCode)[keyof typeof AIErrorCode];\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Contains the list of OpenAPI data types\n * as defined by the\n * {@link https://swagger.io/docs/specification/data-models/data-types/ | OpenAPI specification}\n * @public\n */\nexport const SchemaType = {\n /** String type. */\n STRING: 'string',\n /** Number type. */\n NUMBER: 'number',\n /** Integer type. */\n INTEGER: 'integer',\n /** Boolean type. */\n BOOLEAN: 'boolean',\n /** Array type. */\n ARRAY: 'array',\n /** Object type. */\n OBJECT: 'object'\n} as const;\n\n/**\n * Contains the list of OpenAPI data types\n * as defined by the\n * {@link https://swagger.io/docs/specification/data-models/data-types/ | OpenAPI specification}\n * @public\n */\nexport type SchemaType = (typeof SchemaType)[keyof typeof SchemaType];\n\n/**\n * Basic {@link Schema} properties shared across several Schema-related\n * types.\n * @public\n */\nexport interface SchemaShared<T> {\n /**\n * An array of {@link Schema}. The generated data must be valid against any of the schemas\n * listed in this array. This allows specifying multiple possible structures or types for a\n * single field.\n */\n anyOf?: T[];\n /** Optional. The format of the property.\n * When using the Gemini Developer API ({@link GoogleAIBackend}), this must be either `'enum'` or\n * `'date-time'`, otherwise requests will fail.\n */\n format?: string;\n /** Optional. The description of the property. */\n description?: string;\n /**\n * The title of the property. This helps document the schema's purpose but does not typically\n * constrain the generated value. It can subtly guide the model by clarifying the intent of a\n * field.\n */\n title?: string;\n /** Optional. The items of the property. */\n items?: T;\n /** The minimum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n minItems?: number;\n /** The maximum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n maxItems?: number;\n /** Optional. Map of `Schema` objects. */\n properties?: {\n [k: string]: T;\n };\n /** A hint suggesting the order in which the keys should appear in the generated JSON string. */\n propertyOrdering?: string[];\n /** Optional. The enum of the property. */\n enum?: string[];\n /** Optional. The example of the property. */\n example?: unknown;\n /** Optional. Whether the property is nullable. */\n nullable?: boolean;\n /** The minimum value of a numeric type. */\n minimum?: number;\n /** The maximum value of a numeric type. */\n maximum?: number;\n [key: string]: unknown;\n}\n\n/**\n * Params passed to {@link Schema} static methods to create specific\n * {@link Schema} classes.\n * @public\n */\nexport interface SchemaParams extends SchemaShared<SchemaInterface> {}\n\n/**\n * Final format for {@link Schema} params passed to backend requests.\n * @public\n */\nexport interface SchemaRequest extends SchemaShared<SchemaRequest> {\n /**\n * The type of the property. this can only be undefined when using `anyOf` schemas,\n * which do not have an explicit type in the {@link https://swagger.io/docs/specification/v3_0/data-models/data-types/#any-type | OpenAPI specification }.\n */\n type?: SchemaType;\n /** Optional. Array of required property. */\n required?: string[];\n}\n\n/**\n * Interface for {@link Schema} class.\n * @public\n */\nexport interface SchemaInterface extends SchemaShared<SchemaInterface> {\n /**\n * The type of the property. this can only be undefined when using `anyof` schemas,\n * which do not have an explicit type in the {@link https://swagger.io/docs/specification/v3_0/data-models/data-types/#any-type | OpenAPI Specification}.\n */\n type?: SchemaType;\n}\n\n/**\n * Interface for JSON parameters in a schema of {@link (SchemaType:type)}\n * \"object\" when not using the `Schema.object()` helper.\n * @public\n */\nexport interface ObjectSchemaRequest extends SchemaRequest {\n type: 'object';\n /**\n * This is not a property accepted in the final request to the backend, but is\n * a client-side convenience property that is only usable by constructing\n * a schema through the `Schema.object()` helper method. Populating this\n * property will cause response errors if the object is not wrapped with\n * `Schema.object()`.\n */\n optionalProperties?: never;\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ImagenImageFormat } from '../../requests/imagen-image-format';\n\n/**\n * Parameters for configuring an {@link ImagenModel}.\n *\n * @beta\n */\nexport interface ImagenModelParams {\n /**\n * The Imagen model to use for generating images.\n * For example: `imagen-3.0-generate-002`.\n *\n * Only Imagen 3 models (named `imagen-3.0-*`) are supported.\n *\n * See {@link https://firebase.google.com/docs/vertex-ai/models | model versions}\n * for a full list of supported Imagen 3 models.\n */\n model: string;\n /**\n * Configuration options for generating images with Imagen.\n */\n generationConfig?: ImagenGenerationConfig;\n /**\n * Safety settings for filtering potentially inappropriate content.\n */\n safetySettings?: ImagenSafetySettings;\n}\n\n/**\n * Configuration options for generating images with Imagen.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/generate-images-imagen | documentation} for\n * more details.\n *\n * @beta\n */\nexport interface ImagenGenerationConfig {\n /**\n * A description of what should be omitted from the generated images.\n *\n * Support for negative prompts depends on the Imagen model.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/model-parameters#imagen | documentation} for more details.\n *\n * This is no longer supported in the Gemini Developer API ({@link GoogleAIBackend}) in versions\n * greater than `imagen-3.0-generate-002`.\n */\n negativePrompt?: string;\n /**\n * The number of images to generate. The default value is 1.\n *\n * The number of sample images that may be generated in each request depends on the model\n * (typically up to 4); see the <a href=\"http://firebase.google.com/docs/vertex-ai/model-parameters#imagen\">sampleCount</a>\n * documentation for more details.\n */\n numberOfImages?: number;\n /**\n * The aspect ratio of the generated images. The default value is square 1:1.\n * Supported aspect ratios depend on the Imagen model, see {@link (ImagenAspectRatio:type)}\n * for more details.\n */\n aspectRatio?: ImagenAspectRatio;\n /**\n * The image format of the generated images. The default is PNG.\n *\n * See {@link ImagenImageFormat} for more details.\n */\n imageFormat?: ImagenImageFormat;\n /**\n * Whether to add an invisible watermark to generated images.\n *\n * If set to `true`, an invisible SynthID watermark is embedded in generated images to indicate\n * that they are AI generated. If set to `false`, watermarking will be disabled.\n *\n * For Imagen 3 models, the default value is `true`; see the <a href=\"http://firebase.google.com/docs/vertex-ai/model-parameters#imagen\">addWatermark</a>\n * documentation for more details.\n *\n * When using the Gemini Developer API ({@link GoogleAIBackend}), this will default to true,\n * and cannot be turned off.\n */\n addWatermark?: boolean;\n}\n\n/**\n * A filter level controlling how aggressively to filter sensitive content.\n *\n * Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI\n * are assessed against a list of safety filters, which include 'harmful categories' (for example,\n * `violence`, `sexual`, `derogatory`, and `toxic`). This filter level controls how aggressively to\n * filter out potentially harmful content from responses. See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * and the {@link https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters | Responsible AI and usage guidelines}\n * for more details.\n *\n * @beta\n */\nexport const ImagenSafetyFilterLevel = {\n /**\n * The most aggressive filtering level; most strict blocking.\n */\n BLOCK_LOW_AND_ABOVE: 'block_low_and_above',\n /**\n * Blocks some sensitive prompts and responses.\n */\n BLOCK_MEDIUM_AND_ABOVE: 'block_medium_and_above',\n /**\n * Blocks few sensitive prompts and responses.\n */\n BLOCK_ONLY_HIGH: 'block_only_high',\n /**\n * The least aggressive filtering level; blocks very few sensitive prompts and responses.\n *\n * Access to this feature is restricted and may require your case to be reviewed and approved by\n * Cloud support.\n */\n BLOCK_NONE: 'block_none'\n} as const;\n\n/**\n * A filter level controlling how aggressively to filter sensitive content.\n *\n * Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI\n * are assessed against a list of safety filters, which include 'harmful categories' (for example,\n * `violence`, `sexual`, `derogatory`, and `toxic`). This filter level controls how aggressively to\n * filter out potentially harmful content from responses. See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * and the {@link https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters | Responsible AI and usage guidelines}\n * for more details.\n *\n * @beta\n */\nexport type ImagenSafetyFilterLevel =\n (typeof ImagenSafetyFilterLevel)[keyof typeof ImagenSafetyFilterLevel];\n\n/**\n * A filter level controlling whether generation of images containing people or faces is allowed.\n *\n * See the <a href=\"http://firebase.google.com/docs/vertex-ai/generate-images\">personGeneration</a>\n * documentation for more details.\n *\n * @beta\n */\nexport const ImagenPersonFilterLevel = {\n /**\n * Disallow generation of images containing people or faces; images of people are filtered out.\n */\n BLOCK_ALL: 'dont_allow',\n /**\n * Allow generation of images containing adults only; images of children are filtered out.\n *\n * Generation of images containing people or faces may require your use case to be\n * 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}\n * for more details.\n */\n ALLOW_ADULT: 'allow_adult',\n /**\n * Allow generation of images containing adults only; images of children are filtered out.\n *\n * Generation of images containing people or faces may require your use case to be\n * 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}\n * for more details.\n */\n ALLOW_ALL: 'allow_all'\n} as const;\n\n/**\n * A filter level controlling whether generation of images containing people or faces is allowed.\n *\n * See the <a href=\"http://firebase.google.com/docs/vertex-ai/generate-images\">personGeneration</a>\n * documentation for more details.\n *\n * @beta\n */\nexport type ImagenPersonFilterLevel =\n (typeof ImagenPersonFilterLevel)[keyof typeof ImagenPersonFilterLevel];\n\n/**\n * Settings for controlling the aggressiveness of filtering out sensitive content.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * for more details.\n *\n * @beta\n */\nexport interface ImagenSafetySettings {\n /**\n * A filter level controlling how aggressive to filter out sensitive content from generated\n * images.\n */\n safetyFilterLevel?: ImagenSafetyFilterLevel;\n /**\n * A filter level controlling whether generation of images containing people or faces is allowed.\n */\n personFilterLevel?: ImagenPersonFilterLevel;\n}\n\n/**\n * Aspect ratios for Imagen images.\n *\n * To specify an aspect ratio for generated images, set the `aspectRatio` property in your\n * {@link ImagenGenerationConfig}.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * for more details and examples of the supported aspect ratios.\n *\n * @beta\n */\nexport const ImagenAspectRatio = {\n /**\n * Square (1:1) aspect ratio.\n */\n 'SQUARE': '1:1',\n /**\n * Landscape (3:4) aspect ratio.\n */\n 'LANDSCAPE_3x4': '3:4',\n /**\n * Portrait (4:3) aspect ratio.\n */\n 'PORTRAIT_4x3': '4:3',\n /**\n * Landscape (16:9) aspect ratio.\n */\n 'LANDSCAPE_16x9': '16:9',\n /**\n * Portrait (9:16) aspect ratio.\n */\n 'PORTRAIT_9x16': '9:16'\n} as const;\n\n/**\n * Aspect ratios for Imagen images.\n *\n * To specify an aspect ratio for generated images, set the `aspectRatio` property in your\n * {@link ImagenGenerationConfig}.\n *\n * See the {@link http://firebase.google.com/docs/vertex-ai/generate-images | documentation }\n * for more details and examples of the supported aspect ratios.\n *\n * @beta\n */\nexport type ImagenAspectRatio =\n (typeof ImagenAspectRatio)[keyof typeof ImagenAspectRatio];\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from '@firebase/app';\nimport { Backend } from './backend';\n\nexport * from './types';\n\n/**\n * An instance of the Firebase AI SDK.\n *\n * Do not create this instance directly. Instead, use {@link getAI | getAI()}.\n *\n * @public\n */\nexport interface AI {\n /**\n * The {@link @firebase/app#FirebaseApp} this {@link AI} instance is associated with.\n */\n app: FirebaseApp;\n /**\n * A {@link Backend} instance that specifies the configuration for the target backend,\n * either the Gemini Developer API (using {@link GoogleAIBackend}) or the\n * Vertex AI Gemini API (using {@link VertexAIBackend}).\n */\n backend: Backend;\n /**\n * @deprecated use `AI.backend.location` instead.\n *\n * The location configured for this AI service instance, relevant for Vertex AI backends.\n */\n location: string;\n}\n\n/**\n * An enum-like object containing constants that represent the supported backends\n * for the Firebase AI SDK.\n * This determines which backend service (Vertex AI Gemini API or Gemini Developer API)\n * the SDK will communicate with.\n *\n * These values are assigned to the `backendType` property within the specific backend\n * configuration objects ({@link GoogleAIBackend} or {@link VertexAIBackend}) to identify\n * which service to target.\n *\n * @public\n */\nexport const BackendType = {\n /**\n * Identifies the backend service for the Vertex AI Gemini API provided through Google Cloud.\n * Use this constant when creating a {@link VertexAIBackend} configuration.\n */\n VERTEX_AI: 'VERTEX_AI',\n\n /**\n * Identifies the backend service for the Gemini Developer API ({@link https://ai.google/ | Google AI}).\n * Use this constant when creating a {@link GoogleAIBackend} configuration.\n */\n GOOGLE_AI: 'GOOGLE_AI'\n} as const; // Using 'as const' makes the string values literal types\n\n/**\n * Type alias representing valid backend types.\n * It can be either `'VERTEX_AI'` or `'GOOGLE_AI'`.\n *\n * @public\n */\nexport type BackendType = (typeof BackendType)[keyof typeof BackendType];\n\n/**\n * Options for initializing the AI service using {@link getAI | getAI()}.\n * This allows specifying which backend to use (Vertex AI Gemini API or Gemini Developer API)\n * and configuring its specific options (like location for Vertex AI).\n *\n * @public\n */\nexport interface AIOptions {\n /**\n * The backend configuration to use for the AI service instance.\n */\n backend: Backend;\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_LOCATION } from './constants';\nimport { BackendType } from './public-types';\n\n/**\n * Abstract base class representing the configuration for an AI service backend.\n * This class should not be instantiated directly. Use its subclasses; {@link GoogleAIBackend} for\n * the Gemini Developer API (via {@link https://ai.google/ | Google AI}), and\n * {@link VertexAIBackend} for the Vertex AI Gemini API.\n *\n * @public\n */\nexport abstract class Backend {\n /**\n * Specifies the backend type.\n */\n readonly backendType: BackendType;\n\n /**\n * Protected constructor for use by subclasses.\n * @param type - The backend type.\n */\n protected constructor(type: BackendType) {\n this.backendType = type;\n }\n}\n\n/**\n * Configuration class for the Gemini Developer API.\n *\n * Use this with {@link AIOptions} when initializing the AI service via\n * {@link getAI | getAI()} to specify the Gemini Developer API as the backend.\n *\n * @public\n */\nexport class GoogleAIBackend extends Backend {\n /**\n * Creates a configuration object for the Gemini Developer API backend.\n */\n constructor() {\n super(BackendType.GOOGLE_AI);\n }\n}\n\n/**\n * Configuration class for the Vertex AI Gemini API.\n *\n * Use this with {@link AIOptions} when initializing the AI service via\n * {@link getAI | getAI()} to specify the Vertex AI Gemini API as the backend.\n *\n * @public\n */\nexport class VertexAIBackend extends Backend {\n /**\n * The region identifier.\n * See {@link https://firebase.google.com/docs/vertex-ai/locations#available-locations | Vertex AI locations}\n * for a list of supported locations.\n */\n readonly location: string;\n\n /**\n * Creates a configuration object for the Vertex AI backend.\n *\n * @param location - The region identifier, defaulting to `us-central1`;\n * see {@link https://firebase.google.com/docs/vertex-ai/locations#available-locations | Vertex AI locations}\n * for a list of supported locations.\n */\n constructor(location: string = DEFAULT_LOCATION) {\n super(BackendType.VERTEX_AI);\n if (!location) {\n this.location = DEFAULT_LOCATION;\n } else {\n this.location = location;\n }\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _FirebaseService } from '@firebase/app';\nimport { AI } from './public-types';\nimport {\n AppCheckInternalComponentName,\n FirebaseAppCheckInternal\n} from '@firebase/app-check-interop-types';\nimport { Provider } from '@firebase/component';\nimport {\n FirebaseAuthInternal,\n FirebaseAuthInternalName\n} from '@firebase/auth-interop-types';\nimport { Backend, VertexAIBackend } from './backend';\n\nexport class AIService implements AI, _FirebaseService {\n auth: FirebaseAuthInternal | null;\n appCheck: FirebaseAppCheckInternal | null;\n location: string; // This is here for backwards-compatibility\n\n constructor(\n public app: FirebaseApp,\n public backend: Backend,\n authProvider?: Provider<FirebaseAuthInternalName>,\n appCheckProvider?: Provider<AppCheckInternalComponentName>\n ) {\n const appCheck = appCheckProvider?.getImmediate({ optional: true });\n const auth = authProvider?.getImmediate({ optional: true });\n this.auth = auth || null;\n this.appCheck = appCheck || null;\n\n if (backend instanceof VertexAIBackend) {\n this.location = backend.location;\n } else {\n this.location = '';\n }\n }\n\n _delete(): Promise<void> {\n return Promise.resolve();\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { AIErrorCode, CustomErrorData } from './types';\nimport { AI_TYPE } from './constants';\n\n/**\n * Error class for the Firebase AI SDK.\n *\n * @public\n */\nexport class AIError extends FirebaseError {\n /**\n * Constructs a new instance of the `AIError` class.\n *\n * @param code - The error code from {@link (AIErrorCode:type)}.\n * @param message - A human-readable message describing the error.\n * @param customErrorData - Optional error data.\n */\n constructor(\n readonly code: AIErrorCode,\n message: string,\n readonly customErrorData?: CustomErrorData\n ) {\n // Match error format used by FirebaseError from ErrorFactory\n const service = AI_TYPE;\n const fullCode = `${service}/${code}`;\n const fullMessage = `${service}: ${message} (${fullCode})`;\n super(code, fullMessage);\n\n // FirebaseError initializes a stack trace, but it assumes the error is created from the error\n // factory. Since we break this assumption, we set the stack trace to be originating from this\n // constructor.\n // This is only supported in V8.\n if (Error.captureStackTrace) {\n // Allows us to initialize the stack trace without including the constructor itself at the\n // top level of the stack trace.\n Error.captureStackTrace(this, AIError);\n }\n\n // Allows instanceof AIError in ES5/ES6\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget\n // which we can now use since we no longer target ES5.\n Object.setPrototypeOf(this, AIError.prototype);\n\n // Since Error is an interface, we don't inherit toString and so we define it ourselves.\n this.toString = () => fullMessage;\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from '../errors';\nimport { AIErrorCode, AI, BackendType } from '../public-types';\nimport { AIService } from '../service';\nimport { ApiSettings } from '../types/internal';\nimport { _isFirebaseServerApp } from '@firebase/app';\n\n/**\n * Base class for Firebase AI model APIs.\n *\n * Instances of this class are associated with a specific Firebase AI {@link Backend}\n * and provide methods for interacting with the configured generative model.\n *\n * @public\n */\nexport abstract class AIModel {\n /**\n * The fully qualified model resource name to use for generating images\n * (for example, `publishers/google/models/imagen-3.0-generate-002`).\n */\n readonly model: string;\n\n /**\n * @internal\n */\n protected _apiSettings: ApiSettings;\n\n /**\n * Constructs a new instance of the {@link AIModel} class.\n *\n * This constructor should only be called from subclasses that provide\n * a model API.\n *\n * @param ai - an {@link AI} instance.\n * @param modelName - The name of the model being used. It can be in one of the following formats:\n * - `my-model` (short name, will resolve to `publishers/google/models/my-model`)\n * - `models/my-model` (will resolve to `publishers/google/models/my-model`)\n * - `publishers/my-publisher/models/my-model` (fully qualified model name)\n *\n * @throws If the `apiKey` or `projectId` fields are missing in your\n * Firebase config.\n *\n * @internal\n */\n protected constructor(ai: AI, modelName: string) {\n if (!ai.app?.options?.apiKey) {\n throw new AIError(\n AIErrorCode.NO_API_KEY,\n `The \"apiKey\" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid API key.`\n );\n } else if (!ai.app?.options?.projectId) {\n throw new AIError(\n AIErrorCode.NO_PROJECT_ID,\n `The \"projectId\" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid project ID.`\n );\n } else if (!ai.app?.options?.appId) {\n throw new AIError(\n AIErrorCode.NO_APP_ID,\n `The \"appId\" field is empty in the local Firebase config. Firebase AI requires this field to contain a valid app ID.`\n );\n } else {\n this._apiSettings = {\n apiKey: ai.app.options.apiKey,\n project: ai.app.options.projectId,\n appId: ai.app.options.appId,\n automaticDataCollectionEnabled: ai.app.automaticDataCollectionEnabled,\n location: ai.location,\n backend: ai.backend\n };\n\n if (_isFirebaseServerApp(ai.app) && ai.app.settings.appCheckToken) {\n const token = ai.app.settings.appCheckToken;\n this._apiSettings.getAppCheckToken = () => {\n return Promise.resolve({ token });\n };\n } else if ((ai as AIService).appCheck) {\n this._apiSettings.getAppCheckToken = () =>\n (ai as AIService).appCheck!.getToken();\n }\n\n if ((ai as AIService).auth) {\n this._apiSettings.getAuthToken = () =>\n (ai as AIService).auth!.getToken();\n }\n\n this.model = AIModel.normalizeModelName(\n modelName,\n this._apiSettings.backend.backendType\n );\n }\n }\n\n /**\n * Normalizes the given model name to a fully qualified model resource name.\n *\n * @param modelName - The model name to normalize.\n * @returns The fully qualified model resource name.\n *\n * @internal\n */\n static normalizeModelName(\n modelName: string,\n backendType: BackendType\n ): string {\n if (backendType === BackendType.GOOGLE_AI) {\n return AIModel.normalizeGoogleAIModelName(modelName);\n } else {\n return AIModel.normalizeVertexAIModelName(modelName);\n }\n }\n\n /**\n * @internal\n */\n private static normalizeGoogleAIModelName(modelName: string): string {\n return `models/${modelName}`;\n }\n\n /**\n * @internal\n */\n private static normalizeVertexAIModelName(modelName: string): string {\n let model: string;\n if (modelName.includes('/')) {\n if (modelName.startsWith('models/')) {\n // Add 'publishers/google' if the user is only passing in 'models/model-name'.\n model = `publishers/google/${modelName}`;\n } else {\n // Any other custom format (e.g. tuned models) must be passed in correctly.\n model = modelName;\n }\n } else {\n // If path is not included, assume it's a non-tuned model.\n model = `publishers/google/models/${modelName}`;\n }\n\n return model;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/vertexai');\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorDetails, RequestOptions, AIErrorCode } from '../types';\nimport { AIError } from '../errors';\nimport { ApiSettings } from '../types/internal';\nimport {\n DEFAULT_API_VERSION,\n DEFAULT_BASE_URL,\n DEFAULT_FETCH_TIMEOUT_MS,\n LANGUAGE_TAG,\n PACKAGE_VERSION\n} from '../constants';\nimport { logger } from '../logger';\nimport { GoogleAIBackend, VertexAIBackend } from '../backend';\n\nexport enum Task {\n GENERATE_CONTENT = 'generateContent',\n STREAM_GENERATE_CONTENT = 'streamGenerateContent',\n COUNT_TOKENS = 'countTokens',\n PREDICT = 'predict'\n}\n\nexport class RequestUrl {\n constructor(\n public model: string,\n public task: Task,\n public apiSettings: ApiSettings,\n public stream: boolean,\n public requestOptions?: RequestOptions\n ) {}\n toString(): string {\n const url = new URL(this.baseUrl); // Throws if the URL is invalid\n url.pathname = `/${this.apiVersion}/${this.modelPath}:${this.task}`;\n url.search = this.queryParams.toString();\n return url.toString();\n }\n\n private get baseUrl(): string {\n return this.requestOptions?.baseUrl || DEFAULT_BASE_URL;\n }\n\n private get apiVersion(): string {\n return DEFAULT_API_VERSION; // TODO: allow user-set options if that feature becomes available\n }\n\n private get modelPath(): string {\n if (this.apiSettings.backend instanceof GoogleAIBackend) {\n return `projects/${this.apiSettings.project}/${this.model}`;\n } else if (this.apiSettings.backend instanceof VertexAIBackend) {\n return `projects/${this.apiSettings.project}/locations/${this.apiSettings.backend.location}/${this.model}`;\n } else {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid backend: ${JSON.stringify(this.apiSettings.backend)}`\n );\n }\n }\n\n private get queryParams(): URLSearchParams {\n const params = new URLSearchParams();\n if (this.stream) {\n params.set('alt', 'sse');\n }\n\n return params;\n }\n}\n\n/**\n * Log language and \"fire/version\" to x-goog-api-client\n */\nfunction getClientHeaders(): string {\n const loggingTags = [];\n loggingTags.push(`${LANGUAGE_TAG}/${PACKAGE_VERSION}`);\n loggingTags.push(`fire/${PACKAGE_VERSION}`);\n return loggingTags.join(' ');\n}\n\nexport async function getHeaders(url: RequestUrl): Promise<Headers> {\n const headers = new Headers();\n headers.append('Content-Type', 'application/json');\n headers.append('x-goog-api-client', getClientHeaders());\n headers.append('x-goog-api-key', url.apiSettings.apiKey);\n if (url.apiSettings.automaticDataCollectionEnabled) {\n headers.append('X-Firebase-Appid', url.apiSettings.appId);\n }\n if (url.apiSettings.getAppCheckToken) {\n const appCheckToken = await url.apiSettings.getAppCheckToken();\n if (appCheckToken) {\n headers.append('X-Firebase-AppCheck', appCheckToken.token);\n if (appCheckToken.error) {\n logger.warn(\n `Unable to obtain a valid App Check token: ${appCheckToken.error.message}`\n );\n }\n }\n }\n\n if (url.apiSettings.getAuthToken) {\n const authToken = await url.apiSettings.getAuthToken();\n if (authToken) {\n headers.append('Authorization', `Firebase ${authToken.accessToken}`);\n }\n }\n\n return headers;\n}\n\nexport async function constructRequest(\n model: string,\n task: Task,\n apiSettings: ApiSettings,\n stream: boolean,\n body: string,\n requestOptions?: RequestOptions\n): Promise<{ url: string; fetchOptions: RequestInit }> {\n const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);\n return {\n url: url.toString(),\n fetchOptions: {\n method: 'POST',\n headers: await getHeaders(url),\n body\n }\n };\n}\n\nexport async function makeRequest(\n model: string,\n task: Task,\n apiSettings: ApiSettings,\n stream: boolean,\n body: string,\n requestOptions?: RequestOptions\n): Promise<Response> {\n const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);\n let response;\n let fetchTimeoutId: string | number | NodeJS.Timeout | undefined;\n try {\n const request = await constructRequest(\n model,\n task,\n apiSettings,\n stream,\n body,\n requestOptions\n );\n // Timeout is 180s by default\n const timeoutMillis =\n requestOptions?.timeout != null && requestOptions.timeout >= 0\n ? requestOptions.timeout\n : DEFAULT_FETCH_TIMEOUT_MS;\n const abortController = new AbortController();\n fetchTimeoutId = setTimeout(() => abortController.abort(), timeoutMillis);\n request.fetchOptions.signal = abortController.signal;\n\n response = await fetch(request.url, request.fetchOptions);\n if (!response.ok) {\n let message = '';\n let errorDetails;\n try {\n const json = await response.json();\n message = json.error.message;\n if (json.error.details) {\n message += ` ${JSON.stringify(json.error.details)}`;\n errorDetails = json.error.details;\n }\n } catch (e) {\n // ignored\n }\n if (\n response.status === 403 &&\n errorDetails &&\n errorDetails.some(\n (detail: ErrorDetails) => detail.reason === 'SERVICE_DISABLED'\n ) &&\n errorDetails.some((detail: ErrorDetails) =>\n (\n detail.links as Array<Record<string, string>>\n )?.[0]?.description.includes(\n 'Google developers console API activation'\n )\n )\n ) {\n throw new AIError(\n AIErrorCode.API_NOT_ENABLED,\n `The Firebase AI SDK requires the Firebase AI ` +\n `API ('firebasevertexai.googleapis.com') to be enabled in your ` +\n `Firebase project. Enable this API by visiting the Firebase Console ` +\n `at https://console.firebase.google.com/project/${url.apiSettings.project}/genai/ ` +\n `and clicking \"Get started\". If you enabled this API recently, ` +\n `wait a few minutes for the action to propagate to our systems and ` +\n `then retry.`,\n {\n status: response.status,\n statusText: response.statusText,\n errorDetails\n }\n );\n }\n throw new AIError(\n AIErrorCode.FETCH_ERROR,\n `Error fetching from ${url}: [${response.status} ${response.statusText}] ${message}`,\n {\n status: response.status,\n statusText: response.statusText,\n errorDetails\n }\n );\n }\n } catch (e) {\n let err = e as Error;\n if (\n (e as AIError).code !== AIErrorCode.FETCH_ERROR &&\n (e as AIError).code !== AIErrorCode.API_NOT_ENABLED &&\n e instanceof Error\n ) {\n err = new AIError(\n AIErrorCode.ERROR,\n `Error fetching from ${url.toString()}: ${e.message}`\n );\n err.stack = e.stack;\n }\n\n throw err;\n } finally {\n if (fetchTimeoutId) {\n clearTimeout(fetchTimeoutId);\n }\n }\n return response;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EnhancedGenerateContentResponse,\n FinishReason,\n FunctionCall,\n GenerateContentCandidate,\n GenerateContentResponse,\n ImagenGCSImage,\n ImagenInlineImage,\n AIErrorCode,\n InlineDataPart\n} from '../types';\nimport { AIError } from '../errors';\nimport { logger } from '../logger';\nimport { ImagenResponseInternal } from '../types/internal';\n\n/**\n * Creates an EnhancedGenerateContentResponse object that has helper functions and\n * other modifications that improve usability.\n */\nexport function createEnhancedContentResponse(\n response: GenerateContentResponse\n): EnhancedGenerateContentResponse {\n /**\n * The Vertex AI backend omits default values.\n * This causes the `index` property to be omitted from the first candidate in the\n * response, since it has index 0, and 0 is a default value.\n * See: https://github.com/firebase/firebase-js-sdk/issues/8566\n */\n if (response.candidates && !response.candidates[0].hasOwnProperty('index')) {\n response.candidates[0].index = 0;\n }\n\n const responseWithHelpers = addHelpers(response);\n return responseWithHelpers;\n}\n\n/**\n * Adds convenience helper methods to a response object, including stream\n * chunks (as long as each chunk is a complete GenerateContentResponse JSON).\n */\nexport function addHelpers(\n response: GenerateContentResponse\n): EnhancedGenerateContentResponse {\n (response as EnhancedGenerateContentResponse).text = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n logger.warn(\n `This response had ${response.candidates.length} ` +\n `candidates. Returning text from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`\n );\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Response error: ${formatBlockErrorMessage(\n response\n )}. Response body stored in error.response`,\n {\n response\n }\n );\n }\n return getText(response);\n } else if (response.promptFeedback) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Text not available. ${formatBlockErrorMessage(response)}`,\n {\n response\n }\n );\n }\n return '';\n };\n (response as EnhancedGenerateContentResponse).inlineDataParts = ():\n | InlineDataPart[]\n | undefined => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n logger.warn(\n `This response had ${response.candidates.length} ` +\n `candidates. Returning data from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`\n );\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Response error: ${formatBlockErrorMessage(\n response\n )}. Response body stored in error.response`,\n {\n response\n }\n );\n }\n return getInlineDataParts(response);\n } else if (response.promptFeedback) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Data not available. ${formatBlockErrorMessage(response)}`,\n {\n response\n }\n );\n }\n return undefined;\n };\n (response as EnhancedGenerateContentResponse).functionCalls = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n logger.warn(\n `This response had ${response.candidates.length} ` +\n `candidates. Returning function calls from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`\n );\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Response error: ${formatBlockErrorMessage(\n response\n )}. Response body stored in error.response`,\n {\n response\n }\n );\n }\n return getFunctionCalls(response);\n } else if (response.promptFeedback) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Function call not available. ${formatBlockErrorMessage(response)}`,\n {\n response\n }\n );\n }\n return undefined;\n };\n return response as EnhancedGenerateContentResponse;\n}\n\n/**\n * Returns all text found in all parts of first candidate.\n */\nexport function getText(response: GenerateContentResponse): string {\n const textStrings = [];\n if (response.candidates?.[0].content?.parts) {\n for (const part of response.candidates?.[0].content?.parts) {\n if (part.text) {\n textStrings.push(part.text);\n }\n }\n }\n if (textStrings.length > 0) {\n return textStrings.join('');\n } else {\n return '';\n }\n}\n\n/**\n * Returns {@link FunctionCall}s associated with first candidate.\n */\nexport function getFunctionCalls(\n response: GenerateContentResponse\n): FunctionCall[] | undefined {\n const functionCalls: FunctionCall[] = [];\n if (response.candidates?.[0].content?.parts) {\n for (const part of response.candidates?.[0].content?.parts) {\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n }\n if (functionCalls.length > 0) {\n return functionCalls;\n } else {\n return undefined;\n }\n}\n\n/**\n * Returns {@link InlineDataPart}s in the first candidate if present.\n *\n * @internal\n */\nexport function getInlineDataParts(\n response: GenerateContentResponse\n): InlineDataPart[] | undefined {\n const data: InlineDataPart[] = [];\n\n if (response.candidates?.[0].content?.parts) {\n for (const part of response.candidates?.[0].content?.parts) {\n if (part.inlineData) {\n data.push(part);\n }\n }\n }\n\n if (data.length > 0) {\n return data;\n } else {\n return undefined;\n }\n}\n\nconst badFinishReasons = [FinishReason.RECITATION, FinishReason.SAFETY];\n\nfunction hadBadFinishReason(candidate: GenerateContentCandidate): boolean {\n return (\n !!candidate.finishReason &&\n badFinishReasons.some(reason => reason === candidate.finishReason)\n );\n}\n\nexport function formatBlockErrorMessage(\n response: GenerateContentResponse\n): string {\n let message = '';\n if (\n (!response.candidates || response.candidates.length === 0) &&\n response.promptFeedback\n ) {\n message += 'Response was blocked';\n if (response.promptFeedback?.blockReason) {\n message += ` due to ${response.promptFeedback.blockReason}`;\n }\n if (response.promptFeedback?.blockReasonMessage) {\n message += `: ${response.promptFeedback.blockReasonMessage}`;\n }\n } else if (response.candidates?.[0]) {\n const firstCandidate = response.candidates[0];\n if (hadBadFinishReason(firstCandidate)) {\n message += `Candidate was blocked due to ${firstCandidate.finishReason}`;\n if (firstCandidate.finishMessage) {\n message += `: ${firstCandidate.finishMessage}`;\n }\n }\n }\n return message;\n}\n\n/**\n * Convert a generic successful fetch response body to an Imagen response object\n * that can be returned to the user. This converts the REST APIs response format to our\n * APIs representation of a response.\n *\n * @internal\n */\nexport async function handlePredictResponse<\n T extends ImagenInlineImage | ImagenGCSImage\n>(response: Response): Promise<{ images: T[]; filteredReason?: string }> {\n const responseJson: ImagenResponseInternal = await response.json();\n\n const images: T[] = [];\n let filteredReason: string | undefined = undefined;\n\n // The backend should always send a non-empty array of predictions if the response was successful.\n if (!responseJson.predictions || responseJson.predictions?.length === 0) {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n '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.'\n );\n }\n\n for (const prediction of responseJson.predictions) {\n if (prediction.raiFilteredReason) {\n filteredReason = prediction.raiFilteredReason;\n } else if (prediction.mimeType && prediction.bytesBase64Encoded) {\n images.push({\n mimeType: prediction.mimeType,\n bytesBase64Encoded: prediction.bytesBase64Encoded\n } as T);\n } else if (prediction.mimeType && prediction.gcsUri) {\n images.push({\n mimeType: prediction.mimeType,\n gcsURI: prediction.gcsUri\n } as T);\n } else {\n throw new AIError(\n AIErrorCode.RESPONSE_ERROR,\n `Predictions array in response has missing properties. Response: ${JSON.stringify(\n responseJson\n )}`\n );\n }\n }\n\n return { images, filteredReason };\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from './errors';\nimport { logger } from './logger';\nimport {\n CitationMetadata,\n CountTokensRequest,\n GenerateContentCandidate,\n GenerateContentRequest,\n GenerateContentResponse,\n HarmSeverity,\n InlineDataPart,\n PromptFeedback,\n SafetyRating,\n AIErrorCode\n} from './types';\nimport {\n GoogleAIGenerateContentResponse,\n GoogleAIGenerateContentCandidate,\n GoogleAICountTokensRequest\n} from './types/googleai';\n\n/**\n * This SDK supports both the Vertex AI Gemini API and the Gemini Developer API (using Google AI).\n * The public API prioritizes the format used by the Vertex AI Gemini API.\n * We avoid having two sets of types by translating requests and responses between the two API formats.\n * This translation allows developers to switch between the Vertex AI Gemini API and the Gemini Developer API\n * with minimal code changes.\n *\n * In here are functions that map requests and responses between the two API formats.\n * Requests in the Vertex AI format are mapped to the Google AI format before being sent.\n * Responses from the Google AI backend are mapped back to the Vertex AI format before being returned to the user.\n */\n\n/**\n * Maps a Vertex AI {@link GenerateContentRequest} to a format that can be sent to Google AI.\n *\n * @param generateContentRequest The {@link GenerateContentRequest} to map.\n * @returns A {@link GenerateContentResponse} that conforms to the Google AI format.\n *\n * @throws If the request contains properties that are unsupported by Google AI.\n *\n * @internal\n */\nexport function mapGenerateContentRequest(\n generateContentRequest: GenerateContentRequest\n): GenerateContentRequest {\n generateContentRequest.safetySettings?.forEach(safetySetting => {\n if (safetySetting.method) {\n throw new AIError(\n AIErrorCode.UNSUPPORTED,\n 'SafetySetting.method is not supported in the the Gemini Developer API. Please remove this property.'\n );\n }\n });\n\n if (generateContentRequest.generationConfig?.topK) {\n const roundedTopK = Math.round(\n generateContentRequest.generationConfig.topK\n );\n\n if (roundedTopK !== generateContentRequest.generationConfig.topK) {\n logger.warn(\n 'topK in GenerationConfig has been rounded to the nearest integer to match the format for requests to the Gemini Developer API.'\n );\n generateContentRequest.generationConfig.topK = roundedTopK;\n }\n }\n\n return generateContentRequest;\n}\n\n/**\n * Maps a {@link GenerateContentResponse} from Google AI to the format of the\n * {@link GenerateContentResponse} that we get from VertexAI that is exposed in the public API.\n *\n * @param googleAIResponse The {@link GenerateContentResponse} from Google AI.\n * @returns A {@link GenerateContentResponse} that conforms to the public API's format.\n *\n * @internal\n */\nexport function mapGenerateContentResponse(\n googleAIResponse: GoogleAIGenerateContentResponse\n): GenerateContentResponse {\n const generateContentResponse = {\n candidates: googleAIResponse.candidates\n ? mapGenerateContentCandidates(googleAIResponse.candidates)\n : undefined,\n prompt: googleAIResponse.promptFeedback\n ? mapPromptFeedback(googleAIResponse.promptFeedback)\n : undefined,\n usageMetadata: googleAIResponse.usageMetadata\n };\n\n return generateContentResponse;\n}\n\n/**\n * Maps a Vertex AI {@link CountTokensRequest} to a format that can be sent to Google AI.\n *\n * @param countTokensRequest The {@link CountTokensRequest} to map.\n * @param model The model to count tokens with.\n * @returns A {@link CountTokensRequest} that conforms to the Google AI format.\n *\n * @internal\n */\nexport function mapCountTokensRequest(\n countTokensRequest: CountTokensRequest,\n model: string\n): GoogleAICountTokensRequest {\n const mappedCountTokensRequest: GoogleAICountTokensRequest = {\n generateContentRequest: {\n model,\n ...countTokensRequest\n }\n };\n\n return mappedCountTokensRequest;\n}\n\n/**\n * Maps a Google AI {@link GoogleAIGenerateContentCandidate} to a format that conforms\n * to the Vertex AI API format.\n *\n * @param candidates The {@link GoogleAIGenerateContentCandidate} to map.\n * @returns A {@link GenerateContentCandidate} that conforms to the Vertex AI format.\n *\n * @throws If any {@link Part} in the candidates has a `videoMetadata` property.\n *\n * @internal\n */\nexport function mapGenerateContentCandidates(\n candidates: GoogleAIGenerateContentCandidate[]\n): GenerateContentCandidate[] {\n const mappedCandidates: GenerateContentCandidate[] = [];\n let mappedSafetyRatings: SafetyRating[];\n if (mappedCandidates) {\n candidates.forEach(candidate => {\n // Map citationSources to citations.\n let citationMetadata: CitationMetadata | undefined;\n if (candidate.citationMetadata) {\n citationMetadata = {\n citations: candidate.citationMetadata.citationSources\n };\n }\n\n // Assign missing candidate SafetyRatings properties to their defaults if undefined.\n if (candidate.safetyRatings) {\n mappedSafetyRatings = candidate.safetyRatings.map(safetyRating => {\n return {\n ...safetyRating,\n severity:\n safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,\n probabilityScore: safetyRating.probabilityScore ?? 0,\n severityScore: safetyRating.severityScore ?? 0\n };\n });\n }\n\n // videoMetadata is not supported.\n // Throw early since developers may send a long video as input and only expect to pay\n // for inference on a small portion of the video.\n if (\n candidate.content?.parts.some(\n part => (part as InlineDataPart)?.videoMetadata\n )\n ) {\n throw new AIError(\n AIErrorCode.UNSUPPORTED,\n 'Part.videoMetadata is not supported in the Gemini Developer API. Please remove this property.'\n );\n }\n\n const mappedCandidate = {\n index: candidate.index,\n content: candidate.content,\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n safetyRatings: mappedSafetyRatings,\n citationMetadata,\n groundingMetadata: candidate.groundingMetadata\n };\n mappedCandidates.push(mappedCandidate);\n });\n }\n\n return mappedCandidates;\n}\n\nexport function mapPromptFeedback(\n promptFeedback: PromptFeedback\n): PromptFeedback {\n // Assign missing SafetyRating properties to their defaults if undefined.\n const mappedSafetyRatings: SafetyRating[] = [];\n promptFeedback.safetyRatings.forEach(safetyRating => {\n mappedSafetyRatings.push({\n category: safetyRating.category,\n probability: safetyRating.probability,\n severity: safetyRating.severity ?? HarmSeverity.HARM_SEVERITY_UNSUPPORTED,\n probabilityScore: safetyRating.probabilityScore ?? 0,\n severityScore: safetyRating.severityScore ?? 0,\n blocked: safetyRating.blocked\n });\n });\n\n const mappedPromptFeedback: PromptFeedback = {\n blockReason: promptFeedback.blockReason,\n safetyRatings: mappedSafetyRatings,\n blockReasonMessage: promptFeedback.blockReasonMessage\n };\n return mappedPromptFeedback;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EnhancedGenerateContentResponse,\n GenerateContentCandidate,\n GenerateContentResponse,\n GenerateContentStreamResult,\n Part,\n AIErrorCode\n} from '../types';\nimport { AIError } from '../errors';\nimport { createEnhancedContentResponse } from './response-helpers';\nimport * as GoogleAIMapper from '../googleai-mappers';\nimport { GoogleAIGenerateContentResponse } from '../types/googleai';\nimport { ApiSettings } from '../types/internal';\nimport { BackendType } from '../public-types';\n\nconst responseLineRE = /^data\\: (.*)(?:\\n\\n|\\r\\r|\\r\\n\\r\\n)/;\n\n/**\n * Process a response.body stream from the backend and return an\n * iterator that provides one complete GenerateContentResponse at a time\n * and a promise that resolves with a single aggregated\n * GenerateContentResponse.\n *\n * @param response - Response from a fetch call\n */\nexport function processStream(\n response: Response,\n apiSettings: ApiSettings\n): GenerateContentStreamResult {\n const inputStream = response.body!.pipeThrough(\n new TextDecoderStream('utf8', { fatal: true })\n );\n const responseStream =\n getResponseStream<GenerateContentResponse>(inputStream);\n const [stream1, stream2] = responseStream.tee();\n return {\n stream: generateResponseSequence(stream1, apiSettings),\n response: getResponsePromise(stream2, apiSettings)\n };\n}\n\nasync function getResponsePromise(\n stream: ReadableStream<GenerateContentResponse>,\n apiSettings: ApiSettings\n): Promise<EnhancedGenerateContentResponse> {\n const allResponses: GenerateContentResponse[] = [];\n const reader = stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n let generateContentResponse = aggregateResponses(allResponses);\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n generateContentResponse = GoogleAIMapper.mapGenerateContentResponse(\n generateContentResponse as GoogleAIGenerateContentResponse\n );\n }\n return createEnhancedContentResponse(generateContentResponse);\n }\n\n allResponses.push(value);\n }\n}\n\nasync function* generateResponseSequence(\n stream: ReadableStream<GenerateContentResponse>,\n apiSettings: ApiSettings\n): AsyncGenerator<EnhancedGenerateContentResponse> {\n const reader = stream.getReader();\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n break;\n }\n\n let enhancedResponse: EnhancedGenerateContentResponse;\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n enhancedResponse = createEnhancedContentResponse(\n GoogleAIMapper.mapGenerateContentResponse(\n value as GoogleAIGenerateContentResponse\n )\n );\n } else {\n enhancedResponse = createEnhancedContentResponse(value);\n }\n\n yield enhancedResponse;\n }\n}\n\n/**\n * Reads a raw stream from the fetch response and join incomplete\n * chunks, returning a new stream that provides a single complete\n * GenerateContentResponse in each iteration.\n */\nexport function getResponseStream<T>(\n inputStream: ReadableStream<string>\n): ReadableStream<T> {\n const reader = inputStream.getReader();\n const stream = new ReadableStream<T>({\n start(controller) {\n let currentText = '';\n return pump();\n function pump(): Promise<(() => Promise<void>) | undefined> {\n return reader.read().then(({ value, done }) => {\n if (done) {\n if (currentText.trim()) {\n controller.error(\n new AIError(AIErrorCode.PARSE_FAILED, 'Failed to parse stream')\n );\n return;\n }\n controller.close();\n return;\n }\n\n currentText += value;\n let match = currentText.match(responseLineRE);\n let parsedResponse: T;\n while (match) {\n try {\n parsedResponse = JSON.parse(match[1]);\n } catch (e) {\n controller.error(\n new AIError(\n AIErrorCode.PARSE_FAILED,\n `Error parsing JSON response: \"${match[1]}`\n )\n );\n return;\n }\n controller.enqueue(parsedResponse);\n currentText = currentText.substring(match[0].length);\n match = currentText.match(responseLineRE);\n }\n return pump();\n });\n }\n }\n });\n return stream;\n}\n\n/**\n * Aggregates an array of `GenerateContentResponse`s into a single\n * GenerateContentResponse.\n */\nexport function aggregateResponses(\n responses: GenerateContentResponse[]\n): GenerateContentResponse {\n const lastResponse = responses[responses.length - 1];\n const aggregatedResponse: GenerateContentResponse = {\n promptFeedback: lastResponse?.promptFeedback\n };\n for (const response of responses) {\n if (response.candidates) {\n for (const candidate of response.candidates) {\n // Index will be undefined if it's the first index (0), so we should use 0 if it's undefined.\n // See: https://github.com/firebase/firebase-js-sdk/issues/8566\n const i = candidate.index || 0;\n if (!aggregatedResponse.candidates) {\n aggregatedResponse.candidates = [];\n }\n if (!aggregatedResponse.candidates[i]) {\n aggregatedResponse.candidates[i] = {\n index: candidate.index\n } as GenerateContentCandidate;\n }\n // Keep overwriting, the last one will be final\n aggregatedResponse.candidates[i].citationMetadata =\n candidate.citationMetadata;\n aggregatedResponse.candidates[i].finishReason = candidate.finishReason;\n aggregatedResponse.candidates[i].finishMessage =\n candidate.finishMessage;\n aggregatedResponse.candidates[i].safetyRatings =\n candidate.safetyRatings;\n aggregatedResponse.candidates[i].groundingMetadata =\n candidate.groundingMetadata;\n\n /**\n * Candidates should always have content and parts, but this handles\n * possible malformed responses.\n */\n if (candidate.content && candidate.content.parts) {\n if (!aggregatedResponse.candidates[i].content) {\n aggregatedResponse.candidates[i].content = {\n role: candidate.content.role || 'user',\n parts: []\n };\n }\n const newPart: Partial<Part> = {};\n for (const part of candidate.content.parts) {\n if (part.text !== undefined) {\n // The backend can send empty text parts. If these are sent back\n // (e.g. in chat history), the backend will respond with an error.\n // To prevent this, ignore empty text parts.\n if (part.text === '') {\n continue;\n }\n newPart.text = part.text;\n }\n if (part.functionCall) {\n newPart.functionCall = part.functionCall;\n }\n if (Object.keys(newPart).length === 0) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n 'Part should have at least one property, but there are none. This is likely caused ' +\n 'by a malformed response from the backend.'\n );\n }\n aggregatedResponse.candidates[i].content.parts.push(\n newPart as Part\n );\n }\n }\n }\n }\n }\n return aggregatedResponse;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GenerateContentRequest,\n GenerateContentResponse,\n GenerateContentResult,\n GenerateContentStreamResult,\n RequestOptions\n} from '../types';\nimport { Task, makeRequest } from '../requests/request';\nimport { createEnhancedContentResponse } from '../requests/response-helpers';\nimport { processStream } from '../requests/stream-reader';\nimport { ApiSettings } from '../types/internal';\nimport * as GoogleAIMapper from '../googleai-mappers';\nimport { BackendType } from '../public-types';\nimport { ChromeAdapter } from '../types/chrome-adapter';\n\nasync function generateContentStreamOnCloud(\n apiSettings: ApiSettings,\n model: string,\n params: GenerateContentRequest,\n requestOptions?: RequestOptions\n): Promise<Response> {\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n params = GoogleAIMapper.mapGenerateContentRequest(params);\n }\n return makeRequest(\n model,\n Task.STREAM_GENERATE_CONTENT,\n apiSettings,\n /* stream */ true,\n JSON.stringify(params),\n requestOptions\n );\n}\n\nexport async function generateContentStream(\n apiSettings: ApiSettings,\n model: string,\n params: GenerateContentRequest,\n chromeAdapter?: ChromeAdapter,\n requestOptions?: RequestOptions\n): Promise<GenerateContentStreamResult> {\n let response;\n if (chromeAdapter && (await chromeAdapter.isAvailable(params))) {\n response = await chromeAdapter.generateContentStream(params);\n } else {\n response = await generateContentStreamOnCloud(\n apiSettings,\n model,\n params,\n requestOptions\n );\n }\n return processStream(response, apiSettings); // TODO: Map streaming responses\n}\n\nasync function generateContentOnCloud(\n apiSettings: ApiSettings,\n model: string,\n params: GenerateContentRequest,\n requestOptions?: RequestOptions\n): Promise<Response> {\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n params = GoogleAIMapper.mapGenerateContentRequest(params);\n }\n return makeRequest(\n model,\n Task.GENERATE_CONTENT,\n apiSettings,\n /* stream */ false,\n JSON.stringify(params),\n requestOptions\n );\n}\n\nexport async function generateContent(\n apiSettings: ApiSettings,\n model: string,\n params: GenerateContentRequest,\n chromeAdapter?: ChromeAdapter,\n requestOptions?: RequestOptions\n): Promise<GenerateContentResult> {\n let response;\n if (chromeAdapter && (await chromeAdapter.isAvailable(params))) {\n response = await chromeAdapter.generateContent(params);\n } else {\n response = await generateContentOnCloud(\n apiSettings,\n model,\n params,\n requestOptions\n );\n }\n const generateContentResponse = await processGenerateContentResponse(\n response,\n apiSettings\n );\n const enhancedResponse = createEnhancedContentResponse(\n generateContentResponse\n );\n return {\n response: enhancedResponse\n };\n}\n\nasync function processGenerateContentResponse(\n response: Response,\n apiSettings: ApiSettings\n): Promise<GenerateContentResponse> {\n const responseJson = await response.json();\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n return GoogleAIMapper.mapGenerateContentResponse(responseJson);\n } else {\n return responseJson;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Content, GenerateContentRequest, Part, AIErrorCode } from '../types';\nimport { AIError } from '../errors';\nimport { ImagenGenerationParams, PredictRequestBody } from '../types/internal';\n\nexport function formatSystemInstruction(\n input?: string | Part | Content\n): Content | undefined {\n // null or undefined\n if (input == null) {\n return undefined;\n } else if (typeof input === 'string') {\n return { role: 'system', parts: [{ text: input }] } as Content;\n } else if ((input as Part).text) {\n return { role: 'system', parts: [input as Part] };\n } else if ((input as Content).parts) {\n if (!(input as Content).role) {\n return { role: 'system', parts: (input as Content).parts };\n } else {\n return input as Content;\n }\n }\n}\n\nexport function formatNewContent(\n request: string | Array<string | Part>\n): Content {\n let newParts: Part[] = [];\n if (typeof request === 'string') {\n newParts = [{ text: request }];\n } else {\n for (const partOrString of request) {\n if (typeof partOrString === 'string') {\n newParts.push({ text: partOrString });\n } else {\n newParts.push(partOrString);\n }\n }\n }\n return assignRoleToPartsAndValidateSendMessageRequest(newParts);\n}\n\n/**\n * When multiple Part types (i.e. FunctionResponsePart and TextPart) are\n * passed in a single Part array, we may need to assign different roles to each\n * part. Currently only FunctionResponsePart requires a role other than 'user'.\n * @private\n * @param parts Array of parts to pass to the model\n * @returns Array of content items\n */\nfunction assignRoleToPartsAndValidateSendMessageRequest(\n parts: Part[]\n): Content {\n const userContent: Content = { role: 'user', parts: [] };\n const functionContent: Content = { role: 'function', parts: [] };\n let hasUserContent = false;\n let hasFunctionContent = false;\n for (const part of parts) {\n if ('functionResponse' in part) {\n functionContent.parts.push(part);\n hasFunctionContent = true;\n } else {\n userContent.parts.push(part);\n hasUserContent = true;\n }\n }\n\n if (hasUserContent && hasFunctionContent) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n 'Within a single message, FunctionResponse cannot be mixed with other type of Part in the request for sending chat message.'\n );\n }\n\n if (!hasUserContent && !hasFunctionContent) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n 'No Content is provided for sending chat message.'\n );\n }\n\n if (hasUserContent) {\n return userContent;\n }\n\n return functionContent;\n}\n\nexport function formatGenerateContentInput(\n params: GenerateContentRequest | string | Array<string | Part>\n): GenerateContentRequest {\n let formattedRequest: GenerateContentRequest;\n if ((params as GenerateContentRequest).contents) {\n formattedRequest = params as GenerateContentRequest;\n } else {\n // Array or string\n const content = formatNewContent(params as string | Array<string | Part>);\n formattedRequest = { contents: [content] };\n }\n if ((params as GenerateContentRequest).systemInstruction) {\n formattedRequest.systemInstruction = formatSystemInstruction(\n (params as GenerateContentRequest).systemInstruction\n );\n }\n return formattedRequest;\n}\n\n/**\n * Convert the user-defined parameters in {@link ImagenGenerationParams} to the format\n * that is expected from the REST API.\n *\n * @internal\n */\nexport function createPredictRequestBody(\n prompt: string,\n {\n gcsURI,\n imageFormat,\n addWatermark,\n numberOfImages = 1,\n negativePrompt,\n aspectRatio,\n safetyFilterLevel,\n personFilterLevel\n }: ImagenGenerationParams\n): PredictRequestBody {\n // Properties that are undefined will be omitted from the JSON string that is sent in the request.\n const body: PredictRequestBody = {\n instances: [\n {\n prompt\n }\n ],\n parameters: {\n storageUri: gcsURI,\n negativePrompt,\n sampleCount: numberOfImages,\n aspectRatio,\n outputOptions: imageFormat,\n addWatermark,\n safetyFilterLevel,\n personGeneration: personFilterLevel,\n includeRaiReason: true\n }\n };\n return body;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Content, POSSIBLE_ROLES, Part, Role, AIErrorCode } from '../types';\nimport { AIError } from '../errors';\n\n// https://ai.google.dev/api/rest/v1beta/Content#part\n\nconst VALID_PART_FIELDS: Array<keyof Part> = [\n 'text',\n 'inlineData',\n 'functionCall',\n 'functionResponse'\n];\n\nconst VALID_PARTS_PER_ROLE: { [key in Role]: Array<keyof Part> } = {\n user: ['text', 'inlineData'],\n function: ['functionResponse'],\n model: ['text', 'functionCall'],\n // System instructions shouldn't be in history anyway.\n system: ['text']\n};\n\nconst VALID_PREVIOUS_CONTENT_ROLES: { [key in Role]: Role[] } = {\n user: ['model'],\n function: ['model'],\n model: ['user', 'function'],\n // System instructions shouldn't be in history.\n system: []\n};\n\nexport function validateChatHistory(history: Content[]): void {\n let prevContent: Content | null = null;\n for (const currContent of history) {\n const { role, parts } = currContent;\n if (!prevContent && role !== 'user') {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `First Content should be with role 'user', got ${role}`\n );\n }\n if (!POSSIBLE_ROLES.includes(role)) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Each item should include role field. Got ${role} but valid roles are: ${JSON.stringify(\n POSSIBLE_ROLES\n )}`\n );\n }\n\n if (!Array.isArray(parts)) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Content should have 'parts' but property with an array of Parts`\n );\n }\n\n if (parts.length === 0) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Each Content should have at least one part`\n );\n }\n\n const countFields: Record<keyof Part, number> = {\n text: 0,\n inlineData: 0,\n functionCall: 0,\n functionResponse: 0\n };\n\n for (const part of parts) {\n for (const key of VALID_PART_FIELDS) {\n if (key in part) {\n countFields[key] += 1;\n }\n }\n }\n const validParts = VALID_PARTS_PER_ROLE[role];\n for (const key of VALID_PART_FIELDS) {\n if (!validParts.includes(key) && countFields[key] > 0) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Content with role '${role}' can't contain '${key}' part`\n );\n }\n }\n\n if (prevContent) {\n const validPreviousContentRoles = VALID_PREVIOUS_CONTENT_ROLES[role];\n if (!validPreviousContentRoles.includes(prevContent.role)) {\n throw new AIError(\n AIErrorCode.INVALID_CONTENT,\n `Content with role '${role}' can't follow '${\n prevContent.role\n }'. Valid previous roles: ${JSON.stringify(\n VALID_PREVIOUS_CONTENT_ROLES\n )}`\n );\n }\n }\n prevContent = currContent;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n GenerateContentRequest,\n GenerateContentResult,\n GenerateContentStreamResult,\n Part,\n RequestOptions,\n StartChatParams\n} from '../types';\nimport { formatNewContent } from '../requests/request-helpers';\nimport { formatBlockErrorMessage } from '../requests/response-helpers';\nimport { validateChatHistory } from './chat-session-helpers';\nimport { generateContent, generateContentStream } from './generate-content';\nimport { ApiSettings } from '../types/internal';\nimport { logger } from '../logger';\nimport { ChromeAdapter } from '../types/chrome-adapter';\n\n/**\n * Do not log a message for this error.\n */\nconst SILENT_ERROR = 'SILENT_ERROR';\n\n/**\n * ChatSession class that enables sending chat messages and stores\n * history of sent and received messages so far.\n *\n * @public\n */\nexport class ChatSession {\n private _apiSettings: ApiSettings;\n private _history: Content[] = [];\n private _sendPromise: Promise<void> = Promise.resolve();\n\n constructor(\n apiSettings: ApiSettings,\n public model: string,\n private chromeAdapter?: ChromeAdapter,\n public params?: StartChatParams,\n public requestOptions?: RequestOptions\n ) {\n this._apiSettings = apiSettings;\n if (params?.history) {\n validateChatHistory(params.history);\n this._history = params.history;\n }\n }\n\n /**\n * Gets the chat history so far. Blocked prompts are not added to history.\n * Neither blocked candidates nor the prompts that generated them are added\n * to history.\n */\n async getHistory(): Promise<Content[]> {\n await this._sendPromise;\n return this._history;\n }\n\n /**\n * Sends a chat message and receives a non-streaming\n * {@link GenerateContentResult}\n */\n async sendMessage(\n request: string | Array<string | Part>\n ): Promise<GenerateContentResult> {\n await this._sendPromise;\n const newContent = formatNewContent(request);\n const generateContentRequest: GenerateContentRequest = {\n safetySettings: this.params?.safetySettings,\n generationConfig: this.params?.generationConfig,\n tools: this.params?.tools,\n toolConfig: this.params?.toolConfig,\n systemInstruction: this.params?.systemInstruction,\n contents: [...this._history, newContent]\n };\n let finalResult = {} as GenerateContentResult;\n // Add onto the chain.\n this._sendPromise = this._sendPromise\n .then(() =>\n generateContent(\n this._apiSettings,\n this.model,\n generateContentRequest,\n this.chromeAdapter,\n this.requestOptions\n )\n )\n .then(result => {\n if (\n result.response.candidates &&\n result.response.candidates.length > 0\n ) {\n this._history.push(newContent);\n const responseContent: Content = {\n parts: result.response.candidates?.[0].content.parts || [],\n // Response seems to come back without a role set.\n role: result.response.candidates?.[0].content.role || 'model'\n };\n this._history.push(responseContent);\n } else {\n const blockErrorMessage = formatBlockErrorMessage(result.response);\n if (blockErrorMessage) {\n logger.warn(\n `sendMessage() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`\n );\n }\n }\n finalResult = result;\n });\n await this._sendPromise;\n return finalResult;\n }\n\n /**\n * Sends a chat message and receives the response as a\n * {@link GenerateContentStreamResult} containing an iterable stream\n * and a response promise.\n */\n async sendMessageStream(\n request: string | Array<string | Part>\n ): Promise<GenerateContentStreamResult> {\n await this._sendPromise;\n const newContent = formatNewContent(request);\n const generateContentRequest: GenerateContentRequest = {\n safetySettings: this.params?.safetySettings,\n generationConfig: this.params?.generationConfig,\n tools: this.params?.tools,\n toolConfig: this.params?.toolConfig,\n systemInstruction: this.params?.systemInstruction,\n contents: [...this._history, newContent]\n };\n const streamPromise = generateContentStream(\n this._apiSettings,\n this.model,\n generateContentRequest,\n this.chromeAdapter,\n this.requestOptions\n );\n\n // Add onto the chain.\n this._sendPromise = this._sendPromise\n .then(() => streamPromise)\n // This must be handled to avoid unhandled rejection, but jump\n // to the final catch block with a label to not log this error.\n .catch(_ignored => {\n throw new Error(SILENT_ERROR);\n })\n .then(streamResult => streamResult.response)\n .then(response => {\n if (response.candidates && response.candidates.length > 0) {\n this._history.push(newContent);\n const responseContent = { ...response.candidates[0].content };\n // Response seems to come back without a role set.\n if (!responseContent.role) {\n responseContent.role = 'model';\n }\n this._history.push(responseContent);\n } else {\n const blockErrorMessage = formatBlockErrorMessage(response);\n if (blockErrorMessage) {\n logger.warn(\n `sendMessageStream() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`\n );\n }\n }\n })\n .catch(e => {\n // Errors in streamPromise are already catchable by the user as\n // streamPromise is returned.\n // Avoid duplicating the error message in logs.\n if (e.message !== SILENT_ERROR) {\n // Users do not have access to _sendPromise to catch errors\n // downstream from streamPromise, so they should not throw.\n logger.error(e);\n }\n });\n return streamPromise;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CountTokensRequest,\n CountTokensResponse,\n RequestOptions\n} from '../types';\nimport { Task, makeRequest } from '../requests/request';\nimport { ApiSettings } from '../types/internal';\nimport * as GoogleAIMapper from '../googleai-mappers';\nimport { BackendType } from '../public-types';\nimport { ChromeAdapter } from '../types/chrome-adapter';\n\nexport async function countTokensOnCloud(\n apiSettings: ApiSettings,\n model: string,\n params: CountTokensRequest,\n requestOptions?: RequestOptions\n): Promise<CountTokensResponse> {\n let body: string = '';\n if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {\n const mappedParams = GoogleAIMapper.mapCountTokensRequest(params, model);\n body = JSON.stringify(mappedParams);\n } else {\n body = JSON.stringify(params);\n }\n const response = await makeRequest(\n model,\n Task.COUNT_TOKENS,\n apiSettings,\n false,\n body,\n requestOptions\n );\n return response.json();\n}\n\nexport async function countTokens(\n apiSettings: ApiSettings,\n model: string,\n params: CountTokensRequest,\n chromeAdapter?: ChromeAdapter,\n requestOptions?: RequestOptions\n): Promise<CountTokensResponse> {\n if (chromeAdapter && (await chromeAdapter.isAvailable(params))) {\n return (await chromeAdapter.countTokens(params)).json();\n }\n\n return countTokensOnCloud(apiSettings, model, params, requestOptions);\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n generateContent,\n generateContentStream\n} from '../methods/generate-content';\nimport {\n Content,\n CountTokensRequest,\n CountTokensResponse,\n GenerateContentRequest,\n GenerateContentResult,\n GenerateContentStreamResult,\n GenerationConfig,\n ModelParams,\n Part,\n RequestOptions,\n SafetySetting,\n StartChatParams,\n Tool,\n ToolConfig\n} from '../types';\nimport { ChatSession } from '../methods/chat-session';\nimport { countTokens } from '../methods/count-tokens';\nimport {\n formatGenerateContentInput,\n formatSystemInstruction\n} from '../requests/request-helpers';\nimport { AI } from '../public-types';\nimport { AIModel } from './ai-model';\nimport { ChromeAdapter } from '../types/chrome-adapter';\n\n/**\n * Class for generative model APIs.\n * @public\n */\nexport class GenerativeModel extends AIModel {\n generationConfig: GenerationConfig;\n safetySettings: SafetySetting[];\n requestOptions?: RequestOptions;\n tools?: Tool[];\n toolConfig?: ToolConfig;\n systemInstruction?: Content;\n\n constructor(\n ai: AI,\n modelParams: ModelParams,\n requestOptions?: RequestOptions,\n private chromeAdapter?: ChromeAdapter\n ) {\n super(ai, modelParams.model);\n this.generationConfig = modelParams.generationConfig || {};\n this.safetySettings = modelParams.safetySettings || [];\n this.tools = modelParams.tools;\n this.toolConfig = modelParams.toolConfig;\n this.systemInstruction = formatSystemInstruction(\n modelParams.systemInstruction\n );\n this.requestOptions = requestOptions || {};\n }\n\n /**\n * Makes a single non-streaming call to the model\n * and returns an object containing a single {@link GenerateContentResponse}.\n */\n async generateContent(\n request: GenerateContentRequest | string | Array<string | Part>\n ): Promise<GenerateContentResult> {\n const formattedParams = formatGenerateContentInput(request);\n return generateContent(\n this._apiSettings,\n this.model,\n {\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n ...formattedParams\n },\n this.chromeAdapter,\n this.requestOptions\n );\n }\n\n /**\n * Makes a single streaming call to the model\n * and returns an object containing an iterable stream that iterates\n * over all chunks in the streaming response as well as\n * a promise that returns the final aggregated response.\n */\n async generateContentStream(\n request: GenerateContentRequest | string | Array<string | Part>\n ): Promise<GenerateContentStreamResult> {\n const formattedParams = formatGenerateContentInput(request);\n return generateContentStream(\n this._apiSettings,\n this.model,\n {\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n ...formattedParams\n },\n this.chromeAdapter,\n this.requestOptions\n );\n }\n\n /**\n * Gets a new {@link ChatSession} instance which can be used for\n * multi-turn chats.\n */\n startChat(startChatParams?: StartChatParams): ChatSession {\n return new ChatSession(\n this._apiSettings,\n this.model,\n this.chromeAdapter,\n {\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n /**\n * Overrides params inherited from GenerativeModel with those explicitly set in the\n * StartChatParams. For example, if startChatParams.generationConfig is set, it'll override\n * this.generationConfig.\n */\n ...startChatParams\n },\n this.requestOptions\n );\n }\n\n /**\n * Counts the tokens in the provided request.\n */\n async countTokens(\n request: CountTokensRequest | string | Array<string | Part>\n ): Promise<CountTokensResponse> {\n const formattedParams = formatGenerateContentInput(request);\n return countTokens(\n this._apiSettings,\n this.model,\n formattedParams,\n this.chromeAdapter\n );\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AI } from '../public-types';\nimport { Task, makeRequest } from '../requests/request';\nimport { createPredictRequestBody } from '../requests/request-helpers';\nimport { handlePredictResponse } from '../requests/response-helpers';\nimport {\n ImagenGCSImage,\n ImagenGenerationConfig,\n ImagenInlineImage,\n RequestOptions,\n ImagenModelParams,\n ImagenGenerationResponse,\n ImagenSafetySettings\n} from '../types';\nimport { AIModel } from './ai-model';\n\n/**\n * Class for Imagen model APIs.\n *\n * This class provides methods for generating images using the Imagen model.\n *\n * @example\n * ```javascript\n * const imagen = new ImagenModel(\n * ai,\n * {\n * model: 'imagen-3.0-generate-002'\n * }\n * );\n *\n * const response = await imagen.generateImages('A photo of a cat');\n * if (response.images.length > 0) {\n * console.log(response.images[0].bytesBase64Encoded);\n * }\n * ```\n *\n * @beta\n */\nexport class ImagenModel extends AIModel {\n /**\n * The Imagen generation configuration.\n */\n generationConfig?: ImagenGenerationConfig;\n /**\n * Safety settings for filtering inappropriate content.\n */\n safetySettings?: ImagenSafetySettings;\n\n /**\n * Constructs a new instance of the {@link ImagenModel} class.\n *\n * @param ai - an {@link AI} instance.\n * @param modelParams - Parameters to use when making requests to Imagen.\n * @param requestOptions - Additional options to use when making requests.\n *\n * @throws If the `apiKey` or `projectId` fields are missing in your\n * Firebase config.\n */\n constructor(\n ai: AI,\n modelParams: ImagenModelParams,\n public requestOptions?: RequestOptions\n ) {\n const { model, generationConfig, safetySettings } = modelParams;\n super(ai, model);\n this.generationConfig = generationConfig;\n this.safetySettings = safetySettings;\n }\n\n /**\n * Generates images using the Imagen model and returns them as\n * base64-encoded strings.\n *\n * @param prompt - A text prompt describing the image(s) to generate.\n * @returns A promise that resolves to an {@link ImagenGenerationResponse}\n * object containing the generated images.\n *\n * @throws If the request to generate images fails. This happens if the\n * prompt is blocked.\n *\n * @remarks\n * If the prompt was not blocked, but one or more of the generated images were filtered, the\n * returned object will have a `filteredReason` property.\n * If all images are filtered, the `images` array will be empty.\n *\n * @beta\n */\n async generateImages(\n prompt: string\n ): Promise<ImagenGenerationResponse<ImagenInlineImage>> {\n const body = createPredictRequestBody(prompt, {\n ...this.generationConfig,\n ...this.safetySettings\n });\n const response = await makeRequest(\n this.model,\n Task.PREDICT,\n this._apiSettings,\n /* stream */ false,\n JSON.stringify(body),\n this.requestOptions\n );\n return handlePredictResponse<ImagenInlineImage>(response);\n }\n\n /**\n * Generates images to Cloud Storage for Firebase using the Imagen model.\n *\n * @internal This method is temporarily internal.\n *\n * @param prompt - A text prompt describing the image(s) to generate.\n * @param gcsURI - The URI of file stored in a Cloud Storage for Firebase bucket.\n * This should be a directory. For example, `gs://my-bucket/my-directory/`.\n * @returns A promise that resolves to an {@link ImagenGenerationResponse}\n * object containing the URLs of the generated images.\n *\n * @throws If the request fails to generate images fails. This happens if\n * the prompt is blocked.\n *\n * @remarks\n * If the prompt was not blocked, but one or more of the generated images were filtered, the\n * returned object will have a `filteredReason` property.\n * If all images are filtered, the `images` array will be empty.\n */\n async generateImagesGCS(\n prompt: string,\n gcsURI: string\n ): Promise<ImagenGenerationResponse<ImagenGCSImage>> {\n const body = createPredictRequestBody(prompt, {\n gcsURI,\n ...this.generationConfig,\n ...this.safetySettings\n });\n const response = await makeRequest(\n this.model,\n Task.PREDICT,\n this._apiSettings,\n /* stream */ false,\n JSON.stringify(body),\n this.requestOptions\n );\n return handlePredictResponse<ImagenGCSImage>(response);\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * The subset of the Prompt API\n * (see {@link https://github.com/webmachinelearning/prompt-api#full-api-surface-in-web-idl }\n * required for hybrid functionality.\n *\n * @internal\n */\nexport interface LanguageModel extends EventTarget {\n create(options?: LanguageModelCreateOptions): Promise<LanguageModel>;\n availability(options?: LanguageModelCreateCoreOptions): Promise<Availability>;\n prompt(\n input: LanguageModelPrompt,\n options?: LanguageModelPromptOptions\n ): Promise<string>;\n promptStreaming(\n input: LanguageModelPrompt,\n options?: LanguageModelPromptOptions\n ): ReadableStream;\n measureInputUsage(\n input: LanguageModelPrompt,\n options?: LanguageModelPromptOptions\n ): Promise<number>;\n destroy(): undefined;\n}\n\n/**\n * @internal\n */\nexport enum Availability {\n 'UNAVAILABLE' = 'unavailable',\n 'DOWNLOADABLE' = 'downloadable',\n 'DOWNLOADING' = 'downloading',\n 'AVAILABLE' = 'available'\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Configures the creation of an on-device language model session.\n * @public\n */\nexport interface LanguageModelCreateCoreOptions {\n topK?: number;\n temperature?: number;\n expectedInputs?: LanguageModelExpected[];\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Configures the creation of an on-device language model session.\n * @public\n */\nexport interface LanguageModelCreateOptions\n extends LanguageModelCreateCoreOptions {\n signal?: AbortSignal;\n initialPrompts?: LanguageModelMessage[];\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Options for an on-device language model prompt.\n * @public\n */\nexport interface LanguageModelPromptOptions {\n responseConstraint?: object;\n // TODO: Restore AbortSignal once the API is defined.\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Options for the expected inputs for an on-device language model.\n * @public\n */ export interface LanguageModelExpected {\n type: LanguageModelMessageType;\n languages?: string[];\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * An on-device language model prompt.\n * @public\n */\nexport type LanguageModelPrompt = LanguageModelMessage[];\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * An on-device language model message.\n * @public\n */\nexport interface LanguageModelMessage {\n role: LanguageModelMessageRole;\n content: LanguageModelMessageContent[];\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * An on-device language model content object.\n * @public\n */\nexport interface LanguageModelMessageContent {\n type: LanguageModelMessageType;\n value: LanguageModelMessageContentValue;\n}\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Allowable roles for on-device language model usage.\n * @public\n */\nexport type LanguageModelMessageRole = 'system' | 'user' | 'assistant';\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Allowable types for on-device language model messages.\n * @public\n */\nexport type LanguageModelMessageType = 'text' | 'image' | 'audio';\n\n/**\n * <b>(EXPERIMENTAL)</b>\n * Content formats that can be provided as on-device message content.\n * @public\n */\nexport type LanguageModelMessageContentValue =\n | ImageBitmapSource\n | AudioBuffer\n | BufferSource\n | string;\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from '../errors';\nimport { logger } from '../logger';\nimport {\n CountTokensRequest,\n GenerateContentRequest,\n InferenceMode,\n Part,\n AIErrorCode,\n OnDeviceParams,\n Content,\n Role\n} from '../types';\nimport { ChromeAdapter } from '../types/chrome-adapter';\nimport {\n Availability,\n LanguageModel,\n LanguageModelMessage,\n LanguageModelMessageContent,\n LanguageModelMessageRole\n} from '../types/language-model';\n\n/**\n * Defines an inference \"backend\" that uses Chrome's on-device model,\n * and encapsulates logic for detecting when on-device inference is\n * possible.\n */\nexport class ChromeAdapterImpl implements ChromeAdapter {\n // Visible for testing\n static SUPPORTED_MIME_TYPES = ['image/jpeg', 'image/png'];\n private isDownloading = false;\n private downloadPromise: Promise<LanguageModel | void> | undefined;\n private oldSession: LanguageModel | undefined;\n constructor(\n private languageModelProvider: LanguageModel,\n private mode: InferenceMode,\n private onDeviceParams: OnDeviceParams = {\n createOptions: {\n // Defaults to support image inputs for convenience.\n expectedInputs: [{ type: 'image' }]\n }\n }\n ) {}\n\n /**\n * Checks if a given request can be made on-device.\n *\n * <ol>Encapsulates a few concerns:\n * <li>the mode</li>\n * <li>API existence</li>\n * <li>prompt formatting</li>\n * <li>model availability, including triggering download if necessary</li>\n * </ol>\n *\n * <p>Pros: callers needn't be concerned with details of on-device availability.</p>\n * <p>Cons: this method spans a few concerns and splits request validation from usage.\n * If instance variables weren't already part of the API, we could consider a better\n * separation of concerns.</p>\n */\n async isAvailable(request: GenerateContentRequest): Promise<boolean> {\n if (!this.mode) {\n logger.debug(\n `On-device inference unavailable because mode is undefined.`\n );\n return false;\n }\n if (this.mode === InferenceMode.ONLY_IN_CLOUD) {\n logger.debug(\n `On-device inference unavailable because mode is \"only_in_cloud\".`\n );\n return false;\n }\n\n // Triggers out-of-band download so model will eventually become available.\n const availability = await this.downloadIfAvailable();\n\n if (this.mode === InferenceMode.ONLY_ON_DEVICE) {\n // If it will never be available due to API inavailability, throw.\n if (availability === Availability.UNAVAILABLE) {\n throw new AIError(\n AIErrorCode.API_NOT_ENABLED,\n 'Local LanguageModel API not available in this environment.'\n );\n } else if (\n availability === Availability.DOWNLOADABLE ||\n availability === Availability.DOWNLOADING\n ) {\n // TODO(chholland): Better user experience during download - progress?\n logger.debug(`Waiting for download of LanguageModel to complete.`);\n await this.downloadPromise;\n return true;\n }\n return true;\n }\n\n // Applies prefer_on_device logic.\n if (availability !== Availability.AVAILABLE) {\n logger.debug(\n `On-device inference unavailable because availability is \"${availability}\".`\n );\n return false;\n }\n if (!ChromeAdapterImpl.isOnDeviceRequest(request)) {\n logger.debug(\n `On-device inference unavailable because request is incompatible.`\n );\n return false;\n }\n\n return true;\n }\n\n /**\n * Generates content on device.\n *\n * <p>This is comparable to {@link GenerativeModel.generateContent} for generating content in\n * Cloud.</p>\n * @param request - a standard Firebase AI {@link GenerateContentRequest}\n * @returns {@link Response}, so we can reuse common response formatting.\n */\n async generateContent(request: GenerateContentRequest): Promise<Response> {\n const session = await this.createSession();\n const contents = await Promise.all(\n request.contents.map(ChromeAdapterImpl.toLanguageModelMessage)\n );\n const text = await session.prompt(\n contents,\n this.onDeviceParams.promptOptions\n );\n return ChromeAdapterImpl.toResponse(text);\n }\n\n /**\n * Generates content stream on device.\n *\n * <p>This is comparable to {@link GenerativeModel.generateContentStream} for generating content in\n * Cloud.</p>\n * @param request - a standard Firebase AI {@link GenerateContentRequest}\n * @returns {@link Response}, so we can reuse common response formatting.\n */\n async generateContentStream(\n request: GenerateContentRequest\n ): Promise<Response> {\n const session = await this.createSession();\n const contents = await Promise.all(\n request.contents.map(ChromeAdapterImpl.toLanguageModelMessage)\n );\n const stream = session.promptStreaming(\n contents,\n this.onDeviceParams.promptOptions\n );\n return ChromeAdapterImpl.toStreamResponse(stream);\n }\n\n async countTokens(_request: CountTokensRequest): Promise<Response> {\n throw new AIError(\n AIErrorCode.REQUEST_ERROR,\n 'Count Tokens is not yet available for on-device model.'\n );\n }\n\n /**\n * Asserts inference for the given request can be performed by an on-device model.\n */\n private static isOnDeviceRequest(request: GenerateContentRequest): boolean {\n // Returns false if the prompt is empty.\n if (request.contents.length === 0) {\n logger.debug('Empty prompt rejected for on-device inference.');\n return false;\n }\n\n for (const content of request.contents) {\n if (content.role === 'function') {\n logger.debug(`\"Function\" role rejected for on-device inference.`);\n return false;\n }\n\n // Returns false if request contains an image with an unsupported mime type.\n for (const part of content.parts) {\n if (\n part.inlineData &&\n ChromeAdapterImpl.SUPPORTED_MIME_TYPES.indexOf(\n part.inlineData.mimeType\n ) === -1\n ) {\n logger.debug(\n `Unsupported mime type \"${part.inlineData.mimeType}\" rejected for on-device inference.`\n );\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Encapsulates logic to get availability and download a model if one is downloadable.\n */\n private async downloadIfAvailable(): Promise<Availability | undefined> {\n const availability = await this.languageModelProvider?.availability(\n this.onDeviceParams.createOptions\n );\n\n if (availability === Availability.DOWNLOADABLE) {\n this.download();\n }\n\n return availability;\n }\n\n /**\n * Triggers out-of-band download of an on-device model.\n *\n * <p>Chrome only downloads models as needed. Chrome knows a model is needed when code calls\n * LanguageModel.create.</p>\n *\n * <p>Since Chrome manages the download, the SDK can only avoid redundant download requests by\n * tracking if a download has previously been requested.</p>\n */\n private download(): void {\n if (this.isDownloading) {\n return;\n }\n this.isDownloading = true;\n this.downloadPromise = this.languageModelProvider\n ?.create(this.onDeviceParams.createOptions)\n .finally(() => {\n this.isDownloading = false;\n });\n }\n\n /**\n * Converts Firebase AI {@link Content} object to a Chrome {@link LanguageModelMessage} object.\n */\n private static async toLanguageModelMessage(\n content: Content\n ): Promise<LanguageModelMessage> {\n const languageModelMessageContents = await Promise.all(\n content.parts.map(ChromeAdapterImpl.toLanguageModelMessageContent)\n );\n return {\n role: ChromeAdapterImpl.toLanguageModelMessageRole(content.role),\n content: languageModelMessageContents\n };\n }\n\n /**\n * Converts a Firebase AI Part object to a Chrome LanguageModelMessageContent object.\n */\n private static async toLanguageModelMessageContent(\n part: Part\n ): Promise<LanguageModelMessageContent> {\n if (part.text) {\n return {\n type: 'text',\n value: part.text\n };\n } else if (part.inlineData) {\n const formattedImageContent = await fetch(\n `data:${part.inlineData.mimeType};base64,${part.inlineData.data}`\n );\n const imageBlob = await formattedImageContent.blob();\n const imageBitmap = await createImageBitmap(imageBlob);\n return {\n type: 'image',\n value: imageBitmap\n };\n }\n throw new AIError(\n AIErrorCode.REQUEST_ERROR,\n `Processing of this Part type is not currently supported.`\n );\n }\n\n /**\n * Converts a Firebase AI {@link Role} string to a {@link LanguageModelMessageRole} string.\n */\n private static toLanguageModelMessageRole(\n role: Role\n ): LanguageModelMessageRole {\n // Assumes 'function' rule has been filtered by isOnDeviceRequest\n return role === 'model' ? 'assistant' : 'user';\n }\n\n /**\n * Abstracts Chrome session creation.\n *\n * <p>Chrome uses a multi-turn session for all inference. Firebase AI uses single-turn for all\n * inference. To map the Firebase AI API to Chrome's API, the SDK creates a new session for all\n * inference.</p>\n *\n * <p>Chrome will remove a model from memory if it's no longer in use, so this method ensures a\n * new session is created before an old session is destroyed.</p>\n */\n private async createSession(): Promise<LanguageModel> {\n if (!this.languageModelProvider) {\n throw new AIError(\n AIErrorCode.UNSUPPORTED,\n 'Chrome AI requested for unsupported browser version.'\n );\n }\n const newSession = await this.languageModelProvider.create(\n this.onDeviceParams.createOptions\n );\n if (this.oldSession) {\n this.oldSession.destroy();\n }\n // Holds session reference, so model isn't unloaded from memory.\n this.oldSession = newSession;\n return newSession;\n }\n\n /**\n * Formats string returned by Chrome as a {@link Response} returned by Firebase AI.\n */\n private static toResponse(text: string): Response {\n return {\n json: async () => ({\n candidates: [\n {\n content: {\n parts: [{ text }]\n }\n }\n ]\n })\n } as Response;\n }\n\n /**\n * Formats string stream returned by Chrome as SSE returned by Firebase AI.\n */\n private static toStreamResponse(stream: ReadableStream<string>): Response {\n const encoder = new TextEncoder();\n return {\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n const json = JSON.stringify({\n candidates: [\n {\n content: {\n role: 'model',\n parts: [{ text: chunk }]\n }\n }\n ]\n });\n controller.enqueue(encoder.encode(`data: ${json}\\n\\n`));\n }\n })\n )\n } as Response;\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AIError } from '../errors';\nimport { AIErrorCode } from '../types';\nimport {\n SchemaInterface,\n SchemaType,\n SchemaParams,\n SchemaRequest\n} from '../types/schema';\n\n/**\n * Parent class encompassing all Schema types, with static methods that\n * allow building specific Schema types. This class can be converted with\n * `JSON.stringify()` into a JSON string accepted by Vertex AI REST endpoints.\n * (This string conversion is automatically done when calling SDK methods.)\n * @public\n */\nexport abstract class Schema implements SchemaInterface {\n /**\n * Optional. The type of the property.\n * This can only be undefined when using `anyOf` schemas, which do not have an\n * explicit type in the {@link https://swagger.io/docs/specification/v3_0/data-models/data-types/#any-type | OpenAPI specification}.\n */\n type?: SchemaType;\n /** Optional. The format of the property.\n * Supported formats:<br/>\n * <ul>\n * <li>for NUMBER type: \"float\", \"double\"</li>\n * <li>for INTEGER type: \"int32\", \"int64\"</li>\n * <li>for STRING type: \"email\", \"byte\", etc</li>\n * </ul>\n */\n format?: string;\n /** Optional. The description of the property. */\n description?: string;\n /** Optional. The items of the property. */\n items?: SchemaInterface;\n /** The minimum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n minItems?: number;\n /** The maximum number of items (elements) in a schema of {@link (SchemaType:type)} `array`. */\n maxItems?: number;\n /** Optional. Whether the property is nullable. Defaults to false. */\n nullable: boolean;\n /** Optional. The example of the property. */\n example?: unknown;\n /**\n * Allows user to add other schema properties that have not yet\n * been officially added to the SDK.\n */\n [key: string]: unknown;\n\n constructor(schemaParams: SchemaInterface) {\n // TODO(dlarocque): Enforce this with union types\n if (!schemaParams.type && !schemaParams.anyOf) {\n throw new AIError(\n AIErrorCode.INVALID_SCHEMA,\n \"A schema must have either a 'type' or an 'anyOf' array of sub-schemas.\"\n );\n }\n // eslint-disable-next-line guard-for-in\n for (const paramKey in schemaParams) {\n this[paramKey] = schemaParams[paramKey];\n }\n // Ensure these are explicitly set to avoid TS errors.\n this.type = schemaParams.type;\n this.format = schemaParams.hasOwnProperty('format')\n ? schemaParams.format\n : undefined;\n this.nullable = schemaParams.hasOwnProperty('nullable')\n ? !!schemaParams.nullable\n : false;\n }\n\n /**\n * Defines how this Schema should be serialized as JSON.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj: { type?: SchemaType; [key: string]: unknown } = {\n type: this.type\n };\n for (const prop in this) {\n if (this.hasOwnProperty(prop) && this[prop] !== undefined) {\n if (prop !== 'required' || this.type === SchemaType.OBJECT) {\n obj[prop] = this[prop];\n }\n }\n }\n return obj as SchemaRequest;\n }\n\n static array(arrayParams: SchemaParams & { items: Schema }): ArraySchema {\n return new ArraySchema(arrayParams, arrayParams.items);\n }\n\n static object(\n objectParams: SchemaParams & {\n properties: {\n [k: string]: Schema;\n };\n optionalProperties?: string[];\n }\n ): ObjectSchema {\n return new ObjectSchema(\n objectParams,\n objectParams.properties,\n objectParams.optionalProperties\n );\n }\n\n // eslint-disable-next-line id-blacklist\n static string(stringParams?: SchemaParams): StringSchema {\n return new StringSchema(stringParams);\n }\n\n static enumString(\n stringParams: SchemaParams & { enum: string[] }\n ): StringSchema {\n return new StringSchema(stringParams, stringParams.enum);\n }\n\n static integer(integerParams?: SchemaParams): IntegerSchema {\n return new IntegerSchema(integerParams);\n }\n\n // eslint-disable-next-line id-blacklist\n static number(numberParams?: SchemaParams): NumberSchema {\n return new NumberSchema(numberParams);\n }\n\n // eslint-disable-next-line id-blacklist\n static boolean(booleanParams?: SchemaParams): BooleanSchema {\n return new BooleanSchema(booleanParams);\n }\n\n static anyOf(\n anyOfParams: SchemaParams & { anyOf: TypedSchema[] }\n ): AnyOfSchema {\n return new AnyOfSchema(anyOfParams);\n }\n}\n\n/**\n * A type that includes all specific Schema types.\n * @public\n */\nexport type TypedSchema =\n | IntegerSchema\n | NumberSchema\n | StringSchema\n | BooleanSchema\n | ObjectSchema\n | ArraySchema\n | AnyOfSchema;\n\n/**\n * Schema class for \"integer\" types.\n * @public\n */\nexport class IntegerSchema extends Schema {\n constructor(schemaParams?: SchemaParams) {\n super({\n type: SchemaType.INTEGER,\n ...schemaParams\n });\n }\n}\n\n/**\n * Schema class for \"number\" types.\n * @public\n */\nexport class NumberSchema extends Schema {\n constructor(schemaParams?: SchemaParams) {\n super({\n type: SchemaType.NUMBER,\n ...schemaParams\n });\n }\n}\n\n/**\n * Schema class for \"boolean\" types.\n * @public\n */\nexport class BooleanSchema extends Schema {\n constructor(schemaParams?: SchemaParams) {\n super({\n type: SchemaType.BOOLEAN,\n ...schemaParams\n });\n }\n}\n\n/**\n * Schema class for \"string\" types. Can be used with or without\n * enum values.\n * @public\n */\nexport class StringSchema extends Schema {\n enum?: string[];\n constructor(schemaParams?: SchemaParams, enumValues?: string[]) {\n super({\n type: SchemaType.STRING,\n ...schemaParams\n });\n this.enum = enumValues;\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n if (this.enum) {\n obj['enum'] = this.enum;\n }\n return obj as SchemaRequest;\n }\n}\n\n/**\n * Schema class for \"array\" types.\n * The `items` param should refer to the type of item that can be a member\n * of the array.\n * @public\n */\nexport class ArraySchema extends Schema {\n constructor(schemaParams: SchemaParams, public items: TypedSchema) {\n super({\n type: SchemaType.ARRAY,\n ...schemaParams\n });\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n obj.items = this.items.toJSON();\n return obj;\n }\n}\n\n/**\n * Schema class for \"object\" types.\n * The `properties` param must be a map of `Schema` objects.\n * @public\n */\nexport class ObjectSchema extends Schema {\n constructor(\n schemaParams: SchemaParams,\n public properties: {\n [k: string]: TypedSchema;\n },\n public optionalProperties: string[] = []\n ) {\n super({\n type: SchemaType.OBJECT,\n ...schemaParams\n });\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n obj.properties = { ...this.properties };\n const required = [];\n if (this.optionalProperties) {\n for (const propertyKey of this.optionalProperties) {\n if (!this.properties.hasOwnProperty(propertyKey)) {\n throw new AIError(\n AIErrorCode.INVALID_SCHEMA,\n `Property \"${propertyKey}\" specified in \"optionalProperties\" does not exist.`\n );\n }\n }\n }\n for (const propertyKey in this.properties) {\n if (this.properties.hasOwnProperty(propertyKey)) {\n obj.properties[propertyKey] = this.properties[\n propertyKey\n ].toJSON() as SchemaRequest;\n if (!this.optionalProperties.includes(propertyKey)) {\n required.push(propertyKey);\n }\n }\n }\n if (required.length > 0) {\n obj.required = required;\n }\n delete obj.optionalProperties;\n return obj as SchemaRequest;\n }\n}\n\n/**\n * Schema class representing a value that can conform to any of the provided sub-schemas. This is\n * useful when a field can accept multiple distinct types or structures.\n * @public\n */\nexport class AnyOfSchema extends Schema {\n anyOf: TypedSchema[]; // Re-define field to narrow to required type\n constructor(schemaParams: SchemaParams & { anyOf: TypedSchema[] }) {\n if (schemaParams.anyOf.length === 0) {\n throw new AIError(\n AIErrorCode.INVALID_SCHEMA,\n \"The 'anyOf' array must not be empty.\"\n );\n }\n super({\n ...schemaParams,\n type: undefined // anyOf schemas do not have an explicit type\n });\n this.anyOf = schemaParams.anyOf;\n }\n\n /**\n * @internal\n */\n toJSON(): SchemaRequest {\n const obj = super.toJSON();\n // Ensure the 'anyOf' property contains serialized SchemaRequest objects.\n if (this.anyOf && Array.isArray(this.anyOf)) {\n obj.anyOf = (this.anyOf as TypedSchema[]).map(s => s.toJSON());\n }\n return obj;\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { logger } from '../logger';\n\n/**\n * Defines the image format for images generated by Imagen.\n *\n * Use this class to specify the desired format (JPEG or PNG) and compression quality\n * for images generated by Imagen. This is typically included as part of\n * {@link ImagenModelParams}.\n *\n * @example\n * ```javascript\n * const imagenModelParams = {\n * // ... other ImagenModelParams\n * imageFormat: ImagenImageFormat.jpeg(75) // JPEG with a compression level of 75.\n * }\n * ```\n *\n * @beta\n */\nexport class ImagenImageFormat {\n /**\n * The MIME type.\n */\n mimeType: string;\n /**\n * The level of compression (a number between 0 and 100).\n */\n compressionQuality?: number;\n\n private constructor() {\n this.mimeType = 'image/png';\n }\n\n /**\n * Creates an {@link ImagenImageFormat} for a JPEG image.\n *\n * @param compressionQuality - The level of compression (a number between 0 and 100).\n * @returns An {@link ImagenImageFormat} object for a JPEG image.\n *\n * @beta\n */\n static jpeg(compressionQuality?: number): ImagenImageFormat {\n if (\n compressionQuality &&\n (compressionQuality < 0 || compressionQuality > 100)\n ) {\n logger.warn(\n `Invalid JPEG compression quality of ${compressionQuality} specified; the supported range is [0, 100].`\n );\n }\n return { mimeType: 'image/jpeg', compressionQuality };\n }\n\n /**\n * Creates an {@link ImagenImageFormat} for a PNG image.\n *\n * @returns An {@link ImagenImageFormat} object for a PNG image.\n *\n * @beta\n */\n static png(): ImagenImageFormat {\n return { mimeType: 'image/png' };\n }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, getApp, _getProvider } from '@firebase/app';\nimport { Provider } from '@firebase/component';\nimport { getModularInstance } from '@firebase/util';\nimport { AI_TYPE, DEFAULT_HYBRID_IN_CLOUD_MODEL } from './constants';\nimport { AIService } from './service';\nimport { AI, AIOptions } from './public-types';\nimport {\n ImagenModelParams,\n HybridParams,\n ModelParams,\n RequestOptions,\n AIErrorCode\n} from './types';\nimport { AIError } from './errors';\nimport { AIModel, GenerativeModel, ImagenModel } from './models';\nimport { encodeInstanceIdentifier } from './helpers';\nimport { GoogleAIBackend } from './backend';\nimport { ChromeAdapterImpl } from './methods/chrome-adapter';\nimport { LanguageModel } from './types/language-model';\n\nexport { ChatSession } from './methods/chat-session';\nexport * from './requests/schema-builder';\nexport { ImagenImageFormat } from './requests/imagen-image-format';\nexport { AIModel, GenerativeModel, ImagenModel, AIError };\nexport { Backend, VertexAIBackend, GoogleAIBackend } from './backend';\n\ndeclare module '@firebase/component' {\n interface NameServiceMapping {\n [AI_TYPE]: AIService;\n }\n}\n\n/**\n * Returns the default {@link AI} instance that is associated with the provided\n * {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new instance with the\n * default settings.\n *\n * @example\n * ```javascript\n * const ai = getAI(app);\n * ```\n *\n * @example\n * ```javascript\n * // Get an AI instance configured to use the Gemini Developer API (via Google AI).\n * const ai = getAI(app, { backend: new GoogleAIBackend() });\n * ```\n *\n * @example\n * ```javascript\n * // Get an AI instance configured to use the Vertex AI Gemini API.\n * const ai = getAI(app, { backend: new VertexAIBackend() });\n * ```\n *\n * @param app - The {@link @firebase/app#FirebaseApp} to use.\n * @param options - {@link AIOptions} that configure the AI instance.\n * @returns The default {@link AI} instance for the given {@link @firebase/app#FirebaseApp}.\n *\n * @public\n */\nexport function getAI(\n app: FirebaseApp = getApp(),\n options: AIOptions = { backend: new GoogleAIBackend() }\n): AI {\n app = getModularInstance(app);\n // Dependencies\n const AIProvider: Provider<'AI'> = _getProvider(app, AI_TYPE);\n\n const identifier = encodeInstanceIdentifier(options.backend);\n return AIProvider.getImmediate({\n identifier\n });\n}\n\n/**\n * Returns a {@link GenerativeModel} class with methods for inference\n * and other functionality.\n *\n * @public\n */\nexport function getGenerativeModel(\n ai: AI,\n modelParams: ModelParams | HybridParams,\n requestOptions?: RequestOptions\n): GenerativeModel {\n // Uses the existence of HybridParams.mode to clarify the type of the modelParams input.\n const hybridParams = modelParams as HybridParams;\n let inCloudParams: ModelParams;\n if (hybridParams.mode) {\n inCloudParams = hybridParams.inCloudParams || {\n model: DEFAULT_HYBRID_IN_CLOUD_MODEL\n };\n } else {\n inCloudParams = modelParams as ModelParams;\n }\n\n if (!inCloudParams.model) {\n throw new AIError(\n AIErrorCode.NO_MODEL,\n `Must provide a model name. Example: getGenerativeModel({ model: 'my-model-name' })`\n );\n }\n let chromeAdapter: ChromeAdapterImpl | undefined;\n // Do not initialize a ChromeAdapter if we are not in hybrid mode.\n if (typeof window !== 'undefined' && hybridParams.mode) {\n chromeAdapter = new ChromeAdapterImpl(\n window.LanguageModel as LanguageModel,\n hybridParams.mode,\n hybridParams.onDeviceParams\n );\n }\n return new GenerativeModel(ai, inCloudParams, requestOptions, chromeAdapter);\n}\n\n/**\n * Returns an {@link ImagenModel} class with methods for using Imagen.\n *\n * Only Imagen 3 models (named `imagen-3.0-*`) are supported.\n *\n * @param ai - An {@link AI} instance.\n * @param modelParams - Parameters to use when making Imagen requests.\n * @param requestOptions - Additional options to use when making requests.\n *\n * @throws If the `apiKey` or `projectId` fields are missing in your\n * Firebase config.\n *\n * @beta\n */\nexport function getImagenModel(\n ai: AI,\n modelParams: ImagenModelParams,\n requestOptions?: RequestOptions\n): ImagenModel {\n if (!modelParams.model) {\n throw new AIError(\n AIErrorCode.NO_MODEL,\n `Must provide a model name. Example: getImagenModel({ model: 'my-model-name' })`\n );\n }\n return new ImagenModel(ai, modelParams, requestOptions);\n}\n","/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat<T> {\n _delegate: T;\n}\n\nexport function getModularInstance<ExpService>(\n service: Compat<ExpService> | ExpService\n): ExpService {\n if (service && (service as Compat<ExpService>)._delegate) {\n return (service as Compat<ExpService>)._delegate;\n } else {\n return service as ExpService;\n }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AI_TYPE } from './constants';\nimport { AIError } from './errors';\nimport { AIErrorCode } from './types';\nimport { Backend, GoogleAIBackend, VertexAIBackend } from './backend';\n\n/**\n * Encodes a {@link Backend} into a string that will be used to uniquely identify {@link AI}\n * instances by backend type.\n *\n * @internal\n */\nexport function encodeInstanceIdentifier(backend: Backend): string {\n if (backend instanceof GoogleAIBackend) {\n return `${AI_TYPE}/googleai`;\n } else if (backend instanceof VertexAIBackend) {\n return `${AI_TYPE}/vertexai/${backend.location}`;\n } else {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid backend: ${JSON.stringify(backend.backendType)}`\n );\n }\n}\n\n/**\n * Decodes an instance identifier string into a {@link Backend}.\n *\n * @internal\n */\nexport function decodeInstanceIdentifier(instanceIdentifier: string): Backend {\n const identifierParts = instanceIdentifier.split('/');\n if (identifierParts[0] !== AI_TYPE) {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid instance identifier, unknown prefix '${identifierParts[0]}'`\n );\n }\n const backendType = identifierParts[1];\n switch (backendType) {\n case 'vertexai':\n const location: string | undefined = identifierParts[2];\n if (!location) {\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid instance identifier, unknown location '${instanceIdentifier}'`\n );\n }\n return new VertexAIBackend(location);\n case 'googleai':\n return new GoogleAIBackend();\n default:\n throw new AIError(\n AIErrorCode.ERROR,\n `Invalid instance identifier string: '${instanceIdentifier}'`\n );\n }\n}\n","/**\n * The Firebase AI Web SDK.\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerVersion, _registerComponent } from '@firebase/app';\nimport { AIService } from './service';\nimport { AI_TYPE } from './constants';\nimport { Component, ComponentType } from '@firebase/component';\nimport { name, version } from '../package.json';\nimport { decodeInstanceIdentifier } from './helpers';\nimport { AIError } from './api';\nimport { AIErrorCode } from './types';\n\ndeclare global {\n interface Window {\n [key: string]: unknown;\n }\n}\n\nfunction registerAI(): void {\n _registerComponent(\n new Component(\n AI_TYPE,\n (container, { instanceIdentifier }) => {\n if (!instanceIdentifier) {\n throw new AIError(\n AIErrorCode.ERROR,\n 'AIService instance identifier is undefined.'\n );\n }\n\n const backend = decodeInstanceIdentifier(instanceIdentifier);\n\n // getImmediate for FirebaseApp will always succeed\n const app = container.getProvider('app').getImmediate();\n const auth = container.getProvider('auth-internal');\n const appCheckProvider = container.getProvider('app-check-internal');\n return new AIService(app, backend, auth, appCheckProvider);\n },\n ComponentType.PUBLIC\n ).setMultipleInstances(true)\n );\n\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm, cjs, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\nregisterAI();\n\nexport * from './api';\nexport * from './public-types';\n"],"names":["FirebaseError","Error","constructor","code","message","customData","super","this","name","Object","setPrototypeOf","prototype","captureStackTrace","ErrorFactory","create","service","serviceName","errors","data","fullCode","template","replaceTemplate","replace","PATTERN","_","key","value","String","fullMessage","Component","instanceFactory","type","multipleInstances","serviceProps","instantiationMode","onInstanceCreated","setInstantiationMode","mode","setMultipleInstances","setServiceProps","props","setInstanceCreatedCallback","callback","LogLevel","levelStringToEnum","debug","DEBUG","verbose","VERBOSE","info","INFO","warn","WARN","error","ERROR","silent","SILENT","defaultLogLevel","ConsoleMethod","defaultLogHandler","instance","logType","args","logLevel","now","Date","toISOString","method","console","AI_TYPE","DEFAULT_LOCATION","PACKAGE_VERSION","version","POSSIBLE_ROLES","HarmCategory","HARM_CATEGORY_HATE_SPEECH","HARM_CATEGORY_SEXUALLY_EXPLICIT","HARM_CATEGORY_HARASSMENT","HARM_CATEGORY_DANGEROUS_CONTENT","HarmBlockThreshold","BLOCK_LOW_AND_ABOVE","BLOCK_MEDIUM_AND_ABOVE","BLOCK_ONLY_HIGH","BLOCK_NONE","OFF","HarmBlockMethod","SEVERITY","PROBABILITY","HarmProbability","NEGLIGIBLE","LOW","MEDIUM","HIGH","HarmSeverity","HARM_SEVERITY_NEGLIGIBLE","HARM_SEVERITY_LOW","HARM_SEVERITY_MEDIUM","HARM_SEVERITY_HIGH","HARM_SEVERITY_UNSUPPORTED","BlockReason","SAFETY","OTHER","BLOCKLIST","PROHIBITED_CONTENT","FinishReason","STOP","MAX_TOKENS","RECITATION","SPII","MALFORMED_FUNCTION_CALL","FunctionCallingMode","AUTO","ANY","NONE","Modality","MODALITY_UNSPECIFIED","TEXT","IMAGE","VIDEO","AUDIO","DOCUMENT","ResponseModality","InferenceMode","PREFER_ON_DEVICE","ONLY_ON_DEVICE","ONLY_IN_CLOUD","AIErrorCode","REQUEST_ERROR","RESPONSE_ERROR","FETCH_ERROR","INVALID_CONTENT","API_NOT_ENABLED","INVALID_SCHEMA","NO_API_KEY","NO_APP_ID","NO_MODEL","NO_PROJECT_ID","PARSE_FAILED","UNSUPPORTED","SchemaType","STRING","NUMBER","INTEGER","BOOLEAN","ARRAY","OBJECT","ImagenSafetyFilterLevel","ImagenPersonFilterLevel","BLOCK_ALL","ALLOW_ADULT","ALLOW_ALL","ImagenAspectRatio","SQUARE","LANDSCAPE_3x4","PORTRAIT_4x3","LANDSCAPE_16x9","PORTRAIT_9x16","BackendType","VERTEX_AI","GOOGLE_AI","Backend","backendType","GoogleAIBackend","VertexAIBackend","location","AIService","app","backend","authProvider","appCheckProvider","appCheck","getImmediate","optional","auth","_delete","Promise","resolve","AIError","customErrorData","toString","AIModel","ai","modelName","options","apiKey","projectId","appId","_apiSettings","project","automaticDataCollectionEnabled","_isFirebaseServerApp","settings","appCheckToken","token","getAppCheckToken","getToken","getAuthToken","model","normalizeModelName","normalizeGoogleAIModelName","normalizeVertexAIModelName","includes","startsWith","logger","Logger","_logLevel","_logHandler","_userLogHandler","val","TypeError","setLogLevel","logHandler","userLogHandler","log","Task","RequestUrl","task","apiSettings","stream","requestOptions","url","URL","baseUrl","pathname","apiVersion","modelPath","search","queryParams","JSON","stringify","params","URLSearchParams","set","async","getHeaders","headers","Headers","append","getClientHeaders","loggingTags","push","join","authToken","accessToken","makeRequest","body","response","fetchTimeoutId","request","constructRequest","fetchOptions","timeoutMillis","timeout","abortController","AbortController","setTimeout","abort","signal","fetch","ok","errorDetails","json","details","e","status","some","detail","reason","links","description","statusText","err","stack","clearTimeout","createEnhancedContentResponse","candidates","hasOwnProperty","index","responseWithHelpers","addHelpers","text","length","hadBadFinishReason","formatBlockErrorMessage","getText","textStrings","content","parts","part","promptFeedback","inlineDataParts","getInlineDataParts","inlineData","functionCalls","getFunctionCalls","functionCall","badFinishReasons","candidate","finishReason","firstCandidate","finishMessage","blockReason","blockReasonMessage","handlePredictResponse","responseJson","images","filteredReason","predictions","prediction","raiFilteredReason","mimeType","bytesBase64Encoded","gcsUri","gcsURI","mapGenerateContentRequest","generateContentRequest","safetySettings","forEach","safetySetting","generationConfig","topK","roundedTopK","Math","round","mapGenerateContentResponse","googleAIResponse","mapGenerateContentCandidates","undefined","prompt","mapPromptFeedback","usageMetadata","mappedCandidates","mappedSafetyRatings","citationMetadata","citations","citationSources","safetyRatings","map","safetyRating","severity","probabilityScore","severityScore","videoMetadata","mappedCandidate","groundingMetadata","category","probability","blocked","responseLineRE","processStream","responseStream","getResponseStream","inputStream","reader","getReader","ReadableStream","start","controller","currentText","pump","read","then","done","trim","close","parsedResponse","match","parse","enqueue","substring","pipeThrough","TextDecoderStream","fatal","stream1","stream2","tee","generateResponseSequence","getResponsePromise","allResponses","generateContentResponse","aggregateResponses","GoogleAIMapper.mapGenerateContentResponse","enhancedResponse","responses","lastResponse","aggregatedResponse","i","role","newPart","keys","generateContentStream","chromeAdapter","isAvailable","generateContentStreamOnCloud","GoogleAIMapper.mapGenerateContentRequest","STREAM_GENERATE_CONTENT","generateContent","generateContentOnCloud","GENERATE_CONTENT","processGenerateContentResponse","formatSystemInstruction","input","formatNewContent","newParts","partOrString","assignRoleToPartsAndValidateSendMessageRequest","userContent","functionContent","hasUserContent","hasFunctionContent","formatGenerateContentInput","formattedRequest","contents","systemInstruction","createPredictRequestBody","imageFormat","addWatermark","numberOfImages","negativePrompt","aspectRatio","safetyFilterLevel","personFilterLevel","instances","parameters","storageUri","sampleCount","outputOptions","personGeneration","includeRaiReason","VALID_PART_FIELDS","VALID_PARTS_PER_ROLE","user","function","system","VALID_PREVIOUS_CONTENT_ROLES","SILENT_ERROR","ChatSession","_history","_sendPromise","history","validateChatHistory","prevContent","currContent","Array","isArray","countFields","functionResponse","validParts","getHistory","sendMessage","newContent","tools","toolConfig","finalResult","result","responseContent","blockErrorMessage","sendMessageStream","streamPromise","catch","_ignored","streamResult","countTokens","countTokensOnCloud","mappedParams","mapCountTokensRequest","countTokensRequest","GoogleAIMapper.mapCountTokensRequest","COUNT_TOKENS","GenerativeModel","modelParams","formattedParams","startChat","startChatParams","ImagenModel","generateImages","PREDICT","generateImagesGCS","Availability","ChromeAdapterImpl","languageModelProvider","onDeviceParams","createOptions","expectedInputs","isDownloading","availability","downloadIfAvailable","UNAVAILABLE","DOWNLOADABLE","DOWNLOADING","downloadPromise","AVAILABLE","isOnDeviceRequest","session","createSession","all","toLanguageModelMessage","promptOptions","toResponse","promptStreaming","toStreamResponse","_request","SUPPORTED_MIME_TYPES","indexOf","download","finally","languageModelMessageContents","toLanguageModelMessageContent","toLanguageModelMessageRole","formattedImageContent","imageBlob","blob","createImageBitmap","newSession","oldSession","destroy","encoder","TextEncoder","TransformStream","transform","chunk","encode","Schema","schemaParams","anyOf","paramKey","format","nullable","toJSON","obj","prop","array","arrayParams","ArraySchema","items","object","objectParams","ObjectSchema","properties","optionalProperties","string","stringParams","StringSchema","enumString","enum","integer","integerParams","IntegerSchema","number","numberParams","NumberSchema","boolean","booleanParams","BooleanSchema","anyOfParams","AnyOfSchema","enumValues","required","propertyKey","s","ImagenImageFormat","jpeg","compressionQuality","png","getAI","getApp","getModularInstance","_delegate","AIProvider","_getProvider","identifier","encodeInstanceIdentifier","getGenerativeModel","hybridParams","inCloudParams","window","LanguageModel","getImagenModel","registerAI","_registerComponent","container","instanceIdentifier","decodeInstanceIdentifier","identifierParts","split","getProvider","registerVersion"],"mappings":"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","preExistingComment":"firebase-ai.js.map"}
|