Skip to content

docs: ai chat.task#3226

Draft
ericallam wants to merge 45 commits intomainfrom
docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system
Draft

docs: ai chat.task#3226
ericallam wants to merge 45 commits intomainfrom
docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system

Conversation

@ericallam
Copy link
Copy Markdown
Member

No description provided.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 16, 2026

⚠️ No Changeset found

Latest commit: 0813087

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
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 16, 2026

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

Walkthrough

Adds a new AI Chat documentation suite under docs/ai-chat: overview, quick-start, backend, frontend, features, compaction, pending-messages, and reference, plus a new docs/ai/prompts.mdx. Documents three backend approaches (chat.task, chat.createSession, raw primitives), lifecycle hooks, streaming/pipe behavior, stop/cancel signals, compaction, pending messages, prompt templates, frontend transport integration, persistence examples, and runtime APIs. Updates docs navigation to add an “AI” dropdown with a Chat subgroup and adds a redirect from /guides/ai-chat → /ai-chat/overview. All changes are documentation-only; no SDK source or exported/public APIs were modified.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided, leaving the template sections (Closes, Checklist, Testing, Changelog, Screenshots) entirely unfilled. Add a pull request description following the provided template, including which issue is closed, testing steps, and a changelog summary of the new documentation pages added.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'docs: ai chat.task' is partially related to the changeset, referring to chat.task documentation but not capturing the comprehensive scope of nine new documentation pages covering overview, quick-start, backend, frontend, features, reference, compaction, pending-messages, and prompts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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/ai-chat/backend.mdx`:
- Around line 391-415: The example server actions currently trust raw chatId and
return all rows; update getChatMessages, getAllSessions, and deleteSession to
scope results to the authenticated user by using the caller's user id (from the
auth/session context) and filtering DB queries (replace db.chat.findUnique,
db.chatSession.findMany, db.chatSession.delete usages) with where: { id: chatId,
userId } or where: { userId } respectively; for deleteSession verify ownership
before deleting (return error or no-op if not owner), and for getAllSessions
only return sessions belonging to that user and avoid leaking other users'
publicAccessToken (either omit or mask tokens unless the requester owns them).
Ensure these functions take or derive the current user id and perform explicit
auth checks before DB operations.

In `@docs/ai-chat/features.mdx`:
- Around line 25-29: The example initializes userContext via chat.local with
fields name, plan, and messageCount but later reads userContext.get().userId,
causing a type mismatch; update the chat.local declaration (userContext) to
include userId in the type and initial value so the persisted object actually
contains userId, and mirror the same fix for the other occurrences referenced
(lines 39-43 and 125-134) where userId is later read so all examples are
consistent and will typecheck.

In `@docs/ai-chat/frontend.mdx`:
- Around line 71-126: The component is written as a page but expects a custom
prop chatId; update it to read route params or move logic into a client
component: either (A) change the page to export default async function Page({
params }) { const chatId = params.chatId; return <ChatClientWrapper
chatId={chatId} /> } where ChatClientWrapper is a client component that uses the
existing ChatPage/ChatClient logic, or (B) move ChatClient (and the
useEffect/load logic) into a new client component (e.g., ChatClient.tsx) and
have app/chat/[chatId]/page.tsx import that component and pass params.chatId to
it; adjust references to getChatMessages, getSession, getChatToken and
deleteSession to be called only inside client-side components (use client
directive) and ensure useTriggerChatTransport and useChat remain inside the
client component.

In `@docs/ai-chat/quick-start.mdx`:
- Line 13: The code fence language tags in docs/ai-chat/quick-start.mdx use
`ts`/`tsx` (e.g. the snippet starting with "```ts trigger/chat.ts") but our docs
convention requires full `typescript` tags; update each fenced code block
(including the ones referenced at lines 36 and 50) to use `typescript` instead
of `ts` or `tsx` so the snippets follow the project's language-tagging
guideline.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c811e887-30ff-4b0a-8fc1-304149a04299

📥 Commits

Reviewing files that changed from the base of the PR and between 7672e8d and 00c199b.

⛔ Files ignored due to path filters (1)
  • references/ai-chat/ARCHITECTURE.md is excluded by !references/**
📒 Files selected for processing (7)
  • docs/ai-chat/backend.mdx
  • docs/ai-chat/features.mdx
  • docs/ai-chat/frontend.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/reference.mdx
  • docs/docs.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: typecheck / typecheck
🧰 Additional context used
📓 Path-based instructions (4)
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

Files:

  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/backend.mdx
  • docs/ai-chat/reference.mdx
  • docs/ai-chat/features.mdx
  • docs/ai-chat/frontend.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

Documentation in docs/ directory uses Mintlify MDX format - follow docs/CLAUDE.md for conventions

Files:

  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/backend.mdx
  • docs/ai-chat/reference.mdx
  • docs/ai-chat/features.mdx
  • docs/ai-chat/frontend.mdx
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier before committing

Files:

  • docs/docs.json
docs/**/docs.json

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/**/docs.json: Main documentation config must be defined in docs.json which includes navigation structure, theme, and metadata
Navigation structure in docs.json should be organized using navigation.dropdowns with groups and pages

