@trigger.dev/sdk 0.0.0-prerelease-20260302145933 → 0.0.0-prerelease-20260305142821

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/commonjs/v3/ai.d.ts +347 -2
  2. package/dist/commonjs/v3/ai.js +563 -1
  3. package/dist/commonjs/v3/ai.js.map +1 -1
  4. package/dist/commonjs/v3/chat-constants.d.ts +10 -0
  5. package/dist/commonjs/v3/chat-constants.js +14 -0
  6. package/dist/commonjs/v3/chat-constants.js.map +1 -0
  7. package/dist/commonjs/v3/chat-react.d.ts +45 -0
  8. package/dist/commonjs/v3/chat-react.js +71 -0
  9. package/dist/commonjs/v3/chat-react.js.map +1 -0
  10. package/dist/commonjs/v3/chat.d.ts +241 -0
  11. package/dist/commonjs/v3/chat.js +343 -0
  12. package/dist/commonjs/v3/chat.js.map +1 -0
  13. package/dist/commonjs/v3/chat.test.d.ts +1 -0
  14. package/dist/commonjs/v3/chat.test.js +1557 -0
  15. package/dist/commonjs/v3/chat.test.js.map +1 -0
  16. package/dist/commonjs/v3/runs.d.ts +3 -3
  17. package/dist/commonjs/v3/streams.js +27 -17
  18. package/dist/commonjs/v3/streams.js.map +1 -1
  19. package/dist/commonjs/version.js +1 -1
  20. package/dist/esm/v3/ai.d.ts +347 -2
  21. package/dist/esm/v3/ai.js +564 -2
  22. package/dist/esm/v3/ai.js.map +1 -1
  23. package/dist/esm/v3/chat-constants.d.ts +10 -0
  24. package/dist/esm/v3/chat-constants.js +11 -0
  25. package/dist/esm/v3/chat-constants.js.map +1 -0
  26. package/dist/esm/v3/chat-react.d.ts +45 -0
  27. package/dist/esm/v3/chat-react.js +68 -0
  28. package/dist/esm/v3/chat-react.js.map +1 -0
  29. package/dist/esm/v3/chat.d.ts +241 -0
  30. package/dist/esm/v3/chat.js +338 -0
  31. package/dist/esm/v3/chat.js.map +1 -0
  32. package/dist/esm/v3/chat.test.d.ts +1 -0
  33. package/dist/esm/v3/chat.test.js +1555 -0
  34. package/dist/esm/v3/chat.test.js.map +1 -0
  35. package/dist/esm/v3/streams.js +27 -17
  36. package/dist/esm/v3/streams.js.map +1 -1
  37. package/dist/esm/version.js +1 -1
  38. package/package.json +40 -5
@@ -1,5 +1,7 @@
1
- import { Task, type inferSchemaIn, type TaskSchema, type TaskWithSchema } from "@trigger.dev/core/v3";
1
+ import { AnyTask, Task, type inferSchemaIn, type TaskIdentifier, type TaskOptions, type TaskSchema, type TaskWithSchema } from "@trigger.dev/core/v3";
2
+ import type { ModelMessage, UIMessage } from "ai";
2
3
  import { Tool, ToolCallOptions } from "ai";
4
+ import { CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID } from "./chat-constants.js";
3
5
  export type ToolCallExecutionOptions = Omit<ToolCallOptions, "abortSignal">;
