Skip to content

feat(firebaseai): add responseJsonSchema to GenerationConfig #17564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions packages/firebase_ai/firebase_ai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.1.0

- **FEAT**(firebase_ai): Add support for `responseJsonSchema` in the [GenerationConfig].

## 3.0.0

> Note: This release has breaking changes.
Expand Down
17 changes: 16 additions & 1 deletion packages/firebase_ai/firebase_ai/lib/src/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -998,8 +998,10 @@ final class GenerationConfig extends BaseGenerationConfig {
super.responseModalities,
this.responseMimeType,
this.responseSchema,
this.responseJsonSchema,
this.thinkingConfig,
});
}) : assert(responseSchema == null || responseJsonSchema == null,
'responseSchema and responseJsonSchema cannot both be set.');

/// The set of character sequences (up to 5) that will stop output generation.
///
Expand All @@ -1020,6 +1022,17 @@ final class GenerationConfig extends BaseGenerationConfig {
/// a schema; currently this is limited to `application/json`.
final Schema? responseSchema;

/// The response schema as a JSON string.
///
/// - Note: This only applies when the [responseMimeType] supports a schema;
/// currently this is limited to `application/json`.
///
/// This schema can include more advanced features of JSON than the [Schema]
/// class supports. See [the Gemini
/// documentation](https://ai.google.dev/gemini-api/docs/structured-output#json-schema)
/// about the limitations of this feature.
final String? responseJsonSchema;

/// Config for thinking features.
///
/// An error will be returned if this field is set for models that don't
Expand All @@ -1036,6 +1049,8 @@ final class GenerationConfig extends BaseGenerationConfig {
'responseMimeType': responseMimeType,
if (responseSchema case final responseSchema?)
'responseSchema': responseSchema.toJson(),
if (responseJsonSchema case final responseJsonSchema?)
'responseJsonSchema': responseJsonSchema,
if (thinkingConfig case final thinkingConfig?)
'thinkingConfig': thinkingConfig.toJson(),
};
Expand Down
4 changes: 2 additions & 2 deletions packages/firebase_ai/firebase_ai/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: firebase_ai
description: Firebase AI SDK.
version: 3.0.0
version: 3.1.0
homepage: https://firebase.google.com/docs/vertex-ai/get-started?platform=flutter
topics:
- firebase
Expand All @@ -17,7 +17,7 @@ platforms:

environment:
sdk: '>=3.2.0 <4.0.0'
flutter: ">=3.16.0"
flutter: '>=3.16.0'

dependencies:
firebase_app_check: ^0.4.0
Expand Down
23 changes: 23 additions & 0 deletions packages/firebase_ai/firebase_ai/test/api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,29 @@ void main() {
});
});

test('GenerationConfig toJson with responseJsonSchema', () {
const jsonSchema = '{"type": "string", "title": "MyString"}';
final config = GenerationConfig(
responseMimeType: 'application/json',
responseJsonSchema: jsonSchema,
);
expect(config.toJson(), {
'responseMimeType': 'application/json',
'responseJsonSchema': jsonSchema,
});
});

test(
'throws assertion if both responseSchema and responseJsonSchema are provided',
() {
final schema = Schema.object(properties: {});
const jsonSchema = '{"type": "string", "title": "MyString"}';
expect(
() => GenerationConfig(
responseSchema: schema, responseJsonSchema: jsonSchema),
throwsA(isA<AssertionError>()));
});

test('GenerationConfig toJson with empty stopSequences (omitted)', () {
final config = GenerationConfig(stopSequences: []);
expect(config.toJson(), {}); // Empty list for stopSequences is omitted
Expand Down