Files:

  • docs/docs.json
🧠 Learnings (12)
📓 Common learnings
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 3200
File: docs/config/config-file.mdx:353-368
Timestamp: 2026-03-10T12:44:19.869Z
Learning: In the triggerdotdev/trigger.dev repository, docs PRs are often written as companions to implementation PRs (e.g., PR `#3200` documents features being added in PR `#3196`). When reviewing docs PRs, the documented features may exist in a companion/companion PR branch rather than main. Always check companion PRs referenced in the PR description before flagging missing implementations.
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/cli-v3/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:34.140Z
Learning: Keep SDK documentation in `rules/` and `.claude/skills/trigger-dev-tasks/` synchronized when features are added or changed
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/trigger-sdk/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:48.124Z
Learning: Docs updates should typically be done in a separate PR from SDK feature implementation
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: New documentation pages must be added to the navigation structure in `docs.json` under the correct group after creating the MDX file
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: Applies to docs/**/*.mdx : Always import from `trigger.dev/sdk` in code examples (never from `trigger.dev/sdk/v3`)
📚 Learning: 2026-03-02T12:43:34.140Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/cli-v3/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:34.140Z
Learning: Keep SDK documentation in `rules/` and `.claude/skills/trigger-dev-tasks/` synchronized when features are added or changed

Applied to files:

  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/reference.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks

Applied to files:

  • docs/ai-chat/quick-start.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/reference.mdx
📚 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/quick-start.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/backend.mdx
  • docs/ai-chat/reference.mdx
  • docs/ai-chat/features.mdx
  • docs/ai-chat/frontend.mdx
📚 Learning: 2026-03-02T12:43:02.539Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: Applies to docs/**/docs.json : Navigation structure in `docs.json` should be organized using `navigation.dropdowns` with groups and pages

Applied to files:

  • docs/docs.json
📚 Learning: 2026-03-02T12:43:02.539Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: New documentation pages must be added to the navigation structure in `docs.json` under the correct group after creating the MDX file

Applied to files:

  • docs/docs.json
📚 Learning: 2026-03-02T12:43:02.539Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: Applies to docs/**/docs.json : Main documentation config must be defined in `docs.json` which includes navigation structure, theme, and metadata

Applied to files:

  • docs/docs.json
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `.withStreams()` to subscribe to realtime streams from task metadata in addition to run changes

Applied to files:

  • docs/ai-chat/reference.mdx
📚 Learning: 2026-03-06T14:44:55.489Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3173
File: packages/trigger-sdk/src/v3/chat.test.ts:103-104
Timestamp: 2026-03-06T14:44:55.489Z
Learning: In `packages/trigger-sdk/src/v3/chat.test.ts`, mocking `global.fetch` with `vi.fn()` is acceptable and intentional. `TriggerChatTransport` is a browser-facing SSE/HTTP client, and using testcontainers for these tests is not required. This file is an explicit exception to the repo's general no-mocks policy.

Applied to files:

  • docs/ai-chat/reference.mdx
  • docs/ai-chat/frontend.mdx
📚 Learning: 2026-02-25T17:28:20.456Z
Learnt from: isshaddad
Repo: triggerdotdev/trigger.dev PR: 3130
File: docs/v3-openapi.yaml:3134-3135
Timestamp: 2026-02-25T17:28:20.456Z
Learning: In the Trigger.dev codebase, the `publicAccessToken` returned by the SDK's `wait.createToken()` method is not part of the HTTP response body from `POST /api/v1/waitpoints/tokens`. The server returns only `{ id, isCached, url }`. The SDK's `prepareData` hook generates the JWT client-side from the `x-trigger-jwt-claims` response header after the HTTP call completes. The OpenAPI spec correctly documents only the HTTP response body, not SDK transformations.
<!-- [/add_learning]

Applied to files:

  • docs/ai-chat/reference.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Use `TriggerAuthContext` provider to supply Public Access Token to Trigger.dev React hooks

Applied to files:

  • docs/ai-chat/frontend.mdx
🪛 LanguageTool
docs/ai-chat/features.mdx

