@trigger.dev/sdk 0.0.0-prerelease-20260306173130 → 0.0.0-prerelease-20260309160514
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.
- package/dist/commonjs/v3/ai.d.ts +230 -8
- package/dist/commonjs/v3/ai.js +464 -23
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +13 -0
- package/dist/commonjs/v3/chat.js +59 -1
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai.d.ts +230 -8
- package/dist/esm/v3/ai.js +464 -23
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +13 -0
- package/dist/esm/v3/chat.js +59 -1
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +2 -2
package/dist/commonjs/v3/ai.d.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { AnyTask, Task, type inferSchemaIn, type inferSchemaOut, type TaskIdentifier, type TaskOptions, type TaskSchema, type TaskWithSchema } from "@trigger.dev/core/v3";
|
|
2
|
-
import type { ModelMessage, UIMessage } from "ai";
|
|
3
|
-
import { Tool
|
|
2
|
+
import type { ModelMessage, UIMessage, UIMessageChunk } from "ai";
|
|
3
|
+
import { Tool } from "ai";
|
|
4
4
|
import { locals } from "./locals.js";
|
|
5
5
|
import { CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID } from "./chat-constants.js";
|
|
6
|
-
export type ToolCallExecutionOptions =
|
|
6
|
+
export type ToolCallExecutionOptions = {
|
|
7
|
+
toolCallId: string;
|
|
8
|
+
experimental_context?: unknown;
|
|
9
|
+
/** Chat context — only present when the tool runs inside a chat.task turn. */
|
|
10
|
+
chatId?: string;
|
|
11
|
+
turn?: number;
|
|
12
|
+
continuation?: boolean;
|
|
13
|
+
clientData?: unknown;
|
|
14
|
+
};
|
|
15
|
+
/** Chat context stored in locals during each chat.task turn for auto-detection. */
|
|
16
|
+
type ChatTurnContext<TClientData = unknown> = {
|
|
17
|
+
chatId: string;
|
|
18
|
+
turn: number;
|
|
19
|
+
continuation: boolean;
|
|
20
|
+
clientData?: TClientData;
|
|
21
|
+
};
|
|
7
22
|
type ToolResultContent = Array<{
|
|
8
23
|
type: "text";
|
|
9
24
|
text: string;
|
|
@@ -18,9 +33,43 @@ export type ToolOptions<TResult> = {
|
|
|
18
33
|
declare function toolFromTask<TIdentifier extends string, TInput = void, TOutput = unknown>(task: Task<TIdentifier, TInput, TOutput>, options?: ToolOptions<TOutput>): Tool<TInput, TOutput>;
|
|
19
34
|
declare function toolFromTask<TIdentifier extends string, TTaskSchema extends TaskSchema | undefined = undefined, TOutput = unknown>(task: TaskWithSchema<TIdentifier, TTaskSchema, TOutput>, options?: ToolOptions<TOutput>): Tool<inferSchemaIn<TTaskSchema>, TOutput>;
|
|
20
35
|
declare function getToolOptionsFromMetadata(): ToolCallExecutionOptions | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Get the current tool call ID from inside a subtask invoked via `ai.tool()`.
|
|
38
|
+
* Returns `undefined` if not running as a tool subtask.
|
|
39
|
+
*/
|
|
40
|
+
declare function getToolCallId(): string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Get the chat context from inside a subtask invoked via `ai.tool()` within a `chat.task`.
|
|
43
|
+
* Pass `typeof yourChatTask` as the type parameter to get typed `clientData`.
|
|
44
|
+
* Returns `undefined` if the parent is not a chat task.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const ctx = ai.chatContext<typeof myChat>();
|
|
49
|
+
* // ctx?.clientData is typed based on myChat's clientDataSchema
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare function getToolChatContext<TChatTask extends AnyTask = AnyTask>(): ChatTurnContext<InferChatClientData<TChatTask>> | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Get the chat context from inside a subtask, throwing if not in a chat context.
|
|
55
|
+
* Pass `typeof yourChatTask` as the type parameter to get typed `clientData`.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const ctx = ai.chatContextOrThrow<typeof myChat>();
|
|
60
|
+
* // ctx.chatId, ctx.clientData are guaranteed non-null
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare function getToolChatContextOrThrow<TChatTask extends AnyTask = AnyTask>(): ChatTurnContext<InferChatClientData<TChatTask>>;
|
|
21
64
|
export declare const ai: {
|
|
22
65
|
tool: typeof toolFromTask;
|
|
23
66
|
currentToolOptions: typeof getToolOptionsFromMetadata;
|
|
67
|
+
/** Get the tool call ID from inside a subtask invoked via `ai.tool()`. */
|
|
68
|
+
toolCallId: typeof getToolCallId;
|
|
69
|
+
/** Get chat context (chatId, turn, clientData, etc.) from inside a subtask of a `chat.task`. Returns undefined if not in a chat context. */
|
|
70
|
+
chatContext: typeof getToolChatContext;
|
|
71
|
+
/** Get chat context or throw if not in a chat context. Pass `typeof yourChatTask` for typed clientData. */
|
|
72
|
+
chatContextOrThrow: typeof getToolChatContextOrThrow;
|
|
24
73
|
};
|
|
25
74
|
/**
|
|
26
75
|
* Creates a public access token for a chat task.
|
|
@@ -47,6 +96,21 @@ declare function createChatAccessToken<TTask extends AnyTask>(taskId: TaskIdenti
|
|
|
47
96
|
*/
|
|
48
97
|
export declare const CHAT_STREAM_KEY = "chat";
|
|
49
98
|
export { CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID };
|
|
99
|
+
/**
|
|
100
|
+
* The wire payload shape sent by `TriggerChatTransport`.
|
|
101
|
+
* Uses `metadata` to match the AI SDK's `ChatRequestOptions` field name.
|
|
102
|
+
*/
|
|
103
|
+
export type ChatTaskWirePayload<TMessage extends UIMessage = UIMessage, TMetadata = unknown> = {
|
|
104
|
+
messages: TMessage[];
|
|
105
|
+
chatId: string;
|
|
106
|
+
trigger: "submit-message" | "regenerate-message" | "preload";
|
|
107
|
+
messageId?: string;
|
|
108
|
+
metadata?: TMetadata;
|
|
109
|
+
/** Whether this run is continuing an existing chat whose previous run ended. */
|
|
110
|
+
continuation?: boolean;
|
|
111
|
+
/** The run ID of the previous run (only set when `continuation` is true). */
|
|
112
|
+
previousRunId?: string;
|
|
113
|
+
};
|
|
50
114
|
/**
|
|
51
115
|
* The payload shape passed to the `chatTask` run function.
|
|
52
116
|
*
|
|
@@ -66,12 +130,19 @@ export type ChatTaskPayload<TClientData = unknown> = {
|
|
|
66
130
|
* The trigger type:
|
|
67
131
|
* - `"submit-message"`: A new user message
|
|
68
132
|
* - `"regenerate-message"`: Regenerate the last assistant response
|
|
133
|
+
* - `"preload"`: Run was preloaded before the first message (only on turn 0)
|
|
69
134
|
*/
|
|
70
|
-
trigger: "submit-message" | "regenerate-message";
|
|
135
|
+
trigger: "submit-message" | "regenerate-message" | "preload";
|
|
71
136
|
/** The ID of the message to regenerate (only for `"regenerate-message"`) */
|
|
72
137
|
messageId?: string;
|
|
73
138
|
/** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
|
|
74
139
|
clientData?: TClientData;
|
|
140
|
+
/** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
|
|
141
|
+
continuation: boolean;
|
|
142
|
+
/** The run ID of the previous run (only set when `continuation` is true). */
|
|
143
|
+
previousRunId?: string;
|
|
144
|
+
/** Whether this run was preloaded before the first message. */
|
|
145
|
+
preloaded: boolean;
|
|
75
146
|
};
|
|
76
147
|
/**
|
|
77
148
|
* Abort signals provided to the `chatTask` run function.
|
|
@@ -168,6 +239,19 @@ declare function pipeChat(source: UIMessageStreamable | AsyncIterable<unknown> |
|
|
|
168
239
|
* emits a control chunk and suspends via `messagesInput.wait()`. The frontend
|
|
169
240
|
* transport resumes the same run by sending the next message via input streams.
|
|
170
241
|
*/
|
|
242
|
+
/**
|
|
243
|
+
* Event passed to the `onPreload` callback.
|
|
244
|
+
*/
|
|
245
|
+
export type PreloadEvent<TClientData = unknown> = {
|
|
246
|
+
/** The unique identifier for the chat session. */
|
|
247
|
+
chatId: string;
|
|
248
|
+
/** The Trigger.dev run ID for this conversation. */
|
|
249
|
+
runId: string;
|
|
250
|
+
/** A scoped access token for this chat run. */
|
|
251
|
+
chatAccessToken: string;
|
|
252
|
+
/** Custom data from the frontend. */
|
|
253
|
+
clientData?: TClientData;
|
|
254
|
+
};
|
|
171
255
|
/**
|
|
172
256
|
* Event passed to the `onChatStart` callback.
|
|
173
257
|
*/
|
|
@@ -182,6 +266,12 @@ export type ChatStartEvent<TClientData = unknown> = {
|
|
|
182
266
|
runId: string;
|
|
183
267
|
/** A scoped access token for this chat run. Persist this for frontend reconnection. */
|
|
184
268
|
chatAccessToken: string;
|
|
269
|
+
/** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
|
|
270
|
+
continuation: boolean;
|
|
271
|
+
/** The run ID of the previous run (only set when `continuation` is true). */
|
|
272
|
+
previousRunId?: string;
|
|
273
|
+
/** Whether this run was preloaded before the first message. */
|
|
274
|
+
preloaded: boolean;
|
|
185
275
|
};
|
|
186
276
|
/**
|
|
187
277
|
* Event passed to the `onTurnStart` callback.
|
|
@@ -201,6 +291,12 @@ export type TurnStartEvent<TClientData = unknown> = {
|
|
|
201
291
|
chatAccessToken: string;
|
|
202
292
|
/** Custom data from the frontend. */
|
|
203
293
|
clientData?: TClientData;
|
|
294
|
+
/** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
|
|
295
|
+
continuation: boolean;
|
|
296
|
+
/** The run ID of the previous run (only set when `continuation` is true). */
|
|
297
|
+
previousRunId?: string;
|
|
298
|
+
/** Whether this run was preloaded before the first message. */
|
|
299
|
+
preloaded: boolean;
|
|
204
300
|
};
|
|
205
301
|
/**
|
|
206
302
|
* Event passed to the `onTurnComplete` callback.
|
|
@@ -225,8 +321,14 @@ export type TurnCompleteEvent<TClientData = unknown> = {
|
|
|
225
321
|
* Useful for inserting individual message records instead of overwriting the full history.
|
|
226
322
|
*/
|
|
227
323
|
newUIMessages: UIMessage[];
|
|
228
|
-
/** The assistant's response for this turn
|
|
324
|
+
/** The assistant's response for this turn, with aborted parts cleaned up when `stopped` is true. Undefined if `pipeChat` was used manually. */
|
|
229
325
|
responseMessage: UIMessage | undefined;
|
|
326
|
+
/**
|
|
327
|
+
* The raw assistant response before abort cleanup. Includes incomplete tool parts
|
|
328
|
+
* (`input-available`, `partial-call`) and streaming reasoning/text parts.
|
|
329
|
+
* Use this if you need custom cleanup logic. Same as `responseMessage` when not stopped.
|
|
330
|
+
*/
|
|
331
|
+
rawResponseMessage: UIMessage | undefined;
|
|
230
332
|
/** The turn number (0-indexed). */
|
|
231
333
|
turn: number;
|
|
232
334
|
/** The Trigger.dev run ID for this conversation. */
|
|
@@ -237,6 +339,14 @@ export type TurnCompleteEvent<TClientData = unknown> = {
|
|
|
237
339
|
lastEventId?: string;
|
|
238
340
|
/** Custom data from the frontend. */
|
|
239
341
|
clientData?: TClientData;
|
|
342
|
+
/** Whether the user stopped generation during this turn. */
|
|
343
|
+
stopped: boolean;
|
|
344
|
+
/** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
|
|
345
|
+
continuation: boolean;
|
|
346
|
+
/** The run ID of the previous run (only set when `continuation` is true). */
|
|
347
|
+
previousRunId?: string;
|
|
348
|
+
/** Whether this run was preloaded before the first message. */
|
|
349
|
+
preloaded: boolean;
|
|
240
350
|
};
|
|
241
351
|
export type ChatTaskOptions<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload, unknown>, "run"> & {
|
|
242
352
|
/**
|
|
@@ -268,6 +378,21 @@ export type ChatTaskOptions<TIdentifier extends string, TClientDataSchema extend
|
|
|
268
378
|
* the stream is automatically piped to the frontend.
|
|
269
379
|
*/
|
|
270
380
|
run: (payload: ChatTaskRunPayload<inferSchemaOut<TClientDataSchema>>) => Promise<unknown>;
|
|
381
|
+
/**
|
|
382
|
+
* Called when a preloaded run starts, before the first message arrives.
|
|
383
|
+
*
|
|
384
|
+
* Use this to initialize state, create DB records, and load context early —
|
|
385
|
+
* so everything is ready when the user's first message comes through.
|
|
386
|
+
*
|
|
387
|
+
* @example
|
|
388
|
+
* ```ts
|
|
389
|
+
* onPreload: async ({ chatId, clientData }) => {
|
|
390
|
+
* await db.chat.create({ data: { id: chatId } });
|
|
391
|
+
* userContext.init(await loadUser(clientData.userId));
|
|
392
|
+
* }
|
|
393
|
+
* ```
|
|
394
|
+
*/
|
|
395
|
+
onPreload?: (event: PreloadEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void;
|
|
271
396
|
/**
|
|
272
397
|
* Called on the first turn (turn 0) of a new run, before the `run` function executes.
|
|
273
398
|
*
|
|
@@ -346,6 +471,24 @@ export type ChatTaskOptions<TIdentifier extends string, TClientDataSchema extend
|
|
|
346
471
|
* @default "1h"
|
|
347
472
|
*/
|
|
348
473
|
chatAccessTokenTTL?: string;
|
|
474
|
+
/**
|
|
475
|
+
* How long (in seconds) to keep the run warm after `onPreload` fires,
|
|
476
|
+
* waiting for the first message before suspending.
|
|
477
|
+
*
|
|
478
|
+
* Only applies to preloaded runs (triggered via `transport.preload()`).
|
|
479
|
+
*
|
|
480
|
+
* @default Same as `warmTimeoutInSeconds`
|
|
481
|
+
*/
|
|
482
|
+
preloadWarmTimeoutInSeconds?: number;
|
|
483
|
+
/**
|
|
484
|
+
* How long to wait (suspended) for the first message after a preloaded run starts.
|
|
485
|
+
* If no message arrives within this time, the run ends.
|
|
486
|
+
*
|
|
487
|
+
* Only applies to preloaded runs.
|
|
488
|
+
*
|
|
489
|
+
* @default Same as `turnTimeout`
|
|
490
|
+
*/
|
|
491
|
+
preloadTimeout?: string;
|
|
349
492
|
};
|
|
350
493
|
/**
|
|
351
494
|
* Creates a Trigger.dev task pre-configured for AI SDK chat.
|
|
@@ -427,6 +570,71 @@ declare function setTurnTimeoutInSeconds(seconds: number): void;
|
|
|
427
570
|
* ```
|
|
428
571
|
*/
|
|
429
572
|
declare function setWarmTimeoutInSeconds(seconds: number): void;
|
|
573
|
+
/**
|
|
574
|
+
* Check whether the user stopped generation during the current turn.
|
|
575
|
+
*
|
|
576
|
+
* Works from **anywhere** inside a `chat.task` run — including inside
|
|
577
|
+
* `streamText`'s `onFinish` callback — without needing to thread the
|
|
578
|
+
* `stopSignal` through closures.
|
|
579
|
+
*
|
|
580
|
+
* This is especially useful when the AI SDK's `isAborted` flag is unreliable
|
|
581
|
+
* (e.g. when using `createUIMessageStream` + `writer.merge()`).
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```ts
|
|
585
|
+
* onFinish: ({ isAborted }) => {
|
|
586
|
+
* const wasStopped = isAborted || chat.isStopped();
|
|
587
|
+
* if (wasStopped) {
|
|
588
|
+
* // handle stop
|
|
589
|
+
* }
|
|
590
|
+
* }
|
|
591
|
+
* ```
|
|
592
|
+
*/
|
|
593
|
+
declare function isStopped(): boolean;
|
|
594
|
+
/**
|
|
595
|
+
* Register a promise that runs in the background during the current turn.
|
|
596
|
+
*
|
|
597
|
+
* Use this to move non-blocking work (DB writes, analytics, etc.) out of
|
|
598
|
+
* the critical path. The promise runs in parallel with streaming and is
|
|
599
|
+
* awaited (with a 5 s timeout) before `onTurnComplete` fires.
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```ts
|
|
603
|
+
* onTurnStart: async ({ chatId, uiMessages }) => {
|
|
604
|
+
* // Persist messages without blocking the LLM call
|
|
605
|
+
* chat.defer(db.chat.update({ where: { id: chatId }, data: { messages: uiMessages } }));
|
|
606
|
+
* },
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
declare function chatDefer(promise: Promise<unknown>): void;
|
|
610
|
+
/**
|
|
611
|
+
* Clean up a UIMessage that was captured during an aborted/stopped turn.
|
|
612
|
+
*
|
|
613
|
+
* When generation is stopped mid-stream, the captured message may contain:
|
|
614
|
+
* - Tool parts stuck in incomplete states (`partial-call`, `input-available`,
|
|
615
|
+
* `input-streaming`) that cause permanent UI spinners
|
|
616
|
+
* - Reasoning parts with `state: "streaming"` instead of `"done"`
|
|
617
|
+
* - Text parts with `state: "streaming"` instead of `"done"`
|
|
618
|
+
*
|
|
619
|
+
* This function returns a cleaned copy with:
|
|
620
|
+
* - Incomplete tool parts removed entirely
|
|
621
|
+
* - Reasoning and text parts marked as `"done"`
|
|
622
|
+
*
|
|
623
|
+
* `chat.task` calls this automatically when stop is detected before passing
|
|
624
|
+
* the response to `onTurnComplete`. Use this manually when calling `pipeChat`
|
|
625
|
+
* directly and capturing response messages yourself.
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
* ```ts
|
|
629
|
+
* onTurnComplete: async ({ responseMessage, stopped }) => {
|
|
630
|
+
* // Already cleaned automatically by chat.task — but if you captured
|
|
631
|
+
* // your own message via pipeChat, clean it manually:
|
|
632
|
+
* const cleaned = chat.cleanupAbortedParts(myMessage);
|
|
633
|
+
* await db.messages.save(cleaned);
|
|
634
|
+
* }
|
|
635
|
+
* ```
|
|
636
|
+
*/
|
|
637
|
+
declare function cleanupAbortedParts(message: UIMessage): UIMessage;
|
|
430
638
|
/**
|
|
431
639
|
* A Proxy-backed, run-scoped data object that appears as `T` to users.
|
|
432
640
|
* Includes helper methods for initialization, dirty tracking, and serialization.
|
|
@@ -451,12 +659,16 @@ export type ChatLocal<T extends Record<string, unknown>> = T & {
|
|
|
451
659
|
*
|
|
452
660
|
* Multiple locals can coexist — each gets its own isolated run-scoped storage.
|
|
453
661
|
*
|
|
662
|
+
* The `id` is required and must be unique across all `chat.local()` calls in
|
|
663
|
+
* your project. It's used to serialize values into subtask metadata so that
|
|
664
|
+
* `ai.tool()` subtasks can auto-hydrate parent locals (read-only).
|
|
665
|
+
*
|
|
454
666
|
* @example
|
|
455
667
|
* ```ts
|
|
456
668
|
* import { chat } from "@trigger.dev/sdk/ai";
|
|
457
669
|
*
|
|
458
|
-
* const userPrefs = chat.local<{ theme: string; language: string }>();
|
|
459
|
-
* const gameState = chat.local<{ score: number; streak: number }>();
|
|
670
|
+
* const userPrefs = chat.local<{ theme: string; language: string }>({ id: "userPrefs" });
|
|
671
|
+
* const gameState = chat.local<{ score: number; streak: number }>({ id: "gameState" });
|
|
460
672
|
*
|
|
461
673
|
* export const myChat = chat.task({
|
|
462
674
|
* id: "my-chat",
|
|
@@ -480,7 +692,9 @@ export type ChatLocal<T extends Record<string, unknown>> = T & {
|
|
|
480
692
|
* });
|
|
481
693
|
* ```
|
|
482
694
|
*/
|
|
483
|
-
declare function chatLocal<T extends Record<string, unknown>>(
|
|
695
|
+
declare function chatLocal<T extends Record<string, unknown>>(options: {
|
|
696
|
+
id: string;
|
|
697
|
+
}): ChatLocal<T>;
|
|
484
698
|
/**
|
|
485
699
|
* Extracts the client data (metadata) type from a chat task.
|
|
486
700
|
* Use this to type the `metadata` option on the transport.
|
|
@@ -510,4 +724,12 @@ export declare const chat: {
|
|
|
510
724
|
setTurnTimeoutInSeconds: typeof setTurnTimeoutInSeconds;
|
|
511
725
|
/** Override the warm timeout at runtime. See {@link setWarmTimeoutInSeconds}. */
|
|
512
726
|
setWarmTimeoutInSeconds: typeof setWarmTimeoutInSeconds;
|
|
727
|
+
/** Check if the current turn was stopped by the user. See {@link isStopped}. */
|
|
728
|
+
isStopped: typeof isStopped;
|
|
729
|
+
/** Clean up aborted parts from a UIMessage. See {@link cleanupAbortedParts}. */
|
|
730
|
+
cleanupAbortedParts: typeof cleanupAbortedParts;
|
|
731
|
+
/** Register background work that runs in parallel with streaming. See {@link chatDefer}. */
|
|
732
|
+
defer: typeof chatDefer;
|
|
733
|
+
/** Typed chat output stream for writing custom chunks or piping from subtasks. */
|
|
734
|
+
stream: import("@trigger.dev/core/v3").RealtimeDefinedStream<UIMessageChunk>;
|
|
513
735
|
};
|