Skip to content

feat(chat): accept TanStack AI streams in thread.post() - #934

Merged
bensabic merged 3 commits into
mainfrom
tanstack-streams
Sep 16, 2026
Merged

bensabic merged 3 commits into
mainfrom
tanstack-streams

Conversation

@bensabic

Copy link
Copy Markdown
Collaborator

thread.post() already streams AI SDK fullStream and textStream results. This adds the same treatment for TanStack AI, whose chat() returns an async iterable of AG-UI events.

import { chat } from "@tanstack/ai";
import { vercelGatewayText } from "@tanstack/ai-vercel-gateway";

bot.onNewMention(async (thread, message) => {
  const stream = chat({
    adapter: vercelGatewayText("anthropic/claude-opus-5"),
    messages: [{ role: "user", content: message.text }],
  });
  await thread.post(stream);
});

TEXT_MESSAGE_CONTENT deltas become text, and each TEXT_MESSAGE_END inserts a paragraph break between tool-loop turns, mirroring how finish-step is handled for the AI SDK. Tool call, reasoning, run, and step events are skipped. Detection is duck-typed on the event type, so nothing is imported from @tanstack/ai. The same path serves thread.reply() and channel.post().

Structured-output runs (chat({ outputSchema })) stream their JSON as text deltas, so they would post raw JSON. The docs call this out rather than special-casing it, matching how AI SDK structured output behaves today.

Changed files:

This is the bottom of a three-PR stack. The changeset here covers the whole stack, so the three should merge together.

TanStack AI's chat() returns an async iterable of AG-UI events rather than
AI SDK stream parts. thread.post(), thread.reply() and channel.post() now
recognize both: TEXT_MESSAGE_CONTENT deltas become text, and each
TEXT_MESSAGE_END inserts a paragraph break between tool-loop turns, the
same way finish-step does for the AI SDK's fullStream.

    import { chat } from "@tanstack/ai";

    bot.onNewMention(async (thread, message) => {
      const stream = chat({
        adapter,
        messages: [{ role: "user", content: message.text }],
      });
      await thread.post(stream);
    });

Detection is duck-typed on the event type, so nothing is imported from
@tanstack/ai.

Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com>
@bensabic
bensabic requested a review from a team September 15, 2026 07:05
@vercel

vercel Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
chat Ready Ready Preview, v0 Sep 15, 2026 11:31pm UTC
chat-sdk-nextjs-chat Ready Ready Preview, v0 Sep 15, 2026 11:31pm UTC

Comment thread .changeset/tanstack-ai.md
The docs content test checks every import in an MDX code block against a list of known packages. The new TanStack examples import @tanstack/ai and @tanstack/ai-vercel-gateway.

Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com>
TanStack only streams a structured-output run when stream: true is passed alongside outputSchema, so show the option in the note.

Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com>
@bensabic
bensabic merged commit dc2a777 into main Sep 16, 2026
19 checks passed
@bensabic
bensabic deleted the tanstack-streams branch September 16, 2026 00:12

This branch was successfully deployed

2 active deployments
Preview – chat — 0052856d Deployed Sep 15, 2026 by vercel[bot]
Preview – chat-sdk-nextjs-chat — 0052856d Deployed Sep 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants