Skip to content

docs(ai-chat): guide for migrating an AI SDK route handler to chat.agent - #4519

Merged
matt-aitken merged 3 commits into
mainfrom
docs/migrate-from-route-handler
Aug 6, 2026
Merged

docs(ai-chat): guide for migrating an AI SDK route handler to chat.agent#4519
matt-aitken merged 3 commits into
mainfrom
docs/migrate-from-route-handler

Conversation

@matt-aitken

@matt-aitken matt-aitken commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

Adds a docs page for developers who already have a working Vercel AI SDK chat app (useChat on the client, an app/api/chat/route.ts calling streamText) and want to move it to chat.agent. There was no page covering that path. ai-chat/upgrade-guide reads like it should be the one, but it covers moving prerelease chat.agent code to the Sessions release, which is a different reader.

The page is structured around what stays, what goes, and what is new, because the reassuring part of this migration is how much is untouched: the streamText call, model config, tool definitions, useChat, and all message rendering carry over as-is. What gets deleted is the route handler, the persistence glue wired into it, and any resumable-stream setup. What is new is the agent task, two server actions, and useTriggerChatTransport.

Covers moving tools onto the agent config so toModelOutput survives past turn one, where existing database persistence goes (hydrateMessages plus the turn hooks), a short section on what durability you get once you are across, a note that Hono/SvelteKit/Express follow the same shape, and a gotchas list built from the mistakes this specific migration produces.

Head Start

The one thing this migration makes worse is the opening response of a new chat. The route handler answered out of a warm process; the agent run has to be dequeued and booted first. That is the complaint the page has to answer head on, so Head Start gets a full section rather than a closing aside, plus a callout up top next to the "what changes" table so nobody plans the migration without knowing it exists.

The section walks the four steps: splitting tool schemas away from tool executes (the bundle-isolation constraint the whole feature rests on), building the handler, mounting it back at app/api/chat/route.ts with the original auth check wrapped around it, and the transport option. Both server actions stay, because Head Start only owns the first turn. Three gotchas go with it: a slow first turn without Head Start, Head Start on but the route bundle still heavy, and the route timing out because the handler holds the SSE response open for the whole turn rather than just step 1.

The coding-agent prompt names Head Start as explicitly out of scope, so an agent handed the migration does not attempt the tool split unprompted.

Also fixes the chat.headStart example on ai-chat/fast-starts, which set stopWhen: stepCountIs(15) after the spread. toStreamTextOptions() pins stopWhen to stepCountIs(1), so overriding it makes the warm handler run steps the agent is supposed to own (and stepCountIs was never imported in that snippet either).

Migration prompt

The page also ships a copy-pasteable prompt for handing the migration to a coding agent. It tells the agent to run npx trigger.dev@latest skills first, so it picks up guidance version-pinned to the SDK actually installed in the project, then read quick-start.md, frontend.md, and reference.md (with llms.txt as the index) before editing anything. The instructions are explicit about preserving the existing model, prompt, and tool schemas rather than rewriting them.

Registered in docs.json under Agents, directly after Quick Start, so it is picked up by the generated llms.txt and the per-page .md variants.

Developers arriving with a working Vercel AI SDK chat app had no page telling
them which parts of it survive the move to chat.agent and which parts get
deleted. This walks through it with before/after code: the streamText call,
model config, tools, and useChat stay; the route handler, its persistence glue,
and any resumable-stream setup go; the agent task, two server actions, and
useTriggerChatTransport are new.

Also includes a copy-pasteable prompt that points a coding agent at the live
docs and the version-pinned SDK skills, so the migration can be handed off.
@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: bd2b611

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 Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 616929cf-c7d4-481b-9947-99337b1761b0

📥 Commits

Reviewing files that changed from the base of the PR and between e797790 and bd2b611.

📒 Files selected for processing (1)
  • docs/ai-chat/migrating-from-a-route-handler.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/ai-chat/migrating-from-a-route-handler.mdx

Walkthrough

