Skip to content

docs: rewrite the docs so you can set up each feature in a few minutes - #1843

Merged
AlemTuzlak merged 7 commits into
t3/prepare-v1-releasefrom
docs/v1-rewrite
Oct 21, 2026
Merged

AlemTuzlak merged 7 commits into
t3/prepare-v1-releasefrom
docs/v1-rewrite

Conversation

@AlemTuzlak

Copy link
Copy Markdown
Contributor

Review this PR after #1840, because it targets that branch. It rewrites every hand-written docs page in plain, friendly English. Each page now opens with the problem and a setup you can copy and run in a few minutes. The deep details are in an Advanced part at the end, or on a new advanced page next to it.

🎯 Changes

Who each page is for. The plan has five readers: the first-timer, the feature builder, the provider picker, the production developer, and the upgrader. Each page has a path for its reader:

  1. Getting started and tutorials: Quick Start is 4 steps (install, server route, render, try it). Overview says what TanStack AI is and where to go next.
  2. Guides (tools, interrupts, structured outputs, persistence, media, MCP, memory, sandboxes, computer use): problem, quick setup, how it works, then Advanced.
  3. Adapters: every adapter page has the same order (install, key, first call, render, extras, models and options, Advanced), so you can compare providers.
  4. API pages: the 8 framework pages have the same headings and match the exports in src.
  5. Migration: migration/v1.md is a 5-step upgrade with a done check.

New pages. 23 *-advanced.md pages hold the deep details that moved off the entry pages. Each one is in docs/config.json, right after its parent page.

