Uh oh!
There was an error while loading. Please reload this page.
fix: distinguish custom and native provider tools - #932
Conversation
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAnthropic, Gemini, and OpenAI provider tools now carry stable runtime kind discriminators. Converters use these discriminators instead of names. Tests cover custom-name collisions, JSON round trips, SDK output, Gemini search configuration translation, and wire payloads. ChangesProvider tool dispatch
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Application
participant ToolFactory
participant ProviderConverter
participant ProviderAPI
Application->>ToolFactory: Create provider-native or ordinary tool
ToolFactory->>ToolFactory: Attach provider kind metadata
Application->>ProviderConverter: Convert tools
ProviderConverter->>ProviderAPI: Emit native tool or custom function
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
packages/ai-anthropic/tests/provider-tools-smoke.test.ts (1)
125-152: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFix static analysis warnings by removing the unnecessary type assertion.
The static analysis tools indicate that the
as unknown as Tool[]assertion is unnecessary and thatArray<Tool>should be used instead ofTool[]. Since the array elements are already compatible withTool, you can remove the assertion entirely.♻️ Proposed refactor
textEditorTool({ type: 'text_editor_20250124', name: 'str_replace_editor', }), - ] as unknown as Tool[])+ ]) expect(converted).toHaveLength(7) expect(JSON.stringify(converted)).not.toContain('__kind')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ai-anthropic/tests/provider-tools-smoke.test.ts` around lines 125 - 152, Update the tool array passed to convertToolsToProviderFormat in the “converts multiple provider tools in one call” test by removing the unnecessary “as unknown as Tool[]” assertion; rely on the inferred compatible element types and use Array<Tool> only if an explicit annotation is required.Source: Linters/SAST tools
testing/e2e/src/routes/api.anthropic-skills-wire.ts (1)
3-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCombine imports to fix the import/order warning.
You can resolve the static analysis warning about the import order by combining the type import for
Toolinto the existing@tanstack/aiimport statement.♻️ Proposed refactor
import { createFileRoute } from '`@tanstack/react-router`' -import { chat, createChatOptions } from '`@tanstack/ai`'-import type { Tool } from '`@tanstack/ai`'+import { chat, createChatOptions, type Tool } from '`@tanstack/ai`' import { createAnthropicChat } from '`@tanstack/ai-anthropic`' import { codeExecutionTool } from '`@tanstack/ai-anthropic/tools`'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@testing/e2e/src/routes/api.anthropic-skills-wire.ts` around lines 3 - 18, Combine the `Tool` type import with the existing `@tanstack/ai` import in `api.anthropic-skills-wire.ts`, preserving type-only semantics and leaving the `createAnthropicChat` and `codeExecutionTool` imports unchanged.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ai-gemini/tests/provider-tool-dispatch.test.ts`:
- Line 1: Move provider-tool-dispatch.test.ts from the dedicated tests directory
to packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts, keeping its test
contents unchanged and colocating it with the provider tool dispatch source it
covers.
In `@packages/openai-base/src/tools/computer-use-tool.ts`:
- Around line 42-45: Move the getOpenAIProviderToolMetadata and
openAIProviderTool import to the top of computer-use-tool.ts alongside the other
module imports, removing the duplicate import from its current location.
In `@packages/openai-base/src/tools/image-generation-tool.ts`:
- Around line 58-61: Move the openAIProviderTool import to the top import
section in packages/openai-base/src/tools/image-generation-tool.ts (lines
58-61), packages/openai-base/src/tools/mcp-tool.ts (lines 56-59), and
packages/openai-base/src/tools/shell-tool.ts (lines 54-57), preserving the
existing import ordering rules and leaving usage unchanged.
---
Nitpick comments:
In `@packages/ai-anthropic/tests/provider-tools-smoke.test.ts`:
- Around line 125-152: Update the tool array passed to
convertToolsToProviderFormat in the “converts multiple provider tools in one
call” test by removing the unnecessary “as unknown as Tool[]” assertion; rely on
the inferred compatible element types and use Array<Tool> only if an explicit
annotation is required.
In `@testing/e2e/src/routes/api.anthropic-skills-wire.ts`:
- Around line 3-18: Combine the `Tool` type import with the existing
`@tanstack/ai` import in `api.anthropic-skills-wire.ts`, preserving type-only
semantics and leaving the `createAnthropicChat` and `codeExecutionTool` imports
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 83f2bb1b-2f75-4d7a-893e-ce9b4caa56cb
📒 Files selected for processing (45)
.changeset/tidy-searches-coexist.mdpackages/ai-anthropic/src/adapters/text.tspackages/ai-anthropic/src/tools/anthropic-provider-tool.tspackages/ai-anthropic/src/tools/bash-tool.tspackages/ai-anthropic/src/tools/code-execution-tool.tspackages/ai-anthropic/src/tools/computer-use-tool.tspackages/ai-anthropic/src/tools/memory-tool.tspackages/ai-anthropic/src/tools/text-editor-tool.tspackages/ai-anthropic/src/tools/tool-converter.tspackages/ai-anthropic/src/tools/web-fetch-tool.tspackages/ai-anthropic/src/tools/web-search-tool.tspackages/ai-anthropic/tests/provider-tools-smoke.test.tspackages/ai-anthropic/tests/text.skills.test.tspackages/ai-gemini/src/experimental/text-interactions/adapter.tspackages/ai-gemini/src/tools/code-execution-tool.tspackages/ai-gemini/src/tools/computer-use-tool.tspackages/ai-gemini/src/tools/file-search-tool.tspackages/ai-gemini/src/tools/gemini-provider-tool.tspackages/ai-gemini/src/tools/google-maps-tool.tspackages/ai-gemini/src/tools/google-search-retriveal-tool.tspackages/ai-gemini/src/tools/google-search-tool.tspackages/ai-gemini/src/tools/tool-converter.tspackages/ai-gemini/src/tools/url-context-tool.tspackages/ai-gemini/tests/provider-tool-dispatch.test.tspackages/ai-gemini/tests/text-interactions-adapter.test.tspackages/ai-openai/src/tools/computer-use-tool.tspackages/openai-base/src/tools/apply-patch-tool.tspackages/openai-base/src/tools/code-interpreter-tool.tspackages/openai-base/src/tools/computer-use-tool.tspackages/openai-base/src/tools/custom-tool.tspackages/openai-base/src/tools/file-search-tool.tspackages/openai-base/src/tools/image-generation-tool.tspackages/openai-base/src/tools/local-shell-tool.tspackages/openai-base/src/tools/mcp-tool.tspackages/openai-base/src/tools/openai-provider-tool.tspackages/openai-base/src/tools/shell-tool.tspackages/openai-base/src/tools/tool-converter.tspackages/openai-base/src/tools/web-search-preview-tool.tspackages/openai-base/src/tools/web-search-tool.tspackages/openai-base/tests/provider-tool-dispatch.test.tstesting/e2e/fixtures/provider-tool-dispatch/basic.jsontesting/e2e/src/routes/api.anthropic-skills-wire.tstesting/e2e/src/routes/api.provider-tool-dispatch-wire.tstesting/e2e/tests/anthropic-skills-wire.spec.tstesting/e2e/tests/provider-tool-dispatch-wire.spec.ts
| @@ -0,0 +1,66 @@ | |||
| import { describe, expect, it } from 'vitest' | |||
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Move the test file alongside the source code it covers.
As per coding guidelines, unit tests should be placed in *.test.ts files alongside the source they cover, rather than in a dedicated tests/ directory.
Please move this file to packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/ai-gemini/tests/provider-tool-dispatch.test.ts` at line 1, Move
provider-tool-dispatch.test.ts from the dedicated tests directory to
packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts, keeping its test
contents unchanged and colocating it with the provider tool dispatch source it
covers.
Source: Coding guidelines
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts`:
- Around line 10-11: In provider-tool-dispatch.test.ts, reorder the local
imports so convertToolsToProviderFormat from ./tool-converter appears before the
import from ./index, satisfying the repository’s import/order rule.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f84c6766-9b2c-47d8-9b12-62fb35a31c35
📒 Files selected for processing (1)
packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts
| } from './index' | ||
| import { convertToolsToProviderFormat } from './tool-converter' |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the import order.
Move the ./tool-converter import before the ./index import to satisfy the repository’s import/order ESLint rule.
Proposed fix
+import { convertToolsToProviderFormat } from './tool-converter'
} from './index'
-import { convertToolsToProviderFormat } from './tool-converter'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| }from'./index' | |
| import{convertToolsToProviderFormat}from'./tool-converter' | |
| import{convertToolsToProviderFormat}from'./tool-converter' | |
| }from'./index' |
🧰 Tools
🪛 ESLint
[error] 11-11: ./tool-converter import should occur before import of ./index
(import/order)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts` around lines 10
- 11, In provider-tool-dispatch.test.ts, reorder the local imports so
convertToolsToProviderFormat from ./tool-converter appears before the import
from ./index, satisfying the repository’s import/order rule.
Source: Linters/SAST tools
d66f1ef to
b009147Comparetombeckenham
commented
Aug 10, 2026
Maintainer sweep: rebased onto |
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/ai-anthropic/tests/text.skills.test.ts (1)
149-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffPlace this test beside the source module.
Move this regression test to a source-adjacent
*.test.tsfile. Keep the Vitest test API.As per coding guidelines, “Test files should be placed alongside source code as *.test.ts files using Vitest with happy-dom for DOM testing.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ai-anthropic/tests/text.skills.test.ts` around lines 149 - 164, Move the regression test covering an ordinary function named code_execution from text.skills.test.ts into a *.test.ts file adjacent to the source module that implements computeAnthropicBetas or mapCommonOptionsToAnthropic. Preserve the existing Vitest API and test behavior; only relocate the test and update imports or setup as needed.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ai-anthropic/src/tools/text-editor-tool.ts`:
- Around line 33-43: Update textEditorTool in
packages/ai-anthropic/src/tools/text-editor-tool.ts:33-43, the corresponding
tool factory in
packages/ai-gemini/src/tools/google-search-retriveal-tool.ts:27-37, and the
code-interpreter factory in
packages/openai-base/src/tools/code-interpreter-tool.ts:36-49 to construct tools
through toolDefinition() with the required Zod validation pattern instead of
directly branding objects. For any executable implementation, add both server
and client implementations in each affected factory.
---
Nitpick comments:
In `@packages/ai-anthropic/tests/text.skills.test.ts`:
- Around line 149-164: Move the regression test covering an ordinary function
named code_execution from text.skills.test.ts into a *.test.ts file adjacent to
the source module that implements computeAnthropicBetas or
mapCommonOptionsToAnthropic. Preserve the existing Vitest API and test behavior;
only relocate the test and update imports or setup as needed.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 422cce2d-2a83-4711-99d0-e0e49bc4b497
📒 Files selected for processing (45)
.changeset/tidy-searches-coexist.mdpackages/ai-anthropic/src/adapters/text.tspackages/ai-anthropic/src/tools/anthropic-provider-tool.tspackages/ai-anthropic/src/tools/bash-tool.tspackages/ai-anthropic/src/tools/code-execution-tool.tspackages/ai-anthropic/src/tools/computer-use-tool.tspackages/ai-anthropic/src/tools/memory-tool.tspackages/ai-anthropic/src/tools/text-editor-tool.tspackages/ai-anthropic/src/tools/tool-converter.tspackages/ai-anthropic/src/tools/web-fetch-tool.tspackages/ai-anthropic/src/tools/web-search-tool.tspackages/ai-anthropic/tests/provider-tools-smoke.test.tspackages/ai-anthropic/tests/text.skills.test.tspackages/ai-gemini/src/experimental/text-interactions/adapter.tspackages/ai-gemini/src/tools/code-execution-tool.tspackages/ai-gemini/src/tools/computer-use-tool.tspackages/ai-gemini/src/tools/file-search-tool.tspackages/ai-gemini/src/tools/gemini-provider-tool.tspackages/ai-gemini/src/tools/google-maps-tool.tspackages/ai-gemini/src/tools/google-search-retriveal-tool.tspackages/ai-gemini/src/tools/google-search-tool.tspackages/ai-gemini/src/tools/provider-tool-dispatch.test.tspackages/ai-gemini/src/tools/tool-converter.tspackages/ai-gemini/src/tools/url-context-tool.tspackages/ai-gemini/tests/text-interactions-adapter.test.tspackages/ai-openai/src/tools/computer-use-tool.tspackages/openai-base/src/tools/apply-patch-tool.tspackages/openai-base/src/tools/code-interpreter-tool.tspackages/openai-base/src/tools/computer-use-tool.tspackages/openai-base/src/tools/custom-tool.tspackages/openai-base/src/tools/file-search-tool.tspackages/openai-base/src/tools/image-generation-tool.tspackages/openai-base/src/tools/local-shell-tool.tspackages/openai-base/src/tools/mcp-tool.tspackages/openai-base/src/tools/openai-provider-tool.tspackages/openai-base/src/tools/shell-tool.tspackages/openai-base/src/tools/tool-converter.tspackages/openai-base/src/tools/web-search-preview-tool.tspackages/openai-base/src/tools/web-search-tool.tspackages/openai-base/tests/provider-tool-dispatch.test.tstesting/e2e/fixtures/provider-tool-dispatch/basic.jsontesting/e2e/src/routes/api.anthropic-skills-wire.tstesting/e2e/src/routes/api.provider-tool-dispatch-wire.tstesting/e2e/tests/anthropic-skills-wire.spec.tstesting/e2e/tests/provider-tool-dispatch-wire.spec.ts
🚧 Files skipped from review as they are similar to previous changes (39)
- testing/e2e/fixtures/provider-tool-dispatch/basic.json
- packages/ai-anthropic/src/tools/web-search-tool.ts
- packages/openai-base/tests/provider-tool-dispatch.test.ts
- packages/ai-gemini/src/tools/computer-use-tool.ts
- packages/ai-anthropic/src/tools/bash-tool.ts
- packages/ai-gemini/src/tools/google-search-tool.ts
- packages/openai-base/src/tools/apply-patch-tool.ts
- packages/ai-anthropic/src/tools/tool-converter.ts
- packages/ai-anthropic/src/tools/memory-tool.ts
- packages/ai-gemini/src/tools/file-search-tool.ts
- packages/openai-base/src/tools/tool-converter.ts
- packages/ai-anthropic/src/tools/web-fetch-tool.ts
- packages/openai-base/src/tools/local-shell-tool.ts
- packages/openai-base/src/tools/openai-provider-tool.ts
- packages/ai-gemini/src/tools/provider-tool-dispatch.test.ts
- packages/openai-base/src/tools/custom-tool.ts
- packages/ai-gemini/src/tools/tool-converter.ts
- packages/openai-base/src/tools/mcp-tool.ts
- packages/ai-anthropic/src/tools/code-execution-tool.ts
- packages/openai-base/src/tools/image-generation-tool.ts
- packages/openai-base/src/tools/shell-tool.ts
- testing/e2e/src/routes/api.provider-tool-dispatch-wire.ts
- packages/ai-gemini/src/tools/url-context-tool.ts
- packages/ai-gemini/src/tools/google-maps-tool.ts
- packages/openai-base/src/tools/computer-use-tool.ts
- packages/openai-base/src/tools/file-search-tool.ts
- packages/ai-anthropic/src/adapters/text.ts
- testing/e2e/tests/anthropic-skills-wire.spec.ts
- packages/ai-gemini/tests/text-interactions-adapter.test.ts
- packages/ai-gemini/src/tools/code-execution-tool.ts
- .changeset/tidy-searches-coexist.md
- packages/ai-anthropic/src/tools/computer-use-tool.ts
- packages/ai-gemini/src/tools/gemini-provider-tool.ts
- packages/openai-base/src/tools/web-search-tool.ts
- packages/openai-base/src/tools/web-search-preview-tool.ts
- testing/e2e/tests/provider-tool-dispatch-wire.spec.ts
- packages/ai-anthropic/tests/provider-tools-smoke.test.ts
- packages/ai-openai/src/tools/computer-use-tool.ts
- testing/e2e/src/routes/api.anthropic-skills-wire.ts
Uh oh!
There was an error while loading. Please reload this page.
The two new provider-tool-dispatch E2E tests were failing. They asserted
provider-native wire shapes, but aimock's /v1/_requests journal does not store
raw provider bodies -- both the Responses and Gemini handlers record the request
already normalized into the Chat-Completions envelope
(responsesToCompletionRequest / geminiToCompletionRequest). Assert that shape
instead, and say so in the spec so nobody corrects it back.
Drop the OpenAI case rather than leave it green-but-empty. The OpenAI half of
the fix lives in openai-base/src/tools/tool-converter.ts, and the only adapter
that runs it is ai-openai's openaiText(), which overrides mapOptionsToRequest to
route through the full converter. Neither OpenAI-family provider in the E2E app
reaches it: `openai` is createOpenaiChat() (Chat Completions, never dispatched
on name) and `openai-compatible` inherits the base mapOptionsToRequest, which
sends every tool through convertToolsToResponsesFormat as a function tool. That
case passed against the pre-fix converter, so it proved nothing. The leg is
covered by packages/openai-base/tests/provider-tool-dispatch.test.ts; true E2E
coverage needs an `openai-responses` provider added to the app.
The Gemini case does exercise changed code and now has verified teeth: against
the pre-fix converter the captured tools array comes back empty, because the
tool was swallowed into {googleSearch:{}} and aimock keeps only entries whose
type === 'function'.
Also:
- Commit the regenerated routeTree.gen.ts; the new route was never registered.
- Interactions adapter JSDoc still claimed mcp_server is rejected at runtime
after the throw was removed. There is no Gemini mcp_server factory, so a tool
merely named that is an ordinary function now.
- Changeset: describe the googleSearchTool({searchTypes}) fix. The Interactions
converter read a snake_case search_types array the public factory could never
produce (GoogleSearch.searchTypes: {webSearch?, imageSearch?}), so the
selection was silently dropped and every request fell back to web-search-only.There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
testing/e2e/src/routes/api.provider-tool-dispatch-wire.ts (1)
76-86: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winUse
toolDefinition()for the custom Gemini tool.
createCustomToolcurrently returns a raw JSON-SchemaTool. UsetoolDefinition()with a Zod tool schema so the route follows the TypeScript guideline for schema validation and tool definitions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@testing/e2e/src/routes/api.provider-tool-dispatch-wire.ts` around lines 76 - 86, Update createCustomTool to build the custom Gemini tool through toolDefinition() using a Zod schema for the required query string, rather than returning a raw JSON-Schema Tool object. Preserve the existing tool name and description while allowing the helper to provide schema validation and the resulting tool definition.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@testing/e2e/tests/provider-tool-dispatch-wire.spec.ts`:
- Line 45: Replace the response.json() type assertions in the route response
handling and aimock journal parsing with Zod schemas and safe
parsing/validation. Define schemas for the route envelope and journal entries,
then parse the decoded JSON before accessing fields so malformed aimock
responses fail at the boundary.
- Around line 29-34: The beforeEach cleanup in the provider-tool dispatch tests
clears a shared singleton aimock journal and creates cross-test races. Update
the test setup and journal assertions around the provider-tool dispatch spec to
isolate entries by the current testId (or otherwise use a scoped journal key),
and stop deleting the shared journal before reading it; do not assume entries[0]
belongs to this test.
---
Outside diff comments:
In `@testing/e2e/src/routes/api.provider-tool-dispatch-wire.ts`:
- Around line 76-86: Update createCustomTool to build the custom Gemini tool
through toolDefinition() using a Zod schema for the required query string,
rather than returning a raw JSON-Schema Tool object. Preserve the existing tool
name and description while allowing the helper to provide schema validation and
the resulting tool definition.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: df252695-cec4-4091-ba4b-e6585c3f154a
📒 Files selected for processing (5)
.changeset/tidy-searches-coexist.mdpackages/ai-gemini/src/experimental/text-interactions/adapter.tstesting/e2e/src/routeTree.gen.tstesting/e2e/src/routes/api.provider-tool-dispatch-wire.tstesting/e2e/tests/provider-tool-dispatch-wire.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/ai-gemini/src/experimental/text-interactions/adapter.ts
Uh oh!
There was an error while loading. Please reload this page.
| `/api/provider-tool-dispatch-wire?provider=gemini&testId=${encodeURIComponent(testId)}`, | ||
| ) | ||
| expect(response.ok()).toBe(true) | ||
| const result = (await response.json()) as { ok: boolean; error?: string } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bashset -euo pipefail
rg -n -C 4 'response\.json\(\)|z\.object\(|z\.array\(' \
testing/e2e --glob '*.{ts,tsx}'Repository: TanStack/ai
Length of output: 42229
🏁 Script executed:
#!/bin/bashset -euo pipefail
sed -n '1,95p' testing/e2e/tests/provider-tool-dispatch-wire.spec.tsRepository: TanStack/ai
Length of output: 3220
🏁 Script executed:
#!/bin/bashset -euo pipefail
grep -n "createServer\|tool-dispatch-wire\|/v1/_requests\|PORT\|AIMOCK" testing/e2e/src --include='*.ts' --include='*.tsx' -R ||trueRepository: TanStack/ai
Length of output: 2930
🏁 Script executed:
#!/bin/bashset -euo pipefail
sed -n '1,220p' testing/e2e/src/routes/api.provider-tool-dispatch-wire.tsRepository: TanStack/ai
Length of output: 3369
Validate aimock JSON with Zod.
response.json() uses as casts at both locations in testing/e2e/tests/provider-tool-dispatch-wire.spec.ts (lines 45 and 72-74). Replace these casts with Zod schema parsing for the route envelope and the aimock journal entries so malformed responses fail at the boundary.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@testing/e2e/tests/provider-tool-dispatch-wire.spec.ts` at line 45, Replace
the response.json() type assertions in the route response handling and aimock
journal parsing with Zod schemas and safe parsing/validation. Define schemas for
the route envelope and journal entries, then parse the decoded JSON before
accessing fields so malformed aimock responses fail at the boundary.
Source: Coding guidelines
Addresses the review point that the dispatch spec raced other workers. aimock is a singleton shared by every Playwright worker, so `DELETE /v1/_requests` in beforeEach could wipe a sibling spec's entry between its write and its read, and `entries[0]` could just as easily be somebody else's request. createTextAdapter already tags every provider call with an X-Test-Id header and aimock stores request headers next to the body, so filter the journal by this test's own id and stop mutating shared state. The teeth are unchanged: pre-fix the entry still exists but carries no function tool, so the expectation fails -- and a missing entry now fails with an explicit message instead of silently reading an empty body. Several sibling wire specs (openrouter-web-tools-wire, lazy-tools-wire, multimodal-tool-result-wire, arktype-tool-wire) share the old clear-then-read pattern and have the same latent race; worth a follow-up sweep.
Thanks for the PR, @jan-kubica! 🙌 @AlemTuzlak will take a look. Automated pre-review checks
Automated triage — a human review follows. |
Map Anthropic webSearchTool snake_case config onto the wire payload. Throw DuplicateToolNameError when a factory tool and a custom function share a public name. Strengthen factory tests and document that native tools come from the factory.
View your CI Pipeline Execution ↗ for commit c73f09a
☁️ Nx Cloud last updated this comment at |
@tanstack/ai@tanstack/ai-acp@tanstack/ai-angular@tanstack/ai-anthropic@tanstack/ai-bedrock@tanstack/ai-byteplus@tanstack/ai-claude-code@tanstack/ai-client@tanstack/ai-code-mode@tanstack/ai-code-mode-snippets@tanstack/ai-codex@tanstack/ai-cohere@tanstack/ai-devtools-core@tanstack/ai-durable-stream@tanstack/ai-elevenlabs@tanstack/ai-event-client@tanstack/ai-fal@tanstack/ai-gemini@tanstack/ai-grok@tanstack/ai-grok-build@tanstack/ai-groq@tanstack/ai-isolate-cloudflare@tanstack/ai-isolate-daytona@tanstack/ai-isolate-node@tanstack/ai-isolate-quickjs@tanstack/ai-isolate-quickjs-bun@tanstack/ai-mcp@tanstack/ai-memory@tanstack/ai-mistral@tanstack/ai-ollama@tanstack/ai-openai@tanstack/ai-opencode@tanstack/ai-openrouter@tanstack/ai-perplexity@tanstack/ai-persistence@tanstack/ai-preact@tanstack/ai-react@tanstack/ai-react-ui@tanstack/ai-sandbox@tanstack/ai-sandbox-cloudflare@tanstack/ai-sandbox-daytona@tanstack/ai-sandbox-docker@tanstack/ai-sandbox-local-process@tanstack/ai-sandbox-sprites@tanstack/ai-sandbox-vercel@tanstack/ai-solid@tanstack/ai-solid-ui@tanstack/ai-svelte@tanstack/ai-utils@tanstack/ai-vercel-gateway@tanstack/ai-vue@tanstack/ai-vue-ui@tanstack/openai-base@tanstack/preact-ai-devtools@tanstack/react-ai-devtools@tanstack/solid-ai-devtoolscommit: |
onConfig runs every iteration. Appending the same tool again made chat() throw DuplicateToolNameError. Add the tool only when it is not already in the list. Made-with: Cursor
Uh oh!
There was an error while loading. Please reload this page.
What changed
metadata.__kindvaluesProviderToolphantom brandRoot cause
The Anthropic, Gemini, and OpenAI converters selected provider-native behavior by
tool.name. Tool names are public application identifiers, so an ordinary function could accidentally enter a native converter, acquire provider-only request fields or beta headers, and fail or change behavior on only one provider.Matching versioned provider metadata would fix individual payloads but couple classification to dated wire identifiers. This PR follows the existing OpenRouter and Grok convention instead: adapter-owned metadata carries a stable canonical kind, while provider API versions remain confined to wire converters.
Adapter details
code_executionby name.searchTypesmetadata to its snake_case wire list.customTool, use stable markers inopenai-base;@tanstack/ai-openaireceives a patch release alongside the base package.Test plan
web_search, OpenAI customweb_search, and Gemini customgoogle_searchfinal-wire regressionsSummary by CodeRabbit
New Features
Bug Fixes
Tests