You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: Provider tools on /tools subpath with per-model type gating (#466)
* feat(ai): add ProviderTool phantom-branded subtype
* feat(ai): add toolCapabilities to TextAdapter type channel
* feat(ai): gate TextActivityOptions.tools on model toolCapabilities
* fix(ai): prevent ProviderTool subsumption in TextActivityOptions.tools union
* test(ai): type tests for TextActivityOptions.tools gating
* test(ai): fix import order and cover broad-TKind ProviderTool rejection
* feat(ai-anthropic): add supports.tools and ToolCapabilitiesByName map
* refactor(ai-anthropic): use Array for supports.tools to match supports.input
* feat(ai-anthropic): brand provider tool factory return types
* refactor(ai-anthropic): replace tools barrel with named re-exports
* fix(ai-anthropic): build AnthropicTool union from branded types
* Revert "fix(ai-anthropic): build AnthropicTool union from branded types"
This reverts commit 801255b.
* feat(ai-anthropic): thread toolCapabilities through text adapter
* feat(ai-anthropic): export AnthropicChatModelToolCapabilitiesByName
* feat(ai-anthropic): add /tools subpath export
* test(ai-anthropic): per-model type tests for provider tools
* test(ai-anthropic): cover all unsupported tools in haiku-3-5 negative case
* feat(ai-openai): add ToolCapabilitiesByName and expanded supports.tools
* feat(ai-openai): brand provider tool factories and replace barrel export
* feat(ai-openai): add /tools subpath export
* test(ai-openai): per-model type tests for provider tools
* feat(ai-gemini): split capabilities into capabilities + tools
Separates tool-type entries (code_execution, file_search, search_grounding,
grounding_with_gmaps, url_context, image_generation) from general capability
flags in ModelMeta.supports. Adds a new tools field to the supports shape,
renames grounding_with_gmaps → google_maps and search_grounding → google_search,
drops image_generation (no tool factory yet), and introduces
GeminiChatModelToolCapabilitiesByName. Threads a fifth TToolCapabilities
generic through GeminiTextAdapter and exports the new type map from the root.
* feat(ai-gemini): brand provider tool factories and replace barrel export
* feat(ai-gemini): add /tools subpath export and type tests
* feat(ai-openrouter)!: move and rename createWebSearchTool to webSearchTool on /tools subpath
Renames createWebSearchTool → webSearchTool, brands its return type as
OpenRouterWebSearchTool (ProviderTool<'openrouter', 'web_search'>), moves
web_search exports to the new ./tools subpath, adds
OpenRouterChatModelToolCapabilitiesByName mapped type (all chat models
support web_search via the gateway), threads TToolCapabilities through the
text adapter, and adds per-model type tests.
* feat(ai-grok, ai-groq): add supports.tools, /tools subpath, and thread toolCapabilities
- Add tools?: ReadonlyArray<never> to ModelMeta.supports interface in both packages
- Add tools: [] as const to every chat model constant
- Export GrokChatModelToolCapabilitiesByName / GroqChatModelToolCapabilitiesByName type maps
- Add 5th TToolCapabilities generic to GrokTextAdapter / GroqTextAdapter via ResolveToolCapabilities
- Add ./tools subpath to package.json exports and vite.config.ts entry for both packages
- Re-export new ToolCapabilitiesByName types from root index.ts in both packages
* chore(scripts): update sync-models templates to include supports.tools
* test(ai-anthropic): runtime smoke test for provider tool factories
* docs: add provider tools concept page
* docs(adapters): add Provider Tools sections for every adapter
* docs: cross-link provider tools concept page and migration section 6
* chore: changesets for provider-tools surface
* fix(ai-groq): reorder imports to satisfy import/first ESLint rule
* fix(changesets): bump adapters to minor for new /tools subpath + openrouter breaking
* fix(ai-openrouter): match @deprecated tag wording across adapters
* fix(changesets): confirm gemini relocation claim is accurate for all active models
Investigated file_search and search_grounding entries in model-meta.ts:
- All active (exported) models: correctly have these entries in tools: array
- Commented-out preview models (GEMINI_2_5_FLASH_LIVE, GEMINI_2_FLASH_LIVE):
still have them in capabilities: but are not part of the released API
- Changeset claim is accurate: relocation is complete for all models that matter
* fix(ai-gemini): export convertToolsToProviderFormat from /tools
* test(ai-openai): cover all 10 unsupported tools in gpt-3.5-turbo
* test(ai-gemini): add negative cases for gemini-3.1-pro-preview
* fix(ai-anthropic): debrand customTool — return plain Tool (universal)
* fix(ai-openai): debrand customTool/functionTool — remove unused brand types
* docs: remove customTool from branded-factories matrix
* test(ai-anthropic): cover debranded customTool acceptance on any model
* ci: apply automated fixes
* review: address CodeRabbit PR feedback
- Tighten TProviderOptions constraint from 'extends object' to
'extends Record<string, any>' across all five text adapters to match
BaseTextAdapter (openai, anthropic, gemini, grok, groq).
- OpenAI & Anthropic: wire chatStream / structuredOutput to the
TProviderOptions generic so per-model provider options are enforced
at the call site, matching the openrouter/gemini pattern.
- OpenRouter webSearchTool: brand via a stable __kind marker and gate
the converter on that; reject malformed metadata explicitly instead
of trusting tool.name === 'web_search' (users can collide on name).
- Docs: fix fileSearchTool example to use the real
fileSearchStoreNames shape; switch webSearchTool example back to
type: 'web_search' (preview variant is a separate factory); update
local_shell/shell/apply_patch supported-models copy to match the
actual supports.tools gating; drop 'todays' typo.
- Tests: apply ESLint import/order + sort-imports to the five
tools-per-model type-safety specs.
* review: address CodeRabbit feedback (round 2)
- ai-openrouter: tighten web_search metadata validation against null/arrays
(typeof 'object' alone accepted both)
- ai-gemini: include googleSearchRetrievalTool in the "rejects all provider
tools" case so no gemini provider-tool kind can regress silently
* review: rename generic `A` to `TAdapter` in typedTools helpers
Satisfies @typescript-eslint/naming-convention rule (type params must match
/^(T|T[A-Z][A-Za-z]+)$/). Applies the fix to all four per-adapter
tools-per-model-type-safety test files (anthropic, gemini, openai, openrouter).
* fix(ai-openrouter): type metadata.web_search as unknown for runtime null/array guard
Prior typing as `WebSearchToolConfig['web_search']` was non-nullable at the
type level, so `metadata.web_search === null` and `Array.isArray(...)` tripped
`@typescript-eslint/no-unnecessary-condition` and failed CI lint.
Widen to `unknown` so the defensive null/array runtime checks are type-meaningful,
then narrow on return.
* chore: remove accidentally-committed terminalOutput artifact
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Expose provider-tool factories (`webSearchTool`, `codeExecutionTool`, `computerUseTool`, `bashTool`, `textEditorTool`, `webFetchTool`, `memoryTool`, `customTool`) on a new `/tools` subpath. Each factory now returns a branded type (e.g. `AnthropicWebSearchTool`) that is gated against the selected model's `supports.tools` list. Existing factory signatures and runtime behavior are unchanged; old config-type aliases (`WebSearchTool`, `BashTool`, etc.) remain as `@deprecated` aliases pointing at the renamed `*ToolConfig` types.
Add `ProviderTool<TProvider, TKind>` phantom-branded tool subtype and a `toolCapabilities` channel on `TextAdapter['~types']`. `TextActivityOptions['tools']` is now typed so that adapter-exported provider tools are gated against the selected model's `supports.tools` list. User tools from `toolDefinition()` remain unaffected.
Expose provider-tool factories (`codeExecutionTool`, `fileSearchTool`, `googleSearchTool`, `googleSearchRetrievalTool`, `googleMapsTool`, `urlContextTool`, `computerUseTool`) on a new `/tools` subpath, each returning a branded type gated against the selected model's `supports.tools` list.
6
+
7
+
Note: `supports.capabilities` entries that described tools (`code_execution`, `file_search`, `grounding_with_gmaps` → renamed `google_maps`, `search_grounding` → renamed `google_search`, `url_context`) have been relocated to the new `supports.tools` field. The `capabilities` array loses those entries. This is a model-meta shape change but not a runtime break.
Expose the `/tools` subpath and add an empty `supports.tools: []` channel per model so Grok adapters participate in the core tool-capability type gating. No provider-specific tool factories are exposed yet — define your own tools with `toolDefinition()` from `@tanstack/ai`.
Expose the `/tools` subpath and add an empty `supports.tools: []` channel per model so Groq adapters participate in the core tool-capability type gating. No provider-specific tool factories are exposed yet — define your own tools with `toolDefinition()` from `@tanstack/ai`.
Expose provider-tool factories (`webSearchTool`, `webSearchPreviewTool`, `fileSearchTool`, `imageGenerationTool`, `codeInterpreterTool`, `mcpTool`, `computerUseTool`, `localShellTool`, `shellTool`, `applyPatchTool`, `customTool`) on a new `/tools` subpath. Each factory returns a branded type (e.g. `OpenAIWebSearchTool`) gated against the selected model's `supports.tools` list. `supports.tools` was expanded to include `web_search_preview`, `local_shell`, `shell`, `apply_patch`. Existing factory signatures and runtime behavior are unchanged.
**Breaking export change.**`createWebSearchTool` has been removed from the package root. Import `webSearchTool` from `@tanstack/ai-openrouter/tools` instead. See Migration Guide §6 for the before/after snippet.
6
+
7
+
Alongside: the new `/tools` subpath exposes `webSearchTool` (branded `OpenRouterWebSearchTool`) and the existing `convertToolsToProviderFormat`. A new `supports.tools` channel on each chat model gates provider tools at the type level.
0 commit comments