From 0401c963de8d87f8779fefc539389b1fb1579902 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 16:21:03 +0100 Subject: [PATCH 01/19] initial --- firebase_functions_genkit/.gitignore | 7 ++++ firebase_functions_genkit/CHANGELOG.md | 3 ++ firebase_functions_genkit/README.md | 39 +++++++++++++++++++ .../analysis_options.yaml | 30 ++++++++++++++ .../firebase_functions_genkit_example.dart | 6 +++ .../lib/firebase_functions_genkit.dart | 8 ++++ .../src/firebase_functions_genkit_base.dart | 26 +++++++++++++ firebase_functions_genkit/pubspec.yaml | 28 +++++++++++++ .../test/firebase_functions_genkit_test.dart | 16 ++++++++ 9 files changed, 163 insertions(+) create mode 100644 firebase_functions_genkit/.gitignore create mode 100644 firebase_functions_genkit/CHANGELOG.md create mode 100644 firebase_functions_genkit/README.md create mode 100644 firebase_functions_genkit/analysis_options.yaml create mode 100644 firebase_functions_genkit/example/firebase_functions_genkit_example.dart create mode 100644 firebase_functions_genkit/lib/firebase_functions_genkit.dart create mode 100644 firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart create mode 100644 firebase_functions_genkit/pubspec.yaml create mode 100644 firebase_functions_genkit/test/firebase_functions_genkit_test.dart diff --git a/firebase_functions_genkit/.gitignore b/firebase_functions_genkit/.gitignore new file mode 100644 index 0000000..3cceda5 --- /dev/null +++ b/firebase_functions_genkit/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/firebase_functions_genkit/CHANGELOG.md b/firebase_functions_genkit/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/firebase_functions_genkit/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/firebase_functions_genkit/README.md b/firebase_functions_genkit/README.md new file mode 100644 index 0000000..8831761 --- /dev/null +++ b/firebase_functions_genkit/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/firebase_functions_genkit/analysis_options.yaml b/firebase_functions_genkit/analysis_options.yaml new file mode 100644 index 0000000..dee8927 --- /dev/null +++ b/firebase_functions_genkit/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/firebase_functions_genkit/example/firebase_functions_genkit_example.dart b/firebase_functions_genkit/example/firebase_functions_genkit_example.dart new file mode 100644 index 0000000..8f04a22 --- /dev/null +++ b/firebase_functions_genkit/example/firebase_functions_genkit_example.dart @@ -0,0 +1,6 @@ +import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; + +void main() { + var awesome = Awesome(); + print('awesome: ${awesome.isAwesome}'); +} diff --git a/firebase_functions_genkit/lib/firebase_functions_genkit.dart b/firebase_functions_genkit/lib/firebase_functions_genkit.dart new file mode 100644 index 0000000..2031988 --- /dev/null +++ b/firebase_functions_genkit/lib/firebase_functions_genkit.dart @@ -0,0 +1,8 @@ +/// Support for doing something awesome. +/// +/// More dartdocs go here. +library; + +export 'src/firebase_functions_genkit_base.dart'; + +// TODO: Export any libraries intended for clients of this package. diff --git a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart new file mode 100644 index 0000000..3e2987f --- /dev/null +++ b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart @@ -0,0 +1,26 @@ +import 'package:firebase_functions/firebase_functions.dart'; +import 'package:firebase_functions/src/firebase.dart'; +import 'package:genkit/client.dart' show ActionStream; +import 'package:genkit/src/core/flow.dart'; +// ignore: experimental_member_use +import 'package:meta/meta.dart' show mustBeConst; + +extension GenkitExt on HttpsNamespace { + void onCallGenkit( + // Must repeat the name + // ignore: experimental_member_use + @mustBeConst String name, + Flow flow, + ) { + // ignore: non_const_argument_for_const_parameter + onCall(name: name, (request, response) async { + if (!request.acceptsStreaming) { + return CallableResult(await flow.run(request.data)); + } + + final actionStream = flow.stream(request.data); + actionStream.forEach((chunk) => response.sendChunk(chunk)); + return CallableResult(actionStream.result); + }); + } +} diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml new file mode 100644 index 0000000..97ffabe --- /dev/null +++ b/firebase_functions_genkit/pubspec.yaml @@ -0,0 +1,28 @@ +name: firebase_functions_genkit +description: A starting point for Dart libraries or applications. +version: 1.0.0 +# repository: https://github.com/my_org/my_repo + +environment: + sdk: ^3.12.0-17.0.dev + +# Add regular dependencies here. +dependencies: + firebase_functions: + path: ../ + genkit: + git: + url: https://github.com/genkit-ai/genkit-dart/ + path: packages/genkit + meta: ^1.18.0 + +dependency_overrides: + source_gen: ^4.1.0 + build: ^4.0.4 + analyzer: ^10.0.1 + protobuf: ^6.0.0 + intl: ^0.20.2 + +dev_dependencies: + lints: ^6.0.0 + test: ^1.25.6 diff --git a/firebase_functions_genkit/test/firebase_functions_genkit_test.dart b/firebase_functions_genkit/test/firebase_functions_genkit_test.dart new file mode 100644 index 0000000..b421e83 --- /dev/null +++ b/firebase_functions_genkit/test/firebase_functions_genkit_test.dart @@ -0,0 +1,16 @@ +import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; +import 'package:test/test.dart'; + +void main() { + group('A group of tests', () { + final awesome = Awesome(); + + setUp(() { + // Additional setup goes here. + }); + + test('First Test', () { + expect(awesome.isAwesome, isTrue); + }); + }); +} From 42633154c23e4775bb796d233dc8f1fe0d081db5 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 16:23:19 +0100 Subject: [PATCH 02/19] sdk --- firebase_functions_genkit/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index 97ffabe..e15d0a1 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 # repository: https://github.com/my_org/my_repo environment: - sdk: ^3.12.0-17.0.dev + sdk: ^3.11.0 # Add regular dependencies here. dependencies: From f5106545c024207f41f243e5f790bb656e92c10d Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 18:00:22 +0100 Subject: [PATCH 03/19] add example --- firebase_functions_genkit/example/README.md | 2 ++ .../example/bin/example.dart | 31 +++++++++++++++++++ .../firebase_functions_genkit_example.dart | 6 ---- .../example/pubspec.yaml | 25 +++++++++++++++ .../lib/firebase_functions_genkit.dart | 7 ----- .../src/firebase_functions_genkit_base.dart | 26 ++++++++-------- firebase_functions_genkit/pubspec.yaml | 3 -- .../test/firebase_functions_genkit_test.dart | 7 +---- 8 files changed, 72 insertions(+), 35 deletions(-) create mode 100644 firebase_functions_genkit/example/README.md create mode 100644 firebase_functions_genkit/example/bin/example.dart delete mode 100644 firebase_functions_genkit/example/firebase_functions_genkit_example.dart create mode 100644 firebase_functions_genkit/example/pubspec.yaml diff --git a/firebase_functions_genkit/example/README.md b/firebase_functions_genkit/example/README.md new file mode 100644 index 0000000..3816eca --- /dev/null +++ b/firebase_functions_genkit/example/README.md @@ -0,0 +1,2 @@ +A sample command-line application with an entrypoint in `bin/`, library code +in `lib/`, and example unit test in `test/`. diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart new file mode 100644 index 0000000..f9132a7 --- /dev/null +++ b/firebase_functions_genkit/example/bin/example.dart @@ -0,0 +1,31 @@ +import 'package:firebase_functions/firebase_functions.dart'; +import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; +import 'package:genkit/genkit.dart'; +import 'package:genkit_google_genai/genkit_google_genai.dart'; +import 'package:schemantic/schemantic.dart'; + +const name = 'jokeTeller'; + +void main(List args) { + final gemini = googleAI(); + final ai = Genkit(plugins: [gemini]); + Flow flow = ai.defineFlow( + name: name, + inputType: stringType(), + outputType: stringType(), + streamType: stringType(), + fn: (jokeType, context) async { + final prompt = 'Tell me a $jokeType joke.'; + final stream = ai.generateStream( + model: gemini.model('gemini-2.5-flash'), + prompt: prompt, + ); + await stream.forEach((chunk) => context.sendChunk(chunk.text)); + return stream.result.text; + }, + ); + + fireUp(args, (firebase) { + firebase.https.onCallGenkit(name: name, flow: flow); + }); +} diff --git a/firebase_functions_genkit/example/firebase_functions_genkit_example.dart b/firebase_functions_genkit/example/firebase_functions_genkit_example.dart deleted file mode 100644 index 8f04a22..0000000 --- a/firebase_functions_genkit/example/firebase_functions_genkit_example.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; - -void main() { - var awesome = Awesome(); - print('awesome: ${awesome.isAwesome}'); -} diff --git a/firebase_functions_genkit/example/pubspec.yaml b/firebase_functions_genkit/example/pubspec.yaml new file mode 100644 index 0000000..0f33252 --- /dev/null +++ b/firebase_functions_genkit/example/pubspec.yaml @@ -0,0 +1,25 @@ +name: example + +environment: + sdk: ^3.11.0 + +dependencies: + firebase_functions_genkit: + path: ../ + genkit: ^0.10.0-dev.8 + genkit_google_genai: ^0.0.1-dev.8 + json_schema_builder: ^0.1.3 + schemantic: ^0.0.1-dev.9 + firebase_functions: + path: ../../ + +dev_dependencies: + lints: ^6.0.0 + test: ^1.29.0 + +dependency_overrides: + analyzer: ^10.0.1 + protobuf: ^6.0.0 + dart_firebase_admin: ^0.4.1 + googleapis_auth: ^1.3.0 + genkit: ^0.10.0-dev.2 \ No newline at end of file diff --git a/firebase_functions_genkit/lib/firebase_functions_genkit.dart b/firebase_functions_genkit/lib/firebase_functions_genkit.dart index 2031988..8900c52 100644 --- a/firebase_functions_genkit/lib/firebase_functions_genkit.dart +++ b/firebase_functions_genkit/lib/firebase_functions_genkit.dart @@ -1,8 +1 @@ -/// Support for doing something awesome. -/// -/// More dartdocs go here. -library; - export 'src/firebase_functions_genkit_base.dart'; - -// TODO: Export any libraries intended for clients of this package. diff --git a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart index 3e2987f..41e2595 100644 --- a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart +++ b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart @@ -1,26 +1,26 @@ import 'package:firebase_functions/firebase_functions.dart'; -import 'package:firebase_functions/src/firebase.dart'; -import 'package:genkit/client.dart' show ActionStream; -import 'package:genkit/src/core/flow.dart'; +import 'package:genkit/genkit.dart'; // ignore: experimental_member_use import 'package:meta/meta.dart' show mustBeConst; extension GenkitExt on HttpsNamespace { - void onCallGenkit( + void onCallGenkit({ // Must repeat the name // ignore: experimental_member_use - @mustBeConst String name, - Flow flow, - ) { + @mustBeConst required String name, + required Flow flow, + // ignore: experimental_member_use + @mustBeConst CallableOptions? options = const CallableOptions(), + }) { // ignore: non_const_argument_for_const_parameter - onCall(name: name, (request, response) async { - if (!request.acceptsStreaming) { + onCall(name: name, options: options, (request, response) async { + if (request.acceptsStreaming) { + final actionStream = flow.stream(request.data); + actionStream.forEach((chunk) => response.sendChunk(chunk)); + return CallableResult(actionStream.result); + } else { return CallableResult(await flow.run(request.data)); } - - final actionStream = flow.stream(request.data); - actionStream.forEach((chunk) => response.sendChunk(chunk)); - return CallableResult(actionStream.result); }); } } diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index e15d0a1..8434e70 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -17,11 +17,8 @@ dependencies: meta: ^1.18.0 dependency_overrides: - source_gen: ^4.1.0 - build: ^4.0.4 analyzer: ^10.0.1 protobuf: ^6.0.0 - intl: ^0.20.2 dev_dependencies: lints: ^6.0.0 diff --git a/firebase_functions_genkit/test/firebase_functions_genkit_test.dart b/firebase_functions_genkit/test/firebase_functions_genkit_test.dart index b421e83..7de0162 100644 --- a/firebase_functions_genkit/test/firebase_functions_genkit_test.dart +++ b/firebase_functions_genkit/test/firebase_functions_genkit_test.dart @@ -1,16 +1,11 @@ -import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; import 'package:test/test.dart'; void main() { group('A group of tests', () { - final awesome = Awesome(); - setUp(() { // Additional setup goes here. }); - test('First Test', () { - expect(awesome.isAwesome, isTrue); - }); + test('First Test', () {}); }); } From 41f85e316fdaf1235c256af12e6f6fd579fac9de Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 18:01:34 +0100 Subject: [PATCH 04/19] remove unused deps --- firebase_functions_genkit/example/pubspec.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/firebase_functions_genkit/example/pubspec.yaml b/firebase_functions_genkit/example/pubspec.yaml index 0f33252..ab113fe 100644 --- a/firebase_functions_genkit/example/pubspec.yaml +++ b/firebase_functions_genkit/example/pubspec.yaml @@ -8,15 +8,10 @@ dependencies: path: ../ genkit: ^0.10.0-dev.8 genkit_google_genai: ^0.0.1-dev.8 - json_schema_builder: ^0.1.3 schemantic: ^0.0.1-dev.9 firebase_functions: path: ../../ -dev_dependencies: - lints: ^6.0.0 - test: ^1.29.0 - dependency_overrides: analyzer: ^10.0.1 protobuf: ^6.0.0 From 02c51cbffaef39544512d7b4d36061d0adf98821 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 18:02:05 +0100 Subject: [PATCH 05/19] newline --- firebase_functions_genkit/example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase_functions_genkit/example/pubspec.yaml b/firebase_functions_genkit/example/pubspec.yaml index ab113fe..67299ef 100644 --- a/firebase_functions_genkit/example/pubspec.yaml +++ b/firebase_functions_genkit/example/pubspec.yaml @@ -17,4 +17,4 @@ dependency_overrides: protobuf: ^6.0.0 dart_firebase_admin: ^0.4.1 googleapis_auth: ^1.3.0 - genkit: ^0.10.0-dev.2 \ No newline at end of file + genkit: ^0.10.0-dev.2 From c7dc03bdf00dad522a2c4a016e56ed1484df3e5b Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 18:02:29 +0100 Subject: [PATCH 06/19] add readme --- firebase_functions_genkit/example/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/firebase_functions_genkit/example/README.md b/firebase_functions_genkit/example/README.md index 3816eca..c66feb0 100644 --- a/firebase_functions_genkit/example/README.md +++ b/firebase_functions_genkit/example/README.md @@ -1,2 +1 @@ -A sample command-line application with an entrypoint in `bin/`, library code -in `lib/`, and example unit test in `test/`. +Sample of creating a genkit flow and setting it up for an http trigger. \ No newline at end of file From 18fa4f4df1e4fc11bde59e8f25e9353d81ec9f42 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 18:03:11 +0100 Subject: [PATCH 07/19] fix --- firebase_functions_genkit/pubspec.yaml | 1 - .../test/firebase_functions_genkit_test.dart | 11 ----------- 2 files changed, 12 deletions(-) delete mode 100644 firebase_functions_genkit/test/firebase_functions_genkit_test.dart diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index 8434e70..aba2d05 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -22,4 +22,3 @@ dependency_overrides: dev_dependencies: lints: ^6.0.0 - test: ^1.25.6 diff --git a/firebase_functions_genkit/test/firebase_functions_genkit_test.dart b/firebase_functions_genkit/test/firebase_functions_genkit_test.dart deleted file mode 100644 index 7de0162..0000000 --- a/firebase_functions_genkit/test/firebase_functions_genkit_test.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:test/test.dart'; - -void main() { - group('A group of tests', () { - setUp(() { - // Additional setup goes here. - }); - - test('First Test', () {}); - }); -} From 7f743bb46f2c875cfd91bb5b9e58fbef370fbb0d Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 29 Jan 2026 18:03:49 +0100 Subject: [PATCH 08/19] add more readme --- firebase_functions_genkit/README.md | 40 ++--------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/firebase_functions_genkit/README.md b/firebase_functions_genkit/README.md index 8831761..b399a4c 100644 --- a/firebase_functions_genkit/README.md +++ b/firebase_functions_genkit/README.md @@ -1,39 +1,3 @@ - - -TODO: Put a short description of the package here that helps potential users -know whether this package might be useful for them. - -## Features - -TODO: List what your package can do. Maybe include images, gifs, or videos. - -## Getting started - -TODO: List prerequisites and provide or point to information on how to -start using the package. - -## Usage - -TODO: Include short and useful examples for package users. Add longer examples -to `/example` folder. - -```dart -const like = 'sample'; -``` - -## Additional information - -TODO: Tell users more about the package: where to find more information, how to -contribute to the package, how to file issues, what response they can expect -from the package authors, and more. +Not included in firebase functions itself for more flexibility and reduced deps. \ No newline at end of file From d3c06e394e416600095fcd563760a862fc4d4495 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 3 Feb 2026 14:19:52 +0100 Subject: [PATCH 09/19] fixes --- firebase_functions_genkit/example/bin/example.dart | 6 +++--- firebase_functions_genkit/pubspec.yaml | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index f9132a7..b6c1c80 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -11,9 +11,9 @@ void main(List args) { final ai = Genkit(plugins: [gemini]); Flow flow = ai.defineFlow( name: name, - inputType: stringType(), - outputType: stringType(), - streamType: stringType(), + inputSchema: stringSchema(), + outputSchema: stringSchema(), + streamSchema: stringSchema(), fn: (jokeType, context) async { final prompt = 'Tell me a $jokeType joke.'; final stream = ai.generateStream( diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index aba2d05..edc2e23 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -1,12 +1,13 @@ name: firebase_functions_genkit description: A starting point for Dart libraries or applications. -version: 1.0.0 -# repository: https://github.com/my_org/my_repo +version: 0.1.0 +repository: https://github.com/invertase/firebase-functions-dart + +publish_to: none environment: - sdk: ^3.11.0 + sdk: ^3.10.0 -# Add regular dependencies here. dependencies: firebase_functions: path: ../ @@ -14,11 +15,11 @@ dependencies: git: url: https://github.com/genkit-ai/genkit-dart/ path: packages/genkit - meta: ^1.18.0 + meta: ^1.18.1 dependency_overrides: analyzer: ^10.0.1 protobuf: ^6.0.0 dev_dependencies: - lints: ^6.0.0 + lints: ^6.1.0 From 1986765ad3d0efe212645b780d849a190a75d975 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 3 Feb 2026 14:58:09 +0100 Subject: [PATCH 10/19] add contextprovider --- .../lib/src/firebase_functions_genkit_base.dart | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart index 41e2595..7b2e7ef 100644 --- a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart +++ b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart @@ -11,15 +11,21 @@ extension GenkitExt on HttpsNamespace { required Flow flow, // ignore: experimental_member_use @mustBeConst CallableOptions? options = const CallableOptions(), + Map Function(CallableRequest)? contextProvider, }) { // ignore: non_const_argument_for_const_parameter onCall(name: name, options: options, (request, response) async { if (request.acceptsStreaming) { - final actionStream = flow.stream(request.data); + final actionStream = flow.stream( + request.data, + context: contextProvider?.call(request), + ); actionStream.forEach((chunk) => response.sendChunk(chunk)); return CallableResult(actionStream.result); } else { - return CallableResult(await flow.run(request.data)); + return CallableResult( + await flow.run(request.data, context: contextProvider?.call(request)), + ); } }); } From 0703d9d47588236124102f6ddf099590898218f2 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 3 Feb 2026 15:25:21 +0100 Subject: [PATCH 11/19] add contextprovider --- firebase_functions_genkit/example/bin/example.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index b6c1c80..bb221d8 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -26,6 +26,10 @@ void main(List args) { ); fireUp(args, (firebase) { - firebase.https.onCallGenkit(name: name, flow: flow); + firebase.https.onCallGenkit( + name: name, + flow: flow, + contextProvider: (context) => {'auth': context.auth?.token?['email']}, + ); }); } From 0a884bd9723ad5438b4da4bfd5dbbf73081f01e6 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 3 Feb 2026 15:30:17 +0100 Subject: [PATCH 12/19] add lints --- .../analysis_options.yaml | 40 +++++-------------- .../example/bin/example.dart | 2 +- .../example/pubspec.yaml | 8 ++-- .../src/firebase_functions_genkit_base.dart | 7 +++- firebase_functions_genkit/pubspec.yaml | 2 +- 5 files changed, 22 insertions(+), 37 deletions(-) diff --git a/firebase_functions_genkit/analysis_options.yaml b/firebase_functions_genkit/analysis_options.yaml index dee8927..5c13630 100644 --- a/firebase_functions_genkit/analysis_options.yaml +++ b/firebase_functions_genkit/analysis_options.yaml @@ -1,30 +1,10 @@ -# This file configures the static analysis results for your project (errors, -# warnings, and lints). -# -# This enables the 'recommended' set of lints from `package:lints`. -# This set helps identify many issues that may lead to problems when running -# or consuming Dart code, and enforces writing Dart using a single, idiomatic -# style and format. -# -# If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints -# (the recommended set includes the core lints). -# The core lints are also what is used by pub.dev for scoring packages. - -include: package:lints/recommended.yaml - -# Uncomment the following section to specify additional rules. - -# linter: -# rules: -# - camel_case_types - -# analyzer: -# exclude: -# - path/to/excluded/files/** - -# For more information about the core and recommended set of lints, see -# https://dart.dev/go/core-lints - -# For additional information about configuring this file, see -# https://dart.dev/guides/language/analysis-options +include: package:dart_flutter_team_lints/analysis_options.yaml + +linter: + rules: + - prefer_final_locals + - unnecessary_parenthesis + - prefer_expression_function_bodies + - document_ignores + - parameter_assignments + - prefer_final_in_for_each diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index bb221d8..4d4c73b 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -9,7 +9,7 @@ const name = 'jokeTeller'; void main(List args) { final gemini = googleAI(); final ai = Genkit(plugins: [gemini]); - Flow flow = ai.defineFlow( + final flow = ai.defineFlow( name: name, inputSchema: stringSchema(), outputSchema: stringSchema(), diff --git a/firebase_functions_genkit/example/pubspec.yaml b/firebase_functions_genkit/example/pubspec.yaml index 67299ef..fe31d23 100644 --- a/firebase_functions_genkit/example/pubspec.yaml +++ b/firebase_functions_genkit/example/pubspec.yaml @@ -4,17 +4,17 @@ environment: sdk: ^3.11.0 dependencies: + firebase_functions: + path: ../../ firebase_functions_genkit: path: ../ genkit: ^0.10.0-dev.8 genkit_google_genai: ^0.0.1-dev.8 schemantic: ^0.0.1-dev.9 - firebase_functions: - path: ../../ dependency_overrides: analyzer: ^10.0.1 - protobuf: ^6.0.0 dart_firebase_admin: ^0.4.1 - googleapis_auth: ^1.3.0 genkit: ^0.10.0-dev.2 + googleapis_auth: ^1.3.0 + protobuf: ^6.0.0 diff --git a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart index 7b2e7ef..f5077f6 100644 --- a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart +++ b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart @@ -1,5 +1,7 @@ import 'package:firebase_functions/firebase_functions.dart'; import 'package:genkit/genkit.dart'; + +/// It's experimental as we can't semver package:meta // ignore: experimental_member_use import 'package:meta/meta.dart' show mustBeConst; @@ -9,10 +11,13 @@ extension GenkitExt on HttpsNamespace { // ignore: experimental_member_use @mustBeConst required String name, required Flow flow, + + /// It's experimental as we can't semver package:meta // ignore: experimental_member_use @mustBeConst CallableOptions? options = const CallableOptions(), Map Function(CallableRequest)? contextProvider, }) { + /// This is why we restate the name in the params above // ignore: non_const_argument_for_const_parameter onCall(name: name, options: options, (request, response) async { if (request.acceptsStreaming) { @@ -20,7 +25,7 @@ extension GenkitExt on HttpsNamespace { request.data, context: contextProvider?.call(request), ); - actionStream.forEach((chunk) => response.sendChunk(chunk)); + await actionStream.forEach((chunk) => response.sendChunk(chunk)); return CallableResult(actionStream.result); } else { return CallableResult( diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index edc2e23..0dfa03b 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -22,4 +22,4 @@ dependency_overrides: protobuf: ^6.0.0 dev_dependencies: - lints: ^6.1.0 + dart_flutter_team_lints: ^3.5.2 From 8c3e8c78de1f992043221ebe179b58b8d33ca07d Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 3 Feb 2026 17:22:51 +0100 Subject: [PATCH 13/19] add ignore --- firebase_functions_genkit/example/bin/example.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index 4d4c73b..83a95e7 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -16,6 +16,8 @@ void main(List args) { streamSchema: stringSchema(), fn: (jokeType, context) async { final prompt = 'Tell me a $jokeType joke.'; + /// gemini.model does not have a generic type + // ignore: inference_failure_on_function_invocation final stream = ai.generateStream( model: gemini.model('gemini-2.5-flash'), prompt: prompt, From 519f708821ef199316fcf8c05cfcf3f3cc27b77b Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 3 Feb 2026 17:25:47 +0100 Subject: [PATCH 14/19] fix cl --- firebase_functions_genkit/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase_functions_genkit/CHANGELOG.md b/firebase_functions_genkit/CHANGELOG.md index effe43c..a0712a7 100644 --- a/firebase_functions_genkit/CHANGELOG.md +++ b/firebase_functions_genkit/CHANGELOG.md @@ -1,3 +1,3 @@ -## 1.0.0 +## 0.1.0 - Initial version. From e7158726bd8f4882da9d09d3907f8473e1d86990 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 14 Apr 2026 22:38:58 +0200 Subject: [PATCH 15/19] update --- .../example/bin/example.dart | 8 +++---- .../example/pubspec.yaml | 22 +++++++------------ .../src/firebase_functions_genkit_base.dart | 21 +++++++++++++----- firebase_functions_genkit/pubspec.yaml | 19 +++++++++------- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index 83a95e7..b127b4f 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -2,7 +2,6 @@ import 'package:firebase_functions/firebase_functions.dart'; import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; import 'package:genkit/genkit.dart'; import 'package:genkit_google_genai/genkit_google_genai.dart'; -import 'package:schemantic/schemantic.dart'; const name = 'jokeTeller'; @@ -11,11 +10,12 @@ void main(List args) { final ai = Genkit(plugins: [gemini]); final flow = ai.defineFlow( name: name, - inputSchema: stringSchema(), - outputSchema: stringSchema(), - streamSchema: stringSchema(), + inputSchema: .string(), + outputSchema: .string(), + streamSchema: .string(), fn: (jokeType, context) async { final prompt = 'Tell me a $jokeType joke.'; + /// gemini.model does not have a generic type // ignore: inference_failure_on_function_invocation final stream = ai.generateStream( diff --git a/firebase_functions_genkit/example/pubspec.yaml b/firebase_functions_genkit/example/pubspec.yaml index fe31d23..25c3e79 100644 --- a/firebase_functions_genkit/example/pubspec.yaml +++ b/firebase_functions_genkit/example/pubspec.yaml @@ -1,20 +1,14 @@ name: example +resolution: workspace + environment: - sdk: ^3.11.0 + sdk: ^3.10.0 dependencies: firebase_functions: - path: ../../ - firebase_functions_genkit: - path: ../ - genkit: ^0.10.0-dev.8 - genkit_google_genai: ^0.0.1-dev.8 - schemantic: ^0.0.1-dev.9 - -dependency_overrides: - analyzer: ^10.0.1 - dart_firebase_admin: ^0.4.1 - genkit: ^0.10.0-dev.2 - googleapis_auth: ^1.3.0 - protobuf: ^6.0.0 + git: + url: https://github.com/firebase/firebase-functions-dart/ + firebase_functions_genkit: any + genkit: any + genkit_google_genai: any diff --git a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart index f5077f6..559eedc 100644 --- a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart +++ b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart @@ -5,12 +5,21 @@ import 'package:genkit/genkit.dart'; // ignore: experimental_member_use import 'package:meta/meta.dart' show mustBeConst; +/// Extension on [HttpsNamespace] to provide a seamless integration with Genkit. extension GenkitExt on HttpsNamespace { - void onCallGenkit({ + /// Registers a Genkit [flow] as a Firebase callable function. + /// + /// Automatically handles streaming and non-streaming responses based on + /// [CallableRequest.acceptsStreaming]. + /// + /// Use [contextProvider] to map properties from the Firebase + /// [CallableRequest] (such as authentication tokens) into the Genkit context. + void onCallGenkit({ // Must repeat the name + /// It's experimental as we can't semver package:meta // ignore: experimental_member_use @mustBeConst required String name, - required Flow flow, + required Flow flow, /// It's experimental as we can't semver package:meta // ignore: experimental_member_use @@ -19,7 +28,7 @@ extension GenkitExt on HttpsNamespace { }) { /// This is why we restate the name in the params above // ignore: non_const_argument_for_const_parameter - onCall(name: name, options: options, (request, response) async { + onCall(name: name, options: options, (request, response) async { if (request.acceptsStreaming) { final actionStream = flow.stream( request.data, @@ -28,9 +37,11 @@ extension GenkitExt on HttpsNamespace { await actionStream.forEach((chunk) => response.sendChunk(chunk)); return CallableResult(actionStream.result); } else { - return CallableResult( - await flow.run(request.data, context: contextProvider?.call(request)), + final run = await flow.run( + request.data, + context: contextProvider?.call(request), ); + return CallableResult(run.result); } }); } diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index 0dfa03b..f989d2a 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -5,21 +5,24 @@ repository: https://github.com/invertase/firebase-functions-dart publish_to: none +workspace: + - example + environment: sdk: ^3.10.0 dependencies: firebase_functions: - path: ../ - genkit: git: - url: https://github.com/genkit-ai/genkit-dart/ - path: packages/genkit + url: https://github.com/firebase/firebase-functions-dart/ + genkit: ^0.12.1 meta: ^1.18.1 -dependency_overrides: - analyzer: ^10.0.1 - protobuf: ^6.0.0 - dev_dependencies: dart_flutter_team_lints: ^3.5.2 + +dependency_overrides: + google_cloud_firestore: + git: + url: https://github.com/firebase/firebase-admin-dart/ + path: packages/google_cloud_firestore \ No newline at end of file From b2fadcca4ea6eb2e0e4db76649352106b72d08e2 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 14 Apr 2026 22:40:55 +0200 Subject: [PATCH 16/19] Rename --- firebase_functions_genkit/example/bin/example.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index b127b4f..090b279 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -31,7 +31,7 @@ void main(List args) { firebase.https.onCallGenkit( name: name, flow: flow, - contextProvider: (context) => {'auth': context.auth?.token?['email']}, + contextProvider: (request) => {'auth': request.auth?.token?['email']}, ); }); } From 4e6aac484a2aebdc390168b32659223b6f1353da Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 15 Apr 2026 09:14:43 +0200 Subject: [PATCH 17/19] Use published packages --- firebase_functions_genkit/example/pubspec.yaml | 4 +--- firebase_functions_genkit/pubspec.yaml | 10 +--------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/firebase_functions_genkit/example/pubspec.yaml b/firebase_functions_genkit/example/pubspec.yaml index 25c3e79..d2b8f6a 100644 --- a/firebase_functions_genkit/example/pubspec.yaml +++ b/firebase_functions_genkit/example/pubspec.yaml @@ -6,9 +6,7 @@ environment: sdk: ^3.10.0 dependencies: - firebase_functions: - git: - url: https://github.com/firebase/firebase-functions-dart/ + firebase_functions: any firebase_functions_genkit: any genkit: any genkit_google_genai: any diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index f989d2a..e805f05 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -12,17 +12,9 @@ environment: sdk: ^3.10.0 dependencies: - firebase_functions: - git: - url: https://github.com/firebase/firebase-functions-dart/ + firebase_functions: ^0.5.0 genkit: ^0.12.1 meta: ^1.18.1 dev_dependencies: dart_flutter_team_lints: ^3.5.2 - -dependency_overrides: - google_cloud_firestore: - git: - url: https://github.com/firebase/firebase-admin-dart/ - path: packages/google_cloud_firestore \ No newline at end of file From 1ae6c11ab814e0663b2d1177baeb687920ad7136 Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 15 Apr 2026 09:15:33 +0200 Subject: [PATCH 18/19] use firebase --- firebase_functions_genkit/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase_functions_genkit/pubspec.yaml b/firebase_functions_genkit/pubspec.yaml index e805f05..772cab8 100644 --- a/firebase_functions_genkit/pubspec.yaml +++ b/firebase_functions_genkit/pubspec.yaml @@ -1,7 +1,7 @@ name: firebase_functions_genkit description: A starting point for Dart libraries or applications. version: 0.1.0 -repository: https://github.com/invertase/firebase-functions-dart +repository: https://github.com/firebase/firebase-functions-dart publish_to: none From 93118df9782202df49bbdf1b39ac1491bd44a104 Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 15 Apr 2026 09:48:12 +0200 Subject: [PATCH 19/19] add licenses --- firebase_functions_genkit/example/bin/example.dart | 14 ++++++++++++++ .../lib/firebase_functions_genkit.dart | 14 ++++++++++++++ .../lib/src/firebase_functions_genkit_base.dart | 14 ++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/firebase_functions_genkit/example/bin/example.dart b/firebase_functions_genkit/example/bin/example.dart index 090b279..7dea0ef 100644 --- a/firebase_functions_genkit/example/bin/example.dart +++ b/firebase_functions_genkit/example/bin/example.dart @@ -1,3 +1,17 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + import 'package:firebase_functions/firebase_functions.dart'; import 'package:firebase_functions_genkit/firebase_functions_genkit.dart'; import 'package:genkit/genkit.dart'; diff --git a/firebase_functions_genkit/lib/firebase_functions_genkit.dart b/firebase_functions_genkit/lib/firebase_functions_genkit.dart index 8900c52..c36f67c 100644 --- a/firebase_functions_genkit/lib/firebase_functions_genkit.dart +++ b/firebase_functions_genkit/lib/firebase_functions_genkit.dart @@ -1 +1,15 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + export 'src/firebase_functions_genkit_base.dart'; diff --git a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart index 559eedc..da3e568 100644 --- a/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart +++ b/firebase_functions_genkit/lib/src/firebase_functions_genkit_base.dart @@ -1,3 +1,17 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + import 'package:firebase_functions/firebase_functions.dart'; import 'package:genkit/genkit.dart';