Adds a migration guide for converting an AI chat from a streamText route handler to a Trigger.dev chat.agent task. The guide covers tools, server actions, client transport, persistence hooks, cursor-based resume, Head Start configuration, framework integrations, verification, and troubleshooting. It also adds the guide to the Agents documentation navigation and updates the Head Start example to use the SDK-provided step limit.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main documentation change: migrating an AI SDK route handler to chat.agent.
Description check ✅ Passed The description provides detailed scope and objectives, but it omits the template’s issue, checklist, testing, changelog, and screenshots sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/migrate-from-route-handler

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.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

coderabbitai[bot]

This comment was marked as resolved.

@matt-aitken
matt-aitken force-pushed the docs/migrate-from-route-handler branch from 6d4e177 to 00e9049 Compare August 6, 2026 13:46
@matt-aitken

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

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.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
docs/ai-chat/migrating-from-a-route-handler.mdx (1)

248-306: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Align the bullet label with the code.

The code sets resume: initialMessages.length > 0. The bullet at Line 302 is labeled **resume: true**. The explanation that follows is correct, but the label does not match the snippet. Use the conditional form so a reader does not copy resume: true.

📝 Proposed wording fix
-- **`resume: true`** reconnects to an in-flight stream on mount. Only enable it when there are existing messages — a brand-new chat has nothing to reconnect to.
+- **`resume`** reconnects to an in-flight stream on mount. Enable it only when there are existing messages, as in the snippet above — a brand-new chat has nothing to reconnect to.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 273ea120-5658-4623-9bd9-2029d9ecc8a4

📥 Commits

Reviewing files that changed from the base of the PR and between 337dda1 and 00e9049.

📒 Files selected for processing (3)
  • docs/ai-chat/fast-starts.mdx
  • docs/ai-chat/migrating-from-a-route-handler.mdx
  • docs/docs.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/docs.json
  • docs/ai-chat/fast-starts.mdx
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: code-quality / code-quality
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.mdx

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/**/*.mdx: MDX documentation pages must include frontmatter with title (required), description (required), and sidebarTitle (optional) in YAML format
Use Mintlify components for structured content: , , , , , , /, /
Always import from @trigger.dev/sdk in code examples (never from @trigger.dev/sdk/v3)
Code examples must be complete and runnable where possible
Use language tags in code fences: typescript, bash, json

Documentation in docs/ uses MDX conventions defined by the documentation guidance.

Files:

  • docs/ai-chat/migrating-from-a-route-handler.mdx
🧠 Learnings (4)
📚 Learning: 2026-03-10T12:44:14.176Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 3200
File: docs/config/config-file.mdx:353-368
Timestamp: 2026-03-10T12:44:14.176Z
Learning: In the trigger.dev repo, docs PRs are often companions to implementation PRs. When reviewing docs PRs (MDX files under docs/), check the PR description for any companion/related PR references and verify that the documented features exist in those companion PRs before flagging missing implementations. This ensures docs stay in sync with code changes across related PRs.

Applied to files:

  • docs/ai-chat/migrating-from-a-route-handler.mdx
📚 Learning: 2026-04-30T20:30:29.458Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3226
File: docs/ai-chat/quick-start.mdx:13-13
Timestamp: 2026-04-30T20:30:29.458Z
Learning: In this repo’s documentation MDX files (`docs/**/*.mdx`), use `ts` and `tsx` (not `typescript`) as the code-fence language tags for TypeScript/TSX snippets. Do not flag `ts`/`tsx` code-fence language tags as incorrect in any docs MDX file, since this is the site-wide Mintlify-compatible convention.

Applied to files:

  • docs/ai-chat/migrating-from-a-route-handler.mdx
📚 Learning: 2026-06-16T13:14:09.440Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3964
File: docs/ai-chat/reference.mdx:482-482
Timestamp: 2026-06-16T13:14:09.440Z
Learning: When documenting or reviewing usage of `ChatTurn.complete(source?)` (in `packages/trigger-sdk/src/v3/ai.ts`), note that `source` is optional (`source?: UIMessageStreamable`). Calling `complete()` with no `source` is valid specifically for a final head-start handover (`handover.isFinal`), because the warm partial already contains the response. If examples or guidance omit `source`, ensure they are in this final-hand-over context so they remain correct.

