



























by Alem Tuzlak on Apr 22, 2026.
You wire up on your Anthropic adapter. You ship. A week later, a user complains the model's answers feel weirdly out of date. You dig in. Turns out the model you rolled out to half your users doesn't actually support that tool. No error. No exception. The model just quietly pretends the tool doesn't exist and makes up an answer.
This is the worst kind of bug: type-clean, lint-clean, test-clean, production-loud.
As of the latest TanStack AI release, this class of bug is impossible to ship. Provider tools are now gated at the type level, per model, at compile time. If the pairing is invalid, TypeScript tells you on the line where you pass the tool.
A "provider tool" is a native capability the provider hosts for you. Anthropic web search. OpenAI code interpreter. Gemini Google search. Computer use. Bash. Text editor. These are not functions you wrote; they're first-class features the provider's infrastructure runs on the model's behalf.
Here's the catch: support is per model, not per provider.
| Model | Provider tools supported |
|---|---|
| only | |
| web tools only (, ) | |
| full superset (web, code execution, computer use, bash, editor, memory) | |
| none | |
| family | full superset |
| full superset | |
| narrower subset |
If you pass to , the provider either rejects the request, or more commonly, the model ignores the tool and generates a confident-sounding response anyway. No stack trace. No warning. Nothing for your tests to catch, because the response shape is valid, just wrong.
The SDK cannot help you here unless the type system knows which model accepts which tool. That is the gap this release fills.
Before this release, every tool factory returned a plain . The compiler treated them as interchangeable:
Ships clean. Passes CI. Fails in the wild.
Every provider tool factory now returns a brand. The adapter carries a list in its type channel, derived from each model's array. TypeScript gates the array so only brands in that list are assignable.
Same code, now:
The error lands on the array element, exactly where you would fix it. Swap the model to and the same line compiles. Swap for and it compiles on too, because haiku-3 supports web search.
You don't have to remember the compatibility matrix. The compiler remembers it for you.
Gating only makes sense for provider-hosted tools, because only those have per-model support differences. Tools you write yourself are your code; they run wherever your code runs. The helper in returns a plain unbranded , and the factories from the OpenAI and Anthropic adapters do the same. All of them are universally assignable:
No workarounds. No casts. User-defined tools behave the way they always have.
Three ingredients make this safe:
Per-model capability declarations. Each model constant declares a array: , or the full superset, or . This is the ground truth.
A capability map lifted into types. A mapped type (for example ) converts the runtime into a type map indexed by model name. The text adapter threads this through a generic on its channel.
A gated discriminated union on . is declared as:
Unbranded tools match the first arm. Provider tools only match the second arm if their is in the current adapter's capability list.
"Phantom-branded" means the tag exists only in the type system. At runtime, a is a plain object; the brand is erased by the TypeScript compiler. Zero bundle cost. Zero runtime cost. The guarantee is entirely in the types.
There is a popular pattern in the AI SDK space: abstract tools behind a gateway layer so one interface "works everywhere." That has real ergonomic value. It also has a ceiling: the lowest common denominator of what every provider supports, with every provider's specific options flattened away.
TanStack AI bets the other direction. You want Anthropic's web search with its actual options (, domain filters, citation formatting), not a generic web-search shape that has to marshal onto four different providers. You want OpenAI's code interpreter with its full container model, not a lowest-common sandbox.
The tradeoff of the native approach is obvious: more surface to misuse. That is exactly what per-model type gating fixes. You get the full provider-native tool surface, and you get a compiler that refuses to let you misapply it.
Every adapter now exports its provider tools from a dedicated subpath:
If you don't import a tool, it doesn't end up in your bundle. Adapter roots stay lean; tool factories ship on demand. The same pattern holds across , , , , , and .
The AI tool-calling surface has always been underspecified at the type level. Models advertise capabilities they partially implement. SDKs promise uniformity they cannot fully deliver. The result is a class of bugs that slip past tests and only show up when a real user asks a real question.
TanStack AI closes that gap at the exact point it matters: the line where you hand tools to a model. If the pairing is invalid, you know before you commit.
Upgrade your adapters, import provider tools from the subpath, and read the Provider Tools guide for the per-model matrix.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。