Initial commit
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# Genkit Best Practices
|
||||
|
||||
## Project Structure
|
||||
- **Organized Layout**: Keep flows and tools in separate directories (e.g., `src/flows`, `src/tools`) to maintain a clean codebase.
|
||||
- **Index Exports**: Use `index.ts` files to export flows and tools, making it easier to import them into your main configuration.
|
||||
|
||||
## Model Selection (Google AI)
|
||||
- **Gemini Models**: If using Google AI, ALWAYS use the latest generation (`gemini-3-*` or `gemini-2.5-*`).
|
||||
- **NEVER** use `gemini-2.0-*` or `gemini-1.5-*` series, as they are decommissioned and won't work.
|
||||
- **Recommended**: `gemini-2.5-flash` or `gemini-3-flash-preview` for general use, `gemini-3.1-pro-preview` for complex tasks.
|
||||
|
||||
## Model Selection (Other Providers)
|
||||
- **Consult Documentation**: For other providers (OpenAI, Anthropic, etc.), refer to the provider's official documentation for the latest recommended model versions.
|
||||
|
||||
## Schema Definition
|
||||
- **Use `z` from `genkit`**: Always import `z` from the `genkit` package to ensure compatibility.
|
||||
```ts
|
||||
import { z } from "genkit";
|
||||
```
|
||||
- **Descriptive Schemas**: Use `.describe()` on Zod fields. LLMs use these descriptions to understand how to populate the fields.
|
||||
|
||||
## Flow & Tool Design
|
||||
- **Modularize**: Keep flows and tools in separate files/modules and import them into your main Genkit configuration.
|
||||
- **Single Responsibility**: Tools should do one thing well. Complex logic should be broken down.
|
||||
|
||||
## Configuration
|
||||
- **Environment Variables**: Store sensitive keys (like API keys) in environment variables or `.env` files. Do not hardcode them.
|
||||
|
||||
## Development
|
||||
- **Use Dev Mode**: Run your app with `genkit start -- <start cmd>` to enable the Developer UI.
|
||||
- It is recommended to configure a watcher to auto-reload your app (e.g. `node --watch` or `tsx --watch`)
|
||||
@@ -0,0 +1,132 @@
|
||||
# Common Errors & Pitfalls
|
||||
|
||||
## When Typecheck Fails
|
||||
|
||||
**Before searching source code or docs**, check the sections below. Many type errors are caused by deprecated APIs or incorrect imports.
|
||||
|
||||
## Genkit v1.x vs Pre-1.0 Migration
|
||||
|
||||
Genkit v1.x introduced significant API changes. This section covers critical syntax updates.
|
||||
|
||||
### Package Imports
|
||||
|
||||
- **Correct (v1.x)**: Import core functionality (zod, genkit) from the main `genkit` package and plugins from their specific packages.
|
||||
```ts
|
||||
import { z, genkit } from 'genkit';
|
||||
import { googleAI } from '@genkit-ai/google-genai';
|
||||
```
|
||||
|
||||
- **Incorrect (Pre-1.0)**: Importing from `@genkit-ai/ai`, `@genkit-ai/core`, or `@genkit-ai/flow`. These packages are internal/deprecated for direct use.
|
||||
```ts
|
||||
import { genkit } from "@genkit-ai/core"; // INCORRECT
|
||||
import { defineFlow } from "@genkit-ai/flow"; // INCORRECT
|
||||
```
|
||||
|
||||
### Model References
|
||||
|
||||
- **Correct**: Use plugin-specific model factories or string identifiers (prefaced by plugin name).
|
||||
```ts
|
||||
// Using model factory (v1.x - Preferred)
|
||||
await ai.generate({ model: googleAI.model('gemini-2.5-flash'), ... });
|
||||
|
||||
// Using string identifier
|
||||
await ai.generate({ model: 'googleai/gemini-2.5-flash', ...});
|
||||
// Or
|
||||
await ai.generate({ model: 'vertexai/gemini-2.5-flash', ...});
|
||||
```
|
||||
- **Incorrect**: Using imported model objects directly or string identifiers without plugin name.
|
||||
```ts
|
||||
await ai.generate({ model: gemini15Pro, ... }); // INCORRECT (Pre-1.0)
|
||||
await ai.generate({ model: 'gemini-2.5-flash', ... }); // INCORRECT (No plugin prefix)
|
||||
```
|
||||
|
||||
### Model Selection (Gemini)
|
||||
|
||||
- **Preferred**: Use `gemini-2.5-*` models for best performance and features.
|
||||
```ts
|
||||
model: googleAI.model('gemini-2.5-flash') // PREFERRED
|
||||
```
|
||||
- **DEPRECATED**: `gemini-1.5-*` models are deprecated and will throw errors.
|
||||
```ts
|
||||
model: googleAI.model('gemini-1.5-flash') // ERROR (Deprecated)
|
||||
```
|
||||
|
||||
### Response Access
|
||||
|
||||
- **Correct (v1.x)**: Access properties directly.
|
||||
```ts
|
||||
response.text; // CORRECT
|
||||
response.output; // CORRECT
|
||||
```
|
||||
- **Incorrect (Pre-1.0)**: Calling as methods.
|
||||
```ts
|
||||
response.text(); // INCORRECT
|
||||
response.output(); // INCORRECT
|
||||
```
|
||||
|
||||
### Streaming Generation
|
||||
|
||||
- **Correct (v1.x)**: Do NOT await `generateStream`. Iterate over `stream` directly. Await `response` property for final result.
|
||||
```ts
|
||||
const {stream, response} = ai.generateStream(...); // NO await here
|
||||
for await (const chunk of stream) { ... } // Iterate stream
|
||||
const finalResponse = await response; // Await response property
|
||||
```
|
||||
- **Incorrect (Pre-1.0)**: Calling stream as a function or awaiting the generator incorrectly.
|
||||
```ts
|
||||
for await (const chunk of stream()) { ... } // INCORRECT
|
||||
await response(); // INCORRECT
|
||||
```
|
||||
|
||||
### Initialization
|
||||
|
||||
- **Correct (v1.x)**: Instantiate `genkit`.
|
||||
```ts
|
||||
const ai = genkit({ plugins: [...] });
|
||||
```
|
||||
- **Incorrect (Pre-1.0)**: Global configuration.
|
||||
```ts
|
||||
configureGenkit({ plugins: [...] }); // INCORRECT
|
||||
```
|
||||
|
||||
### Flow Definitions
|
||||
|
||||
- **Correct (v1.x)**: Define flows on the `ai` instance.
|
||||
```ts
|
||||
ai.defineFlow({...}, (input) => {...});
|
||||
```
|
||||
- **Incorrect (Pre-1.0)**: Importing `defineFlow` globally.
|
||||
```ts
|
||||
import { defineFlow } from "@genkit-ai/flow"; // INCORRECT
|
||||
|
||||
You should never import `@genkit-ai/flow`, `@genkit-ai/ai` or `@genkit-ai/core` packages directly.
|
||||
|
||||
## Zod & Schema Errors
|
||||
|
||||
- **Import Source**: ALWAYS use `import { z } from "genkit"`.
|
||||
- Using `zod` directly from `zod` package may cause instance mismatches or compatibility issues.
|
||||
- **Supported Types**: Stick to basic types: scalar (`string`, `number`, `boolean`), `object`, and `array`.
|
||||
- Avoid complex Zod features unless strictly necessary and verified.
|
||||
- **Descriptions**: Always use `.describe('...')` for fields in output schemas to guide the LLM.
|
||||
|
||||
## Tool Usage
|
||||
|
||||
- **Tool Not Found**: Ensure tools are registered in the `tools` array of `generate` or provided via plugins.
|
||||
- **MCP Tools**: Use the `ServerName:tool_name` format when referencing MCP tools.
|
||||
|
||||
## Multimodal & Image Generation
|
||||
|
||||
- **Missing responseModalities**: When using image generation models (like `gemini-2.5-flash-image`), you **MUST** specify the response modalities in the config.
|
||||
```ts
|
||||
config: {
|
||||
responseModalities: ["TEXT", "IMAGE"]
|
||||
}
|
||||
```
|
||||
Failure to do so will result in errors or incorrect output format.
|
||||
|
||||
## Audio & Speech Generation
|
||||
|
||||
- **Raw PCM Data vs MP3**: Some providers (e.g., Google GenAI) return raw PCM data, while others (e.g., OpenAI) return MP3.
|
||||
- **DO NOT assume MP3 format.**
|
||||
- **DO NOT embed raw PCM in HTML audio tags.**
|
||||
- **Action**: Run `genkit docs:search "speech audio"` to find provider-specific conversion steps (e.g., PCM to WAV).
|
||||
@@ -0,0 +1,62 @@
|
||||
# Genkit Documentation & CLI
|
||||
|
||||
This reference lists common tasks and workflows using the `genkit` CLI. For authoritative command details, always run `genkit --help` or `genkit <command> --help`.
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
Ensure that the CLI is on `genkit-cli` version >= 1.29.0. If not, or if an older version (1.x < 1.29.0) is present, update the Genkit CLI version. Alternatively, to run commands with a specific version or without global installation, prefix them with `npx -y genkit-cli@^1.29.0`.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Search docs**: `genkit docs:search <query>`
|
||||
- Example: `genkit docs:search "streaming"`
|
||||
- Example: `genkit docs:search "rag retrieval"`
|
||||
- **Read doc**: `genkit docs:read <path>`
|
||||
- Example: `genkit docs:read js/overview.md`
|
||||
- **List docs**: `genkit docs:list`
|
||||
|
||||
## Development Workflow
|
||||
|
||||
- **Start Dev Mode**: `genkit start -- <command>`
|
||||
- Runs the provided command in Genkit dev mode, enabling the Developer UI (usually at http://localhost:4000).
|
||||
- **Node.js (TypeScript)**:
|
||||
```bash
|
||||
genkit start -- npx tsx --watch src/index.ts
|
||||
```
|
||||
- **Next.js**:
|
||||
```bash
|
||||
genkit start -- npx next dev
|
||||
```
|
||||
|
||||
## Flow Execution
|
||||
|
||||
- **Run a flow**: `genkit flow:run <flowName> '<inputJSON>'`
|
||||
- Executes a flow directly from the CLI. Useful for testing.
|
||||
- **Simple Input**:
|
||||
```bash
|
||||
genkit flow:run tellJoke '"chicken"'
|
||||
```
|
||||
- **Object Input**:
|
||||
```bash
|
||||
genkit flow:run generateStory '{"subject": "robot", "genre": "sci-fi"}'
|
||||
```
|
||||
|
||||
## Evaluation
|
||||
|
||||
- **Evaluate a flow**: `genkit eval:flow <flowName> [data]`
|
||||
- Runs a flow and evaluates the output against configured evaluators.
|
||||
- **Example (Single Input)**:
|
||||
```bash
|
||||
genkit eval:flow answerQuestion '[{"testCaseId": "1", "input": {"question": "What is Genkit?"}}]'
|
||||
```
|
||||
- **Example (Batch Input)**:
|
||||
```bash
|
||||
genkit eval:flow answerQuestion --input inputs.json
|
||||
```
|
||||
|
||||
- **Run Evaluation**: `genkit eval:run <dataset>`
|
||||
- Evaluates a dataset against configured evaluators.
|
||||
- **Example**:
|
||||
```bash
|
||||
genkit eval:run dataset.json --output results.json
|
||||
```
|
||||
@@ -0,0 +1,157 @@
|
||||
# Genkit Examples
|
||||
|
||||
This reference contains minimal, reproducible examples (MREs) for common Genkit patterns.
|
||||
|
||||
> **Disclaimer**: These examples use **Google AI** models (`googleAI`, `gemini-*`) for demonstration. The patterns apply to **any provider**. To use a different provider:
|
||||
> 1. Search the docs for the correct plugin: `genkit docs:search "plugins"`.
|
||||
> 2. Install and configure the plugin.
|
||||
> 3. Swap the model reference in the code.
|
||||
|
||||
## Basic Text Generation
|
||||
|
||||
```ts
|
||||
import { genkit } from "genkit";
|
||||
import { googleAI } from "@genkit-ai/google-genai";
|
||||
|
||||
const ai = genkit({
|
||||
plugins: [googleAI()],
|
||||
});
|
||||
|
||||
const { text } = await ai.generate({
|
||||
model: googleAI.model('gemini-2.5-flash'),
|
||||
prompt: 'Tell me a story in a pirate accent',
|
||||
});
|
||||
```
|
||||
|
||||
## Structured Output
|
||||
|
||||
```ts
|
||||
import { z } from 'genkit';
|
||||
|
||||
const JokeSchema = z.object({
|
||||
setup: z.string().describe('The setup of the joke'),
|
||||
punchline: z.string().describe('The punchline'),
|
||||
});
|
||||
|
||||
const response = await ai.generate({
|
||||
model: googleAI.model('gemini-2.5-flash'),
|
||||
prompt: 'Tell me a joke about developers.',
|
||||
output: { schema: JokeSchema },
|
||||
});
|
||||
|
||||
// response.output is strongly typed
|
||||
const joke = response.output;
|
||||
if (joke) {
|
||||
console.log(`${joke.setup} ... ${joke.punchline}`);
|
||||
}
|
||||
```
|
||||
|
||||
## Streaming
|
||||
|
||||
```ts
|
||||
const { stream, response } = ai.generateStream({
|
||||
model: googleAI.model('gemini-2.5-flash'),
|
||||
prompt: 'Tell a long story about a developer using Genkit.',
|
||||
});
|
||||
|
||||
for await (const chunk of stream) {
|
||||
console.log(chunk.text);
|
||||
}
|
||||
|
||||
// Await the final response
|
||||
const finalResponse = await response;
|
||||
console.log('Complete:', finalResponse.text);
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Thinking Mode (Gemini 3 Only)
|
||||
|
||||
Enable "thinking" process for complex reasoning tasks.
|
||||
|
||||
```ts
|
||||
const response = await ai.generate({
|
||||
model: googleAI.model('gemini-3.1-pro-preview'),
|
||||
prompt: 'what is heavier, one kilo of steel or one kilo of feathers',
|
||||
config: {
|
||||
thinkingConfig: {
|
||||
thinkingLevel: 'HIGH', // or 'LOW'
|
||||
includeThoughts: true, // Returns thought process in response
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Google Search Grounding
|
||||
|
||||
Enable models to access current information via Google Search.
|
||||
|
||||
```ts
|
||||
const response = await ai.generate({
|
||||
model: googleAI.model('gemini-2.5-flash'),
|
||||
prompt: 'What are the top tech news stories this week?',
|
||||
config: {
|
||||
googleSearchRetrieval: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Access grounding metadata (sources)
|
||||
const groundingMetadata = (response.custom as any)?.candidates?.[0]?.groundingMetadata;
|
||||
if (groundingMetadata) {
|
||||
console.log('Sources:', groundingMetadata.groundingChunks);
|
||||
}
|
||||
```
|
||||
|
||||
## Multimodal Generation
|
||||
|
||||
### Image Generation / Editing
|
||||
|
||||
**Critical**: You MUST set `responseModalities: ['TEXT', 'IMAGE']` when using image generation models.
|
||||
|
||||
```ts
|
||||
// Generate an image
|
||||
const { media } = await ai.generate({
|
||||
model: googleAI.model('gemini-2.5-flash-image'),
|
||||
config: { responseModalities: ['TEXT', 'IMAGE'] },
|
||||
prompt: "generate a picture of a unicorn wearing a space suit on the moon",
|
||||
});
|
||||
// media.url contains the data URI
|
||||
```
|
||||
|
||||
```ts
|
||||
// Edit an image
|
||||
const { media } = await ai.generate({
|
||||
model: googleAI.model('gemini-2.5-flash-image'),
|
||||
config: { responseModalities: ['TEXT', 'IMAGE'] },
|
||||
prompt: [
|
||||
{ text: "change the person's outfit to a banana costume" },
|
||||
{ media: { url: "https://example.com/photo.jpg" } },
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
### Speech Generation (TTS)
|
||||
|
||||
Generate audio from text.
|
||||
|
||||
```ts
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
|
||||
const { media } = await ai.generate({
|
||||
model: googleAI.model('gemini-2.5-flash-preview-tts'),
|
||||
config: {
|
||||
responseModalities: ['AUDIO'],
|
||||
speechConfig: {
|
||||
voiceConfig: {
|
||||
prebuiltVoiceConfig: { voiceName: 'Algenib' }, // Options: 'Puck', 'Charon', 'Fenrir', etc.
|
||||
},
|
||||
},
|
||||
},
|
||||
prompt: 'Genkit is an amazing library',
|
||||
});
|
||||
|
||||
// The response contains raw PCM data in media.url (base64 encoded).
|
||||
// CAUTION: This is NOT an MP3/WAV file. It requires conversion (e.g., PCM to WAV).
|
||||
// DO NOT GUESS. Run `genkit docs:search "speech audio"` to find the correct
|
||||
// conversion code for your provider.
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
# Genkit JS Setup
|
||||
|
||||
Follow these instructions to set up Genkit in the current codebase. These instructions are general-purpose and have not been written with specific codebase knowledge, so use your best judgement when following them.
|
||||
|
||||
0. Tell the user "I'm going to check out your workspace and set you up to use Genkit for GenAI workflows."
|
||||
1. If the current workspace is empty or is a starter template, your goal will be to create a simple image generation flow that allows someone to generate an image based on a prompt and selectable style. If the current workspace is not empty, you will create a simple example flow to help get the user started.
|
||||
2. Check to see if any Genkit provider plugin (such as `@genkit-ai/google-genai` or `@genkit-ai/oai-compat` or others, may start with `genkitx-*`) is installed.
|
||||
- If not, ask the user which provider they want to use.
|
||||
- **For non-Google providers**: Use `genkit docs:search "plugins"` to find the correct package and installation instructions.
|
||||
- If they have no preference, default to `@genkit-ai/google-genai` for a quick start.
|
||||
- If this is a Next.js app, install `@genkit-ai/next` as well.
|
||||
3. Search the codebase for the exact string `genkit(` (remember to escape regexes properly) which would indicate that the user has already set up Genkit in the codebase. If found, no need to set it up again, tell the user "Genkit is already configured in this app." and exit this workflow.
|
||||
4. Create an `ai` directory in the primary source directory of the project (this may be e.g. `src` but is project-dependent). Adapt this path if your project uses a different structure.
|
||||
5. Create `{sourceDir}/ai/genkit.ts` and populate it using the example below. DO NOT add a `next` plugin to the file, ONLY add a model provider plugin to the plugins array:
|
||||
|
||||
```ts
|
||||
import { genkit, z } from 'genkit';
|
||||
// Import your chosen provider plugin here. Example:
|
||||
import { googleAI } from '@genkit-ai/google-genai';
|
||||
|
||||
export const ai = genkit({
|
||||
plugins: [
|
||||
googleAI(), // Add your provider plugin here
|
||||
],
|
||||
model: googleAI.model('gemini-2.5-flash'), // Set your provider's model here
|
||||
});
|
||||
|
||||
export { z };
|
||||
```
|
||||
|
||||
6. Create `{sourceDir}/ai/tools` and `{sourceDir}/ai/flows` directories, but leave them empty for now.
|
||||
7. Create `{sourceDir}/ai/index.ts` and populate it with the following (change the import to match import aliases in `tsconfig.json` as needed):
|
||||
|
||||
```ts
|
||||
import './genkit.js';
|
||||
// import each created flow, tool, etc. here for use in the Genkit Dev UI
|
||||
```
|
||||
|
||||
8. Add a `genkit:ui` script to `package.json` that runs `genkit start -- npx tsx --watch {sourceDir}/ai/index.ts` (or `npx genkit-cli` or `pnpm dlx` or `yarn dlx` for those package managers, if CLI is not locally installed). DO NOT try to run the script now.
|
||||
9. Tell the user "Genkit is now configured and ready for use." as setup is now complete. Also remind them to set appropriate env variables (e.g. `GEMINI_API_KEY` for Google providers). Wait for the user to prompt further before creating any specific flows.
|
||||
|
||||
## Next Steps & Troubleshooting
|
||||
|
||||
- **Documentation**: Use the [CLI](docs-and-cli.md) to access documentation (e.g., `genkit docs:search`).
|
||||
- **Building Flows**: See [examples.md](examples.md) for patterns on creating flows, adding tools, and advanced configuration.
|
||||
- **Troubleshooting**: If you encounter issues during setup or initialization, check [common-errors.md](common-errors.md) for solutions.
|
||||
Reference in New Issue
Block a user