[style] ~172-~172: To form a complete sentence, be sure to include a subject.
Context: ...signal }); }, }); ``` chat.defer() can be called from anywhere during a turn —...

(MISSING_IT_THERE)

🔇 Additional comments (1)
docs/docs.json (1)

83-93: Nice nav + redirect wiring.

Adding the new group under navigation.dropdowns and redirecting the old guide entry point to the overview should make the AI Chat docs discoverable without breaking existing links.

Based on learnings, "New documentation pages must be added to the navigation structure in docs.json under the correct group after creating the MDX file".

Also applies to: 744-746

Comment thread docs/ai-chat/backend.mdx
Comment on lines +391 to +415
export async function getChatMessages(chatId: string) {
const found = await db.chat.findUnique({ where: { id: chatId } });
return found?.messages ?? [];
}

export async function getAllSessions() {
const sessions = await db.chatSession.findMany();
const result: Record<string, {
runId: string;
publicAccessToken: string;
lastEventId?: string;
}> = {};
for (const s of sessions) {
result[s.id] = {
runId: s.runId,
publicAccessToken: s.publicAccessToken,
lastEventId: s.lastEventId ?? undefined,
};
}
return result;
}

export async function deleteSession(chatId: string) {
await db.chatSession.delete({ where: { id: chatId } }).catch(() => {});
}
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.

⚠️ Potential issue | 🟠 Major

Scope these example server actions to the authenticated user.

getChatMessages, getAllSessions, and deleteSession trust raw chatIds or return all rows. In a multi-user app, copying this verbatim would let one client read or remove another user's chat state, and getAllSessions() would expose other users' publicAccessTokens.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ai-chat/backend.mdx` around lines 391 - 415, The example server actions
currently trust raw chatId and return all rows; update getChatMessages,
getAllSessions, and deleteSession to scope results to the authenticated user by
using the caller's user id (from the auth/session context) and filtering DB
queries (replace db.chat.findUnique, db.chatSession.findMany,
db.chatSession.delete usages) with where: { id: chatId, userId } or where: {
userId } respectively; for deleteSession verify ownership before deleting
(return error or no-op if not owner), and for getAllSessions only return
sessions belonging to that user and avoid leaking other users' publicAccessToken
(either omit or mask tokens unless the requester owns them). Ensure these
functions take or derive the current user id and perform explicit auth checks
before DB operations.

Comment thread docs/ai-chat/features.mdx
Comment on lines +25 to +29
const userContext = chat.local<{
name: string;
plan: "free" | "pro";
messageCount: number;
}>({ id: "userContext" });
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.

⚠️ Potential issue | 🟠 Major

Persist userId if the later example reads it back.

This local is initialized with name, plan, and messageCount, but the persistence example later calls userContext.get().userId. As written, the snippet won't typecheck and suggests data is available that was never stored.

🛠️ Suggested fix
 const userContext = chat.local<{
+  userId: string;
   name: string;
   plan: "free" | "pro";
   messageCount: number;
 }>({ id: "userContext" });
@@
     userContext.init({
+      userId: clientData.userId,
       name: user.name,
       plan: user.plan,
       messageCount: user.messageCount,
     });

As per coding guidelines, "Code examples must be complete and runnable where possible".

Also applies to: 39-43, 125-134

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ai-chat/features.mdx` around lines 25 - 29, The example initializes
userContext via chat.local with fields name, plan, and messageCount but later
reads userContext.get().userId, causing a type mismatch; update the chat.local
declaration (userContext) to include userId in the type and initial value so the
persisted object actually contains userId, and mirror the same fix for the other
occurrences referenced (lines 39-43 and 125-134) where userId is later read so
all examples are consistent and will typecheck.

Comment thread docs/ai-chat/frontend.mdx
Comment on lines +71 to +126
```tsx app/page.tsx
"use client";

import { useEffect, useState } from "react";
import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
import { useChat } from "@ai-sdk/react";
import { getChatToken, getChatMessages, getSession, deleteSession } from "@/app/actions";

export default function ChatPage({ chatId }: { chatId: string }) {
const [initialMessages, setInitialMessages] = useState([]);
const [initialSession, setInitialSession] = useState(undefined);
const [loaded, setLoaded] = useState(false);

useEffect(() => {
async function load() {
const [messages, session] = await Promise.all([
getChatMessages(chatId),
getSession(chatId),
]);
setInitialMessages(messages);
setInitialSession(session ? { [chatId]: session } : undefined);
setLoaded(true);
}
load();
}, [chatId]);

if (!loaded) return null;

return (
<ChatClient
chatId={chatId}
initialMessages={initialMessages}
initialSessions={initialSession}
/>
);
}

