From 362e21d738d8e613dcec298261f87501807b0647 Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 12 Jan 2026 15:15:16 +0000 Subject: [PATCH 1/2] chore(testapps/anthropic): update readme --- js/testapps/anthropic/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/js/testapps/anthropic/README.md b/js/testapps/anthropic/README.md index b209958e68..9b0e42aae8 100644 --- a/js/testapps/anthropic/README.md +++ b/js/testapps/anthropic/README.md @@ -36,12 +36,17 @@ src/ - `pnpm run start:beta` – Run the compiled beta basic sample. - `pnpm run dev:stable` – Start the Genkit Dev UI over `src/stable/basic.ts` with live reload. - `pnpm run dev:beta` – Start the Genkit Dev UI over `src/beta/basic.ts` with live reload. +- `pnpm run dev:beta:additional-params` – Start Dev UI for additional beta parameters demo. +- `pnpm run dev:beta:effort` – Start Dev UI for beta effort levels demo. +- `pnpm run dev:beta:files-api` – Start Dev UI for beta files API demo. +- `pnpm run dev:beta:structured-output` – Start Dev UI for beta structured output demo. ### Feature-Specific Examples - `pnpm run dev:stable:text-plain` – Start Dev UI for text/plain error handling demo. - `pnpm run dev:stable:webp` – Start Dev UI for WEBP image handling demo. - `pnpm run dev:stable:pdf` – Start Dev UI for PDF document processing demo. - `pnpm run dev:stable:vision` – Start Dev UI for image/vision analysis demo. +- `pnpm run dev:stable:tools` – Start Dev UI for tool/function calling demo. ## Flows @@ -72,4 +77,23 @@ Each source file defines flows that can be invoked from the Dev UI or the Genkit - `stable-vision-base64` – Analyze an image from a local file (base64 encoded) - `stable-vision-conversation` – Multi-turn conversation about an image +### Tool Usage +- `anthropic-stable-tools` – Demonstrates tool/function calling with a weather Genkit tool + +### Beta API - Additional Parameters +- `anthropic-beta-additional-params` – Pass custom parameters (betas, output_config) to the beta API +- `anthropic-beta-additional-params-stream` – Streaming with additional beta parameters + +### Beta API - Effort Levels +- `anthropic-beta-low-effort` – Generate a Python class using low effort configuration +- `anthropic-beta-medium-effort` – Generate a Python class using medium effort configuration +- `anthropic-beta-high-effort` – Generate a Python class using high effort configuration + +### Beta API - Files API +- `beta-pdf-url` – Process a PDF document using Anthropic's Files API + +### Beta API - Structured Output +- `anthropic-beta-generate-person-json` – Generate structured JSON output with constrained schema +- `anthropic-beta-generate-person-json-stream` – Streaming structured JSON generation + Example: `genkit flow:run anthropic-stable-hello` From a9d1e48644fb58e8b8dd1ad7080c643b10a0db77 Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 12 Jan 2026 15:42:28 +0000 Subject: [PATCH 2/2] chore(plugins/anthropic): update readme --- js/plugins/anthropic/README.md | 344 ++++++++++++++++++++++++++++++++- 1 file changed, 340 insertions(+), 4 deletions(-) diff --git a/js/plugins/anthropic/README.md b/js/plugins/anthropic/README.md index 99bb31e688..3aec879558 100644 --- a/js/plugins/anthropic/README.md +++ b/js/plugins/anthropic/README.md @@ -18,6 +18,31 @@ Install the plugin in your project with your favorite package manager: - `yarn add @genkit-ai/anthropic` - `pnpm add @genkit-ai/anthropic` +## Configuration + +The plugin accepts the following configuration options: + +| Option | Type | Required | Description | +|--------|------|----------|-------------| +| `apiKey` | `string` | Yes* | Your Anthropic API key. Can also be set via `ANTHROPIC_API_KEY` environment variable | +| `cacheSystemPrompt` | `boolean` | No | Enable prompt caching to reduce costs and latency for repeated system prompts (default: `false`) | +| `apiVersion` | `'stable' \| 'beta'` | No | Default API surface for all requests. Can be overridden per-request (default: `'stable'`) | + +*The API key is required but can be provided via the environment variable `ANTHROPIC_API_KEY` instead of the config option. + +### Request-level configuration + +In addition to plugin-level configuration, you can pass the following options in the `config` parameter of `generate()` or `generateStream()`: + +| Option | Type | Description | +|--------|------|-------------| +| `apiVersion` | `'stable' \| 'beta'` | Override the API version for this specific request | +| `tool_choice` | `object` | Control which tools the model can use: `{ type: 'auto' }` (default), `{ type: 'any' }` (require any tool), or `{ type: 'tool', name: 'toolName' }` (force specific tool) | +| `thinking` | `object` | Enable extended thinking: `{ enabled: true, budgetTokens: 4096 }` | +| `metadata` | `object` | Request metadata, e.g., `{ user_id: 'user123' }` | + +Plus all standard Genkit configuration options like `temperature`, `maxOutputTokens`, `topP`, `topK`, and `stopSequences`. + ## Usage ### Initialize @@ -46,18 +71,209 @@ const response = await ai.generate({ console.log(response.text); ``` -### Multi-modal prompt +### Streaming responses + +Use `generateStream` to receive responses incrementally: ```typescript -// ...initialize Genkit instance (as shown above)... +const { stream } = ai.generateStream({ + model: anthropic.model('claude-sonnet-4-5'), + prompt: 'Write a short story about a robot.', +}); +for await (const chunk of stream) { + if (chunk.text) { + process.stdout.write(chunk.text); + } +} +``` + +### Multi-modal prompts + +Claude supports analyzing images, PDFs, and other media types. + +**Supported image formats:** JPEG, PNG, GIF, WEBP + +**Supported document formats:** PDF (via base64 data URLs, public URLs, or Files API) + +#### Image analysis + +Analyze images from URLs or base64-encoded data: + +```typescript +// From a URL const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), prompt: [ { text: 'What animal is in the photo?' }, - { media: { url: imageUrl } }, + { media: { url: 'https://example.com/image.jpg' } }, + ], +}); + +// From base64-encoded data +import * as fs from 'fs'; + +const imageBuffer = fs.readFileSync('image.png'); +const imageBase64 = imageBuffer.toString('base64'); + +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + prompt: [ + { text: 'Describe this image in detail.' }, + { + media: { + url: `data:image/png;base64,${imageBase64}`, + contentType: 'image/png', + }, + }, ], }); -console.log(response.text); +``` + +#### Multi-turn conversations with images + +Continue conversations about images across multiple turns: + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + messages: [ + { + role: 'user', + content: [ + { text: 'What do you see in this image?' }, + { media: { url: imageUrl } }, + ], + }, + { + role: 'model', + content: [{ text: 'I see a cat sitting on a windowsill.' }], + }, + { + role: 'user', + content: [{ text: 'What color is the cat?' }], + }, + ], +}); +``` + +#### PDF document processing + +Process PDF documents by providing them as base64 data URLs or public URLs: + +```typescript +import * as fs from 'fs'; +import * as path from 'path'; + +// Using base64 encoding +const pdfBuffer = fs.readFileSync('document.pdf'); +const pdfBase64 = pdfBuffer.toString('base64'); + +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + messages: [ + { + role: 'user', + content: [ + { text: 'Summarize the key points from this document.' }, + { + media: { + url: `data:application/pdf;base64,${pdfBase64}`, + contentType: 'application/pdf', + }, + }, + ], + }, + ], +}); +``` + +Alternatively, use a publicly accessible URL: + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + messages: [ + { + role: 'user', + content: [ + { text: 'What are the main findings in this research paper?' }, + { + media: { + url: 'https://example.com/paper.pdf', + contentType: 'application/pdf', + }, + }, + ], + }, + ], +}); +``` + +### Tool/function calling + +Define tools that Claude can use to answer questions: + +```typescript +import { z } from 'genkit'; + +const getWeather = ai.defineTool( + { + name: 'getWeather', + description: 'Gets the current weather in a given location', + inputSchema: z.object({ + location: z.string().describe('The location to get the weather for'), + }), + outputSchema: z.string(), + }, + async (input) => { + // Your implementation here + return `The current weather in ${input.location} is 72°F and sunny.`; + } +); + +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + tools: [getWeather], + prompt: 'What is the weather in San Francisco?', +}); +``` + +You can control tool usage with the `tool_choice` config: + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + tools: [getWeather], + prompt: 'What is the weather in Paris?', + config: { + tool_choice: { type: 'tool', name: 'getWeather' }, // Force specific tool + // or { type: 'any' } to require any tool + // or { type: 'auto' } to let model decide (default) + }, +}); +``` + +### Structured output + +Generate JSON responses that conform to a specific schema using the `output` option: + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + prompt: 'Generate a fictional person with a name, age, and city.', + output: { + schema: z.object({ + name: z.string(), + age: z.number(), + city: z.string(), + }), + format: 'json', + constrained: true, // Ensures strict schema adherence (beta API) + }, +}); + +console.log(response.output); // Typed object matching the schema ``` ### Extended thinking @@ -81,6 +297,122 @@ console.log(response.reasoning); // Summarized thinking steps When thinking is enabled, request bodies sent through the plugin include the `thinking` payload (`{ type: 'enabled', budget_tokens: … }`) that Anthropic's API expects, and streamed responses deliver `reasoning` parts as they arrive so you can render the chain-of-thought incrementally. +### System prompt caching + +Enable prompt caching to reduce costs and latency for repeated system prompts: + +```typescript +const ai = genkit({ + plugins: [ + anthropic({ + apiKey: process.env.ANTHROPIC_API_KEY, + cacheSystemPrompt: true, // Enable caching + }), + ], +}); +``` + +When enabled, system prompts are automatically cached according to [Anthropic's prompt caching documentation](https://docs.anthropic.com/en/docs/prompt-caching). + +### API version selection + +The plugin supports both stable and beta API surfaces. Configure the default API version at the plugin level or override per-request: + +```typescript +// Set default to beta for all requests +const ai = genkit({ + plugins: [ + anthropic({ + apiKey: process.env.ANTHROPIC_API_KEY, + apiVersion: 'beta', // Default to beta API + }), + ], +}); + +// Override per-request +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + prompt: 'Hello', + config: { + apiVersion: 'stable', // Use stable API for this request + }, +}); +``` + +You can also specify the API version when creating model references: + +```typescript +const betaModel = anthropic.model('claude-opus-4-5', { apiVersion: 'beta' }); +``` + +### Beta API features + +The beta API surface provides access to experimental features. These features require setting `apiVersion: 'beta'` at the plugin or request level. + +#### Effort levels + +Control the computational effort Claude uses when generating responses (beta API only): + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-opus-4-5'), + prompt: 'Write a complex algorithm in Python.', + config: { + apiVersion: 'beta', + output_config: { + effort: 'high', // 'low', 'medium', or 'high' + }, + }, +}); +``` + +Higher effort levels may produce more thoughtful responses, but take longer to generate. + +#### Files API + +Process documents using Anthropic's Files API (beta only). The file must be uploaded to Anthropic's Files API first. This plugin does not handle the file upload for you. + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + messages: [ + { + role: 'user', + content: [ + { text: 'What are the key findings in this document?' }, + { + media: { + url: fileId, + contentType: 'anthropic/file', + }, + }, + ], + }, + ], + config: { + apiVersion: 'beta', + }, +}); +``` + +#### Additional beta parameters + +Pass custom parameters to the beta API using the passthrough config: + +```typescript +const response = await ai.generate({ + model: anthropic.model('claude-opus-4-5'), + prompt: 'Generate a creative story.', + config: { + apiVersion: 'beta', + betas: ['effort-2025-11-24'], // Enable specific beta features + output_config: { + effort: 'medium', + }, + }, +}); +``` + ### Beta API Limitations The beta API surface provides access to experimental features, but some server-managed tool blocks are not yet supported by this plugin. The following beta API features will cause an error if encountered: @@ -167,6 +499,10 @@ This approach is useful for: - Testing models in isolation - Using Genkit models in non-Genkit applications +## Examples + +For comprehensive examples demonstrating all plugin features, see the [testapp](../../testapps/anthropic/). + ## Acknowledgements This plugin builds on the community work published as [`genkitx-anthropic`](https://github.com/BloomLabsInc/genkit-plugins/blob/main/plugins/anthropic/README.md) by Bloom Labs Inc. Their Apache 2.0–licensed implementation provided the foundation for this maintained package.