4
6
  type ToolResultContent = Array<{
5
7
  type: "text";
@@ -19,4 +21,347 @@ export declare const ai: {
19
21
  tool: typeof toolFromTask;
20
22
  currentToolOptions: typeof getToolOptionsFromMetadata;
21
23
  };
22
- export {};
24
+ /**
25
+ * Creates a public access token for a chat task.
26
+ *
27
+ * This is a convenience helper that creates a multi-use trigger public token
28
+ * scoped to the given task. Use it in a server action to provide the frontend
29
+ * `TriggerChatTransport` with an `accessToken`.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // actions.ts
34
+ * "use server";
35
+ * import { chat } from "@trigger.dev/sdk/ai";
36
+ * import type { myChat } from "@/trigger/chat";
37
+ *
38
+ * export const getChatToken = () => chat.createAccessToken<typeof myChat>("my-chat");
39
+ * ```
40
+ */
41
+ declare function createChatAccessToken<TTask extends AnyTask>(taskId: TaskIdentifier<TTask>): Promise<string>;
42
+ /**
43
+ * The default stream key used for chat transport communication.
44
+ * Both `TriggerChatTransport` (frontend) and `pipeChat`/`chatTask` (backend)
45
+ * use this key by default.
46
+ */
47
+ export declare const CHAT_STREAM_KEY = "chat";
48
+ export { CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID };
49
+ /**
50
+ * The payload shape passed to the `chatTask` run function.
51
+ *
52
+ * - `messages` contains model-ready messages (converted via `convertToModelMessages`) —
53
+ * pass these directly to `streamText`.
54
+ * - `clientData` contains custom data from the frontend (the `metadata` field from `sendMessage()`).
55
+ *
56
+ * The backend accumulates the full conversation history across turns, so the frontend
57
+ * only needs to send new messages after the first turn.
58
+ */
59
+ export type ChatTaskPayload = {
60
+ /** Model-ready messages — pass directly to `streamText({ messages })`. */
61
+ messages: ModelMessage[];
62
+ /** The unique identifier for the chat session */
63
+ chatId: string;
64
+ /**
65
+ * The trigger type:
66
+ * - `"submit-message"`: A new user message
67
+ * - `"regenerate-message"`: Regenerate the last assistant response
68
+ */
69
+ trigger: "submit-message" | "regenerate-message";
70
+ /** The ID of the message to regenerate (only for `"regenerate-message"`) */
71
+ messageId?: string;
72
+ /** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
73
+ clientData?: unknown;
74
+ };
75
+ /**
76
+ * Abort signals provided to the `chatTask` run function.
77
+ */
78
+ export type ChatTaskSignals = {
79
+ /** Combined signal — fires on run cancel OR stop generation. Pass to `streamText`. */
80
+ signal: AbortSignal;
81
+ /** Fires only when the run is cancelled, expired, or exceeds maxDuration. */
82
+ cancelSignal: AbortSignal;
83
+ /** Fires only when the frontend stops generation for this turn (per-turn, reset each turn). */
84
+ stopSignal: AbortSignal;
85
+ };
86
+ /**
87
+ * The full payload passed to a `chatTask` run function.
88
+ * Extends `ChatTaskPayload` (the wire payload) with abort signals.
89
+ */
90
+ export type ChatTaskRunPayload = ChatTaskPayload & ChatTaskSignals;
91
+ /**
92
+ * Options for `pipeChat`.
93
+ */
94
+ export type PipeChatOptions = {
95
+ /**
96
+ * Override the stream key. Must match the `streamKey` on `TriggerChatTransport`.
97
+ * @default "chat"
98
+ */
99
+ streamKey?: string;
100
+ /** An AbortSignal to cancel the stream. */
101
+ signal?: AbortSignal;
102
+ /**
103
+ * The target run ID to pipe to.
104
+ * @default "self" (current run)
105
+ */
106
+ target?: string;
107
+ /** Override the default span name for this operation. */
108
+ spanName?: string;
109
+ };
110
+ /**
111
+ * An object with a `toUIMessageStream()` method (e.g. `StreamTextResult` from `streamText()`).
112
+ */
113
+ type UIMessageStreamable = {
114
+ toUIMessageStream: (...args: any[]) => AsyncIterable<unknown> | ReadableStream<unknown>;
115
+ };
116
+ /**
117
+ * Pipes a chat stream to the realtime stream, making it available to the
118
+ * `TriggerChatTransport` on the frontend.
119
+ *
120
+ * Accepts:
121
+ * - A `StreamTextResult` from `streamText()` (has `.toUIMessageStream()`)
122
+ * - An `AsyncIterable` of `UIMessageChunk`s
123
+ * - A `ReadableStream` of `UIMessageChunk`s
124
+ *
125
+ * Must be called from inside a Trigger.dev task's `run` function.
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * import { task } from "@trigger.dev/sdk";
130
+ * import { chat, type ChatTaskPayload } from "@trigger.dev/sdk/ai";
131
+ * import { streamText, convertToModelMessages } from "ai";
132
+ *
133
+ * export const myChatTask = task({
134
+ * id: "my-chat-task",
135
+ * run: async (payload: ChatTaskPayload) => {
136
+ * const result = streamText({
137
+ * model: openai("gpt-4o"),
138
+ * messages: payload.messages,
139
+ * });
140
+ *
141
+ * await chat.pipe(result);
142
+ * },
143
+ * });
144
+ * ```
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * // Works from anywhere inside a task — even deep in your agent code
149
+ * async function runAgentLoop(messages: CoreMessage[]) {
150
+ * const result = streamText({ model, messages });
151
+ * await chat.pipe(result);
152
+ * }
153
+ * ```
154
+ */
155
+ declare function pipeChat(source: UIMessageStreamable | AsyncIterable<unknown> | ReadableStream<unknown>, options?: PipeChatOptions): Promise<void>;
156
+ /**
157
+ * Options for defining a chat task.
158
+ *
159
+ * Extends the standard `TaskOptions` but pre-types the payload as `ChatTaskPayload`
160
+ * and overrides `run` to accept `ChatTaskRunPayload` (with abort signals).
161
+ *
162
+ * **Auto-piping:** If the `run` function returns a value with `.toUIMessageStream()`
163
+ * (like a `StreamTextResult`), the stream is automatically piped to the frontend.
164
+ *
165
+ * **Single-run mode:** By default, the task uses input streams so that the
166
+ * entire conversation lives inside one run. After each AI response, the task
167
+ * emits a control chunk and suspends via `messagesInput.wait()`. The frontend
168
+ * transport resumes the same run by sending the next message via input streams.
169
+ */
170
+ /**
171
+ * Event passed to the `onChatStart` callback.
172
+ */
173
+ export type ChatStartEvent = {
174
+ /** The unique identifier for the chat session. */
175
+ chatId: string;
176
+ /** The initial model-ready messages for this conversation. */
177
+ messages: ModelMessage[];
178
+ /** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
179
+ clientData: unknown;
180
+ };
181
+ /**
182
+ * Event passed to the `onTurnComplete` callback.
183
+ */
184
+ export type TurnCompleteEvent = {
185
+ /** The unique identifier for the chat session. */
186
+ chatId: string;
187
+ /** The full accumulated conversation in model format (all turns so far). */
188
+ messages: ModelMessage[];
189
+ /**
190
+ * The full accumulated conversation in UI format (all turns so far).
191
+ * This is the format expected by `useChat` — store this for persistence.
192
+ */
193
+ uiMessages: UIMessage[];
194
+ /**
195
+ * Only the new model messages from this turn (user message(s) + assistant response).
196
+ * Useful for appending to an existing conversation record.
197
+ */
198
+ newMessages: ModelMessage[];
199
+ /**
200
+ * Only the new UI messages from this turn (user message(s) + assistant response).
201
+ * Useful for inserting individual message records instead of overwriting the full history.
202
+ */
203
+ newUIMessages: UIMessage[];
204
+ /** The assistant's response for this turn (undefined if `pipeChat` was used manually). */
205
+ responseMessage: UIMessage | undefined;
206
+ /** The turn number (0-indexed). */
207
+ turn: number;
208
+ };
209
+ export type ChatTaskOptions<TIdentifier extends string> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload, unknown>, "run"> & {
210
+ /**
211
+ * The run function for the chat task.
212
+ *
213
+ * Receives a `ChatTaskRunPayload` with the conversation messages, chat session ID,
214
+ * trigger type, and abort signals (`signal`, `cancelSignal`, `stopSignal`).
215
+ *
216
+ * **Auto-piping:** If this function returns a value with `.toUIMessageStream()`,
217
+ * the stream is automatically piped to the frontend.
218
+ */
219
+ run: (payload: ChatTaskRunPayload) => Promise<unknown>;
220
+ /**
221
+ * Called on the first turn (turn 0) of a new run, before the `run` function executes.
222
+ *
223
+ * Use this to create the chat record in your database when a new conversation starts.
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * onChatStart: async ({ chatId, messages, clientData }) => {
228
+ * await db.chat.create({ data: { id: chatId, userId: clientData.userId } });
229
+ * }
230
+ * ```
231
+ */
232
+ onChatStart?: (event: ChatStartEvent) => Promise<void> | void;
233
+ /**
234
+ * Called after each turn completes (after the response is captured, before waiting
235
+ * for the next message). Also fires on the final turn.
236
+ *
237
+ * Use this to persist the conversation to your database after each assistant response.
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * onTurnComplete: async ({ chatId, messages }) => {
242
+ * await db.chat.update({ where: { id: chatId }, data: { messages } });
243
+ * }
244
+ * ```
245
+ */
246
+ onTurnComplete?: (event: TurnCompleteEvent) => Promise<void> | void;
247
+ /**
248
+ * Maximum number of conversational turns (message round-trips) a single run
249
+ * will handle before ending. After this many turns the run completes
250
+ * normally and the next message will start a fresh run.
251
+ *
252
+ * @default 100
253
+ */
254
+ maxTurns?: number;
255
+ /**
256
+ * How long to wait for the next message before timing out and ending the run.
257
+ * Accepts any duration string (e.g. `"1h"`, `"30m"`).
258
+ *
259
+ * @default "1h"
260
+ */
261
+ turnTimeout?: string;
262
+ /**
263
+ * How long (in seconds) to keep the run warm after each turn before suspending.
264
+ * During this window the run stays active and can respond instantly to the
265
+ * next message. After this timeout, the run suspends (frees compute) and waits
266
+ * via `inputStream.wait()`.
267
+ *
268
+ * Set to `0` to suspend immediately after each turn.
269
+ *
270
+ * @default 30
271
+ */
272
+ warmTimeoutInSeconds?: number;
273
+ };
274
+ /**
275
+ * Creates a Trigger.dev task pre-configured for AI SDK chat.
276
+ *
277
+ * - **Pre-types the payload** as `ChatTaskRunPayload` — includes abort signals
278
+ * - **Auto-pipes the stream** if `run` returns a `StreamTextResult`
279
+ * - **Multi-turn**: keeps the conversation in a single run using input streams
280
+ * - **Stop support**: frontend can stop generation mid-stream via the stop input stream
281
+ * - For complex flows, use `pipeChat()` from anywhere inside your task code
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * import { chat } from "@trigger.dev/sdk/ai";
286
+ * import { streamText, convertToModelMessages } from "ai";
287
+ * import { openai } from "@ai-sdk/openai";
288
+ *
289
+ * export const myChat = chat.task({
290
+ * id: "my-chat",
291
+ * run: async ({ messages, signal }) => {
292
+ * return streamText({
293
+ * model: openai("gpt-4o"),
294
+ * messages, // already converted via convertToModelMessages
295
+ * abortSignal: signal,
296
+ * });
297
+ * },
298
+ * });
299
+ * ```
300
+ */
301
+ declare function chatTask<TIdentifier extends string>(options: ChatTaskOptions<TIdentifier>): Task<TIdentifier, ChatTaskWirePayload, unknown>;
302
+ /**
303
+ * Override the turn timeout for subsequent turns in the current run.
304
+ *
305
+ * The turn timeout controls how long the run stays suspended (freeing compute)
306
+ * waiting for the next user message. When it expires, the run completes
307
+ * gracefully and the next message starts a fresh run.
308
+ *
309
+ * Call from inside a `chatTask` run function to adjust based on context.
310
+ *
311
+ * @param duration - A duration string (e.g. `"5m"`, `"1h"`, `"30s"`)
312
+ *
313
+ * @example
314
+ * ```ts
315
+ * run: async ({ messages, signal }) => {
316
+ * chat.setTurnTimeout("2h");
317
+ * return streamText({ model, messages, abortSignal: signal });
318
+ * }
319
+ * ```
320
+ */
321
+ declare function setTurnTimeout(duration: string): void;
322
+ /**
323
+ * Override the turn timeout in seconds for subsequent turns in the current run.
324
+ *
325
+ * @param seconds - Number of seconds to wait for the next message before ending the run
326
+ *
327
+ * @example
328
+ * ```ts
329
+ * run: async ({ messages, signal }) => {
330
+ * chat.setTurnTimeoutInSeconds(3600); // 1 hour
331
+ * return streamText({ model, messages, abortSignal: signal });
332
+ * }
333
+ * ```
334
+ */
335
+ declare function setTurnTimeoutInSeconds(seconds: number): void;
336
+ /**
337
+ * Override the warm timeout for subsequent turns in the current run.
338
+ *
339
+ * The warm timeout controls how long the run stays active (using compute)
340
+ * after each turn, waiting for the next message. During this window,
341
+ * responses are instant. After it expires, the run suspends.
342
+ *
343
+ * @param seconds - Number of seconds to stay warm (0 to suspend immediately)
344
+ *
345
+ * @example
346
+ * ```ts
347
+ * run: async ({ messages, signal }) => {
348
+ * chat.setWarmTimeoutInSeconds(60);
349
+ * return streamText({ model, messages, abortSignal: signal });
350
+ * }
351
+ * ```
352
+ */
353
+ declare function setWarmTimeoutInSeconds(seconds: number): void;
354
+ export declare const chat: {
355
+ /** Create a chat task. See {@link chatTask}. */
356
+ task: typeof chatTask;
357
+ /** Pipe a stream to the chat transport. See {@link pipeChat}. */
358
+ pipe: typeof pipeChat;
359
+ /** Create a public access token for a chat task. See {@link createChatAccessToken}. */
360
+ createAccessToken: typeof createChatAccessToken;
361
+ /** Override the turn timeout at runtime (duration string). See {@link setTurnTimeout}. */
362
+ setTurnTimeout: typeof setTurnTimeout;
363
+ /** Override the turn timeout at runtime (seconds). See {@link setTurnTimeoutInSeconds}. */
364
+ setTurnTimeoutInSeconds: typeof setTurnTimeoutInSeconds;
365
+ /** Override the warm timeout at runtime. See {@link setWarmTimeoutInSeconds}. */
366
+ setWarmTimeoutInSeconds: typeof setWarmTimeoutInSeconds;
367
+ };