惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
量子位
V
Visual Studio Blog
博客园 - Franky
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
罗磊的独立博客
小众软件
小众软件
V
V2EX
GbyAI
GbyAI
B
Blog RSS Feed
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
有赞技术团队
有赞技术团队
月光博客
月光博客
Recent Announcements
Recent Announcements
雷峰网
雷峰网
F
Fortinet All Blogs
M
MIT News - Artificial intelligence

TanStack Blog

TanStack + Vercel Partnership | TanStack Blog TanStack AI Enters the RC Phase | TanStack Blog Inside a TanStack Router Navigation | TanStack Blog Form v2 is here: All you need to know about the alpha | TanStack Blog Announcing TanStack Table V9 | TanStack Blog TanStack Has a New Look | TanStack Blog Introducing TanStack Markdown and TanStack Highlight | TanStack Blog We Removed React Server Components from TanStack.com | TanStack Blog We Stopped Using RSC on TanStack.com | TanStack Blog Inside TanStack Table V9 Reactivity | TanStack Blog Run Any Coding Agent in a Sandbox, With One chat() Call | TanStack Blog TanStack Start and TanStack AI Win 2026 Open Source Awards | TanStack Blog How an Underrated Refactor Saved 90% Memory Usage | TanStack Blog TypeScript Performance in TanStack Table V9 | TanStack Blog TanStack AI Beta: The Switzerland of AI Tooling Grows Up | TanStack Blog TanStack Table V9: Taking Form | TanStack Blog TanStack AI: Your MCP, your way | TanStack Blog TanStack Start Adds First-Class Rsbuild Support | TanStack Blog Introducing Experimental Workflows and Orchestrators in TanStack AI | TanStack Blog Chat UIs Are Lists Until They Aren't | TanStack Blog Structured Output That Remembers Across Turns | TanStack Blog TanStack Virtual just got a lot faster, and finally handles iOS | TanStack Blog TanStack AI now fully speaks AG-UI | TanStack Blog Stop Waiting on JSON: Stream Structured Output with One Schema | TanStack Blog Hardening TanStack After the npm Compromise | TanStack Blog Postmortem: TanStack npm supply-chain compromise | TanStack Blog Who Owns the Tree? RSC as a Protocol, Not an Architecture | TanStack Blog TanStack AI Just Learned to Compose Music | TanStack Blog One Flag, Every Chunk: Debug Logging Lands in TanStack AI | TanStack Blog How We Test TanStack AI Across 7 Providers on Every PR | TanStack Blog
Your AI Tool Calls Should Fail at Compile Time, Not in Pr...
Alem Tuzlak · 2026-04-23 · via TanStack Blog

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.

ModelProvider tools supported
only
web tools only (, )
full superset (web, code execution, computer use, bash, editor, memory)
none
familyfull 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:

  1. Per-model capability declarations. Each model constant declares a array: , or the full superset, or . This is the ground truth.

  2. 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.

  3. 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.