Overview
The@nimble-way/ai-sdk package provides pre-built tools for Vercel’s AI SDK v6. Register them on an agent and the model decides when to search the web, read a page, or commission deeper research. Nimble runs the request and returns clean, structured results to cite.
- Five tools, zero boilerplate: search, extract, and the three deep-research run tools.
- Works with any model: OpenAI, Anthropic, Google, and others supported by the AI SDK.
- Two search depths:
litefor fast metadata,deepfor full page content. - Asynchronous deep research: start a Web Search Agent run, collect the cited answer minutes later.
- Type-safe: written in TypeScript with typed options and output.
tool() definitions, not provider-executed search. They behave the same whether the model call routes through the Vercel AI Gateway or a provider SDK directly. The gateway, when present, routes only the model call.
web_search and web_fetch.Prerequisites
Node.js 18 or later
Node.js 18 or later
Vercel AI SDK v6
Vercel AI SDK v6
ai (v6) and zod (^3.25.76 or ^4.1.8) are peer dependencies. Your app supplies both.NIMBLE_API_KEY (server-side)
NIMBLE_API_KEY (server-side)
NIMBLE_AGENT_ID (deep research only)
NIMBLE_AGENT_ID (deep research only)
POST /v2/agents. The ID looks like wsa_01j9x8.... The search and extract tools do not need it.Quick Start
Install
ai (v6) and zod are peer dependencies. The examples use OpenAI via @ai-sdk/openai, but nimbleSearch works with any AI SDK model provider.Set your API keys
nimbleSearch({ apiKey: '...' }).For deep research, also set NIMBLE_AGENT_ID.Add the tool to an agent
How it works
The model receives the tool
nimbleSearch() registers a webSearch tool the model can call when it needs current information.The model decides to search
query (and optional maxResults).Nimble runs the search
The model answers
stopWhen: stepCountIs(n) caps how many search rounds a single turn can take.Search
nimbleSearch() grounds an answer in live web results. Configure it once; the model only ever supplies { query, maxResults? }.
Next.js route handler
For a streaming chat app, swapgenerateText for streamText inside a route handler and return toUIMessageStreamResponse(). The client connects with the AI SDK useChat hook, with no extra wiring needed.
Search options
apiKey
apiKey
process.env.NIMBLE_API_KEY.searchDepth
searchDepth
'lite' returns metadata only (fast); 'deep' returns full page content. Default 'lite'.maxResults
maxResults
number, default 5.maxResultsCap
maxResultsCap
number, default 10.maxContentLength
maxContentLength
number, default 10_000.country
country
string, default 'US'.locale
locale
string, default 'en'.client
client
NimbleSearchClient for testing. Optional.Search response
Each tool call returns a structured result the model can reason over:Extract
nimbleExtract() registers an extract tool that takes a single URL and returns clean page content, markdown by default, for the model to read, quote, or summarize. The model only ever supplies { url }; all policy below is developer-controlled.
Extract options
ConfigurenimbleExtract() once; the model only ever supplies { url }.
apiKey
apiKey
process.env.NIMBLE_API_KEY.format
format
'markdown' or 'html'. Default 'markdown'.country
country
string, optional.maxContentLength
maxContentLength
number, default 50_000.client
client
NimbleExtractClient for testing. Optional.Extract response
Deep research with Web Search Agents
nimbleSearch() and nimbleExtract() are synchronous building blocks: one call, one response, seconds. A Web Search Agent run is a different capability. An autonomous agent plans, searches, reads, and cross-checks many sources, then returns a final answer with per-claim citations and confidence. It takes minutes, not seconds.
nimbleAgentStartRun()
nimbleAgentRunStatus()
nimbleAgentRunResult()
Start now, answer later
PointNIMBLE_AGENT_ID at your agent instance, then start the run and persist the returned runId.
runId crosses over.
Runs that are still working
A run that has not finished is a normal state, not an error.nimbleAgentRunResult() returns ready: false so the model can tell the user to check back.
nimbleAgentRunStatus() for cheap progress checks that never fetch the result. Its output adds isActive, startedAt, completedAt, and error on failed runs.
Optional bounded waiting
Optional bounded waiting
wait: true for the defaults: a 300_000 ms timeout and a 2_000 ms poll interval, with a 100 ms floor on the interval. On timeout the tool returns ready: false and the run stays healthy. The package never polls without a bound.Abort handling
Abort handling
AbortSignal. Aborting stops the wait only. The run keeps going on Nimble’s side and stays resumable from the same runId.Failed and cancelled runs
Failed and cancelled runs
NimbleAgentRunError. Its reason is 'failed', 'cancelled', 'protocol', or 'request', and it always carries runId so your code can still reference the run. An HTTP status, when there is one, is on error.status.Results and citations
A completed run returns prose or structured data, along withtrust metadata passed through verbatim from the API so citation markers stay aligned with the answer.
trust carries the sources consulted, the per-claim citations, and confidence:
callout, matching the numeric markers in the prose. Structured answers key each claim by path, the JSON path of the value. Exactly one of the two is present. See Trust and citations for how confidence is graded.
Agent run options
All three factories share this configuration. Every field is optional.agentId
agentId
wsa_.... Defaults to process.env.NIMBLE_AGENT_ID. Resolved when the tool executes, so the model can never choose the agent.apiKey
apiKey
process.env.NIMBLE_API_KEY.client
client
NimbleAgentRunsClient for testing. Optional.clientOptions
clientOptions
baseURL, fetch, timeout, and maxRetries on the Nimble client. Optional.nimbleAgentStartRun() adds two more:
effort
effort
'low', 'medium', 'high', 'x-high', or 'max'. Leave it unset to use the agent instance’s own default. Higher tiers research more sources and take longer. See Efforts.effortCap
effortCap
'high', so a model cannot trigger the x-high or max cost tiers on its own. It never limits the developer-set effort.nimbleAgentRunResult() adds wait, documented under bounded waiting.
The model-facing inputs stay small: { task, effort? } for the start tool and { runId } for the status and result tools. The agent identity, credentials, and wait policy are never model-controlled.
Limitations
- Search, Extract, and Web Search Agent runs ship today. Map and Crawl are planned follow-ups.
- Agent runs need a pre-created agent instance. Set
NIMBLE_AGENT_ID. Creating and managing agents, and managing templates, are deliberately not model-callable tools in this release. - Run event streaming (SSE) is not exposed by this release. Use the status and result tools.
- No built-in answer generation in Search. The tool returns results and the model writes the answer.
searchDepth: 'fast'is not available in this package.- Node.js runtime (18 or later) is the supported target. Edge and serverless compatibility is unverified.
Resources
npm Package
@nimble-way/ai-sdk on npm.