You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
1124
1124
1125
+
When a subtask is invoked via `ai.tool()`, initialized locals are automatically serialized into the subtask's metadata and hydrated on first access — no extra code needed. Subtask changes to hydrated locals are local to the subtask and don't propagate back to the parent.
1126
+
1125
1127
### Declaring and initializing
1126
1128
1127
-
Declare locals at module level, then initialize them inside a lifecycle hook where you have context (chatId, clientData, etc.):
1129
+
Declare locals at module level with a unique `id`, then initialize them inside a lifecycle hook where you have context (chatId, clientData, etc.):
1128
1130
1129
1131
```ts
1130
1132
import { chat } from"@trigger.dev/sdk/ai";
@@ -1133,12 +1135,12 @@ import { openai } from "@ai-sdk/openai";
1133
1135
import { z } from"zod";
1134
1136
import { db } from"@/lib/db";
1135
1137
1136
-
// Declare at module level — multiple locals can coexist
1138
+
// Declare at module level — each local needs a unique id
// userContext.name just works — auto-hydrated from parent metadata
1209
+
console.log(`Analyzing for ${userContext.name}`);
1210
+
// Changes here are local to this subtask and don't propagate back
1211
+
},
1212
+
});
1213
+
1214
+
exportconst myChat =chat.task({
1215
+
id: "my-chat",
1216
+
onChatStart: async ({ clientData }) => {
1217
+
userContext.init({ name: "Alice", plan: "pro" });
1218
+
},
1219
+
run: async ({ messages, signal }) => {
1220
+
returnstreamText({
1221
+
model: openai("gpt-4o"),
1222
+
messages,
1223
+
tools: { analyzeData: ai.tool(analyzeData) },
1224
+
abortSignal: signal,
1225
+
});
1226
+
},
1227
+
});
1228
+
```
1229
+
1230
+
<Note>
1231
+
Values must be JSON-serializable for subtask access. Non-serializable values (functions, class instances, etc.) will be lost during transfer.
1232
+
</Note>
1233
+
1189
1234
### Dirty tracking and persistence
1190
1235
1191
1236
The `hasChanged()` method returns `true` if any property was set since the last check, then resets the flag. Use it in lifecycle hooks to only persist when data actually changed:
0 commit comments