diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 77e35085e1..d50a2f6df5 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -2,5 +2,4 @@ Description here...
Checklist (if applicable):
- [ ] Tested (manually, unit tested, etc.)
-- [ ] Changelog updated
- [ ] Docs updated
diff --git a/docs-go/plugins/firebase.md b/docs-go/plugins/firebase.md
new file mode 100644
index 0000000000..a8cb3769d1
--- /dev/null
+++ b/docs-go/plugins/firebase.md
@@ -0,0 +1,188 @@
+
+# Firebase Genkit Plugin
+
+The Firebase plugin for Genkit allows flows to integrate seamlessly with Firebase services, such as Firestore and Firebase Authentication.
+
+This plugin includes initialization for Firebase, a retriever for Firestore, and Firebase Authentication integration for enhanced flow security.
+
+## Prerequisites
+
+Before using this plugin, ensure you have the following prerequisites:
+
+1. **Google Cloud Account**: Sign up for a Google Cloud account if you don’t already have one [here](https://cloud.google.com/gcp).
+
+2. **Google Cloud SDK**: Ensure that you have the [Google Cloud SDK (gcloud)](https://cloud.google.com/sdk/docs/install) installed on your local machine.
+
+3. **Firebase Project**: Create a Firebase project or use an existing one. This project should have Firestore and Firebase Authentication enabled.
+
+4. **APIs to Enable**:
+ - [Firestore API](https://console.cloud.google.com/apis/library/firestore.googleapis.com)
+ - [Firebase Authentication API](https://console.cloud.google.com/apis/library/identitytoolkit.googleapis.com)
+
+ You can enable these APIs from the [API Dashboard](https://console.cloud.google.com/apis/dashboard) of your Google Cloud project.
+
+5. **Firebase CLI**: To locally run or interact with Firebase, ensure you have the Firebase CLI installed.
+
+## Setup Instructions
+
+### Firebase Initialization
+
+To initialize Firebase in your Genkit project, first, import the `firebase` package:
+
+```go
+import "github.com/firebase/genkit/go/plugins/firebase"
+```
+
+### Configuration
+
+You need to provide the Firebase configuration in the form of a `FirebasePluginConfig` struct. This example assumes that you are loading the project ID and Firestore collection from environment variables:
+
+```go
+// Load project ID and Firestore collection from environment variables
+projectID := os.Getenv("FIREBASE_PROJECT_ID")
+collectionName := os.Getenv("FIRESTORE_COLLECTION")
+
+firebaseConfig := &firebase.FirebasePluginConfig{
+ App: firebaseApp, // Pass the pre-initialized Firebase app
+ Retrievers: []firebase.RetrieverOptions{
+ {
+ Name: "example-retriever",
+ Client: firestoreClient,
+ Collection: collectionName,
+ Embedder: embedder,
+ VectorField: "embedding",
+ ContentField: "text",
+ MetadataFields: []string{"metadata"},
+ Limit: 10,
+ DistanceMeasure: firestore.DistanceMeasureEuclidean,
+ VectorType: firebase.Vector64,
+ },
+ },
+}
+```
+
+### Initialize Firebase
+
+To initialize Firebase with the configuration, call the `Init` function. This ensures that the Firebase App is only initialized once:
+
+```go
+ctx := context.Background()
+err := firebase.Init(ctx, firebaseConfig)
+if err != nil {
+ log.Fatalf("Error initializing Firebase: %v", err)
+}
+```
+
+Once initialized, the Firebase app can be accessed using the `App` function:
+
+```go
+app, err := firebase.App(ctx)
+if err != nil {
+ log.Fatalf("Error getting Firebase app: %v", err)
+}
+```
+
+### Firestore Retriever
+
+The Firebase plugin provides a Firestore retriever that can be used to query documents in a Firestore collection based on vector similarity.
+
+1. **Options Configuration**:
+ You need to configure `RetrieverOptions`, which include:
+
+ - **Client**: The Firestore client.
+ - **Collection**: The Firestore collection you want to query.
+ - **Embedder**: The AI embedder to convert documents into embeddings.
+ - **VectorField**: The Firestore field containing the vector embeddings.
+ - **ContentField**: The field containing the text of the document.
+ - **MetadataFields**: A list of fields to include in the document metadata.
+
+```go
+retrieverOptions := firebase.RetrieverOptions{
+ Name: "example-retriever",
+ Client: firestoreClient,
+ Collection: collectionName,
+ Embedder: embedder,
+ VectorField: "embedding",
+ ContentField: "text",
+ MetadataFields: []string{"metadata"},
+ Limit: 10,
+ DistanceMeasure: firestore.DistanceMeasureEuclidean,
+ VectorType: firebase.Vector64,
+}
+```
+
+2. **Define the Retriever**:
+
+```go
+retriever, err := firebase.DefineFirestoreRetriever(retrieverOptions)
+if err != nil {
+ log.Fatalf("Error defining Firestore retriever: %v", err)
+}
+```
+
+3. **Use the Retriever**:
+
+To perform a retrieval based on a query document:
+
+```go
+req := &ai.RetrieverRequest{
+ Document: ai.DocumentFromText("Query text", nil),
+}
+
+resp, err := retriever.Retrieve(ctx, req)
+if err != nil {
+ log.Fatalf("Error retrieving documents: %v", err)
+}
+
+for _, doc := range resp.Documents {
+ log.Printf("Retrieved document: %s", doc.Content[0].Text)
+}
+```
+
+### Firebase Authentication
+
+The Firebase plugin integrates Firebase Authentication to provide authorization and access control in Genkit flows.
+
+1. **Creating an Auth Object**:
+ Use the `NewAuth` function to create an auth object, specifying whether authentication is required and the policy for checking the context:
+
+```go
+auth, err := firebase.NewAuth(ctx, nil, true)
+if err != nil {
+ log.Fatalf("Error initializing Firebase Auth: %v", err)
+}
+```
+
+2. **Providing Authentication Context**:
+ To use authentication, the `ProvideAuthContext` function extracts the authentication header from a request, verifies the token, and provides the auth context:
+
+```go
+ctx, err := auth.ProvideAuthContext(ctx, "Bearer your-id-token")
+if err != nil {
+ log.Fatalf("Error providing auth context: %v", err)
+}
+```
+
+3. **Checking Authorization Policy**:
+ The `CheckAuthPolicy` function ensures that the current auth context satisfies any policies you’ve defined for your flow:
+
+```go
+err := auth.CheckAuthPolicy(ctx, inputData)
+if err != nil {
+ log.Fatalf("Authorization check failed: %v", err)
+}
+```
+
+## Local Testing
+
+When testing flows locally, ensure that the Google Cloud credentials are available to the Firebase SDK. Use the following command to authenticate:
+
+```bash
+gcloud auth application-default login
+```
+
+This will provide your local environment with the necessary credentials to interact with Firebase services.
+
+## Conclusion
+
+The Firebase Genkit Plugin simplifies the integration of Firebase services, including Firestore and Firebase Authentication, into your Genkit flows. With features like Firestore vector queries and flow-level authentication, it provides powerful tools for building intelligent, secure applications.
diff --git a/docs/get-started.md b/docs/get-started.md
index 0b7c02b890..ead5745fb2 100644
--- a/docs/get-started.md
+++ b/docs/get-started.md
@@ -1,189 +1,74 @@
# Get started
-To get started with Firebase Genkit, install the Genkit CLI and run
-`genkit init` in a Node.js project. The rest of this page shows you how.
+This guide shows you how to get started with Genkit in a Node.js app.
-## Requirements
+## Prerequisites
-Node.js 20 or later.
+This guide assumes that you're familiar with building applications with Node.js.
-Recommendation: The [`nvm`](https://github.com/nvm-sh/nvm) and
-[`nvm-windows`](https://github.com/coreybutler/nvm-windows) tools are a
-convenient way to install Node.
+To complete this quickstart, make sure that your development environment meets the following requirements:
-## Install Genkit {:#install}
+* Node.js v20+
+* npm
-Install the Genkit CLI by running the following command:
+## Install Genkit dependencies
-```posix-terminal
-npm i -g genkit
-```
-
-This command installs the Genkit CLI into your Node installation directory
-so that it can be used outside of a Node project.
+Install the following Genkit dependencies to use Genkit in your project:
-## Create and explore a sample project {:#explore}
+* `@genkit-ai/ai` and `@genkit-ai/core` provide Genkit core capabilities.
+* `@genkit-ai/googleai` provide access to the Google AI Gemini models.
+* `genkit` provides the Genkit CLI and tooling to help you test and debug your solution later.
-1. Create a new Node project:
+```posix-terminal
+npm install @genkit-ai/ai @genkit-ai/core @genkit-ai/googleai
- ```posix-terminal
- mkdir genkit-intro && cd genkit-intro
+npm install -g genkit
+```
- npm init -y
- ```
+## Configure your model API key
- Look at package.json and make sure the `main` field is set to
- `lib/index.js`.
+For this guide, we’ll show you how to use the Gemini API which provides a generous free tier and does not require a credit card to get started. To use the Gemini API, you'll need an API key. If you don't already have one, create a key in Google AI Studio.
-1. Initialize a Genkit project:
+Get an API key from Google AI Studio
- ```posix-terminal
- genkit init
- ```
-
- 1. Select your model:
-
- - {Gemini (Google AI)}
-
- The simplest way to get started is with Google AI Gemini API. Make sure
- it's
- [available in your region](https://ai.google.dev/available_regions).
-
- [Generate an API key](https://aistudio.google.com/app/apikey) for the
- Gemini API using Google AI Studio. Then, set the `GOOGLE_GENAI_API_KEY`
- environment variable to your key:
-
- ```posix-terminal
- export GOOGLE_GENAI_API_KEY=
- ```
+After you’ve created an API key, set the `GOOGLE_GENAI_API_KEY` environment variable to your key with the following command:
- - {Gemini (Vertex AI)}
-
- If the Google AI Gemini API is not available in your region, consider
- using the Vertex AI API which also offers Gemini and other models. You
- will need to have a billing-enabled Google Cloud project, enable AI
- Platform API, and set some additional environment variables:
-
- ```posix-terminal
- gcloud services enable aiplatform.googleapis.com
-
- export GCLOUD_PROJECT=
+```
+export GOOGLE_GENAI_API_KEY=
+```
- export GCLOUD_LOCATION=us-central1
- ```
+Note: While this tutorial uses the Gemini API from AI Studio, Genkit supports a wide variety of model providers including [Gemini from Vertex AI](https://firebase.google.com/docs/genkit/plugins/vertex-ai#generative_ai_models), Anthropic’s Claude 3 models and Llama 3.1 through the [Vertex AI Model Garden](https://firebase.google.com/docs/genkit/plugins/vertex-ai#anthropic_claude_3_on_vertex_ai_model_garden), open source models through [Ollama](https://firebase.google.com/docs/genkit/plugins/ollama), and several other [community-supported providers](https://firebase.google.com/docs/genkit/models#models-supported) like OpenAI and Cohere.
- See https://cloud.google.com/vertex-ai/generative-ai/pricing for Vertex AI pricing.
-
- 1. Choose default answers to the rest of the questions, which will
- initialize your project folder with some sample code.
+## Import the library
- The `genkit init` command creates a sample source file, `index.ts`, which
- defines a single flow, `menuSuggestionFlow`, that prompts an LLM to suggest
- an item for a restaurant with a given theme.
+Import the Genkit core libraries and the plugin for the Google AI Gemini APIs.
- This file looks something like the following (the plugin configuration steps
- might look different if you selected Vertex AI):
+```javascript
+import { generate } from '@genkit-ai/ai';
+import { configureGenkit } from '@genkit-ai/core';
+import { googleAI, gemini15Flash } from '@genkit-ai/googleai';
+```
- ```ts
- import * as z from 'zod';
+## Make your first request
- // Import the Genkit core libraries and plugins.
- import { generate } from '@genkit-ai/ai';
- import { configureGenkit } from '@genkit-ai/core';
- import { defineFlow, startFlowsServer } from '@genkit-ai/flow';
- import { googleAI } from '@genkit-ai/googleai';
+Use the `generate` method to generate a text response.
- // Import models from the Google AI plugin. The Google AI API provides access to
- // several generative models. Here, we import Gemini 1.5 Flash.
- import { gemini15Flash } from '@genkit-ai/googleai';
+```javascript
+configureGenkit({ plugins: [googleAI()] });
- configureGenkit({
- plugins: [
- // Load the Google AI plugin. You can optionally specify your API key
- // by passing in a config object; if you don't, the Google AI plugin uses
- // the value from the GOOGLE_GENAI_API_KEY environment variable, which is
- // the recommended practice.
- googleAI(),
- ],
- // Log debug output to tbe console.
- logLevel: 'debug',
- // Perform OpenTelemetry instrumentation and enable trace collection.
- enableTracingAndMetrics: true,
- });
+const result = await generate({
+ model: gemini15Flash,
+ prompt: 'Tell me a heroic story about a software developer.',
+});
- // Define a simple flow that prompts an LLM to generate menu suggestions.
- export const menuSuggestionFlow = defineFlow(
- {
- name: 'menuSuggestionFlow',
- inputSchema: z.string(),
- outputSchema: z.string(),
- },
- async (subject) => {
- // Construct a request and send it to the model API.
- const llmResponse = await generate({
- prompt: `Suggest an item for the menu of a ${subject} themed restaurant`,
- model: gemini15Flash,
- config: {
- temperature: 1,
- },
- });
-
- // Handle the response from the model API. In this sample, we just convert
- // it to a string, but more complicated flows might coerce the response into
- // structured output or chain the response into another LLM call, etc.
- return llmResponse.text();
- }
- );
-
- // Start a flow server, which exposes your flows as HTTP endpoints. This call
- // must come last, after all of your plug-in configuration and flow definitions.
- // You can optionally specify a subset of flows to serve, and configure some
- // HTTP server options, but by default, the flow server serves all defined flows.
- startFlowsServer();
- ```
-
- As you build out your app's AI features with Genkit, you will likely
- create flows with multiple steps such as input preprocessing, more
- sophisticated prompt construction, integrating external information
- sources for retrieval-augmented generation (RAG), and more.
-
-1. Now you can run and explore Genkit features and the sample project locally
- on your machine. Download and start the Genkit Developer UI:
-
- ```posix-terminal
- genkit start
- ```
-
-
-
- The Genkit Developer UI is now running on your machine. When you run models
- or flows in the next step, your machine will perform the orchestration tasks
- needed to get the steps of your flow working together; calls to external
- services such as the Gemini API will continue to be made against live
- servers.
-
- Also, because you are in a dev environment, Genkit will store traces and
- flow state in local files.
-
-1. The Genkit Developer UI downloads and opens automatically when you run the
- `genkit start` command.
-
- The Developer UI lets you see which flows you have defined and models you
- configured, run them, and examine traces of previous runs. Try out some of
- these features:
-
- - On the **Run** tab, you will see a list of all of the flows that you have
- defined and any models that have been configured by plugins.
-
- Click **menuSuggestionFlow** and try running it with some input text (for example,
- `"cat"`). If all goes well, you'll be rewarded with a menu suggestion for a cat
- themed restaurant.
-
- - On the **Inspect** tab, you'll see a history of flow executions. For each
- flow, you can see the parameters that were passed to the flow and a
- trace of each step as they ran.
+console.log(result.text())
+```
## Next steps
-Check out how to build and deploy your Genkit app with [Firebase](firebase.md),
-[Cloud Run](cloud-run.md), or any [Node.js platform](deploy-node.md).
+Now that you’re set up to make model requests with Genkit, learn how to use more Genkit capabilities to build your AI-powered apps and workflows. To get started with additional Genkit capabilities, see the following guides:
+
+* [Developer tools](docs/genkit/devtools): Learn how to set up and use Genkit’s CLI and developer UI to help you locally test and debug your app.
+* [Generating content](/docs/genkit/models): Learn how to use Genkit’s unified generation API to generate text and structured data from any supported model.
+* [Creating flows](docs/genkit/flows): Learn how to use special Genkit functions, called flows, that provide end-to-end observability for workflows and rich debugging from Genkit tooling.
+* [Prompting models](/docs/genkit/prompts): Learn how Genkit lets you treat prompt templates as functions, encapsulating model configurations and input/output schema.
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index a7351a5b61..e3e72f53f7 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -56,7 +56,7 @@ See the following code samples for a concrete idea of how to use these capabilit
- {Basic generation}
```javascript
- import { generate } from `@genkit-ai/ai`;
+ import { generate } from '@genkit-ai/ai';
import { gemini15Flash, claude3Sonnet, llama31 } from '@genkit-ai/vertexai';
import { gpt4o } from 'genkitx-openai';
@@ -70,9 +70,9 @@ See the following code samples for a concrete idea of how to use these capabilit
- {Structured generation}
```javascript
- import { generate } from `@genkit-ai/ai`;
- import { gemini15Flash } from `@genkit-ai/googleai`;
- import { z } from `zod`;
+ import { generate } from '@genkit-ai/ai';
+ import { gemini15Flash } from '@genkit-ai/googleai';
+ import { z } from 'zod';
const result = await generate({
model: gemini15Flash,
@@ -95,9 +95,9 @@ See the following code samples for a concrete idea of how to use these capabilit
- {Tool calling}
```javascript
- import { generate, defineTool } from `@genkit-ai/ai`;
- import { gemini15Flash } from `@genkit-ai/googleai`;
- import { z } from `zod`;
+ import { generate, defineTool } from '@genkit-ai/ai';
+ import { gemini15Flash } from '@genkit-ai/googleai';
+ import { z } from 'zod';
// Define tool to get weather data for a given location
const lookupWeather = defineTool({
@@ -126,9 +126,9 @@ See the following code samples for a concrete idea of how to use these capabilit
- {Retrieval}
```javascript
- import { generate, retrieve } from `@genkit-ai/ai`;
+ import { generate, retrieve } from '@genkit-ai/ai';
import { devLocalRetrieverRef } from '@genkit-ai/dev-local-vectorstore';
- import { gemini15Flash } from `@genkit-ai/googleai`;
+ import { gemini15Flash } from '@genkit-ai/googleai';
// Sample assumes Genkit documentation has been chunked, stored, and indexed in
// local vectorstore in previous step.
diff --git a/docs/monitoring.md b/docs/monitoring.md
index 591daafe37..0e288c2acc 100644
--- a/docs/monitoring.md
+++ b/docs/monitoring.md
@@ -31,7 +31,7 @@ want to enable TTL for the trace documents:
https://firebase.google.com/docs/firestore/ttl
```ts
-import { firebase } from '@genkit-ai/plugin-firebase';
+import { firebase } from '@genkit-ai/firebase';
configureGenkit({
plugins: [firebase()],
diff --git a/docs/nextjs.md b/docs/nextjs.md
index 9547e6f4b6..5245838ec9 100644
--- a/docs/nextjs.md
+++ b/docs/nextjs.md
@@ -127,21 +127,23 @@ Node.js 20 or later.
import { useState } from 'react';
export default function Home() {
- const [menuItem, setMenu] = useState('');
+ const [menuItem, setMenuItem] = useState('');
async function getMenuItem(formData: FormData) {
const theme = formData.get('theme')?.toString() ?? '';
const suggestion = await callMenuSuggestionFlow(theme);
- setMenu(suggestion);
+ setMenuItem(suggestion);
}
return (
diff --git a/docs/plugins/ollama.md b/docs/plugins/ollama.md
index 8e0a85aa22..b6606bdc43 100644
--- a/docs/plugins/ollama.md
+++ b/docs/plugins/ollama.md
@@ -66,39 +66,49 @@ import { GoogleAuth } from 'google-auth-library';
import { ollama, OllamaPluginParams } from 'genkitx-ollama';
import { configureGenkit, isDevEnv } from '@genkit-ai/core';
-const ollamaCommon = {models: [{name: "gemma:2b"}]};
+const ollamaCommon = { models: [{ name: 'gemma:2b' }] };
+
const ollamaDev = {
...ollamaCommon,
serverAddress: 'http://127.0.0.1:11434',
} as OllamaPluginParams;
+
const ollamaProd = {
...ollamaCommon,
serverAddress: 'https://my-deployment',
- requestHeaders: async (params) => ({
- Authorization: `Bearer ${await getIdToken(params.serverAddress)}`,
- }),
+ requestHeaders: async (params) => {
+ const headers = await fetchWithAuthHeader(params.serverAddress);
+ return { Authorization: headers['Authorization'] };
+ },
} as OllamaPluginParams;
export default configureGenkit({
plugins: [
- ollama(isDevEnv() ? ollamaDev: ollamaProd),
+ ollama(isDevEnv() ? ollamaDev : ollamaProd),
],
});
-export async function getIdToken(url: string): Promise {
- const auth = getAuthClient();
- const client = await auth.getIdTokenClient(url);
- return client.idTokenProvider.fetchIdToken(url);
-}
-
+// Function to lazily load GoogleAuth client
let auth: GoogleAuth;
function getAuthClient() {
- // Lazy load GoogleAuth client.
if (!auth) {
auth = new GoogleAuth();
}
return auth;
}
+
+// Function to fetch headers, reusing tokens when possible
+async function fetchWithAuthHeader(url: string) {
+ const client = await getIdTokenClient(url);
+ const headers = await client.getRequestHeaders(url); // Auto-manages token refresh
+ return headers;
+}
+
+async function getIdTokenClient(url: string) {
+ const auth = getAuthClient();
+ const client = await auth.getIdTokenClient(url);
+ return client;
+}
```
## Usage
diff --git a/docs/plugins/vertex-ai.md b/docs/plugins/vertex-ai.md
index 30da54b31f..be13edf8ce 100644
--- a/docs/plugins/vertex-ai.md
+++ b/docs/plugins/vertex-ai.md
@@ -4,7 +4,7 @@ The Vertex AI plugin provides interfaces to several AI services:
- [Google generative AI models](https://cloud.google.com/vertex-ai/generative-ai/docs/):
- Gemini text generation
- - Imagen2 image generation
+ - Imagen2 and Imagen3 image generation
- Text embedding generation
- A subset of evaluation metrics through the Vertex AI [Rapid Evaluation API](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/evaluation):
- [BLEU](https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/projects.locations/evaluateInstances#bleuinput)
@@ -157,6 +157,20 @@ const embedding = await embed({
});
```
+Imagen3 model allows generating images from user prompt:
+
+```js
+import { imagen3 } from '@genkit-ai/vertexai';
+
+const response = await generate({
+ model: imagen3,
+ output: { format: 'media' },
+ prompt: 'a banana riding a bicycle',
+});
+
+return response.media();
+```
+
#### Anthropic Claude 3 on Vertex AI Model Garden
If you have access to Claude 3 models ([haiku](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-haiku), [sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-sonnet) or [opus](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-opus)) in Vertex AI Model Garden you can use them with Genkit.
diff --git a/genkit-tools/cli/package.json b/genkit-tools/cli/package.json
index 33de6cbd25..1af960dc63 100644
--- a/genkit-tools/cli/package.json
+++ b/genkit-tools/cli/package.json
@@ -1,7 +1,7 @@
{
"name": "genkit",
- "version": "0.5.13",
- "description": "CLI for interacting with the Google GenKit AI framework",
+ "version": "0.5.16",
+ "description": "CLI for interacting with the Google Genkit AI framework",
"license": "Apache-2.0",
"keywords": [
"genkit",
diff --git a/genkit-tools/common/package.json b/genkit-tools/common/package.json
index dca8ec9b51..ba5ff1c94c 100644
--- a/genkit-tools/common/package.json
+++ b/genkit-tools/common/package.json
@@ -1,9 +1,9 @@
{
"name": "@genkit-ai/tools-common",
- "version": "0.5.13",
+ "version": "0.5.16",
"scripts": {
"compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean compile",
"test": "jest --verbose",
"build:watch": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json --watch"
@@ -18,7 +18,7 @@
"colorette": "^2.0.20",
"commander": "^11.1.0",
"configstore": "^5.0.1",
- "express": "^4.18.2",
+ "express": "^4.21.0",
"get-port": "5.1.1",
"glob": "^10.3.12",
"inquirer": "^8.2.0",
@@ -50,7 +50,8 @@
"genversion": "^3.2.0",
"npm-run-all": "^4.1.5",
"ts-node": "^10.9.2",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
},
"repository": {
"type": "git",
diff --git a/genkit-tools/package.json b/genkit-tools/package.json
index a4ed19dac5..f796c07967 100644
--- a/genkit-tools/package.json
+++ b/genkit-tools/package.json
@@ -20,5 +20,5 @@
"zod": "^3.22.4",
"zod-to-json-schema": "^3.22.4"
},
- "packageManager": "pnpm@9.10.0+sha256.355a8ab8dbb6ad41befbef39bc4fd6b5df85e12761d2724bd01f13e878de4b13"
+ "packageManager": "pnpm@9.12.0+sha256.a61b67ff6cc97af864564f4442556c22a04f2e5a7714fbee76a1011361d9b726"
}
diff --git a/genkit-tools/plugins/firebase/package.json b/genkit-tools/plugins/firebase/package.json
index bb072e05f1..d779964bfc 100644
--- a/genkit-tools/plugins/firebase/package.json
+++ b/genkit-tools/plugins/firebase/package.json
@@ -3,7 +3,7 @@
"version": "0.5.10",
"scripts": {
"compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean compile",
"build:watch": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json --watch"
},
@@ -11,7 +11,8 @@
"@genkit-ai/tools-common": "workspace:*",
"@types/node": "^20.11.19",
"npm-run-all": "^4.1.5",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "lib/types/index.d.ts",
"exports": {
diff --git a/genkit-tools/plugins/google/package.json b/genkit-tools/plugins/google/package.json
index d9ae1825ee..7876d43a4f 100644
--- a/genkit-tools/plugins/google/package.json
+++ b/genkit-tools/plugins/google/package.json
@@ -3,7 +3,7 @@
"version": "0.5.10",
"scripts": {
"compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean compile",
"build:watch": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json --watch"
},
@@ -11,7 +11,8 @@
"@genkit-ai/tools-common": "workspace:*",
"@types/node": "^20.11.19",
"npm-run-all": "^4.1.5",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "lib/types/index.d.ts",
"exports": {
diff --git a/genkit-tools/pnpm-lock.yaml b/genkit-tools/pnpm-lock.yaml
index 2672e59bfc..df0e35f7b5 100644
--- a/genkit-tools/pnpm-lock.yaml
+++ b/genkit-tools/pnpm-lock.yaml
@@ -100,8 +100,8 @@ importers:
specifier: ^5.0.1
version: 5.0.1
express:
- specifier: ^4.18.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
get-port:
specifier: 5.1.1
version: 5.1.1
@@ -184,6 +184,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
ts-jest:
specifier: ^29.1.2
version: 29.1.2(@babel/core@7.24.5)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.5))(jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)))(typescript@5.4.5)
@@ -209,6 +212,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^4.9.0
version: 4.9.5
@@ -228,6 +234,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^4.9.0
version: 4.9.5
@@ -906,6 +915,10 @@ packages:
resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+ body-parser@1.20.3:
+ resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@@ -1217,6 +1230,10 @@ packages:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
end-of-stream@1.4.4:
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
@@ -1291,8 +1308,8 @@ packages:
resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- express@4.19.2:
- resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==}
+ express@4.21.0:
+ resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==}
engines: {node: '>= 0.10.0'}
external-editor@3.1.0:
@@ -1327,8 +1344,8 @@ packages:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
- finalhandler@1.2.0:
- resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
+ finalhandler@1.3.1:
+ resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
engines: {node: '>= 0.8'}
find-package@1.0.0:
@@ -1439,8 +1456,14 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Glob versions prior to v9 are no longer supported
globals@11.12.0:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
@@ -1678,6 +1701,10 @@ packages:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
+ jackspeak@4.0.2:
+ resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
+ engines: {node: 20 || >=22}
+
jake@10.8.7:
resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==}
engines: {node: '>=10'}
@@ -1886,6 +1913,10 @@ packages:
resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==}
engines: {node: 14 || >=16.14}
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -1914,8 +1945,8 @@ packages:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
- merge-descriptors@1.0.1:
- resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
+ merge-descriptors@1.0.3:
+ resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
@@ -1945,6 +1976,10 @@ packages:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -1960,6 +1995,10 @@ packages:
resolution: {integrity: sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==}
engines: {node: '>=16 || 14 >=14.17'}
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@@ -2064,6 +2103,9 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
parents@1.0.1:
resolution: {integrity: sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==}
@@ -2106,8 +2148,12 @@ packages:
resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
engines: {node: '>=16 || 14 >=14.17'}
- path-to-regexp@0.1.7:
- resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ path-to-regexp@0.1.10:
+ resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==}
path-type@3.0.0:
resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
@@ -2177,6 +2223,10 @@ packages:
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
engines: {node: '>=0.6'}
+ qs@6.13.0:
+ resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
+ engines: {node: '>=0.6'}
+
range-parser@1.2.1:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
@@ -2231,6 +2281,11 @@ packages:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
run-async@2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'}
@@ -2269,12 +2324,12 @@ packages:
engines: {node: '>=10'}
hasBin: true
- send@0.18.0:
- resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
+ send@0.19.0:
+ resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
engines: {node: '>= 0.8.0'}
- serve-static@1.15.0:
- resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
+ serve-static@1.16.2:
+ resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'}
set-function-length@1.2.2:
@@ -3502,6 +3557,23 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ body-parser@1.20.3:
+ dependencies:
+ bytes: 3.1.2
+ content-type: 1.0.5
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ on-finished: 2.4.1
+ qs: 6.13.0
+ raw-body: 2.5.2
+ type-is: 1.6.18
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
@@ -3789,6 +3861,8 @@ snapshots:
encodeurl@1.0.2: {}
+ encodeurl@2.0.0: {}
+
end-of-stream@1.4.4:
dependencies:
once: 1.4.0
@@ -3938,34 +4012,34 @@ snapshots:
jest-message-util: 29.7.0
jest-util: 29.7.0
- express@4.19.2:
+ express@4.21.0:
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
- body-parser: 1.20.2
+ body-parser: 1.20.3
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.6.0
cookie-signature: 1.0.6
debug: 2.6.9
depd: 2.0.0
- encodeurl: 1.0.2
+ encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
- finalhandler: 1.2.0
+ finalhandler: 1.3.1
fresh: 0.5.2
http-errors: 2.0.0
- merge-descriptors: 1.0.1
+ merge-descriptors: 1.0.3
methods: 1.1.2
on-finished: 2.4.1
parseurl: 1.3.3
- path-to-regexp: 0.1.7
+ path-to-regexp: 0.1.10
proxy-addr: 2.0.7
- qs: 6.11.0
+ qs: 6.13.0
range-parser: 1.2.1
safe-buffer: 5.2.1
- send: 0.18.0
- serve-static: 1.15.0
+ send: 0.19.0
+ serve-static: 1.16.2
setprototypeof: 1.2.0
statuses: 2.0.1
type-is: 1.6.18
@@ -4014,10 +4088,10 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
- finalhandler@1.2.0:
+ finalhandler@1.3.1:
dependencies:
debug: 2.6.9
- encodeurl: 1.0.2
+ encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
parseurl: 1.3.3
@@ -4126,6 +4200,15 @@ snapshots:
minipass: 7.1.0
path-scurry: 1.10.2
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.1.1
+ jackspeak: 4.0.2
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -4371,6 +4454,10 @@ snapshots:
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
+ jackspeak@4.0.2:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
jake@10.8.7:
dependencies:
async: 3.2.5
@@ -4752,6 +4839,8 @@ snapshots:
lru-cache@10.2.2: {}
+ lru-cache@11.0.1: {}
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -4776,7 +4865,7 @@ snapshots:
memorystream@0.3.1: {}
- merge-descriptors@1.0.1: {}
+ merge-descriptors@1.0.3: {}
merge-stream@2.0.0: {}
@@ -4797,6 +4886,10 @@ snapshots:
mimic-fn@2.1.0: {}
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
@@ -4811,6 +4904,8 @@ snapshots:
minipass@7.1.0: {}
+ minipass@7.1.2: {}
+
ms@2.0.0: {}
ms@2.1.2: {}
@@ -4921,6 +5016,8 @@ snapshots:
p-try@2.2.0: {}
+ package-json-from-dist@1.0.1: {}
+
parents@1.0.1:
dependencies:
path-platform: 0.11.15
@@ -4956,7 +5053,12 @@ snapshots:
lru-cache: 10.2.2
minipass: 7.1.0
- path-to-regexp@0.1.7: {}
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
+ path-to-regexp@0.1.10: {}
path-type@3.0.0:
dependencies:
@@ -5017,6 +5119,10 @@ snapshots:
dependencies:
side-channel: 1.0.6
+ qs@6.13.0:
+ dependencies:
+ side-channel: 1.0.6
+
range-parser@1.2.1: {}
raw-body@2.5.2:
@@ -5074,6 +5180,11 @@ snapshots:
onetime: 5.1.2
signal-exit: 3.0.7
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.1
+
run-async@2.4.1: {}
rxjs@7.8.1:
@@ -5105,7 +5216,7 @@ snapshots:
semver@7.6.1: {}
- send@0.18.0:
+ send@0.19.0:
dependencies:
debug: 2.6.9
depd: 2.0.0
@@ -5123,12 +5234,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- serve-static@1.15.0:
+ serve-static@1.16.2:
dependencies:
- encodeurl: 1.0.2
+ encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
- send: 0.18.0
+ send: 0.19.0
transitivePeerDependencies:
- supports-color
diff --git a/go/go.mod b/go/go.mod
index c6133f9d11..439d08af7d 100644
--- a/go/go.mod
+++ b/go/go.mod
@@ -28,7 +28,7 @@ require (
go.opentelemetry.io/otel/trace v1.26.0
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81
golang.org/x/tools v0.23.0
- google.golang.org/api v0.188.0
+ google.golang.org/api v0.189.0
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
@@ -37,10 +37,10 @@ require (
require (
cloud.google.com/go v0.115.0 // indirect
cloud.google.com/go/ai v0.8.1-0.20240711230438-265963bd5b91 // indirect
- cloud.google.com/go/auth v0.7.0 // indirect
- cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
- cloud.google.com/go/compute/metadata v0.4.0 // indirect
- cloud.google.com/go/firestore v1.15.0 // indirect
+ cloud.google.com/go/auth v0.7.2 // indirect
+ cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect
+ cloud.google.com/go/compute/metadata v0.5.0 // indirect
+ cloud.google.com/go/firestore v1.16.0 // indirect
cloud.google.com/go/iam v1.1.10 // indirect
cloud.google.com/go/longrunning v0.5.9 // indirect
cloud.google.com/go/monitoring v1.20.1 // indirect
@@ -54,7 +54,7 @@ require (
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
- github.com/go-logr/logr v1.4.1 // indirect
+ github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.2 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
@@ -70,7 +70,7 @@ require (
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
- github.com/googleapis/gax-go/v2 v2.12.5 // indirect
+ github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -90,8 +90,8 @@ require (
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine/v2 v2.0.2 // indirect
- google.golang.org/genproto v0.0.0-20240708141625-4ad9e859172b // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect
+ google.golang.org/genproto v0.0.0-20240722135656-d784300faade // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade // indirect
google.golang.org/grpc v1.65.0 // indirect
)
diff --git a/go/go.sum b/go/go.sum
index fbd0eb794b..fcef3852af 100644
--- a/go/go.sum
+++ b/go/go.sum
@@ -7,12 +7,20 @@ cloud.google.com/go/aiplatform v1.68.0 h1:EPPqgHDJpBZKRvv+OsB3cr0jYz3EL2pZ+802rB
cloud.google.com/go/aiplatform v1.68.0/go.mod h1:105MFA3svHjC3Oazl7yjXAmIR89LKhRAeNdnDKJczME=
cloud.google.com/go/auth v0.7.0 h1:kf/x9B3WTbBUHkC+1VS8wwwli9TzhSt0vSTVBmMR8Ts=
cloud.google.com/go/auth v0.7.0/go.mod h1:D+WqdrpcjmiCgWrXmLLxOVq1GACoE36chW6KXoEvuIw=
+cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE=
+cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs=
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
+cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
+cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
cloud.google.com/go/compute/metadata v0.4.0 h1:vHzJCWaM4g8XIcm8kopr3XmDA4Gy/lblD3EhhSux05c=
cloud.google.com/go/compute/metadata v0.4.0/go.mod h1:SIQh1Kkb4ZJ8zJ874fqVkslA29PRXuleyj6vOzlbK7M=
+cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
+cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/firestore v1.15.0 h1:/k8ppuWOtNuDHt2tsRV42yI21uaGnKDEQnRFeBpbFF8=
cloud.google.com/go/firestore v1.15.0/go.mod h1:GWOxFXcv8GZUtYpWHw/w6IuYNux/BtmeVTMmjrm4yhk=
+cloud.google.com/go/firestore v1.16.0 h1:YwmDHcyrxVRErWcgxunzEaZxtNbc8QoFYA/JOEwDPgc=
+cloud.google.com/go/firestore v1.16.0/go.mod h1:+22v/7p+WNBSQwdSwP57vz47aZiY+HrDkrOsJNhk7rg=
cloud.google.com/go/iam v1.1.10 h1:ZSAr64oEhQSClwBL670MsJAW5/RLiC6kfw3Bqmd5ZDI=
cloud.google.com/go/iam v1.1.10/go.mod h1:iEgMq62sg8zx446GCaijmA2Miwg5o3UbO+nI47WHJps=
cloud.google.com/go/logging v1.10.0 h1:f+ZXMqyrSJ5vZ5pE/zr0xC8y/M9BLNzQeLBwfeZ+wY4=
@@ -73,6 +81,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU=
@@ -174,6 +184,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
+github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s=
+github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
@@ -388,6 +400,8 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSm
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
+google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI=
+google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine/v2 v2.0.2 h1:MSqyWy2shDLwG7chbwBJ5uMyw6SNqJzhJHNDwYB0Akk=
@@ -397,10 +411,16 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240708141625-4ad9e859172b h1:dSTjko30weBaMj3eERKc0ZVXW4GudCswM3m+P++ukU0=
google.golang.org/genproto v0.0.0-20240708141625-4ad9e859172b/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
+google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg=
+google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
+google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade h1:WxZOF2yayUHpHSbUE6NMzumUzBxYc3YGwo0YHnbzsJY=
+google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade h1:oCRSWfwGXQsqlVdErcyTt4A93Y8fo0/9D4b1gnI++qo=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
diff --git a/go/plugins/dotprompt/genkit.go b/go/plugins/dotprompt/genkit.go
index ce31434d49..f139b9df60 100644
--- a/go/plugins/dotprompt/genkit.go
+++ b/go/plugins/dotprompt/genkit.go
@@ -218,7 +218,7 @@ func (p *Prompt) Generate(ctx context.Context, pr *PromptRequest, cb func(contex
return nil, errors.New("dotprompt model not in provider/name format")
}
- model := ai.LookupModel(provider, name)
+ model = ai.LookupModel(provider, name)
if model == nil {
return nil, fmt.Errorf("no model named %q for provider %q", name, provider)
}
diff --git a/go/plugins/dotprompt/genkit_test.go b/go/plugins/dotprompt/genkit_test.go
index 71bb3bb229..a724d28d8a 100644
--- a/go/plugins/dotprompt/genkit_test.go
+++ b/go/plugins/dotprompt/genkit_test.go
@@ -43,14 +43,31 @@ func testGenerate(ctx context.Context, req *ai.GenerateRequest, cb func(context.
func TestExecute(t *testing.T) {
testModel := ai.DefineModel("test", "test", nil, testGenerate)
- p, err := New("TestExecute", "TestExecute", Config{Model: testModel})
- if err != nil {
- t.Fatal(err)
- }
- resp, err := p.Generate(context.Background(), &PromptRequest{}, nil)
- if err != nil {
- t.Fatal(err)
- }
+ t.Run("Model", func(t *testing.T) {
+ p, err := New("TestExecute", "TestExecute", Config{Model: testModel})
+ if err != nil {
+ t.Fatal(err)
+ }
+ resp, err := p.Generate(context.Background(), &PromptRequest{}, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ assertResponse(t, resp)
+ })
+ t.Run("ModelName", func(t *testing.T) {
+ p, err := New("TestExecute", "TestExecute", Config{ModelName: "test/test"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ resp, err := p.Generate(context.Background(), &PromptRequest{}, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ assertResponse(t, resp)
+ })
+}
+
+func assertResponse(t *testing.T, resp *ai.GenerateResponse) {
if len(resp.Candidates) != 1 {
t.Errorf("got %d candidates, want 1", len(resp.Candidates))
if len(resp.Candidates) < 1 {
diff --git a/go/plugins/firebase/firebase.go b/go/plugins/firebase/firebase.go
index e2f4a85b4d..6002f6f3ea 100644
--- a/go/plugins/firebase/firebase.go
+++ b/go/plugins/firebase/firebase.go
@@ -16,31 +16,102 @@ package firebase
import (
"context"
+ "fmt"
+ "log"
"sync"
firebase "firebase.google.com/go/v4"
"firebase.google.com/go/v4/auth"
+ "github.com/firebase/genkit/go/ai"
)
+var state struct {
+ mu sync.Mutex // Ensures thread-safe access to state
+ initted bool // Tracks if the plugin has been initialized
+ app *firebase.App // Holds the Firebase app instance
+ retrievers []ai.Retriever // Holds the list of initialized retrievers
+}
+
+// FirebaseApp is an interface to represent the Firebase App object
type FirebaseApp interface {
Auth(ctx context.Context) (*auth.Client, error)
}
-var (
- app *firebase.App
- mutex sync.Mutex
-)
+// FirebasePluginConfig is the configuration for the Firebase plugin.
+// It passes an already initialized Firebase app and retriever options.
+type FirebasePluginConfig struct {
+ App *firebase.App // Pre-initialized Firebase app
+ Retrievers []RetrieverOptions // Array of retriever options
+}
+
+// Init initializes the plugin with the provided configuration.
+// It caches the provided Firebase app and initializes retrievers.
+func Init(ctx context.Context, cfg *FirebasePluginConfig) error {
+ state.mu.Lock()
+ defer state.mu.Unlock()
+
+ if state.initted {
+ log.Println("firebase.Init: plugin already initialized, returning without reinitializing")
+ return nil
+ }
-// app returns a cached Firebase app.
-func App(ctx context.Context) (FirebaseApp, error) {
- mutex.Lock()
- defer mutex.Unlock()
- if app == nil {
- newApp, err := firebase.NewApp(ctx, nil)
+ // Ensure an app is provided
+ if cfg.App == nil {
+ return fmt.Errorf("firebase.Init: no Firebase app provided")
+ }
+
+ // Cache the provided app
+ state.app = cfg.App
+
+ // Initialize retrievers
+ var retrievers []ai.Retriever
+ for _, retrieverCfg := range cfg.Retrievers {
+ retriever, err := DefineFirestoreRetriever(retrieverCfg)
if err != nil {
- return nil, err
+ return fmt.Errorf("firebase.Init: failed to initialize retriever %s: %v", retrieverCfg.Name, err)
}
- app = newApp
+ retrievers = append(retrievers, retriever)
}
- return app, nil
+
+ // Cache the initialized retrievers
+ state.retrievers = retrievers
+ state.initted = true
+
+ return nil
+}
+
+// unInit clears the initialized plugin state.
+func unInit() {
+ state.mu.Lock()
+ defer state.mu.Unlock()
+
+ state.initted = false
+ state.app = nil
+ state.retrievers = nil
+}
+
+// App returns the cached Firebase app.
+// If the app is not initialized, it returns an error.
+func App(ctx context.Context) (*firebase.App, error) {
+ state.mu.Lock()
+ defer state.mu.Unlock()
+
+ if !state.initted {
+ return nil, fmt.Errorf("firebase.App: Firebase app not initialized. Call Init first")
+ }
+
+ return state.app, nil
+}
+
+// Retrievers returns the cached list of retrievers.
+// If retrievers are not initialized, it returns an error.
+func Retrievers(ctx context.Context) ([]ai.Retriever, error) {
+ state.mu.Lock()
+ defer state.mu.Unlock()
+
+ if !state.initted {
+ return nil, fmt.Errorf("firebase.Retrievers: Plugin not initialized. Call Init first")
+ }
+
+ return state.retrievers, nil
}
diff --git a/go/plugins/firebase/firebase_app_test.go b/go/plugins/firebase/firebase_app_test.go
new file mode 100644
index 0000000000..d86e5aa48a
--- /dev/null
+++ b/go/plugins/firebase/firebase_app_test.go
@@ -0,0 +1,80 @@
+// Copyright 2024 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.
+
+package firebase
+
+import (
+ "context"
+ "testing"
+
+ firebase "firebase.google.com/go/v4"
+)
+
+func TestApp(t *testing.T) {
+ t.Parallel()
+
+ ctx := context.Background()
+
+ tests := []struct {
+ name string
+ setup func() error
+ expectedError string
+ }{
+ {
+ name: "Get App before initialization",
+ setup: func() error {
+ // No initialization setup here, calling App directly should fail
+ return nil
+ },
+ expectedError: "firebase.App: Firebase app not initialized. Call Init first",
+ },
+ {
+ name: "Get App after successful initialization",
+ setup: func() error {
+ // Properly initialize the app by passing it in the config
+ config := &FirebasePluginConfig{
+ App: &firebase.App{}, // Pass a mock Firebase app instance
+ }
+ return Init(ctx, config)
+ },
+ expectedError: "",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ defer unInit()
+ // Execute setup
+ if err := tt.setup(); err != nil {
+ t.Fatalf("Setup failed: %v", err)
+ }
+
+ // Now test the App function
+ app, err := App(ctx)
+
+ if tt.expectedError != "" {
+ if err == nil || err.Error() != tt.expectedError {
+ t.Errorf("Expected error %q, got %v", tt.expectedError, err)
+ }
+ if app != nil {
+ t.Errorf("Expected no app, got %v", app)
+ }
+ } else if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ } else if app == nil {
+ t.Errorf("Expected a valid app instance, got nil")
+ }
+ })
+ }
+}
diff --git a/go/plugins/firebase/firebase_init_test.go b/go/plugins/firebase/firebase_init_test.go
new file mode 100644
index 0000000000..18b277e5a9
--- /dev/null
+++ b/go/plugins/firebase/firebase_init_test.go
@@ -0,0 +1,89 @@
+// Copyright 2024 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.
+
+package firebase
+
+import (
+ "context"
+ "testing"
+
+ firebase "firebase.google.com/go/v4"
+)
+
+func TestInit(t *testing.T) {
+ t.Parallel()
+
+ ctx := context.Background()
+
+ tests := []struct {
+ name string
+ config *FirebasePluginConfig
+ expectedError string
+ setup func() error
+ }{
+ {
+ name: "Successful initialization",
+ config: &FirebasePluginConfig{
+ App: &firebase.App{}, // Mock Firebase app
+ },
+ expectedError: "",
+ setup: func() error {
+ return nil // No setup required, first call should succeed
+ },
+ },
+ {
+ name: "Initialization when already initialized",
+ config: &FirebasePluginConfig{
+ App: &firebase.App{}, // Mock Firebase app
+ },
+ expectedError: "",
+ setup: func() error {
+ // Initialize once
+ return Init(ctx, &FirebasePluginConfig{
+ App: &firebase.App{}, // Mock Firebase app
+ })
+ },
+ },
+ {
+ name: "Initialization with missing App",
+ config: &FirebasePluginConfig{
+ App: nil, // No app provided
+ },
+ expectedError: "firebase.Init: no Firebase app provided", // Expecting an error when no app is passed
+ setup: func() error {
+ return nil // No setup required
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ defer unInit()
+
+ if err := tt.setup(); err != nil {
+ t.Fatalf("Setup failed: %v", err)
+ }
+
+ err := Init(ctx, tt.config)
+
+ if tt.expectedError != "" {
+ if err == nil || err.Error() != tt.expectedError {
+ t.Errorf("Expected error %q, got %v", tt.expectedError, err)
+ }
+ } else if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+ })
+ }
+}
diff --git a/go/plugins/firebase/retriever.go b/go/plugins/firebase/retriever.go
new file mode 100644
index 0000000000..5cb92247fe
--- /dev/null
+++ b/go/plugins/firebase/retriever.go
@@ -0,0 +1,125 @@
+// Copyright 2024 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.
+
+package firebase
+
+import (
+ "context"
+ "fmt"
+
+ "cloud.google.com/go/firestore"
+ "github.com/firebase/genkit/go/ai"
+)
+
+type VectorType int
+
+const (
+ Vector64 VectorType = iota
+)
+
+const provider = "firebase"
+
+type RetrieverOptions struct {
+ Name string
+ Label string
+ Client *firestore.Client
+ Collection string
+ Embedder ai.Embedder
+ VectorField string
+ MetadataFields []string
+ ContentField string
+ Limit int
+ DistanceMeasure firestore.DistanceMeasure
+ VectorType VectorType
+}
+
+func DefineFirestoreRetriever(cfg RetrieverOptions) (ai.Retriever, error) {
+ if cfg.VectorType != Vector64 {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: only Vector64 is supported")
+ }
+ if cfg.Client == nil {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: Firestore client is not provided")
+ }
+
+ Retrieve := func(ctx context.Context, req *ai.RetrieverRequest) (*ai.RetrieverResponse, error) {
+
+ if req.Document == nil {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: Request document is nil")
+ }
+
+ // Generate query embedding using the Embedder
+ embedRequest := &ai.EmbedRequest{Documents: []*ai.Document{req.Document}}
+ embedResponse, err := cfg.Embedder.Embed(ctx, embedRequest)
+ if err != nil {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: Embedding failed: %v", err)
+ }
+
+ if len(embedResponse.Embeddings) == 0 {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: No embeddings returned")
+ }
+
+ queryEmbedding := embedResponse.Embeddings[0].Embedding
+ if len(queryEmbedding) == 0 {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: Generated embedding is empty")
+ }
+
+ // Convert to []float64
+ queryEmbedding64 := make([]float64, len(queryEmbedding))
+ for i, val := range queryEmbedding {
+ queryEmbedding64[i] = float64(val)
+ }
+ // Perform the FindNearest query
+ vectorQuery := cfg.Client.Collection(cfg.Collection).FindNearest(
+ cfg.VectorField,
+ firestore.Vector64(queryEmbedding64),
+ cfg.Limit,
+ cfg.DistanceMeasure,
+ nil,
+ )
+ iter := vectorQuery.Documents(ctx)
+
+ results, err := iter.GetAll()
+ if err != nil {
+ return nil, fmt.Errorf("DefineFirestoreRetriever: FindNearest query failed: %v", err)
+ }
+
+ // Prepare the documents to return in the response
+ var documents []*ai.Document
+ for _, result := range results {
+ data := result.Data()
+
+ // Ensure content field exists and is of type string
+ content, ok := data[cfg.ContentField].(string)
+ if !ok {
+ fmt.Printf("Content field %s missing or not a string in document %s", cfg.ContentField, result.Ref.ID)
+ continue
+ }
+
+ // Extract metadata fields
+ metadata := make(map[string]interface{})
+ for _, field := range cfg.MetadataFields {
+ if value, ok := data[field]; ok {
+ metadata[field] = value
+ }
+ }
+
+ doc := ai.DocumentFromText(content, metadata)
+ documents = append(documents, doc)
+ }
+
+ return &ai.RetrieverResponse{Documents: documents}, nil
+ }
+
+ return ai.DefineRetriever(provider, cfg.Name, Retrieve), nil
+}
diff --git a/go/plugins/firebase/retriever_test.go b/go/plugins/firebase/retriever_test.go
new file mode 100644
index 0000000000..a69ac9365a
--- /dev/null
+++ b/go/plugins/firebase/retriever_test.go
@@ -0,0 +1,292 @@
+// Copyright 2024 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.
+
+package firebase
+
+import (
+ "context"
+ "flag"
+ "testing"
+
+ "cloud.google.com/go/firestore"
+ firebasev4 "firebase.google.com/go/v4"
+ "github.com/firebase/genkit/go/ai"
+ "google.golang.org/api/iterator"
+)
+
+var (
+ testProjectID = flag.String("test-project-id", "", "GCP Project ID to use for tests")
+ testCollection = flag.String("test-collection", "testR2", "Firestore collection to use for tests")
+ testVectorField = flag.String("test-vector-field", "embedding", "Field name for vector embeddings")
+)
+
+/*
+ * Pre-requisites to run this test:
+ *
+ * 1. **Set Up Firebase Project and Firestore:**
+ * You must create a Firebase project and ensure Firestore is enabled for that project. To do so:
+ *
+ * - Visit the Firebase Console: https://console.firebase.google.com/
+ * - Create a new project (or use an existing one).
+ * - Enable Firestore in your project from the "Build" section > "Firestore Database".
+ *
+ * 2. **Create a Firestore Collection and Composite Index:**
+ * This test assumes you have a Firestore collection set up for storing documents with vector embeddings.
+ * Additionally, you need to create a vector index for the embedding field. You can do this via the Firestore API with the following `curl` command:
+ *
+ * ```bash
+ * curl -X POST \
+ * "https://firestore.googleapis.com/v1/projects//databases/(default)/collectionGroups//indexes" \
+ * -H "Authorization: Bearer $(gcloud auth print-access-token)" \
+ * -H "Content-Type: application/json" \
+ * -d '{
+ * "fields": [
+ * {
+ * "fieldPath": "embedding",
+ * "vectorConfig": {
+ * "dimension": 3,
+ * "flat": {}
+ * }
+ * }
+ * ],
+ * "queryScope": "COLLECTION"
+ * }'
+ * ```
+ * Replace `` and `` with your project and collection names.
+ *
+ * 3. **Authentication & Credentials:**
+ * Ensure you have access to the project and Firestore using Google Cloud CLI. You can authenticate using the following commands:
+ *
+ * ```bash
+ * gcloud auth login
+ * gcloud config set project
+ * gcloud auth application-default login
+ * ```
+ *
+ * This authenticates your local environment with your GCP project and ensures the Go SDK can access Firestore.
+ *
+ * 4. **Running the Test:**
+ * After setting up Firestore and the index, you can run the test by passing in the required flags for the project, collection, and vector field:
+ *
+ * ```bash
+ * go test \
+ * -test-project-id= \
+ * -test-collection= \
+ * -test-vector-field=embedding
+ * ```
+ */
+
+// MockEmbedder implements the Embedder interface for testing purposes
+type MockEmbedder struct{}
+
+func (e *MockEmbedder) Name() string {
+ return "MockEmbedder"
+}
+
+func (e *MockEmbedder) Embed(ctx context.Context, req *ai.EmbedRequest) (*ai.EmbedResponse, error) {
+ var embeddings []*ai.DocumentEmbedding
+ for _, doc := range req.Documents {
+ var embedding []float32
+ switch doc.Content[0].Text {
+ case "This is document one":
+ // Embedding for document one is the closest to the query
+ embedding = []float32{0.9, 0.1, 0.0}
+ case "This is document two":
+ // Embedding for document two is less close to the query
+ embedding = []float32{0.7, 0.2, 0.1}
+ case "This is document three":
+ // Embedding for document three is even further from the query
+ embedding = []float32{0.4, 0.3, 0.3}
+ case "This is input query":
+ // Embedding for the input query
+ embedding = []float32{0.9, 0.1, 0.0}
+ default:
+ // Default embedding for any other documents
+ embedding = []float32{0.0, 0.0, 0.0}
+ }
+
+ embeddings = append(embeddings, &ai.DocumentEmbedding{Embedding: embedding})
+ }
+ return &ai.EmbedResponse{Embeddings: embeddings}, nil
+}
+
+// To run this test you must have a Firestore database initialized in a GCP project, with a vector indexed collection (of dimension 3).
+// Warning: This test will delete all documents in the collection in cleanup.
+
+func TestFirestoreRetriever(t *testing.T) {
+
+ // skip if flags aren't defined
+ if *testProjectID == "" {
+ t.Skip("Skipping test due to missing flags")
+ }
+ if *testCollection == "" {
+ t.Skip("Skipping test due to missing flags")
+ }
+ if *testVectorField == "" {
+ t.Skip("Skipping test due to missing flags")
+ }
+
+ ctx := context.Background()
+
+ // Initialize Firebase app
+ conf := &firebasev4.Config{ProjectID: *testProjectID}
+ app, err := firebasev4.NewApp(ctx, conf)
+ if err != nil {
+ t.Fatalf("Failed to create Firebase app: %v", err)
+ }
+
+ // Initialize Firestore client
+ client, err := app.Firestore(ctx)
+ if err != nil {
+ t.Fatalf("Failed to create Firestore client: %v", err)
+ }
+ defer client.Close()
+
+ // Clean up the collection before the test
+ defer deleteCollection(ctx, client, *testCollection, t)
+
+ // Initialize the embedder
+ embedder := &MockEmbedder{}
+
+ // Insert test documents with embeddings generated by the embedder
+ testDocs := []struct {
+ ID string
+ Text string
+ Data map[string]interface{}
+ }{
+ {"doc1", "This is document one", map[string]interface{}{"metadata": "meta1"}},
+ {"doc2", "This is document two", map[string]interface{}{"metadata": "meta2"}},
+ {"doc3", "This is document three", map[string]interface{}{"metadata": "meta3"}},
+ }
+
+ // Expected document text content in order of relevance for the query
+ expectedTexts := []string{
+ "This is document one",
+ "This is document two",
+ }
+
+ for _, doc := range testDocs {
+ // Create an ai.Document
+ aiDoc := ai.DocumentFromText(doc.Text, doc.Data)
+
+ // Generate embedding
+ embedRequest := &ai.EmbedRequest{Documents: []*ai.Document{aiDoc}}
+ embedResponse, err := embedder.Embed(ctx, embedRequest)
+ if err != nil {
+ t.Fatalf("Failed to generate embedding for document %s: %v", doc.ID, err)
+ }
+
+ if len(embedResponse.Embeddings) == 0 {
+ t.Fatalf("No embeddings returned for document %s", doc.ID)
+ }
+
+ embedding := embedResponse.Embeddings[0].Embedding
+ if len(embedding) == 0 {
+ t.Fatalf("Generated embedding is empty for document %s", doc.ID)
+ }
+
+ // Convert to []float64
+ embedding64 := make([]float64, len(embedding))
+ for i, val := range embedding {
+ embedding64[i] = float64(val)
+ }
+
+ // Store in Firestore
+ _, err = client.Collection(*testCollection).Doc(doc.ID).Set(ctx, map[string]interface{}{
+ "text": doc.Text,
+ "metadata": doc.Data["metadata"],
+ *testVectorField: firestore.Vector64(embedding64),
+ })
+ if err != nil {
+ t.Fatalf("Failed to insert document %s: %v", doc.ID, err)
+ }
+ t.Logf("Inserted document: %s with embedding: %v", doc.ID, embedding64)
+ }
+
+ // Define retriever options
+ retrieverOptions := RetrieverOptions{
+ Name: "test-retriever",
+ Label: "Test Retriever",
+ Client: client,
+ Collection: *testCollection,
+ Embedder: embedder,
+ VectorField: *testVectorField,
+ MetadataFields: []string{"metadata"},
+ ContentField: "text",
+ Limit: 2,
+ DistanceMeasure: firestore.DistanceMeasureEuclidean,
+ VectorType: Vector64,
+ }
+
+ // Define the retriever
+ retriever, err := DefineFirestoreRetriever(retrieverOptions)
+ if err != nil {
+ t.Fatalf("Failed to define retriever: %v", err)
+ }
+
+ // Create a retriever request with the input document
+ queryText := "This is input query"
+ inputDocument := ai.DocumentFromText(queryText, nil)
+
+ req := &ai.RetrieverRequest{
+ Document: inputDocument,
+ }
+
+ // Perform the retrieval
+ resp, err := retriever.Retrieve(ctx, req)
+ if err != nil {
+ t.Fatalf("Retriever failed: %v", err)
+ }
+
+ // Check the retrieved documents
+ if len(resp.Documents) == 0 {
+ t.Fatalf("No documents retrieved")
+ }
+
+ // Verify the content of all retrieved documents against the expected list
+ for i, doc := range resp.Documents {
+ if i >= len(expectedTexts) {
+ t.Errorf("More documents retrieved than expected. Retrieved: %d, Expected: %d", len(resp.Documents), len(expectedTexts))
+ break
+ }
+
+ if doc.Content[0].Text != expectedTexts[i] {
+ t.Errorf("Mismatch in document %d content. Expected: '%s', Got: '%s'", i+1, expectedTexts[i], doc.Content[0].Text)
+ } else {
+ t.Logf("Retrieved Document %d matches expected content: '%s'", i+1, expectedTexts[i])
+ }
+ }
+}
+
+func deleteCollection(ctx context.Context, client *firestore.Client, collectionName string, t *testing.T) {
+ // Get all documents in the collection
+ iter := client.Collection(collectionName).Documents(ctx)
+ for {
+ doc, err := iter.Next()
+ if err == iterator.Done {
+ break // No more documents
+ }
+ if err != nil {
+ t.Fatalf("Failed to iterate documents for deletion: %v", err)
+ }
+
+ // Delete each document
+ _, err = doc.Ref.Delete(ctx)
+ if err != nil {
+ t.Errorf("Failed to delete document %s: %v", doc.Ref.ID, err)
+ } else {
+ t.Logf("Deleted document: %s", doc.Ref.ID)
+ }
+ }
+}
diff --git a/go/plugins/firebase/test_project/.gitignore b/go/plugins/firebase/test_project/.gitignore
new file mode 100644
index 0000000000..dbb58ffbfa
--- /dev/null
+++ b/go/plugins/firebase/test_project/.gitignore
@@ -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
diff --git a/go/plugins/firebase/test_project/firebase.json b/go/plugins/firebase/test_project/firebase.json
new file mode 100644
index 0000000000..a21361e89d
--- /dev/null
+++ b/go/plugins/firebase/test_project/firebase.json
@@ -0,0 +1,15 @@
+{
+ "firestore": {
+ "rules": "firestore.rules",
+ "indexes": "firestore.indexes.json"
+ },
+ "emulators": {
+ "firestore": {
+ "port": 8080
+ },
+ "ui": {
+ "enabled": true
+ },
+ "singleProjectMode": true
+ }
+}
diff --git a/go/samples/firebase-retrievers/README.md b/go/samples/firebase-retrievers/README.md
new file mode 100644
index 0000000000..1e3d8e3249
--- /dev/null
+++ b/go/samples/firebase-retrievers/README.md
@@ -0,0 +1,101 @@
+
+# Genkit Firestore Example
+
+This sample demonstrates how to index and retrieve documents using Firestore and Genkit. The documents contain text about famous films, and users can query the indexed documents to retrieve information based on their input.
+
+Currently the sample uses a mock embedder for simplicity. In your applications you will want to use an actual embedder from genkit.
+
+## Prerequisites
+
+Before running the sample, ensure you have the following:
+
+1. **Google Cloud Project**: You must have a Google Cloud project with Firestore enabled.
+2. **Genkit**: Installed and set up in your local environment.
+3. **Authentication & Credentials**: Ensure you are authenticated with your Google Cloud project using the following command:
+ ```bash
+ gcloud auth application-default login
+ ```
+4. **Firestore Composite Index**: You need to create a composite vector index in Firestore for the `embedding` field. You can do this by running the following `curl` command:
+
+ ```bash
+ curl -X POST "https://firestore.googleapis.com/v1/projects//databases/(default)/collectionGroups//indexes" -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json" -d '{
+ "fields": [
+ {
+ "fieldPath": "embedding",
+ "vectorConfig": {
+ "dimension": 3,
+ "flat": {}
+ }
+ }
+ ],
+ "queryScope": "COLLECTION"
+ }'
+ ```
+
+ Replace `` and `` with your actual project and collection names.
+
+## Environment Variables
+
+You need to set the following environment variables before running the project:
+
+- `FIREBASE_PROJECT_ID`: The ID of your Google Cloud project.
+- `FIRESTORE_COLLECTION`: The name of the Firestore collection to use for storing and retrieving documents.
+
+You can set these variables by running:
+
+```bash
+export FIREBASE_PROJECT_ID=your-project-id
+export FIRESTORE_COLLECTION=your-collection-name
+```
+
+## Running the Project
+
+Once the environment is set up, follow these steps:
+
+1. **Start Genkit**:
+ Run the following command to start the Genkit server:
+
+ ```bash
+ genkit start
+ ```
+
+2. **Index Documents**:
+ To index the 10 documents with text about famous films, run the following Genkit flow:
+
+ ```bash
+ curl -X POST http://localhost:4000/api/runAction -H "Content-Type: application/json" -d '{"key":"/flow/flow-index-documents"}'
+ ```
+
+ This will insert 10 documents into the Firestore collection.
+
+3. **Retrieve Documents**:
+ To query the indexed documents, run the following Genkit flow and pass your query as input:
+
+ ```bash
+ curl -X POST http://localhost:4000/api/runAction -H "Content-Type: application/json" -d '{"key":"/flow/flow-retrieve-documents", "input": "crime film"}'
+ ```
+
+ You can replace `"crime film"` with any other query related to the indexed film documents.
+
+## Troubleshooting
+
+1. **Firestore Composite Index**: Ensure the Firestore composite index for the `embedding` field is correctly set up, otherwise queries may fail.
+2. **Environment Variables**: Make sure that the `FIREBASE_PROJECT_ID` and `FIRESTORE_COLLECTION` environment variables are correctly exported.
+
+## License
+
+```
+Copyright 2024 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.
+```
diff --git a/go/samples/firebase-retrievers/main.go b/go/samples/firebase-retrievers/main.go
new file mode 100644
index 0000000000..23fcf7461d
--- /dev/null
+++ b/go/samples/firebase-retrievers/main.go
@@ -0,0 +1,178 @@
+// Copyright 2024 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.
+
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "os"
+
+ "cloud.google.com/go/firestore"
+ firebasev4 "firebase.google.com/go/v4"
+
+ "github.com/firebase/genkit/go/ai"
+ "github.com/firebase/genkit/go/genkit"
+ "github.com/firebase/genkit/go/plugins/firebase"
+ "google.golang.org/api/option"
+)
+
+func main() {
+ ctx := context.Background()
+
+ // Load project ID and Firestore collection from environment variables
+ projectID := os.Getenv("FIREBASE_PROJECT_ID")
+ if projectID == "" {
+ log.Fatal("Environment variable FIREBASE_PROJECT_ID is not set")
+ }
+
+ collectionName := os.Getenv("FIRESTORE_COLLECTION")
+ if collectionName == "" {
+ log.Fatal("Environment variable FIRESTORE_COLLECTION is not set")
+ }
+
+ // Initialize Firestore client
+ firestoreClient, err := firestore.NewClient(ctx, projectID, option.WithCredentialsFile(""))
+ if err != nil {
+ log.Fatalf("Error creating Firestore client: %v", err)
+ }
+ defer firestoreClient.Close()
+
+ // Firebase app configuration and initialization
+ firebaseApp, err := firebasev4.NewApp(ctx, nil)
+ if err != nil {
+ log.Fatalf("Error initializing Firebase app: %v", err)
+ }
+
+ // Firebase configuration using the initialized app
+ firebaseConfig := &firebase.FirebasePluginConfig{
+ App: firebaseApp, // Pass the pre-initialized Firebase app
+ }
+
+ // Initialize Firebase plugin
+ if err := firebase.Init(ctx, firebaseConfig); err != nil {
+ log.Fatalf("Error initializing Firebase: %v", err)
+ }
+
+ // Mock embedder
+ embedder := &MockEmbedder{}
+
+ // Famous films text
+ films := []string{
+ "The Godfather is a 1972 crime film directed by Francis Ford Coppola.",
+ "The Dark Knight is a 2008 superhero film directed by Christopher Nolan.",
+ "Pulp Fiction is a 1994 crime film directed by Quentin Tarantino.",
+ "Schindler's List is a 1993 historical drama directed by Steven Spielberg.",
+ "Inception is a 2010 sci-fi film directed by Christopher Nolan.",
+ "The Matrix is a 1999 sci-fi film directed by the Wachowskis.",
+ "Fight Club is a 1999 film directed by David Fincher.",
+ "Forrest Gump is a 1994 drama directed by Robert Zemeckis.",
+ "Star Wars is a 1977 sci-fi film directed by George Lucas.",
+ "The Shawshank Redemption is a 1994 drama directed by Frank Darabont.",
+ }
+
+ // Define the index flow: Insert 10 documents about famous films
+ genkit.DefineFlow("flow-index-documents", func(ctx context.Context, _ struct{}) (string, error) {
+ for i, filmText := range films {
+ docID := fmt.Sprintf("doc-%d", i+1)
+ embedding := []float64{float64(i+1) * 0.1, float64(i+1) * 0.2, float64(i+1) * 0.3}
+
+ _, err := firestoreClient.Collection(collectionName).Doc(docID).Set(ctx, map[string]interface{}{
+ "text": filmText,
+ "embedding": firestore.Vector64(embedding),
+ "metadata": fmt.Sprintf("metadata for doc %d", i+1),
+ })
+ if err != nil {
+ return "", fmt.Errorf("failed to index document %d: %w", i+1, err)
+ }
+ log.Printf("Indexed document %d with text: %s", i+1, filmText)
+ }
+ return "10 film documents indexed successfully", nil
+ })
+
+ // Firestore Retriever Configuration
+ retrieverOptions := firebase.RetrieverOptions{
+ Name: "example-retriever",
+ Client: firestoreClient,
+ Collection: collectionName,
+ Embedder: embedder,
+ VectorField: "embedding",
+ ContentField: "text",
+ MetadataFields: []string{"metadata"},
+ Limit: 10,
+ DistanceMeasure: firestore.DistanceMeasureEuclidean,
+ VectorType: firebase.Vector64,
+ }
+
+ // Define Firestore Retriever
+ retriever, err := firebase.DefineFirestoreRetriever(retrieverOptions)
+ if err != nil {
+ log.Fatalf("Error defining Firestore retriever: %v", err)
+ }
+
+ // Define the retrieval flow: Retrieve documents based on user query
+ genkit.DefineFlow("flow-retrieve-documents", func(ctx context.Context, query string) (string, error) {
+ // Perform Firestore retrieval based on user input
+ req := &ai.RetrieverRequest{
+ Document: ai.DocumentFromText(query, nil),
+ }
+ log.Println("Starting retrieval with query:", query)
+ resp, err := retriever.Retrieve(ctx, req)
+ if err != nil {
+ return "", fmt.Errorf("retriever error: %w", err)
+ }
+
+ // Check if documents were retrieved
+ if len(resp.Documents) == 0 {
+ log.Println("No documents retrieved, response:", resp)
+ return "", fmt.Errorf("no documents retrieved")
+ }
+
+ // Log the retrieved documents for debugging
+ for _, doc := range resp.Documents {
+ log.Printf("Retrieved document: %s", doc.Content[0].Text)
+ }
+
+ return fmt.Sprintf("Retrieved document: %s", resp.Documents[0].Content[0].Text), nil
+ }, genkit.WithFlowAuth(nil)) // Removed the Firebase Auth requirement
+
+ // Initialize Genkit
+ if err := genkit.Init(ctx, nil); err != nil {
+ log.Fatal(err)
+ }
+}
+
+// MockEmbedder is used to simulate an AI embedder for testing purposes.
+type MockEmbedder struct{}
+
+func (e *MockEmbedder) Name() string {
+ return "MockEmbedder"
+}
+
+func (e *MockEmbedder) Embed(ctx context.Context, req *ai.EmbedRequest) (*ai.EmbedResponse, error) {
+ var embeddings []*ai.DocumentEmbedding
+
+ // Generate a simple uniform embedding for each document
+ for _, doc := range req.Documents {
+ // Example: Use the length of the document text to generate embeddings
+ embedding := []float32{
+ float32(len(doc.Content[0].Text)) * 0.1, // Scale based on text length
+ 0.5, // Static value
+ 0.3, // Static value
+ }
+ embeddings = append(embeddings, &ai.DocumentEmbedding{Embedding: embedding})
+ }
+ return &ai.EmbedResponse{Embeddings: embeddings}, nil
+}
diff --git a/js/ai/package.json b/js/ai/package.json
index 583c89f4c1..929dd4d3fb 100644
--- a/js/ai/package.json
+++ b/js/ai/package.json
@@ -7,12 +7,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "node --import tsx --test ./tests/**/*_test.ts",
@@ -39,7 +39,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.1",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "lib/index.d.ts",
"exports": {
diff --git a/js/core/package.json b/js/core/package.json
index 88757b67e5..d7d8b51b0f 100644
--- a/js/core/package.json
+++ b/js/core/package.json
@@ -7,12 +7,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all genversion build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "node --import tsx --test tests/*_test.ts",
@@ -35,7 +35,7 @@
"ajv": "^8.12.0",
"ajv-formats": "^3.0.1",
"async-mutex": "^0.5.0",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"json-schema": "^0.4.0",
"zod": "^3.22.4",
"zod-to-json-schema": "^3.22.4"
@@ -46,7 +46,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "lib/index.d.ts",
"exports": {
diff --git a/js/flow/package.json b/js/flow/package.json
index 9bd8db3835..d57cf7df3d 100644
--- a/js/flow/package.json
+++ b/js/flow/package.json
@@ -7,13 +7,13 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"main": "./lib/cjs/index.js",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "node --import tsx --test tests/*_test.ts"
@@ -30,9 +30,9 @@
"@google-cloud/firestore": "^7.6.0",
"@opentelemetry/api": "^1.9.0",
"@types/cors": "^2.8.17",
- "body-parser": "^1.20.2",
+ "body-parser": "^1.20.3",
"cors": "^2.8.5",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"firebase-admin": "^12.1.0",
"firebase-functions": "^4.8.0 || ^5.0.0",
"uuid": "^9.0.1",
@@ -45,7 +45,8 @@
"tsup": "^8.0.2",
"typescript": "^4.9.0",
"tsx": "^4.7.1",
- "@types/body-parser": "^1.19.5"
+ "@types/body-parser": "^1.19.5",
+ "rimraf": "^6.0.1"
},
"files": [
"genkit-ui",
diff --git a/js/flow/src/flow.ts b/js/flow/src/flow.ts
index 09b533d24a..99138a3b40 100644
--- a/js/flow/src/flow.ts
+++ b/js/flow/src/flow.ts
@@ -16,28 +16,28 @@
import {
Action,
- defineAction,
FlowError,
FlowState,
FlowStateSchema,
FlowStateStore,
+ Operation,
+ StreamingCallback,
+ defineAction,
getStreamingCallback,
config as globalConfig,
isDevEnv,
- Operation,
- StreamingCallback,
} from '@genkit-ai/core';
import { logger } from '@genkit-ai/core/logging';
import { toJsonSchema } from '@genkit-ai/core/schema';
import {
+ SPAN_TYPE_ATTR,
newTrace,
setCustomMetadataAttribute,
setCustomMetadataAttributes,
- SPAN_TYPE_ATTR,
} from '@genkit-ai/core/tracing';
import { SpanStatusCode } from '@opentelemetry/api';
import * as bodyParser from 'body-parser';
-import { default as cors, CorsOptions } from 'cors';
+import { CorsOptions, default as cors } from 'cors';
import express from 'express';
import { performance } from 'node:perf_hooks';
import * as z from 'zod';
@@ -45,9 +45,9 @@ import { Context } from './context.js';
import {
FlowExecutionError,
FlowStillRunningError,
+ InterruptError,
getErrorMessage,
getErrorStack,
- InterruptError,
} from './errors.js';
import {
FlowActionInputSchema,
@@ -638,11 +638,15 @@ export async function runFlow<
);
}
- const state = await flow.runEnvelope({
- start: {
- input,
+ const state = await flow.runEnvelope(
+ {
+ start: {
+ input,
+ },
},
- });
+ undefined,
+ opts?.withLocalAuthContext
+ );
if (!state.operation.done) {
throw new FlowStillRunningError(
`flow ${state.name} did not finish execution`
@@ -704,14 +708,14 @@ export function streamFlow<
},
(c) => {
chunkStreamController.enqueue(c);
- }
+ },
+ opts?.withLocalAuthContext
)
)
- .then((s) => s.operation);
- operationPromise.then((o) => {
- chunkStreamController.close();
- return o;
- });
+ .then((s) => s.operation)
+ .finally(() => {
+ chunkStreamController.close();
+ });
return {
output() {
diff --git a/js/flow/tests/flow_test.ts b/js/flow/tests/flow_test.ts
index ff84ac9524..2951585350 100644
--- a/js/flow/tests/flow_test.ts
+++ b/js/flow/tests/flow_test.ts
@@ -20,6 +20,7 @@ import assert from 'node:assert';
import { beforeEach, describe, it } from 'node:test';
import { z } from 'zod';
import { defineFlow, runFlow, streamFlow } from '../src/flow.js';
+import { getFlowAuth } from '../src/utils.js';
import { configureInMemoryStateStore } from './testUtil.js';
function createTestFlow() {
@@ -35,6 +36,24 @@ function createTestFlow() {
);
}
+function createTestFlowWithAuth() {
+ return defineFlow(
+ {
+ name: 'testFlowWithAuth',
+ inputSchema: z.string(),
+ outputSchema: z.string(),
+ authPolicy: async (auth) => {
+ if (auth != 'open sesame') {
+ throw new Error('forty thieves!');
+ }
+ },
+ },
+ async (input) => {
+ return `foo ${input}, auth ${JSON.stringify(getFlowAuth())}`;
+ }
+ );
+}
+
function createTestStreamingFlow() {
return defineFlow(
{
@@ -115,6 +134,30 @@ describe('flow', () => {
}
);
});
+
+ it('should pass auth context all the way', async () => {
+ configureInMemoryStateStore('prod');
+ const testFlow = createTestFlowWithAuth();
+
+ const result = await runFlow(testFlow, 'bar', {
+ withLocalAuthContext: 'open sesame',
+ });
+
+ assert.equal(result, 'foo bar, auth "open sesame"');
+ });
+
+ it('should fail auth', async () => {
+ configureInMemoryStateStore('prod');
+ const testFlow = createTestFlowWithAuth();
+
+ await assert.rejects(
+ () =>
+ runFlow(testFlow, 'bar', {
+ withLocalAuthContext: 'yolo',
+ }),
+ /forty thieves/
+ );
+ });
});
describe('streamFlow', () => {
@@ -151,6 +194,27 @@ describe('flow', () => {
message: 'bad happened: foo',
});
});
+
+ it('should pass auth context all the way', async () => {
+ configureInMemoryStateStore('prod');
+ const testFlow = createTestFlowWithAuth();
+
+ const result = await streamFlow(testFlow, 'bar', {
+ withLocalAuthContext: 'open sesame',
+ });
+
+ assert.equal(await result.output(), 'foo bar, auth "open sesame"');
+ });
+
+ it('should fail auth', async () => {
+ configureInMemoryStateStore('prod');
+ const testFlow = createTestFlowWithAuth();
+ const response = streamFlow(testFlow, 'bar', {
+ withLocalAuthContext: 'yolo',
+ });
+
+ await assert.rejects(() => response.output(), /forty thieves/);
+ });
});
describe('stateStore', () => {
diff --git a/js/package.json b/js/package.json
index 71054cdc52..5f47a621af 100644
--- a/js/package.json
+++ b/js/package.json
@@ -19,5 +19,5 @@
"only-allow": "^1.2.1",
"typescript": "^4.9.0"
},
- "packageManager": "pnpm@9.10.0+sha256.355a8ab8dbb6ad41befbef39bc4fd6b5df85e12761d2724bd01f13e878de4b13"
+ "packageManager": "pnpm@9.12.0+sha256.a61b67ff6cc97af864564f4442556c22a04f2e5a7714fbee76a1011361d9b726"
}
diff --git a/js/plugins/chroma/package.json b/js/plugins/chroma/package.json
index c33fd7a586..67ee2dcb22 100644
--- a/js/plugins/chroma/package.json
+++ b/js/plugins/chroma/package.json
@@ -13,12 +13,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch"
},
@@ -43,7 +43,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/dev-local-vectorstore/package.json b/js/plugins/dev-local-vectorstore/package.json
index a9b41b3fb6..0bf731593e 100644
--- a/js/plugins/dev-local-vectorstore/package.json
+++ b/js/plugins/dev-local-vectorstore/package.json
@@ -10,12 +10,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch"
},
@@ -40,7 +40,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/dotprompt/package.json b/js/plugins/dotprompt/package.json
index ec881b28b9..ce5a8ce20a 100644
--- a/js/plugins/dotprompt/package.json
+++ b/js/plugins/dotprompt/package.json
@@ -9,12 +9,12 @@
"prompting",
"templating"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "tsx --test tests/*_test.ts"
@@ -42,7 +42,8 @@
"tsup": "^8.0.2",
"tsx": "^4.7.0",
"typescript": "^4.9.0",
- "yaml": "^2.4.1"
+ "yaml": "^2.4.1",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/evaluators/package.json b/js/plugins/evaluators/package.json
index 568234d3dc..19428cde2c 100644
--- a/js/plugins/evaluators/package.json
+++ b/js/plugins/evaluators/package.json
@@ -11,12 +11,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"lint": "eslint --config ../../.eslintrc.js --ext .ts src",
@@ -45,7 +45,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/firebase/package.json b/js/plugins/firebase/package.json
index 084c6644aa..3827319deb 100644
--- a/js/plugins/firebase/package.json
+++ b/js/plugins/firebase/package.json
@@ -13,12 +13,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "node --import tsx --test tests/*_test.ts"
@@ -32,7 +32,7 @@
"license": "Apache-2.0",
"dependencies": {
"@genkit-ai/google-cloud": "workspace:*",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"google-auth-library": "^9.6.3",
"zod": "^3.22.4"
},
@@ -49,7 +49,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/google-cloud/package.json b/js/plugins/google-cloud/package.json
index 8f1b9234f6..57550818f5 100644
--- a/js/plugins/google-cloud/package.json
+++ b/js/plugins/google-cloud/package.json
@@ -13,12 +13,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "tsx --test ./tests/*_test.ts"
@@ -33,8 +33,8 @@
"dependencies": {
"@google-cloud/logging-winston": "^6.0.0",
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.19.0",
- "@google-cloud/opentelemetry-cloud-trace-exporter": "^2.1.0",
- "@google-cloud/opentelemetry-resource-util": "^2.1.0",
+ "@google-cloud/opentelemetry-cloud-trace-exporter": "^2.4.1",
+ "@google-cloud/opentelemetry-resource-util": "^2.4.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.49.1",
"@opentelemetry/core": "^1.25.0",
@@ -48,6 +48,7 @@
"google-auth-library": "^9.6.3",
"node-fetch": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.4",
+ "truncate-utf8-bytes": "^1.0.2",
"winston": "^3.12.0",
"zod": "^3.22.4"
},
@@ -61,7 +62,8 @@
"tsup": "^8.0.2",
"tsx": "^4.7.0",
"typescript": "^4.9.0",
- "@genkit-ai/flow": "workspace:*"
+ "@genkit-ai/flow": "workspace:*",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/google-cloud/src/telemetry/generate.ts b/js/plugins/google-cloud/src/telemetry/generate.ts
index f235a3ab3d..1246b88992 100644
--- a/js/plugins/google-cloud/src/telemetry/generate.ts
+++ b/js/plugins/google-cloud/src/telemetry/generate.ts
@@ -35,6 +35,7 @@ import {
} from '../metrics';
import { ReadableSpan } from '@opentelemetry/sdk-trace-base';
+import truncate from 'truncate-utf8-bytes';
import { Telemetry } from '../metrics';
import {
createCommonLogAttributes,
@@ -60,8 +61,10 @@ class GenerateTelemetry implements Telemetry {
*/
private _N = internalMetricNamespaceWrap.bind(null, 'ai');
- /** The maximum length (in characters) of a logged prompt message. */
- private MAX_LOG_CONTENT_CHARS = 128_000;
+ /** The maximum length (in bytes) of a logged prompt message. The maximum log
+ * size in GCP is 256kb, so using slightly lower for some buffer for the rest
+ * of the message*/
+ private MAX_LOG_CONTENT_BYTES = 200_000;
private actionCounter = new MetricCounter(this._N('generate/requests'), {
description: 'Counts calls to genkit generate actions.',
@@ -299,6 +302,18 @@ class GenerateTelemetry implements Telemetry {
output.candidates.forEach((cand, candIdx) => {
const parts = cand.message.content.length;
+ const candCounts = parts > 1 ? ` (${candIdx + 1} of ${parts})` : '';
+ logger.logStructured(`Output Candidate[${path}, ${model}]${candCounts}`, {
+ ...sharedMetadata,
+ candidateIndex: candIdx,
+ totalCandidates: candidates,
+ messageIndex: cand.index,
+ finishReason: cand.finishReason,
+ finishMessage: cand.finishMessage,
+ role: cand.message.role,
+ usage: cand.usage,
+ custom: cand.custom,
+ });
cand.message.content.forEach((part, partIdx) => {
const partCounts = this.toPartCounts(
partIdx,
@@ -321,6 +336,12 @@ class GenerateTelemetry implements Telemetry {
finishReason: cand.finishReason,
});
});
+ if (output.usage) {
+ logger.logStructured(`Usage[${path}, ${model}]`, {
+ ...sharedMetadata,
+ usage: output.usage,
+ });
+ }
});
}
@@ -366,7 +387,7 @@ class GenerateTelemetry implements Telemetry {
}
private toPartLogText(text: string): string {
- return text.substring(0, this.MAX_LOG_CONTENT_CHARS);
+ return truncate(text, this.MAX_LOG_CONTENT_BYTES);
}
private toPartLogMedia(part: MediaPart): string {
diff --git a/js/plugins/google-cloud/src/utils.ts b/js/plugins/google-cloud/src/utils.ts
index d8ea43cde4..ad6673469c 100644
--- a/js/plugins/google-cloud/src/utils.ts
+++ b/js/plugins/google-cloud/src/utils.ts
@@ -22,7 +22,7 @@ export function extractOuterFlowNameFromPath(path: string) {
return '';
}
- const flowName = path.match('/{(.+),t:flow}+');
+ const flowName = path.match('/{([^,}]+),t:flow}+');
return flowName ? flowName[1] : '';
}
diff --git a/js/plugins/google-cloud/tests/logs_test.ts b/js/plugins/google-cloud/tests/logs_test.ts
index 596c3bb503..127d198a90 100644
--- a/js/plugins/google-cloud/tests/logs_test.ts
+++ b/js/plugins/google-cloud/tests/logs_test.ts
@@ -185,6 +185,18 @@ describe('GoogleCloudLogs no I/O', () => {
logMessages.includes('[info] Output[testFlow, testModel]'),
false
);
+ assert.equal(
+ logMessages.includes(
+ '[info] Output Candidate[testFlow > sub1 > sub2 > testModel, testModel]'
+ ),
+ false
+ );
+ assert.equal(
+ logMessages.includes(
+ '[info] Usage[testFlow > sub1 > sub2 > testModel, testModel]'
+ ),
+ false
+ );
});
});
@@ -336,6 +348,18 @@ describe('GoogleCloudLogs', () => {
logMessages.includes('[info] Output[testFlow, testFlow]'),
true
);
+ assert.equal(
+ logMessages.includes(
+ '[info] Output Candidate[testFlow > sub1 > sub2 > testModel, testModel]'
+ ),
+ true
+ );
+ assert.equal(
+ logMessages.includes(
+ '[info] Usage[testFlow > sub1 > sub2 > testModel, testModel]'
+ ),
+ true
+ );
});
});
diff --git a/js/plugins/google-cloud/tests/metrics_test.ts b/js/plugins/google-cloud/tests/metrics_test.ts
index 2ed07ab955..d343dd43d4 100644
--- a/js/plugins/google-cloud/tests/metrics_test.ts
+++ b/js/plugins/google-cloud/tests/metrics_test.ts
@@ -25,6 +25,7 @@ import {
FlowStateStore,
} from '@genkit-ai/core';
import { registerFlowStateStore } from '@genkit-ai/core/registry';
+import { newTrace } from '@genkit-ai/core/tracing';
import { defineFlow, run, runAction, runFlow } from '@genkit-ai/flow';
import {
__forceFlushSpansForTesting,
@@ -370,7 +371,9 @@ describe('GoogleCloudMetrics', () => {
});
});
- await runFlow(flow);
+ await newTrace({ name: 'dev-run-action-wrapper' }, async (_, span) => {
+ await runFlow(flow);
+ });
await getExportedSpans();
diff --git a/js/plugins/googleai/package.json b/js/plugins/googleai/package.json
index 68f96a9bb2..8c36ba2b62 100644
--- a/js/plugins/googleai/package.json
+++ b/js/plugins/googleai/package.json
@@ -13,12 +13,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "tsx --test ./tests/*_test.ts"
@@ -45,7 +45,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/googleai/src/gemini.ts b/js/plugins/googleai/src/gemini.ts
index 5e1084fd33..22a64e400f 100644
--- a/js/plugins/googleai/src/gemini.ts
+++ b/js/plugins/googleai/src/gemini.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import { extractJson } from '@genkit-ai/ai/extract';
import {
CandidateData,
defineModel,
@@ -80,19 +81,19 @@ export const geminiPro = modelRef({
name: 'googleai/gemini-pro',
info: {
label: 'Google AI - Gemini Pro',
- versions: ['gemini-1.0-pro', 'gemini-1.0-pro-latest', 'gemini-1.0-pro-001'],
supports: {
multiturn: true,
media: false,
tools: true,
systemRole: true,
},
+ versions: ['gemini-1.0-pro', 'gemini-1.0-pro-latest', 'gemini-1.0-pro-001'],
},
configSchema: GeminiConfigSchema,
});
/**
- * @deprecated Use `gemini15Pro` or `gemini15Flash` instead.
+ * @deprecated Use `gemini15Pro`, `gemini15Flash`, or `gemini15flash8B` instead.
*/
export const geminiProVision = modelRef({
name: 'googleai/gemini-pro-vision',
@@ -122,7 +123,12 @@ export const gemini15Pro = modelRef({
systemRole: true,
output: ['text', 'json'],
},
- versions: ['gemini-1.5-pro-001'],
+ versions: [
+ 'gemini-1.5-pro',
+ 'gemini-1.5-pro-001',
+ 'gemini-1.5-pro-002',
+ 'gemini-1.5-pro-exp-0827',
+ ],
},
configSchema: GeminiConfigSchema,
});
@@ -138,7 +144,30 @@ export const gemini15Flash = modelRef({
systemRole: true,
output: ['text', 'json'],
},
- versions: ['gemini-1.5-flash-001'],
+ versions: [
+ 'gemini-1.5-flash',
+ 'gemini-1.5-flash-001',
+ 'gemini-1.5-flash-002',
+ 'gemini-1.5-flash-8b-exp-0924',
+ 'gemini-1.5-flash-8b-exp-0827',
+ 'gemini-1.5-flash-exp-0827',
+ ],
+ },
+ configSchema: GeminiConfigSchema,
+});
+
+export const gemini15Flash8B = modelRef({
+ name: 'googleai/gemini-1.5-flash-8b-latest',
+ info: {
+ label: 'Google AI - Gemini 1.5 Flash-8B',
+ supports: {
+ multiturn: true,
+ media: true,
+ tools: true,
+ systemRole: true,
+ output: ['text', 'json'],
+ },
+ versions: ['gemini-1.5-flash-8b', 'gemini-1.5-flash-8b-001'],
},
configSchema: GeminiConfigSchema,
});
@@ -173,6 +202,7 @@ export const SUPPORTED_V15_MODELS: Record<
> = {
'gemini-1.5-pro-latest': gemini15Pro,
'gemini-1.5-flash-latest': gemini15Flash,
+ 'gemini-1.5-flash-8b-latest': gemini15Flash8B,
};
const SUPPORTED_MODELS = {
@@ -388,7 +418,7 @@ function toGeminiPart(part: Part): GeminiPart {
function fromGeminiPart(part: GeminiPart, jsonMode: boolean): Part {
if (jsonMode && part.text !== undefined) {
- return { data: JSON.parse(part.text) };
+ return { data: extractJson(part.text) };
}
if (part.text !== undefined) return { text: part.text };
if (part.inlineData) return fromInlineData(part);
@@ -534,18 +564,6 @@ export function googleAIModel(
systemInstruction = toGeminiSystemInstruction(systemMessage);
}
}
- const generationConfig: GenerationConfig = {
- candidateCount: request.candidates || undefined,
- temperature: request.config?.temperature,
- maxOutputTokens: request.config?.maxOutputTokens,
- topK: request.config?.topK,
- topP: request.config?.topP,
- stopSequences: request.config?.stopSequences,
- responseMimeType:
- request.output?.format === 'json' || request.output?.schema
- ? 'application/json'
- : undefined,
- };
const tools: Tool[] = [];
@@ -564,6 +582,21 @@ export function googleAIModel(
});
}
+ // cannot use tools with json mode
+ const jsonMode =
+ (request.output?.format === 'json' || !!request.output?.schema) &&
+ tools.length === 0;
+
+ const generationConfig: GenerationConfig = {
+ candidateCount: request.candidates || undefined,
+ temperature: request.config?.temperature,
+ maxOutputTokens: request.config?.maxOutputTokens,
+ topK: request.config?.topK,
+ topP: request.config?.topP,
+ stopSequences: request.config?.stopSequences,
+ responseMimeType: jsonMode ? 'application/json' : undefined,
+ };
+
const chatRequest = {
systemInstruction,
generationConfig,
@@ -574,8 +607,6 @@ export function googleAIModel(
safetySettings: request.config?.safetySettings,
} as StartChatParams;
const msg = toGeminiMessage(messages[messages.length - 1], model);
- const jsonMode =
- request.output?.format === 'json' || !!request.output?.schema;
const fromJSONModeScopedGeminiCandidate = (
candidate: GeminiCandidate
) => {
diff --git a/js/plugins/googleai/src/index.ts b/js/plugins/googleai/src/index.ts
index f55c2f15f6..848ffb9ae8 100644
--- a/js/plugins/googleai/src/index.ts
+++ b/js/plugins/googleai/src/index.ts
@@ -22,6 +22,7 @@ import {
} from './embedder.js';
import {
gemini15Flash,
+ gemini15Flash8B,
gemini15Pro,
geminiPro,
geminiProVision,
@@ -31,6 +32,7 @@ import {
} from './gemini.js';
export {
gemini15Flash,
+ gemini15Flash8B,
gemini15Pro,
geminiPro,
geminiProVision,
diff --git a/js/plugins/langchain/package.json b/js/plugins/langchain/package.json
index a61fd39e01..a0e8b2f76f 100644
--- a/js/plugins/langchain/package.json
+++ b/js/plugins/langchain/package.json
@@ -9,12 +9,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch"
},
@@ -42,7 +42,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/ollama/package.json b/js/plugins/ollama/package.json
index 1d5b887260..0c76c0c17f 100644
--- a/js/plugins/ollama/package.json
+++ b/js/plugins/ollama/package.json
@@ -10,12 +10,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch"
},
@@ -26,6 +26,9 @@
},
"author": "genkit",
"license": "Apache-2.0",
+ "dependencies": {
+ "zod": "^3.22.4"
+ },
"peerDependencies": {
"@genkit-ai/ai": "workspace:*",
"@genkit-ai/core": "workspace:*"
@@ -35,7 +38,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/ollama/src/embeddings.ts b/js/plugins/ollama/src/embeddings.ts
new file mode 100644
index 0000000000..0b991672fb
--- /dev/null
+++ b/js/plugins/ollama/src/embeddings.ts
@@ -0,0 +1,96 @@
+/**
+ * Copyright 2024 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 { defineEmbedder } from '@genkit-ai/ai/embedder';
+import { logger } from '@genkit-ai/core/logging';
+import z from 'zod';
+import { OllamaPluginParams } from './index.js';
+// Define the schema for Ollama embedding configuration
+export const OllamaEmbeddingConfigSchema = z.object({
+ modelName: z.string(),
+ serverAddress: z.string(),
+});
+export type OllamaEmbeddingConfig = z.infer;
+// Define the structure of the request and response for embedding
+interface OllamaEmbeddingInstance {
+ content: string;
+}
+interface OllamaEmbeddingPrediction {
+ embedding: number[];
+}
+interface DefineOllamaEmbeddingParams {
+ name: string;
+ modelName: string;
+ dimensions: number;
+ options: OllamaPluginParams;
+}
+export function defineOllamaEmbedder({
+ name,
+ modelName,
+ dimensions,
+ options,
+}: DefineOllamaEmbeddingParams) {
+ return defineEmbedder(
+ {
+ name,
+ configSchema: OllamaEmbeddingConfigSchema, // Use the Zod schema directly here
+ info: {
+ // TODO: do we want users to be able to specify the label when they call this method directly?
+ label: 'Ollama Embedding - ' + modelName,
+ dimensions,
+ supports: {
+ // TODO: do any ollama models support other modalities?
+ input: ['text'],
+ },
+ },
+ },
+ async (input, _config) => {
+ const serverAddress = options.serverAddress;
+ const responses = await Promise.all(
+ input.map(async (i) => {
+ const requestPayload = {
+ model: modelName,
+ prompt: i.text(),
+ };
+ let res: Response;
+ try {
+ console.log('MODEL NAME: ', modelName);
+ res = await fetch(`${serverAddress}/api/embeddings`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(requestPayload),
+ });
+ } catch (e) {
+ logger.error('Failed to fetch Ollama embedding');
+ throw new Error(`Error fetching embedding from Ollama: ${e}`);
+ }
+ if (!res.ok) {
+ logger.error('Failed to fetch Ollama embedding');
+ throw new Error(
+ `Error fetching embedding from Ollama: ${res.statusText}`
+ );
+ }
+ const responseData = (await res.json()) as OllamaEmbeddingPrediction;
+ return responseData;
+ })
+ );
+ return {
+ embeddings: responses,
+ };
+ }
+ );
+}
diff --git a/js/plugins/ollama/src/index.ts b/js/plugins/ollama/src/index.ts
index 7a7bbb636c..8e5b7ceef6 100644
--- a/js/plugins/ollama/src/index.ts
+++ b/js/plugins/ollama/src/index.ts
@@ -25,6 +25,7 @@ import {
} from '@genkit-ai/ai/model';
import { genkitPlugin, Plugin } from '@genkit-ai/core';
import { logger } from '@genkit-ai/core/logging';
+import { defineOllamaEmbedder } from './embeddings';
type ApiType = 'chat' | 'generate';
@@ -36,9 +37,10 @@ type RequestHeaders =
) => Promise | void>);
type ModelDefinition = { name: string; type?: ApiType };
-
+type EmbeddingModelDefinition = { name: string; dimensions: number };
export interface OllamaPluginParams {
models: ModelDefinition[];
+ embeddingModels?: EmbeddingModelDefinition[];
/**
* ollama server address.
*/
@@ -55,6 +57,14 @@ export const ollama: Plugin<[OllamaPluginParams]> = genkitPlugin(
models: params.models.map((model) =>
ollamaModel(model, serverAddress, params.requestHeaders)
),
+ embedders: params.embeddingModels?.map((model) =>
+ defineOllamaEmbedder({
+ name: `${ollama}/model.name`,
+ modelName: model.name,
+ dimensions: model.dimensions,
+ options: params,
+ })
+ ),
};
}
);
diff --git a/js/plugins/ollama/tests/embeddings_live_test.ts b/js/plugins/ollama/tests/embeddings_live_test.ts
new file mode 100644
index 0000000000..f89500df1c
--- /dev/null
+++ b/js/plugins/ollama/tests/embeddings_live_test.ts
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2024 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 { embed } from '@genkit-ai/ai/embedder';
+import assert from 'node:assert';
+import { describe, it } from 'node:test';
+import { defineOllamaEmbedder } from '../src/embeddings.js'; // Adjust the import path as necessary
+import { OllamaPluginParams } from '../src/index.js'; // Adjust the import path as necessary
+// Utility function to parse command-line arguments
+function parseArgs() {
+ const args = process.argv.slice(2);
+ const serverAddress =
+ args.find((arg) => arg.startsWith('--server-address='))?.split('=')[1] ||
+ 'http://localhost:11434';
+ const modelName =
+ args.find((arg) => arg.startsWith('--model-name='))?.split('=')[1] ||
+ 'nomic-embed-text';
+ return { serverAddress, modelName };
+}
+const { serverAddress, modelName } = parseArgs();
+describe('defineOllamaEmbedder - Live Tests', () => {
+ const options: OllamaPluginParams = {
+ models: [{ name: modelName }],
+ serverAddress,
+ };
+ it('should successfully return embeddings', async () => {
+ const embedder = defineOllamaEmbedder({
+ name: 'live-test-embedder',
+ modelName: 'nomic-embed-text',
+ dimensions: 768,
+ options,
+ });
+ const result = await embed({
+ embedder,
+ content: 'Hello, world!',
+ });
+ assert.strictEqual(result.length, 768);
+ });
+});
diff --git a/js/plugins/ollama/tests/embeddings_test.ts b/js/plugins/ollama/tests/embeddings_test.ts
new file mode 100644
index 0000000000..61255028a4
--- /dev/null
+++ b/js/plugins/ollama/tests/embeddings_test.ts
@@ -0,0 +1,119 @@
+/**
+ * Copyright 2024 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 { embed } from '@genkit-ai/ai/embedder';
+import assert from 'node:assert';
+import { describe, it } from 'node:test';
+import {
+ OllamaEmbeddingConfigSchema,
+ defineOllamaEmbedder,
+} from '../src/embeddings.js'; // Adjust the import path as necessary
+import { OllamaPluginParams } from '../src/index.js'; // Adjust the import path as necessary
+// Mock fetch to simulate API responses
+global.fetch = async (input: RequestInfo | URL, options?: RequestInit) => {
+ const url = typeof input === 'string' ? input : input.toString();
+ if (url.includes('/api/embedding')) {
+ if (options?.body && JSON.stringify(options.body).includes('fail')) {
+ return {
+ ok: false,
+ statusText: 'Internal Server Error',
+ json: async () => ({}),
+ } as Response;
+ }
+ return {
+ ok: true,
+ json: async () => ({
+ embedding: [0.1, 0.2, 0.3], // Example embedding values
+ }),
+ } as Response;
+ }
+ throw new Error('Unknown API endpoint');
+};
+describe('defineOllamaEmbedder', () => {
+ const options: OllamaPluginParams = {
+ models: [{ name: 'test-model' }],
+ serverAddress: 'http://localhost:3000',
+ };
+ it('should successfully return embeddings', async () => {
+ const embedder = defineOllamaEmbedder({
+ name: 'test-embedder',
+ modelName: 'test-model',
+ dimensions: 123,
+ options,
+ });
+ const result = await embed({
+ embedder,
+ content: 'Hello, world!',
+ });
+ assert.deepStrictEqual(result, [0.1, 0.2, 0.3]);
+ });
+ it('should handle API errors correctly', async () => {
+ const embedder = defineOllamaEmbedder({
+ name: 'test-embedder',
+ modelName: 'test-model',
+ dimensions: 123,
+ options,
+ });
+ await assert.rejects(
+ async () => {
+ await embed({
+ embedder,
+ content: 'fail',
+ });
+ },
+ (error) => {
+ // Check if error is an instance of Error
+ assert(error instanceof Error);
+ assert.strictEqual(
+ error.message,
+ 'Error fetching embedding from Ollama: Internal Server Error'
+ );
+ return true;
+ }
+ );
+ });
+ it('should validate the embedding configuration schema', async () => {
+ const validConfig = {
+ modelName: 'test-model',
+ serverAddress: 'http://localhost:3000',
+ };
+ const invalidConfig = {
+ modelName: 123, // Invalid type
+ serverAddress: 'http://localhost:3000',
+ };
+ // Valid configuration should pass
+ assert.doesNotThrow(() => {
+ OllamaEmbeddingConfigSchema.parse(validConfig);
+ });
+ // Invalid configuration should throw
+ assert.throws(() => {
+ OllamaEmbeddingConfigSchema.parse(invalidConfig);
+ });
+ });
+ it('should throw an error if the fetch response is not ok', async () => {
+ const embedder = defineOllamaEmbedder({
+ name: 'test-embedder',
+ modelName: 'test-model',
+ dimensions: 123,
+ options,
+ });
+ await assert.rejects(async () => {
+ await embed({
+ embedder,
+ content: 'fail',
+ });
+ }, new Error('Error fetching embedding from Ollama: Internal Server Error'));
+ });
+});
diff --git a/js/plugins/pinecone/package.json b/js/plugins/pinecone/package.json
index fc5d73b58d..27b1a47fc7 100644
--- a/js/plugins/pinecone/package.json
+++ b/js/plugins/pinecone/package.json
@@ -13,12 +13,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch"
},
@@ -43,7 +43,8 @@
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/vertexai/package.json b/js/plugins/vertexai/package.json
index f6aac424ad..47e77e0298 100644
--- a/js/plugins/vertexai/package.json
+++ b/js/plugins/vertexai/package.json
@@ -17,12 +17,12 @@
"genai",
"generative-ai"
],
- "version": "0.5.13",
+ "version": "0.5.16",
"type": "commonjs",
"scripts": {
"check": "tsc",
"compile": "tsup-node",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build": "npm-run-all build:clean check compile",
"build:watch": "tsup-node --watch",
"test": "tsx --test ./tests/**/*_test.ts"
@@ -38,8 +38,8 @@
"@anthropic-ai/sdk": "^0.24.3",
"@anthropic-ai/vertex-sdk": "^0.4.0",
"@google-cloud/aiplatform": "^3.23.0",
- "@google-cloud/vertexai": "^1.1.0",
- "google-auth-library": "^9.6.3",
+ "@google-cloud/vertexai": "^1.7.0",
+ "google-auth-library": "^9.14.1",
"googleapis": "^140.0.1",
"node-fetch": "^3.3.2",
"openai": "^4.52.7",
@@ -51,15 +51,16 @@
"@genkit-ai/flow": "workspace:*"
},
"optionalDependencies": {
- "firebase-admin": "^12.1.0",
- "@google-cloud/bigquery": "^7.8.0"
+ "@google-cloud/bigquery": "^7.8.0",
+ "firebase-admin": "^12.1.0"
},
"devDependencies": {
"@types/node": "^20.11.16",
"npm-run-all": "^4.1.5",
"tsup": "^8.0.2",
"tsx": "^4.7.0",
- "typescript": "^4.9.0"
+ "typescript": "^4.9.0",
+ "rimraf": "^6.0.1"
},
"types": "./lib/index.d.ts",
"exports": {
diff --git a/js/plugins/vertexai/src/gemini.ts b/js/plugins/vertexai/src/gemini.ts
index 49d347bce8..0ad11216b3 100644
--- a/js/plugins/vertexai/src/gemini.ts
+++ b/js/plugins/vertexai/src/gemini.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import { extractJson } from '@genkit-ai/ai/extract';
import {
CandidateData,
defineModel,
@@ -79,7 +80,7 @@ export const geminiPro = modelRef({
name: 'vertexai/gemini-1.0-pro',
info: {
label: 'Vertex AI - Gemini Pro',
- versions: ['gemini-1.0-pro', 'gemini-1.0-pro-001'],
+ versions: ['gemini-1.0-pro', 'gemini-1.0-pro-001', 'gemini-1.0-pro-002'],
supports: {
multiturn: true,
media: false,
@@ -112,7 +113,11 @@ export const gemini15Pro = modelRef({
name: 'vertexai/gemini-1.5-pro',
info: {
label: 'Vertex AI - Gemini 1.5 Pro',
- versions: ['gemini-1.5-pro-001'],
+ versions: [
+ 'gemini-1.5-pro-001',
+ 'gemini-1.5-pro-002',
+ 'gemini-pro-experimental',
+ ],
supports: {
multiturn: true,
media: true,
@@ -159,7 +164,11 @@ export const gemini15Flash = modelRef({
name: 'vertexai/gemini-1.5-flash',
info: {
label: 'Vertex AI - Gemini 1.5 Flash',
- versions: ['gemini-1.5-flash-001'],
+ versions: [
+ 'gemini-1.5-flash-001',
+ 'gemini-1.5-flash-002',
+ 'gemini-flash-experimental',
+ ],
supports: {
multiturn: true,
media: true,
@@ -399,7 +408,10 @@ function fromGeminiFunctionResponsePart(part: GeminiPart): Part {
}
// Converts vertex part to genkit part
-function fromGeminiPart(part: GeminiPart): Part {
+function fromGeminiPart(part: GeminiPart, jsonMode: boolean): Part {
+ if (jsonMode && part.text !== undefined) {
+ return { data: extractJson(part.text) };
+ }
if (part.text !== undefined) return { text: part.text };
if (part.functionCall) return fromGeminiFunctionCallPart(part);
if (part.functionResponse) return fromGeminiFunctionResponsePart(part);
@@ -411,14 +423,15 @@ function fromGeminiPart(part: GeminiPart): Part {
}
export function fromGeminiCandidate(
- candidate: GenerateContentCandidate
+ candidate: GenerateContentCandidate,
+ jsonMode: boolean
): CandidateData {
const parts = candidate.content.parts || [];
const genkitCandidate: CandidateData = {
index: candidate.index || 0, // reasonable default?
message: {
role: 'model',
- content: parts.map(fromGeminiPart),
+ content: parts.map((p) => fromGeminiPart(p, jsonMode)),
},
finishReason: fromGeminiFinishReason(candidate.finishReason),
finishMessage: candidate.finishMessage,
@@ -518,11 +531,18 @@ export function geminiModel(
}
}
+ const tools = request.tools?.length
+ ? [{ functionDeclarations: request.tools?.map(toGeminiTool) }]
+ : [];
+
+ // Cannot use tools and function calling at the same time
+ const jsonMode =
+ (request.output?.format === 'json' || !!request.output?.schema) &&
+ tools.length === 0;
+
const chatRequest: StartChatParams = {
systemInstruction,
- tools: request.tools?.length
- ? [{ functionDeclarations: request.tools?.map(toGeminiTool) }]
- : [],
+ tools,
history: messages
.slice(0, -1)
.map((message) => toGeminiMessage(message, model)),
@@ -532,6 +552,7 @@ export function geminiModel(
maxOutputTokens: request.config?.maxOutputTokens,
topK: request.config?.topK,
topP: request.config?.topP,
+ responseMimeType: jsonMode ? 'application/json' : undefined,
stopSequences: request.config?.stopSequences,
},
safetySettings: request.config?.safetySettings,
@@ -566,7 +587,7 @@ export function geminiModel(
.sendMessageStream(msg.parts);
for await (const item of result.stream) {
(item as GenerateContentResponse).candidates?.forEach((candidate) => {
- const c = fromGeminiCandidate(candidate);
+ const c = fromGeminiCandidate(candidate, jsonMode);
streamingCallback({
index: c.index,
content: c.message.content,
@@ -578,7 +599,9 @@ export function geminiModel(
throw new Error('No valid candidates returned.');
}
return {
- candidates: response.candidates?.map(fromGeminiCandidate) || [],
+ candidates:
+ response.candidates?.map((c) => fromGeminiCandidate(c, jsonMode)) ||
+ [],
custom: response,
};
} else {
@@ -592,7 +615,9 @@ export function geminiModel(
throw new Error('No valid candidates returned.');
}
const responseCandidates =
- result.response.candidates?.map(fromGeminiCandidate) || [];
+ result.response.candidates?.map((c) =>
+ fromGeminiCandidate(c, jsonMode)
+ ) || [];
return {
candidates: responseCandidates,
custom: result.response,
diff --git a/js/plugins/vertexai/src/imagen.ts b/js/plugins/vertexai/src/imagen.ts
index 8c9e41c564..d961e6bd57 100644
--- a/js/plugins/vertexai/src/imagen.ts
+++ b/js/plugins/vertexai/src/imagen.ts
@@ -61,7 +61,40 @@ const ImagenConfigSchema = GenerationCommonConfigSchema.extend({
addWatermark: z.boolean().optional(),
/** Cloud Storage URI to store the generated images. **/
storageUri: z.string().optional(),
-});
+ /** Mode must be set for upscaling requests. */
+ mode: z.enum(['upscale']).optional(),
+ /**
+ * Describes the editing intention for the request.
+ *
+ * Refer to https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#edit_images_2 for details.
+ */
+ editConfig: z
+ .object({
+ /** Describes the editing intention for the request. */
+ editMode: z
+ .enum([
+ 'inpainting-insert',
+ 'inpainting-remove',
+ 'outpainting',
+ 'product-image',
+ ])
+ .optional(),
+ /** Prompts the model to generate a mask instead of you needing to provide one. Consequently, when you provide this parameter you can omit a mask object. */
+ maskMode: z
+ .object({
+ maskType: z.enum(['background', 'foreground', 'semantic']),
+ classes: z.array(z.number()).optional(),
+ })
+ .optional(),
+ maskDilation: z.number().optional(),
+ guidanceScale: z.number().optional(),
+ productPosition: z.enum(['reposition', 'fixed']).optional(),
+ })
+ .passthrough()
+ .optional(),
+ /** Upscale config object. */
+ upscaleConfig: z.object({ upscaleFactor: z.enum(['x2', 'x4']) }).optional(),
+}).passthrough();
export const imagen2 = modelRef({
name: 'vertexai/imagen2',
@@ -86,7 +119,7 @@ export const imagen3 = modelRef({
label: 'Vertex AI - Imagen3',
versions: ['imagen-3.0-generate-001'],
supports: {
- media: false,
+ media: true,
multiturn: false,
tools: false,
systemRole: false,
@@ -144,14 +177,7 @@ function toParameters(
): ImagenParameters {
const out = {
sampleCount: request.candidates ?? 1,
- aspectRatio: request.config?.aspectRatio,
- negativePrompt: request.config?.negativePrompt,
- seed: request.config?.seed,
- language: request.config?.language,
- personGeneration: request.config?.personGeneration,
- safetySetting: request.config?.safetySetting,
- addWatermark: request.config?.addWatermark,
- storageUri: request.config?.storageUri,
+ ...request?.config,
};
for (const k in out) {
@@ -161,10 +187,19 @@ function toParameters(
return out;
}
-function extractPromptImage(request: GenerateRequest): string | undefined {
+function extractMaskImage(request: GenerateRequest): string | undefined {
+ return request.messages
+ .at(-1)
+ ?.content.find((p) => !!p.media && p.metadata?.type === 'mask')
+ ?.media?.url.split(',')[1];
+}
+
+function extractBaseImage(request: GenerateRequest): string | undefined {
return request.messages
.at(-1)
- ?.content.find((p) => !!p.media)
+ ?.content.find(
+ (p) => !!p.media && (!p.metadata?.type || p.metadata?.type === 'base')
+ )
?.media?.url.split(',')[1];
}
@@ -176,6 +211,7 @@ interface ImagenPrediction {
interface ImagenInstance {
prompt: string;
image?: { bytesBase64Encoded: string };
+ mask?: { image?: { bytesBase64Encoded: string } };
}
export function imagenModel(
@@ -222,8 +258,16 @@ export function imagenModel(
const instance: ImagenInstance = {
prompt: extractText(request),
};
- if (extractPromptImage(request))
- instance.image = { bytesBase64Encoded: extractPromptImage(request)! };
+ const baseImage = extractBaseImage(request);
+ if (baseImage) {
+ instance.image = { bytesBase64Encoded: baseImage };
+ }
+ const maskImage = extractMaskImage(request);
+ if (maskImage) {
+ instance.mask = {
+ image: { bytesBase64Encoded: maskImage },
+ };
+ }
const req: any = {
instances: [instance],
diff --git a/js/plugins/vertexai/src/index.ts b/js/plugins/vertexai/src/index.ts
index 81cb22eb72..a0b5990269 100644
--- a/js/plugins/vertexai/src/index.ts
+++ b/js/plugins/vertexai/src/index.ts
@@ -66,6 +66,7 @@ import {
SUPPORTED_OPENAI_FORMAT_MODELS,
llama3,
llama31,
+ llama32,
modelGardenOpenaiCompatibleModel,
} from './model_garden.js';
import {
@@ -104,6 +105,7 @@ export {
imagen3Fast,
llama3,
llama31,
+ llama32,
textEmbedding004,
textEmbeddingGecko,
textEmbeddingGecko001,
diff --git a/js/plugins/vertexai/src/model_garden.ts b/js/plugins/vertexai/src/model_garden.ts
index 96b5694261..3d493fb793 100644
--- a/js/plugins/vertexai/src/model_garden.ts
+++ b/js/plugins/vertexai/src/model_garden.ts
@@ -29,6 +29,23 @@ export const ModelGardenModelConfigSchema = OpenAIConfigSchema.extend({
location: z.string().optional(),
});
+export const llama32 = modelRef({
+ name: 'vertexai/llama-3.2',
+ info: {
+ label: 'Llama 3.2',
+ supports: {
+ multiturn: true,
+ tools: true,
+ media: true,
+ systemRole: true,
+ output: ['text', 'json'],
+ },
+ versions: ['meta/llama-3.2-90b-vision-instruct-maas'],
+ },
+ configSchema: ModelGardenModelConfigSchema,
+ version: 'meta/llama-3.2-90b-vision-instruct-maas',
+});
+
export const llama31 = modelRef({
name: 'vertexai/llama-3.1',
info: {
@@ -72,6 +89,7 @@ export const llama3 = modelRef({
export const SUPPORTED_OPENAI_FORMAT_MODELS = {
'llama3-405b': llama3,
'llama-3.1': llama31,
+ 'llama-3.2': llama32,
};
export function modelGardenOpenaiCompatibleModel(
@@ -87,7 +105,6 @@ export function modelGardenOpenaiCompatibleModel(
baseUrlTemplate =
'https://{location}-aiplatform.googleapis.com/v1beta1/projects/{projectId}/locations/{location}/endpoints/openapi';
}
-
const clientFactory = async (
request: GenerateRequest
): Promise => {
diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml
index 1c97b84df7..20d959f513 100644
--- a/js/pnpm-lock.yaml
+++ b/js/pnpm-lock.yaml
@@ -48,6 +48,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -88,8 +91,8 @@ importers:
specifier: ^0.5.0
version: 0.5.0
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
json-schema:
specifier: ^0.4.0
version: 0.4.0
@@ -109,6 +112,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -134,14 +140,14 @@ importers:
specifier: ^2.8.17
version: 2.8.17
body-parser:
- specifier: ^1.20.2
- version: 1.20.2
+ specifier: ^1.20.3
+ version: 1.20.3
cors:
specifier: ^2.8.5
version: 2.8.5
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
firebase-admin:
specifier: ^12.1.0
version: 12.1.0(encoding@0.1.13)
@@ -167,6 +173,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -201,6 +210,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -235,6 +247,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -272,6 +287,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -315,6 +333,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -343,8 +364,8 @@ importers:
specifier: ^7.6.0
version: 7.6.0(encoding@0.1.13)
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
firebase-admin:
specifier: ^12.2.0
version: 12.2.0(encoding@0.1.13)
@@ -364,6 +385,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -389,11 +413,11 @@ importers:
specifier: ^0.19.0
version: 0.19.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)
'@google-cloud/opentelemetry-cloud-trace-exporter':
- specifier: ^2.1.0
- version: 2.1.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.26.0)(encoding@0.1.13)
+ specifier: ^2.4.1
+ version: 2.4.1(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)
'@google-cloud/opentelemetry-resource-util':
- specifier: ^2.1.0
- version: 2.1.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.26.0)(encoding@0.1.13)
+ specifier: ^2.4.0
+ version: 2.4.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)
'@opentelemetry/api':
specifier: ^1.9.0
version: 1.9.0
@@ -433,6 +457,9 @@ importers:
prettier-plugin-organize-imports:
specifier: ^3.2.4
version: 3.2.4(prettier@3.2.5)(typescript@4.9.5)
+ truncate-utf8-bytes:
+ specifier: ^1.0.2
+ version: 1.0.2
winston:
specifier: ^3.12.0
version: 3.13.0
@@ -449,6 +476,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -486,6 +516,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -529,6 +562,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -547,6 +583,9 @@ importers:
'@genkit-ai/core':
specifier: workspace:*
version: link:../../core
+ zod:
+ specifier: ^3.22.4
+ version: 3.22.4
devDependencies:
'@types/node':
specifier: ^20.11.16
@@ -554,6 +593,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -588,6 +630,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -619,11 +664,11 @@ importers:
specifier: ^3.23.0
version: 3.25.0(encoding@0.1.13)
'@google-cloud/vertexai':
- specifier: ^1.1.0
- version: 1.1.0(encoding@0.1.13)
+ specifier: ^1.7.0
+ version: 1.7.0(encoding@0.1.13)
google-auth-library:
- specifier: ^9.6.3
- version: 9.7.0(encoding@0.1.13)
+ specifier: ^9.14.1
+ version: 9.14.1(encoding@0.1.13)
googleapis:
specifier: ^140.0.1
version: 140.0.1(encoding@0.1.13)
@@ -650,6 +695,9 @@ importers:
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
tsup:
specifier: ^8.0.2
version: 8.0.2(typescript@4.9.5)
@@ -681,8 +729,8 @@ importers:
specifier: workspace:*
version: link:../../plugins/vertexai
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
zod:
specifier: 3.22.4
version: 3.22.4
@@ -691,6 +739,37 @@ importers:
specifier: ^5.5.3
version: 5.5.3
+ testapps/basic-gemini:
+ dependencies:
+ '@genkit-ai/ai':
+ specifier: workspace:*
+ version: link:../../ai
+ '@genkit-ai/core':
+ specifier: workspace:*
+ version: link:../../core
+ '@genkit-ai/dotprompt':
+ specifier: workspace:*
+ version: link:../../plugins/dotprompt
+ '@genkit-ai/flow':
+ specifier: workspace:*
+ version: link:../../flow
+ '@genkit-ai/googleai':
+ specifier: workspace:*
+ version: link:../../plugins/googleai
+ '@genkit-ai/vertexai':
+ specifier: workspace:*
+ version: link:../../plugins/vertexai
+ express:
+ specifier: ^4.21.0
+ version: 4.21.0
+ zod:
+ specifier: ^3.22.4
+ version: 3.22.4
+ devDependencies:
+ typescript:
+ specifier: ^5.6.2
+ version: 5.6.2
+
testapps/byo-evaluator:
dependencies:
'@genkit-ai/ai':
@@ -727,6 +806,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -791,6 +873,9 @@ importers:
'@types/pdf-parse':
specifier: ^1.1.4
version: 1.1.4
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -840,6 +925,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -862,12 +950,15 @@ importers:
specifier: workspace:*
version: link:../../plugins/googleai
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
zod:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -905,6 +996,9 @@ importers:
'@types/pdf-parse':
specifier: ^1.1.4
version: 1.1.4
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -933,6 +1027,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -967,6 +1064,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -992,8 +1092,8 @@ importers:
specifier: workspace:*
version: link:../../plugins/vertexai
express:
- specifier: ~4.19.2
- version: 4.19.2
+ specifier: ~4.20.0
+ version: 4.20.0
genkitx-ollama:
specifier: workspace:*
version: link:../../plugins/ollama
@@ -1004,6 +1104,9 @@ importers:
'@types/express':
specifier: ^4.17.21
version: 4.17.21
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -1023,6 +1126,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -1069,6 +1175,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -1097,8 +1206,8 @@ importers:
specifier: ^16.4.5
version: 16.4.5
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
zod:
specifier: 3.22.4
version: 3.22.4
@@ -1137,8 +1246,8 @@ importers:
specifier: ^1.9.0
version: 1.9.0
express:
- specifier: ~4.19.2
- version: 4.19.2
+ specifier: ~4.20.0
+ version: 4.20.0
genkitx-langchain:
specifier: workspace:*
version: link:../../plugins/langchain
@@ -1158,6 +1267,9 @@ importers:
'@types/express':
specifier: ^4.17.21
version: 4.17.21
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -1183,6 +1295,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -1217,6 +1332,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.3.3
version: 5.4.5
@@ -1346,8 +1464,8 @@ importers:
specifier: ^16.4.5
version: 16.4.5
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
genkitx-chromadb:
specifier: workspace:*
version: link:../../plugins/chroma
@@ -1364,6 +1482,9 @@ importers:
specifier: 3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.5.2
version: 5.5.3
@@ -1404,8 +1525,8 @@ importers:
specifier: ^16.4.5
version: 16.4.5
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
genkitx-chromadb:
specifier: workspace:*
version: link:../../plugins/chroma
@@ -1422,6 +1543,9 @@ importers:
specifier: 3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.5.2
version: 5.5.3
@@ -1459,8 +1583,8 @@ importers:
specifier: ^16.4.5
version: 16.4.5
express:
- specifier: ^4.19.2
- version: 4.19.2
+ specifier: ^4.21.0
+ version: 4.21.0
firebase-admin:
specifier: ^12.1.0
version: 12.2.0(encoding@0.1.13)
@@ -1480,6 +1604,9 @@ importers:
specifier: 3.22.4
version: 3.22.4
devDependencies:
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
typescript:
specifier: ^5.5.2
version: 5.5.3
@@ -1704,8 +1831,8 @@ packages:
peerDependencies:
winston: '>=3.2.1'
- '@google-cloud/logging@11.0.0':
- resolution: {integrity: sha512-uQeReiVICoV5yt9J/cczNxHxqzTkLLG7yGHXCMAk/wQNVZGevT4Bi7CBWpt0aXxm044a76Aj6V08cCAlBj7UZw==}
+ '@google-cloud/logging@11.2.0':
+ resolution: {integrity: sha512-Ma94jvuoMpbgNniwtelOt8w82hxK62FuOXZonEv0Hyk3B+/YVuLG/SWNyY9yMso/RXnPEc1fP2qo9kDrjf/b2w==}
engines: {node: '>=14.0.0'}
'@google-cloud/opentelemetry-cloud-monitoring-exporter@0.19.0':
@@ -1717,8 +1844,8 @@ packages:
'@opentelemetry/resources': ^1.0.0
'@opentelemetry/sdk-metrics': ^1.0.0
- '@google-cloud/opentelemetry-cloud-trace-exporter@2.1.0':
- resolution: {integrity: sha512-6IPFnWG4edDgNfgLxXJjTjNYGAW8ZQ7Oz7eGZJMgQsIiEALNIAk4e/MgccglL3yh5ReONY3YePcGRWQKPbxmUg==}
+ '@google-cloud/opentelemetry-cloud-trace-exporter@2.4.1':
+ resolution: {integrity: sha512-Dq2IyAyA9PCjbjLOn86i2byjkYPC59b5ic8k/L4q5bBWH0Jro8lzMs8C0G5pJfqh2druj8HF+oAIAlSdWQ+Z9Q==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.0.0
@@ -1726,15 +1853,8 @@ packages:
'@opentelemetry/resources': ^1.0.0
'@opentelemetry/sdk-trace-base': ^1.0.0
- '@google-cloud/opentelemetry-resource-util@2.1.0':
- resolution: {integrity: sha512-/Qqnm6f10e89Txt39qpIhD+LCOF80artYOVwNF1ZAzgJFxBldEniNkf19SR+q9LAp75ZZWKyhRlumM1V7fT8gw==}
- engines: {node: '>=14'}
- peerDependencies:
- '@opentelemetry/resources': ^1.0.0
- '@opentelemetry/semantic-conventions': ^1.0.0
-
- '@google-cloud/opentelemetry-resource-util@2.3.0':
- resolution: {integrity: sha512-3yyG2IiOWXy23IIGW4rRaqVf0efsgkUyXLvDpCxiZPPIgSAevYVdfcJ2cQSp4d1y+2NCpS2Wq0XLbTLzTw/j5Q==}
+ '@google-cloud/opentelemetry-resource-util@2.4.0':
+ resolution: {integrity: sha512-/7ujlMoKtDtrbQlJihCjQnm31n2s2RTlvJqcSbt2jV3OkCzPAdo3u31Q13HNugqtIRUSk7bUoLx6AzhURkhW4w==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/resources': ^1.0.0
@@ -1763,8 +1883,8 @@ packages:
resolution: {integrity: sha512-sZW14pfxEQZSIbBPs6doFYtcbK31Bs3E4jH5Ly3jJnBkYfkMPX8sXG3ZQXCJa88MKtUNPlgBdMN2OJUzmFe5/g==}
engines: {node: '>=14'}
- '@google-cloud/vertexai@1.1.0':
- resolution: {integrity: sha512-hfwfdlVpJ+kM6o2b5UFfPnweBcz8tgHAFRswnqUKYqLJsvKU0DDD0Z2/YKoHyAUoPJAv20qg6KlC3msNeUKUiw==}
+ '@google-cloud/vertexai@1.7.0':
+ resolution: {integrity: sha512-N4YcVzFQ+sPN9c3SeMhbpLfWVbeaLxPbICKsJ6yKthcr4G7tdu9pCs3HUw+Mip0M2xgiKZ8/WWvq6FXbPnlrUA==}
engines: {node: '>=18.0.0'}
'@google/generative-ai@0.15.0':
@@ -2929,6 +3049,10 @@ packages:
resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+ body-parser@1.20.3:
+ resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@@ -3241,6 +3365,10 @@ packages:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
encoding@0.1.13:
resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
@@ -3324,8 +3452,12 @@ packages:
expr-eval@2.0.2:
resolution: {integrity: sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==}
- express@4.19.2:
- resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==}
+ express@4.20.0:
+ resolution: {integrity: sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==}
+ engines: {node: '>= 0.10.0'}
+
+ express@4.21.0:
+ resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==}
engines: {node: '>= 0.10.0'}
extend@3.0.2:
@@ -3378,6 +3510,10 @@ packages:
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
engines: {node: '>= 0.8'}
+ finalhandler@1.3.1:
+ resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
+ engines: {node: '>= 0.8'}
+
find-package@1.0.0:
resolution: {integrity: sha512-yVn71XCCaNgxz58ERTl8nA/8YYtIQDY9mHSrgFBfiFtdNNfY0h183Vh8BRkKxD8x9TUw3ec290uJKhDVxqGZBw==}
@@ -3484,10 +3620,6 @@ packages:
engines: {node: '>=10'}
deprecated: This package is no longer supported.
- gaxios@4.3.3:
- resolution: {integrity: sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==}
- engines: {node: '>=10'}
-
gaxios@5.1.3:
resolution: {integrity: sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==}
engines: {node: '>=12'}
@@ -3496,10 +3628,6 @@ packages:
resolution: {integrity: sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==}
engines: {node: '>=14'}
- gcp-metadata@4.3.1:
- resolution: {integrity: sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==}
- engines: {node: '>=10'}
-
gcp-metadata@5.3.0:
resolution: {integrity: sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==}
engines: {node: '>=12'}
@@ -3544,6 +3672,11 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
@@ -3556,10 +3689,6 @@ packages:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
- google-auth-library@7.14.1:
- resolution: {integrity: sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==}
- engines: {node: '>=10'}
-
google-auth-library@8.9.0:
resolution: {integrity: sha512-f7aQCJODJFmYWN6PeNKzgvy9LI2tYmXnzpNDHEjG5sDNPgGb2FXQyTBnXeSH+PAtpKESFD+LmHw3Ox3mN7e1Fg==}
engines: {node: '>=12'}
@@ -3568,6 +3697,10 @@ packages:
resolution: {integrity: sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw==}
engines: {node: '>=14'}
+ google-auth-library@9.14.1:
+ resolution: {integrity: sha512-Rj+PMjoNFGFTmtItH7gHfbHpGVSb3vmnGK3nwNBqxQF9NoBpttSZI/rc0WiM63ma2uGDQtYEkMHkK9U6937NiA==}
+ engines: {node: '>=14'}
+
google-auth-library@9.7.0:
resolution: {integrity: sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==}
engines: {node: '>=14'}
@@ -3580,22 +3713,12 @@ packages:
resolution: {integrity: sha512-3bnD8RASQyaxOYTdWLgwpQco/aytTxFavoI/UN5QN5txDLp8QRrBHNtCUJ5+Ago+551GD92jG8jJduwvmaneUw==}
engines: {node: '>=14'}
- google-p12-pem@3.1.4:
- resolution: {integrity: sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==}
- engines: {node: '>=10'}
- deprecated: Package is no longer maintained
- hasBin: true
-
google-p12-pem@4.0.1:
resolution: {integrity: sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==}
engines: {node: '>=12.0.0'}
deprecated: Package is no longer maintained
hasBin: true
- google-proto-files@3.0.3:
- resolution: {integrity: sha512-7JaU/smPA/FpNsCaXyVjitwiQyn5zYC/ETA+xag3ziovBojIWvzevyrbVqhxgnQdgMJ0p1RVSvpzQL6hkg6yGw==}
- engines: {node: '>=12.0.0'}
-
googleapis-common@7.2.0:
resolution: {integrity: sha512-/fhDZEJZvOV3X5jmD+fKxMqma5q2Q9nZNSF3kn1F18tpxmA86BcTxAGBQdM0N89Z3bEaIs+HVznSmFJEAmMTjA==}
engines: {node: '>=14.0.0'}
@@ -3614,10 +3737,6 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
- gtoken@5.3.2:
- resolution: {integrity: sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==}
- engines: {node: '>=10'}
-
gtoken@6.1.2:
resolution: {integrity: sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==}
engines: {node: '>=12.0.0'}
@@ -3845,6 +3964,10 @@ packages:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
+ jackspeak@4.0.2:
+ resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
+ engines: {node: 20 || >=22}
+
jake@10.9.1:
resolution: {integrity: sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==}
engines: {node: '>=10'}
@@ -4152,6 +4275,10 @@ packages:
resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
engines: {node: 14 || >=16.14}
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
lru-cache@4.0.2:
resolution: {integrity: sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==}
@@ -4177,8 +4304,8 @@ packages:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
- merge-descriptors@1.0.1:
- resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
+ merge-descriptors@1.0.3:
+ resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
@@ -4225,6 +4352,10 @@ packages:
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
engines: {node: '>=10'}
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -4251,6 +4382,10 @@ packages:
resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
engines: {node: '>=16 || 14 >=14.17'}
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
@@ -4437,6 +4572,9 @@ packages:
resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==}
engines: {node: '>=8'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
parents@1.0.1:
resolution: {integrity: sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==}
@@ -4474,8 +4612,12 @@ packages:
resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
engines: {node: '>=16 || 14 >=14.17'}
- path-to-regexp@0.1.7:
- resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ path-to-regexp@0.1.10:
+ resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==}
path-type@3.0.0:
resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
@@ -4630,8 +4772,8 @@ packages:
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
engines: {node: '>=0.6'}
- qs@6.12.0:
- resolution: {integrity: sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==}
+ qs@6.13.0:
+ resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'}
queue-microtask@1.2.3:
@@ -4705,6 +4847,11 @@ packages:
deprecated: Rimraf versions prior to v4 are no longer supported
hasBin: true
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
rollup@4.13.2:
resolution: {integrity: sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -4748,8 +4895,16 @@ packages:
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
engines: {node: '>= 0.8.0'}
- serve-static@1.15.0:
- resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
+ send@0.19.0:
+ resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
+ engines: {node: '>= 0.8.0'}
+
+ serve-static@1.16.0:
+ resolution: {integrity: sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==}
+ engines: {node: '>= 0.8.0'}
+
+ serve-static@1.16.2:
+ resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'}
set-blocking@2.0.0:
@@ -4967,6 +5122,9 @@ packages:
resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==}
engines: {node: '>= 14.0.0'}
+ truncate-utf8-bytes@1.0.2:
+ resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==}
+
ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
@@ -5039,6 +5197,11 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ typescript@5.6.2:
+ resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
uglify-js@3.17.4:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
engines: {node: '>=0.8.0'}
@@ -5063,6 +5226,9 @@ packages:
url-template@2.0.8:
resolution: {integrity: sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==}
+ utf8-byte-length@1.0.5:
+ resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==}
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -5098,10 +5264,6 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
- walkdir@0.4.1:
- resolution: {integrity: sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==}
- engines: {node: '>=6.0.0'}
-
web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
@@ -5249,7 +5411,7 @@ snapshots:
'@anthropic-ai/vertex-sdk@0.4.0(encoding@0.1.13)':
dependencies:
'@anthropic-ai/sdk': 0.24.3(encoding@0.1.13)
- google-auth-library: 9.7.0(encoding@0.1.13)
+ google-auth-library: 9.14.1(encoding@0.1.13)
transitivePeerDependencies:
- encoding
- supports-color
@@ -5411,7 +5573,7 @@ snapshots:
duplexify: 4.1.3
ent: 2.2.0
extend: 3.0.2
- google-auth-library: 9.11.0(encoding@0.1.13)
+ google-auth-library: 9.14.1(encoding@0.1.13)
retry-request: 7.0.2(encoding@0.1.13)
teeny-request: 9.0.0(encoding@0.1.13)
transitivePeerDependencies:
@@ -5451,7 +5613,7 @@ snapshots:
'@google-cloud/logging-winston@6.0.0(encoding@0.1.13)(winston@3.13.0)':
dependencies:
- '@google-cloud/logging': 11.0.0(encoding@0.1.13)
+ '@google-cloud/logging': 11.2.0(encoding@0.1.13)
google-auth-library: 9.7.0(encoding@0.1.13)
lodash.mapvalues: 4.6.0
winston: 3.13.0
@@ -5460,19 +5622,20 @@ snapshots:
- encoding
- supports-color
- '@google-cloud/logging@11.0.0(encoding@0.1.13)':
+ '@google-cloud/logging@11.2.0(encoding@0.1.13)':
dependencies:
'@google-cloud/common': 5.0.1(encoding@0.1.13)
- '@google-cloud/paginator': 5.0.0
+ '@google-cloud/paginator': 5.0.2
'@google-cloud/projectify': 4.0.0
'@google-cloud/promisify': 4.0.0
+ '@opentelemetry/api': 1.9.0
arrify: 2.0.1
dot-prop: 6.0.1
eventid: 2.0.1
extend: 3.0.2
gcp-metadata: 6.1.0(encoding@0.1.13)
google-auth-library: 9.11.0(encoding@0.1.13)
- google-gax: 4.3.2(encoding@0.1.13)
+ google-gax: 4.3.7(encoding@0.1.13)
on-finished: 2.4.1
pumpify: 2.0.1
stream-events: 1.0.5
@@ -5483,47 +5646,36 @@ snapshots:
'@google-cloud/opentelemetry-cloud-monitoring-exporter@0.19.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)':
dependencies:
- '@google-cloud/opentelemetry-resource-util': 2.3.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)
+ '@google-cloud/opentelemetry-resource-util': 2.4.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)
'@google-cloud/precise-date': 4.0.0
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0)
- google-auth-library: 9.7.0(encoding@0.1.13)
+ google-auth-library: 9.11.0(encoding@0.1.13)
googleapis: 137.1.0(encoding@0.1.13)
transitivePeerDependencies:
- encoding
- supports-color
- '@google-cloud/opentelemetry-cloud-trace-exporter@2.1.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.26.0)(encoding@0.1.13)':
+ '@google-cloud/opentelemetry-cloud-trace-exporter@2.4.1(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)':
dependencies:
- '@google-cloud/opentelemetry-resource-util': 2.1.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.26.0)(encoding@0.1.13)
- '@grpc/grpc-js': 1.10.4
- '@grpc/proto-loader': 0.7.12
+ '@google-cloud/opentelemetry-resource-util': 2.4.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)
+ '@grpc/grpc-js': 1.10.10
+ '@grpc/proto-loader': 0.7.13
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0)
- google-auth-library: 7.14.1(encoding@0.1.13)
- google-proto-files: 3.0.3
+ google-auth-library: 9.14.1(encoding@0.1.13)
transitivePeerDependencies:
- - '@opentelemetry/semantic-conventions'
- encoding
- supports-color
- '@google-cloud/opentelemetry-resource-util@2.1.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.26.0)(encoding@0.1.13)':
+ '@google-cloud/opentelemetry-resource-util@2.4.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)':
dependencies:
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.26.0
- gcp-metadata: 5.3.0(encoding@0.1.13)
- transitivePeerDependencies:
- - encoding
- - supports-color
-
- '@google-cloud/opentelemetry-resource-util@2.3.0(@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)':
- dependencies:
- '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
- '@opentelemetry/semantic-conventions': 1.22.0
gcp-metadata: 6.1.0(encoding@0.1.13)
transitivePeerDependencies:
- encoding
@@ -5533,6 +5685,7 @@ snapshots:
dependencies:
arrify: 2.0.1
extend: 3.0.2
+ optional: true
'@google-cloud/paginator@5.0.2':
dependencies:
@@ -5556,7 +5709,7 @@ snapshots:
ent: 2.2.0
fast-xml-parser: 4.3.6
gaxios: 6.3.0(encoding@0.1.13)
- google-auth-library: 9.11.0(encoding@0.1.13)
+ google-auth-library: 9.14.1(encoding@0.1.13)
mime: 3.0.0
p-limit: 3.1.0
retry-request: 7.0.2(encoding@0.1.13)
@@ -5567,9 +5720,9 @@ snapshots:
- supports-color
optional: true
- '@google-cloud/vertexai@1.1.0(encoding@0.1.13)':
+ '@google-cloud/vertexai@1.7.0(encoding@0.1.13)':
dependencies:
- google-auth-library: 9.7.0(encoding@0.1.13)
+ google-auth-library: 9.14.1(encoding@0.1.13)
transitivePeerDependencies:
- encoding
- supports-color
@@ -6683,6 +6836,23 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ body-parser@1.20.3:
+ dependencies:
+ bytes: 3.1.2
+ content-type: 1.0.5
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ on-finished: 2.4.1
+ qs: 6.13.0
+ raw-body: 2.5.2
+ type-is: 1.6.18
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
@@ -6992,6 +7162,8 @@ snapshots:
encodeurl@1.0.2: {}
+ encodeurl@2.0.0: {}
+
encoding@0.1.13:
dependencies:
iconv-lite: 0.6.3
@@ -7137,34 +7309,70 @@ snapshots:
expr-eval@2.0.2: {}
- express@4.19.2:
+ express@4.20.0:
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
- body-parser: 1.20.2
+ body-parser: 1.20.3
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.6.0
cookie-signature: 1.0.6
debug: 2.6.9
depd: 2.0.0
- encodeurl: 1.0.2
+ encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 1.2.0
fresh: 0.5.2
http-errors: 2.0.0
- merge-descriptors: 1.0.1
+ merge-descriptors: 1.0.3
methods: 1.1.2
on-finished: 2.4.1
parseurl: 1.3.3
- path-to-regexp: 0.1.7
+ path-to-regexp: 0.1.10
proxy-addr: 2.0.7
qs: 6.11.0
range-parser: 1.2.1
safe-buffer: 5.2.1
- send: 0.18.0
- serve-static: 1.15.0
+ send: 0.19.0
+ serve-static: 1.16.0
+ setprototypeof: 1.2.0
+ statuses: 2.0.1
+ type-is: 1.6.18
+ utils-merge: 1.0.1
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ express@4.21.0:
+ dependencies:
+ accepts: 1.3.8
+ array-flatten: 1.1.1
+ body-parser: 1.20.3
+ content-disposition: 0.5.4
+ content-type: 1.0.5
+ cookie: 0.6.0
+ cookie-signature: 1.0.6
+ debug: 2.6.9
+ depd: 2.0.0
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ finalhandler: 1.3.1
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ merge-descriptors: 1.0.3
+ methods: 1.1.2
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ path-to-regexp: 0.1.10
+ proxy-addr: 2.0.7
+ qs: 6.13.0
+ range-parser: 1.2.1
+ safe-buffer: 5.2.1
+ send: 0.19.0
+ serve-static: 1.16.2
setprototypeof: 1.2.0
statuses: 2.0.1
type-is: 1.6.18
@@ -7192,7 +7400,8 @@ snapshots:
merge2: 1.4.1
micromatch: 4.0.5
- fast-text-encoding@1.0.6: {}
+ fast-text-encoding@1.0.6:
+ optional: true
fast-xml-parser@4.3.6:
dependencies:
@@ -7234,6 +7443,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ finalhandler@1.3.1:
+ dependencies:
+ debug: 2.6.9
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ statuses: 2.0.1
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
find-package@1.0.0:
dependencies:
parents: 1.0.1
@@ -7299,7 +7520,7 @@ snapshots:
'@types/cors': 2.8.17
'@types/express': 4.17.3
cors: 2.8.5
- express: 4.19.2
+ express: 4.21.0
firebase-admin: 12.2.0(encoding@0.1.13)
node-fetch: 2.7.0(encoding@0.1.13)
protobufjs: 7.2.6
@@ -7312,7 +7533,7 @@ snapshots:
'@types/cors': 2.8.17
'@types/express': 4.17.3
cors: 2.8.5
- express: 4.19.2
+ express: 4.21.0
firebase-admin: 12.1.0(encoding@0.1.13)
protobufjs: 7.2.6
transitivePeerDependencies:
@@ -7401,17 +7622,6 @@ snapshots:
wide-align: 1.1.5
optional: true
- gaxios@4.3.3(encoding@0.1.13):
- dependencies:
- abort-controller: 3.0.0
- extend: 3.0.2
- https-proxy-agent: 5.0.1
- is-stream: 2.0.1
- node-fetch: 2.7.0(encoding@0.1.13)
- transitivePeerDependencies:
- - encoding
- - supports-color
-
gaxios@5.1.3(encoding@0.1.13):
dependencies:
extend: 3.0.2
@@ -7421,6 +7631,7 @@ snapshots:
transitivePeerDependencies:
- encoding
- supports-color
+ optional: true
gaxios@6.3.0(encoding@0.1.13):
dependencies:
@@ -7432,14 +7643,6 @@ snapshots:
- encoding
- supports-color
- gcp-metadata@4.3.1(encoding@0.1.13):
- dependencies:
- gaxios: 4.3.3(encoding@0.1.13)
- json-bigint: 1.0.0
- transitivePeerDependencies:
- - encoding
- - supports-color
-
gcp-metadata@5.3.0(encoding@0.1.13):
dependencies:
gaxios: 5.1.3(encoding@0.1.13)
@@ -7447,6 +7650,7 @@ snapshots:
transitivePeerDependencies:
- encoding
- supports-color
+ optional: true
gcp-metadata@6.1.0(encoding@0.1.13):
dependencies:
@@ -7498,6 +7702,15 @@ snapshots:
minipass: 7.0.4
path-scurry: 1.10.2
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.1.1
+ jackspeak: 4.0.2
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -7521,38 +7734,35 @@ snapshots:
merge2: 1.4.1
slash: 3.0.0
- google-auth-library@7.14.1(encoding@0.1.13):
+ google-auth-library@8.9.0(encoding@0.1.13):
dependencies:
arrify: 2.0.1
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
fast-text-encoding: 1.0.6
- gaxios: 4.3.3(encoding@0.1.13)
- gcp-metadata: 4.3.1(encoding@0.1.13)
- gtoken: 5.3.2(encoding@0.1.13)
+ gaxios: 5.1.3(encoding@0.1.13)
+ gcp-metadata: 5.3.0(encoding@0.1.13)
+ gtoken: 6.1.2(encoding@0.1.13)
jws: 4.0.0
lru-cache: 6.0.0
transitivePeerDependencies:
- encoding
- supports-color
+ optional: true
- google-auth-library@8.9.0(encoding@0.1.13):
+ google-auth-library@9.11.0(encoding@0.1.13):
dependencies:
- arrify: 2.0.1
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
- fast-text-encoding: 1.0.6
- gaxios: 5.1.3(encoding@0.1.13)
- gcp-metadata: 5.3.0(encoding@0.1.13)
- gtoken: 6.1.2(encoding@0.1.13)
+ gaxios: 6.3.0(encoding@0.1.13)
+ gcp-metadata: 6.1.0(encoding@0.1.13)
+ gtoken: 7.1.0(encoding@0.1.13)
jws: 4.0.0
- lru-cache: 6.0.0
transitivePeerDependencies:
- encoding
- supports-color
- optional: true
- google-auth-library@9.11.0(encoding@0.1.13):
+ google-auth-library@9.14.1(encoding@0.1.13):
dependencies:
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
@@ -7601,7 +7811,7 @@ snapshots:
'@types/long': 4.0.2
abort-controller: 3.0.0
duplexify: 4.1.3
- google-auth-library: 9.11.0(encoding@0.1.13)
+ google-auth-library: 9.14.1(encoding@0.1.13)
node-fetch: 2.7.0(encoding@0.1.13)
object-hash: 3.0.0
proto3-json-serializer: 2.0.2
@@ -7612,26 +7822,17 @@ snapshots:
- encoding
- supports-color
- google-p12-pem@3.1.4:
- dependencies:
- node-forge: 1.3.1
-
google-p12-pem@4.0.1:
dependencies:
node-forge: 1.3.1
optional: true
- google-proto-files@3.0.3:
- dependencies:
- protobufjs: 7.2.6
- walkdir: 0.4.1
-
googleapis-common@7.2.0(encoding@0.1.13):
dependencies:
extend: 3.0.2
gaxios: 6.3.0(encoding@0.1.13)
- google-auth-library: 9.11.0(encoding@0.1.13)
- qs: 6.12.0
+ google-auth-library: 9.14.1(encoding@0.1.13)
+ qs: 6.13.0
url-template: 2.0.8
uuid: 9.0.1
transitivePeerDependencies:
@@ -7648,7 +7849,7 @@ snapshots:
googleapis@140.0.1(encoding@0.1.13):
dependencies:
- google-auth-library: 9.7.0(encoding@0.1.13)
+ google-auth-library: 9.14.1(encoding@0.1.13)
googleapis-common: 7.2.0(encoding@0.1.13)
transitivePeerDependencies:
- encoding
@@ -7660,15 +7861,6 @@ snapshots:
graceful-fs@4.2.11: {}
- gtoken@5.3.2(encoding@0.1.13):
- dependencies:
- gaxios: 4.3.3(encoding@0.1.13)
- google-p12-pem: 3.1.4
- jws: 4.0.0
- transitivePeerDependencies:
- - encoding
- - supports-color
-
gtoken@6.1.2(encoding@0.1.13):
dependencies:
gaxios: 5.1.3(encoding@0.1.13)
@@ -7904,6 +8096,10 @@ snapshots:
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
+ jackspeak@4.0.2:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
jake@10.9.1:
dependencies:
async: 3.2.5
@@ -8155,6 +8351,8 @@ snapshots:
lru-cache@10.2.0: {}
+ lru-cache@11.0.1: {}
+
lru-cache@4.0.2:
dependencies:
pseudomap: 1.0.2
@@ -8184,7 +8382,7 @@ snapshots:
memorystream@0.3.1: {}
- merge-descriptors@1.0.1: {}
+ merge-descriptors@1.0.3: {}
merge-stream@2.0.0: {}
@@ -8215,6 +8413,10 @@ snapshots:
mimic-response@3.1.0: {}
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
@@ -8239,6 +8441,8 @@ snapshots:
minipass@7.0.4: {}
+ minipass@7.1.2: {}
+
minizlib@2.1.2:
dependencies:
minipass: 3.3.6
@@ -8433,6 +8637,8 @@ snapshots:
dependencies:
p-finally: 1.0.0
+ package-json-from-dist@1.0.1: {}
+
parents@1.0.1:
dependencies:
path-platform: 0.11.15
@@ -8462,7 +8668,12 @@ snapshots:
lru-cache: 10.2.0
minipass: 7.0.4
- path-to-regexp@0.1.7: {}
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
+ path-to-regexp@0.1.10: {}
path-type@3.0.0:
dependencies:
@@ -8625,7 +8836,7 @@ snapshots:
dependencies:
side-channel: 1.0.6
- qs@6.12.0:
+ qs@6.13.0:
dependencies:
side-channel: 1.0.6
@@ -8710,6 +8921,11 @@ snapshots:
glob: 7.2.3
optional: true
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.1
+
rollup@4.13.2:
dependencies:
'@types/estree': 1.0.5
@@ -8781,7 +8997,25 @@ snapshots:
transitivePeerDependencies:
- supports-color
- serve-static@1.15.0:
+ send@0.19.0:
+ dependencies:
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ etag: 1.8.1
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ mime: 1.6.0
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: 1.2.1
+ statuses: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ serve-static@1.16.0:
dependencies:
encodeurl: 1.0.2
escape-html: 1.0.3
@@ -8790,6 +9024,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ serve-static@1.16.2:
+ dependencies:
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 0.19.0
+ transitivePeerDependencies:
+ - supports-color
+
set-blocking@2.0.0:
optional: true
@@ -9034,6 +9277,10 @@ snapshots:
triple-beam@1.4.1: {}
+ truncate-utf8-bytes@1.0.2:
+ dependencies:
+ utf8-byte-length: 1.0.5
+
ts-interface-checker@0.1.13: {}
ts-md5@1.3.1: {}
@@ -9116,6 +9363,8 @@ snapshots:
typescript@5.5.3: {}
+ typescript@5.6.2: {}
+
uglify-js@3.17.4:
optional: true
@@ -9138,6 +9387,8 @@ snapshots:
url-template@2.0.8: {}
+ utf8-byte-length@1.0.5: {}
+
util-deprecate@1.0.2: {}
util@0.10.4:
@@ -9163,8 +9414,6 @@ snapshots:
vary@1.1.2: {}
- walkdir@0.4.1: {}
-
web-streams-polyfill@3.3.3: {}
web-streams-polyfill@4.0.0-beta.3: {}
diff --git a/js/testapps/anthropic-models/package.json b/js/testapps/anthropic-models/package.json
index d9fbcdc73c..b9c0837494 100644
--- a/js/testapps/anthropic-models/package.json
+++ b/js/testapps/anthropic-models/package.json
@@ -19,7 +19,7 @@
"@genkit-ai/firebase": "workspace:*",
"@genkit-ai/flow": "workspace:*",
"@genkit-ai/vertexai": "workspace:*",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"zod": "3.22.4"
},
"devDependencies": {
diff --git a/js/testapps/basic-gemini/package.json b/js/testapps/basic-gemini/package.json
new file mode 100644
index 0000000000..8ae47a2dad
--- /dev/null
+++ b/js/testapps/basic-gemini/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "basic-gemini",
+ "version": "1.0.0",
+ "description": "",
+ "main": "lib/index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "node lib/index.js",
+ "build": "tsc",
+ "build:watch": "tsc --watch"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@genkit-ai/ai": "workspace:*",
+ "@genkit-ai/core": "workspace:*",
+ "@genkit-ai/dotprompt": "workspace:*",
+ "@genkit-ai/flow": "workspace:*",
+ "@genkit-ai/googleai": "workspace:*",
+ "@genkit-ai/vertexai": "workspace:*",
+ "express": "^4.21.0",
+ "zod": "^3.22.4"
+ },
+ "devDependencies": {
+ "typescript": "^5.6.2"
+ }
+}
diff --git a/js/testapps/basic-gemini/src/index.ts b/js/testapps/basic-gemini/src/index.ts
new file mode 100644
index 0000000000..e91d94dfd4
--- /dev/null
+++ b/js/testapps/basic-gemini/src/index.ts
@@ -0,0 +1,172 @@
+/**
+ * Copyright 2024 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 * as z from 'zod';
+
+// Import the Genkit core libraries and plugins.
+import { defineTool, generate } from '@genkit-ai/ai';
+import { configureGenkit } from '@genkit-ai/core';
+import { defineFlow, startFlowsServer } from '@genkit-ai/flow';
+import {
+ gemini15Flash as gemini15FlashGoogleAi,
+ googleAI,
+} from '@genkit-ai/googleai';
+
+// Import models from the Google AI plugin. The Google AI API provides access to
+
+import {
+ gemini15Flash as gemini15FlashVertexAi,
+ vertexAI,
+} from '@genkit-ai/vertexai';
+
+const provider = process.env.PROVIDER || 'vertexai';
+
+configureGenkit({
+ plugins: [vertexAI(), googleAI()],
+ // Log debug output to tbe console.
+ logLevel: 'debug',
+ // Perform OpenTelemetry instrumentation and enable trace collection.
+ enableTracingAndMetrics: true,
+});
+
+const jokeSubjectGenerator = defineTool(
+ {
+ name: 'jokeSubjectGenerator',
+ description: 'can be called to generate a subject for a joke',
+ inputSchema: z.object({ input: z.string() }),
+ outputSchema: z.string(),
+ },
+ async (input) => {
+ throw new Error('banana');
+ return 'banana';
+ }
+);
+
+// Define a simple flow that prompts an LLM to generate menu suggestions.
+export const jokeFlow = defineFlow(
+ {
+ name: 'jokeFlow',
+ inputSchema: z.object({ provider: z.enum(['vertexai', 'googleai']) }),
+ outputSchema: z.any(),
+ },
+ async ({ provider }) => {
+ // Construct a request and send it to the model API.
+ if (provider === 'vertexai') {
+ const llmResponse = await generate({
+ model: gemini15FlashVertexAi,
+ config: {
+ temperature: 2,
+ },
+ output: {
+ schema: z.object({ jokeSubject: z.string() }),
+ },
+ tools: [jokeSubjectGenerator],
+ prompt: `come up with a subject to joke about (using the function provided)`,
+ });
+
+ return llmResponse.output();
+ } else {
+ const llmResponse = await generate({
+ model: gemini15FlashGoogleAi,
+ config: {
+ temperature: 2,
+ },
+ output: {
+ schema: z.object({ jokeSubject: z.string() }),
+ },
+ tools: [jokeSubjectGenerator],
+ prompt: `come up with a subject to joke about (using the function provided)`,
+ });
+ return llmResponse.output();
+ }
+
+ // Handle the response from the model API. In this sample, we just convert
+ // it to a string, but more complicated flows might coerce the response into
+ }
+);
+
+export const streamingFlow = defineFlow(
+ {
+ name: 'streamingFlow',
+ inputSchema: z.object({ provider: z.enum(['vertexai', 'googleai']) }),
+ outputSchema: z.any(),
+ },
+ async ({ provider }) => {
+ let count = 0;
+
+ if (provider === 'vertexai') {
+ // Construct a request and send it to the model API.
+ const llmResponse = await generate({
+ model: gemini15FlashVertexAi,
+ config: {
+ temperature: 2,
+ },
+ output: {
+ schema: z.array(
+ z.object({
+ name: z.string(),
+ age: z.number(),
+ description: z.string(),
+ personal_statement: z.string(),
+ })
+ ),
+ },
+ tools: [jokeSubjectGenerator],
+ prompt: `come up with some test user data. 10 users long`,
+ streamingCallback: (chunk) => {
+ count++;
+ const output = chunk.text();
+ console.log(`chunk ${count}`, output);
+ return output;
+ },
+ });
+
+ return llmResponse.output()!;
+ } else {
+ const llmResponse = await generate({
+ model: gemini15FlashGoogleAi,
+ config: {
+ temperature: 2,
+ },
+ output: {
+ schema: z.array(
+ z.object({
+ name: z.string(),
+ age: z.number(),
+ description: z.string(),
+ personal_statement: z.string(),
+ })
+ ),
+ },
+ tools: [jokeSubjectGenerator],
+ prompt: `come up with some test user data. 10 users long`,
+ streamingCallback: (chunk) => {
+ count++;
+ const output = chunk.text();
+ console.log(`chunk ${count}`, output);
+ return output;
+ },
+ });
+ return llmResponse.output()!;
+ }
+ }
+);
+
+// Start a flow server, which exposes your flows as HTTP endpoints. This call
+// must come last, after all of your plug-in configuration and flow definitions.
+// You can optionally specify a subset of flows to serve, and configure some
+// HTTP server options, but by default, the flow server serves all defined flows.
+startFlowsServer();
diff --git a/js/testapps/basic-gemini/tsconfig.json b/js/testapps/basic-gemini/tsconfig.json
new file mode 100644
index 0000000000..efbb566bf7
--- /dev/null
+++ b/js/testapps/basic-gemini/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "compileOnSave": true,
+ "include": ["src"],
+ "compilerOptions": {
+ "module": "commonjs",
+ "noImplicitReturns": true,
+ "outDir": "lib",
+ "sourceMap": true,
+ "strict": true,
+ "target": "es2017",
+ "skipLibCheck": true,
+ "esModuleInterop": true
+ }
+}
diff --git a/js/testapps/byo-evaluator/package.json b/js/testapps/byo-evaluator/package.json
index 16479c5512..9ada5a0867 100644
--- a/js/testapps/byo-evaluator/package.json
+++ b/js/testapps/byo-evaluator/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
@@ -27,6 +27,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/cat-eval/package.json b/js/testapps/cat-eval/package.json
index 3d2487e6ff..3d618f2eeb 100644
--- a/js/testapps/cat-eval/package.json
+++ b/js/testapps/cat-eval/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
@@ -35,6 +35,7 @@
},
"devDependencies": {
"@types/pdf-parse": "^1.1.4",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/dev-ui-gallery/package.json b/js/testapps/dev-ui-gallery/package.json
index dd663d07be..e74f0f25f4 100644
--- a/js/testapps/dev-ui-gallery/package.json
+++ b/js/testapps/dev-ui-gallery/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -15,7 +15,8 @@
"author": "Google, LLC",
"license": "ISC",
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
},
"dependencies": {
"@genkit-ai/ai": "workspace:*",
diff --git a/js/testapps/docs-menu-basic/package.json b/js/testapps/docs-menu-basic/package.json
index a41df0bc3e..6d2c3db432 100644
--- a/js/testapps/docs-menu-basic/package.json
+++ b/js/testapps/docs-menu-basic/package.json
@@ -4,7 +4,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "npm run build:clean && npm run compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
@@ -20,10 +20,11 @@
"@genkit-ai/firebase": "workspace:*",
"@genkit-ai/flow": "workspace:*",
"@genkit-ai/googleai": "workspace:*",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/docs-menu-rag/package.json b/js/testapps/docs-menu-rag/package.json
index f3454876c5..0e31f1a07b 100644
--- a/js/testapps/docs-menu-rag/package.json
+++ b/js/testapps/docs-menu-rag/package.json
@@ -4,7 +4,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -27,6 +27,7 @@
},
"devDependencies": {
"@types/pdf-parse": "^1.1.4",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/eval/package.json b/js/testapps/eval/package.json
index 0d42e5b116..0ae05b5a62 100644
--- a/js/testapps/eval/package.json
+++ b/js/testapps/eval/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -24,6 +24,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/evaluator-gut-check/package.json b/js/testapps/evaluator-gut-check/package.json
index 3023e1aa95..788adf0afc 100644
--- a/js/testapps/evaluator-gut-check/package.json
+++ b/js/testapps/evaluator-gut-check/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
@@ -25,6 +25,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/express/package.json b/js/testapps/express/package.json
index 1c697b8090..3eb19a1ca2 100644
--- a/js/testapps/express/package.json
+++ b/js/testapps/express/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -22,11 +22,12 @@
"@genkit-ai/googleai": "workspace:*",
"genkitx-ollama": "workspace:*",
"@genkit-ai/vertexai": "workspace:*",
- "express": "~4.19.2",
+ "express": "~4.20.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/express": "^4.17.21",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/flow-sample1/package.json b/js/testapps/flow-sample1/package.json
index 826337ed70..e9badd501f 100644
--- a/js/testapps/flow-sample1/package.json
+++ b/js/testapps/flow-sample1/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -21,6 +21,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/flow-simple-ai/package.json b/js/testapps/flow-simple-ai/package.json
index 3084225505..1fe48c994e 100644
--- a/js/testapps/flow-simple-ai/package.json
+++ b/js/testapps/flow-simple-ai/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -30,6 +30,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/google-ai-code-execution/package.json b/js/testapps/google-ai-code-execution/package.json
index d1b4f727b7..8baf92d154 100644
--- a/js/testapps/google-ai-code-execution/package.json
+++ b/js/testapps/google-ai-code-execution/package.json
@@ -20,7 +20,7 @@
"@genkit-ai/google-cloud": "workspace:*",
"@genkit-ai/googleai": "workspace:*",
"dotenv": "^16.4.5",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"zod": "3.22.4"
},
"devDependencies": {
diff --git a/js/testapps/langchain/package.json b/js/testapps/langchain/package.json
index 84dc973655..7999f9ceb5 100644
--- a/js/testapps/langchain/package.json
+++ b/js/testapps/langchain/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -26,13 +26,14 @@
"@langchain/community": "^0.0.53",
"@langchain/core": "^0.1.61",
"@opentelemetry/api": "^1.9.0",
- "express": "~4.19.2",
+ "express": "~4.20.0",
"langchain": "^0.1.36",
"pdf-parse": "^1.1.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/express": "^4.17.21",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/llm-human-in-the-loop/package.json b/js/testapps/llm-human-in-the-loop/package.json
index 41bc652e2a..fe46561782 100644
--- a/js/testapps/llm-human-in-the-loop/package.json
+++ b/js/testapps/llm-human-in-the-loop/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -23,6 +23,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/menu/package.json b/js/testapps/menu/package.json
index 9a4f3c2589..3095de56d5 100644
--- a/js/testapps/menu/package.json
+++ b/js/testapps/menu/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -26,7 +26,8 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
},
"type": "module"
}
diff --git a/js/testapps/vertexai-vector-search-bigquery/package.json b/js/testapps/vertexai-vector-search-bigquery/package.json
index 8fe03522b9..46167568e1 100644
--- a/js/testapps/vertexai-vector-search-bigquery/package.json
+++ b/js/testapps/vertexai-vector-search-bigquery/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
@@ -25,7 +25,7 @@
"@genkit-ai/vertexai": "workspace:*",
"@google-cloud/bigquery": "^7.8.0",
"dotenv": "^16.4.5",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"genkitx-chromadb": "workspace:*",
"genkitx-langchain": "workspace:*",
"genkitx-pinecone": "workspace:*",
@@ -33,6 +33,7 @@
"zod": "3.22.4"
},
"devDependencies": {
- "typescript": "^5.5.2"
+ "typescript": "^5.5.2",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/vertexai-vector-search-custom/package.json b/js/testapps/vertexai-vector-search-custom/package.json
index 8fe03522b9..46167568e1 100644
--- a/js/testapps/vertexai-vector-search-custom/package.json
+++ b/js/testapps/vertexai-vector-search-custom/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
@@ -25,7 +25,7 @@
"@genkit-ai/vertexai": "workspace:*",
"@google-cloud/bigquery": "^7.8.0",
"dotenv": "^16.4.5",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"genkitx-chromadb": "workspace:*",
"genkitx-langchain": "workspace:*",
"genkitx-pinecone": "workspace:*",
@@ -33,6 +33,7 @@
"zod": "3.22.4"
},
"devDependencies": {
- "typescript": "^5.5.2"
+ "typescript": "^5.5.2",
+ "rimraf": "^6.0.1"
}
}
diff --git a/js/testapps/vertexai-vector-search-firestore/package.json b/js/testapps/vertexai-vector-search-firestore/package.json
index 6717381d56..1bf7ab0433 100644
--- a/js/testapps/vertexai-vector-search-firestore/package.json
+++ b/js/testapps/vertexai-vector-search-firestore/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
@@ -24,7 +24,7 @@
"@genkit-ai/googleai": "workspace:*",
"@genkit-ai/vertexai": "workspace:*",
"dotenv": "^16.4.5",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"firebase-admin": "^12.1.0",
"genkitx-chromadb": "workspace:*",
"genkitx-langchain": "workspace:*",
@@ -33,6 +33,7 @@
"zod": "3.22.4"
},
"devDependencies": {
- "typescript": "^5.5.2"
+ "typescript": "^5.5.2",
+ "rimraf": "^6.0.1"
}
}
diff --git a/package.json b/package.json
index 3188a910a6..91cb4e0b37 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"link-genkit-cli": "cd genkit-tools/cli && npm link",
"pnpm-install-js": "cd js && pnpm i",
"pnpm-install-genkit-tools": "cd genkit-tools && pnpm i",
- "pack:all": "rm -r dist || true && mkdir dist && pnpm run pack:tools && pnpm run pack:js && pnpm dist:zip",
+ "pack:all": "rimraf dist || true && mkdir dist && pnpm run pack:tools && pnpm run pack:js && pnpm dist:zip",
"pack:tools": "cd genkit-tools && pnpm pack:all",
"pack:js": "cd js && pnpm pack:all",
"dist:zip": "cd dist && zip genkit-dist.zip *.tgz",
@@ -37,7 +37,8 @@
"prettier-plugin-css-order": "2.0.1",
"prettier-plugin-organize-imports": "^3.2.4",
"ts-node": "^10.9.2",
- "tsx": "^4.7.1"
+ "tsx": "^4.7.1",
+ "rimraf": "^6.0.1"
},
- "packageManager": "pnpm@9.10.0+sha256.355a8ab8dbb6ad41befbef39bc4fd6b5df85e12761d2724bd01f13e878de4b13"
+ "packageManager": "pnpm@9.12.0+sha256.a61b67ff6cc97af864564f4442556c22a04f2e5a7714fbee76a1011361d9b726"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8c98aea4f4..d0fcea4688 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -29,6 +29,9 @@ importers:
prettier-plugin-organize-imports:
specifier: ^3.2.4
version: 3.2.4(prettier@3.2.5)(typescript@5.4.5)
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@20.12.11)(typescript@5.4.5)
@@ -180,6 +183,10 @@ packages:
cpu: [x64]
os: [win32]
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
@@ -222,6 +229,10 @@ packages:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
ansi-styles@3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
@@ -230,6 +241,10 @@ packages:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -257,6 +272,9 @@ packages:
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
@@ -327,6 +345,10 @@ packages:
resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==}
engines: {node: '>=4.8'}
+ cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+
css-declaration-sorter@7.2.0:
resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==}
engines: {node: ^14 || ^16 || >=18}
@@ -360,9 +382,15 @@ packages:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
@@ -410,6 +438,10 @@ packages:
for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ foreground-child@3.3.0:
+ resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+ engines: {node: '>=14'}
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -436,6 +468,11 @@ packages:
get-tsconfig@4.7.5:
resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==}
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
globalthis@1.0.4:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
@@ -578,6 +615,10 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ jackspeak@4.0.2:
+ resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
+ engines: {node: 20 || >=22}
+
json-parse-better-errors@1.0.2:
resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
@@ -592,6 +633,10 @@ packages:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
engines: {node: '>=10'}
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
lru-cache@4.1.5:
resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
@@ -606,9 +651,17 @@ packages:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
mute-stream@0.0.8:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
@@ -659,6 +712,9 @@ packages:
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
parse-json@4.0.0:
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
engines: {node: '>=4'}
@@ -667,9 +723,17 @@ packages:
resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==}
engines: {node: '>=4'}
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
path-type@3.0.0:
resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
engines: {node: '>=4'}
@@ -765,6 +829,11 @@ packages:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
run-async@2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'}
@@ -805,10 +874,18 @@ packages:
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
engines: {node: '>=0.10.0'}
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
shebang-regex@1.0.0:
resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==}
engines: {node: '>=0.10.0'}
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
shell-quote@1.8.1:
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
@@ -819,6 +896,10 @@ packages:
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
source-map-js@1.2.0:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
@@ -842,6 +923,10 @@ packages:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
string.prototype.padend@3.1.6:
resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==}
engines: {node: '>= 0.4'}
@@ -867,6 +952,10 @@ packages:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
@@ -977,10 +1066,23 @@ packages:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
hasBin: true
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
yallist@2.1.2:
resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
@@ -1063,6 +1165,15 @@ snapshots:
'@esbuild/win32-x64@0.21.5':
optional: true
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.4.15': {}
@@ -1094,6 +1205,8 @@ snapshots:
ansi-regex@5.0.1: {}
+ ansi-regex@6.1.0: {}
+
ansi-styles@3.2.1:
dependencies:
color-convert: 1.9.3
@@ -1102,6 +1215,8 @@ snapshots:
dependencies:
color-convert: 2.0.1
+ ansi-styles@6.2.1: {}
+
arg@4.1.3: {}
array-buffer-byte-length@1.0.1:
@@ -1139,6 +1254,10 @@ snapshots:
balanced-match: 1.0.2
concat-map: 0.0.1
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
buffer-from@1.1.2: {}
buffer@5.7.1:
@@ -1216,6 +1335,12 @@ snapshots:
shebang-command: 1.2.0
which: 1.3.1
+ cross-spawn@7.0.3:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
css-declaration-sorter@7.2.0(postcss@8.4.38):
dependencies:
postcss: 8.4.38
@@ -1256,8 +1381,12 @@ snapshots:
diff@4.0.2: {}
+ eastasianwidth@0.2.0: {}
+
emoji-regex@8.0.0: {}
+ emoji-regex@9.2.2: {}
+
error-ex@1.3.2:
dependencies:
is-arrayish: 0.2.1
@@ -1375,6 +1504,11 @@ snapshots:
dependencies:
is-callable: 1.2.7
+ foreground-child@3.3.0:
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
fsevents@2.3.3:
optional: true
@@ -1407,6 +1541,15 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 4.0.2
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
globalthis@1.0.4:
dependencies:
define-properties: 1.2.1
@@ -1547,6 +1690,10 @@ snapshots:
isexe@2.0.0: {}
+ jackspeak@4.0.2:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
json-parse-better-errors@1.0.2: {}
load-json-file@4.0.0:
@@ -1563,6 +1710,8 @@ snapshots:
chalk: 4.1.2
is-unicode-supported: 0.1.0
+ lru-cache@11.0.1: {}
+
lru-cache@4.1.5:
dependencies:
pseudomap: 1.0.2
@@ -1574,10 +1723,16 @@ snapshots:
mimic-fn@2.1.0: {}
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
+ minipass@7.1.2: {}
+
mute-stream@0.0.8: {}
nanoid@3.3.7: {}
@@ -1638,6 +1793,8 @@ snapshots:
os-tmpdir@1.0.2: {}
+ package-json-from-dist@1.0.1: {}
+
parse-json@4.0.0:
dependencies:
error-ex: 1.3.2
@@ -1645,8 +1802,15 @@ snapshots:
path-key@2.0.1: {}
+ path-key@3.1.1: {}
+
path-parse@1.0.7: {}
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
path-type@3.0.0:
dependencies:
pify: 3.0.0
@@ -1741,6 +1905,11 @@ snapshots:
onetime: 5.1.2
signal-exit: 3.0.7
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.1
+
run-async@2.4.1: {}
rxjs@7.8.1:
@@ -1788,8 +1957,14 @@ snapshots:
dependencies:
shebang-regex: 1.0.0
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
shebang-regex@1.0.0: {}
+ shebang-regex@3.0.0: {}
+
shell-quote@1.8.1: {}
side-channel@1.0.6:
@@ -1801,6 +1976,8 @@ snapshots:
signal-exit@3.0.7: {}
+ signal-exit@4.1.0: {}
+
source-map-js@1.2.0: {}
spawn-sync@1.0.15:
@@ -1828,6 +2005,12 @@ snapshots:
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
string.prototype.padend@3.1.6:
dependencies:
call-bind: 1.0.7
@@ -1866,6 +2049,10 @@ snapshots:
dependencies:
ansi-regex: 5.0.1
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
strip-bom@3.0.0: {}
supports-color@5.5.0:
@@ -1997,12 +2184,28 @@ snapshots:
dependencies:
isexe: 2.0.0
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
yallist@2.1.2: {}
yn@3.1.1: {}
diff --git a/samples/chatbot/server/package.json b/samples/chatbot/server/package.json
index ce17919ce2..fe668e8d5c 100644
--- a/samples/chatbot/server/package.json
+++ b/samples/chatbot/server/package.json
@@ -18,7 +18,7 @@
"@genkit-ai/dotprompt": "^0.5.8",
"@genkit-ai/flow": "^0.5.8",
"@genkit-ai/vertexai": "^0.5.8",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"partial-json": "^0.1.7",
"zod": "^3.23.8"
},
diff --git a/samples/js-angular/server/package.json b/samples/js-angular/server/package.json
index 855136c3d9..ec9fa50d25 100644
--- a/samples/js-angular/server/package.json
+++ b/samples/js-angular/server/package.json
@@ -18,7 +18,7 @@
"@genkit-ai/dotprompt": "^0.5.2",
"@genkit-ai/flow": "^0.5.2",
"@genkit-ai/vertexai": "^0.5.2",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"partial-json": "^0.1.7",
"zod": "^3.23.8"
},
diff --git a/samples/js-coffee-shop/package.json b/samples/js-coffee-shop/package.json
index 608ba9003d..bf7ac1a5bd 100644
--- a/samples/js-coffee-shop/package.json
+++ b/samples/js-coffee-shop/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "npm run build:clean && npm run compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "npm run build && node lib/index.js"
},
@@ -31,6 +31,7 @@
},
"devDependencies": {
"genkit": "^0.5.0",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/samples/js-menu/package.json b/samples/js-menu/package.json
index f7f11c3d2a..0f79b14683 100644
--- a/samples/js-menu/package.json
+++ b/samples/js-menu/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "npm run build:clean && npm run compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "npm run build && node lib/index.js"
},
@@ -27,6 +27,7 @@
},
"devDependencies": {
"genkit": "^0.5.0",
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}
diff --git a/samples/prompts/package.json b/samples/prompts/package.json
index e202253db4..30a11802c2 100644
--- a/samples/prompts/package.json
+++ b/samples/prompts/package.json
@@ -18,7 +18,7 @@
"@genkit-ai/dotprompt": "^0.5.10",
"@genkit-ai/flow": "^0.5.10",
"@genkit-ai/googleai": "^0.5.10",
- "express": "^4.19.2",
+ "express": "^4.21.0",
"zod": "^3.23.8"
},
"devDependencies": {
diff --git a/tests/test_js_app/package.json b/tests/test_js_app/package.json
index b0066e4878..8c97f13de4 100644
--- a/tests/test_js_app/package.json
+++ b/tests/test_js_app/package.json
@@ -7,7 +7,7 @@
"start": "node lib/index.js",
"compile": "tsc",
"build": "pnpm build:clean && pnpm compile",
- "build:clean": "rm -rf ./lib",
+ "build:clean": "rimraf ./lib",
"build:watch": "tsc --watch",
"build-and-run": "pnpm build && node lib/index.js"
},
@@ -18,6 +18,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "typescript": "^5.3.3"
+ "typescript": "^5.3.3",
+ "rimraf": "^6.0.1"
}
}