Skip to content

Commit 9137dc4

Browse files
committed
Adds an upgrade to v4 using AI section
1 parent 34445d6 commit 9137dc4

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

docs/migrating-from-v3.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ description: "What's new in v4, how to migrate, and breaking changes."
44
---
55

66
import NodeVersions from "/snippets/node-versions.mdx";
7+
import MigrateV4UsingAi from "/snippets/migrate-v4-using-ai.mdx";
78

89
## What's new in v4?
910

@@ -47,6 +48,12 @@ Note that between steps 4 and 5, runs triggered with the v4 package will continu
4748
concurrency will return to normal.
4849
</Warning>
4950

51+
## Migrate using AI
52+
53+
Use the prompt in the accordion below to help you migrate your v3 tasks to v4. The prompt gives good results when using Claude 4 Sonnet. You’ll need a relatively large token limit.
54+
55+
<MigrateV4UsingAi />
56+
5057
## Installation
5158

5259
To opt-in to using v4, you will need to update your dependencies to the latest version:
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
<Accordion title="Copy paste this prompt in full" icon="sparkles">
2+
3+
I would like you to help me migrate my v3 task code to v4. Here are the important differences:
4+
5+
We've deprecated the `@trigger.dev/sdk/v3` import path and moved to a new path:
6+
7+
```ts
8+
// This is the old path
9+
import { task } from "@trigger.dev/sdk/v3";
10+
11+
// This is the new path, use this instead
12+
import { task } from "@trigger.dev/sdk";
13+
```
14+
15+
We've renamed the `handleError` hook to `catchError`. Use this instead of `handleError`.
16+
17+
`init` was previously used to initialize data used in the run function. This is the old version:
18+
19+
```ts
20+
import { task } from "@trigger.dev/sdk";
21+
22+
const myTask = task({
23+
init: async () => {
24+
return {
25+
myClient: new MyClient(),
26+
};
27+
},
28+
run: async (payload: any, { ctx, init }) => {
29+
const client = init.myClient;
30+
await client.doSomething();
31+
},
32+
});
33+
```
34+
35+
This is the new version using middleware and locals:
36+
37+
```ts
38+
import { task, locals, tasks } from "@trigger.dev/sdk";
39+
40+
// Create a local for your client
41+
const MyClientLocal = locals.create<MyClient>("myClient");
42+
43+
// Set up middleware to initialize the client
44+
tasks.middleware("my-client", async ({ next }) => {
45+
const client = new MyClient();
46+
locals.set(MyClientLocal, client);
47+
await next();
48+
});
49+
50+
// Helper function to get the client
51+
function getMyClient() {
52+
return locals.getOrThrow(MyClientLocal);
53+
}
54+
55+
const myTask = task({
56+
run: async (payload: any, { ctx }) => {
57+
const client = getMyClient();
58+
await client.doSomething();
59+
},
60+
});
61+
```
62+
63+
We’ve deprecated the `toolTask` function and replaced it with the `ai.tool` function, which creates an AI tool from an existing `schemaTask`. This is the old version:
64+
65+
```ts
66+
import { toolTask, schemaTask } from "@trigger.dev/sdk";
67+
import { z } from "zod";
68+
import { generateText } from "ai";
69+
70+
const myToolTask = toolTask({
71+
id: "my-tool-task",
72+
run: async (payload: any, { ctx }) => {},
73+
});
74+
75+
export const myAiTask = schemaTask({
76+
id: "my-ai-task",
77+
schema: z.object({
78+
text: z.string(),
79+
}),
80+
run: async (payload, { ctx }) => {
81+
const { text } = await generateText({
82+
prompt: payload.text,
83+
model: openai("gpt-4o"),
84+
tools: {
85+
myToolTask,
86+
},
87+
});
88+
},
89+
});
90+
```
91+
92+
This is the new version:
93+
94+
```ts
95+
import { schemaTask, ai } from "@trigger.dev/sdk";
96+
import { z } from "zod";
97+
import { generateText } from "ai";
98+
99+
// Convert toolTask to schemaTask with a schema
100+
const myToolTask = schemaTask({
101+
id: "my-tool-task",
102+
schema: z.object({
103+
// Add appropriate schema for your tool's payload
104+
input: z.string(),
105+
}),
106+
run: async (payload, { ctx }) => {},
107+
});
108+
109+
// Create an AI tool from the schemaTask
110+
const myTool = ai.tool(myToolTask);
111+
112+
export const myAiTask = schemaTask({
113+
id: "my-ai-task",
114+
schema: z.object({
115+
text: z.string(),
116+
}),
117+
run: async (payload, { ctx }) => {
118+
const { text } = await generateText({
119+
prompt: payload.text,
120+
model: openai("gpt-4o"),
121+
tools: {
122+
myTool, // Use the ai.tool created from schemaTask
123+
},
124+
});
125+
},
126+
});
127+
```
128+
129+
We've made several breaking changes that require code updates:
130+
131+
**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:
132+
133+
```ts
134+
// Old v3 way - creating queue on-demand
135+
await myTask.trigger({ foo: "bar" }, { queue: { name: "my-queue", concurrencyLimit: 10 } });
136+
```
137+
138+
This is the new version:
139+
140+
```ts
141+
// New v4 way - define queue first
142+
import { queue, task } from "@trigger.dev/sdk";
143+
144+
const myQueue = queue({
145+
name: "my-queue",
146+
concurrencyLimit: 10,
147+
});
148+
149+
export const myTask = task({
150+
id: "my-task",
151+
queue: myQueue, // Set queue on task
152+
run: async (payload: any, { ctx }) => {},
153+
});
154+
155+
// Now trigger without queue options
156+
await myTask.trigger({ foo: "bar" });
157+
158+
// Or specify queue by name
159+
await myTask.trigger({ foo: "bar" }, { queue: "my-queue" });
160+
```
161+
162+
**Lifecycle hooks**: Function signatures have changed to use a single object parameter instead of separate parameters. This is the old version:
163+
164+
```ts
165+
// Old v3 way
166+
export const myTask = task({
167+
id: "my-task",
168+
onStart: (payload, { ctx }) => {},
169+
onSuccess: (payload, output, { ctx }) => {},
170+
onFailure: (payload, error, { ctx }) => {},
171+
catchError: (payload, { ctx, error, retry }) => {},
172+
run: async (payload, { ctx }) => {},
173+
});
174+
```
175+
176+
This is the new version:
177+
178+
```ts
179+
// New v4 way - single object parameter for hooks
180+
export const myTask = task({
181+
id: "my-task",
182+
onStart: ({ payload, ctx }) => {},
183+
onSuccess: ({ payload, output, ctx }) => {},
184+
onFailure: ({ payload, error, ctx }) => {},
185+
catchError: ({ payload, ctx, error, retry }) => {},
186+
run: async (payload, { ctx }) => {}, // run function unchanged
187+
});
188+
```
189+
190+
**BatchTrigger changes**: The `batchTrigger` function no longer returns runs directly. This is the old version:
191+
192+
```ts
193+
// Old v3 way
194+
const batchHandle = await tasks.batchTrigger([
195+
[myTask, { foo: "bar" }],
196+
[myOtherTask, { baz: "qux" }],
197+
]);
198+
199+
console.log(batchHandle.runs); // Direct access
200+
```
201+
202+
This is the new version:
203+
204+
```ts
205+
// New v4 way
206+
const batchHandle = await tasks.batchTrigger([
207+
[myTask, { foo: "bar" }],
208+
[myOtherTask, { baz: "qux" }],
209+
]);
210+
211+
const runs = await batchHandle.runs.list(); // Use runs.list()
212+
console.log(runs);
213+
```
214+
215+
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.
216+
217+
</Accordion>

0 commit comments

Comments
 (0)