Native grounding
Some providers search the web for you. Hand the model a provider-hosted tool and it searches on its own side, then answers with citations attached. This is the native counterpart to grounded answer: same agent loop, but you skip wiring a search backend.
Drop the hosted tool in
Each provider ships its own constructor, since the tools are provider-specific:
import { googleSearchTool } from "@effect-uai/google/Gemini"import { webSearchTool as anthropicWebSearch } from "@effect-uai/anthropic/Anthropic"import { webSearchTool as openaiWebSearch } from "@effect-uai/responses/Responses"
const searchTool = googleSearchTool // or anthropicWebSearch() / openaiWebSearch()You never write a run for it and the loop never asks you to execute it. It
sits next to your own Tool.make tools; the model uses it to ground its
answer. A hosted tool only works with the provider that hosts it: give a
Gemini tool to the Anthropic model and the request fails with
AiError.Unsupported.
Run it
GOOGLE_API_KEY=... pnpm tsx recipes/native-grounding/run-node.tsANTHROPIC_API_KEY=... pnpm tsx recipes/native-grounding/run-node.ts --provider=anthropicOPENAI_API_KEY=... pnpm tsx recipes/native-grounding/run-node.ts --provider=openai
QUESTION="who won the 2026 F1 season opener?" \ GOOGLE_API_KEY=... pnpm tsx recipes/native-grounding/run-node.tsThe answer streams to stdout as the model writes it. run-bun.ts and
run-deno.ts differ only in the platform HttpClient.