function ChatClient({ chatId, initialMessages, initialSessions }) {
const transport = useTriggerChatTransport({
task: "my-chat",
accessToken: getChatToken,
sessions: initialSessions,
onSessionChange: (id, session) => {
if (!session) deleteSession(id);
},
});

const { messages, sendMessage, stop, status } = useChat({
id: chatId,
messages: initialMessages,
transport,
resume: initialMessages.length > 0, // Resume if there's an existing conversation
});

// ... render UI
}
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In Next.js App Router, what props does a default export in app/page.tsxreceive, and how should a page component access a dynamicchatId?

💡 Result:

In the App Router, the default export in app/page.tsx (a Page component) does not receive arbitrary “props” like pageProps. It only receives route-derived props:

  • searchParams (query string params) — and in Next.js 15, it’s passed as a Promise. [1], [2]
  • params (dynamic route segments) — only if the route has dynamic segments; in Next.js 15, it’s also a Promise. [1], [3]

To access a dynamic chatId, make the route dynamic (e.g. app/chat/[chatId]/page.tsx) and read it from params, e.g.:

// app/chat/[chatId]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ chatId: string }>;
}) {
  const { chatId } = await params;
  // use chatId...
}

This is the App Router pattern for dynamic segments (params) rather than expecting chatId as a normal prop. [1], [3]

Sources: [1] https://nextjs.org/docs/messages/next-prerender-sync-params, [2] https://nextjs.org/learn/dashboard-app/adding-search-and-pagination, [3] https://nextjs.org/docs/app/api-reference/file-conventions/dynamic-routes


Show a runnable app/page.tsx example that reads chatId from dynamic route params.

This snippet is labeled app/page.tsx but expects chatId as a custom prop. In App Router, page components receive only params (for dynamic route segments) and searchParams (from query strings), not arbitrary props. Move this to a non-page client component file (e.g., components/ChatClient.tsx), or rewrite it as an actual page that reads params.chatId from a route like app/chat/[chatId]/page.tsx.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ai-chat/frontend.mdx` around lines 71 - 126, The component is written as
a page but expects a custom prop chatId; update it to read route params or move
logic into a client component: either (A) change the page to export default
async function Page({ params }) { const chatId = params.chatId; return
<ChatClientWrapper chatId={chatId} /> } where ChatClientWrapper is a client
component that uses the existing ChatPage/ChatClient logic, or (B) move
ChatClient (and the useEffect/load logic) into a new client component (e.g.,
ChatClient.tsx) and have app/chat/[chatId]/page.tsx import that component and
pass params.chatId to it; adjust references to getChatMessages, getSession,
getChatToken and deleteSession to be called only inside client-side components
(use client directive) and ensure useTriggerChatTransport and useChat remain
inside the client component.


If you return a `StreamTextResult`, it's **automatically piped** to the frontend.

```ts trigger/chat.ts
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.

⚠️ Potential issue | 🟡 Minor

Use typescript fence tags for the snippets.

These blocks are tagged ts/tsx. The docs conventions here require typescript, and the same cleanup likely applies across the other new AI Chat pages too.

As per coding guidelines, "Use language tags in code fences: typescript, bash, json".

Also applies to: 36-36, 50-50

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ai-chat/quick-start.mdx` at line 13, The code fence language tags in
docs/ai-chat/quick-start.mdx use `ts`/`tsx` (e.g. the snippet starting with
"```ts trigger/chat.ts") but our docs convention requires full `typescript`
tags; update each fenced code block (including the ones referenced at lines 36
and 50) to use `typescript` instead of `ts` or `tsx` so the snippets follow the
project's language-tagging guideline.

@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from 00c199b to 4bab668 Compare March 23, 2026 10:27
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/ai-chat/features.mdx (1)

159-170: Add missing imports for completeness.

This example uses streamText, openai, and db without importing them. Consider adding the necessary imports to make the example self-contained.