Applied to files:

  • docs/ai-chat/migrating-from-a-route-handler.mdx
📚 Learning: 2026-06-16T13:14:14.382Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3964
File: docs/ai-chat/reference.mdx:478-478
Timestamp: 2026-06-16T13:14:14.382Z
Learning: When reviewing RC-gated `ai-chat` docs under `docs/ai-chat/`, don’t immediately flag missing SDK type fields or implementation details just because the field isn’t present on the docs branch yet. Instead, find and cross-check the companion implementation PR that’s intended to land alongside the docs PR, and only report missing/incorrect fields if they are also absent in the companion SDK/type changes.

Applied to files:

  • docs/ai-chat/migrating-from-a-route-handler.mdx
🪛 LanguageTool
docs/ai-chat/migrating-from-a-route-handler.mdx

[style] ~7-~7: Consider using “the surrounding plumbing”.
Context: ... migration unchanged. What goes away is the plumbing around them: the route handler, the persistence glu...

(NOUN_AROUND_IT)

🔇 Additional comments (4)
docs/ai-chat/migrating-from-a-route-handler.mdx (4)

1-9: LGTM!

Also applies to: 11-29, 35-98, 102-176, 200-246, 363-405, 523-578


178-194: LGTM!


407-521: 📐 Maintainability & Code Quality

Cross-page anchors are present.


314-361: 🗄️ Data Integrity & Integration

No change needed. The documented upsertIncomingMessage export and the referenced hydrateMessages / onTurnComplete payload fields are present in the SDK surface.

The migration trades a warm route handler for an agent run that has to boot,
so the opening response of a new chat gets slower and that is the first thing
a reader will notice. Head Start was only a closing aside. It is now a full
section: splitting tool schemas from executes, building and mounting the
handler with the original auth check intact, the transport option, and the
function-timeout and bundle-isolation gotchas.

Also drops a stopWhen override from the fast starts handler example. The
spread pins stopWhen to stepCountIs(1), and re-setting it makes the warm
handler run steps the agent is supposed to own.
@matt-aitken
matt-aitken force-pushed the docs/migrate-from-route-handler branch from 00e9049 to e797790 Compare August 6, 2026 13:51
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

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.

coderabbitai[bot]

This comment was marked as resolved.

The server action examples checked only that a session existed. Since chatId
comes from the browser, any signed-in user copying them could mint a token
scoped read/write to someone else's chat session. Both actions now bind the
two, and the head-start route handler gets the same check.
@matt-aitken

Copy link
Copy Markdown
Member Author

@coderabbitai the ownership fix landed in bd2b611, which was pushed after your verification ran. Please review the latest commit.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Commit metadata =='
git show --no-ext-diff --format=fuller --stat bd2b611f0

echo
echo '== Commit diff =='
git diff --no-ext-diff --find-renames bd2b611f0^ bd2b611f0 --

echo
echo '== Documentation structure =='
ast-grep outline docs/ai-chat/migrating-from-a-route-handler.mdx --items all 2>/dev/null || true
ast-grep outline docs/ai-chat/fast-starts.mdx --items all 2>/dev/null || true

echo
echo '== Authorization-related documentation context =='
rg -n -i -C 12 \
  'chatId|chat\.authorize|authorize|authenticate|userId|session|warm|head.?start|create.*token' \
  docs/ai-chat/migrating-from-a-route-handler.mdx docs/ai-chat/fast-starts.mdx

Length of output: 111732


@mat-aitken Reviewed bd2b611f0.

No findings.

The server action examples now bind chatId to the authenticated user before session creation or token minting. The Head Start example applies the same check and preserves the request body for chatHandler. The warning also documents the authorization requirement clearly.

You are interacting with an AI system.

@matt-aitken
matt-aitken enabled auto-merge (squash) August 6, 2026 15:36
@matt-aitken
matt-aitken merged commit f8e1c91 into main Aug 6, 2026
23 checks passed
@matt-aitken
matt-aitken deleted the docs/migrate-from-route-handler branch August 6, 2026 15:37
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