Files
triggerdotdev--trigger.dev/docs/snippets/migrate-v4-using-ai.mdx
T
Eric Allam 80bb600cd5 docs(ai-chat): AI Agents documentation for v4.5 (#3226)
## Summary

Lands the full AI Agents documentation surface alongside the v4.5
release candidate of `@trigger.dev/sdk`. Covers `chat.agent` end to end
— defining agents, lifecycle hooks, the frontend transport, sub-agents,
recovery from cancel/crash/OOM, AI Prompts integration — and the
Sessions primitive that backs it.

## Coverage

- **Conceptual**: Overview, Quick Start, How it works.
- **Building agents**: Backend (`chat.agent` / `chat.createSession` /
raw primitives), Lifecycle hooks, Frontend transport, Server-side
`AgentChat`, Sessions reference, `chat.local` state primitive,
TypeScript types.
- **Features**: AI Prompts integration, Fast starts (Preload + Head
Start), Compaction, Pending Messages (steering), Background Injection
(`chat.inject` + `chat.defer`), Actions (undo / regenerate / edit),
Error handling.
- **Patterns (13)**: Sub-agents, Branching conversations, Code sandbox,
Database persistence, Persistence and replay, HITL, Tool result
auditing, Large payloads, Agent skills, OOM resilience, Recovery boot,
Trusted edge signals, Version upgrades.
- **Reference**: API Reference, Client Protocol (wire format), Testing
harness (`mockChatAgent`), MCP server tools, Upgrade guide, Changelog.

## Structure changes

- Top-level nav: AI → **Agents**, with sub-groups for *Building agents /
Features / Patterns / Reference*.
- New RC banner snippet on every page links to the supported AI SDK
versions table on the API Reference.
- All examples use Anthropic with `stopWhen: stepCountIs(15)`.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 16:50:59 +01:00

224 lines
6.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Accordion title="Copy paste this prompt in full" icon="sparkles">
```md
I would like you to help me migrate my v3 task code to v4. Here are the important differences:
We've deprecated the `@trigger.dev/sdk/v3` import path and moved to a new path:
// This is the old path
import { task } from "@trigger.dev/sdk/v3";
// This is the new path, use this instead
import { task } from "@trigger.dev/sdk";
We've renamed the `handleError` hook to `catchError`. Use this instead of `handleError`.
`init` was previously used to initialize data used in the run function. This is the old version:
import { task } from "@trigger.dev/sdk";
const myTask = task({
init: async () => {
return {
myClient: new MyClient(),
};
},
run: async (payload: any, { ctx, init }) => {
const client = init.myClient;
await client.doSomething();
},
});
This is the new version using middleware and locals:
import { task, locals, tasks } from "@trigger.dev/sdk";
// Create a local for your client
const MyClientLocal = locals.create<MyClient>("myClient");
// Set up middleware to initialize the client
tasks.middleware("my-client", async ({ next }) => {
const client = new MyClient();
locals.set(MyClientLocal, client);
await next();
});
// Helper function to get the client
function getMyClient() {
return locals.getOrThrow(MyClientLocal);
}
const myTask = task({
run: async (payload: any, { ctx }) => {
const client = getMyClient();
await client.doSomething();
},
});
Weve deprecated the `toolTask` function. Use `schemaTask` plus AI SDK `tool()` with `execute: ai.toolExecute(task)` (the `ai.tool()` wrapper is deprecated). This is the old version:
import { toolTask, schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";
import { generateText } from "ai";
const myToolTask = toolTask({
id: "my-tool-task",
run: async (payload: any, { ctx }) => {},
});
export const myAiTask = schemaTask({
id: "my-ai-task",
schema: z.object({
text: z.string(),
}),
run: async (payload, { ctx }) => {
const { text } = await generateText({
prompt: payload.text,
model: openai("gpt-4o"),
tools: {
myToolTask,
},
});
},
});
This is the new version:
import { schemaTask } from "@trigger.dev/sdk";
import { ai } from "@trigger.dev/sdk/ai";
import { z } from "zod";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
// Convert toolTask to schemaTask with a schema
const myToolTask = schemaTask({
id: "my-tool-task",
schema: z.object({
// Add appropriate schema for your tool's payload
input: z.string(),
}),
run: async (payload, { ctx }) => {},
});
const myTool = tool({
description: myToolTask.description ?? "",
inputSchema: myToolTask.schema!,
execute: ai.toolExecute(myToolTask),
});
export const myAiTask = schemaTask({
id: "my-ai-task",
schema: z.object({
text: z.string(),
}),
run: async (payload, { ctx }) => {
const { text } = await generateText({
prompt: payload.text,
model: openai("gpt-4o"),
tools: {
myTool,
},
});
},
});
We've made several breaking changes that require code updates:
**Queue changes**: Queues must now be defined ahead of time using the `queue` function. You can no longer create queues "on-demand" when triggering tasks. This is the old version:
// Old v3 way - creating queue on-demand
await myTask.trigger({ foo: "bar" }, { queue: { name: "my-queue", concurrencyLimit: 10 } });
This is the new version:
// New v4 way - define queue first
import { queue, task } from "@trigger.dev/sdk";
const myQueue = queue({
name: "my-queue",
concurrencyLimit: 10,
});
export const myTask = task({
id: "my-task",
queue: myQueue, // Set queue on task
run: async (payload: any, { ctx }) => {},
});
// Now trigger without queue options
await myTask.trigger({ foo: "bar" });
// Or specify queue by name
await myTask.trigger({ foo: "bar" }, { queue: "my-queue" });
**Lifecycle hooks**: Function signatures have changed to use a single object parameter instead of separate parameters. Prefer `onStartAttempt` over the deprecated `onStart` when you need code to run before each attempt. This is the old version:
// Old v3 way
export const myTask = task({
id: "my-task",
onStart: (payload, { ctx }) => {},
onSuccess: (payload, output, { ctx }) => {},
onFailure: (payload, error, { ctx }) => {},
catchError: (payload, { ctx, error, retry }) => {},
run: async (payload, { ctx }) => {},
});
This is the new version:
// New v4 way - single object parameter for hooks
export const myTask = task({
id: "my-task",
onStartAttempt: ({ payload, ctx }) => {}, // prefer over deprecated onStart
onSuccess: ({ payload, ctx, task, output }) => {},
onFailure: ({ payload, ctx, task, error }) => {},
catchError: ({ payload, ctx, task, error, retry, retryAt, retryDelayInMs }) => {},
run: async (payload, { ctx }) => {}, // run function unchanged
});
**BatchTrigger changes**: The `batchTrigger` function no longer returns runs directly. This is the old version:
// Old v3 way
const batchHandle = await tasks.batchTrigger([
[myTask, { foo: "bar" }],
[myOtherTask, { baz: "qux" }],
]);
console.log(batchHandle.runs); // Direct access
This is the new version:
// New v4 way
const batchHandle = await tasks.batchTrigger([
[myTask, { foo: "bar" }],
[myOtherTask, { baz: "qux" }],
]);
const batch = await batch.retrieve(batchHandle.batchId); // Use batch.retrieve()
console.log(batch.runs);
**triggerAndWait / batchTriggerAndWait**: In v4 these return a Result object, not the raw output. Use `if (result.ok) { ... result.output }` or call `.unwrap()` to get the output (throws if the run failed). Do not wrap `triggerAndWait` or `batchTriggerAndWait` in `Promise.all` — this is not supported.
**Context (ctx) changes**: `ctx.attempt.id` and `ctx.attempt.status` have been removed; use `ctx.attempt.number` where needed. `ctx.task.exportName` has been removed.
Can you help me convert the following code from v3 to v4? Please include the full converted code in the answer, do not truncate it anywhere.
```
</Accordion>