Suggested imports
+import { chat } from "@trigger.dev/sdk/ai";
+import { streamText } from "ai";
+import { openai } from "@ai-sdk/openai";
+import { db } from "@/lib/db";
+
 export const myChat = chat.task({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ai-chat/features.mdx` around lines 159 - 170, The example for myChat
uses streamText, openai, and db but omits their imports; update the snippet so
it is self-contained by adding import statements for streamText, the openai
helper, and the database client used (the symbols streamText, openai, and db) at
the top of the file or example block, ensuring the imports match the project's
export names and runtime (e.g., import { streamText } from "...", import {
openai } from "...", import { db } from "...") so chat.task and myChat can run
without unresolved symbol errors.
🤖 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/ai-chat/features.mdx`:
- Around line 314-320: The code sample uses schemaTask and z without imports;
add the missing imports at the top (e.g., import { schemaTask } from the SDK
module that exports it and import { z } from "zod") so schemaTask(...) and
z.object(...) resolve; specifically, add an import for schemaTask (to match your
SDK export, e.g., from "@trigger.dev/sdk" or the tasks submodule) and import z
from "zod" alongside the existing ai and chat imports.
- Around line 376-382: The code uses the React hook useEffect but doesn't import
it; add an import for useEffect from React (so the file imports useEffect
alongside any existing React imports) to ensure useEffect in the useEffect(() =>
{ transport.preload(chatId, { idleTimeoutInSeconds: 60 }); }, [chatId]); block
resolves; verify other symbols like useChat, transport, chatId and sendMessage
remain unchanged.

---

Nitpick comments:
In `@docs/ai-chat/features.mdx`:
- Around line 159-170: The example for myChat uses streamText, openai, and db
but omits their imports; update the snippet so it is self-contained by adding
import statements for streamText, the openai helper, and the database client
used (the symbols streamText, openai, and db) at the top of the file or example
block, ensuring the imports match the project's export names and runtime (e.g.,
import { streamText } from "...", import { openai } from "...", import { db }
from "...") so chat.task and myChat can run without unresolved symbol errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cfa5d92f-2c1f-4b43-89c7-1d682b13584c

📥 Commits

Reviewing files that changed from the base of the PR and between 00c199b and 4bab668.

⛔ Files ignored due to path filters (1)
  • references/ai-chat/ARCHITECTURE.md is excluded by !references/**
📒 Files selected for processing (7)
  • docs/ai-chat/backend.mdx
  • docs/ai-chat/features.mdx
  • docs/ai-chat/frontend.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/reference.mdx
  • docs/docs.json
✅ Files skipped from review due to trivial changes (5)
  • docs/docs.json
  • docs/ai-chat/quick-start.mdx
  • docs/ai-chat/overview.mdx
  • docs/ai-chat/reference.mdx
  • docs/ai-chat/backend.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/ai-chat/frontend.mdx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: sdk-compat / Deno Runtime
🧰 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

Files:

  • docs/ai-chat/features.mdx
🧠 Learnings (2)
📓 Common learnings
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 3200
File: docs/config/config-file.mdx:353-368
Timestamp: 2026-03-10T12:44:19.869Z
Learning: In the triggerdotdev/trigger.dev repository, docs PRs are often written as companions to implementation PRs (e.g., PR `#3200` documents features being added in PR `#3196`). When reviewing docs PRs, the documented features may exist in a companion/companion PR branch rather than main. Always check companion PRs referenced in the PR description before flagging missing implementations.
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: New documentation pages must be added to the navigation structure in `docs.json` under the correct group after creating the MDX file
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: Applies to docs/**/*.mdx : MDX documentation pages must include frontmatter with title (required), description (required), and sidebarTitle (optional) in YAML format
📚 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/features.mdx
🪛 LanguageTool
docs/ai-chat/features.mdx

[style] ~172-~172: To form a complete sentence, be sure to include a subject.
Context: ...signal }); }, }); ``` chat.defer() can be called from anywhere during a turn —...

(MISSING_IT_THERE)

🔇 Additional comments (6)
docs/ai-chat/features.mdx (6)

124-135: Type mismatch: userId not declared in userContext.

The example accesses userContext.get().userId at line 128, but the userContext type declared earlier (lines 25-29) doesn't include userId. Either add userId to the type declaration and initialization, or use a different property that exists (like deriving from clientData).


17-56: LGTM!

The example demonstrates the full lifecycle of chat.local with consistent types and usage.


81-114: LGTM!

The subtask example clearly demonstrates auto-hydration of locals with consistent typing.


223-284: LGTM!

The subtask streaming example effectively demonstrates the target: "root" pattern with clear progression from in-progress to done states.


288-300: LGTM!

Clear frontend example showing how to conditionally render custom data parts.


65-74: > Likely an incorrect or invalid review comment.

Comment thread docs/ai-chat/features.mdx
Comment thread docs/ai-chat/features.mdx
Comment on lines +376 to +382
useEffect(() => {
transport.preload(chatId, { idleTimeoutInSeconds: 60 });
}, [chatId]);

const { messages, sendMessage } = useChat({ id: chatId, transport });
// ...
}
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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

AI SDK useChat hook return values append handleSubmit

💡 Result:

The useChat hook from Vercel AI SDK (current version as of 2026 is 5+) returns an object with several properties and methods for managing chat state and interactions. Key returns include: - messages: UIMessage[] - Current array of chat messages. - status: 'submitted' | 'streaming' | 'ready' | 'error' - Current chat status. - error?: Error - Error if one occurred. - id: string - Unique chat identifier. - sendMessage: (message?: { text: string; ... }, options?: ChatRequestOptions) => Promise - Sends a new message (replaces older 'append'). - handleSubmit is not a direct return of useChat in current versions; it was likely a custom form handler in older examples using the old input/handleInputChange/handleSubmit pattern. Now, manage input with useState and call sendMessage on form submit. - Other methods: regenerate, stop, setMessages, addToolOutput, clearError, resumeStream. In older versions (pre-5.0, e.g. ai/react), useChat returned additional items like input, handleInputChange, handleSubmit (for form submission), and append (for programmatic message addition). These were removed in 5.0 with the transport architecture change - input state is no longer managed internally; use sendMessage instead. See migration guide for details. Example usage (current): const { messages, sendMessage, status } = useChat({ transport: new DefaultChatTransport({ api: '/api/chat' }) }); const [input, setInput] = useState(''); const handleSubmit = (e) => { e.preventDefault; if (!input.trim) return; sendMessage({ text: input }); setInput(''); }; For programmatic append (older style): In v4, use append({ role: 'user', content: 'text' }). In v5+, use setMessages(prev => [...prev, newMessage]) for local updates, or sendMessage.

Citations:


🏁 Script executed:

# Check the actual file and examine context around the lines
fd "features.mdx" docs/ai-chat/ | head -5

Repository: triggerdotdev/trigger.dev

Length of output: 94


🏁 Script executed:

# If found, examine the file contents around lines 376-382
if [ -f "docs/ai-chat/features.mdx" ]; then
  wc -l "docs/ai-chat/features.mdx"
fi

Repository: triggerdotdev/trigger.dev

Length of output: 98


🏁 Script executed:

# Get the relevant section with more context
if [ -f "docs/ai-chat/features.mdx" ]; then
  sed -n '360,390p' "docs/ai-chat/features.mdx"
fi

Repository: triggerdotdev/trigger.dev

Length of output: 1015


Import useEffect from React.

The useEffect hook is missing its import statement from React. The sendMessage API is correct for current Vercel AI SDK versions.

Suggested fix
+import { useEffect } from "react";
 import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
 import { useChat } from "@ai-sdk/react";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ai-chat/features.mdx` around lines 376 - 382, The code uses the React
