feat(ai): add type-safe tool call events to chat() stream#452
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:
📝 WalkthroughWalkthroughThe changes introduce type-safe streaming for tool calls in the chat function. When Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
🚀 Changeset Version Preview3 package(s) bumped directly, 44 bumped as dependents. 🟥 Major bumps
🟨 Minor bumps
🟩 Patch bumps
|
|
View your CI Pipeline Execution ↗ for commit c0ada34
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-codex
@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-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-mcp
@tanstack/ai-mistral
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@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-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/chat/streaming.md`:
- Around line 115-117: Remove the blank line between the two blockquotes so the
"**Note:**" and "**Tip:**" paragraphs are adjacent (or merge them into one
blockquote); specifically edit the section containing the "**Note:** When
multiple tools..." and the "**Tip:** The typed stream chunk type..." strings so
there is no empty line between those blockquote lines to satisfy markdownlint
MD028.
In `@docs/reference/type-aliases/StreamChunk.md`:
- Line 23: The "Defined in" source anchor for the TypedStreamChunk entry is
stale; update the anchor in docs/reference/type-aliases/StreamChunk.md to point
to the current declaration location packages/typescript/ai/src/types.ts at line
1048 (or to the exact URL/permalink generated by TypeDoc for TypedStreamChunk),
ensuring the link text and URL reflect the new file and line; update the
markdown so it uses the correct Markdown link format and matches the repo's
TypeDoc-generated anchor for TypedStreamChunk.
In `@packages/typescript/ai/tests/type-check.test.ts`:
- Around line 6-17: The named imports in this test file are not alphabetized
causing ESLint sort-imports errors; reorder the members inside each import's
braces alphabetically (e.g., change "describe, it, expectTypeOf" to "describe,
expectTypeOf, it" for the vitest import, and similarly alphabetize "chat,
createChatOptions, toolDefinition" and the type import list "JSONSchema,
StreamChunk, Tool, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent,
TypedStreamChunk") so each import's named members are in ascending alphabetical
order.
🪄 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: 28ddc119-4e8d-45ba-8567-1aae00525797
📒 Files selected for processing (7)
docs/chat/streaming.mddocs/reference/type-aliases/StreamChunk.mddocs/tools/tools.mdexamples/ts-react-chat/src/routes/api.tanchat.tspackages/typescript/ai/src/activities/chat/index.tspackages/typescript/ai/src/types.tspackages/typescript/ai/tests/type-check.test.ts
There was a problem hiding this comment.
♻️ Duplicate comments (2)
docs/reference/type-aliases/StreamChunk.md (1)
23-23:⚠️ Potential issue | 🟡 MinorStale
Defined inlink forTypedStreamChunk.The link points to
types.ts:1033, butTypedStreamChunkis defined at line 1065 in the current code. This will create a broken anchor.📝 Suggested fix
-Defined in: [types.ts:1033](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L1033) +Defined in: [types.ts:1065](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L1065)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/reference/type-aliases/StreamChunk.md` at line 23, The documentation entry for TypedStreamChunk has a stale "Defined in" anchor; update the link target in docs/reference/type-aliases/StreamChunk.md so it points to the actual definition of TypedStreamChunk in types.ts (current location around line 1065) or replace the fragile line-number anchor with a file-level link to types.ts and a search-friendly fragment for TypedStreamChunk; ensure the reference text "Defined in" continues to reference types.ts and that the anchor resolves to the TypedStreamChunk definition.packages/typescript/ai/tests/type-check.test.ts (1)
6-17:⚠️ Potential issue | 🟡 MinorImport members need alphabetical sorting.
ESLint's
sort-importsrule requires alphabetically ordered named imports within each statement.🔧 Suggested fix
-import { describe, it, expectTypeOf } from 'vitest' +import { describe, expectTypeOf, it } from 'vitest' import { z } from 'zod' import { chat, createChatOptions, toolDefinition } from '../src' import type { JSONSchema, StreamChunk, Tool, ToolCallArgsEvent, - ToolCallStartEvent, ToolCallEndEvent, + ToolCallStartEvent, TypedStreamChunk, } from '../src'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/typescript/ai/tests/type-check.test.ts` around lines 6 - 17, The named imports in this file are not alphabetized; reorder the identifiers alphabetically within each import statement—for example change "describe, it, expectTypeOf" to "describe, expectTypeOf, it", "chat, createChatOptions, toolDefinition" to "chat, createChatOptions, toolDefinition" (ensure correct alphabetical order), and the type import list "JSONSchema, StreamChunk, Tool, ToolCallArgsEvent, ToolCallStartEvent, ToolCallEndEvent, TypedStreamChunk" should be reordered alphabetically (e.g., "JSONSchema, StreamChunk, Tool, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent, TypedStreamChunk") so each import's named members follow ESLint's sort-imports rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@docs/reference/type-aliases/StreamChunk.md`:
- Line 23: The documentation entry for TypedStreamChunk has a stale "Defined in"
anchor; update the link target in docs/reference/type-aliases/StreamChunk.md so
it points to the actual definition of TypedStreamChunk in types.ts (current
location around line 1065) or replace the fragile line-number anchor with a
file-level link to types.ts and a search-friendly fragment for TypedStreamChunk;
ensure the reference text "Defined in" continues to reference types.ts and that
the anchor resolves to the TypedStreamChunk definition.
In `@packages/typescript/ai/tests/type-check.test.ts`:
- Around line 6-17: The named imports in this file are not alphabetized; reorder
the identifiers alphabetically within each import statement—for example change
"describe, it, expectTypeOf" to "describe, expectTypeOf, it", "chat,
createChatOptions, toolDefinition" to "chat, createChatOptions, toolDefinition"
(ensure correct alphabetical order), and the type import list "JSONSchema,
StreamChunk, Tool, ToolCallArgsEvent, ToolCallStartEvent, ToolCallEndEvent,
TypedStreamChunk" should be reordered alphabetically (e.g., "JSONSchema,
StreamChunk, Tool, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent,
TypedStreamChunk") so each import's named members follow ESLint's sort-imports
rule.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 230ab7f9-f926-49b5-a973-0080ff8b4502
📒 Files selected for processing (5)
docs/chat/streaming.mddocs/reference/type-aliases/StreamChunk.mdexamples/ts-react-chat/src/routes/api.tanchat.tspackages/typescript/ai/src/types.tspackages/typescript/ai/tests/type-check.test.ts
✅ Files skipped from review due to trivial changes (1)
- docs/chat/streaming.md
c798ae0 to
f2aaac0
Compare
tombeckenham
left a comment
There was a problem hiding this comment.
The event types diverge from @ag-ui/core . If we can't keep those types, then this isn't worth it
Address PR #452 review: drop the Pick/AssertSatisfiesAGUI rewrite and restore extends AGUI*Event. Keep tool-aware TypedStreamChunk, thread TTools through chat(), fix mergeAgentTools with honest overloads, strip-to-spec without unknown casts, and populate input/output on ToolResult for typed engine END emissions (continuation path). Add toolCallName/output type tests.
Drop bulk gpt-4o→gpt-5.2 renames, unrelated Svelte callback fix, and other incidental file churn so #452 is scoped to TypedStreamChunk / chat() tool event typing and its docs/tests.
Rebased onto current main as a single clean commit (old history targeted packages/typescript/ai and could not replay). - TypedStreamChunk<TTools> with per-tool TOOL_CALL_START/END discrimination - Thread TTools through chat() / TextActivityResult / createChatOptions - Honest mergeAgentTools overloads; populate input/output on ToolResult - Docs + type-level tests
28f2157 to
083835d
Compare
- Pick-based ToolCallStart/End/CustomEvent (no Zod index signature leak)
- Remap StreamChunk via type-literal discriminant, not Exclude<{type}>
- Docs: self-contained snippets; use `'type' in chunk` for control-flow narrow
- Sandbox test narrows CUSTOM before reading value
expect-type v1.2+ deprecates toMatchTypeOf in favor of toExtend for assignability checks.
- Rename RemapStreamChunkForTools type param C → TChunk - Drop unnecessary as StreamChunk/CustomEvent/ToolCallEndEvent casts - Bedrock test: extract CUSTOM by string literal after Pick-based CustomEvent
tombeckenham
left a comment
There was a problem hiding this comment.
Made a few changes. It looks clean now. Ready to merge
Summary
ToolCallStartEventandToolCallEndEventgeneric with backward-compatible defaults (string/unknown)TypedStreamChunk<TTools>exported type that replaces untyped tool call events with typed versions based on the tools arrayTToolsgeneric throughTextActivityOptions,TextActivityResult,chat(), andcreateChatOptions()so the stream return type carries tool type informationIsAnyguard inToolInputsOfto preventanyleaking throughInferSchemaTypefor tools withoutinputSchemachat()inference without explicit type argsStreamChunk.mdreference, and cross-links from tools docsts-react-chatexampleTest plan
pnpm --filter @tanstack/ai test:lib)pnpm --filter @tanstack/ai build)pnpm --filter ts-react-chat build)string/unknown, empty arrays,as const, server/client tool variants,chat()inference, backward compat (assignability,StreamChunkunchanged)toBeUnknown()assertions used instead oftoEqualTypeOf<unknown>()to catchanyleaks🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
toolNamenarrowed to tool name literals andinputtyped to corresponding tool schemas.Bug Fixes
Documentation