Skip to content
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

docs: 2nd tranche of docs updates for 6 Feb GA release #1865

Merged
merged 5 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 80 additions & 79 deletions docs/firebase.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Deploy flows using Cloud Functions for Firebase

Cloud Functions for Firebase has an `onCallGenkit` method that allows you to
Cloud Functions for Firebase has an `onCallGenkit` method that lets you
quickly create a [callable function](https://firebase.google.com/docs/functions/callable?gen=2nd)
with a Genkit action (e.g. a Flow). These functions can be called with `genkit/beta/client` or the
[Functions client SDK](https://firebase.google.com/docs/functions/callable?gen=2nd#call_the_function),
which will automatically add auth info.
with a Genkit action (e.g. a Flow). These functions can be called using
`genkit/beta/client`or the [Functions clientSDK](https://firebase.google.com/docs/functions/callable?gen=2nd#call_the_function),
which automatically adds auth info.

## Before you begin

Expand All @@ -14,7 +14,7 @@ which will automatically add auth info.
* It would be helpful, but not required, if you've already used Cloud
Functions for Firebase before.

## 1. Set up a Firebase project
## 1. Set up a Firebase project {:#setup}

If you don't already have a Firebase project with TypeScript Cloud Functions set
up, follow these steps:
Expand Down Expand Up @@ -53,21 +53,21 @@ up, follow these steps:
firebase init genkit
```

The rest of this page assumes that you've selected to write your functions
The rest of this page assumes that you've decided to write your functions
in TypeScript, but you can also deploy your Genkit flows if you're using
JavaScript.

## 2. Wrap the Flow in onCallGenkit
## 2. Wrap the Flow in onCallGenkit {:#wrap-flow}

After you've set up a Firebase project with Cloud Functions, you can copy or
write flow definitions in the project’s `functions/src` directory, and export
them in `index.ts`.

For your flows to be deployable, you will need to wrap them in `onCallGenkit`.
This method has all the features of the normal `onCall`. It automatically supports
both streaming and JSON responses.
For your flows to be deployable, you need to wrap them in `onCallGenkit`.
This method has all the features of the normal `onCall`. It automatically
supports both streaming and JSON responses.

Suppose you have the following flow:
Suppose you have the following flow:

```ts
const generatePoemFlow = ai.defineFlow(
Expand All @@ -83,7 +83,7 @@ const generatePoemFlow = ai.defineFlow(
);
```

You can expose this Flow as a Callable Function using `onCallGenkit`:
You can expose this flow as a callable function using `onCallGenkit`:

```ts
import { onCallGenkit } from 'firebase-functions/https';
Expand All @@ -94,9 +94,9 @@ export generatePoem = onCallGenkit(generatePoemFlow);
### Define an authorization policy

All deployed flows, whether deployed to Firebase or not, should have an
authorization policy; without one, your potentially-expensive generative AI
flows would be invocable by anyone. To define an authorization policy, use the
`authPolicy` parameter in `onCallGenkit`:
authorization policy; without one, anyone can invoke your potentially-expensive
generative AI flows. To define an authorization policy, use the
`authPolicy` parameter of `onCallGenkit`:

```ts
export const generatePoem = onCallGenkit({
Expand All @@ -105,7 +105,7 @@ export const generatePoem = onCallGenkit({
```

This sample uses a manual function as its auth policy. In addition, the https
library exports the helpers `signedIn()` and `hasClaim()`. Here is the same code
library exports the `signedIn()` and `hasClaim()` helpers. Here is the same code
using one of those helpers:

```ts
Expand All @@ -116,70 +116,72 @@ export const generatePoem = onCallGenkit({
}, generatePoemFlow);
```

### Make API credentials available to deployed flows
### Make API credentials available to deployed flows

Once deployed, your flows need some way to authenticate with any remote services
they rely on. Most flows will at a minimum need credentials for accessing the
they rely on. Most flows need, at a minimum, credentials for accessing the
model API service they use.

For this example, do one of the following, depending on the model provider you
chose:

- {Gemini (Google AI)}

1. Make sure Google AI is [available in your
region](https://ai.google.dev/available_regions).
1. Make sure Google AI is [available in your
region](https://ai.google.dev/available_regions).

1. [Generate an API key](https://aistudio.google.com/app/apikey) for the
Gemini API using Google AI Studio.
1. [Generate an API key](https://aistudio.google.com/app/apikey) for the
Gemini API using Google AI Studio.

1. Store your API key in Cloud Secret Manager:
1. Store your API key in Cloud Secret Manager:

```posix-terminal
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
```
```posix-terminal
firebase functions:secrets:set GOOGLE_GENAI_API_KEY
```

This step is important to prevent accidentally leaking your API key, which
grants access to a potentially metered service.
This step is important to prevent accidentally leaking your API key,
which grants access to a potentially metered service.

See [Store and access sensitive configuration information](/docs/functions/config-env?gen=2nd#secret-manager)
for more information on managing secrets.
See [Store and access sensitive configuration information](/docs/functions/config-env?gen=2nd#secret-manager)
for more information on managing secrets.

1. Edit `src/index.ts` and add the following after the existing imports:
1. Edit `src/index.ts` and add the following after the existing imports:

```ts
import {defineSecret} from "firebase-functions/params";
const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
```
```ts
import {defineSecret} from "firebase-functions/params";
const googleAIapiKey = defineSecret("GOOGLE_GENAI_API_KEY");
```

Then, in the flow definition, declare that the cloud function needs access
to this secret value:
Then, in the flow definition, declare that the cloud function needs
access to this secret value:

```ts
export const generatePoem = onCallGenkit({
secrets: [googleAIapiKey]
}, generatePoemFlow);
```
```ts
export const generatePoem = onCallGenkit({
secrets: [googleAIapiKey]
}, generatePoemFlow);
```

Now, when you deploy this function, your API key will be stored in Cloud
Now, when you deploy this function, your API key is stored in Cloud
Secret Manager, and available from the Cloud Functions environment.

- {Gemini (Vertex AI)}

1. In the Cloud console, [Enable the Vertex AI
API](https://console.cloud.google.com/apis/library/aiplatform.googleapis.com?project=_)
for your Firebase project.
1. In the Cloud console, [Enable the Vertex AI
API](https://console.cloud.google.com/apis/library/aiplatform.googleapis.com?project=_)
for your Firebase project.

1. On the [IAM](https://console.cloud.google.com/iam-admin/iam?project=_)
page, ensure that the **Default compute service account** is granted the
**Vertex AI User** role.
1. On the [IAM](https://console.cloud.google.com/iam-admin/iam?project=_)
page, ensure that the **Default compute service account** is granted the
**Vertex AI User** role.

The only secret you need to set up for this tutorial is for the model provider,
but in general, you must do something similar for each service your flow uses.

### Add App Check enforcement
[Firebase App Check](https://firebase.google.com/docs/app-check) uses native attestation
to verify that your API is only being called by your application. onCallGenkit supports App Check enforcement declaratively.

[Firebase App Check](https://firebase.google.com/docs/app-check) uses a
built-in attestation mechanism to verify that your API is only being called by
your application. `onCallGenkit` supports App Check enforcement declaratively.

```ts
export const generatePoem = onCallGenkit({
Expand All @@ -191,23 +193,22 @@ export const generatePoem = onCallGenkit({
}, generatePoemFlow);
```

### Set a CORS policy
### Set a CORS policy

Callable functions default to allowing any domain to call your function. If you would
like to customize this, use the `cors` option.
Callable functions default to allowing any domain to call your function. If you
want to customize the domains that can do this, use the `cors` option.
With proper authentication (especially App Check), CORS is often unnecessary.

```ts
export const generatePoem = onCallGenkit({
cors: 'mydomain.com',
}, generatePoemFlow);
```

With proper authentication (especially App Check), CORS is often unnecessary.

### Complete example

After you've made all of the changes described above, your deployable flow will
look something like the following example:
After you've made all of the changes described earlier, your deployable flow
looks something like the following example:

```ts
import { genkit } from 'genkit';
Expand All @@ -232,21 +233,21 @@ export const generateFlow = onCallGenkit({
}, generatePoemFlow);
```

## 3. Deploy flows to Firebase
## 3. Deploy flows to Firebase {:#deploy-flows}

After you've defined flows using `onCallGenkit`, you can deploy them as you would
deploy other Cloud Functions:
After you've defined flows using `onCallGenkit`, you can deploy them the same
way you would deploy other Cloud Functions:

```posix-terminal
cd $PROJECT_ROOT

firebase deploy --only functions
```

You've now deployed the flow as a Cloud Function! But, you won't be able to
You've now deployed the flow as a Cloud Function! But you can't
access your deployed endpoint with `curl` or similar, because of the flow's
authorization policy. Continue to the next section to learn how to securely
access the flow.
authorization policy. The next section explains how to securely access the
flow.

## Optional: Try the deployed flow {:#example-client}

Expand All @@ -259,8 +260,8 @@ app:

1. In the
[Authentication](https://console.firebase.google.com/project/_/authentication/providers)
section of the Firebase console, enable the **Google** provider, which you
will use in this example.
section of the Firebase console, enable the **Google** provider, used in
this example.

1. In your project directory, set up Firebase Hosting, where you will deploy
the sample app:
Expand Down Expand Up @@ -351,11 +352,11 @@ Open the web app by visiting the URL printed by the `deploy` command. The app
requires you to sign in with a Google account, after which you can initiate
endpoint requests.

## Optional: Run flows in the developer UI
## Optional: Run flows in the developer UI {:#run-flows}

You can run flows defined using `onCallGenkit` in the developer UI, exactly the same
way as you run flows defined using `defineFlow`, so there's no need to switch
between the two between deployment and development.
You can run flows defined using `onCallGenkit` in the developer UI, exactly the
same way as you run flows defined using `defineFlow`, so there's no need to
switch between the two between deployment and development.

```posix-terminal
cd $PROJECT_ROOT/functions
Expand All @@ -364,7 +365,7 @@ npx genkit start -- npx tsx --watch src/index.ts
```

or

```posix-terminal
cd $PROJECT_ROOT/functions

Expand All @@ -373,23 +374,23 @@ npm run genkit:start

You can now navigate to the URL printed by the `genkit start` command to access.

## Optional: Developing using Firebase Local Emulator Suite
## Optional: Developing using Firebase Local Emulator Suite {:#firebase-local}

Firebase offers a
[suite of emulators for local development](/docs/emulator-suite), which you can
use with Genkit.

To use the Genkit Dev UI with the Firebase Emulator Suite, start the Firebase emulators
like this:
To use the Genkit Dev UI with the Firebase Emulator Suite, start the Firebase
emulators as follows:

```posix-terminal
npx genkit start -- firebase emulators:start --inspect-functions
```

This will run your code in the emulator and run the Genkit framework in
development mode, which launches and exposes the Genkit reflection API (but not
This command runs your code in the emulator, and runs the Genkit framework in
development mode. This launches and exposes the Genkit reflection API (but not
the Dev UI).

To see traces from Firestore in the Dev UI you can navigate to the Inspect tab
and toggle the "Dev/Prod" switch. When toggled to "prod" it will be loading
traces from firestore.
To see traces from Firestore in the Dev UI, you can navigate to the _Inspect_
tab and toggle the *Dev/Prod* switch. When toggled to _prod_ it loads
traces from firestore.
9 changes: 5 additions & 4 deletions docs/flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ Here's an example of a flow that supports streaming:
* The `streamSchema` option specifies the type of values your flow streams.
This does not necessarily need to be the same type as the `outputSchema`,
which is the type of the flow's complete output.
* The second parameter to your flow definition is called "sideChannel". It provides
multiple useful features, such as request context and the `sendChunk` callback.
* The second parameter to your flow definition is called `sideChannel`. It
provides features such as request context and the `sendChunk` callback.
The `sendChunk` callback takes a single parameter, of
the type specified by `streamSchema`. Whenever data becomes available within
your flow, send the data to the output stream by calling this function.
Expand Down Expand Up @@ -240,8 +240,9 @@ but this section gives brief overviews of your deployment options.

### Cloud Functions for Firebase

To deploy flows with Cloud Functions for Firebase, use the `onCallGenkit` feature of `firebase-functions/https`.
This will wrap your flow in a callable function. You may set an auth policy and configure App Check.
To deploy flows with Cloud Functions for Firebase, use the `onCallGenkit`
feature of `firebase-functions/https`. `onCallGenkit` wraps your flow in a
callable function. You may set an auth policy and configure App Check.

```ts
{% includecode github_path="firebase/genkit/js/doc-snippets/src/flows/firebase.ts" region_tag="ex" adjust_indentation="auto" %}
Expand Down
7 changes: 3 additions & 4 deletions docs/plugin-authoring-evaluator.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ function getDeliciousnessPrompt(ai: Genkit) {

Define a function that takes an example that includes `output` as
required by the prompt, and scores the result. Genkit testcases include
`input` as
a required field, with `output` and `context` as optional fields. It is the
responsibility of the evaluator to validate that all fields required for
evaluation are present.
`input` as a required field, with `output` and `context` as optional fields.
It is the responsibility of the evaluator to validate that all fields
required for evaluation are present.

```ts
import { ModelArgument } from 'genkit';
Expand Down
8 changes: 4 additions & 4 deletions docs/tool-calling.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ const getWeather = ai.defineTool(
```

The syntax here looks just like the `defineFlow()` syntax; however, `name`,
`description` and `inputSchema` parameters are required. When writing a tool
`description`, and `inputSchema` parameters are required. When writing a tool
definition, take special care with the wording and descriptiveness of these
parameters, as they are vital for the LLM to effectively make use of the
parameters. They are vital for the LLM to make effective use of the
available tools.

### Using tools
Expand Down Expand Up @@ -199,8 +199,8 @@ Genkit will automatically handle the tool call if the LLM needs to use the
### Pause the tool loop by using interrupts

By default, Genkit repeatedly calls the LLM until every tool call has been
resolved. You may want to conditionally pause execution in situations where
you want to, for example:
resolved. You can conditionally pause execution in situations where you want
to, for example:

* Ask the user a question or display UI.
* Confirm a potentially risky action with the user.
Expand Down
Loading