From 5ff525c4b6d288fef4a6e0fbf11fa98636285830 Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 12 Jan 2026 08:55:21 +0000 Subject: [PATCH 1/4] feat(anthropic): add web search --- .../anthropic/src/runner/converters/beta.ts | 1 - .../anthropic/src/runner/converters/shared.ts | 1 - .../anthropic/src/runner/converters/stable.ts | 1 - js/testapps/anthropic/package.json | 1 + .../anthropic/src/stable/web-search-tool.ts | 70 +++++++++++++++++++ 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 js/testapps/anthropic/src/stable/web-search-tool.ts diff --git a/js/plugins/anthropic/src/runner/converters/beta.ts b/js/plugins/anthropic/src/runner/converters/beta.ts index c597dbb848..cd6a3d031e 100644 --- a/js/plugins/anthropic/src/runner/converters/beta.ts +++ b/js/plugins/anthropic/src/runner/converters/beta.ts @@ -35,7 +35,6 @@ export function betaServerToolUseBlockToPart(block: { ? `${block.server_name}/${baseName}` : baseName; return { - text: `[Anthropic server tool ${serverToolName}] input: ${JSON.stringify(block.input)}`, metadata: { anthropicServerToolUse: { id: block.id, diff --git a/js/plugins/anthropic/src/runner/converters/shared.ts b/js/plugins/anthropic/src/runner/converters/shared.ts index 6d6faf6091..a34bb90a7d 100644 --- a/js/plugins/anthropic/src/runner/converters/shared.ts +++ b/js/plugins/anthropic/src/runner/converters/shared.ts @@ -76,7 +76,6 @@ export function webSearchToolResultBlockToPart(block: { content: unknown; }): Part { return { - text: `[Anthropic server tool result ${block.tool_use_id}] ${JSON.stringify(block.content)}`, metadata: { anthropicServerToolResult: { type: 'web_search_tool_result', diff --git a/js/plugins/anthropic/src/runner/converters/stable.ts b/js/plugins/anthropic/src/runner/converters/stable.ts index d6b3508d42..bfa7e8b56f 100644 --- a/js/plugins/anthropic/src/runner/converters/stable.ts +++ b/js/plugins/anthropic/src/runner/converters/stable.ts @@ -30,7 +30,6 @@ export function serverToolUseBlockToPart(block: { input: unknown; }): Part { return { - text: `[Anthropic server tool ${block.name}] input: ${JSON.stringify(block.input)}`, metadata: { anthropicServerToolUse: { id: block.id, diff --git a/js/testapps/anthropic/package.json b/js/testapps/anthropic/package.json index 0f7ac15001..ce866bca4d 100644 --- a/js/testapps/anthropic/package.json +++ b/js/testapps/anthropic/package.json @@ -19,6 +19,7 @@ "dev:stable:pdf": "genkit start -- npx tsx --watch src/stable/pdf.ts", "dev:stable:tools": "genkit start -- npx tsx --watch src/stable/tools.ts", "dev:stable:vision": "genkit start -- npx tsx --watch src/stable/vision.ts", + "dev:stable:web-search-tool": "genkit start -- npx tsx --watch src/stable/web-search-tool.ts", "genkit:dev": "cross-env GENKIT_ENV=dev npm run dev:stable", "genkit:start": "cross-env GENKIT_ENV=dev genkit start -- tsx --watch src/stable/basic.ts", "dev": "export GENKIT_RUNTIME_ID=$(openssl rand -hex 8) && node lib/stable/basic.js 2>&1" diff --git a/js/testapps/anthropic/src/stable/web-search-tool.ts b/js/testapps/anthropic/src/stable/web-search-tool.ts new file mode 100644 index 0000000000..c056f4c935 --- /dev/null +++ b/js/testapps/anthropic/src/stable/web-search-tool.ts @@ -0,0 +1,70 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { anthropic } from '@genkit-ai/anthropic'; +import { genkit } from 'genkit'; + +const ai = genkit({ + plugins: [ + // Configure the plugin with environment-driven API key + anthropic(), + ], +}); + +ai.defineFlow('anthropic-stable-web-search-tool', async () => { + const { text } = await ai.generate({ + model: anthropic.model('claude-sonnet-4-5'), + prompt: 'What is the weather in Tokyo?', + config: { + tools: [ + { + type: 'web_search_20250305', + name: 'web_search', + }, + ], + }, + }); + + return text; +}); + +ai.defineFlow( + 'anthropic-stable-web-search-tool-stream', + async (_, { sendChunk }) => { + const { stream } = ai.generateStream({ + model: anthropic.model('claude-sonnet-4-5'), + prompt: 'What is the weather in Tokyo?', + config: { + tools: [ + { + type: 'web_search_20250305', + name: 'web_search', + }, + ], + }, + }); + + let response = ''; + for await (const chunk of stream) { + if (chunk.text) { + response += chunk.text; + sendChunk(chunk.text); + } + } + + return response; + } +); From 728b01013193fc03547d037827eb092aecba898b Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 12 Jan 2026 09:07:35 +0000 Subject: [PATCH 2/4] fix(anthropic): tests --- js/plugins/anthropic/tests/beta_runner_test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/js/plugins/anthropic/tests/beta_runner_test.ts b/js/plugins/anthropic/tests/beta_runner_test.ts index 98e4226e86..19ec75c028 100644 --- a/js/plugins/anthropic/tests/beta_runner_test.ts +++ b/js/plugins/anthropic/tests/beta_runner_test.ts @@ -320,7 +320,6 @@ describe('BetaRunner', () => { } as any; const toolPart = exposed.toGenkitPart(serverToolEvent); assert.deepStrictEqual(toolPart, { - text: '[Anthropic server tool srv/myTool] input: {"foo":"bar"}', metadata: { anthropicServerToolUse: { id: 'toolu_test', @@ -765,7 +764,6 @@ describe('BetaRunner', () => { server_name: 'srv', }); assert.deepStrictEqual(serverToolPart, { - text: '[Anthropic server tool srv/serverTool] input: {"arg":"value"}', metadata: { anthropicServerToolUse: { id: 'srv_tool_1', From a03266ade8cc5d8d7556029bc1ca5d14c7fa827b Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 12 Jan 2026 14:58:43 +0000 Subject: [PATCH 3/4] chore(testapps/anthropic): update readme --- js/testapps/anthropic/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/testapps/anthropic/README.md b/js/testapps/anthropic/README.md index b209958e68..b17dc7aab6 100644 --- a/js/testapps/anthropic/README.md +++ b/js/testapps/anthropic/README.md @@ -42,6 +42,7 @@ src/ - `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:web-search-tool` – Start Dev UI for web search tool demo. ## Flows @@ -72,4 +73,8 @@ 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 +### Web Search Tool +- `stable-web-search-tool` – Use the web search tool to find the weather in Tokyo +- `stable-web-search-tool-stream` – Streaming response with web search tool + Example: `genkit flow:run anthropic-stable-hello` From e6faa832cf19b82158e3c08bf9352926715123e7 Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 12 Jan 2026 15:52:50 +0000 Subject: [PATCH 4/4] chore(anthropic): update readme --- js/plugins/anthropic/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/js/plugins/anthropic/README.md b/js/plugins/anthropic/README.md index 99bb31e688..7b0ba6682a 100644 --- a/js/plugins/anthropic/README.md +++ b/js/plugins/anthropic/README.md @@ -95,6 +95,21 @@ The beta API surface provides access to experimental features, but some server-m Note that `server_tool_use` and `web_search_tool_result` ARE supported and work with both stable and beta APIs. +### Web Search Tool + +You can use Anthropic's web search tool by defining the tool in the prompt. + +```typescript +const response = await ai.generate({ + prompt: 'What is the weather in Tokyo?', + config: { + tools: [{ type: 'web_search_20250305', name: 'web_search' }], + }, +}); +``` + +By default, the tool will only be used if it matches the user's prompt. You can override this behavior by modifying the `tool_choice` config option. + ### Within a flow ```typescript