hook useEffect but doesn't import it; add an import for useEffect from React (so
the file imports useEffect alongside any existing React imports) to ensure
useEffect in the useEffect(() => { transport.preload(chatId, {
idleTimeoutInSeconds: 60 }); }, [chatId]); block resolves; verify other symbols
like useChat, transport, chatId and sendMessage remain unchanged.

@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from 2626ff2 to 22331d4 Compare March 25, 2026 14:52
@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from 22331d4 to a78bc05 Compare March 25, 2026 17:01
@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from c62b5e2 to 585b781 Compare March 26, 2026 15:32
@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from c017aa2 to 63d4719 Compare March 30, 2026 20:59
@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from 63d4719 to ea46733 Compare April 1, 2026 07:07
@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from ea46733 to 4c34098 Compare April 1, 2026 13:57
Covers the mockChatAgent harness end-to-end: setup, driver methods,
turn assertions, hook ordering, and the locals-based dependency
injection pattern for testing against a real database (testcontainers,
PGlite, or in-memory fakes).
Documents the new mockChatAgent test harness, setupLocals DI pattern,
and the lower-level runInMockTaskContext utility.
Covers askUser-style mid-turn user input end-to-end: defining a
no-execute tool, rendering pending tool calls on the frontend with
addToolOutput + sendAutomaticallyWhen, detecting paused turns via
finishReason, and persistence patterns (overwrite vs checkpoint nodes)
for apps that need an immutable audit trail.

Resolves TRI-8404.
Add an "Ending a run on your terms" section to backend.mdx covering
chat.endRun() — exit after the current turn without the upgrade-required
signal, for one-shot or self-terminating agents.
Show how to wire a "Summarize conversation" button or slash command
via actionSchema + onAction. The backend summarizes and replaces
history with chat.history.set(); run() short-circuits when
trigger === "action" so no LLM response is generated. Includes a
progress-feedback variant using chat.stream.append().

