diff --git a/.changeset/feat-prefer-in-cloud.md b/.changeset/feat-prefer-in-cloud.md deleted file mode 100644 index 90f859c2da8..00000000000 --- a/.changeset/feat-prefer-in-cloud.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@firebase/ai": minor -"firebase": minor ---- - -Added a new `InferenceMode` option for the hybrid on-device capability: `prefer_in_cloud`. When this mode is selected, the SDK will attempt to use a cloud-hosted model first. If the call to the cloud-hosted model fails with a network-related error, the SDK will fall back to the on-device model, if it's available. diff --git a/.changeset/heavy-teachers-enjoy.md b/.changeset/heavy-teachers-enjoy.md deleted file mode 100644 index a5cf0820429..00000000000 --- a/.changeset/heavy-teachers-enjoy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@firebase/ai': patch ---- - -Refactor component registration. diff --git a/.changeset/lazy-donuts-agree.md b/.changeset/lazy-donuts-agree.md new file mode 100644 index 00000000000..f2baca4dcab --- /dev/null +++ b/.changeset/lazy-donuts-agree.md @@ -0,0 +1,9 @@ +--- +'firebase': minor +'@firebase/ai': minor +--- + +Added a `sendFunctionResponses` method to `LiveSession`, allowing function responses to be sent during realtime sessions. +Fixed an issue where function responses during audio conversations caused the WebSocket connection to close. See [GitHub Issue #9264](https://github.com/firebase/firebase-js-sdk/issues/9264). + - **Breaking Change**: Changed the `functionCallingHandler` property in `StartAudioConversationOptions` so that it now must return a `Promise`. + This breaking change is allowed in a minor release since the Live API is in Public Preview. diff --git a/.changeset/lemon-baboons-lick.md b/.changeset/lemon-baboons-lick.md deleted file mode 100644 index 3414d4c9bde..00000000000 --- a/.changeset/lemon-baboons-lick.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@firebase/remote-config': minor -'firebase': minor -'@firebase/remote-config-types': minor ---- - -Added support for Realtime Remote Config for the web. This feature introduces a new `onConfigUpdate` API and allows web applications to receive near-instant configuration updates without requiring periodic polling. diff --git a/.changeset/lucky-socks-roll.md b/.changeset/lucky-socks-roll.md deleted file mode 100644 index 8b9d9a19e97..00000000000 --- a/.changeset/lucky-socks-roll.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@firebase/ai': minor -'firebase': minor ---- - -Added Code Execution feature. diff --git a/.changeset/poor-cobras-dream.md b/.changeset/poor-cobras-dream.md new file mode 100644 index 00000000000..3ff9e7bc7bd --- /dev/null +++ b/.changeset/poor-cobras-dream.md @@ -0,0 +1,5 @@ +--- +'@firebase/ai': patch +--- + +Updated SDK to handle empty parts when streaming. diff --git a/.changeset/poor-rings-admire.md b/.changeset/poor-rings-admire.md new file mode 100644 index 00000000000..1b63c0138d0 --- /dev/null +++ b/.changeset/poor-rings-admire.md @@ -0,0 +1,6 @@ +--- +'firebase': minor +'@firebase/ai': minor +--- + +Added support for the URL context tool, which allows the model to access content from provided public web URLs to inform and enhance its responses. diff --git a/.changeset/selfish-elephants-sniff.md b/.changeset/selfish-elephants-sniff.md deleted file mode 100644 index dc791fbb9b8..00000000000 --- a/.changeset/selfish-elephants-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@firebase/ai': patch ---- - -Change documentation tags for hybrid inference from "EXPERIMENTAL" to "public preview". diff --git a/.changeset/tender-meals-clap.md b/.changeset/tender-meals-clap.md new file mode 100644 index 00000000000..44509f4f489 --- /dev/null +++ b/.changeset/tender-meals-clap.md @@ -0,0 +1,5 @@ +--- +'@firebase/ai': patch +--- + +Tag code execution with beta tag (public preview). diff --git a/.changeset/tiny-doors-talk.md b/.changeset/tiny-doors-talk.md deleted file mode 100644 index 683f9c28d90..00000000000 --- a/.changeset/tiny-doors-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@firebase/webchannel-wrapper": patch -"@firebase/firestore": patch ---- -Increased the buffering-proxy detection timeout to minimize the false-positive rate. Updating WebChannel to ignore duplicate messages received from the server. Fix for https://github.com/firebase/firebase-js-sdk/issues/8250. diff --git a/.changeset/young-timers-jump.md b/.changeset/young-timers-jump.md new file mode 100644 index 00000000000..2c572813ae8 --- /dev/null +++ b/.changeset/young-timers-jump.md @@ -0,0 +1,6 @@ +--- +'@firebase/analytics-interop-types': patch +'@firebase/analytics': patch +--- + +Expose `setUserProperties` on internal Analytics instance. diff --git a/common/api-review/ai.api.md b/common/api-review/ai.api.md index d4c3c1ad507..d3c43d906fd 100644 --- a/common/api-review/ai.api.md +++ b/common/api-review/ai.api.md @@ -175,13 +175,13 @@ export interface CitationMetadata { citations: Citation[]; } -// @public +// @beta export interface CodeExecutionResult { outcome?: Outcome; output?: string; } -// @public +// @beta export interface CodeExecutionResultPart { // (undocumented) codeExecutionResult?: CodeExecutionResult; @@ -203,7 +203,7 @@ export interface CodeExecutionResultPart { thoughtSignature?: never; } -// @public +// @beta export interface CodeExecutionTool { codeExecution: {}; } @@ -271,13 +271,13 @@ export interface ErrorDetails { reason?: string; } -// @public +// @beta export interface ExecutableCode { code?: string; language?: Language; } -// @public +// @beta export interface ExecutableCodePart { // (undocumented) codeExecutionResult?: never; @@ -449,6 +449,10 @@ export interface GenerateContentCandidate { index: number; // (undocumented) safetyRatings?: SafetyRating[]; + // Warning: (ae-incompatible-release-tags) The symbol "urlContextMetadata" is marked as @public, but its signature references "URLContextMetadata" which is marked as @beta + // + // (undocumented) + urlContextMetadata?: URLContextMetadata; } // @public @@ -600,6 +604,8 @@ export interface GoogleAIGenerateContentCandidate { index: number; // (undocumented) safetyRatings?: SafetyRating[]; + // (undocumented) + urlContextMetadata?: URLContextMetadata; } // Warning: (ae-internal-missing-underscore) The name "GoogleAIGenerateContentResponse" should be prefixed with an underscore because the declaration is marked as @internal @@ -836,13 +842,13 @@ export class IntegerSchema extends Schema { constructor(schemaParams?: SchemaParams); } -// @public +// @beta export const Language: { UNSPECIFIED: string; PYTHON: string; }; -// @public +// @beta export type Language = (typeof Language)[keyof typeof Language]; // @beta @@ -988,6 +994,7 @@ export class LiveSession { isClosed: boolean; receive(): AsyncGenerator; send(request: string | Array, turnComplete?: boolean): Promise; + sendFunctionResponses(functionResponses: FunctionResponse[]): Promise; sendMediaChunks(mediaChunks: GenerativeContentBlob[]): Promise; sendMediaStream(mediaChunkStream: ReadableStream): Promise; } @@ -1058,7 +1065,7 @@ export interface OnDeviceParams { promptOptions?: LanguageModelPromptOptions; } -// @public +// @beta export const Outcome: { UNSPECIFIED: string; OK: string; @@ -1066,9 +1073,12 @@ export const Outcome: { DEADLINE_EXCEEDED: string; }; -// @public +// @beta export type Outcome = (typeof Outcome)[keyof typeof Outcome]; +// Warning: (ae-incompatible-release-tags) The symbol "Part" is marked as @public, but its signature references "ExecutableCodePart" which is marked as @beta +// Warning: (ae-incompatible-release-tags) The symbol "Part" is marked as @public, but its signature references "CodeExecutionResultPart" which is marked as @beta +// // @public export type Part = TextPart | InlineDataPart | FunctionCallPart | FunctionResponsePart | FileDataPart | ExecutableCodePart | CodeExecutionResultPart; @@ -1254,7 +1264,7 @@ export function startAudioConversation(liveSession: LiveSession, options?: Start // @beta export interface StartAudioConversationOptions { - functionCallingHandler?: (functionCalls: LiveServerToolCall['functionCalls']) => Promise; + functionCallingHandler?: (functionCalls: FunctionCall[]) => Promise; } // @public @@ -1304,8 +1314,11 @@ export interface ThinkingConfig { thinkingBudget?: number; } +// Warning: (ae-incompatible-release-tags) The symbol "Tool" is marked as @public, but its signature references "CodeExecutionTool" which is marked as @beta +// Warning: (ae-incompatible-release-tags) The symbol "Tool" is marked as @public, but its signature references "URLContextTool" which is marked as @beta +// // @public -export type Tool = FunctionDeclarationsTool | GoogleSearchTool | CodeExecutionTool; +export type Tool = FunctionDeclarationsTool | GoogleSearchTool | CodeExecutionTool | URLContextTool; // @public export interface ToolConfig { @@ -1316,6 +1329,38 @@ export interface ToolConfig { // @public export type TypedSchema = IntegerSchema | NumberSchema | StringSchema | BooleanSchema | ObjectSchema | ArraySchema | AnyOfSchema; +// @beta +export interface URLContext { +} + +// @beta +export interface URLContextMetadata { + urlMetadata: URLMetadata[]; +} + +// @beta +export interface URLContextTool { + urlContext: URLContext; +} + +// @beta +export interface URLMetadata { + retrievedUrl?: string; + urlRetrievalStatus?: URLRetrievalStatus; +} + +// @beta +export const URLRetrievalStatus: { + URL_RETRIEVAL_STATUS_UNSPECIFIED: string; + URL_RETRIEVAL_STATUS_SUCCESS: string; + URL_RETRIEVAL_STATUS_ERROR: string; + URL_RETRIEVAL_STATUS_PAYWALL: string; + URL_RETRIEVAL_STATUS_UNSAFE: string; +}; + +// @beta +export type URLRetrievalStatus = (typeof URLRetrievalStatus)[keyof typeof URLRetrievalStatus]; + // @public export interface UsageMetadata { // (undocumented) @@ -1327,6 +1372,8 @@ export interface UsageMetadata { // (undocumented) promptTokensDetails?: ModalityTokenCount[]; thoughtsTokenCount?: number; + toolUsePromptTokenCount?: number; + toolUsePromptTokensDetails?: ModalityTokenCount[]; // (undocumented) totalTokenCount: number; } diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml index b814910c792..c55d94327cf 100644 --- a/docs-devsite/_toc.yaml +++ b/docs-devsite/_toc.yaml @@ -202,6 +202,14 @@ toc: path: /docs/reference/js/ai.thinkingconfig.md - title: ToolConfig path: /docs/reference/js/ai.toolconfig.md + - title: URLContext + path: /docs/reference/js/ai.urlcontext.md + - title: URLContextMetadata + path: /docs/reference/js/ai.urlcontextmetadata.md + - title: URLContextTool + path: /docs/reference/js/ai.urlcontexttool.md + - title: URLMetadata + path: /docs/reference/js/ai.urlmetadata.md - title: UsageMetadata path: /docs/reference/js/ai.usagemetadata.md - title: VertexAIBackend diff --git a/docs-devsite/ai.codeexecutionresult.md b/docs-devsite/ai.codeexecutionresult.md index d0be155c4e6..d9d937ecad6 100644 --- a/docs-devsite/ai.codeexecutionresult.md +++ b/docs-devsite/ai.codeexecutionresult.md @@ -10,6 +10,9 @@ https://github.com/firebase/firebase-js-sdk {% endcomment %} # CodeExecutionResult interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The results of code execution run by the model. Signature: @@ -22,11 +25,14 @@ export interface CodeExecutionResult | Property | Type | Description | | --- | --- | --- | -| [outcome](./ai.codeexecutionresult.md#codeexecutionresultoutcome) | [Outcome](./ai.md#outcome) | The result of the code execution. | -| [output](./ai.codeexecutionresult.md#codeexecutionresultoutput) | string | The output from the code execution, or an error message if it failed. | +| [outcome](./ai.codeexecutionresult.md#codeexecutionresultoutcome) | [Outcome](./ai.md#outcome) | (Public Preview) The result of the code execution. | +| [output](./ai.codeexecutionresult.md#codeexecutionresultoutput) | string | (Public Preview) The output from the code execution, or an error message if it failed. | ## CodeExecutionResult.outcome +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The result of the code execution. Signature: @@ -37,6 +43,9 @@ outcome?: Outcome; ## CodeExecutionResult.output +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The output from the code execution, or an error message if it failed. Signature: diff --git a/docs-devsite/ai.codeexecutionresultpart.md b/docs-devsite/ai.codeexecutionresultpart.md index 6142a3ec79f..19364c5a7b7 100644 --- a/docs-devsite/ai.codeexecutionresultpart.md +++ b/docs-devsite/ai.codeexecutionresultpart.md @@ -10,6 +10,9 @@ https://github.com/firebase/firebase-js-sdk {% endcomment %} # CodeExecutionResultPart interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Represents the code execution result from the model. Signature: @@ -22,17 +25,20 @@ export interface CodeExecutionResultPart | Property | Type | Description | | --- | --- | --- | -| [codeExecutionResult](./ai.codeexecutionresultpart.md#codeexecutionresultpartcodeexecutionresult) | [CodeExecutionResult](./ai.codeexecutionresult.md#codeexecutionresult_interface) | | -| [executableCode](./ai.codeexecutionresultpart.md#codeexecutionresultpartexecutablecode) | never | | -| [fileData](./ai.codeexecutionresultpart.md#codeexecutionresultpartfiledata) | never | | -| [functionCall](./ai.codeexecutionresultpart.md#codeexecutionresultpartfunctioncall) | never | | -| [functionResponse](./ai.codeexecutionresultpart.md#codeexecutionresultpartfunctionresponse) | never | | -| [inlineData](./ai.codeexecutionresultpart.md#codeexecutionresultpartinlinedata) | never | | -| [text](./ai.codeexecutionresultpart.md#codeexecutionresultparttext) | never | | -| [thought](./ai.codeexecutionresultpart.md#codeexecutionresultpartthought) | never | | +| [codeExecutionResult](./ai.codeexecutionresultpart.md#codeexecutionresultpartcodeexecutionresult) | [CodeExecutionResult](./ai.codeexecutionresult.md#codeexecutionresult_interface) | (Public Preview) | +| [executableCode](./ai.codeexecutionresultpart.md#codeexecutionresultpartexecutablecode) | never | (Public Preview) | +| [fileData](./ai.codeexecutionresultpart.md#codeexecutionresultpartfiledata) | never | (Public Preview) | +| [functionCall](./ai.codeexecutionresultpart.md#codeexecutionresultpartfunctioncall) | never | (Public Preview) | +| [functionResponse](./ai.codeexecutionresultpart.md#codeexecutionresultpartfunctionresponse) | never | (Public Preview) | +| [inlineData](./ai.codeexecutionresultpart.md#codeexecutionresultpartinlinedata) | never | (Public Preview) | +| [text](./ai.codeexecutionresultpart.md#codeexecutionresultparttext) | never | (Public Preview) | +| [thought](./ai.codeexecutionresultpart.md#codeexecutionresultpartthought) | never | (Public Preview) | ## CodeExecutionResultPart.codeExecutionResult +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -41,6 +47,9 @@ codeExecutionResult?: CodeExecutionResult; ## CodeExecutionResultPart.executableCode +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -49,6 +58,9 @@ executableCode?: never; ## CodeExecutionResultPart.fileData +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -57,6 +69,9 @@ fileData: never; ## CodeExecutionResultPart.functionCall +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -65,6 +80,9 @@ functionCall?: never; ## CodeExecutionResultPart.functionResponse +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -73,6 +91,9 @@ functionResponse?: never; ## CodeExecutionResultPart.inlineData +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -81,6 +102,9 @@ inlineData?: never; ## CodeExecutionResultPart.text +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -89,6 +113,9 @@ text?: never; ## CodeExecutionResultPart.thought +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript diff --git a/docs-devsite/ai.codeexecutiontool.md b/docs-devsite/ai.codeexecutiontool.md index 34a4715ac63..68a1e133d7b 100644 --- a/docs-devsite/ai.codeexecutiontool.md +++ b/docs-devsite/ai.codeexecutiontool.md @@ -10,6 +10,9 @@ https://github.com/firebase/firebase-js-sdk {% endcomment %} # CodeExecutionTool interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + A tool that enables the model to use code execution. Signature: @@ -22,10 +25,13 @@ export interface CodeExecutionTool | Property | Type | Description | | --- | --- | --- | -| [codeExecution](./ai.codeexecutiontool.md#codeexecutiontoolcodeexecution) | {} | Specifies the Google Search configuration. Currently, this is an empty object, but it's reserved for future configuration options. | +| [codeExecution](./ai.codeexecutiontool.md#codeexecutiontoolcodeexecution) | {} | (Public Preview) Specifies the Google Search configuration. Currently, this is an empty object, but it's reserved for future configuration options. | ## CodeExecutionTool.codeExecution +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Specifies the Google Search configuration. Currently, this is an empty object, but it's reserved for future configuration options. Signature: diff --git a/docs-devsite/ai.executablecode.md b/docs-devsite/ai.executablecode.md index bab79bacc50..c2dfa09cd77 100644 --- a/docs-devsite/ai.executablecode.md +++ b/docs-devsite/ai.executablecode.md @@ -10,6 +10,9 @@ https://github.com/firebase/firebase-js-sdk {% endcomment %} # ExecutableCode interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + An interface for executable code returned by the model. Signature: @@ -22,11 +25,14 @@ export interface ExecutableCode | Property | Type | Description | | --- | --- | --- | -| [code](./ai.executablecode.md#executablecodecode) | string | The source code to be executed. | -| [language](./ai.executablecode.md#executablecodelanguage) | [Language](./ai.md#language) | The programming language of the code. | +| [code](./ai.executablecode.md#executablecodecode) | string | (Public Preview) The source code to be executed. | +| [language](./ai.executablecode.md#executablecodelanguage) | [Language](./ai.md#language) | (Public Preview) The programming language of the code. | ## ExecutableCode.code +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The source code to be executed. Signature: @@ -37,6 +43,9 @@ code?: string; ## ExecutableCode.language +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The programming language of the code. Signature: diff --git a/docs-devsite/ai.executablecodepart.md b/docs-devsite/ai.executablecodepart.md index 99c6bf05987..cac32c132ed 100644 --- a/docs-devsite/ai.executablecodepart.md +++ b/docs-devsite/ai.executablecodepart.md @@ -10,6 +10,9 @@ https://github.com/firebase/firebase-js-sdk {% endcomment %} # ExecutableCodePart interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Represents the code that is executed by the model. Signature: @@ -22,17 +25,20 @@ export interface ExecutableCodePart | Property | Type | Description | | --- | --- | --- | -| [codeExecutionResult](./ai.executablecodepart.md#executablecodepartcodeexecutionresult) | never | | -| [executableCode](./ai.executablecodepart.md#executablecodepartexecutablecode) | [ExecutableCode](./ai.executablecode.md#executablecode_interface) | | -| [fileData](./ai.executablecodepart.md#executablecodepartfiledata) | never | | -| [functionCall](./ai.executablecodepart.md#executablecodepartfunctioncall) | never | | -| [functionResponse](./ai.executablecodepart.md#executablecodepartfunctionresponse) | never | | -| [inlineData](./ai.executablecodepart.md#executablecodepartinlinedata) | never | | -| [text](./ai.executablecodepart.md#executablecodeparttext) | never | | -| [thought](./ai.executablecodepart.md#executablecodepartthought) | never | | +| [codeExecutionResult](./ai.executablecodepart.md#executablecodepartcodeexecutionresult) | never | (Public Preview) | +| [executableCode](./ai.executablecodepart.md#executablecodepartexecutablecode) | [ExecutableCode](./ai.executablecode.md#executablecode_interface) | (Public Preview) | +| [fileData](./ai.executablecodepart.md#executablecodepartfiledata) | never | (Public Preview) | +| [functionCall](./ai.executablecodepart.md#executablecodepartfunctioncall) | never | (Public Preview) | +| [functionResponse](./ai.executablecodepart.md#executablecodepartfunctionresponse) | never | (Public Preview) | +| [inlineData](./ai.executablecodepart.md#executablecodepartinlinedata) | never | (Public Preview) | +| [text](./ai.executablecodepart.md#executablecodeparttext) | never | (Public Preview) | +| [thought](./ai.executablecodepart.md#executablecodepartthought) | never | (Public Preview) | ## ExecutableCodePart.codeExecutionResult +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -41,6 +47,9 @@ codeExecutionResult?: never; ## ExecutableCodePart.executableCode +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -49,6 +58,9 @@ executableCode?: ExecutableCode; ## ExecutableCodePart.fileData +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -57,6 +69,9 @@ fileData: never; ## ExecutableCodePart.functionCall +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -65,6 +80,9 @@ functionCall?: never; ## ExecutableCodePart.functionResponse +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -73,6 +91,9 @@ functionResponse?: never; ## ExecutableCodePart.inlineData +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -81,6 +102,9 @@ inlineData?: never; ## ExecutableCodePart.text +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript @@ -89,6 +113,9 @@ text?: never; ## ExecutableCodePart.thought +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Signature: ```typescript diff --git a/docs-devsite/ai.generatecontentcandidate.md b/docs-devsite/ai.generatecontentcandidate.md index ca0383549a7..1691442ecfa 100644 --- a/docs-devsite/ai.generatecontentcandidate.md +++ b/docs-devsite/ai.generatecontentcandidate.md @@ -29,6 +29,7 @@ export interface GenerateContentCandidate | [groundingMetadata](./ai.generatecontentcandidate.md#generatecontentcandidategroundingmetadata) | [GroundingMetadata](./ai.groundingmetadata.md#groundingmetadata_interface) | | | [index](./ai.generatecontentcandidate.md#generatecontentcandidateindex) | number | | | [safetyRatings](./ai.generatecontentcandidate.md#generatecontentcandidatesafetyratings) | [SafetyRating](./ai.safetyrating.md#safetyrating_interface)\[\] | | +| [urlContextMetadata](./ai.generatecontentcandidate.md#generatecontentcandidateurlcontextmetadata) | [URLContextMetadata](./ai.urlcontextmetadata.md#urlcontextmetadata_interface) | | ## GenerateContentCandidate.citationMetadata @@ -85,3 +86,11 @@ index: number; ```typescript safetyRatings?: SafetyRating[]; ``` + +## GenerateContentCandidate.urlContextMetadata + +Signature: + +```typescript +urlContextMetadata?: URLContextMetadata; +``` diff --git a/docs-devsite/ai.livesession.md b/docs-devsite/ai.livesession.md index 6ae2cde711c..558c5eb3bd6 100644 --- a/docs-devsite/ai.livesession.md +++ b/docs-devsite/ai.livesession.md @@ -39,6 +39,7 @@ export declare class LiveSession | [close()](./ai.livesession.md#livesessionclose) | | (Public Preview) Closes this session. All methods on this session will throw an error once this resolves. | | [receive()](./ai.livesession.md#livesessionreceive) | | (Public Preview) Yields messages received from the server. This can only be used by one consumer at a time. | | [send(request, turnComplete)](./ai.livesession.md#livesessionsend) | | (Public Preview) Sends content to the server. | +| [sendFunctionResponses(functionResponses)](./ai.livesession.md#livesessionsendfunctionresponses) | | (Public Preview) Sends function responses to the server. | | [sendMediaChunks(mediaChunks)](./ai.livesession.md#livesessionsendmediachunks) | | (Public Preview) Sends realtime input to the server. | | [sendMediaStream(mediaChunkStream)](./ai.livesession.md#livesessionsendmediastream) | | (Public Preview) Sends a stream of [GenerativeContentBlob](./ai.generativecontentblob.md#generativecontentblob_interface). | @@ -134,6 +135,33 @@ Promise<void> If this session has been closed. +## LiveSession.sendFunctionResponses() + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Sends function responses to the server. + +Signature: + +```typescript +sendFunctionResponses(functionResponses: FunctionResponse[]): Promise; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionResponses | [FunctionResponse](./ai.functionresponse.md#functionresponse_interface)\[\] | The function responses to send. | + +Returns: + +Promise<void> + +#### Exceptions + +If this session has been closed. + ## LiveSession.sendMediaChunks() > This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. diff --git a/docs-devsite/ai.md b/docs-devsite/ai.md index 78d82d23800..c6e8fa365f7 100644 --- a/docs-devsite/ai.md +++ b/docs-devsite/ai.md @@ -60,9 +60,9 @@ The Firebase AI Web SDK. | [ChromeAdapter](./ai.chromeadapter.md#chromeadapter_interface) | (Public Preview) Defines an inference "backend" that uses Chrome's on-device model, and encapsulates logic for detecting when on-device inference is possible.These methods should not be called directly by the user. | | [Citation](./ai.citation.md#citation_interface) | A single citation. | | [CitationMetadata](./ai.citationmetadata.md#citationmetadata_interface) | Citation metadata that may be found on a [GenerateContentCandidate](./ai.generatecontentcandidate.md#generatecontentcandidate_interface). | -| [CodeExecutionResult](./ai.codeexecutionresult.md#codeexecutionresult_interface) | The results of code execution run by the model. | -| [CodeExecutionResultPart](./ai.codeexecutionresultpart.md#codeexecutionresultpart_interface) | Represents the code execution result from the model. | -| [CodeExecutionTool](./ai.codeexecutiontool.md#codeexecutiontool_interface) | A tool that enables the model to use code execution. | +| [CodeExecutionResult](./ai.codeexecutionresult.md#codeexecutionresult_interface) | (Public Preview) The results of code execution run by the model. | +| [CodeExecutionResultPart](./ai.codeexecutionresultpart.md#codeexecutionresultpart_interface) | (Public Preview) Represents the code execution result from the model. | +| [CodeExecutionTool](./ai.codeexecutiontool.md#codeexecutiontool_interface) | (Public Preview) A tool that enables the model to use code execution. | | [Content](./ai.content.md#content_interface) | Content type for both prompts and response candidates. | | [CountTokensRequest](./ai.counttokensrequest.md#counttokensrequest_interface) | Params for calling [GenerativeModel.countTokens()](./ai.generativemodel.md#generativemodelcounttokens) | | [CountTokensResponse](./ai.counttokensresponse.md#counttokensresponse_interface) | Response from calling [GenerativeModel.countTokens()](./ai.generativemodel.md#generativemodelcounttokens). | @@ -70,8 +70,8 @@ The Firebase AI Web SDK. | [Date\_2](./ai.date_2.md#date_2_interface) | Protobuf google.type.Date | | [EnhancedGenerateContentResponse](./ai.enhancedgeneratecontentresponse.md#enhancedgeneratecontentresponse_interface) | Response object wrapped with helper methods. | | [ErrorDetails](./ai.errordetails.md#errordetails_interface) | Details object that may be included in an error response. | -| [ExecutableCode](./ai.executablecode.md#executablecode_interface) | An interface for executable code returned by the model. | -| [ExecutableCodePart](./ai.executablecodepart.md#executablecodepart_interface) | Represents the code that is executed by the model. | +| [ExecutableCode](./ai.executablecode.md#executablecode_interface) | (Public Preview) An interface for executable code returned by the model. | +| [ExecutableCodePart](./ai.executablecodepart.md#executablecodepart_interface) | (Public Preview) Represents the code that is executed by the model. | | [FileData](./ai.filedata.md#filedata_interface) | Data pointing to a file uploaded on Google Cloud Storage. | | [FileDataPart](./ai.filedatapart.md#filedatapart_interface) | Content part interface if the part represents [FileData](./ai.filedata.md#filedata_interface) | | [FunctionCall](./ai.functioncall.md#functioncall_interface) | A predicted [FunctionCall](./ai.functioncall.md#functioncall_interface) returned from the model that contains a string representing the [FunctionDeclaration.name](./ai.functiondeclaration.md#functiondeclarationname) and a structured JSON object containing the parameters and their values. | @@ -134,6 +134,10 @@ The Firebase AI Web SDK. | [TextPart](./ai.textpart.md#textpart_interface) | Content part interface if the part represents a text string. | | [ThinkingConfig](./ai.thinkingconfig.md#thinkingconfig_interface) | Configuration for "thinking" behavior of compatible Gemini models.Certain models utilize a thinking process before generating a response. This allows them to reason through complex problems and plan a more coherent and accurate answer. | | [ToolConfig](./ai.toolconfig.md#toolconfig_interface) | Tool config. This config is shared for all tools provided in the request. | +| [URLContext](./ai.urlcontext.md#urlcontext_interface) | (Public Preview) Specifies the URL Context configuration. | +| [URLContextMetadata](./ai.urlcontextmetadata.md#urlcontextmetadata_interface) | (Public Preview) Metadata related to [URLContextTool](./ai.urlcontexttool.md#urlcontexttool_interface). | +| [URLContextTool](./ai.urlcontexttool.md#urlcontexttool_interface) | (Public Preview) A tool that allows you to provide additional context to the models in the form of public web URLs. By including URLs in your request, the Gemini model will access the content from those pages to inform and enhance its response. | +| [URLMetadata](./ai.urlmetadata.md#urlmetadata_interface) | (Public Preview) Metadata for a single URL retrieved by the [URLContextTool](./ai.urlcontexttool.md#urlcontexttool_interface) tool. | | [UsageMetadata](./ai.usagemetadata.md#usagemetadata_interface) | Usage metadata about a [GenerateContentResponse](./ai.generatecontentresponse.md#generatecontentresponse_interface). | | [VideoMetadata](./ai.videometadata.md#videometadata_interface) | Describes the input video content. | | [VoiceConfig](./ai.voiceconfig.md#voiceconfig_interface) | (Public Preview) Configuration for the voice to used in speech synthesis. | @@ -158,13 +162,14 @@ The Firebase AI Web SDK. | [ImagenPersonFilterLevel](./ai.md#imagenpersonfilterlevel) | (Public Preview) A filter level controlling whether generation of images containing people or faces is allowed.See the personGeneration documentation for more details. | | [ImagenSafetyFilterLevel](./ai.md#imagensafetyfilterlevel) | (Public Preview) A filter level controlling how aggressively to filter sensitive content.Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI are assessed against a list of safety filters, which include 'harmful categories' (for example, violence, sexual, derogatory, and toxic). This filter level controls how aggressively to filter out potentially harmful content from responses. See the [documentation](http://firebase.google.com/docs/vertex-ai/generate-images) and the [Responsible AI and usage guidelines](https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters) for more details. | | [InferenceMode](./ai.md#inferencemode) | (Public Preview) Determines whether inference happens on-device or in-cloud. | -| [Language](./ai.md#language) | The programming language of the code. | +| [Language](./ai.md#language) | (Public Preview) The programming language of the code. | | [LiveResponseType](./ai.md#liveresponsetype) | (Public Preview) The types of responses that can be returned by [LiveSession.receive()](./ai.livesession.md#livesessionreceive). | | [Modality](./ai.md#modality) | Content part modality. | -| [Outcome](./ai.md#outcome) | Represents the result of the code execution. | +| [Outcome](./ai.md#outcome) | (Public Preview) Represents the result of the code execution. | | [POSSIBLE\_ROLES](./ai.md#possible_roles) | Possible roles. | | [ResponseModality](./ai.md#responsemodality) | (Public Preview) Generation modalities to be returned in generation responses. | | [SchemaType](./ai.md#schematype) | Contains the list of OpenAPI data types as defined by the [OpenAPI specification](https://swagger.io/docs/specification/data-models/data-types/) | +| [URLRetrievalStatus](./ai.md#urlretrievalstatus) | (Public Preview) The status of a URL retrieval. | ## Type Aliases @@ -184,19 +189,20 @@ The Firebase AI Web SDK. | [ImagenPersonFilterLevel](./ai.md#imagenpersonfilterlevel) | (Public Preview) A filter level controlling whether generation of images containing people or faces is allowed.See the personGeneration documentation for more details. | | [ImagenSafetyFilterLevel](./ai.md#imagensafetyfilterlevel) | (Public Preview) A filter level controlling how aggressively to filter sensitive content.Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI are assessed against a list of safety filters, which include 'harmful categories' (for example, violence, sexual, derogatory, and toxic). This filter level controls how aggressively to filter out potentially harmful content from responses. See the [documentation](http://firebase.google.com/docs/vertex-ai/generate-images) and the [Responsible AI and usage guidelines](https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters) for more details. | | [InferenceMode](./ai.md#inferencemode) | (Public Preview) Determines whether inference happens on-device or in-cloud. | -| [Language](./ai.md#language) | The programming language of the code. | +| [Language](./ai.md#language) | (Public Preview) The programming language of the code. | | [LanguageModelMessageContentValue](./ai.md#languagemodelmessagecontentvalue) | (Public Preview) Content formats that can be provided as on-device message content. | | [LanguageModelMessageRole](./ai.md#languagemodelmessagerole) | (Public Preview) Allowable roles for on-device language model usage. | | [LanguageModelMessageType](./ai.md#languagemodelmessagetype) | (Public Preview) Allowable types for on-device language model messages. | | [LiveResponseType](./ai.md#liveresponsetype) | (Public Preview) The types of responses that can be returned by [LiveSession.receive()](./ai.livesession.md#livesessionreceive). This is a property on all messages that can be used for type narrowing. This property is not returned by the server, it is assigned to a server message object once it's parsed. | | [Modality](./ai.md#modality) | Content part modality. | -| [Outcome](./ai.md#outcome) | Represents the result of the code execution. | +| [Outcome](./ai.md#outcome) | (Public Preview) Represents the result of the code execution. | | [Part](./ai.md#part) | Content part - includes text, image/video, or function call/response part types. | | [ResponseModality](./ai.md#responsemodality) | (Public Preview) Generation modalities to be returned in generation responses. | | [Role](./ai.md#role) | Role is the producer of the content. | | [SchemaType](./ai.md#schematype) | Contains the list of OpenAPI data types as defined by the [OpenAPI specification](https://swagger.io/docs/specification/data-models/data-types/) | | [Tool](./ai.md#tool) | Defines a tool that model can call to access external knowledge. | | [TypedSchema](./ai.md#typedschema) | A type that includes all specific Schema types. | +| [URLRetrievalStatus](./ai.md#urlretrievalstatus) | (Public Preview) The status of a URL retrieval. | ## function(app, ...) @@ -651,6 +657,9 @@ InferenceMode: { ## Language +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The programming language of the code. Signature: @@ -698,6 +707,9 @@ Modality: { ## Outcome +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Represents the result of the code execution. Signature: @@ -755,6 +767,27 @@ SchemaType: { } ``` +## URLRetrievalStatus + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +The status of a URL retrieval. + +URL\_RETRIEVAL\_STATUS\_UNSPECIFIED: Unspecified retrieval status.
URL\_RETRIEVAL\_STATUS\_SUCCESS: The URL retrieval was successful.
URL\_RETRIEVAL\_STATUS\_ERROR: The URL retrieval failed.
URL\_RETRIEVAL\_STATUS\_PAYWALL: The URL retrieval failed because the content is behind a paywall.
URL\_RETRIEVAL\_STATUS\_UNSAFE: The URL retrieval failed because the content is unsafe.
+ +Signature: + +```typescript +URLRetrievalStatus: { + URL_RETRIEVAL_STATUS_UNSPECIFIED: string; + URL_RETRIEVAL_STATUS_SUCCESS: string; + URL_RETRIEVAL_STATUS_ERROR: string; + URL_RETRIEVAL_STATUS_PAYWALL: string; + URL_RETRIEVAL_STATUS_UNSAFE: string; +} +``` + ## AIErrorCode Standardized error codes that [AIError](./ai.aierror.md#aierror_class) can have. @@ -916,6 +949,9 @@ export type InferenceMode = (typeof InferenceMode)[keyof typeof InferenceMode]; ## Language +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + The programming language of the code. Signature: @@ -988,6 +1024,9 @@ export type Modality = (typeof Modality)[keyof typeof Modality]; ## Outcome +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + Represents the result of the code execution. Signature: @@ -1046,7 +1085,7 @@ Defines a tool that model can call to access external knowledge. Signature: ```typescript -export type Tool = FunctionDeclarationsTool | GoogleSearchTool | CodeExecutionTool; +export type Tool = FunctionDeclarationsTool | GoogleSearchTool | CodeExecutionTool | URLContextTool; ``` ## TypedSchema @@ -1058,3 +1097,18 @@ A type that includes all specific Schema types. ```typescript export type TypedSchema = IntegerSchema | NumberSchema | StringSchema | BooleanSchema | ObjectSchema | ArraySchema | AnyOfSchema; ``` + +## URLRetrievalStatus + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +The status of a URL retrieval. + +URL\_RETRIEVAL\_STATUS\_UNSPECIFIED: Unspecified retrieval status.
URL\_RETRIEVAL\_STATUS\_SUCCESS: The URL retrieval was successful.
URL\_RETRIEVAL\_STATUS\_ERROR: The URL retrieval failed.
URL\_RETRIEVAL\_STATUS\_PAYWALL: The URL retrieval failed because the content is behind a paywall.
URL\_RETRIEVAL\_STATUS\_UNSAFE: The URL retrieval failed because the content is unsafe.
+ +Signature: + +```typescript +export type URLRetrievalStatus = (typeof URLRetrievalStatus)[keyof typeof URLRetrievalStatus]; +``` diff --git a/docs-devsite/ai.startaudioconversationoptions.md b/docs-devsite/ai.startaudioconversationoptions.md index 08e91d2c7b5..827cc0b129b 100644 --- a/docs-devsite/ai.startaudioconversationoptions.md +++ b/docs-devsite/ai.startaudioconversationoptions.md @@ -25,7 +25,7 @@ export interface StartAudioConversationOptions | Property | Type | Description | | --- | --- | --- | -| [functionCallingHandler](./ai.startaudioconversationoptions.md#startaudioconversationoptionsfunctioncallinghandler) | (functionCalls: [LiveServerToolCall](./ai.liveservertoolcall.md#liveservertoolcall_interface)\['functionCalls'\]) => Promise<[Part](./ai.md#part)> | (Public Preview) An async handler that is called when the model requests a function to be executed. The handler should perform the function call and return the result as a Part, which will then be sent back to the model. | +| [functionCallingHandler](./ai.startaudioconversationoptions.md#startaudioconversationoptionsfunctioncallinghandler) | (functionCalls: [FunctionCall](./ai.functioncall.md#functioncall_interface)\[\]) => Promise<[FunctionResponse](./ai.functionresponse.md#functionresponse_interface)> | (Public Preview) An async handler that is called when the model requests a function to be executed. The handler should perform the function call and return the result as a Part, which will then be sent back to the model. | ## StartAudioConversationOptions.functionCallingHandler @@ -37,5 +37,5 @@ An async handler that is called when the model requests a function to be execute Signature: ```typescript -functionCallingHandler?: (functionCalls: LiveServerToolCall['functionCalls']) => Promise; +functionCallingHandler?: (functionCalls: FunctionCall[]) => Promise; ``` diff --git a/docs-devsite/ai.urlcontext.md b/docs-devsite/ai.urlcontext.md new file mode 100644 index 00000000000..435d278e4d1 --- /dev/null +++ b/docs-devsite/ai.urlcontext.md @@ -0,0 +1,22 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# URLContext interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Specifies the URL Context configuration. + +Signature: + +```typescript +export interface URLContext +``` diff --git a/docs-devsite/ai.urlcontextmetadata.md b/docs-devsite/ai.urlcontextmetadata.md new file mode 100644 index 00000000000..bc260b997ad --- /dev/null +++ b/docs-devsite/ai.urlcontextmetadata.md @@ -0,0 +1,41 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# URLContextMetadata interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Metadata related to [URLContextTool](./ai.urlcontexttool.md#urlcontexttool_interface). + +Signature: + +```typescript +export interface URLContextMetadata +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [urlMetadata](./ai.urlcontextmetadata.md#urlcontextmetadataurlmetadata) | [URLMetadata](./ai.urlmetadata.md#urlmetadata_interface)\[\] | (Public Preview) List of URL metadata used to provide context to the Gemini model. | + +## URLContextMetadata.urlMetadata + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +List of URL metadata used to provide context to the Gemini model. + +Signature: + +```typescript +urlMetadata: URLMetadata[]; +``` diff --git a/docs-devsite/ai.urlcontexttool.md b/docs-devsite/ai.urlcontexttool.md new file mode 100644 index 00000000000..6ecc2a323c1 --- /dev/null +++ b/docs-devsite/ai.urlcontexttool.md @@ -0,0 +1,41 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# URLContextTool interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +A tool that allows you to provide additional context to the models in the form of public web URLs. By including URLs in your request, the Gemini model will access the content from those pages to inform and enhance its response. + +Signature: + +```typescript +export interface URLContextTool +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [urlContext](./ai.urlcontexttool.md#urlcontexttoolurlcontext) | [URLContext](./ai.urlcontext.md#urlcontext_interface) | (Public Preview) Specifies the URL Context configuration. | + +## URLContextTool.urlContext + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Specifies the URL Context configuration. + +Signature: + +```typescript +urlContext: URLContext; +``` diff --git a/docs-devsite/ai.urlmetadata.md b/docs-devsite/ai.urlmetadata.md new file mode 100644 index 00000000000..3cbd27632d0 --- /dev/null +++ b/docs-devsite/ai.urlmetadata.md @@ -0,0 +1,55 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# URLMetadata interface +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Metadata for a single URL retrieved by the [URLContextTool](./ai.urlcontexttool.md#urlcontexttool_interface) tool. + +Signature: + +```typescript +export interface URLMetadata +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [retrievedUrl](./ai.urlmetadata.md#urlmetadataretrievedurl) | string | (Public Preview) The retrieved URL. | +| [urlRetrievalStatus](./ai.urlmetadata.md#urlmetadataurlretrievalstatus) | [URLRetrievalStatus](./ai.md#urlretrievalstatus) | (Public Preview) The status of the URL retrieval. | + +## URLMetadata.retrievedUrl + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +The retrieved URL. + +Signature: + +```typescript +retrievedUrl?: string; +``` + +## URLMetadata.urlRetrievalStatus + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +The status of the URL retrieval. + +Signature: + +```typescript +urlRetrievalStatus?: URLRetrievalStatus; +``` diff --git a/docs-devsite/ai.usagemetadata.md b/docs-devsite/ai.usagemetadata.md index 954fcc6e530..bf45610f4a1 100644 --- a/docs-devsite/ai.usagemetadata.md +++ b/docs-devsite/ai.usagemetadata.md @@ -27,6 +27,8 @@ export interface UsageMetadata | [promptTokenCount](./ai.usagemetadata.md#usagemetadataprompttokencount) | number | | | [promptTokensDetails](./ai.usagemetadata.md#usagemetadataprompttokensdetails) | [ModalityTokenCount](./ai.modalitytokencount.md#modalitytokencount_interface)\[\] | | | [thoughtsTokenCount](./ai.usagemetadata.md#usagemetadatathoughtstokencount) | number | The number of tokens used by the model's internal "thinking" process. | +| [toolUsePromptTokenCount](./ai.usagemetadata.md#usagemetadatatooluseprompttokencount) | number | The number of tokens used by tools. | +| [toolUsePromptTokensDetails](./ai.usagemetadata.md#usagemetadatatooluseprompttokensdetails) | [ModalityTokenCount](./ai.modalitytokencount.md#modalitytokencount_interface)\[\] | A list of tokens used by tools, broken down by modality. | | [totalTokenCount](./ai.usagemetadata.md#usagemetadatatotaltokencount) | number | | ## UsageMetadata.candidatesTokenCount @@ -71,6 +73,26 @@ The number of tokens used by the model's internal "thinking" process. thoughtsTokenCount?: number; ``` +## UsageMetadata.toolUsePromptTokenCount + +The number of tokens used by tools. + +Signature: + +```typescript +toolUsePromptTokenCount?: number; +``` + +## UsageMetadata.toolUsePromptTokensDetails + +A list of tokens used by tools, broken down by modality. + +Signature: + +```typescript +toolUsePromptTokensDetails?: ModalityTokenCount[]; +``` + ## UsageMetadata.totalTokenCount Signature: diff --git a/e2e/smoke-tests/sample-apps/modular.js b/e2e/smoke-tests/sample-apps/modular.js index 2d66b752081..20ff0ce7bd2 100644 --- a/e2e/smoke-tests/sample-apps/modular.js +++ b/e2e/smoke-tests/sample-apps/modular.js @@ -313,7 +313,7 @@ function callPerformance(app) { async function callAI(app) { console.log('[AI] start'); const ai = getAI(app, { backend: new VertexAIBackend() }); - const model = getGenerativeModel(ai, { model: 'gemini-1.5-flash' }); + const model = getGenerativeModel(ai, { model: 'gemini-2.5-flash' }); const result = await model.countTokens('abcdefg'); console.log(`[AI] counted tokens: ${result.totalTokens}`); } diff --git a/e2e/smoke-tests/tests/modular.test.ts b/e2e/smoke-tests/tests/modular.test.ts index c8f6afe779d..536a271ca5e 100644 --- a/e2e/smoke-tests/tests/modular.test.ts +++ b/e2e/smoke-tests/tests/modular.test.ts @@ -314,8 +314,8 @@ describe('MODULAR', () => { ai = getAI(app, { backend: new VertexAIBackend() }); }); it('getGenerativeModel() and countTokens()', async () => { - const model = getGenerativeModel(ai, { model: 'gemini-1.5-flash' }); - expect(model.model).toMatch(/gemini-1.5-flash$/); + const model = getGenerativeModel(ai, { model: 'gemini-2.5-flash' }); + expect(model.model).toMatch(/gemini-2.5-flash$/); const result = await model.countTokens('abcdefg'); expect(result.totalTokens).toBeTruthy; }); diff --git a/integration/compat-interop/package.json b/integration/compat-interop/package.json index 43918524893..d578466418a 100644 --- a/integration/compat-interop/package.json +++ b/integration/compat-interop/package.json @@ -8,8 +8,8 @@ "test:debug": "karma start --browsers Chrome --auto-watch" }, "dependencies": { - "@firebase/app": "0.14.2", - "@firebase/app-compat": "0.5.2", + "@firebase/app": "0.14.3", + "@firebase/app-compat": "0.5.3", "@firebase/analytics": "0.10.18", "@firebase/analytics-compat": "0.2.24", "@firebase/auth": "1.11.0", @@ -20,8 +20,8 @@ "@firebase/messaging-compat": "0.2.23", "@firebase/performance": "0.7.9", "@firebase/performance-compat": "0.2.22", - "@firebase/remote-config": "0.6.6", - "@firebase/remote-config-compat": "0.2.19" + "@firebase/remote-config": "0.7.0", + "@firebase/remote-config-compat": "0.2.20" }, "devDependencies": { "typescript": "5.5.4" diff --git a/integration/firestore/package.json b/integration/firestore/package.json index 9b5b2411e6a..73fc72ec219 100644 --- a/integration/firestore/package.json +++ b/integration/firestore/package.json @@ -14,8 +14,8 @@ "test:memory:debug": "yarn build:memory; karma start --auto-watch --browsers Chrome" }, "dependencies": { - "@firebase/app": "0.14.2", - "@firebase/firestore": "4.9.1" + "@firebase/app": "0.14.3", + "@firebase/firestore": "4.9.2" }, "devDependencies": { "@types/mocha": "9.1.1", diff --git a/integration/messaging/package.json b/integration/messaging/package.json index 6a93c1bc284..704d2530a62 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -9,7 +9,7 @@ "test:manual": "mocha --exit" }, "devDependencies": { - "firebase": "12.2.1", + "firebase": "12.3.0", "chai": "4.5.0", "chromedriver": "119.0.1", "express": "4.21.2", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index f6aeba8f6f6..7679505f722 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,19 @@ # @firebase/ai +## 2.3.0 + +### Minor Changes + +- [`06ab5c4`](https://github.com/firebase/firebase-js-sdk/commit/06ab5c4f9b84085068381f6dff5e03b1b7cf4b2c) [#9236](https://github.com/firebase/firebase-js-sdk/pull/9236) - Added a new `InferenceMode` option for the hybrid on-device capability: `prefer_in_cloud`. When this mode is selected, the SDK will attempt to use a cloud-hosted model first. If the call to the cloud-hosted model fails with a network-related error, the SDK will fall back to the on-device model, if it's available. + +- [`9b8ab02`](https://github.com/firebase/firebase-js-sdk/commit/9b8ab02c543785226fafec056d39be7cf7ee03d1) [#9249](https://github.com/firebase/firebase-js-sdk/pull/9249) - Added Code Execution feature. + +### Patch Changes + +- [`a4848b4`](https://github.com/firebase/firebase-js-sdk/commit/a4848b401f6e8da16b0d0fdbfd064e8d68566555) [#9235](https://github.com/firebase/firebase-js-sdk/pull/9235) - Refactor component registration. + +- [`c123766`](https://github.com/firebase/firebase-js-sdk/commit/c1237662e6851936d2dd6017ab4bc7f0aa5112fd) [#9253](https://github.com/firebase/firebase-js-sdk/pull/9253) - Change documentation tags for hybrid inference from "EXPERIMENTAL" to "public preview". + ## 2.2.1 ### Patch Changes diff --git a/packages/ai/integration/generate-content.test.ts b/packages/ai/integration/generate-content.test.ts index a827a447d90..ffb1ecca698 100644 --- a/packages/ai/integration/generate-content.test.ts +++ b/packages/ai/integration/generate-content.test.ts @@ -17,6 +17,7 @@ import { expect } from 'chai'; import { + BackendType, Content, GenerationConfig, HarmBlockThreshold, @@ -25,11 +26,13 @@ import { Modality, Outcome, SafetySetting, + URLRetrievalStatus, getGenerativeModel } from '../src'; import { testConfigs, TOKEN_COUNT_DELTA } from './constants'; -describe('Generate Content', () => { +describe('Generate Content', function () { + this.timeout(20_000); testConfigs.forEach(testConfig => { describe(`${testConfig.toString()}`, () => { const commonGenerationConfig: GenerationConfig = { @@ -41,19 +44,19 @@ describe('Generate Content', () => { const commonSafetySettings: SafetySetting[] = [ { category: HarmCategory.HARM_CATEGORY_HARASSMENT, - threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE + threshold: HarmBlockThreshold.BLOCK_NONE }, { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, - threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE + threshold: HarmBlockThreshold.BLOCK_NONE }, { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, - threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE + threshold: HarmBlockThreshold.BLOCK_NONE }, { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, - threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE + threshold: HarmBlockThreshold.BLOCK_NONE } ]; @@ -190,6 +193,132 @@ describe('Generate Content', () => { }); }); + describe('URL Context', async () => { + // URL Context is not supported in Google AI for gemini-2.0-flash + if ( + testConfig.ai.backend.backendType === BackendType.GOOGLE_AI && + testConfig.model === 'gemini-2.0-flash' + ) { + return; + } + + it('generateContent: url context', async () => { + const model = getGenerativeModel(testConfig.ai, { + model: testConfig.model, + generationConfig: commonGenerationConfig, + safetySettings: commonSafetySettings, + tools: [{ urlContext: {} }] + }); + + const result = await model.generateContent( + 'Summarize this website https://berkshirehathaway.com' + ); + const response = result.response; + const urlContextMetadata = + response.candidates?.[0].urlContextMetadata; + expect(urlContextMetadata?.urlMetadata).to.exist; + expect( + urlContextMetadata?.urlMetadata.length + ).to.be.greaterThanOrEqual(1); + expect(urlContextMetadata?.urlMetadata[0].retrievedUrl).to.exist; + expect(urlContextMetadata?.urlMetadata[0].retrievedUrl).to.equal( + 'https://berkshirehathaway.com' + ); + expect( + urlContextMetadata?.urlMetadata[0].urlRetrievalStatus + ).to.equal(URLRetrievalStatus.URL_RETRIEVAL_STATUS_SUCCESS); + + const usageMetadata = response.usageMetadata; + expect(usageMetadata).to.exist; + expect(usageMetadata?.toolUsePromptTokenCount).to.exist; + expect(usageMetadata?.toolUsePromptTokenCount).to.be.greaterThan(0); + }); + + it('generateContent: url context and google search grounding', async () => { + const model = getGenerativeModel(testConfig.ai, { + model: testConfig.model, + generationConfig: commonGenerationConfig, + safetySettings: commonSafetySettings, + tools: [{ urlContext: {} }, { googleSearch: {} }] + }); + + const result = await model.generateContent( + 'According to https://info.cern.ch/hypertext/WWW/TheProject.html, what is the WorldWideWeb? Search the web for other definitions.' + ); + const response = result.response; + const trimmedText = response.text().trim(); + const urlContextMetadata = + response.candidates?.[0].urlContextMetadata; + const groundingMetadata = response.candidates?.[0].groundingMetadata; + expect(trimmedText).to.contain( + 'hypermedia information retrieval initiative' + ); + expect(urlContextMetadata?.urlMetadata).to.exist; + expect( + urlContextMetadata?.urlMetadata.length + ).to.be.greaterThanOrEqual(1); + expect(urlContextMetadata?.urlMetadata[0].retrievedUrl).to.exist; + expect(urlContextMetadata?.urlMetadata[0].retrievedUrl).to.equal( + 'https://info.cern.ch/hypertext/WWW/TheProject.html' + ); + expect( + urlContextMetadata?.urlMetadata[0].urlRetrievalStatus + ).to.equal(URLRetrievalStatus.URL_RETRIEVAL_STATUS_SUCCESS); + expect(groundingMetadata).to.exist; + expect(groundingMetadata?.groundingChunks).to.exist; + expect( + groundingMetadata?.groundingChunks!.length + ).to.be.greaterThanOrEqual(1); + expect( + groundingMetadata?.groundingSupports!.length + ).to.be.greaterThanOrEqual(1); + + const usageMetadata = response.usageMetadata; + expect(usageMetadata).to.exist; + expect(usageMetadata?.toolUsePromptTokenCount).to.exist; + expect(usageMetadata?.toolUsePromptTokenCount).to.be.greaterThan(0); + }); + + it('generateContent: url context and google search grounding without URLs in prompt', async () => { + const model = getGenerativeModel(testConfig.ai, { + model: testConfig.model, + generationConfig: commonGenerationConfig, + safetySettings: commonSafetySettings, + tools: [{ urlContext: {} }, { googleSearch: {} }] + }); + + const result = await model.generateContent( + 'Recommend 3 books for beginners to read to learn more about the latest advancements in Quantum Computing.' + ); + const response = result.response; + const urlContextMetadata = + response.candidates?.[0].urlContextMetadata; + const groundingMetadata = response.candidates?.[0].groundingMetadata; + if (testConfig.ai.backend.backendType === BackendType.GOOGLE_AI) { + expect(urlContextMetadata?.urlMetadata).to.exist; + expect( + urlContextMetadata?.urlMetadata.length + ).to.be.greaterThanOrEqual(1); + expect(urlContextMetadata?.urlMetadata[0].retrievedUrl).to.exist; + expect( + urlContextMetadata?.urlMetadata[0].urlRetrievalStatus + ).to.equal(URLRetrievalStatus.URL_RETRIEVAL_STATUS_SUCCESS); + expect(groundingMetadata).to.exist; + expect(groundingMetadata?.groundingChunks).to.exist; + + const usageMetadata = response.usageMetadata; + expect(usageMetadata).to.exist; + expect(usageMetadata?.toolUsePromptTokenCount).to.exist; + expect(usageMetadata?.toolUsePromptTokenCount).to.be.greaterThan(0); + } else { + // URL Context does not integrate with Google Search Grounding in Vertex AI + expect(urlContextMetadata?.urlMetadata).to.not.exist; + expect(groundingMetadata).to.exist; + expect(groundingMetadata?.groundingChunks).to.exist; + } + }); + }); + it('generateContent: code execution', async () => { const model = getGenerativeModel(testConfig.ai, { model: testConfig.model, diff --git a/packages/ai/package.json b/packages/ai/package.json index 5b219d1bf94..b36081aa8f0 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/ai", - "version": "2.2.1", + "version": "2.3.0", "description": "The Firebase AI SDK", "author": "Firebase (https://firebase.google.com/)", "engines": { @@ -60,7 +60,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "@rollup/plugin-json": "6.1.0", "rollup": "2.79.2", "rollup-plugin-replace": "2.2.0", diff --git a/packages/ai/src/googleai-mappers.ts b/packages/ai/src/googleai-mappers.ts index 23c238c1e3b..c6656c8318d 100644 --- a/packages/ai/src/googleai-mappers.ts +++ b/packages/ai/src/googleai-mappers.ts @@ -176,7 +176,7 @@ export function mapGenerateContentCandidates( // Throw early since developers may send a long video as input and only expect to pay // for inference on a small portion of the video. if ( - candidate.content?.parts.some( + candidate.content?.parts?.some( part => (part as InlineDataPart)?.videoMetadata ) ) { @@ -193,7 +193,8 @@ export function mapGenerateContentCandidates( finishMessage: candidate.finishMessage, safetyRatings: mappedSafetyRatings, citationMetadata, - groundingMetadata: candidate.groundingMetadata + groundingMetadata: candidate.groundingMetadata, + urlContextMetadata: candidate.urlContextMetadata }; mappedCandidates.push(mappedCandidate); }); diff --git a/packages/ai/src/methods/generate-content.test.ts b/packages/ai/src/methods/generate-content.test.ts index 3bb396ac6d8..40dc7c7b36e 100644 --- a/packages/ai/src/methods/generate-content.test.ts +++ b/packages/ai/src/methods/generate-content.test.ts @@ -249,6 +249,57 @@ describe('generateContent()', () => { false, match.any ); + + it('url context', async () => { + const mockResponse = getMockResponse( + 'vertexAI', + 'unary-success-url-context.json' + ); + const makeRequestStub = stub(request, 'makeRequest').resolves( + mockResponse as Response + ); + const result = await generateContent( + fakeApiSettings, + 'model', + fakeRequestParams + ); + expect(result.response.text()).to.include( + 'The temperature is 67°F (19°C)' + ); + const groundingMetadata = + result.response.candidates?.[0].groundingMetadata; + expect(groundingMetadata).to.not.be.undefined; + expect(groundingMetadata!.searchEntryPoint?.renderedContent).to.contain( + 'div' + ); + expect(groundingMetadata!.groundingChunks?.length).to.equal(2); + expect(groundingMetadata!.groundingChunks?.[0].web?.uri).to.contain( + 'https://vertexaisearch.cloud.google.com' + ); + expect(groundingMetadata!.groundingChunks?.[0].web?.title).to.equal( + 'accuweather.com' + ); + expect(groundingMetadata!.groundingSupports?.length).to.equal(3); + expect( + groundingMetadata!.groundingSupports?.[0].groundingChunkIndices + ).to.deep.equal([0]); + expect(groundingMetadata!.groundingSupports?.[0].segment).to.deep.equal({ + endIndex: 56, + text: 'The current weather in London, United Kingdom is cloudy.' + }); + expect(groundingMetadata!.groundingSupports?.[0].segment?.partIndex).to.be + .undefined; + expect(groundingMetadata!.groundingSupports?.[0].segment?.startIndex).to + .be.undefined; + + expect(makeRequestStub).to.be.calledWith( + 'model', + Task.GENERATE_CONTENT, + fakeApiSettings, + false, + match.any + ); + }); }); it('codeExecution', async () => { const mockResponse = getMockResponse( @@ -335,6 +386,22 @@ describe('generateContent()', () => { match.any ); }); + it('empty part', async () => { + const mockResponse = getMockResponse( + 'vertexAI', + 'unary-success-empty-part.json' + ); + stub(request, 'makeRequest').resolves(mockResponse as Response); + const result = await generateContent( + fakeApiSettings, + 'model', + fakeRequestParams + ); + expect(result.response.text()).to.include( + 'I can certainly help you with that!' + ); + expect(result.response.inlineDataParts()?.length).to.equal(1); + }); it('unknown enum - should ignore', async () => { const mockResponse = getMockResponse( 'vertexAI', diff --git a/packages/ai/src/methods/live-session-helpers.test.ts b/packages/ai/src/methods/live-session-helpers.test.ts index d7d1e2aabbf..cad0475b358 100644 --- a/packages/ai/src/methods/live-session-helpers.test.ts +++ b/packages/ai/src/methods/live-session-helpers.test.ts @@ -21,7 +21,11 @@ import sinonChai from 'sinon-chai'; import chaiAsPromised from 'chai-as-promised'; import { AIError } from '../errors'; import { startAudioConversation } from './live-session-helpers'; -import { LiveServerContent, LiveServerToolCall, Part } from '../types'; +import { + FunctionResponse, + LiveServerContent, + LiveServerToolCall +} from '../types'; import { logger } from '../logger'; import { isNode } from '@firebase/util'; @@ -62,6 +66,7 @@ class MockLiveSession { inConversation = false; send = sinon.stub(); sendMediaChunks = sinon.stub(); + sendFunctionResponses = sinon.stub(); messageGenerator = new MockMessageGenerator(); receive = (): MockMessageGenerator => this.messageGenerator; } @@ -249,16 +254,21 @@ describe('Audio Conversation Helpers', () => { }); it('should call function handler and send result on toolCall message.', async () => { - const handlerStub = sinon.stub().resolves({ - functionResponse: { name: 'get_weather', response: { temp: '72F' } } - } as Part); + const functionResponse: FunctionResponse = { + id: '1', + name: 'get_weather', + response: { temp: '72F' } + }; + const handlerStub = sinon.stub().resolves(functionResponse); const controller = await startAudioConversation(liveSession as any, { functionCallingHandler: handlerStub }); const toolCallMessage: LiveServerToolCall = { type: 'toolCall', - functionCalls: [{ name: 'get_weather', args: { location: 'LA' } }] + functionCalls: [ + { id: '1', name: 'get_weather', args: { location: 'LA' } } + ] }; liveSession.messageGenerator.simulateMessage(toolCallMessage); @@ -267,8 +277,8 @@ describe('Audio Conversation Helpers', () => { expect(handlerStub).to.have.been.calledOnceWith( toolCallMessage.functionCalls ); - expect(liveSession.send).to.have.been.calledOnceWith([ - { functionResponse: { name: 'get_weather', response: { temp: '72F' } } } + expect(liveSession.sendFunctionResponses).to.have.been.calledOnceWith([ + functionResponse ]); await controller.stop(); }); diff --git a/packages/ai/src/methods/live-session-helpers.ts b/packages/ai/src/methods/live-session-helpers.ts index e52715de36e..b3907d6219b 100644 --- a/packages/ai/src/methods/live-session-helpers.ts +++ b/packages/ai/src/methods/live-session-helpers.ts @@ -19,10 +19,10 @@ import { AIError } from '../errors'; import { logger } from '../logger'; import { AIErrorCode, + FunctionCall, + FunctionResponse, GenerativeContentBlob, - LiveServerContent, - LiveServerToolCall, - Part + LiveServerContent } from '../types'; import { LiveSession } from './live-session'; import { Deferred } from '@firebase/util'; @@ -115,8 +115,8 @@ export interface StartAudioConversationOptions { * which will then be sent back to the model. */ functionCallingHandler?: ( - functionCalls: LiveServerToolCall['functionCalls'] - ) => Promise; + functionCalls: FunctionCall[] + ) => Promise; } /** @@ -338,11 +338,11 @@ export class AudioConversationRunner { ); } else { try { - const resultPart = await this.options.functionCallingHandler( + const functionResponse = await this.options.functionCallingHandler( message.functionCalls ); if (!this.isStopped) { - void this.liveSession.send([resultPart]); + void this.liveSession.sendFunctionResponses([functionResponse]); } } catch (e) { throw new AIError( diff --git a/packages/ai/src/methods/live-session.test.ts b/packages/ai/src/methods/live-session.test.ts index 7db9daaebe6..7454b1208c9 100644 --- a/packages/ai/src/methods/live-session.test.ts +++ b/packages/ai/src/methods/live-session.test.ts @@ -20,6 +20,7 @@ import { spy, stub } from 'sinon'; import sinonChai from 'sinon-chai'; import chaiAsPromised from 'chai-as-promised'; import { + FunctionResponse, LiveResponseType, LiveServerContent, LiveServerToolCall, @@ -153,6 +154,35 @@ describe('LiveSession', () => { }); }); + describe('sendFunctionResponses()', () => { + it('should send all function responses', async () => { + const functionResponses: FunctionResponse[] = [ + { + id: 'function-call-1', + name: 'function-name', + response: { + result: 'foo' + } + }, + { + id: 'function-call-2', + name: 'function-name-2', + response: { + result: 'bar' + } + } + ]; + await session.sendFunctionResponses(functionResponses); + expect(mockHandler.send).to.have.been.calledOnce; + const sentData = JSON.parse(mockHandler.send.getCall(0).args[0]); + expect(sentData).to.deep.equal({ + toolResponse: { + functionResponses + } + }); + }); + }); + describe('receive()', () => { it('should correctly parse and transform all server message types', async () => { const receivePromise = (async () => { diff --git a/packages/ai/src/methods/live-session.ts b/packages/ai/src/methods/live-session.ts index 11e5346adc0..92d325e2f0d 100644 --- a/packages/ai/src/methods/live-session.ts +++ b/packages/ai/src/methods/live-session.ts @@ -17,6 +17,7 @@ import { AIErrorCode, + FunctionResponse, GenerativeContentBlob, LiveResponseType, LiveServerContent, @@ -30,7 +31,8 @@ import { WebSocketHandler } from '../websocket'; import { logger } from '../logger'; import { _LiveClientContent, - _LiveClientRealtimeInput + _LiveClientRealtimeInput, + _LiveClientToolResponse } from '../types/live-responses'; /** @@ -119,6 +121,32 @@ export class LiveSession { }); } + /** + * Sends function responses to the server. + * + * @param functionResponses - The function responses to send. + * @throws If this session has been closed. + * + * @beta + */ + async sendFunctionResponses( + functionResponses: FunctionResponse[] + ): Promise { + if (this.isClosed) { + throw new AIError( + AIErrorCode.REQUEST_ERROR, + 'This LiveSession has been closed and cannot be used.' + ); + } + + const message: _LiveClientToolResponse = { + toolResponse: { + functionResponses + } + }; + this.webSocketHandler.send(JSON.stringify(message)); + } + /** * Sends a stream of {@link GenerativeContentBlob}. * diff --git a/packages/ai/src/requests/stream-reader.test.ts b/packages/ai/src/requests/stream-reader.test.ts index f0298082f68..2e50bbb3d3e 100644 --- a/packages/ai/src/requests/stream-reader.test.ts +++ b/packages/ai/src/requests/stream-reader.test.ts @@ -194,6 +194,20 @@ describe('processStream', () => { expect(response.text()).to.equal(''); } }); + it('handles empty parts', async () => { + const fakeResponse = getMockResponseStreaming( + 'googleAI', + 'streaming-success-empty-parts.txt' + ); + + const result = processStream(fakeResponse as Response, fakeApiSettings); + for await (const response of result.stream) { + expect(response.candidates?.[0].content.parts.length).to.be.at.least(1); + } + + const aggregatedResponse = await result.response; + expect(aggregatedResponse.candidates?.[0].content.parts.length).to.equal(6); + }); it('unknown enum - should ignore', async () => { const fakeResponse = getMockResponseStreaming( 'vertexAI', diff --git a/packages/ai/src/requests/stream-reader.ts b/packages/ai/src/requests/stream-reader.ts index c3a35b1da4a..042c052fa82 100644 --- a/packages/ai/src/requests/stream-reader.ts +++ b/packages/ai/src/requests/stream-reader.ts @@ -28,7 +28,7 @@ import { createEnhancedContentResponse } from './response-helpers'; import * as GoogleAIMapper from '../googleai-mappers'; import { GoogleAIGenerateContentResponse } from '../types/googleai'; import { ApiSettings } from '../types/internal'; -import { BackendType } from '../public-types'; +import { BackendType, URLContextMetadata } from '../public-types'; const responseLineRE = /^data\: (.*)(?:\n\n|\r\r|\r\n\r\n)/; @@ -100,6 +100,17 @@ async function* generateResponseSequence( enhancedResponse = createEnhancedContentResponse(value); } + const firstCandidate = enhancedResponse.candidates?.[0]; + // Don't yield a response with no useful data for the developer. + if ( + !firstCandidate?.content?.parts && + !firstCandidate?.finishReason && + !firstCandidate?.citationMetadata && + !firstCandidate?.urlContextMetadata + ) { + continue; + } + yield enhancedResponse; } } @@ -193,41 +204,48 @@ export function aggregateResponses( aggregatedResponse.candidates[i].groundingMetadata = candidate.groundingMetadata; + // The urlContextMetadata object is defined in the first chunk of the response stream. + // In all subsequent chunks, the urlContextMetadata object will be undefined. We need to + // make sure that we don't overwrite the first value urlContextMetadata object with undefined. + // FIXME: What happens if we receive a second, valid urlContextMetadata object? + const urlContextMetadata = candidate.urlContextMetadata as unknown; + if ( + typeof urlContextMetadata === 'object' && + urlContextMetadata !== null && + Object.keys(urlContextMetadata).length > 0 + ) { + aggregatedResponse.candidates[i].urlContextMetadata = + urlContextMetadata as URLContextMetadata; + } + /** * Candidates should always have content and parts, but this handles * possible malformed responses. */ - if (candidate.content && candidate.content.parts) { + if (candidate.content) { + // Skip a candidate without parts. + if (!candidate.content.parts) { + continue; + } if (!aggregatedResponse.candidates[i].content) { aggregatedResponse.candidates[i].content = { role: candidate.content.role || 'user', parts: [] }; } - const newPart: Partial = {}; for (const part of candidate.content.parts) { - if (part.text !== undefined) { - // The backend can send empty text parts. If these are sent back - // (e.g. in chat history), the backend will respond with an error. - // To prevent this, ignore empty text parts. - if (part.text === '') { - continue; - } - newPart.text = part.text; - } - if (part.functionCall) { - newPart.functionCall = part.functionCall; + const newPart: Part = { ...part }; + // The backend can send empty text parts. If these are sent back + // (e.g. in chat history), the backend will respond with an error. + // To prevent this, ignore empty text parts. + if (part.text === '') { + continue; } - if (Object.keys(newPart).length === 0) { - throw new AIError( - AIErrorCode.INVALID_CONTENT, - 'Part should have at least one property, but there are none. This is likely caused ' + - 'by a malformed response from the backend.' + if (Object.keys(newPart).length > 0) { + aggregatedResponse.candidates[i].content.parts.push( + newPart as Part ); } - aggregatedResponse.candidates[i].content.parts.push( - newPart as Part - ); } } } diff --git a/packages/ai/src/types/content.ts b/packages/ai/src/types/content.ts index b51dcd9c69f..401a8cfb1a8 100644 --- a/packages/ai/src/types/content.ts +++ b/packages/ai/src/types/content.ts @@ -155,7 +155,7 @@ export interface FileDataPart { /** * Represents the code that is executed by the model. * - * @public + * @beta */ export interface ExecutableCodePart { text?: never; @@ -175,7 +175,7 @@ export interface ExecutableCodePart { /** * Represents the code execution result from the model. * - * @public + * @beta */ export interface CodeExecutionResultPart { text?: never; @@ -195,7 +195,7 @@ export interface CodeExecutionResultPart { /** * An interface for executable code returned by the model. * - * @public + * @beta */ export interface ExecutableCode { /** @@ -211,7 +211,7 @@ export interface ExecutableCode { /** * The results of code execution run by the model. * - * @public + * @beta */ export interface CodeExecutionResult { /** diff --git a/packages/ai/src/types/enums.ts b/packages/ai/src/types/enums.ts index 997df1265b0..cd7029df3b0 100644 --- a/packages/ai/src/types/enums.ts +++ b/packages/ai/src/types/enums.ts @@ -382,7 +382,7 @@ export type InferenceMode = (typeof InferenceMode)[keyof typeof InferenceMode]; /** * Represents the result of the code execution. * - * @public + * @beta */ export const Outcome = { UNSPECIFIED: 'OUTCOME_UNSPECIFIED', @@ -394,14 +394,14 @@ export const Outcome = { /** * Represents the result of the code execution. * - * @public + * @beta */ export type Outcome = (typeof Outcome)[keyof typeof Outcome]; /** * The programming language of the code. * - * @public + * @beta */ export const Language = { UNSPECIFIED: 'LANGUAGE_UNSPECIFIED', @@ -411,6 +411,6 @@ export const Language = { /** * The programming language of the code. * - * @public + * @beta */ export type Language = (typeof Language)[keyof typeof Language]; diff --git a/packages/ai/src/types/googleai.ts b/packages/ai/src/types/googleai.ts index 38c27b3fe8b..eb282b094fc 100644 --- a/packages/ai/src/types/googleai.ts +++ b/packages/ai/src/types/googleai.ts @@ -23,7 +23,8 @@ import { GroundingMetadata, PromptFeedback, SafetyRating, - UsageMetadata + UsageMetadata, + URLContextMetadata } from '../public-types'; import { Content, Part } from './content'; @@ -60,6 +61,7 @@ export interface GoogleAIGenerateContentCandidate { safetyRatings?: SafetyRating[]; citationMetadata?: GoogleAICitationMetadata; groundingMetadata?: GroundingMetadata; + urlContextMetadata?: URLContextMetadata; } /** diff --git a/packages/ai/src/types/live-responses.ts b/packages/ai/src/types/live-responses.ts index 66170f1a5ab..d1870fa109f 100644 --- a/packages/ai/src/types/live-responses.ts +++ b/packages/ai/src/types/live-responses.ts @@ -15,7 +15,12 @@ * limitations under the License. */ -import { Content, GenerativeContentBlob, Part } from './content'; +import { + Content, + FunctionResponse, + GenerativeContentBlob, + Part +} from './content'; import { LiveGenerationConfig, Tool, ToolConfig } from './requests'; /** @@ -42,6 +47,17 @@ export interface _LiveClientRealtimeInput { mediaChunks: GenerativeContentBlob[]; }; } + +/** + * Function responses that are sent to the model in real time. + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export interface _LiveClientToolResponse { + toolResponse: { + functionResponses: FunctionResponse[]; + }; +} + /** * The first message in a Live session, used to configure generation options. * diff --git a/packages/ai/src/types/requests.ts b/packages/ai/src/types/requests.ts index eea03e55fe4..1e5fa367420 100644 --- a/packages/ai/src/types/requests.ts +++ b/packages/ai/src/types/requests.ts @@ -242,7 +242,8 @@ export interface RequestOptions { export type Tool = | FunctionDeclarationsTool | GoogleSearchTool - | CodeExecutionTool; + | CodeExecutionTool + | URLContextTool; /** * Structured representation of a function declaration as defined by the @@ -300,7 +301,7 @@ export interface GoogleSearchTool { /** * A tool that enables the model to use code execution. * - * @public + * @beta */ export interface CodeExecutionTool { /** @@ -319,6 +320,27 @@ export interface CodeExecutionTool { */ export interface GoogleSearch {} +/** + * A tool that allows you to provide additional context to the models in the form of public web + * URLs. By including URLs in your request, the Gemini model will access the content from those + * pages to inform and enhance its response. + * + * @beta + */ +export interface URLContextTool { + /** + * Specifies the URL Context configuration. + */ + urlContext: URLContext; +} + +/** + * Specifies the URL Context configuration. + * + * @beta + */ +export interface URLContext {} + /** * A `FunctionDeclarationsTool` is a piece of code that enables the system to * interact with external systems to perform an action, or set of actions, diff --git a/packages/ai/src/types/responses.ts b/packages/ai/src/types/responses.ts index 4a01e79a77c..8b8e1351675 100644 --- a/packages/ai/src/types/responses.ts +++ b/packages/ai/src/types/responses.ts @@ -116,8 +116,16 @@ export interface UsageMetadata { */ thoughtsTokenCount?: number; totalTokenCount: number; + /** + * The number of tokens used by tools. + */ + toolUsePromptTokenCount?: number; promptTokensDetails?: ModalityTokenCount[]; candidatesTokensDetails?: ModalityTokenCount[]; + /** + * A list of tokens used by tools, broken down by modality. + */ + toolUsePromptTokensDetails?: ModalityTokenCount[]; } /** @@ -160,6 +168,7 @@ export interface GenerateContentCandidate { safetyRatings?: SafetyRating[]; citationMetadata?: CitationMetadata; groundingMetadata?: GroundingMetadata; + urlContextMetadata?: URLContextMetadata; } /** @@ -349,6 +358,94 @@ export interface Segment { text: string; } +/** + * Metadata related to {@link URLContextTool}. + * + * @beta + */ +export interface URLContextMetadata { + /** + * List of URL metadata used to provide context to the Gemini model. + */ + urlMetadata: URLMetadata[]; +} + +/** + * Metadata for a single URL retrieved by the {@link URLContextTool} tool. + * + * @beta + */ +export interface URLMetadata { + /** + * The retrieved URL. + */ + retrievedUrl?: string; + /** + * The status of the URL retrieval. + */ + urlRetrievalStatus?: URLRetrievalStatus; +} + +/** + * The status of a URL retrieval. + * + * @remarks + * URL_RETRIEVAL_STATUS_UNSPECIFIED: Unspecified retrieval status. + *
+ * URL_RETRIEVAL_STATUS_SUCCESS: The URL retrieval was successful. + *
+ * URL_RETRIEVAL_STATUS_ERROR: The URL retrieval failed. + *
+ * URL_RETRIEVAL_STATUS_PAYWALL: The URL retrieval failed because the content is behind a paywall. + *
+ * URL_RETRIEVAL_STATUS_UNSAFE: The URL retrieval failed because the content is unsafe. + *
+ * + * @beta + */ +export const URLRetrievalStatus = { + /** + * Unspecified retrieval status. + */ + URL_RETRIEVAL_STATUS_UNSPECIFIED: 'URL_RETRIEVAL_STATUS_UNSPECIFIED', + /** + * The URL retrieval was successful. + */ + URL_RETRIEVAL_STATUS_SUCCESS: 'URL_RETRIEVAL_STATUS_SUCCESS', + /** + * The URL retrieval failed. + */ + URL_RETRIEVAL_STATUS_ERROR: 'URL_RETRIEVAL_STATUS_ERROR', + /** + * The URL retrieval failed because the content is behind a paywall. + */ + URL_RETRIEVAL_STATUS_PAYWALL: 'URL_RETRIEVAL_STATUS_PAYWALL', + /** + * The URL retrieval failed because the content is unsafe. + */ + URL_RETRIEVAL_STATUS_UNSAFE: 'URL_RETRIEVAL_STATUS_UNSAFE' +}; + +/** + * The status of a URL retrieval. + * + * @remarks + * URL_RETRIEVAL_STATUS_UNSPECIFIED: Unspecified retrieval status. + *
+ * URL_RETRIEVAL_STATUS_SUCCESS: The URL retrieval was successful. + *
+ * URL_RETRIEVAL_STATUS_ERROR: The URL retrieval failed. + *
+ * URL_RETRIEVAL_STATUS_PAYWALL: The URL retrieval failed because the content is behind a paywall. + *
+ * URL_RETRIEVAL_STATUS_UNSAFE: The URL retrieval failed because the content is unsafe. + *
+ * + * @beta + */ +export type URLRetrievalStatus = + (typeof URLRetrievalStatus)[keyof typeof URLRetrievalStatus]; + /** * @public */ diff --git a/packages/analytics-compat/package.json b/packages/analytics-compat/package.json index ce4241b8080..c978d3653cf 100644 --- a/packages/analytics-compat/package.json +++ b/packages/analytics-compat/package.json @@ -22,7 +22,7 @@ "@firebase/app-compat": "0.x" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "rollup": "2.79.2", "@rollup/plugin-json": "6.1.0", "rollup-plugin-typescript2": "0.36.0", diff --git a/packages/analytics-interop-types/index.d.ts b/packages/analytics-interop-types/index.d.ts index b3e2fb0fe07..6cb6936147b 100644 --- a/packages/analytics-interop-types/index.d.ts +++ b/packages/analytics-interop-types/index.d.ts @@ -29,6 +29,10 @@ export interface FirebaseAnalyticsInternal { eventParams?: { [key: string]: unknown }, options?: AnalyticsCallOptions ): void; + setUserProperties: ( + properties: { [key: string]: unknown }, + options?: AnalyticsCallOptions + ) => void; } export interface AnalyticsCallOptions { diff --git a/packages/analytics/package.json b/packages/analytics/package.json index f4e35751e58..c8d359102f0 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -47,7 +47,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "rollup-plugin-dts": "5.3.1", "@rollup/plugin-commonjs": "21.1.0", diff --git a/packages/analytics/src/index.ts b/packages/analytics/src/index.ts index 7fa2e8fa10b..6017aed21b0 100644 --- a/packages/analytics/src/index.ts +++ b/packages/analytics/src/index.ts @@ -33,9 +33,9 @@ import { InstanceFactoryOptions } from '@firebase/component'; import { ERROR_FACTORY, AnalyticsError } from './errors'; -import { logEvent } from './api'; +import { logEvent, setUserProperties } from './api'; import { name, version } from '../package.json'; -import { AnalyticsCallOptions } from './public-types'; +import { AnalyticsCallOptions, CustomParams } from './public-types'; import '@firebase/installations'; declare global { @@ -79,7 +79,11 @@ function registerAnalytics(): void { eventName: string, eventParams?: { [key: string]: unknown }, options?: AnalyticsCallOptions - ) => logEvent(analytics, eventName, eventParams, options) + ) => logEvent(analytics, eventName, eventParams, options), + setUserProperties: ( + properties: CustomParams, + options?: AnalyticsCallOptions + ) => setUserProperties(analytics, properties, options) }; } catch (e) { throw ERROR_FACTORY.create(AnalyticsError.INTEROP_COMPONENT_REG_FAILED, { diff --git a/packages/app-check-compat/package.json b/packages/app-check-compat/package.json index fd07d8ffebc..d2b13f78d39 100644 --- a/packages/app-check-compat/package.json +++ b/packages/app-check-compat/package.json @@ -43,7 +43,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "rollup": "2.79.2", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "6.1.0", diff --git a/packages/app-check/package.json b/packages/app-check/package.json index 2bfeb8d01cb..a0e03d895cd 100644 --- a/packages/app-check/package.json +++ b/packages/app-check/package.json @@ -44,7 +44,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "6.1.0", diff --git a/packages/app-compat/CHANGELOG.md b/packages/app-compat/CHANGELOG.md index d9251a873c2..adcd3b62a59 100644 --- a/packages/app-compat/CHANGELOG.md +++ b/packages/app-compat/CHANGELOG.md @@ -1,5 +1,12 @@ # @firebase/app-compat +## 0.5.3 + +### Patch Changes + +- Updated dependencies []: + - @firebase/app@0.14.3 + ## 0.5.2 ### Patch Changes diff --git a/packages/app-compat/package.json b/packages/app-compat/package.json index 505a04a3536..a27c1627811 100644 --- a/packages/app-compat/package.json +++ b/packages/app-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app-compat", - "version": "0.5.2", + "version": "0.5.3", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.cjs.js", @@ -37,7 +37,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "@firebase/util": "1.13.0", "@firebase/logger": "0.5.0", "@firebase/component": "0.7.0", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 57891db7332..5e283b1bef0 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,11 @@ # @firebase/app +## 0.14.3 + +### Patch Changes + +- Update SDK_VERSION. + ## 0.14.2 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 8228e2d4477..9d9d9d3d89e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app", - "version": "0.14.2", + "version": "0.14.3", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.cjs.js", diff --git a/packages/auth-compat/package.json b/packages/auth-compat/package.json index fbb2e443b64..83f02a17be4 100644 --- a/packages/auth-compat/package.json +++ b/packages/auth-compat/package.json @@ -57,7 +57,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "@rollup/plugin-json": "6.1.0", "rollup": "2.79.2", "rollup-plugin-replace": "2.2.0", diff --git a/packages/auth/package.json b/packages/auth/package.json index 2fe122d762c..9a49314e2c1 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -131,7 +131,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "@rollup/plugin-json": "6.1.0", "@rollup/plugin-strip": "2.1.0", "@types/express": "4.17.21", diff --git a/packages/data-connect/package.json b/packages/data-connect/package.json index 44493b03eb2..29459b94f4e 100644 --- a/packages/data-connect/package.json +++ b/packages/data-connect/package.json @@ -55,7 +55,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "rollup-plugin-typescript2": "0.36.0", "typescript": "5.5.4" diff --git a/packages/database-compat/package.json b/packages/database-compat/package.json index d9cce7ef390..3c4460524be 100644 --- a/packages/database-compat/package.json +++ b/packages/database-compat/package.json @@ -57,7 +57,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "typescript": "5.5.4" }, "repository": { diff --git a/packages/database/package.json b/packages/database/package.json index 54bac8ce5fc..305c42aac23 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -57,7 +57,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "rollup-plugin-typescript2": "0.36.0", "typescript": "5.5.4" diff --git a/packages/firebase/CHANGELOG.md b/packages/firebase/CHANGELOG.md index 29f2617cb46..c21448da4f8 100644 --- a/packages/firebase/CHANGELOG.md +++ b/packages/firebase/CHANGELOG.md @@ -1,5 +1,26 @@ # firebase +## 12.3.0 + +### Minor Changes + +- [`06ab5c4`](https://github.com/firebase/firebase-js-sdk/commit/06ab5c4f9b84085068381f6dff5e03b1b7cf4b2c) [#9236](https://github.com/firebase/firebase-js-sdk/pull/9236) - Added a new `InferenceMode` option for the hybrid on-device capability: `prefer_in_cloud`. When this mode is selected, the SDK will attempt to use a cloud-hosted model first. If the call to the cloud-hosted model fails with a network-related error, the SDK will fall back to the on-device model, if it's available. + +- [`120a308`](https://github.com/firebase/firebase-js-sdk/commit/120a30838da50f5ade4f634e97c34cbfcaff41ba) [#9221](https://github.com/firebase/firebase-js-sdk/pull/9221) - Added support for Realtime Remote Config for the web. This feature introduces a new `onConfigUpdate` API and allows web applications to receive near-instant configuration updates without requiring periodic polling. + +- [`9b8ab02`](https://github.com/firebase/firebase-js-sdk/commit/9b8ab02c543785226fafec056d39be7cf7ee03d1) [#9249](https://github.com/firebase/firebase-js-sdk/pull/9249) - Added Code Execution feature. + +### Patch Changes + +- Updated dependencies [[`06ab5c4`](https://github.com/firebase/firebase-js-sdk/commit/06ab5c4f9b84085068381f6dff5e03b1b7cf4b2c), [`a4848b4`](https://github.com/firebase/firebase-js-sdk/commit/a4848b401f6e8da16b0d0fdbfd064e8d68566555), [`120a308`](https://github.com/firebase/firebase-js-sdk/commit/120a30838da50f5ade4f634e97c34cbfcaff41ba), [`9b8ab02`](https://github.com/firebase/firebase-js-sdk/commit/9b8ab02c543785226fafec056d39be7cf7ee03d1), [`c123766`](https://github.com/firebase/firebase-js-sdk/commit/c1237662e6851936d2dd6017ab4bc7f0aa5112fd), [`43276b0`](https://github.com/firebase/firebase-js-sdk/commit/43276b0414ea5a73e8d8f7e3b80275d8b910102f)]: + - @firebase/app@0.14.3 + - @firebase/ai@2.3.0 + - @firebase/remote-config@0.7.0 + - @firebase/firestore@4.9.2 + - @firebase/app-compat@0.5.3 + - @firebase/remote-config-compat@0.2.20 + - @firebase/firestore-compat@0.4.2 + ## 12.2.1 ### Patch Changes diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 1244a026910..2bf6821139a 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "firebase", - "version": "12.2.1", + "version": "12.3.0", "description": "Firebase JavaScript library for web and Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -411,17 +411,17 @@ "trusted-type-check": "tsec -p tsconfig.json --noEmit" }, "dependencies": { - "@firebase/ai": "2.2.1", - "@firebase/app": "0.14.2", - "@firebase/app-compat": "0.5.2", + "@firebase/ai": "2.3.0", + "@firebase/app": "0.14.3", + "@firebase/app-compat": "0.5.3", "@firebase/app-types": "0.9.3", "@firebase/auth": "1.11.0", "@firebase/auth-compat": "0.6.0", "@firebase/data-connect": "0.3.11", "@firebase/database": "1.1.0", "@firebase/database-compat": "2.1.0", - "@firebase/firestore": "4.9.1", - "@firebase/firestore-compat": "0.4.1", + "@firebase/firestore": "4.9.2", + "@firebase/firestore-compat": "0.4.2", "@firebase/functions": "0.13.1", "@firebase/functions-compat": "0.4.1", "@firebase/installations": "0.6.19", @@ -433,8 +433,8 @@ "@firebase/telemetry": "0.0.1", "@firebase/performance": "0.7.9", "@firebase/performance-compat": "0.2.22", - "@firebase/remote-config": "0.6.6", - "@firebase/remote-config-compat": "0.2.19", + "@firebase/remote-config": "0.7.0", + "@firebase/remote-config-compat": "0.2.20", "@firebase/analytics": "0.10.18", "@firebase/analytics-compat": "0.2.24", "@firebase/app-check": "0.11.0", diff --git a/packages/firestore-compat/CHANGELOG.md b/packages/firestore-compat/CHANGELOG.md index 4345e2b808c..e5a1aa19d6e 100644 --- a/packages/firestore-compat/CHANGELOG.md +++ b/packages/firestore-compat/CHANGELOG.md @@ -1,5 +1,12 @@ # @firebase/firestore-compat +## 0.4.2 + +### Patch Changes + +- Updated dependencies [[`43276b0`](https://github.com/firebase/firebase-js-sdk/commit/43276b0414ea5a73e8d8f7e3b80275d8b910102f)]: + - @firebase/firestore@4.9.2 + ## 0.4.1 ### Patch Changes diff --git a/packages/firestore-compat/package.json b/packages/firestore-compat/package.json index 3ae7c8bb6d0..0787c21f397 100644 --- a/packages/firestore-compat/package.json +++ b/packages/firestore-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore-compat", - "version": "0.4.1", + "version": "0.4.2", "description": "The Cloud Firestore component of the Firebase JS SDK.", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.node.cjs.js", @@ -47,13 +47,13 @@ }, "dependencies": { "@firebase/component": "0.7.0", - "@firebase/firestore": "4.9.1", + "@firebase/firestore": "4.9.2", "@firebase/util": "1.13.0", "@firebase/firestore-types": "3.0.3", "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "@types/eslint": "7.29.0", "rollup": "2.79.2", "rollup-plugin-sourcemaps": "0.6.3", diff --git a/packages/firestore/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 47ab4e61c30..b3d1f6d4626 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -1,5 +1,14 @@ # @firebase/firestore +## 4.9.2 + +### Patch Changes + +- [`43276b0`](https://github.com/firebase/firebase-js-sdk/commit/43276b0414ea5a73e8d8f7e3b80275d8b910102f) [#9242](https://github.com/firebase/firebase-js-sdk/pull/9242) - Increased the buffering-proxy detection timeout to minimize the false-positive rate. Updating WebChannel to ignore duplicate messages received from the server. Fix for https://github.com/firebase/firebase-js-sdk/issues/8250. + +- Updated dependencies [[`43276b0`](https://github.com/firebase/firebase-js-sdk/commit/43276b0414ea5a73e8d8f7e3b80275d8b910102f)]: + - @firebase/webchannel-wrapper@1.0.5 + ## 4.9.1 ### Patch Changes diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 625a51020ca..4001c19fe8c 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore", - "version": "4.9.1", + "version": "4.9.2", "engines": { "node": ">=20.0.0" }, @@ -103,7 +103,7 @@ "@firebase/component": "0.7.0", "@firebase/logger": "0.5.0", "@firebase/util": "1.13.0", - "@firebase/webchannel-wrapper": "1.0.4", + "@firebase/webchannel-wrapper": "1.0.5", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", "tslib": "^2.1.0" @@ -112,8 +112,8 @@ "@firebase/app": "0.x" }, "devDependencies": { - "@firebase/app": "0.14.2", - "@firebase/app-compat": "0.5.2", + "@firebase/app": "0.14.3", + "@firebase/app-compat": "0.5.3", "@firebase/auth": "1.11.0", "@rollup/plugin-alias": "5.1.1", "@rollup/plugin-json": "6.1.0", diff --git a/packages/functions-compat/package.json b/packages/functions-compat/package.json index 55c31dc9bd6..fd5b482bb66 100644 --- a/packages/functions-compat/package.json +++ b/packages/functions-compat/package.json @@ -29,7 +29,7 @@ "@firebase/app-compat": "0.x" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "rollup": "2.79.2", "@rollup/plugin-json": "6.1.0", "rollup-plugin-typescript2": "0.36.0", diff --git a/packages/functions/package.json b/packages/functions/package.json index c3e20894a8b..6099275f6cf 100644 --- a/packages/functions/package.json +++ b/packages/functions/package.json @@ -49,7 +49,7 @@ "@firebase/app": "0.x" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "@rollup/plugin-json": "6.1.0", "rollup-plugin-typescript2": "0.36.0", diff --git a/packages/installations-compat/package.json b/packages/installations-compat/package.json index 5102c37fcd5..058f690f237 100644 --- a/packages/installations-compat/package.json +++ b/packages/installations-compat/package.json @@ -44,7 +44,7 @@ "url": "https://github.com/firebase/firebase-js-sdk/issues" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "rollup": "2.79.2", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "6.1.0", diff --git a/packages/installations/package.json b/packages/installations/package.json index a5ef2efd243..a1b5db5bdce 100644 --- a/packages/installations/package.json +++ b/packages/installations/package.json @@ -49,7 +49,7 @@ "url": "https://github.com/firebase/firebase-js-sdk/issues" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "6.1.0", diff --git a/packages/messaging-compat/package.json b/packages/messaging-compat/package.json index 1dfe8021e48..643e1bd73e9 100644 --- a/packages/messaging-compat/package.json +++ b/packages/messaging-compat/package.json @@ -44,7 +44,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "@rollup/plugin-json": "6.1.0", "rollup-plugin-typescript2": "0.36.0", "ts-essentials": "9.4.2", diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 74438811c69..4d475ebadfa 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -60,7 +60,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "rollup-plugin-typescript2": "0.36.0", "@rollup/plugin-json": "6.1.0", diff --git a/packages/messaging/src/testing/fakes/firebase-dependencies.ts b/packages/messaging/src/testing/fakes/firebase-dependencies.ts index 8fd3b219f33..ccb40f276ed 100644 --- a/packages/messaging/src/testing/fakes/firebase-dependencies.ts +++ b/packages/messaging/src/testing/fakes/firebase-dependencies.ts @@ -68,7 +68,8 @@ export function getFakeInstallations(): _FirebaseInstallationsInternal { export function getFakeAnalyticsProvider(): Provider { const analytics: FirebaseAnalyticsInternal = { - logEvent() {} + logEvent() {}, + setUserProperties() {} }; return { diff --git a/packages/performance-compat/package.json b/packages/performance-compat/package.json index 27bac29090e..32c041916e2 100644 --- a/packages/performance-compat/package.json +++ b/packages/performance-compat/package.json @@ -51,7 +51,7 @@ "rollup-plugin-replace": "2.2.0", "rollup-plugin-typescript2": "0.36.0", "typescript": "5.5.4", - "@firebase/app-compat": "0.5.2" + "@firebase/app-compat": "0.5.3" }, "repository": { "directory": "packages/performance-compat", diff --git a/packages/performance/package.json b/packages/performance/package.json index e6d69780279..cfbd414c0a4 100644 --- a/packages/performance/package.json +++ b/packages/performance/package.json @@ -47,7 +47,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "@rollup/plugin-json": "6.1.0", "rollup-plugin-typescript2": "0.36.0", diff --git a/packages/remote-config-compat/CHANGELOG.md b/packages/remote-config-compat/CHANGELOG.md index 032b2fd59c0..08cd52e62d0 100644 --- a/packages/remote-config-compat/CHANGELOG.md +++ b/packages/remote-config-compat/CHANGELOG.md @@ -1,5 +1,13 @@ # @firebase/remote-config-compat +## 0.2.20 + +### Patch Changes + +- Updated dependencies [[`120a308`](https://github.com/firebase/firebase-js-sdk/commit/120a30838da50f5ade4f634e97c34cbfcaff41ba)]: + - @firebase/remote-config@0.7.0 + - @firebase/remote-config-types@0.5.0 + ## 0.2.19 ### Patch Changes diff --git a/packages/remote-config-compat/package.json b/packages/remote-config-compat/package.json index 9d24228c146..b733ab07582 100644 --- a/packages/remote-config-compat/package.json +++ b/packages/remote-config-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/remote-config-compat", - "version": "0.2.19", + "version": "0.2.20", "description": "The compatibility package of Remote Config", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.cjs.js", @@ -37,8 +37,8 @@ "@firebase/app-compat": "0.x" }, "dependencies": { - "@firebase/remote-config": "0.6.6", - "@firebase/remote-config-types": "0.4.0", + "@firebase/remote-config": "0.7.0", + "@firebase/remote-config-types": "0.5.0", "@firebase/util": "1.13.0", "@firebase/logger": "0.5.0", "@firebase/component": "0.7.0", @@ -50,7 +50,7 @@ "rollup-plugin-replace": "2.2.0", "rollup-plugin-typescript2": "0.36.0", "typescript": "5.5.4", - "@firebase/app-compat": "0.5.2" + "@firebase/app-compat": "0.5.3" }, "repository": { "directory": "packages/remote-config-compat", diff --git a/packages/remote-config-types/CHANGELOG.md b/packages/remote-config-types/CHANGELOG.md index d4b52e801e8..ef86acb1e08 100644 --- a/packages/remote-config-types/CHANGELOG.md +++ b/packages/remote-config-types/CHANGELOG.md @@ -1,5 +1,11 @@ # @firebase/remote-config-types +## 0.5.0 + +### Minor Changes + +- [`120a308`](https://github.com/firebase/firebase-js-sdk/commit/120a30838da50f5ade4f634e97c34cbfcaff41ba) [#9221](https://github.com/firebase/firebase-js-sdk/pull/9221) - Added support for Realtime Remote Config for the web. This feature introduces a new `onConfigUpdate` API and allows web applications to receive near-instant configuration updates without requiring periodic polling. + ## 0.4.0 ### Minor Changes diff --git a/packages/remote-config-types/package.json b/packages/remote-config-types/package.json index 7de29a27043..ec02d236ec9 100644 --- a/packages/remote-config-types/package.json +++ b/packages/remote-config-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/remote-config-types", - "version": "0.4.0", + "version": "0.5.0", "description": "@firebase/remote-config Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/remote-config/CHANGELOG.md b/packages/remote-config/CHANGELOG.md index 55443c14bbf..fcf552b0e3e 100644 --- a/packages/remote-config/CHANGELOG.md +++ b/packages/remote-config/CHANGELOG.md @@ -1,5 +1,11 @@ # @firebase/remote-config +## 0.7.0 + +### Minor Changes + +- [`120a308`](https://github.com/firebase/firebase-js-sdk/commit/120a30838da50f5ade4f634e97c34cbfcaff41ba) [#9221](https://github.com/firebase/firebase-js-sdk/pull/9221) - Added support for Realtime Remote Config for the web. This feature introduces a new `onConfigUpdate` API and allows web applications to receive near-instant configuration updates without requiring periodic polling. + ## 0.6.6 ### Patch Changes diff --git a/packages/remote-config/package.json b/packages/remote-config/package.json index 2ac97aab639..963b23acdcc 100644 --- a/packages/remote-config/package.json +++ b/packages/remote-config/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/remote-config", - "version": "0.6.6", + "version": "0.7.0", "description": "The Remote Config package of the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.cjs.js", @@ -48,7 +48,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "rollup-plugin-dts": "5.3.1", "rollup-plugin-typescript2": "0.36.0", diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 42b24581777..cf86443967c 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -44,7 +44,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.5.2", + "@firebase/app-compat": "0.5.3", "@firebase/auth-compat": "0.6.0", "rollup": "2.79.2", "@rollup/plugin-json": "6.1.0", diff --git a/packages/storage/package.json b/packages/storage/package.json index 8f9d1c9182e..6248ead4f5c 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -54,7 +54,7 @@ "@firebase/app": "0.x" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "@firebase/auth": "1.11.0", "rollup": "2.79.2", "@rollup/plugin-alias": "5.1.1", diff --git a/packages/template/package.json b/packages/template/package.json index 89e3cc1a515..6ef9c2d81be 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -48,7 +48,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "rollup": "2.79.2", "rollup-plugin-typescript2": "0.36.0", "typescript": "5.5.4" diff --git a/packages/webchannel-wrapper/CHANGELOG.md b/packages/webchannel-wrapper/CHANGELOG.md index 6c93950e82f..e415fdd90bc 100644 --- a/packages/webchannel-wrapper/CHANGELOG.md +++ b/packages/webchannel-wrapper/CHANGELOG.md @@ -1,5 +1,11 @@ # @firebase/webchannel-wrapper +## 1.0.5 + +### Patch Changes + +- [`43276b0`](https://github.com/firebase/firebase-js-sdk/commit/43276b0414ea5a73e8d8f7e3b80275d8b910102f) [#9242](https://github.com/firebase/firebase-js-sdk/pull/9242) - Increased the buffering-proxy detection timeout to minimize the false-positive rate. Updating WebChannel to ignore duplicate messages received from the server. Fix for https://github.com/firebase/firebase-js-sdk/issues/8250. + ## 1.0.4 ### Patch Changes diff --git a/packages/webchannel-wrapper/package.json b/packages/webchannel-wrapper/package.json index 8d02520a362..bddf3cec8ed 100644 --- a/packages/webchannel-wrapper/package.json +++ b/packages/webchannel-wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/webchannel-wrapper", - "version": "1.0.4", + "version": "1.0.5", "description": "A wrapper of the webchannel packages from closure-library for use outside of a closure compiled application", "author": "Firebase (https://firebase.google.com/)", "main": "empty.js", diff --git a/repo-scripts/size-analysis/package.json b/repo-scripts/size-analysis/package.json index 70b42ce4501..dd71cc9a378 100644 --- a/repo-scripts/size-analysis/package.json +++ b/repo-scripts/size-analysis/package.json @@ -40,7 +40,7 @@ "yargs": "17.7.2" }, "devDependencies": { - "@firebase/app": "0.14.2", + "@firebase/app": "0.14.3", "@firebase/logger": "0.5.0", "@types/webpack": "5.28.5" }, diff --git a/scripts/docgen/docgen.ts b/scripts/docgen/docgen.ts index 936eb0d69ca..ece1600b762 100644 --- a/scripts/docgen/docgen.ts +++ b/scripts/docgen/docgen.ts @@ -199,7 +199,19 @@ async function generateDocs( `"mainEntryPointFilePath": "/dist/esm/index.doc.d.ts"` ); + /** + * Exclude compat as this script is only for modular docgen. + */ + const packageDirectories = ( + await mapWorkspaceToPackages([`${projectRoot}/packages/*`]) + ).filter(path => fs.existsSync(path) && !path.includes('-compat')); + try { + console.log(`Deleting old temp directories in each package.`); + for (const dir of packageDirectories) { + fs.rmSync(join(dir, 'temp'), { recursive: true, force: true }); + } + fs.writeFileSync( `${projectRoot}/packages/auth/api-extractor.json`, authApiConfigModified @@ -248,13 +260,9 @@ async function generateDocs( fs.mkdirSync(tmpDir); - // TODO: Throw error if path doesn't exist once all packages add markdown support. - const apiJsonDirectories = ( - await mapWorkspaceToPackages([`${projectRoot}/packages/*`]) - ) - .map(path => `${path}/temp`) + const apiJsonDirectories = packageDirectories + .map(path => join(path, 'temp')) .filter(path => fs.existsSync(path)); - for (const dir of apiJsonDirectories) { const paths = await new Promise(resolve => glob(`${dir}/*.api.json`, (err, paths) => {