Facts corrected from the source code. The writers checked samples and claims against packages/*/src. The biggest corrections:

  • The Claude Code, Codex, and OpenCode pages described an old setup. All three run the CLI inside a sandbox (withSandbox), and many documented options did not exist.
  • The client tool and approval sample routes did not forward resume and parentRunId, so those flows did not resume.
  • The Grok, Groq, Mistral, and Bedrock pages said features were missing that the adapters have (Grok provider tools, Groq speech, Mistral embeddings, Bedrock reasoning).
  • The Solid, Vue, and Angular UI samples had bugs (an accessor read as an array, a count that was always 0, a component in the wrong slot).
  • store-reference.md listed 7 store keys. There are 8.

URLs did not change. Headings that other pages link to kept their text. docs/reference/ (TypeDoc output) is not touched.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.
  • Docs: I updated docs/ for this change, or this change is not user-facing.
  • Changeset: I added a changeset (pnpm changeset), or this PR does not change a published package.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Testing

Commands run (all pass):

  1. pnpm test:docs: no broken links in 877 markdown files.
  2. pnpm test:kiira: 1802 of 1802 code samples type-check (286 marked ignore, for example .vue, .svelte, and fences that need a generated route tree).
  3. A search of every changed page for the forbidden characters (em dash, en dash, ×, ·): no hits.

I did not run pnpm test:pr. This PR changes only files under docs/, so CI runs the rest.

Manual test:

  1. Open docs/getting-started/quick-start.md and follow the 4 steps in a new Next.js app. A streaming chat works.
  2. Open any guide, for example docs/tools/tools.md, and run its quick setup. One server tool runs in 3 steps.
  3. Open two adapter pages, for example docs/adapters/openai.md and docs/adapters/groq.md. The sections are in the same order.

How this PR makes testing easy: every code sample is type-checked by kiira in CI, so a sample that does not match the API fails the build.

Risk / rollback

Low risk. Only docs change. External links to a moved anchor (for example a deep link to an OpenAI provider tool) now land at the top of the page and not at that section. The section is on the new -advanced page. To undo, revert this PR.

Found while writing (not fixed here)

These are code issues, not docs. Each one needs its own PR:

  1. The sampling codemod writes max_tokens for Grok, but Grok needs max_output_tokens (codemods/move-sampling-to-model-options/transform.ts).
  2. Cloudflare sandbox previews: exposePreviewTool finds the container by threadId, but cloudflareSandbox names it with the hashed sandbox key.
  3. resolvePreviewHost throws on *.workers.dev when PREVIEW_HOSTNAME is not set.
  4. Memory: the shipped adapters recall only inside one thread. The docs make no claim about recall across threads until this is decided.
  5. In 1.0, a client tool resumes only when its server and browser definitions have the same outputSchema. The upgrade guide now says so.

…inutes

Rewrite every hand-written docs page in plain, friendly English. Each
page starts with the problem and a short setup that runs. The deep
details move to an Advanced part, or to a new advanced page next to it.

- Add 23 advanced pages and their nav entries.
- Correct facts that did not match the source code.
- Keep page URLs and the anchors that other pages link to.
@changeset-bot

changeset-bot Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 45679d6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: TanStack/ai/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4feeca4e-b41a-44e8-af5c-1c8a0b66a8df

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 45679d6

Command Status Duration Result
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 2s View ↗
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 13s View ↗

☁️ Nx Cloud last updated this comment at 2026-10-21 17:21:10 UTC

@pkg-pr-new

pkg-pr-new Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@1843

@tanstack/ai-acp

npm i https://pkg.pr.new/@tanstack/ai-acp@1843

@tanstack/ai-angular

npm i https://pkg.pr.new/@tanstack/ai-angular@1843

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@1843

@tanstack/ai-bedrock

npm i https://pkg.pr.new/@tanstack/ai-bedrock@1843

@tanstack/ai-byteplus

npm i https://pkg.pr.new/@tanstack/ai-byteplus@1843

@tanstack/ai-claude-code

npm i https://pkg.pr.new/@tanstack/ai-claude-code@1843

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@1843

@tanstack/ai-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-cloudflare@1843

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@1843

@tanstack/ai-code-mode-snippets

npm i https://pkg.pr.new/@tanstack/ai-code-mode-snippets@1843

@tanstack/ai-codex

npm i https://pkg.pr.new/@tanstack/ai-codex@1843

@tanstack/ai-cohere

npm i https://pkg.pr.new/@tanstack/ai-cohere@1843

@tanstack/ai-compaction

npm i https://pkg.pr.new/@tanstack/ai-compaction@1843

@tanstack/ai-computer-local

npm i https://pkg.pr.new/@tanstack/ai-computer-local@1843

@tanstack/ai-computer-playwright

npm i https://pkg.pr.new/@tanstack/ai-computer-playwright@1843

@tanstack/ai-computer-sandbox

npm i https://pkg.pr.new/@tanstack/ai-computer-sandbox@1843

@tanstack/ai-computer-use

npm i https://pkg.pr.new/@tanstack/ai-computer-use@1843

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@1843

@tanstack/ai-durable-stream

npm i https://pkg.pr.new/@tanstack/ai-durable-stream@1843

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@1843

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@1843

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@1843

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@1843

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@1843

@tanstack/ai-grok-build

npm i https://pkg.pr.new/@tanstack/ai-grok-build@1843

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@1843

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@1843

@tanstack/ai-isolate-daytona

npm i https://pkg.pr.new/@tanstack/ai-isolate-daytona@1843

@tanstack/ai-isolate-e2b

npm i https://pkg.pr.new/@tanstack/ai-isolate-e2b@1843

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@1843

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@1843

@tanstack/ai-isolate-quickjs-bun

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs-bun@1843

@tanstack/ai-llmgateway

npm i https://pkg.pr.new/@tanstack/ai-llmgateway@1843

@tanstack/ai-lovable

npm i https://pkg.pr.new/@tanstack/ai-lovable@1843

@tanstack/ai-mcp

npm i https://pkg.pr.new/@tanstack/ai-mcp@1843

@tanstack/ai-memory

npm i https://pkg.pr.new/@tanstack/ai-memory@1843

@tanstack/ai-mistral

npm i https://pkg.pr.new/@tanstack/ai-mistral@1843

@tanstack/ai-octane

npm i https://pkg.pr.new/@tanstack/ai-octane@1843

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@1843

@tanstack/ai-ollaya

npm i https://pkg.pr.new/@tanstack/ai-ollaya@1843

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@1843

@tanstack/ai-opencode

npm i https://pkg.pr.new/@tanstack/ai-opencode@1843

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@1843

@tanstack/ai-perplexity

npm i https://pkg.pr.new/@tanstack/ai-perplexity@1843

@tanstack/ai-persistence

npm i https://pkg.pr.new/@tanstack/ai-persistence@1843

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@1843

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@1843

@tanstack/ai-reactor

npm i https://pkg.pr.new/@tanstack/ai-reactor@1843

@tanstack/ai-remix

npm i https://pkg.pr.new/@tanstack/ai-remix@1843

@tanstack/ai-sandbox

npm i https://pkg.pr.new/@tanstack/ai-sandbox@1843

@tanstack/ai-sandbox-blaxel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-blaxel@1843

@tanstack/ai-sandbox-boxd

npm i https://pkg.pr.new/@tanstack/ai-sandbox-boxd@1843

@tanstack/ai-sandbox-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-sandbox-cloudflare@1843

@tanstack/ai-sandbox-daytona

npm i https://pkg.pr.new/@tanstack/ai-sandbox-daytona@1843

@tanstack/ai-sandbox-docker

npm i https://pkg.pr.new/@tanstack/ai-sandbox-docker@1843

@tanstack/ai-sandbox-e2b

npm i https://pkg.pr.new/@tanstack/ai-sandbox-e2b@1843

@tanstack/ai-sandbox-local-process

npm i https://pkg.pr.new/@tanstack/ai-sandbox-local-process@1843

@tanstack/ai-sandbox-railway

npm i https://pkg.pr.new/@tanstack/ai-sandbox-railway@1843

@tanstack/ai-sandbox-sprites

npm i https://pkg.pr.new/@tanstack/ai-sandbox-sprites@1843

@tanstack/ai-sandbox-upstash-box

npm i https://pkg.pr.new/@tanstack/ai-sandbox-upstash-box@1843

@tanstack/ai-sandbox-vercel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-vercel@1843

@tanstack/ai-skills

npm i https://pkg.pr.new/@tanstack/ai-skills@1843

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@1843

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@1843

@tanstack/ai-typesafe

npm i https://pkg.pr.new/@tanstack/ai-typesafe@1843

@tanstack/ai-utils

npm i https://pkg.pr.new/@tanstack/ai-utils@1843

@tanstack/ai-vercel-gateway

npm i https://pkg.pr.new/@tanstack/ai-vercel-gateway@1843

@tanstack/ai-vertex

npm i https://pkg.pr.new/@tanstack/ai-vertex@1843

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@1843

@tanstack/ai-worldlabs

npm i https://pkg.pr.new/@tanstack/ai-worldlabs@1843

@tanstack/openai-base

npm i https://pkg.pr.new/@tanstack/openai-base@1843

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@1843

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@1843

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@1843

@tanstack/svelte-ai-devtools

npm i https://pkg.pr.new/@tanstack/svelte-ai-devtools@1843

commit: 45679d6

@github-actions
github-actions Bot requested a review from jherr October 21, 2026 17:17
@github-actions github-actions Bot added the waiting-on: maintainer The ball is in the maintainers’ court label Oct 21, 2026
@AlemTuzlak
AlemTuzlak merged commit c92b51f into t3/prepare-v1-release Oct 21, 2026
14 checks passed
@AlemTuzlak
AlemTuzlak deleted the docs/v1-rewrite branch October 21, 2026 17:22
tombeckenham added a commit that referenced this pull request Oct 22, 2026
…0.0 (#1840)

* feat!: remove deprecated APIs for 1.0

Remove every deprecated export, option, field, and type alias from all
packages, and the internal code that only served them. Remove old wire
formats, readers for old saved data, shut-down provider models, and the
@tanstack/ai-react-ui, ai-solid-ui, and ai-vue-ui packages.

* docs: add the 1.0 upgrade guide and remove deprecated APIs from docs

* chore: add the 1.0.0 major changeset for all packages

* ci: apply automated fixes

* fix(ai): read the generation input from forwardedProps

The 1.0 client does not send the data copy of forwardedProps.
generationParamsFromBody still required body.data, so every
generation request to a route that used it failed. The envelope is
now found by forwardedProps, and the input comes from forwardedProps.

* fix(examples, testing): read request input from forwardedProps

Server routes in the examples, the e2e app, and the panel still read
body.data. The 1.0 client sends the input only in forwardedProps, so
these routes now read forwardedProps and no longer fall back to data.

* test(e2e): use the same client tool output schema on server and browser

The server definitions of show_notification and display_chart had no
outputSchema, but the browser tools had one. The schema hashes did not
match, so the client treated the pause as a generic interrupt and did
not resume after the tool ran. The removed pre-binding fallback hid
this before.

* fix(ai-vertex): use the same @google/genai copy as ai-gemini

The lockfile moved the ai-vertex dev copy of @google/genai to another
peer set. The vertex tests mock @google/genai, but ai-gemini loaded
the other copy, so the mock did not apply and the tests failed.

* docs(ai): remove container.skills from the Anthropic skill reference

1.0 removed modelOptions.container.skills, so the code block failed
the kiira type check. Skills go on codeExecutionTool instead.

* fix(testing): send the audio request input as the plain body

The /api/audio route reads its input from forwardedProps or from the
plain body. The audio page and the devtools generation hooks page still
wrapped the input in { data }, so the route got no provider and failed.

* chore: remove the last deprecated leftovers for 1.0

- Stop reading the 0.x interrupt reasons approval_required and
  client_tool_input in the stream processor. The kind comes from
  metadata.kind only. These reasons are no longer reserved for MCP input.
- Rewrite the tests that asserted the old reason aliases.
- Remove the deprecated pending alias from the useChat test titles.
- Reword comments, the codemods README, the adapter skill, and CLAUDE.md
  that still described removed or deprecated APIs.
- Move the testing panel chunk tables and sample traces to AG-UI events.
- Remove the unused deprecated setHandler from the group chat example.

* docs: regenerate the API reference for 1.0

This removes the pages and members of the deprecated APIs.

* chore: name the removed interrupt reasons in the changeset

* refactor!: remove the toolName alias from TOOL_CALL_START

TOOL_CALL_START now carries the tool name only in toolCallName, the
AG-UI field. The adapter extra toolName is also gone, so adapters no
longer send it on TOOL_CALL_START or TOOL_CALL_END. The stream
normalizer no longer copies toolName into toolCallName, and the client
no longer adds toolName back on inbound chunks.

* docs: regenerate the API reference without the toolName alias

* test(e2e): read toolCallName on TOOL_CALL_START in the webFetch spec

* docs: rewrite the docs so you can set up each feature in a few minutes (#1843)

* docs: rewrite the docs so a reader can set up each feature in a few minutes

Rewrite every hand-written docs page in plain, friendly English. Each
page starts with the problem and a short setup that runs. The deep
details move to an Advanced part, or to a new advanced page next to it.

- Add 23 advanced pages and their nav entries.
- Correct facts that did not match the source code.
- Keep page URLs and the anchors that other pages link to.

* docs: fix the code samples that failed the kiira type check

* docs: rewrite the computer use pages and use gpt-6.1-sol in the samples

* docs: show the interrupt flow in the tool approval diagram

* docs: read toolCallName on TOOL_CALL_START in the OpenAI samples

* refactor!: require threadId on chat and generation APIs

threadId is now required on every chat and generation entry point.
TanStack AI no longer makes a thread id for you.

- Client: ChatClient, useChat and the other chat hooks, the hook that
  createChatHook returns, GenerationClient, VideoGenerationClient, and
  every generation hook in each framework.
- Server: chat(), summarize(), getVideoJobStatus(), and the generation
  functions. TextOptions, SummarizationOptions, and ToolExecutionContext
  now carry a string threadId.
- Remove the fallbacks that made up thread ids in core, the clients, the
  framework hooks, and the provider adapters.
- createChatOptions() keeps threadId optional. chat() still needs it.
- Remove resolveDurableThreadId and DurableThreadIdRequiredError from
  @tanstack/ai-sandbox.
- Update tests, examples, testing apps, skills, READMEs, the migration
  guide, and the changeset.

* docs: regenerate the API reference for required threadId

* docs: pass threadId in every sample now that it is required

* test: pass threadId in the Mistral test and the code mode eval

* feat(ai-client)!: pass threadId to the generation fetcher

* refactor(ai)!: make threadId optional on subagent bound calls

* refactor!: stop making up thread ids

* refactor!: take the threadId in toJsonResponse for structured output

* revert: toJsonResponse does not need a threadId for structured output

A structured-output response wraps the object in its own run events.
Nothing resumes or saves that thread, so the caller does not pass a
threadId. Keep the removed fake-text fallback and the real thread ids
in the ts-react-chat server functions.

* fix!: apply threadId only where it is used

- getVideoJobStatus(): threadId is optional again. Only middleware reads it.
  Plain status polls in docs, READMEs, the skill, and apps drop it.
- createComputerUse: a call with no threadId uses the fixed
  'computer-use:shared' thread again.
- @tanstack/ai-sandbox: the tool bridge and executeHostTool() take a
  required threadId and put it in each tool context. The harness adapters
  and the Cloudflare coordinators pass the run's thread id.
- ChatClient passes its threadId to client tool execution.
- Code Mode bindings always get a context. The threadId comes from the
  parent context. A tool gets no context when there is no threadId.
- Compaction and snippet selection run their internal chat() calls on
  `${threadId}:compaction` and `${threadId}:snippets`.
- Connection adapters: the run context is a required fourth argument of
  connect() and send(). The runtime error stays for untyped callers.

* docs: regenerate the API reference for getVideoJobStatus

* fix(ai)!: ToolExecutionContext.threadId is optional outside a chat

registerWebMCPTools and the ai-mcp server run tools with no chat, so
there is no thread id. Every chat path still sets it: chat(), ChatClient
client tools, the sandbox bridges, and the Code Mode bindings.

- Code Mode bindings use ToolExecutionContext again. ToolBindingContext
  is gone, and a tool always gets the binding context.
- Docs say when threadId is missing.

* docs: regenerate the API reference for ToolExecutionContext.threadId

* docs: pass threadId in samples that kiira could not check

Samples that pass a value from a relative import (./tools) into chat() or
createChatClientOptions() were not type-checked in full: kiira hides the
unresolved-import error, and TypeScript then drops every other error in that
call. Add the missing threadId, drop the removed useChat id option, and fix
the ag-ui-compliance prose that said the runtime makes a thread id.

Also correct the kiira snippet lesson, which called the binding a usable any.

* fix: reject 0.x Cloudflare run records and wire byok in Octane useChat

- ai-sandbox-cloudflare: a rec: value in the 0.x layout (done/error
  status) now throws a clear "migrate first" error. Read as-is it looked
  like a live run, and the stall watchdog marked finished runs failed.
  list() skips such records with a log line, so one old record cannot
  stop the watchdog for live runs.
- ai-octane: useChat passes byok and byokProvider to ChatClient, like
  the other framework hooks. The option was typed but dropped.
- ai-mistral, ai-octane: published dependencies use workspace:^, so 1.0
  does not pin ai-utils and ai-client to an exact version.
- ai-solid: the README was a copy of the React one. Rewrite it for Solid
  and 1.0 (threadId, interrupts).

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: fix 1.0 samples and claims found in the full PR review

- Pass threadId in every sample and JSDoc @example that calls chat(),
  summarize(), a generate* function, a client, or a hook. Regenerate
  docs/reference.
- Server samples read the 1.0 request: generationParamsFromRequest and
  forwardedProps, not a top-level prompt or body.data. Custom transport
  samples forward runContext instead of making ids up.
- Fix samples that ran but did the wrong thing: Claude Code and Codex
  session resume, generation runId, the hardcoded video thread, the
  aborted status, shared 'thread-1' helpers in skills, the Svelte
  quick-start submit, apply-answers, the subagents tutorial.
- Correct claims the code does not support: sandbox policy, tool bridge
  host, sandbox key, harness tool checks, Gemini structured streaming,
  WebSocket resume, mcp-input reasons, openai-compatible features,
  OpenAI sampling params, the 0.x Cloudflare run-log migration, blobKey.
- Fix stale comments that named removed APIs.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: define persistence and sandbox inline so kiira checks the calls

The video persistence route and the harness structured-output skill
sample imported persistence and sandbox from relative modules. kiira
hides the unresolved import, and TypeScript then drops every other error
in the call that uses the value. Build both values in the same fence.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(ai-sandbox): refuse needsApproval tools in the harness tool bridge

The bridge called execute() directly, so a needsApproval tool ran with no
approval through every harness adapter. It cannot pause for an approval
round-trip, so fail fast with a clear error, as the docs already state.

Closes #1854

* test(ai-vertex): dedupe @google/genai so the factory mock applies

pnpm resolves two copies of @google/genai 2.10.0, one per zod peer
(4.3.6 for ai-gemini, 4.6.5 for ai-vertex). The vertex tests mock the
copy ai-vertex sees, but ai-gemini constructs GoogleGenAI from its own,
so the mock did not apply and factories.test.ts failed. f568fef fixed
this by hand-editing the lockfile, and the next pnpm install undid it.
resolve.dedupe in the test config loads one copy, whatever pnpm picks.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(ai-client)!: pass the AG-UI RunAgentInput to stream() and rpcStream()

The factory got only (messages, data, abortSignal), so a server function
could not read the client's runId or interrupt resume, and every caller
passed threadId a second time by hand. The run context was dropped on
purpose in #511, when ids were made up if missing; 1.0 requires them.

- The factory gets the run's AG-UI RunAgentInput as a 4th argument: the
  same body the HTTP adapters POST. A server reads it with
  chatParamsFromRequestBody() or generationParamsFromBody().
- RunAgentInput is re-exported as a type from @tanstack/ai/client.
- data and abortSignal are typed `| undefined` so input can be required.
  A factory that takes fewer parameters still type-checks.
- Docs, the custom-backend skill, and JSDoc send input instead of a
  hand-passed threadId.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: start each guide with the call, not a scene

* chore(skills): open docs pages with the call, said once

The docs skill told pages to open with the reader's problem as a short
scene. The docs now open with the call and what the reader gets, which
answers "is this my page?" in one line. Encode that, and add the rule
the rewrite missed on some pages: the opener is said once, so the next
paragraph starts the steps or adds a new fact.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: say each page opener once

The call-first openers landed above the old intro paragraphs, so 42
pages repeated the opener, kept a "X fixes this." line whose problem
was cut, or kept a broken "createChatHook from ..." fragment (all eight
UI framework pages). Remove the repeats and orphaned lines, keep each
new fact as one sentence, and fix the fragments. Openers are unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix!: fail loudly on a missing threadId and on 0.x saved data

- chat(), ChatClient, GenerationClient and VideoGenerationClient throw a
  clear error when threadId is missing or empty. The type already
  required it; a JS caller got persistence keyed "undefined" and runs
  with no thread. Drops two guards that could no longer fire.
- A 0.x bare UIMessage[] in client persistence logs an error and is not
  overwritten by the next save, so the history is not lost.
- retrieveBlob throws a clear error for a 0.x artifact record with no
  blobKey, instead of a misleading not-found.
- A 0.x unbound tool interrupt record logs a warning that it stays
  pending.
- A client tool or approval interrupt whose server and client schemas
  differ logs a warning naming the tool before it falls back to a
  generic interrupt.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(ai)!: require threadId and runId in generation params

GenerationParams typed threadId and runId as optional and the parser
also took a bare input body, a 0.x shape with no ids. 1.0 generation
functions need a threadId, so every route repeated an
`if (!threadId) return 400` check. AG-UI RunAgentInput requires both
ids, and chatParamsFromRequestBody already does.

- generationParamsFromBody reads only the envelope and throws when
  threadId or runId is missing or empty. Drops the bare-input branches
  and three helpers.
- Remove the per-route threadId checks and optional runId spreads from
  docs, the media-generation skill, and the examples.

Co-Authored-By: Claude <noreply@anthropic.com>

* test: pass threadId where chat() and the clients now require it

69a3bbe made chat(), ChatClient, GenerationClient and
VideoGenerationClient throw at runtime on a missing threadId. Tests that
called them without one now failed, and tests that checked the
"connection or fetcher" error hit the threadId error first. Pass a
threadId so each test reaches the case it is about.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove dead fallbacks and copies left by required threadId

- ai-client devtools: the bridge threadId is required, so drop
  withLiveClientIdentity, the `?? ''` fallbacks, the always-true branch,
  and the `const client = this` getters in the three clients.
- ai-client: drop the restoreInboundUsage alias and a `?? {}` on a spread.
- Framework generation hooks: drop the `Omit<..., 'persistence' |
  'threadId'> & GenerationPersistenceOptions` that re-added what it
  removed (43 signatures), and the persistenceProps temporary in 8 files.
- ai-react: delete tool-result-content.ts; its only caller was deleted.
- ai: one WithOptionalThreadId type, reused by BoundTextActivityOptions,
  bound calls, and createChatOptions, which reuses BoundTextActivityOptions
  instead of a copy. Drop the 0.x nested RUN_ERROR copy in
  normalizeStreamChunk.
- ai-persistence: artifactBlobKey is a local function in middleware.ts;
  simplify the resume guard.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(e2e): type-check the specs and fix what that found

testing/e2e/tsconfig.json only included src/, so tsc never saw tests/.
Include it and fix the 20 errors with narrowing and real types, no casts:

- multi-turn-reasoning never ran: a stale-branch squash merge (98979f7)
  dropped the feature from the E2E registry, so the spec matched no
  providers. Restore it for Anthropic.
- delivery-durability: "a second tab joins an existing run" parsed the
  producing tab's output but never compared it. Assert both tabs match.
- web-mcp-tools: the local registration type required `options`, which
  Chrome does not pass. Make it optional.
- getMessages() returns UIMessage[] instead of any[]; narrow the reads
  that exposed. Type guards for tool-call events, typed fixtures.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(ai-client): match the WebMCP execute type to what Chrome and the code pass

Chrome calls a registered WebMCP tool's execute(input) with no options,
and the function TanStack AI registers already takes optional options.
The internal WebMCPTool interface required them.

Co-Authored-By: Claude <noreply@anthropic.com>

* test: type-check the Octane tests, remix example tests, and e2e setup

- ai-octane: include tests/ in the type check. Type the chat-ui test
  callbacks with the real ai-client UI types, add a declaration for the
  SSR fixture, and resolve @octanejs/testing-library subpaths through a
  tsconfig paths entry that mirrors the vite alias. Fix two test bugs:
  "preserves unrelated caller metadata" passed a field the hook does not
  accept, and a TEXT_MESSAGE_CONTENT event carried a `content` field.
- ts-remix-chat: type-check its tests; build the test router with the
  render middleware the app's RouterTypes expects.
- e2e: type-check the Playwright config and global setup/teardown. Drop
  a `duration` field aimock never reads, and type the aimock global
  instead of casting globalThis.
- ts-solid-chat: delete three files nothing imported.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: upgrade oxlint to 1.89 and oxlint-tsgolint to 7.0.2004

The repo was on oxlint-tsgolint 0.24, the pre-TypeScript-7 line, and
`^0.24.0` can never reach 7.x. oxlint 1.89 requires
oxlint-tsgolint >= 7.0.2003. Bump oxlint, oxlint-plugin-eslint and
oxlint-tsgolint together.

The only new finding across all 76 linted projects: a zero-width space
in an ai-skills doc comment, used to break up `**/`. Write the path as
`skills/<name>/SKILL.md` instead.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(ai-octane): make the published ui types match the .tsrx source

The hand-written create-ui and create-chat-hook .tsrx.d.ts files had
drifted to ComponentBody<any> and loose prop shapes. Replace them with
the real declaration emit, export the part and interrupt mixin types,
drop the hand-copied test aliases, and add a typetest that fails if the
declarations loosen again. The docs sample now uses ToolProps directly.

* chore(skills): docs skill states readers and tone instead of asking

* docs: merge the Vercel AI SDK comparison into one page

* docs: drop the agent class and RSC reasons from the AI SDK comparison

* docs: point missing providers to a request or the adapter guide

* docs: put TanStack AI first in the AI SDK API map

* Revert "docs: put TanStack AI first in the AI SDK API map"

This reverts commit 82aad9d.

* docs: put the Vercel AI SDK first in the comparison table

* ci: apply automated fixes

* test(ai): pass threadId in the activity middleware test from main

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on: maintainer The ball is in the maintainers’ court

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants