Conversation
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds 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)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
references/ai-chat/ARCHITECTURE.mdis excluded by!references/**
📒 Files selected for processing (7)
docs/ai-chat/backend.mdxdocs/ai-chat/features.mdxdocs/ai-chat/frontend.mdxdocs/ai-chat/overview.mdxdocs/ai-chat/quick-start.mdxdocs/ai-chat/reference.mdxdocs/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/sdkin 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.mdxdocs/ai-chat/overview.mdxdocs/ai-chat/backend.mdxdocs/ai-chat/reference.mdxdocs/ai-chat/features.mdxdocs/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.mdxdocs/ai-chat/overview.mdxdocs/ai-chat/backend.mdxdocs/ai-chat/reference.mdxdocs/ai-chat/features.mdxdocs/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 indocs.jsonwhich includes navigation structure, theme, and metadata
Navigation structure indocs.jsonshould be organized usingnavigation.dropdownswith 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.mdxdocs/ai-chat/overview.mdxdocs/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.mdxdocs/ai-chat/overview.mdxdocs/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.mdxdocs/ai-chat/overview.mdxdocs/ai-chat/backend.mdxdocs/ai-chat/reference.mdxdocs/ai-chat/features.mdxdocs/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.mdxdocs/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.dropdownsand 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.jsonunder the correct group after creating the MDX file".Also applies to: 744-746
| 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(() => {}); | ||
| } |
There was a problem hiding this comment.
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.
| const userContext = chat.local<{ | ||
| name: string; | ||
| plan: "free" | "pro"; | ||
| messageCount: number; | ||
| }>({ id: "userContext" }); |
There was a problem hiding this comment.
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.
| ```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 | ||
| } |
There was a problem hiding this comment.
🧩 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 |
There was a problem hiding this comment.
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.
00c199b to
4bab668
Compare
There was a problem hiding this comment.
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, anddbwithout 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
⛔ Files ignored due to path filters (1)
references/ai-chat/ARCHITECTURE.mdis excluded by!references/**
📒 Files selected for processing (7)
docs/ai-chat/backend.mdxdocs/ai-chat/features.mdxdocs/ai-chat/frontend.mdxdocs/ai-chat/overview.mdxdocs/ai-chat/quick-start.mdxdocs/ai-chat/reference.mdxdocs/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/sdkin 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:userIdnot declared inuserContext.The example accesses
userContext.get().userIdat line 128, but theuserContexttype declared earlier (lines 25-29) doesn't includeuserId. Either adduserIdto the type declaration and initialization, or use a different property that exists (like deriving fromclientData).
17-56: LGTM!The example demonstrates the full lifecycle of
chat.localwith 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.
| useEffect(() => { | ||
| transport.preload(chatId, { idleTimeoutInSeconds: 60 }); | ||
| }, [chatId]); | ||
|
|
||
| const { messages, sendMessage } = useChat({ id: chatId, transport }); | ||
| // ... | ||
| } |
There was a problem hiding this comment.
🧩 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:
- 1: https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat
- 2: https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-chat
- 3: https://sdk.vercel.ai/docs/ai-sdk-ui/chatbot
- 4: https://v5.ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat
- 5: https://v4.ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat
- 6: https://ai-sdk.dev/docs/ai-sdk-ui/chatbot
- 7: https://sdk.vercel.ai/docs/reference/ai-sdk-ui/append-response-messages
🏁 Script executed:
# Check the actual file and examine context around the lines
fd "features.mdx" docs/ai-chat/ | head -5Repository: 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"
fiRepository: 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"
fiRepository: 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.
2626ff2 to
22331d4
Compare
22331d4 to
a78bc05
Compare
c62b5e2 to
585b781
Compare
c017aa2 to
63d4719
Compare
63d4719 to
ea46733
Compare
ea46733 to
4c34098
Compare
…ool approvals wire protocol
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.
277c630 to
5f48914
Compare
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.
No description provided.