Resolves TRI-8268.
Covers chat.endRun(), finishReason on turn-complete events,
user-initiated compaction pattern, and the new human-in-the-loop
patterns page.
New docs/ai-chat/patterns/skills.mdx covering Phase 1 end-to-end:
folder layout, SKILL.md format, skills.define + chat.skills.set,
auto-wired loadSkill/readFile/bash tools, built-in CLI bundling,
path scoping rules, and mixing with custom tools. Links to the
AI SDK cookbook pattern we build on.
Covers Agent Skills Phase 1 — skills.define, chat.skills.set,
auto-wired loadSkill/readFile/bash tools, and CLI bundling into
/app/.trigger/skills/ at deploy time.
Net-new Sessions section (4 pages under docs/sessions/) plus updates
to 10 ai-chat pages and cross-reference callouts on two realtime
backend pages — covers the chat.agent migration to the Session
primitive and the X-Session-Settled fast-close work.

Phase 1 — Sessions primitive (net-new)

docs/sessions/overview.mdx — what a Session is, identity
(sessionId + externalId, idempotent create on externalId), the
.in / .out asymmetry, durability across runs, when to use Sessions
vs run-scoped streams, relationship to chat.agent.

docs/sessions/quick-start.mdx — four-step walkthrough (create →
open from a task → subscribe from a client → close), plus a brief
.in example.

docs/sessions/channels.mdx — deep dive. .out producer methods
(append / pipe / writer) and consumer method (read).
.in consumer methods (on / once / peek / wait /
waitWithIdleTimeout) and producer method (send). Suspend-while-idle
via session-stream waitpoints. Uniform serialization. Buffering
and attachment semantics.

docs/sessions/reference.mdx — full API reference tables. `sessions.*`
methods with signatures. CreateSessionRequestBody / SessionItem /
UpdateSessionRequestBody / CloseSessionRequestBody / ListSessionsOptions
shapes. SessionHandle / SessionOutputChannel / SessionInputChannel
method tables. Option types (WriterStreamOptions,
SessionSubscribeOptions, InputStreamOnceOptions / InputStreamWaitOptions
/ InputStreamWaitWithIdleTimeoutOptions). Token scopes. Wire
endpoints including X-Session-Settled.

docs/docs.json — added Sessions subgroup under the AI dropdown,
placed right after Agents.

Phase 2 — chat.agent updates

docs/ai-chat/client-protocol.mdx — full rewrite. Old run-scoped
endpoints (`/realtime/v1/streams/{runId}/chat`,
`/realtime/v1/streams/{runId}/input/chat-messages`) replaced with
session endpoints (`POST /api/v1/sessions`,
`POST /realtime/v1/sessions/{sessionId}/in/append`,
`GET /realtime/v1/sessions/{sessionId}/out`). Documents ChatInputChunk
tagged union, Last-Event-ID resume, X-Session-Settled header. Keeps
sequence diagrams, upgrade-required flow, tool approvals, actions,
pending / steering messages, and continuations — all re-framed
around sessions.

docs/ai-chat/frontend.mdx — new "What the transport persists per
chat" table under Session management: sessionId durable,
publicAccessToken refreshed, lastEventId for resume, runId optional,
isStreaming optional (server decides via X-Session-Settled now).
Short paragraph under Restoring on page load explaining cross-run
resume.

docs/ai-chat/server-chat.mdx — stateless handler example rewritten
around sessionId as the durable key (runId + lastEventId are
live-run hints). Info callout on cross-run durability. New inbox
example via sessions.list({type: "chat.agent"}). Updated session
option row in the AgentChat options table to reflect the new
ChatSession shape.

docs/ai-chat/backend.mdx — Info callout at the top of chat.agent()
section: every conversation is a Session, externalId = chatId,
type = "chat.agent". Rarely need to touch directly, but
`payload.sessionId` + `sessions.open()` is available.

docs/ai-chat/reference.mdx — ChatTaskRunPayload gained sessionId
row. TriggerChatTransport options updated for ChatSession shape.
RenewRunAccessTokenParams documented with sessionId; renew callback
example mints both run + session scopes. New ChatSession type
section. New ChatInputChunk type section. Session scopes table
with links to /sessions/reference.

docs/ai-chat/overview.mdx — recast "How multi-turn works": one
conversation, many runs (sessionId is durable). New "Resume and
inbox" section covering cross-run resume on page load and
sessions.list for inbox views. Link to /sessions/overview in
Related.

docs/ai-chat/quick-start.mdx — Sessions link added to Next steps.

docs/ai-chat/changelog.mdx — new dated entry covering the session
migration: externalId = chatId, public surface unchanged,
cross-run resume is free, inbox via sessions.list, X-Session-Settled
fast-close improvement, migration notes for custom-transport
authors.

docs/ai-chat/testing.mdx — note that mockChatAgent drives the
agent's backing Session channels under the hood (API unchanged).
"close" wording updated from "input stream" to ".in channel".

