From 6772212621805c01a576ce99d45596113b4b5242 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Mon, 20 Jul 2026 16:29:59 -0700 Subject: [PATCH 1/4] Rename vertexAI to agentPlatform --- .../firebase_ai/firebase_ai/lib/src/api.dart | 6 +- .../firebase_ai/lib/src/base_model.dart | 21 ++-- .../firebase_ai/lib/src/content.dart | 6 +- .../firebase_ai/lib/src/developer/api.dart | 4 +- .../firebase_ai/lib/src/error.dart | 6 +- .../firebase_ai/lib/src/firebase_ai.dart | 57 +++++++-- .../firebase_ai/lib/src/generative_model.dart | 28 ++--- .../lib/src/imagen/imagen_api.dart | 3 - .../lib/src/imagen/imagen_model.dart | 14 +-- .../firebase_ai/lib/src/live_model.dart | 32 ++--- .../template_generative_model.dart | 36 +++--- .../template_imagen_model.dart | 16 +-- .../firebase_ai/test/api_test.dart | 119 ++++++++++-------- .../firebase_ai/test/chat_test.dart | 2 +- .../test/google_ai_generative_model_test.dart | 2 +- .../firebase_ai/test/model_test.dart | 2 +- .../test/response_parsing_test.dart | 62 +++++---- .../test/server_template_test.dart | 4 +- .../firebase_ai/firebase_ai_mock_test.dart | 36 +++--- ...firebase_ai_response_parsing_e2e_test.dart | 4 +- 20 files changed, 259 insertions(+), 201 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/api.dart b/packages/firebase_ai/firebase_ai/lib/src/api.dart index d2c2c7c9b3e9..296638c92d2a 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/api.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/api.dart @@ -345,7 +345,7 @@ final class WebGroundingChunk { /// The domain of the original URI from which the content was retrieved. /// - /// This field is only populated when using the Vertex AI Gemini API. + /// This field is only populated when using the Agent Platform Gemini API. final String? domain; } @@ -425,7 +425,7 @@ final class SearchEntryPoint { /// comply with the "Grounding with Google Search" usage requirements for your /// chosen API provider: /// [Gemini Developer API](https://ai.google.dev/gemini-api/terms#grounding-with-google-search) -/// or Vertex AI Gemini API (see [Service Terms](https://cloud.google.com/terms/service-terms) +/// or Agent Platform Gemini API (see [Service Terms](https://cloud.google.com/terms/service-terms) /// section within the Service Specific Terms). final class GroundingMetadata { // ignore: public_member_api_docs @@ -1482,7 +1482,7 @@ abstract interface class SerializationStrategy { } // ignore: public_member_api_docs -final class VertexSerialization implements SerializationStrategy { +final class AgentPlatformSerialization implements SerializationStrategy { /// Parse the json to [GenerateContentResponse] @override GenerateContentResponse parseGenerateContentResponse(Object jsonObject) { diff --git a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart index 96972eb5dafb..7082f0c65546 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart @@ -77,13 +77,13 @@ abstract interface class _ModelUri { ({String prefix, String name}) get model; } -final class _VertexUri implements _ModelUri { - _VertexUri( +final class _AgentPlatformUri implements _ModelUri { + _AgentPlatformUri( {required String model, required String location, required FirebaseApp app}) : model = _normalizeModelName(model), - _projectUri = _vertexUri(app, location); + _projectUri = _agentPlatformUri(app, location); static const _baseAuthority = 'firebasevertexai.googleapis.com'; static const _apiVersion = 'v1beta'; @@ -98,7 +98,7 @@ final class _VertexUri implements _ModelUri { return (prefix: parts.first, name: parts.skip(1).join('/')); } - static Uri _vertexUri(FirebaseApp app, String location) { + static Uri _agentPlatformUri(FirebaseApp app, String location) { var projectId = app.options.projectId; return Uri.https( _baseAuthority, @@ -174,10 +174,11 @@ abstract interface class _TemplateUri { String templateName(String templateId); } -final class _TemplateVertexUri implements _TemplateUri { - _TemplateVertexUri({required String location, required FirebaseApp app}) - : _templateUri = _vertexTemplateUri(app, location), - _templateName = _vertexTemplateName(app, location); +final class _TemplateAgentPlatformUri implements _TemplateUri { + _TemplateAgentPlatformUri( + {required String location, required FirebaseApp app}) + : _templateUri = _agentPlatformTemplateUri(app, location), + _templateName = _agentPlatformTemplateName(app, location); static const _baseAuthority = 'firebasevertexai.googleapis.com'; static const _apiVersion = 'v1beta'; @@ -185,7 +186,7 @@ final class _TemplateVertexUri implements _TemplateUri { final Uri _templateUri; final String _templateName; - static Uri _vertexTemplateUri(FirebaseApp app, String location) { + static Uri _agentPlatformTemplateUri(FirebaseApp app, String location) { var projectId = app.options.projectId; return Uri.https( _baseAuthority, @@ -193,7 +194,7 @@ final class _TemplateVertexUri implements _TemplateUri { ); } - static String _vertexTemplateName(FirebaseApp app, String location) { + static String _agentPlatformTemplateName(FirebaseApp app, String location) { var projectId = app.options.projectId; return 'projects/$projectId/locations/$location'; } diff --git a/packages/firebase_ai/firebase_ai/lib/src/content.dart b/packages/firebase_ai/firebase_ai/lib/src/content.dart index 1cac4e3d9dd1..64f31365b650 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/content.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/content.dart @@ -304,7 +304,8 @@ final class InlineDataPart extends Part { ); /// File type of the [InlineDataPart]. - /// https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/send-multimodal-prompts#media_requirements + /// + /// Can find details in [FirebaseAIMimeTypes] final String mimeType; /// Data contents in bytes. @@ -485,7 +486,8 @@ final class FileData extends Part { ); /// File type of the [FileData]. - /// https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/send-multimodal-prompts#media_requirements + /// + /// Can find details in [FirebaseAIMimeTypes] final String mimeType; /// The gs link for Firebase Storage reference diff --git a/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart b/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart index d89f711aea27..b27eec0d325d 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart @@ -148,7 +148,7 @@ final class DeveloperSerialization implements SerializationStrategy { }; } -// Developer API and Vertex AI has different _parseSafetyRating logic. +// Developer API and Agent Platform has different _parseSafetyRating logic. Candidate _parseCandidate(Object? jsonObject) { if (jsonObject is! Map) { throw unhandledFormat('Candidate', jsonObject); @@ -190,7 +190,7 @@ Candidate _parseCandidate(Object? jsonObject) { ); } -// Developer API and Vertex AI has different _parseSafetyRating logic. +// Developer API and Agent Platform has different _parseSafetyRating logic. PromptFeedback _parsePromptFeedback(Object jsonObject) { return switch (jsonObject) { { diff --git a/packages/firebase_ai/firebase_ai/lib/src/error.dart b/packages/firebase_ai/firebase_ai/lib/src/error.dart index 00f594a704a8..5f438fa4496f 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/error.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/error.dart @@ -53,9 +53,7 @@ final class ServiceApiNotEnabled implements FirebaseAIException { @override String get message => - 'The Vertex AI in Firebase SDK requires the Vertex AI in Firebase API ' - '(`firebasevertexai.googleapis.com`) to be enabled in your Firebase project. Enable this API ' - 'by visiting the Firebase Console at ' + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' 'https://console.firebase.google.com/project/$_id/ailogic ' 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' 'action to propagate to our systems and then retry.'; @@ -114,7 +112,7 @@ final class FirebaseAISdkException implements Exception { /// Exception indicating all images filtered out. /// /// This exception indicates all images were filtered out because they violated -/// Vertex AI's usage guidelines. +/// usage guidelines. final class ImagenImagesBlockedException implements Exception { // ignore: public_member_api_docs ImagenImagesBlockedException(this.message); diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index 5841c0d2de47..3781cba23bb4 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -23,18 +23,19 @@ import 'package:meta/meta.dart'; import '../firebase_ai.dart'; import 'base_model.dart'; -const _defaultLocation = 'us-central1'; +const _defaultVertexAILocation = 'us-central1'; +const _defaultAgentPlatformLocation = 'global'; /// The entrypoint for generative models. class FirebaseAI extends FirebasePlugin { FirebaseAI._({ required this.app, required this.location, - required bool useVertexBackend, + required bool useAgentPlatform, this.appCheck, this.auth, this.useLimitedUseAppCheckTokens = false, - }) : _useVertexBackend = useVertexBackend, + }) : _useAgentPlatform = useAgentPlatform, super(app.name, 'plugins.flutter.io/firebase_vertexai'); /// The [FirebaseApp] for this current [FirebaseAI] instance. @@ -53,7 +54,7 @@ class FirebaseAI extends FirebasePlugin { /// Whether to use App Check limited use tokens. Defaults to false. final bool useLimitedUseAppCheckTokens; - final bool _useVertexBackend; + final bool _useAgentPlatform; static final Map _cachedInstances = {}; @@ -61,6 +62,8 @@ class FirebaseAI extends FirebasePlugin { /// /// If [app] is not provided, the default Firebase app will be used. /// If pass in [appCheck], request session will get protected from abusing. + @Deprecated( + 'Use agentPlatform() instead. Note that the default location is now "global" instead of "us-central1"') static FirebaseAI vertexAI({ FirebaseApp? app, @Deprecated( @@ -81,14 +84,42 @@ class FirebaseAI extends FirebasePlugin { return _cachedInstances[instanceKey]!; } - location ??= _defaultLocation; + location ??= _defaultVertexAILocation; FirebaseAI newInstance = FirebaseAI._( app: app, location: location, appCheck: appCheck, auth: auth, - useVertexBackend: true, + useAgentPlatform: true, + useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens ?? false, + ); + _cachedInstances[instanceKey] = newInstance; + + return newInstance; + } + + /// Returns an instance using a specified [FirebaseApp]. + /// + /// If [app] is not provided, the default Firebase app will be used. + static FirebaseAI agentPlatform({ + FirebaseApp? app, + String? location, + bool? useLimitedUseAppCheckTokens, + }) { + app ??= Firebase.app(); + var instanceKey = '${app.name}::agentPlatform::$location'; + + if (_cachedInstances.containsKey(instanceKey)) { + return _cachedInstances[instanceKey]!; + } + + location ??= _defaultAgentPlatformLocation; + + FirebaseAI newInstance = FirebaseAI._( + app: app, + location: location, + useAgentPlatform: true, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens ?? false, ); _cachedInstances[instanceKey] = newInstance; @@ -121,10 +152,10 @@ class FirebaseAI extends FirebasePlugin { FirebaseAI newInstance = FirebaseAI._( app: app, - location: _defaultLocation, + location: _defaultAgentPlatformLocation, appCheck: appCheck, auth: auth, - useVertexBackend: false, + useAgentPlatform: false, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens ?? false, ); _cachedInstances[instanceKey] = newInstance; @@ -159,7 +190,7 @@ class FirebaseAI extends FirebasePlugin { model: model, app: app, appCheck: appCheck, - useVertexBackend: _useVertexBackend, + useAgentPlatform: _useAgentPlatform, auth: auth, location: location, safetySettings: safetySettings, @@ -184,7 +215,7 @@ class FirebaseAI extends FirebasePlugin { app: app, location: location, model: model, - useVertexBackend: _useVertexBackend, + useAgentPlatform: _useAgentPlatform, generationConfig: generationConfig, safetySettings: safetySettings, appCheck: appCheck, @@ -206,7 +237,7 @@ class FirebaseAI extends FirebasePlugin { app: app, location: location, model: model, - useVertexBackend: _useVertexBackend, + useAgentPlatform: _useAgentPlatform, liveGenerationConfig: liveGenerationConfig, tools: tools, systemInstruction: systemInstruction, @@ -224,7 +255,7 @@ class FirebaseAI extends FirebasePlugin { return createTemplateGenerativeModel( app: app, location: location, - useVertexBackend: _useVertexBackend, + useAgentPlatform: _useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, auth: auth, appCheck: appCheck); @@ -238,7 +269,7 @@ class FirebaseAI extends FirebasePlugin { return createTemplateImagenModel( app: app, location: location, - useVertexBackend: _useVertexBackend, + useAgentPlatform: _useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, auth: auth, appCheck: appCheck, diff --git a/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart b/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart index 844614583889..347eaf8b589c 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart @@ -36,7 +36,7 @@ final class GenerativeModel extends BaseApiClientModel { required String model, required String location, required FirebaseApp app, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -51,11 +51,11 @@ final class GenerativeModel extends BaseApiClientModel { _toolConfig = toolConfig, _systemInstruction = systemInstruction, super( - serializationStrategy: useVertexBackend - ? VertexSerialization() + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() : DeveloperSerialization(), - modelUri: useVertexBackend - ? _VertexUri(app: app, model: model, location: location) + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: model, location: location) : _GoogleAIUri(app: app, model: model), client: HttpApiClient( apiKey: app.options.apiKey, @@ -67,7 +67,7 @@ final class GenerativeModel extends BaseApiClientModel { required String model, required String location, required FirebaseApp app, - required useVertexBackend, + required useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -82,11 +82,11 @@ final class GenerativeModel extends BaseApiClientModel { _toolConfig = toolConfig, _systemInstruction = systemInstruction, super( - serializationStrategy: useVertexBackend - ? VertexSerialization() + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() : DeveloperSerialization(), - modelUri: useVertexBackend - ? _VertexUri(app: app, model: model, location: location) + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: model, location: location) : _GoogleAIUri(app: app, model: model), client: apiClient ?? HttpApiClient( @@ -201,7 +201,7 @@ GenerativeModel createGenerativeModel({ required FirebaseApp app, required String location, required String model, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -216,7 +216,7 @@ GenerativeModel createGenerativeModel({ model: model, app: app, appCheck: appCheck, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, auth: auth, location: location, @@ -236,7 +236,7 @@ GenerativeModel createModelWithClient({ required String location, required String model, required ApiClient client, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, Content? systemInstruction, FirebaseAppCheck? appCheck, @@ -250,7 +250,7 @@ GenerativeModel createModelWithClient({ model: model, app: app, appCheck: appCheck, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, auth: auth, location: location, diff --git a/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_api.dart b/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_api.dart index 8bf9ef018b9a..363c7f36dfb7 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_api.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_api.dart @@ -204,9 +204,6 @@ final class ImagenGenerationConfig { final ImagenFormat? imageFormat; /// Whether to add an invisible watermark to generated images. - /// - /// Default value for each imagen model can be found in - /// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#generate_images final bool? addWatermark; // ignore: public_member_api_docs diff --git a/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_model.dart b/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_model.dart index 197ed5714866..936047886f29 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/imagen/imagen_model.dart @@ -17,11 +17,7 @@ part of '../base_model.dart'; /// Represents a remote Imagen model with the ability to generate images using /// text prompts. /// -/// See the [Cloud -/// documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/image/generate-images) -/// for more details about the image generation capabilities offered by the Imagen model. -/// -/// > Warning: For Vertex AI in Firebase, image generation using Imagen 3 models +/// > Warning: For Firebase AI Logic, image generation using Imagen 3 models /// is in Public Preview, which means that the feature is not subject to any SLA /// or deprecation policy and could change in backwards-incompatible ways. @Deprecated( @@ -45,10 +41,10 @@ final class ImagenModel extends BaseApiClientModel { _useVertexBackend = useVertexBackend, super( serializationStrategy: useVertexBackend - ? VertexSerialization() + ? AgentPlatformSerialization() : DeveloperSerialization(), modelUri: useVertexBackend - ? _VertexUri(app: app, model: model, location: location) + ? _AgentPlatformUri(app: app, model: model, location: location) : _GoogleAIUri(app: app, model: model), client: HttpApiClient( apiKey: app.options.apiKey, @@ -203,7 +199,7 @@ ImagenModel createImagenModel({ required FirebaseApp app, required String location, required String model, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -216,7 +212,7 @@ ImagenModel createImagenModel({ appCheck: appCheck, auth: auth, location: location, - useVertexBackend: useVertexBackend, + useVertexBackend: useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, safetySettings: safetySettings, generationConfig: generationConfig, diff --git a/packages/firebase_ai/firebase_ai/lib/src/live_model.dart b/packages/firebase_ai/firebase_ai/lib/src/live_model.dart index 19e837fcf849..0bb7aba55a26 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/live_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/live_model.dart @@ -15,7 +15,8 @@ part of 'base_model.dart'; const _apiUrl = 'ws/google.firebase.vertexai'; -const _apiUrlSuffixVertexAI = 'LlmBidiService/BidiGenerateContent/locations'; +const _apiUrlSuffixAgentPlatform = + 'LlmBidiService/BidiGenerateContent/locations'; const _apiUrlSuffixGoogleAI = 'GenerativeService/BidiGenerateContent'; /// A live, generative AI model for real-time interaction. @@ -33,7 +34,7 @@ final class LiveGenerativeModel extends BaseModel { {required String model, required String location, required FirebaseApp app, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -42,7 +43,7 @@ final class LiveGenerativeModel extends BaseModel { Content? systemInstruction}) : _app = app, _location = location, - _useVertexBackend = useVertexBackend, + _useAgentPlatform = useAgentPlatform, _appCheck = appCheck, _auth = auth, _liveGenerationConfig = liveGenerationConfig, @@ -50,9 +51,9 @@ final class LiveGenerativeModel extends BaseModel { _systemInstruction = systemInstruction, _useLimitedUseAppCheckTokens = useLimitedUseAppCheckTokens, super._( - serializationStrategy: VertexSerialization(), - modelUri: useVertexBackend - ? _VertexUri( + serializationStrategy: AgentPlatformSerialization(), + modelUri: useAgentPlatform + ? _AgentPlatformUri( model: model, app: app, location: location, @@ -65,7 +66,7 @@ final class LiveGenerativeModel extends BaseModel { final FirebaseApp _app; final String _location; - final bool _useVertexBackend; + final bool _useAgentPlatform; final FirebaseAppCheck? _appCheck; final FirebaseAuth? _auth; final LiveGenerationConfig? _liveGenerationConfig; @@ -73,11 +74,11 @@ final class LiveGenerativeModel extends BaseModel { final Content? _systemInstruction; final bool? _useLimitedUseAppCheckTokens; - String _vertexAIUri() => 'wss://${_modelUri.baseAuthority}/' - '$_apiUrl.${_modelUri.apiVersion}.$_apiUrlSuffixVertexAI/' + String _agentPlatformUri() => 'wss://${_modelUri.baseAuthority}/' + '$_apiUrl.${_modelUri.apiVersion}.$_apiUrlSuffixAgentPlatform/' '$_location?key=${_app.options.apiKey}'; - String _vertexAIModelString() => 'projects/${_app.options.projectId}/' + String _agentPlatformModelString() => 'projects/${_app.options.projectId}/' 'locations/$_location/publishers/google/models/${model.name}'; String _googleAIUri() => 'wss://${_modelUri.baseAuthority}/' @@ -97,9 +98,10 @@ final class LiveGenerativeModel extends BaseModel { /// connection. Future connect( {SessionResumptionConfig? sessionResumption}) async { - final uri = _useVertexBackend ? _vertexAIUri() : _googleAIUri(); - final modelString = - _useVertexBackend ? _vertexAIModelString() : _googleAIModelString(); + final uri = _useAgentPlatform ? _agentPlatformUri() : _googleAIUri(); + final modelString = _useAgentPlatform + ? _agentPlatformModelString() + : _googleAIModelString(); final headers = await BaseModel.firebaseTokens( _appCheck, @@ -125,7 +127,7 @@ LiveGenerativeModel createLiveGenerativeModel({ required FirebaseApp app, required String location, required String model, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -139,7 +141,7 @@ LiveGenerativeModel createLiveGenerativeModel({ appCheck: appCheck, auth: auth, location: location, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, liveGenerationConfig: liveGenerationConfig, tools: tools, diff --git a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart index 0b94fc9eaea4..2cfab6fc1046 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart @@ -21,46 +21,46 @@ final class TemplateGenerativeModel extends BaseTemplateApiClientModel { TemplateGenerativeModel._test({ required String location, required FirebaseApp app, - required bool useVertexBackend, + required bool useAgentPlatform, http.Client? httpClient, }) : super( - serializationStrategy: useVertexBackend - ? VertexSerialization() + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() : DeveloperSerialization(), - modelUri: useVertexBackend - ? _VertexUri(app: app, model: '', location: location) + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: '', location: location) : _GoogleAIUri(app: app, model: ''), client: HttpApiClient( apiKey: app.options.apiKey, httpClient: httpClient, requestHeaders: BaseModel.firebaseTokens(null, null, app, false)), - templateUri: useVertexBackend - ? _TemplateVertexUri(app: app, location: location) + templateUri: useAgentPlatform + ? _TemplateAgentPlatformUri(app: app, location: location) : _TemplateGoogleAIUri(app: app), ); TemplateGenerativeModel._({ required String location, required FirebaseApp app, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, http.Client? httpClient, }) : super( - serializationStrategy: useVertexBackend - ? VertexSerialization() + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() : DeveloperSerialization(), - modelUri: useVertexBackend - ? _VertexUri(app: app, model: '', location: location) + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: '', location: location) : _GoogleAIUri(app: app, model: ''), client: HttpApiClient( apiKey: app.options.apiKey, httpClient: httpClient, requestHeaders: BaseModel.firebaseTokens( appCheck, auth, app, useLimitedUseAppCheckTokens)), - templateUri: useVertexBackend - ? _TemplateVertexUri(app: app, location: location) + templateUri: useAgentPlatform + ? _TemplateAgentPlatformUri(app: app, location: location) : _TemplateGoogleAIUri(app: app), ); @@ -139,7 +139,7 @@ final class TemplateGenerativeModel extends BaseTemplateApiClientModel { TemplateGenerativeModel createTemplateGenerativeModel({ required FirebaseApp app, required String location, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -147,7 +147,7 @@ TemplateGenerativeModel createTemplateGenerativeModel({ TemplateGenerativeModel._( app: app, appCheck: appCheck, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, auth: auth, location: location, @@ -159,12 +159,12 @@ TemplateGenerativeModel createTemplateGenerativeModel({ TemplateGenerativeModel createTestTemplateGenerativeModel({ required FirebaseApp app, required String location, - required bool useVertexBackend, + required bool useAgentPlatform, required http.Client client, }) => TemplateGenerativeModel._test( app: app, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, location: location, httpClient: client, ); diff --git a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_imagen_model.dart b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_imagen_model.dart index 14437e5f2ec3..6d2216f68660 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_imagen_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_imagen_model.dart @@ -28,16 +28,16 @@ final class TemplateImagenModel extends BaseTemplateApiClientModel { required bool useVertexBackend, http.Client? httpClient}) : super( - serializationStrategy: VertexSerialization(), + serializationStrategy: AgentPlatformSerialization(), modelUri: useVertexBackend - ? _VertexUri(app: app, model: '', location: location) + ? _AgentPlatformUri(app: app, model: '', location: location) : _GoogleAIUri(app: app, model: ''), client: HttpApiClient( apiKey: app.options.apiKey, httpClient: httpClient, requestHeaders: BaseModel.firebaseTokens(null, null, app, false)), templateUri: useVertexBackend - ? _TemplateVertexUri(app: app, location: location) + ? _TemplateAgentPlatformUri(app: app, location: location) : _TemplateGoogleAIUri(app: app), ); @@ -50,17 +50,17 @@ final class TemplateImagenModel extends BaseTemplateApiClientModel { FirebaseAuth? auth}) : super( serializationStrategy: useVertexBackend - ? VertexSerialization() + ? AgentPlatformSerialization() : DeveloperSerialization(), modelUri: useVertexBackend - ? _VertexUri(app: app, model: '', location: location) + ? _AgentPlatformUri(app: app, model: '', location: location) : _GoogleAIUri(app: app, model: ''), client: HttpApiClient( apiKey: app.options.apiKey, requestHeaders: BaseModel.firebaseTokens( appCheck, auth, app, useLimitedUseAppCheckTokens)), templateUri: useVertexBackend - ? _TemplateVertexUri(app: app, location: location) + ? _TemplateAgentPlatformUri(app: app, location: location) : _TemplateGoogleAIUri(app: app), ); @@ -87,7 +87,7 @@ final class TemplateImagenModel extends BaseTemplateApiClientModel { TemplateImagenModel createTemplateImagenModel({ required FirebaseApp app, required String location, - required bool useVertexBackend, + required bool useAgentPlatform, bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, @@ -97,7 +97,7 @@ TemplateImagenModel createTemplateImagenModel({ appCheck: appCheck, auth: auth, location: location, - useVertexBackend: useVertexBackend, + useVertexBackend: useAgentPlatform, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, ); diff --git a/packages/firebase_ai/firebase_ai/test/api_test.dart b/packages/firebase_ai/firebase_ai/test/api_test.dart index a177abe5e374..ff65ed0405f4 100644 --- a/packages/firebase_ai/firebase_ai/test/api_test.dart +++ b/packages/firebase_ai/firebase_ai/test/api_test.dart @@ -720,7 +720,8 @@ void main() { {'modality': 'IMAGE', 'tokenCount': 20} ] }; - final response = VertexSerialization().parseCountTokensResponse(json); + final response = + AgentPlatformSerialization().parseCountTokensResponse(json); expect(response.totalTokens, 120); expect(response.promptTokensDetails, isNotNull); expect(response.promptTokensDetails, hasLength(2)); @@ -733,7 +734,8 @@ void main() { test('parses valid JSON with minimal fields (only totalTokens)', () { final json = {'totalTokens': 50}; - final response = VertexSerialization().parseCountTokensResponse(json); + final response = + AgentPlatformSerialization().parseCountTokensResponse(json); expect(response.totalTokens, 50); expect(response.promptTokensDetails, isNull); }); @@ -742,21 +744,23 @@ void main() { final json = { 'error': {'code': 400, 'message': 'Invalid request'} }; - expect(() => VertexSerialization().parseCountTokensResponse(json), + expect( + () => AgentPlatformSerialization().parseCountTokensResponse(json), throwsA(isA())); }); test('throws FormatException for invalid JSON structure (not a Map)', () { const json = 'not_a_map'; expect( - () => VertexSerialization().parseCountTokensResponse(json), + () => AgentPlatformSerialization().parseCountTokensResponse(json), throwsA(isA().having( (e) => e.message, 'message', contains('CountTokensResponse')))); }); test('throws if totalTokens is missing', () { final json = {'totalBillableCharacters': 100}; - expect(() => VertexSerialization().parseCountTokensResponse(json), + expect( + () => AgentPlatformSerialization().parseCountTokensResponse(json), throwsA(anything)); // More specific error expected }); }); @@ -807,7 +811,7 @@ void main() { } }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.text, 'Hello world'); expect(response.candidates.first.finishReason, FinishReason.stop); @@ -870,7 +874,7 @@ void main() { ] }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); final ratings = response.candidates.first.safetyRatings!; expect(ratings.map((r) => r.category), [ HarmCategory.imageDangerousContent, @@ -901,7 +905,7 @@ void main() { ] }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates.first.safetyRatings!.first.category, HarmCategory.unknown); }); @@ -918,7 +922,7 @@ void main() { } }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.promptTokenCount, 10); expect(response.usageMetadata!.candidatesTokenCount, 20); @@ -936,7 +940,7 @@ void main() { } }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.thoughtsTokenCount, isNull); }); @@ -979,8 +983,8 @@ void main() { ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); @@ -1038,8 +1042,8 @@ void main() { ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); @@ -1081,7 +1085,7 @@ void main() { }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('SearchEntryPoint')))); @@ -1108,8 +1112,8 @@ void main() { } ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); @@ -1130,7 +1134,8 @@ void main() { ] }; expect( - () => VertexSerialization().parseGenerateContentResponse(json), + () => AgentPlatformSerialization() + .parseGenerateContentResponse(json), throwsA(isA().having( (e) => e.message, 'message', contains('GroundingChunk')))); }); @@ -1147,7 +1152,8 @@ void main() { ] }; expect( - () => VertexSerialization().parseGenerateContentResponse(json), + () => AgentPlatformSerialization() + .parseGenerateContentResponse(json), throwsA(isA().having( (e) => e.message, 'message', contains('GroundingSupport')))); }); @@ -1162,7 +1168,8 @@ void main() { ] }; expect( - () => VertexSerialization().parseGenerateContentResponse(json), + () => AgentPlatformSerialization() + .parseGenerateContentResponse(json), throwsA(isA().having( (e) => e.message, 'message', contains('SearchEntryPoint')))); }); @@ -1182,7 +1189,8 @@ void main() { ] }; expect( - () => VertexSerialization().parseGenerateContentResponse(json), + () => AgentPlatformSerialization() + .parseGenerateContentResponse(json), throwsA(isA() .having((e) => e.message, 'message', contains('Segment')))); }); @@ -1202,7 +1210,8 @@ void main() { ] }; expect( - () => VertexSerialization().parseGenerateContentResponse(json), + () => AgentPlatformSerialization() + .parseGenerateContentResponse(json), throwsA(isA().having( (e) => e.message, 'message', contains('WebGroundingChunk')))); }); @@ -1213,8 +1222,8 @@ void main() { {'finishReason': 'MALFORMED_FUNCTION_CALL'} ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); expect(response.candidates.first.finishReason, FinishReason.malformedFunctionCall); }); @@ -1225,8 +1234,8 @@ void main() { {'finishReason': 'UNEXPECTED_TOOL_CALL'} ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); expect(response.candidates.first.finishReason, FinishReason.unexpectedToolCall); }); @@ -1266,8 +1275,8 @@ void main() { ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); @@ -1302,8 +1311,8 @@ void main() { } ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final urlContextMetadata = response.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); @@ -1340,8 +1349,8 @@ void main() { } ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final urlContextMetadata = response.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); @@ -1369,8 +1378,8 @@ void main() { } ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final urlMetadata = response.candidates.first.urlContextMetadata!.urlMetadata.first; expect(urlMetadata.retrievedUrl, isNull); @@ -1385,8 +1394,8 @@ void main() { } ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final urlContextMetadata = response.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); @@ -1399,8 +1408,8 @@ void main() { {'finishReason': 'STOP'} ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final candidate = response.candidates.first; expect(candidate.urlContextMetadata, isNull); }); @@ -1412,7 +1421,7 @@ void main() { ] }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having((e) => e.message, 'message', contains('UrlContextMetadata')))); @@ -1429,7 +1438,7 @@ void main() { ] }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('UrlMetadata')))); @@ -1439,7 +1448,7 @@ void main() { test('parses JSON with no candidates (empty list)', () { final json = {'candidates': []}; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates, isEmpty); expect(response.promptFeedback, isNull); expect(response.usageMetadata, isNull); @@ -1449,7 +1458,7 @@ void main() { // The code defaults to [] if 'candidates' key is missing final json = {'promptFeedback': null}; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates, isEmpty); expect(response.promptFeedback, isNull); }); @@ -1468,7 +1477,7 @@ void main() { ] }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.text, 'Minimal'); expect(response.candidates.first.finishReason, isNull); @@ -1498,7 +1507,7 @@ void main() { } }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.text, 'Hello world'); expect(response.candidates.first.finishReason, FinishReason.stop); @@ -1554,7 +1563,7 @@ void main() { ] }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); final candidate = response.candidates.first; expect(candidate.citationMetadata, isNotNull); expect(candidate.citationMetadata!.citations, hasLength(1)); @@ -1585,7 +1594,7 @@ void main() { ] }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); final candidate = response.candidates.first; expect(candidate.citationMetadata, isNotNull); expect(candidate.citationMetadata!.citations, hasLength(1)); @@ -1598,7 +1607,9 @@ void main() { final json = { 'error': {'code': 500, 'message': 'Internal server error'} }; - expect(() => VertexSerialization().parseGenerateContentResponse(json), + expect( + () => + AgentPlatformSerialization().parseGenerateContentResponse(json), throwsA(isA())); }); @@ -1613,7 +1624,7 @@ void main() { ] }; final response = - VertexSerialization().parseGenerateContentResponse(json); + AgentPlatformSerialization().parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.content.parts, isEmpty); expect(response.candidates.first.text, isNull); @@ -1624,7 +1635,7 @@ void main() { 'candidates': ['not_a_map_candidate'] }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA() .having((e) => e.message, 'message', contains('Candidate')))); @@ -1640,7 +1651,7 @@ void main() { ] }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('SafetyRating')))); @@ -1656,7 +1667,7 @@ void main() { ] }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('CitationMetadata')))); @@ -1664,7 +1675,7 @@ void main() { test('throws FormatException for invalid prompt feedback structure', () { final jsonResponse = {'promptFeedback': 'not_a_map_feedback'}; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('PromptFeedback')))); @@ -1672,7 +1683,7 @@ void main() { test('throws FormatException for invalid usage metadata structure', () { final jsonResponse = {'usageMetadata': 'not_a_map_usage'}; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('UsageMetadata')))); @@ -1685,7 +1696,7 @@ void main() { } }; expect( - () => VertexSerialization() + () => AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse), throwsA(isA().having( (e) => e.message, 'message', contains('ModalityTokenCount')))); diff --git a/packages/firebase_ai/firebase_ai/test/chat_test.dart b/packages/firebase_ai/firebase_ai/test/chat_test.dart index f2104aeadc4f..757568e1989d 100644 --- a/packages/firebase_ai/firebase_ai/test/chat_test.dart +++ b/packages/firebase_ai/firebase_ai/test/chat_test.dart @@ -39,7 +39,7 @@ void main() { final client = ClientController(); final model = createModelWithClient( app: app, - useVertexBackend: true, + useAgentPlatform: true, model: modelName, client: client.client, location: 'us-central1'); diff --git a/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart b/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart index 40d05f630844..c8d2a8e551ed 100644 --- a/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart +++ b/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart @@ -39,7 +39,7 @@ void main() { }) { final client = ClientController(); final model = createModelWithClient( - useVertexBackend: false, + useAgentPlatform: false, app: app, model: modelName, client: client.client, diff --git a/packages/firebase_ai/firebase_ai/test/model_test.dart b/packages/firebase_ai/firebase_ai/test/model_test.dart index c14cf5ca3b95..668712db6ff4 100644 --- a/packages/firebase_ai/firebase_ai/test/model_test.dart +++ b/packages/firebase_ai/firebase_ai/test/model_test.dart @@ -40,7 +40,7 @@ void main() { }) { final client = ClientController(); final model = createModelWithClient( - useVertexBackend: true, + useAgentPlatform: true, app: app, model: modelName, client: client.client, diff --git a/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart b/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart index 7ad3aebe6572..8d94de1b895e 100644 --- a/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart +++ b/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart @@ -55,7 +55,8 @@ void main() { '''; final decoded = jsonDecode(response) as Object; expect( - () => VertexSerialization().parseGenerateContentResponse(decoded), + () => + AgentPlatformSerialization().parseGenerateContentResponse(decoded), throwsA( isA().having( (e) => e.message, @@ -87,7 +88,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; expect( - VertexSerialization().parseGenerateContentResponse(decoded), + AgentPlatformSerialization().parseGenerateContentResponse(decoded), isA(), ); }); @@ -120,7 +121,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -184,7 +185,8 @@ void main() { '''; final decoded = jsonDecode(response) as Object; expect( - () => VertexSerialization().parseGenerateContentResponse(decoded), + () => + AgentPlatformSerialization().parseGenerateContentResponse(decoded), throwsA( isA().having( (e) => e.message, @@ -232,7 +234,8 @@ void main() { '''; final decoded = jsonDecode(response) as Object; expect( - () => VertexSerialization().parseGenerateContentResponse(decoded), + () => + AgentPlatformSerialization().parseGenerateContentResponse(decoded), throwsA( isA().having( (e) => e.message, @@ -304,7 +307,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -438,7 +441,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -573,7 +576,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -655,7 +658,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -722,7 +725,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse.text, 'Here is a description of the image:'); expect(generateContentResponse.usageMetadata?.totalTokenCount, 1913); @@ -771,7 +774,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final countTokensResponse = - VertexSerialization().parseCountTokensResponse(decoded); + AgentPlatformSerialization().parseCountTokensResponse(decoded); expect(countTokensResponse.totalTokens, 1837); expect(countTokensResponse.promptTokensDetails?.first.modality, ContentModality.image); @@ -805,7 +808,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect(generateContentResponse.text, 'Initial text And more text'); expect(generateContentResponse.candidates.single.text, 'Initial text And more text'); @@ -890,7 +893,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); final candidate = generateContentResponse.candidates.first; final urlContextMetadata = candidate.urlContextMetadata; expect(urlContextMetadata, isNotNull); @@ -1031,7 +1034,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); final urlContextMetadata = generateContentResponse.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); @@ -1106,7 +1109,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); final urlContextMetadata = generateContentResponse.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); @@ -1141,8 +1144,8 @@ void main() { ] }; - final response = - VertexSerialization().parseGenerateContentResponse(jsonResponse); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); @@ -1204,7 +1207,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -1275,7 +1278,7 @@ void main() { '''; final decoded = jsonDecode(response) as Object; final generateContentResponse = - VertexSerialization().parseGenerateContentResponse(decoded); + AgentPlatformSerialization().parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -1331,9 +1334,12 @@ void main() { 'API key not valid. Please pass a valid API key.', ), ); - expect(() => VertexSerialization().parseGenerateContentResponse(decoded), + expect( + () => AgentPlatformSerialization() + .parseGenerateContentResponse(decoded), expectedThrow); - expect(() => VertexSerialization().parseCountTokensResponse(decoded), + expect( + () => AgentPlatformSerialization().parseCountTokensResponse(decoded), expectedThrow); }); @@ -1361,9 +1367,12 @@ void main() { 'User location is not supported for the API use.', ), ); - expect(() => VertexSerialization().parseGenerateContentResponse(decoded), + expect( + () => AgentPlatformSerialization() + .parseGenerateContentResponse(decoded), expectedThrow); - expect(() => VertexSerialization().parseCountTokensResponse(decoded), + expect( + () => AgentPlatformSerialization().parseCountTokensResponse(decoded), expectedThrow); }); @@ -1394,9 +1403,12 @@ void main() { ), ), ); - expect(() => VertexSerialization().parseGenerateContentResponse(decoded), + expect( + () => AgentPlatformSerialization() + .parseGenerateContentResponse(decoded), expectedThrow); - expect(() => VertexSerialization().parseCountTokensResponse(decoded), + expect( + () => AgentPlatformSerialization().parseCountTokensResponse(decoded), expectedThrow); }); }); diff --git a/packages/firebase_ai/firebase_ai/test/server_template_test.dart b/packages/firebase_ai/firebase_ai/test/server_template_test.dart index 1dbde35afc0c..f92ace1c6bfc 100644 --- a/packages/firebase_ai/firebase_ai/test/server_template_test.dart +++ b/packages/firebase_ai/firebase_ai/test/server_template_test.dart @@ -61,12 +61,12 @@ void main() { const location = 'us-central1'; TemplateGenerativeModel createModel(http.Client client, - {bool useVertexBackend = true}) { + {bool useAgentPlatform = true}) { // ignore: invalid_use_of_internal_member return createTestTemplateGenerativeModel( app: app, location: location, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, client: client, ); } diff --git a/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart b/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart index 26ebddba04a8..2ad21be93833 100644 --- a/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart +++ b/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart @@ -30,14 +30,18 @@ class MockApiClient implements ApiClient { @override Future> makeRequest( - Uri uri, Map body,) async { + Uri uri, + Map body, + ) async { requests.add({'uri': uri, 'body': body}); return mockResponse; } @override Stream> streamRequest( - Uri uri, Map body,) async* { + Uri uri, + Map body, + ) async* { requests.add({'uri': uri, 'body': body}); yield mockResponse; } @@ -76,7 +80,7 @@ void main() { location: 'us-central1', model: 'gemini-pro', client: mockClient, - useVertexBackend: true, + useAgentPlatform: true, ); // We need to construct a request that uses Grounding. @@ -111,7 +115,7 @@ void main() { location: 'us-central1', model: 'gemini-pro', client: mockClient, - useVertexBackend: true, + useAgentPlatform: true, ); final schema = { @@ -132,10 +136,12 @@ void main() { ); expect(mockClient.requests, hasLength(1)); - final requestBody = mockClient.requests.first['body']! as Map; + final requestBody = + mockClient.requests.first['body']! as Map; expect(requestBody, contains('generationConfig')); - - final genConfig = requestBody['generationConfig']! as Map; + + final genConfig = + requestBody['generationConfig']! as Map; expect(genConfig['responseMimeType'], equals('application/json')); expect(genConfig['responseJsonSchema'], equals(schema)); }); @@ -161,7 +167,7 @@ void main() { location: 'us-central1', model: 'gemini-pro', client: mockClient, - useVertexBackend: true, + useAgentPlatform: true, ); final chat = model.startChat(); @@ -188,18 +194,20 @@ void main() { // Verify that the second request contains the history expect(mockClient.requests, hasLength(2)); - - final secondRequest = mockClient.requests[1]['body']! as Map; + + final secondRequest = + mockClient.requests[1]['body']! as Map; expect(secondRequest, contains('contents')); - + final contents = secondRequest['contents']! as List; - expect(contents, hasLength(3)); // User 'Hi', Model 'Hello!', User 'How are you?' - + expect(contents, + hasLength(3)); // User 'Hi', Model 'Hello!', User 'How are you?' + // Verify roles and text expect(contents[0]['role'], equals('user')); expect(contents[1]['role'], equals('model')); expect(contents[2]['role'], equals('user')); - + expect(contents[0]['parts'][0]['text'], equals('Hi')); expect(contents[1]['parts'][0]['text'], equals('Hello!')); expect(contents[2]['parts'][0]['text'], equals('How are you?')); diff --git a/tests/integration_test/firebase_ai/firebase_ai_response_parsing_e2e_test.dart b/tests/integration_test/firebase_ai/firebase_ai_response_parsing_e2e_test.dart index fe0b91644945..be4ed70ab8eb 100644 --- a/tests/integration_test/firebase_ai/firebase_ai_response_parsing_e2e_test.dart +++ b/tests/integration_test/firebase_ai/firebase_ai_response_parsing_e2e_test.dart @@ -46,7 +46,7 @@ void main() { if (treeResponse.statusCode == 403 || treeResponse.statusCode == 429) { // ignore: avoid_print print( - 'Skipping test: Failed to fetch tree due to rate limit (status ${treeResponse.statusCode})', + 'Skipping test: Failed to fetch tree due to rate limit (status ${treeResponse.statusCode})', ); return; } @@ -74,7 +74,7 @@ void main() { final isVertex = path.contains('vertexai'); final serializer = - isVertex ? VertexSerialization() : DeveloperSerialization(); + isVertex ? AgentPlatformSerialization() : DeveloperSerialization(); try { if (path.contains('total-tokens') || path.contains('token')) { From 36f537c0d220c0b0b1bfef4565291af0fed00d37 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Mon, 20 Jul 2026 17:14:48 -0700 Subject: [PATCH 2/4] Update test and example --- .../firebase_ai/example/lib/main.dart | 55 +++--- .../example/lib/pages/bidi_page.dart | 8 +- .../example/lib/pages/chat_page.dart | 8 +- .../lib/pages/function_calling_page.dart | 8 +- .../example/lib/pages/grounding_page.dart | 8 +- .../lib/pages/image_generation_page.dart | 9 +- .../lib/pages/integration_test_page.dart | 39 ++-- .../lib/pages/server_template_page.dart | 8 +- .../example/lib/pages/tts_page.dart | 8 +- .../firebase_ai/lib/src/firebase_ai.dart | 2 + .../test/firebase_vertexai_test.dart | 173 +++++++++++++----- 11 files changed, 204 insertions(+), 122 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/example/lib/main.dart b/packages/firebase_ai/firebase_ai/example/lib/main.dart index 13a234dae379..a5cf530d46ab 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/main.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/main.dart @@ -49,7 +49,7 @@ class GenerativeAISample extends StatefulWidget { } class _GenerativeAISampleState extends State { - bool _useVertexBackend = false; + bool _useAgentPlatform = false; late GenerativeModel _currentModel; static final ThemeData _darkTheme = ThemeData( @@ -64,14 +64,15 @@ class _GenerativeAISampleState extends State { void initState() { super.initState(); - _initializeModel(_useVertexBackend); + _initializeModel(_useAgentPlatform); } void _initializeModel(bool useVertexBackend) { if (useVertexBackend) { - final vertexInstance = FirebaseAI.vertexAI(location: 'global'); + final agentPlatformInstance = + FirebaseAI.agentPlatform(location: 'global'); _currentModel = - vertexInstance.generativeModel(model: 'gemini-3.1-flash-lite'); + agentPlatformInstance.generativeModel(model: 'gemini-3.1-flash-lite'); } else { final googleAI = FirebaseAI.googleAI(); _currentModel = googleAI.generativeModel(model: 'gemini-3.1-flash-lite'); @@ -80,24 +81,24 @@ class _GenerativeAISampleState extends State { void _toggleBackend(bool value) { setState(() { - _useVertexBackend = value; + _useAgentPlatform = value; }); - _initializeModel(_useVertexBackend); + _initializeModel(_useAgentPlatform); } @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter + ${_useVertexBackend ? 'Vertex AI' : 'Google AI'}', + title: 'Flutter + ${_useAgentPlatform ? 'Agent Platform' : 'Google AI'}', debugShowCheckedModeBanner: false, themeMode: ThemeMode.dark, theme: _darkTheme, home: HomeScreen( key: ValueKey( - '${_useVertexBackend}_${_currentModel.hashCode}', + '${_useAgentPlatform}_${_currentModel.hashCode}', ), model: _currentModel, - useVertexBackend: _useVertexBackend, + useAgentPlatform: _useAgentPlatform, onBackendChanged: _toggleBackend, ), ); @@ -106,13 +107,13 @@ class _GenerativeAISampleState extends State { class HomeScreen extends StatefulWidget { final GenerativeModel model; - final bool useVertexBackend; + final bool useAgentPlatform; final ValueChanged onBackendChanged; const HomeScreen({ super.key, required this.model, - required this.useVertexBackend, + required this.useAgentPlatform, required this.onBackendChanged, }); @@ -133,13 +134,13 @@ class _HomeScreenState extends State { Widget _buildSelectedPage( int index, GenerativeModel currentModel, - bool useVertexBackend, + bool useAgentPlatform, ) { switch (index) { case 0: return ChatPage( title: 'Chat', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); case 1: return CapabilitiesPage( @@ -150,40 +151,40 @@ class _HomeScreenState extends State { // FunctionCallingPage initializes its own model as per original design return FunctionCallingPage( title: 'Function Calling', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); case 3: return ImageGenerationPage( title: 'Image Gen', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); case 4: return BidiPage( title: 'Live Stream', model: currentModel, - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); case 5: return ServerTemplatePage( title: 'Server Template', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); case 6: return GroundingPage( title: 'Grounding', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); case 7: return TTSPage( title: 'TTS Test', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); default: // Fallback to the first page in case of an unexpected index return ChatPage( title: 'Chat', - useVertexBackend: useVertexBackend, + useAgentPlatform: useAgentPlatform, ); } } @@ -193,7 +194,7 @@ class _HomeScreenState extends State { return Scaffold( appBar: AppBar( title: Text( - 'Flutter + ${widget.useVertexBackend ? 'Vertex AI' : 'Google AI'}', + 'Flutter + ${widget.useAgentPlatform ? 'Agent Platform' : 'Google AI'}', ), actions: [ IconButton( @@ -217,13 +218,13 @@ class _HomeScreenState extends State { 'Google AI', style: TextStyle( fontSize: 12, - color: widget.useVertexBackend + color: widget.useAgentPlatform ? Theme.of(context).colorScheme.onSurface.withAlpha(180) : Theme.of(context).colorScheme.primary, ), ), Switch( - value: widget.useVertexBackend, + value: widget.useAgentPlatform, onChanged: widget.onBackendChanged, activeTrackColor: Colors.green.withAlpha(128), inactiveTrackColor: Colors.blueGrey.withAlpha(128), @@ -231,10 +232,10 @@ class _HomeScreenState extends State { inactiveThumbColor: Colors.blueGrey, ), Text( - 'Vertex AI', + 'Agent Platform', style: TextStyle( fontSize: 12, - color: widget.useVertexBackend + color: widget.useAgentPlatform ? Theme.of(context).colorScheme.primary : Theme.of(context) .colorScheme @@ -251,7 +252,7 @@ class _HomeScreenState extends State { child: _buildSelectedPage( _selectedIndex, widget.model, - widget.useVertexBackend, + widget.useAgentPlatform, ), ), bottomNavigationBar: BottomNavigationBar( @@ -259,7 +260,7 @@ class _HomeScreenState extends State { selectedFontSize: 10, unselectedFontSize: 9, selectedItemColor: Theme.of(context).colorScheme.primary, - unselectedItemColor: widget.useVertexBackend + unselectedItemColor: widget.useAgentPlatform ? Theme.of(context).colorScheme.onSurface.withAlpha(180) : Colors.grey, items: const [ diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart index 56c7e950d0ce..fd81fd25ae0f 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart @@ -184,7 +184,7 @@ class BidiSessionController extends ChangeNotifier { ]; _liveModel = useVertexBackend - ? FirebaseAI.vertexAI().liveGenerativeModel( + ? FirebaseAI.agentPlatform().liveGenerativeModel( model: 'gemini-live-2.5-flash-preview-native-audio-09-2025', liveGenerationConfig: config, tools: tools, @@ -561,12 +561,12 @@ class BidiPage extends StatefulWidget { super.key, required this.title, required this.model, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; final GenerativeModel model; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _BidiPageState(); @@ -583,7 +583,7 @@ class _BidiPageState extends State { super.initState(); _controller = BidiSessionController( model: widget.model, - useVertexBackend: widget.useVertexBackend, + useVertexBackend: widget.useAgentPlatform, onShowError: _showError, onScrollDown: _scrollDown, ); diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart index 6562420bbdc4..572968688d79 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart @@ -20,11 +20,11 @@ class ChatPage extends StatefulWidget { const ChatPage({ super.key, required this.title, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _ChatPageState(); @@ -52,8 +52,8 @@ class _ChatPageState extends State { ? ThinkingConfig.withThinkingLevel(ThinkingLevel.medium) : null, ); - if (widget.useVertexBackend) { - _model = FirebaseAI.vertexAI(location: 'global').generativeModel( + if (widget.useAgentPlatform) { + _model = FirebaseAI.agentPlatform().generativeModel( model: 'gemini-3.1-flash-lite', generationConfig: generationConfig, ); diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart index b6db853772ee..a18bba00f476 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart @@ -22,11 +22,11 @@ class FunctionCallingPage extends StatefulWidget { const FunctionCallingPage({ super.key, required this.title, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _FunctionCallingPageState(); @@ -235,8 +235,8 @@ class _FunctionCallingPageState extends State { : null, ); - final aiClient = widget.useVertexBackend - ? FirebaseAI.vertexAI(location: 'global') + final aiClient = widget.useAgentPlatform + ? FirebaseAI.agentPlatform() : FirebaseAI.googleAI(); _functionCallModel = aiClient.generativeModel( diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart index 68e52d5b5fe9..f8d8315bab92 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart @@ -20,11 +20,11 @@ class GroundingPage extends StatefulWidget { const GroundingPage({ super.key, required this.title, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _GroundingPageState(); @@ -73,8 +73,8 @@ class _GroundingPageState extends State { } } - final aiProvider = widget.useVertexBackend - ? FirebaseAI.vertexAI(location: 'global') + final aiProvider = widget.useAgentPlatform + ? FirebaseAI.agentPlatform() : FirebaseAI.googleAI(); _model = aiProvider.generativeModel( diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart index 6206760bdfb1..8511cb6c72af 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart @@ -22,11 +22,11 @@ class ImageGenerationPage extends StatefulWidget { const ImageGenerationPage({ super.key, required this.title, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _ImageGenerationPageState(); @@ -49,8 +49,9 @@ class _ImageGenerationPageState extends State { } void _initializeModel() { - final aiClient = - widget.useVertexBackend ? FirebaseAI.vertexAI() : FirebaseAI.googleAI(); + final aiClient = widget.useAgentPlatform + ? FirebaseAI.agentPlatform() + : FirebaseAI.googleAI(); _model = aiClient.generativeModel( model: 'gemini-2.5-flash-image', diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart index 0efd521eb7e2..172b7a96cdf6 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart @@ -49,7 +49,7 @@ class TestItem { final String description; final Future Function(FirebaseAI provider, TestLogger logger) run; TestResult googleAIResult; - TestResult vertexAIResult; + TestResult agentPlatformResult; TestItem({ required this.id, @@ -57,7 +57,7 @@ class TestItem { required this.description, required this.run, }) : googleAIResult = TestResult.pending(), - vertexAIResult = TestResult.pending(); + agentPlatformResult = TestResult.pending(); } class TestLogger { @@ -636,15 +636,14 @@ class _IntegrationTestPageState extends State { ]; } - Future _runTestItem(TestItem item, bool isVertex) async { - final provider = isVertex - ? FirebaseAI.vertexAI(location: 'global') - : FirebaseAI.googleAI(); + Future _runTestItem(TestItem item, bool isAgentPlatform) async { + final provider = + isAgentPlatform ? FirebaseAI.agentPlatform() : FirebaseAI.googleAI(); final logger = TestLogger(); setState(() { - if (isVertex) { - item.vertexAIResult = + if (isAgentPlatform) { + item.agentPlatformResult = TestResult(status: TestStatus.running, logs: 'Running...'); } else { item.googleAIResult = @@ -654,12 +653,12 @@ class _IntegrationTestPageState extends State { try { logger.log( - 'Starting execution for ${item.name} (${isVertex ? 'Vertex AI' : 'Google AI'})...', + 'Starting execution for ${item.name} (${isAgentPlatform ? 'Agent Platform' : 'Google AI'})...', ); final result = await item.run(provider, logger); setState(() { - if (isVertex) { - item.vertexAIResult = result; + if (isAgentPlatform) { + item.agentPlatformResult = result; } else { item.googleAIResult = result; } @@ -672,8 +671,8 @@ class _IntegrationTestPageState extends State { logs: logger.toString(), errorMessage: e.toString(), ); - if (isVertex) { - item.vertexAIResult = failResult; + if (isAgentPlatform) { + item.agentPlatformResult = failResult; } else { item.googleAIResult = failResult; } @@ -689,7 +688,7 @@ class _IntegrationTestPageState extends State { _progress = 0; for (final item in _testCases) { item.googleAIResult = TestResult.pending(); - item.vertexAIResult = TestResult.pending(); + item.agentPlatformResult = TestResult.pending(); } }); @@ -895,7 +894,7 @@ class _IntegrationTestPageState extends State { final googleAIResults = _testCases.map((item) => item.googleAIResult).toList(); final vertexAIResults = - _testCases.map((item) => item.vertexAIResult).toList(); + _testCases.map((item) => item.agentPlatformResult).toList(); return Scaffold( appBar: AppBar( @@ -942,7 +941,7 @@ class _IntegrationTestPageState extends State { const SizedBox(width: 8), Expanded( child: _buildProviderSummary( - 'Vertex AI Suite', + 'Agent Platform Suite', vertexAIResults, ), ), @@ -992,13 +991,13 @@ class _IntegrationTestPageState extends State { Row( children: [ const Text( - 'V: ', + 'AP: ', style: TextStyle( fontSize: 10, color: Colors.grey, ), ), - _buildStatusBadge(item.vertexAIResult), + _buildStatusBadge(item.agentPlatformResult), ], ), ], @@ -1020,8 +1019,8 @@ class _IntegrationTestPageState extends State { const SizedBox(width: 8), Expanded( child: _buildLogsConsole( - 'Vertex AI Details', - item.vertexAIResult, + 'Agent Platform Details', + item.agentPlatformResult, ), ), ], diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart index ad351e4778c7..d38bdb9fe1eb 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart @@ -22,11 +22,11 @@ class ServerTemplatePage extends StatefulWidget { const ServerTemplatePage({ super.key, required this.title, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _ServerTemplatePageState(); @@ -54,10 +54,10 @@ class _ServerTemplatePageState extends State { } void _initializeServerTemplate() { - if (widget.useVertexBackend) { + if (widget.useAgentPlatform) { _templateGenerativeModel = // ignore: experimental_member_use - FirebaseAI.vertexAI(location: 'global').templateGenerativeModel(); + FirebaseAI.agentPlatform().templateGenerativeModel(); } else { _templateGenerativeModel = // ignore: experimental_member_use diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart index ed3393d7dcbb..ee00af84b4fd 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart @@ -25,11 +25,11 @@ class TTSPage extends StatefulWidget { const TTSPage({ super.key, required this.title, - required this.useVertexBackend, + required this.useAgentPlatform, }); final String title; - final bool useVertexBackend; + final bool useAgentPlatform; @override State createState() => _TTSPageState(); @@ -156,8 +156,8 @@ class _TTSPageState extends State { // Use the preview model for TTS const modelName = 'gemini-3.1-flash-tts-preview'; final GenerativeModel model; - if (widget.useVertexBackend) { - model = FirebaseAI.vertexAI().generativeModel( + if (widget.useAgentPlatform) { + model = FirebaseAI.agentPlatform().generativeModel( model: modelName, generationConfig: config, ); diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index 3781cba23bb4..d3520a7f22af 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -119,6 +119,8 @@ class FirebaseAI extends FirebasePlugin { FirebaseAI newInstance = FirebaseAI._( app: app, location: location, + appCheck: app.getService(), + auth: app.getService(), useAgentPlatform: true, useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens ?? false, ); diff --git a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart index 52fab592b2f5..166cd3ff6939 100644 --- a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart +++ b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart @@ -66,65 +66,144 @@ void main() { ); }); - test('Singleton behavior', () { - final instance1 = FirebaseAI.vertexAI(); - final instance2 = FirebaseAI.vertexAI(app: app); - expect(identical(instance1, instance2), isTrue); - }); + group('agentPlatform tests', () { + test('Singleton behavior', () { + final instance1 = FirebaseAI.agentPlatform(); + final instance2 = FirebaseAI.agentPlatform(app: app); + expect(identical(instance1, instance2), isTrue); + }); - test('Instance creation with defaults', () { - final vertexAI = FirebaseAI.vertexAI(app: app); - expect(vertexAI.app, equals(app)); - expect(vertexAI.location, equals('us-central1')); - }); + test('Instance creation with defaults', () { + final agentPlatform = FirebaseAI.agentPlatform(app: app); + expect(agentPlatform.app, equals(app)); + expect(agentPlatform.location, equals('global')); + }); - test('Instance creation with custom', () { - final vertexAI = FirebaseAI.vertexAI( + test('Instance creation with custom location', () { + final agentPlatform = FirebaseAI.agentPlatform( app: customApp, - appCheck: customAppCheck, - location: 'custom-location'); - expect(vertexAI.app, equals(customApp)); - expect(vertexAI.appCheck, equals(customAppCheck)); - expect(vertexAI.location, equals('custom-location')); - }); + location: 'custom-location', + ); + expect(agentPlatform.app, equals(customApp)); + expect(agentPlatform.appCheck, equals(customAppCheck)); + expect(agentPlatform.location, equals('custom-location')); + }); - test('generativeModel creation', () { - final vertexAI = FirebaseAI.vertexAI(); + test('generativeModel creation', () { + final agentPlatform = FirebaseAI.agentPlatform(); - final model = vertexAI.generativeModel( - model: 'gemini-pro', - generationConfig: GenerationConfig(maxOutputTokens: 1024), - systemInstruction: Content.system('You are a helpful assistant.'), - ); + final model = agentPlatform.generativeModel( + model: 'gemini-pro', + generationConfig: GenerationConfig(maxOutputTokens: 1024), + systemInstruction: Content.system('You are a helpful assistant.'), + ); - expect(model, isA()); - }); + expect(model, isA()); + }); - test('Instance creation with useLimitedUseAppCheckTokens', () { - final vertexAIAppCheck = FirebaseAI.vertexAI( - app: limitTokenApp, - appCheck: limitTokenAppCheck, - location: 'limit-token-location', - useLimitedUseAppCheckTokens: true, - ); - expect(vertexAIAppCheck.app, equals(limitTokenApp)); - expect(vertexAIAppCheck.appCheck, equals(limitTokenAppCheck)); - expect(vertexAIAppCheck.location, equals('limit-token-location')); - expect(vertexAIAppCheck.useLimitedUseAppCheckTokens, true); - }); + test('Instance creation with useLimitedUseAppCheckTokens', () { + final agentPlatform = FirebaseAI.agentPlatform( + app: limitTokenApp, + location: 'limit-token-location', + useLimitedUseAppCheckTokens: true, + ); + expect(agentPlatform.app, equals(limitTokenApp)); + expect(agentPlatform.appCheck, equals(limitTokenAppCheck)); + expect(agentPlatform.location, equals('limit-token-location')); + expect(agentPlatform.useLimitedUseAppCheckTokens, true); + }); + + test('Instance creation with auto-injected AppCheck', () { + final agentPlatform = FirebaseAI.agentPlatform(app: customApp); + + expect(agentPlatform.app, equals(customApp)); + expect(agentPlatform.appCheck, equals(customAppCheck)); + }); - test('Instance creation with auto-injected AppCheck', () { - final vertexAI = FirebaseAI.vertexAI(app: customApp); + test('Instance creation with auto-injected Auth', () { + final agentPlatform = FirebaseAI.agentPlatform(app: customApp); - expect(vertexAI.app, equals(customApp)); - expect(vertexAI.appCheck, equals(customAppCheck)); + expect(agentPlatform.app, equals(customApp)); + expect(agentPlatform.auth, equals(customAuth)); + }); }); - test('Instance creation with auto-injected Auth', () { - final vertexAI = FirebaseAI.vertexAI(app: customApp); + group('Deprecated vertexAI tests', () { + // ignore: deprecated_member_use_from_same_package + test('Singleton behavior', () { + // ignore: deprecated_member_use_from_same_package + final instance1 = FirebaseAI.vertexAI(); + // ignore: deprecated_member_use_from_same_package + final instance2 = FirebaseAI.vertexAI(app: app); + expect(identical(instance1, instance2), isTrue); + }); + + // ignore: deprecated_member_use_from_same_package + test('Instance creation with defaults', () { + // ignore: deprecated_member_use_from_same_package + final vertexAI = FirebaseAI.vertexAI(app: app); + expect(vertexAI.app, equals(app)); + expect(vertexAI.location, equals('us-central1')); + }); + + // ignore: deprecated_member_use_from_same_package + test('Instance creation with custom', () { + // ignore: deprecated_member_use_from_same_package + final vertexAI = FirebaseAI.vertexAI( + app: customApp, + appCheck: customAppCheck, + location: 'custom-location'); + expect(vertexAI.app, equals(customApp)); + expect(vertexAI.appCheck, equals(customAppCheck)); + expect(vertexAI.location, equals('custom-location')); + }); + + // ignore: deprecated_member_use_from_same_package + test('generativeModel creation', () { + // ignore: deprecated_member_use_from_same_package + final vertexAI = FirebaseAI.vertexAI(); - expect(vertexAI.app, equals(customApp)); - expect(vertexAI.auth, equals(customAuth)); + final model = vertexAI.generativeModel( + model: 'gemini-pro', + generationConfig: GenerationConfig(maxOutputTokens: 1024), + systemInstruction: Content.system('You are a helpful assistant.'), + ); + + expect(model, isA()); + }); + + // ignore: deprecated_member_use_from_same_package + test('Instance creation with useLimitedUseAppCheckTokens', () { + // ignore: deprecated_member_use_from_same_package + final vertexAIAppCheck = FirebaseAI.vertexAI( + app: limitTokenApp, + appCheck: limitTokenAppCheck, + location: 'limit-token-location', + useLimitedUseAppCheckTokens: true, + ); + expect(vertexAIAppCheck.app, equals(limitTokenApp)); + expect(vertexAIAppCheck.appCheck, equals(limitTokenAppCheck)); + expect(vertexAIAppCheck.location, equals('limit-token-location')); + expect(vertexAIAppCheck.useLimitedUseAppCheckTokens, true); + }); + + // ignore: deprecated_member_use_from_same_package + test('Instance creation with auto-injected AppCheck', () { + // ignore: deprecated_member_use_from_same_package + final vertexAI = FirebaseAI.vertexAI(app: customApp); + + expect(vertexAI.app, equals(customApp)); + expect(vertexAI.appCheck, equals(customAppCheck)); + }); + + // ignore: deprecated_member_use_from_same_package + test('Instance creation with auto-injected Auth', () { + // ignore: deprecated_member_use_from_same_package + final vertexAI = FirebaseAI.vertexAI(app: customApp); + + expect(vertexAI.app, equals(customApp)); + expect(vertexAI.auth, equals(customAuth)); + }); }); test('generativeModel creation with Grounding tools', () { From c24973da6328433ef2020dde3ff4e62d4b071797 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Mon, 20 Jul 2026 17:19:41 -0700 Subject: [PATCH 3/4] fix one test with error message change --- .../firebase_ai/firebase_ai/test/response_parsing_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart b/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart index 8d94de1b895e..28868a31a496 100644 --- a/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart +++ b/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart @@ -192,7 +192,7 @@ void main() { (e) => e.message, 'message', startsWith( - 'The Vertex AI in Firebase SDK requires the Vertex AI in Firebase API'), + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console'), ), ), ); From 41933ec389151198f6748d6ef36dfcd6f6a9d7ac Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Mon, 20 Jul 2026 19:49:06 -0700 Subject: [PATCH 4/4] address review comments and fix test --- .../firebase_ai/firebase_ai/lib/src/firebase_ai.dart | 2 +- packages/firebase_ai/firebase_ai/test/error_test.dart | 10 +++------- .../firebase_ai/firebase_ai_mock_test.dart | 6 ++++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index d3520a7f22af..29e6db0f75ba 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -63,7 +63,7 @@ class FirebaseAI extends FirebasePlugin { /// If [app] is not provided, the default Firebase app will be used. /// If pass in [appCheck], request session will get protected from abusing. @Deprecated( - 'Use agentPlatform() instead. Note that the default location is now "global" instead of "us-central1"') + 'Use agentPlatform() instead. Note that the default location for agentPlatform is now "global" instead of "us-central1"') static FirebaseAI vertexAI({ FirebaseApp? app, @Deprecated( diff --git a/packages/firebase_ai/firebase_ai/test/error_test.dart b/packages/firebase_ai/firebase_ai/test/error_test.dart index ead4f25ea909..368d71268b5f 100644 --- a/packages/firebase_ai/firebase_ai/test/error_test.dart +++ b/packages/firebase_ai/firebase_ai/test/error_test.dart @@ -37,10 +37,8 @@ void main() { final exception = ServiceApiNotEnabled('projects/test-project'); expect( exception.message, - 'The Vertex AI in Firebase SDK requires the Vertex AI in Firebase API ' - '(`firebasevertexai.googleapis.com`) to be enabled in your Firebase project. Enable this API ' - 'by visiting the Firebase Console at ' - 'https://console.firebase.google.com/project/test-project/ailogic ' + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' + 'https://console.firebase.google.com/project/test_project/ailogic ' 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' 'action to propagate to our systems and then retry.'); }); @@ -140,9 +138,7 @@ void main() { expect(exception, isInstanceOf()); expect( (exception as ServiceApiNotEnabled).message, - 'The Vertex AI in Firebase SDK requires the Vertex AI in Firebase API ' - '(`firebasevertexai.googleapis.com`) to be enabled in your Firebase project. Enable this API ' - 'by visiting the Firebase Console at ' + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' 'https://console.firebase.google.com/project/my-project-id/ailogic ' 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' 'action to propagate to our systems and then retry.'); diff --git a/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart b/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart index 2ad21be93833..119def4620a5 100644 --- a/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart +++ b/tests/integration_test/firebase_ai/firebase_ai_mock_test.dart @@ -200,8 +200,10 @@ void main() { expect(secondRequest, contains('contents')); final contents = secondRequest['contents']! as List; - expect(contents, - hasLength(3)); // User 'Hi', Model 'Hello!', User 'How are you?' + expect( + contents, + hasLength(3), + ); // User 'Hi', Model 'Hello!', User 'How are you?' // Verify roles and text expect(contents[0]['role'], equals('user'));