Skip to content

Commit

Permalink
Add sample for onCallGenkit (#1189)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhuleatt authored Feb 5, 2025
1 parent 814a99a commit 8e35cdc
Show file tree
Hide file tree
Showing 8 changed files with 836 additions and 3 deletions.
587 changes: 584 additions & 3 deletions Node/pnpm-lock.yaml

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions Node/quickstarts/genkit-helloworld/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
firebase-debug.log*
firebase-debug.*.log*

# Firebase cache
.firebase/

# Firebase config

# Uncomment this if you'd like others to create their own Firebase project.
# For a team working on the same Firebase project(s), it is recommended to leave
# it commented so all members can deploy to the same project(s) in .firebaserc.
# .firebaserc

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
33 changes: 33 additions & 0 deletions Node/quickstarts/genkit-helloworld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Genkit quickstart
================================================

This quickstart demonstrates how to initialize a [Genkit flow](https://firebase.google.com/docs/genkit/flows) and serve it with Cloud Functions for Firebase.

[Read more about Cloud Functions for Firebase](https://firebase.google.com/docs/functions/)


Getting Started
---------------

1. Install dependencies with `npm install`
1. Start the functions emulator with `firebase emulators:start --only functions`
1. The emulator will output the function URL. It is usually of the form:

```
https://127.0.0.1:5001/{$PROJECT}/us-central1/tellJoke
```
1. Call the function from a terminal, replacing the `url` argument with your function's URL:
```bash
$ curl -X POST \
--url https://127.0.0.1:5001/{$PROJECT}/us-central1/tellJoke \
--header "Content-Type: application/json" \
--header "Accept: text/event-stream" \
--data '{"data": "Observational comedy"}'
```
License
-------
© Google, 2025. Licensed under an [Apache-2](../../../LICENSE) license.
8 changes: 8 additions & 0 deletions Node/quickstarts/genkit-helloworld/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"functions": {
"codebase": "oncallgenkit-helloworld",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
}
}
30 changes: 30 additions & 0 deletions Node/quickstarts/genkit-helloworld/functions/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2025 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.
*/

module.exports = {
root: true,
env: {
es2020: true,
node: true,
},
extends: [
"eslint:recommended",
"google",
],
rules: {
quotes: ["error", "double"],
},
};
1 change: 1 addition & 0 deletions Node/quickstarts/genkit-helloworld/functions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
84 changes: 84 additions & 0 deletions Node/quickstarts/genkit-helloworld/functions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Copyright 2025 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
*
* https://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.
*/

// [START complete-example]
// [START imports]
// [START import-trigger]
const {onCallGenkit} = require("firebase-functions/v2/https");
// [END import-trigger]
// [START import-params]
const {defineSecret} = require("firebase-functions/params");
// [END import-params]

// [START import-genkit]
// Dependencies for Genkit.
const {gemini15Flash, googleAI} = require("@genkit-ai/googleai");
const {genkit, z} = require("genkit");
// [END import-genkit]
// [END imports]

// [START define-secret]
// Store the Gemini API key in Cloud Secret Manager.
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
// [END define-secret]

// [START flow]
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});

const jokeTeller = ai.defineFlow({
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
}, async (jokeType = "knock-knock", response) => {
const prompt = `Tell me a ${jokeType} joke.`;

// Call the `generateStream()` method to
// receive the `stream` async iterable.
const {stream, response: aiResponse} = ai.generateStream(prompt);

// Send new words of the generative AI response
// to the client as they're generated.
for await (const chunk of stream) {
response.sendChunk(chunk.text);
}

// Return the full generative AI response
// to clients that may not support streaming.
return (await aiResponse).text;
},
);
// [END flow]

// [START trigger]
exports.tellJoke = onCallGenkit({
// [START bind-secrets]
// Bind the Gemini API key secret parameter to the function.
secrets: [apiKey],
// [END bind-secrets]
// [START auth-policy]
// Protect your endpoint with authPolicy.
// authPolicy: (auth) => !!auth?.token.email_verified,
// [END auth-policy]
},
// Pass in the genkit flow.
jokeTeller,
);
// [END trigger]
// [END complete-example]
30 changes: 30 additions & 0 deletions Node/quickstarts/genkit-helloworld/functions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"lintfix": "eslint . --fix",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"compile": "cp ../../../../tsconfig.template.json ./tsconfig-compile.json && tsc --project tsconfig-compile.json"
},
"engines": {
"node": "22"
},
"main": "index.js",
"dependencies": {
"@genkit-ai/googleai": "1.0.0-rc.12",
"firebase-admin": "^13.0.2",
"firebase-functions": "^6.3.0",
"genkit": "1.0.0-rc.12"
},
"devDependencies": {
"eslint": "^8.57.1",
"eslint-config-google": "^0.14.0",
"firebase-functions-test": "^3.4.0"
},
"private": true
}

0 comments on commit 8e35cdc

Please sign in to comment.