docs/ai-chat/patterns/version-upgrades.mdx — clarified that
chat.requestUpgrade() re-triggers on the same session; only runId
+ publicAccessToken refresh. Subsequent-messages terminology
updated from "input stream" to "session's .in channel" for
consistency.

Phase 3 — Cross-references

docs/realtime/backend/streams.mdx — Tip callout pointing to
Sessions for durable long-lived channels. Run-scoped streams
explicitly not deprecated.

docs/realtime/backend/input-streams.mdx — same callout, framed
around runId vs sessionId addressing.

All 16 affected pages verified serving 200 on the local Mintlify
dev server. Plan lives at .claude/docs-plans/sessions-chat-agent.md
for anyone picking up the work later.
Bring the AI Chat documentation in line with the Sessions-as-run-manager
release. Public surface (chat.agent({...}), useTriggerChatTransport,
AgentChat, chat.store / chat.defer / chat.history) is unchanged in
shape; the wiring docs around it changed enough that every transport
example, every server-action snippet, and the auth/session model needed
updating.

New:
- ai-chat/upgrade-guide.mdx — step-by-step migration for prerelease
  customers (replace getStartToken / getChatToken with startSession +
  accessToken, drop runId from ChatSession persistence, etc.).

Updated transport-shape group (these all share the same callback
shape and ship together):
- quick-start, frontend, backend, server-chat, types, reference

Updated peripherals:
- overview, changelog, client-protocol, features, error-handling,
  testing, patterns/version-upgrades, patterns/database-persistence

Outside ai-chat:
- realtime/backend/{streams,input-streams}: callout cross-references
  no longer point at the deleted Sessions docs.

Removed:
- docs/sessions/{overview,quick-start,channels,reference}.mdx — the
  standalone-Sessions surface predates the task-bound model and was
  giving stale guidance. We'll re-introduce Sessions docs once the
  primitive ships a non-chat.agent customer flow worth documenting.
- The "Sessions" group in docs.json's AI nav.
@ericallam ericallam force-pushed the docs/tri-7532-ai-sdk-chat-transport-and-chat-task-system branch from 277c630 to 5f48914 Compare April 28, 2026 12:05
The page-load reads Chat.messages and ChatSession.lastEventId in parallel.
A non-atomic onTurnComplete that writes them as two separate awaits has a
narrow race window where messages are post-write but lastEventId is still
pre-write — the transport then replays this turn's chunks on resume and
duplicates the assistant render.

Add a Warning callout in the persistence pattern doc with the ✅ atomic and
❌ non-atomic shapes, and update both code examples (basic + hydrateMessages
variant) to use prisma.$transaction.
- Move Upgrade Guide to the bottom of the Agents sidebar (after API Reference) and rename its sidebarTitle to "Sessions Upgrade Guide" so it reads as a standalone migration doc rather than a regular concept page.
- Replace the inaccurate inline Migration section in the 4/24 Sessions changelog entry with a pointer to the upgrade guide.
- Add a Docs section to the same entry summarizing the Sessions doc surface that shipped: rewritten Client Protocol, atomic-write warning on the persistence pattern, new reference symbols, and the broader page refreshes.
…tence

`chat.defer(db.chat.update(...))` in `onTurnStart` is fire-and-forget — the hook resolves and streaming begins before the write lands. A mid-stream page refresh then reads `[]` from the DB, the resumed SSE stream pushes the assistant into an empty array, and the user's message disappears from the rendered conversation.

- patterns/database-persistence.mdx: replace the misleading "optionally use chat.defer" line with an awaited persistence + a Warning showing wrong/right examples and the failure mode. Update the minimal pseudocode to use await.
- features.mdx (chat.defer reference): swap the misleading example (db.chat.update inside onTurnStart) for an analytics-tracking example. Add a Warning cross-linking back to the persistence doc.

Reserve chat.defer for writes whose timing has no resume implication.
The chat output stream caps each record at ~1 MiB, and chat.agent now
throws a typed ChatChunkTooLargeError when a chunk overruns. Document
both the typed error and the two workaround patterns:

- ID-reference: persist large values to your store, emit only an id +
  preview through the chat stream, fetch the full payload on demand.
- Out-of-band streams.writer(): a separate run-scoped channel for
  transient/per-turn data the chat stream shouldn't carry.

Pages
- New patterns/large-payloads.mdx covering the cause, the typed error,
  both patterns, and what doesn't trigger the cap (chat.history,
  chat.inject, chat.defer).
- error-handling.mdx gains a short ChatChunkTooLargeError section that
  cross-links the new patterns page.
- docs.json adds the new patterns page to the Agents → Patterns sidebar.
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.

1 participant