Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions docs/ai-chat/actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Actions"
description: "Custom commands sent from the frontend that mutate chat state without consuming a turn — undo, rollback, edit, regenerate."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

## Overview

Custom actions let the frontend send structured commands (undo, rollback, edit, regenerate) that modify the conversation state. **Actions are not turns**: they fire `hydrateMessages` (if set) and `onAction` only. No turn lifecycle hooks (`onTurnStart` / `prepareMessages` / `onBeforeTurnComplete` / `onTurnComplete`), no `run()`, no turn-counter increment. The trace span is named `chat action`.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/anatomy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Anatomy"
description: "The moving parts of a chat agent — the agent task, the session, the frontend transport — and which page covers each."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

**A chat agent is three parts: a long-lived agent task that runs the turn loop, a durable Session carrying messages in and the response stream out, and a frontend transport that plugs the session into `useChat`.** The pages in this section each own one part of that picture. This page is the map — if you'd rather read mechanics end to end, skip to [How it works](/ai-chat/how-it-works).

```mermaid
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/backend.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Backend"
description: "Three approaches to building your chat backend — chat.agent(), session iterator, or raw task primitives."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

There are three abstraction levels for a chat backend. All three speak the same wire protocol, so the [frontend transport](/ai-chat/frontend) works unchanged whichever you pick.

| Capability | `chat.agent()` | `chat.createSession()` | Raw primitives |
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/background-injection.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Background injection"
description: "Inject context from background work into the agent's conversation — self-review, RAG augmentation, or any async analysis."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

## Overview

`chat.inject()` queues model messages for injection into the conversation. Messages are picked up at the start of the next turn or at the next `prepareStep` boundary (between tool-call steps).
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/chat-local.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "chat.local"
description: "Typed, run-scoped data accessible from hooks, run(), tools, and subtasks. Survives across turns, auto-cleared between runs, auto-hydrated into subtasks."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Use `chat.local` to create typed, run-scoped data that persists across turns and is accessible from anywhere — the run function, tools, nested helpers. Each run gets its own isolated copy, and locals are automatically cleared between runs.

Lifecycle hooks and **`run`** also receive **`ctx`** ([`TaskRunContext`](/ai-chat/reference#task-context-ctx)) — the same object as on a standard `task()` — for tags, metadata, and cleanup that needs the full run record.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/client-protocol.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Client Protocol"
description: "The wire protocol for building custom chat transports — how clients communicate with chat agents over Sessions and SSE."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

This page documents the protocol that chat clients use to communicate with `chat.agent()` tasks. Use this if you're building a custom transport (e.g., for a Slack bot, CLI tool, or native app) instead of using the built-in `TriggerChatTransport` or `AgentChat`.

<Note>
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/compaction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Compaction"
description: "Automatic context compaction to keep long conversations within token limits."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

## Overview

Long conversations accumulate tokens across turns. Eventually the context window fills up, causing errors or degraded responses. Compaction solves this by automatically summarizing the conversation when token usage exceeds a threshold, then using that summary as the context for future turns.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Custom agents"
description: "Build chat agents without chat.agent()'s managed lifecycle: register with chat.customAgent(), then drive turns with the createSession iterator or a hand-rolled loop."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

**A custom agent is a task you register with `chat.customAgent()` and drive yourself — either with the managed turn iterator from `chat.createSession()`, or with a fully hand-rolled loop over the raw chat primitives.** You give up `chat.agent()`'s lifecycle hooks and automatic continuation recovery; you gain inline control over every turn, and (at the lowest level) full control over the stream conversion.

See the [comparison table](/ai-chat/backend) before dropping down. The frontend is unchanged either way: all levels speak the same wire protocol, so [`useTriggerChatTransport`](/ai-chat/frontend) points at a custom agent exactly like a `chat.agent()`.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/error-handling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Error handling"
description: "How errors flow through chat.agent — stream errors, hook errors, run failures — and how to recover."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

`chat.agent` errors fall into four layers, each with different recovery semantics. The default behavior is **conversation-preserving**: a thrown error in a hook or `run()` does not kill the chat. The current turn ends with an error chunk, and the agent waits for the user's next message.

## Error layers at a glance
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/fast-starts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Fast starts"
description: "Two ways to cut first-turn TTFC: Preload eagerly triggers the run before the first message; Head Start runs step 1 in your warm server while the agent boots in parallel."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

The first turn of a brand-new conversation pays for the chat.agent run's cold start: dequeue, process boot, `onPreload` / `onChatStart` hooks, and only then the LLM call. Two features address this from different angles.

## Picking an approach
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/frontend.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Frontend"
description: "Transport setup, session management, client data, and frontend patterns for AI Chat."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

## How the transport works

Vanilla `useChat` expects an `api` URL — it POSTs the conversation to your own Next.js route handler, which terminates the stream. `useTriggerChatTransport` replaces that round-trip: instead of an `api` URL, you pass a custom [`ChatTransport`](https://ai-sdk.dev/docs/ai-sdk-ui/transport) that talks directly to the Trigger.dev cloud (or your self-hosted webapp) on behalf of `useChat`.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/how-it-works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "How it works"
description: "End-to-end mechanics of a chat.agent turn: the two durable channels per session, the long-lived task that reads and writes them, and how a chat survives refreshes, deploys, and idle gaps."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

This page explains how `chat.agent` is put together, what each piece does on a single turn, and how a chat survives across turns. It is not an API tour — for that, see [Backend](/ai-chat/backend), [Frontend](/ai-chat/frontend), and the [Reference](/ai-chat/reference). For the byte-level wire format, see [Client Protocol](/ai-chat/client-protocol).

<Note>
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/lifecycle-hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Lifecycle hooks"
description: "Hook into every stage of a chat agent's run: preload, turn start, turn complete, suspend, resume, and more."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

`chat.agent({ ... })` accepts a set of lifecycle hooks for persisting state, validating input, transforming messages, and reacting to suspension and resumption. They fire at well-defined points in the chat agent's lifetime.

**Once per worker process (every fresh run boot):** `onBoot` → `onPreload` (preloaded runs only).
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/mcp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "MCP Server"
description: "Chat with your agents from any AI coding tool using the Trigger.dev MCP server."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

The Trigger.dev MCP server includes tools for having conversations with your chat agents directly from AI coding tools like Claude Code, Cursor, Windsurf, and others. This lets your AI assistant interact with your agents without writing any code.

## Available tools
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Overview"
description: "Durable multi-turn AI chats — one Trigger.dev task per conversation, surviving refreshes, deploys, and crashes."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

An AI chat isn't a request — it's a session. `chat.agent` runs every conversation as a single long-lived Trigger.dev task: you write the loop, it wakes up when a message arrives, freezes when none do, and the same in-memory state and on-disk workspace survive across page refreshes, deploys, idle gaps, and crashes. The substrate handles the parts most teams stitch together by hand — turn lifecycle, mid-stream resume, recovery from cancel/crash/OOM, HITL approvals, deploy upgrades — so your code is the loop you'd write anyway: messages in, `streamText` out.

## A minimal example
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/branching-conversations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Branching conversations"
description: "Build ChatGPT-style conversation trees with edit, regenerate, undo, and branch switching using hydrateMessages, chat.history, and actions."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Most chat UIs treat conversations as linear sequences. But real conversations branch — users edit previous messages, regenerate responses, undo exchanges, and explore alternative paths. This pattern shows how to build a branching conversation system using `hydrateMessages`, `chat.history`, and custom actions.

## Data model
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/code-sandbox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Code sandbox"
description: "Warm an isolated sandbox on each chat turn, run an AI SDK executeCode tool, and tear down right before the run suspends — using chat.agent hooks and chat.local."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Use a **hosted code sandbox** (for example [E2B](https://e2b.dev)) when the model should run short scripts to analyze tool output (PostHog queries, CSV-like data, math) without executing arbitrary code on the Trigger worker host.

This page describes a **durable chat** pattern that fits `chat.agent()`:
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/database-persistence.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Database persistence"
description: "Split conversation state and live session metadata across hooks — preload, turn start, turn complete — without tying the pattern to a specific ORM or schema."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Durable chat runs can span **hours** and **many turns**. You usually want:

1. **Conversation state** — full **`UIMessage[]`** (or equivalent) keyed by **`chatId`**, so reloads and history views work.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/human-in-the-loop.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Human-in-the-loop"
description: "Pause the agent mid-response to ask the user a clarifying question, then resume with their answer."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Some turns need to stop and ask the user something before they can finish — picking between options, confirming a destructive action, or clarifying an ambiguous request. The AI SDK calls this **human-in-the-loop** (HITL), and the building block is a tool with no `execute` function.

When the LLM calls a tool that has no `execute`, `streamText` ends with the tool call still pending. The turn completes cleanly, the frontend renders UI to collect the answer, and when the user responds, a new turn resumes with the answer merged into the same assistant message.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/large-payloads.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Large payloads"
description: "Why a single chunk on the chat stream is capped at ~1 MiB, what error you'll see, and how to work around it with ID references."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

The realtime stream that backs `chat.agent` enforces a **per-record cap of ~1 MiB** (`1048576` bytes minus a small envelope reserve). Anything written through the chat output — auto-piped LLM chunks, `chat.response.write`, custom `writer.write` parts — counts as one record per chunk and is rejected if it crosses the cap.

This is a platform-level limit and cannot be raised per project or per stream.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/oom-resilience.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "OOM resilience"
description: "Recover from out-of-memory errors mid-turn by automatically retrying the failed turn on a larger machine — without losing the in-flight user message or re-processing completed turns."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

When a `chat.agent` turn runs out of memory, the worker process dies and everything in it is gone: the in-flight LLM call, the accumulator, any tool execution mid-flight. By default, Trigger.dev surfaces the OOM as a run failure.

Setting `oomMachine` opts the agent into automatic recovery: the failed turn re-runs on a larger machine, picks up the user message that triggered the OOM (without re-processing earlier completed turns), and produces a normal response.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/persistence-and-replay.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Persistence and replay"
description: "How chat.agent rebuilds conversation history at run boot — durable JSON snapshot in object storage plus session.out replay, with a hydrateMessages short-circuit for backend-owned history."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

`chat.agent` runs are processes — they boot, stream a turn, and either suspend (waiting for the next message) or exit. When the next message arrives at a session whose previous run already exited, a **fresh** run boots with no in-memory state. Something has to rebuild the conversation history before that turn can produce a coherent response.

This page walks through the **snapshot + replay** model the runtime uses by default, and the [`hydrateMessages`](/ai-chat/lifecycle-hooks#hydratemessages) short-circuit that turns the whole thing off when the customer owns history.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/recovery-boot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Recovery boot"
description: "Recover from cancel-mid-stream, crashes, and OOM kills with full conversational context. The smart default Just Works; the onRecoveryBoot hook is the override path for advanced policies."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

When a `chat.agent` run dies in the middle of streaming a response — the user cancels, the worker OOMs, or an unhandled exception kills the process — the durable streams hold what was in flight. The next run boots as a continuation, reads both stream tails, and reconstructs a chain that preserves the partial response so any follow-up (`keep going`, `actually do X instead`, a new question) has full context.

The behavior is automatic. The `onRecoveryBoot` hook is opt-in for policies that need something different.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/skills.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Agent Skills"
description: "Ship reusable capabilities (folders with SKILL.md + scripts) that a chat agent discovers and invokes on demand."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Agent skills are reusable capabilities you ship as folders — a `SKILL.md` describing when and how to use them, plus optional scripts, references, and assets. The chat agent sees a short description of each skill in its system prompt, loads the full instructions on demand via a `loadSkill` tool, and invokes the bundled scripts via `bash` — all without you wiring anything up manually.

Built on the [AI SDK cookbook pattern](https://ai-sdk.dev/cookbook/guides/agent-skills). Works with any provider (OpenAI, Anthropic, Gemini, etc.) — not tied to Anthropic's server-side skills.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/sub-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Sub-Agents"
description: "Delegate work to durable sub-agents from within a parent agent's tool calls, with streaming preliminary results."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Sub-agents let a parent agent delegate work to other agents running as durable Trigger.dev tasks. The sub-agent's response streams back through the parent as preliminary tool results, so the frontend sees the sub-agent working inside the parent's tool call card.

This builds on the AI SDK's [async generator tool pattern](https://ai-sdk.dev/docs/agents/subagents) and Trigger.dev's [AgentChat](/ai-chat/server-chat) for server-side agent interaction.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/tool-result-auditing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Tool result auditing"
description: "Fire side effects exactly once per resolved tool call — audit logs, billing, notifications — using extractNewToolResults inside hydrateMessages or onTurnComplete."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

When a chat agent uses [tools](/ai-chat/tools) (especially [human-in-the-loop](/ai-chat/patterns/human-in-the-loop) tools that wait on `addToolOutput` from the frontend), you often need to fire side effects exactly once per resolved tool call:

- **Audit logs** — record every tool result for compliance.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/trusted-edge-signals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Trusted edge signals"
description: "How to safely deliver server-trusted signals (bot scores, JA4, ASN, ReCAPTCHA verdicts) to a chat.agent run via an edge proxy."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

A common need for chat-style endpoints is to drive agent behavior from **server-trusted signals** that the browser cannot be allowed to declare itself — bot management scores, JA4 fingerprints, ASN, ReCAPTCHA verdicts, or any other anti-abuse data only the edge can see. The agent's [`clientData`](/ai-chat/reference#withclientdata) channel is the right delivery mechanism, but `clientData` set in the browser is by definition spoofable. The fix is to move the value population out of the browser and into a trusted edge proxy.

This page documents the pattern using Cloudflare Workers as the proxy. The same shape applies to any edge layer (custom reverse proxy, Vercel Edge Middleware, AWS Lambda@Edge) — the trust comes from the deployment topology, not from Trigger.dev validating the source.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/patterns/version-upgrades.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Version upgrades"
description: "Gracefully migrate suspended chat agents to a new deployment using chat.requestUpgrade() and the continuation mechanism."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

Chat agent runs are pinned to the worker version they started on. When you deploy a new version, suspended runs resume on the **old** code. If your deploy includes breaking changes (new tools, changed schemas, updated API contracts), this can cause issues.

`chat.requestUpgrade()` lets the agent opt out of the current run so the transport triggers a new one on the latest version.
Expand Down
4 changes: 0 additions & 4 deletions docs/ai-chat/pending-messages.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ sidebarTitle: "Pending Messages"
description: "Inject user messages mid-execution to steer agents between tool-call steps."
---

import RcBanner from "/snippets/ai-chat-rc-banner.mdx";

<RcBanner />

## Overview

When an AI agent is executing tool calls, users may want to send a message that **steers the agent mid-execution** — adding context, correcting course, or refining the request without waiting for the response to finish.
Expand Down
Loading