@trigger.dev/sdk 0.0.0-prerelease-20260220162801 → 0.0.0-prerelease-20260304181730

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 (54) hide show
  1. package/dist/commonjs/v3/ai.d.ts +245 -2
  2. package/dist/commonjs/v3/ai.js +384 -1
  3. package/dist/commonjs/v3/ai.js.map +1 -1
  4. package/dist/commonjs/v3/auth.d.ts +4 -0
  5. package/dist/commonjs/v3/auth.js.map +1 -1
  6. package/dist/commonjs/v3/chat-constants.d.ts +10 -0
  7. package/dist/commonjs/v3/chat-constants.js +14 -0
  8. package/dist/commonjs/v3/chat-constants.js.map +1 -0
  9. package/dist/commonjs/v3/chat-react.d.ts +42 -0
  10. package/dist/commonjs/v3/chat-react.js +63 -0
  11. package/dist/commonjs/v3/chat-react.js.map +1 -0
  12. package/dist/commonjs/v3/chat.d.ts +156 -0
  13. package/dist/commonjs/v3/chat.js +270 -0
  14. package/dist/commonjs/v3/chat.js.map +1 -0
  15. package/dist/commonjs/v3/chat.test.d.ts +1 -0
  16. package/dist/commonjs/v3/chat.test.js +1304 -0
  17. package/dist/commonjs/v3/chat.test.js.map +1 -0
  18. package/dist/commonjs/v3/runs.d.ts +4 -4
  19. package/dist/commonjs/v3/shared.js +10 -9
  20. package/dist/commonjs/v3/shared.js.map +1 -1
  21. package/dist/commonjs/v3/streams.d.ts +34 -2
  22. package/dist/commonjs/v3/streams.js +166 -2
  23. package/dist/commonjs/v3/streams.js.map +1 -1
  24. package/dist/commonjs/v3/wait.d.ts +2 -9
  25. package/dist/commonjs/v3/wait.js +7 -26
  26. package/dist/commonjs/v3/wait.js.map +1 -1
  27. package/dist/commonjs/version.js +1 -1
  28. package/dist/esm/v3/ai.d.ts +245 -2
  29. package/dist/esm/v3/ai.js +385 -2
  30. package/dist/esm/v3/ai.js.map +1 -1
  31. package/dist/esm/v3/auth.d.ts +4 -0
  32. package/dist/esm/v3/auth.js.map +1 -1
  33. package/dist/esm/v3/chat-constants.d.ts +10 -0
  34. package/dist/esm/v3/chat-constants.js +11 -0
  35. package/dist/esm/v3/chat-constants.js.map +1 -0
  36. package/dist/esm/v3/chat-react.d.ts +42 -0
  37. package/dist/esm/v3/chat-react.js +60 -0
  38. package/dist/esm/v3/chat-react.js.map +1 -0
  39. package/dist/esm/v3/chat.d.ts +156 -0
  40. package/dist/esm/v3/chat.js +265 -0
  41. package/dist/esm/v3/chat.js.map +1 -0
  42. package/dist/esm/v3/chat.test.d.ts +1 -0
  43. package/dist/esm/v3/chat.test.js +1302 -0
  44. package/dist/esm/v3/chat.test.js.map +1 -0
  45. package/dist/esm/v3/shared.js +10 -9
  46. package/dist/esm/v3/shared.js.map +1 -1
  47. package/dist/esm/v3/streams.d.ts +34 -2
  48. package/dist/esm/v3/streams.js +167 -3
  49. package/dist/esm/v3/streams.js.map +1 -1
  50. package/dist/esm/v3/wait.d.ts +2 -9
  51. package/dist/esm/v3/wait.js +2 -22
  52. package/dist/esm/v3/wait.js.map +1 -1
  53. package/dist/esm/version.js +1 -1
  54. 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,245 @@ 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
+ * - `uiMessages` contains the raw `UIMessage[]` from the frontend.
55
+ * - `clientData` contains custom data from the frontend (the `metadata` field from `sendMessage()`).
56
+ */
57
+ export type ChatTaskPayload = {
58
+ /** Model-ready messages — pass directly to `streamText({ messages })`. */
59
+ messages: ModelMessage[];
60
+ /** Raw UI messages from the frontend. */
61
+ uiMessages: UIMessage[];
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
+ export type ChatTaskOptions<TIdentifier extends string> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload, unknown>, "run"> & {
171
+ /**
172
+ * The run function for the chat task.
173
+ *
174
+ * Receives a `ChatTaskRunPayload` with the conversation messages, chat session ID,
175
+ * trigger type, and abort signals (`signal`, `cancelSignal`, `stopSignal`).
176
+ *
177
+ * **Auto-piping:** If this function returns a value with `.toUIMessageStream()`,
178
+ * the stream is automatically piped to the frontend.
179
+ */
180
+ run: (payload: ChatTaskRunPayload) => Promise<unknown>;
181
+ /**
182
+ * Maximum number of conversational turns (message round-trips) a single run
183
+ * will handle before ending. After this many turns the run completes
184
+ * normally and the next message will start a fresh run.
185
+ *
186
+ * @default 100
187
+ */
188
+ maxTurns?: number;
189
+ /**
190
+ * How long to wait for the next message before timing out and ending the run.
191
+ * Accepts any duration string (e.g. `"1h"`, `"30m"`).
192
+ *
193
+ * @default "1h"
194
+ */
195
+ turnTimeout?: string;
196
+ /**
197
+ * How long (in seconds) to keep the run warm after each turn before suspending.
198
+ * During this window the run stays active and can respond instantly to the
199
+ * next message. After this timeout, the run suspends (frees compute) and waits
200
+ * via `inputStream.wait()`.
201
+ *
202
+ * Set to `0` to suspend immediately after each turn.
203
+ *
204
+ * @default 30
205
+ */
206
+ warmTimeoutInSeconds?: number;
207
+ };
208
+ /**
209
+ * Creates a Trigger.dev task pre-configured for AI SDK chat.
210
+ *
211
+ * - **Pre-types the payload** as `ChatTaskRunPayload` — includes abort signals
212
+ * - **Auto-pipes the stream** if `run` returns a `StreamTextResult`
213
+ * - **Multi-turn**: keeps the conversation in a single run using input streams
214
+ * - **Stop support**: frontend can stop generation mid-stream via the stop input stream
215
+ * - For complex flows, use `pipeChat()` from anywhere inside your task code
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * import { chat } from "@trigger.dev/sdk/ai";
220
+ * import { streamText, convertToModelMessages } from "ai";
221
+ * import { openai } from "@ai-sdk/openai";
222
+ *
223
+ * export const myChat = chat.task({
224
+ * id: "my-chat",
225
+ * run: async ({ messages, signal }) => {
226
+ * return streamText({
227
+ * model: openai("gpt-4o"),
228
+ * messages, // already converted via convertToModelMessages
229
+ * abortSignal: signal,
230
+ * });
231
+ * },
232
+ * });
233
+ * ```
234
+ */
235
+ declare function chatTask<TIdentifier extends string>(options: ChatTaskOptions<TIdentifier>): Task<TIdentifier, ChatTaskWirePayload, unknown>;
236
+ /**
237
+ * Namespace for AI SDK chat integration.
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * import { chat } from "@trigger.dev/sdk/ai";
242
+ *
243
+ * // Define a chat task
244
+ * export const myChat = chat.task({
245
+ * id: "my-chat",
246
+ * run: async ({ messages, signal }) => {
247
+ * return streamText({ model, messages, abortSignal: signal });
248
+ * },
249
+ * });
250
+ *
251
+ * // Pipe a stream manually (from inside a task)
252
+ * await chat.pipe(streamTextResult);
253
+ *
254
+ * // Create an access token (from a server action)
255
+ * const token = await chat.createAccessToken("my-chat");
256
+ * ```
257
+ */
258
+ export declare const chat: {
259
+ /** Create a chat task. See {@link chatTask}. */
260
+ task: typeof chatTask;
261
+ /** Pipe a stream to the chat transport. See {@link pipeChat}. */
262
+ pipe: typeof pipeChat;
263
+ /** Create a public access token for a chat task. See {@link createChatAccessToken}. */
264
+ createAccessToken: typeof createChatAccessToken;
265
+ };
@@ -1,9 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ai = void 0;
3
+ exports.chat = exports.CHAT_STOP_STREAM_ID = exports.CHAT_MESSAGES_STREAM_ID = exports.CHAT_STREAM_KEY = exports.ai = void 0;
4
4
  const v3_1 = require("@trigger.dev/core/v3");
5
5
  const ai_1 = require("ai");
6
+ const api_1 = require("@opentelemetry/api");
7
+ const auth_js_1 = require("./auth.js");
6
8
  const metadata_js_1 = require("./metadata.js");
9
+ const streams_js_1 = require("./streams.js");
10
+ const shared_js_1 = require("./shared.js");
11
+ const tracer_js_1 = require("./tracer.js");
12
+ const chat_constants_js_1 = require("./chat-constants.js");
13
+ Object.defineProperty(exports, "CHAT_MESSAGES_STREAM_ID", { enumerable: true, get: function () { return chat_constants_js_1.CHAT_MESSAGES_STREAM_ID; } });
14
+ Object.defineProperty(exports, "CHAT_STOP_STREAM_ID", { enumerable: true, get: function () { return chat_constants_js_1.CHAT_STOP_STREAM_ID; } });
7
15
  const METADATA_KEY = "tool.execute.options";
8
16
  function toolFromTask(task, options) {
9
17
  if (("schema" in task && !task.schema) || ("jsonSchema" in task && !task.jsonSchema)) {
@@ -53,4 +61,379 @@ exports.ai = {
53
61
  tool: toolFromTask,
54
62
  currentToolOptions: getToolOptionsFromMetadata,
55
63
  };
64
+ /**
65
+ * Creates a public access token for a chat task.
66
+ *
67
+ * This is a convenience helper that creates a multi-use trigger public token
68
+ * scoped to the given task. Use it in a server action to provide the frontend
69
+ * `TriggerChatTransport` with an `accessToken`.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * // actions.ts
74
+ * "use server";
75
+ * import { chat } from "@trigger.dev/sdk/ai";
76
+ * import type { myChat } from "@/trigger/chat";
77
+ *
78
+ * export const getChatToken = () => chat.createAccessToken<typeof myChat>("my-chat");
79
+ * ```
80
+ */
81
+ function createChatAccessToken(taskId) {
82
+ return auth_js_1.auth.createTriggerPublicToken(taskId, { multipleUse: true });
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // Chat transport helpers — backend side
86
+ // ---------------------------------------------------------------------------
87
+ /**
88
+ * The default stream key used for chat transport communication.
89
+ * Both `TriggerChatTransport` (frontend) and `pipeChat`/`chatTask` (backend)
90
+ * use this key by default.
91
+ */
92
+ exports.CHAT_STREAM_KEY = chat_constants_js_1.CHAT_STREAM_KEY;
93
+ // Input streams for bidirectional chat communication
94
+ const messagesInput = streams_js_1.streams.input({ id: chat_constants_js_1.CHAT_MESSAGES_STREAM_ID });
95
+ const stopInput = streams_js_1.streams.input({ id: chat_constants_js_1.CHAT_STOP_STREAM_ID });
96
+ /**
97
+ * Strips provider-specific IDs from message parts so that partial/stopped
98
+ * assistant responses don't cause 404s when sent back to the provider
99
+ * (e.g. OpenAI Responses API message IDs).
100
+ * @internal
101
+ */
102
+ function sanitizeMessages(messages) {
103
+ return messages.map((msg) => {
104
+ if (msg.role !== "assistant" || !msg.parts)
105
+ return msg;
106
+ return {
107
+ ...msg,
108
+ parts: msg.parts.map((part) => {
109
+ // Strip provider-specific metadata (e.g. OpenAI Responses API itemId)
110
+ // and streaming state from assistant message parts. These cause 404s
111
+ // when partial/stopped responses are sent back to the provider.
112
+ const { providerMetadata, state, id, ...rest } = part;
113
+ return rest;
114
+ }),
115
+ };
116
+ });
117
+ }
118
+ /**
119
+ * Tracks how many times `pipeChat` has been called in the current `chatTask` run.
120
+ * Used to prevent double-piping when a user both calls `pipeChat()` manually
121
+ * and returns a streamable from their `run` function.
122
+ * @internal
123
+ */
124
+ let _chatPipeCount = 0;
125
+ function isUIMessageStreamable(value) {
126
+ return (typeof value === "object" &&
127
+ value !== null &&
128
+ "toUIMessageStream" in value &&
129
+ typeof value.toUIMessageStream === "function");
130
+ }
131
+ function isAsyncIterable(value) {
132
+ return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
133
+ }
134
+ function isReadableStream(value) {
135
+ return typeof value === "object" && value !== null && typeof value.getReader === "function";
136
+ }
137
+ /**
138
+ * Pipes a chat stream to the realtime stream, making it available to the
139
+ * `TriggerChatTransport` on the frontend.
140
+ *
141
+ * Accepts:
142
+ * - A `StreamTextResult` from `streamText()` (has `.toUIMessageStream()`)
143
+ * - An `AsyncIterable` of `UIMessageChunk`s
144
+ * - A `ReadableStream` of `UIMessageChunk`s
145
+ *
146
+ * Must be called from inside a Trigger.dev task's `run` function.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * import { task } from "@trigger.dev/sdk";
151
+ * import { chat, type ChatTaskPayload } from "@trigger.dev/sdk/ai";
152
+ * import { streamText, convertToModelMessages } from "ai";
153
+ *
154
+ * export const myChatTask = task({
155
+ * id: "my-chat-task",
156
+ * run: async (payload: ChatTaskPayload) => {
157
+ * const result = streamText({
158
+ * model: openai("gpt-4o"),
159
+ * messages: payload.messages,
160
+ * });
161
+ *
162
+ * await chat.pipe(result);
163
+ * },
164
+ * });
165
+ * ```
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * // Works from anywhere inside a task — even deep in your agent code
170
+ * async function runAgentLoop(messages: CoreMessage[]) {
171
+ * const result = streamText({ model, messages });
172
+ * await chat.pipe(result);
173
+ * }
174
+ * ```
175
+ */
176
+ async function pipeChat(source, options) {
177
+ _chatPipeCount++;
178
+ const streamKey = options?.streamKey ?? exports.CHAT_STREAM_KEY;
179
+ let stream;
180
+ if (isUIMessageStreamable(source)) {
181
+ stream = source.toUIMessageStream();
182
+ }
183
+ else if (isAsyncIterable(source) || isReadableStream(source)) {
184
+ stream = source;
185
+ }
186
+ else {
187
+ throw new Error("pipeChat: source must be a StreamTextResult (with .toUIMessageStream()), " +
188
+ "an AsyncIterable, or a ReadableStream");
189
+ }
190
+ const pipeOptions = {};
191
+ if (options?.signal) {
192
+ pipeOptions.signal = options.signal;
193
+ }
194
+ if (options?.target) {
195
+ pipeOptions.target = options.target;
196
+ }
197
+ if (options?.spanName) {
198
+ pipeOptions.spanName = options.spanName;
199
+ }
200
+ const { waitUntilComplete } = streams_js_1.streams.pipe(streamKey, stream, pipeOptions);
201
+ await waitUntilComplete();
202
+ }
203
+ /**
204
+ * Creates a Trigger.dev task pre-configured for AI SDK chat.
205
+ *
206
+ * - **Pre-types the payload** as `ChatTaskRunPayload` — includes abort signals
207
+ * - **Auto-pipes the stream** if `run` returns a `StreamTextResult`
208
+ * - **Multi-turn**: keeps the conversation in a single run using input streams
209
+ * - **Stop support**: frontend can stop generation mid-stream via the stop input stream
210
+ * - For complex flows, use `pipeChat()` from anywhere inside your task code
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * import { chat } from "@trigger.dev/sdk/ai";
215
+ * import { streamText, convertToModelMessages } from "ai";
216
+ * import { openai } from "@ai-sdk/openai";
217
+ *
218
+ * export const myChat = chat.task({
219
+ * id: "my-chat",
220
+ * run: async ({ messages, signal }) => {
221
+ * return streamText({
222
+ * model: openai("gpt-4o"),
223
+ * messages, // already converted via convertToModelMessages
224
+ * abortSignal: signal,
225
+ * });
226
+ * },
227
+ * });
228
+ * ```
229
+ */
230
+ function chatTask(options) {
231
+ const { run: userRun, maxTurns = 100, turnTimeout = "1h", warmTimeoutInSeconds = 30, ...restOptions } = options;
232
+ return (0, shared_js_1.createTask)({
233
+ ...restOptions,
234
+ run: async (payload, { signal: runSignal }) => {
235
+ // Set gen_ai.conversation.id on the run-level span for dashboard context
236
+ const activeSpan = api_1.trace.getActiveSpan();
237
+ if (activeSpan) {
238
+ activeSpan.setAttribute("gen_ai.conversation.id", payload.chatId);
239
+ }
240
+ let currentWirePayload = payload;
241
+ // Mutable reference to the current turn's stop controller so the
242
+ // stop input stream listener (registered once) can abort the right turn.
243
+ let currentStopController;
244
+ // Listen for stop signals for the lifetime of the run
245
+ const stopSub = stopInput.on((data) => {
246
+ currentStopController?.abort(data?.message || "stopped");
247
+ });
248
+ try {
249
+ for (let turn = 0; turn < maxTurns; turn++) {
250
+ // Extract turn-level context before entering the span
251
+ const { metadata: wireMetadata, messages: uiMessages, ...restWire } = currentWirePayload;
252
+ const lastUserMessage = extractLastUserMessageText(uiMessages);
253
+ const turnAttributes = {
254
+ "turn.number": turn + 1,
255
+ "gen_ai.conversation.id": currentWirePayload.chatId,
256
+ "gen_ai.operation.name": "chat",
257
+ "chat.trigger": currentWirePayload.trigger,
258
+ [v3_1.SemanticInternalAttributes.STYLE_ICON]: "tabler-message-chatbot",
259
+ [v3_1.SemanticInternalAttributes.ENTITY_TYPE]: "chat-turn",
260
+ };
261
+ if (lastUserMessage) {
262
+ turnAttributes["chat.user_message"] = lastUserMessage;
263
+ // Show a truncated preview of the user message as an accessory
264
+ const preview = lastUserMessage.length > 80
265
+ ? lastUserMessage.slice(0, 80) + "..."
266
+ : lastUserMessage;
267
+ Object.assign(turnAttributes, (0, v3_1.accessoryAttributes)({
268
+ items: [{ text: preview, variant: "normal" }],
269
+ style: "codepath",
270
+ }));
271
+ }
272
+ if (wireMetadata !== undefined) {
273
+ turnAttributes["chat.client_data"] =
274
+ typeof wireMetadata === "string" ? wireMetadata : JSON.stringify(wireMetadata);
275
+ }
276
+ const turnResult = await tracer_js_1.tracer.startActiveSpan(`chat turn ${turn + 1}`, async () => {
277
+ _chatPipeCount = 0;
278
+ // Per-turn stop controller (reset each turn)
279
+ const stopController = new AbortController();
280
+ currentStopController = stopController;
281
+ // Three signals for the user's run function
282
+ const stopSignal = stopController.signal;
283
+ const cancelSignal = runSignal;
284
+ const combinedSignal = AbortSignal.any([runSignal, stopController.signal]);
285
+ // Buffer messages that arrive during streaming
286
+ const pendingMessages = [];
287
+ const msgSub = messagesInput.on((msg) => {
288
+ pendingMessages.push(msg);
289
+ });
290
+ // Convert wire payload to user-facing payload
291
+ const sanitized = sanitizeMessages(uiMessages);
292
+ const modelMessages = await (0, ai_1.convertToModelMessages)(sanitized);
293
+ try {
294
+ const result = await userRun({
295
+ ...restWire,
296
+ messages: modelMessages,
297
+ uiMessages: sanitized,
298
+ clientData: wireMetadata,
299
+ signal: combinedSignal,
300
+ cancelSignal,
301
+ stopSignal,
302
+ });
303
+ // Auto-pipe if the run function returned a StreamTextResult or similar,
304
+ // but only if pipeChat() wasn't already called manually during this turn
305
+ if (_chatPipeCount === 0 && isUIMessageStreamable(result)) {
306
+ await pipeChat(result, { signal: combinedSignal, spanName: "stream response" });
307
+ }
308
+ }
309
+ catch (error) {
310
+ // Handle AbortError from streamText gracefully
311
+ if (error instanceof Error && error.name === "AbortError") {
312
+ if (runSignal.aborted) {
313
+ return "exit"; // Full run cancellation — exit
314
+ }
315
+ // Stop generation — fall through to continue the loop
316
+ }
317
+ else {
318
+ throw error;
319
+ }
320
+ }
321
+ finally {
322
+ msgSub.off();
323
+ }
324
+ if (runSignal.aborted)
325
+ return "exit";
326
+ // Write turn-complete control chunk so frontend closes its stream
327
+ await writeTurnCompleteChunk(currentWirePayload.chatId);
328
+ // If messages arrived during streaming, use the first one immediately
329
+ if (pendingMessages.length > 0) {
330
+ currentWirePayload = pendingMessages[0];
331
+ return "continue";
332
+ }
333
+ // Phase 1: Keep the run warm for quick response to the next message.
334
+ // The run stays active (using compute) during this window.
335
+ if (warmTimeoutInSeconds > 0) {
336
+ const warm = await messagesInput.once({
337
+ timeoutMs: warmTimeoutInSeconds * 1000,
338
+ spanName: "waiting (warm)",
339
+ });
340
+ if (warm.ok) {
341
+ // Message arrived while warm — respond instantly
342
+ currentWirePayload = warm.output;
343
+ return "continue";
344
+ }
345
+ }
346
+ // Phase 2: Suspend the task (frees compute) until the next message arrives
347
+ const next = await messagesInput.wait({
348
+ timeout: turnTimeout,
349
+ spanName: "waiting (suspended)",
350
+ });
351
+ if (!next.ok) {
352
+ // Timed out waiting for the next message — end the conversation
353
+ return "exit";
354
+ }
355
+ currentWirePayload = next.output;
356
+ return "continue";
357
+ }, {
358
+ attributes: turnAttributes,
359
+ });
360
+ if (turnResult === "exit")
361
+ return;
362
+ // "continue" means proceed to next iteration
363
+ }
364
+ }
365
+ finally {
366
+ stopSub.off();
367
+ }
368
+ },
369
+ });
370
+ }
371
+ /**
372
+ * Namespace for AI SDK chat integration.
373
+ *
374
+ * @example
375
+ * ```ts
376
+ * import { chat } from "@trigger.dev/sdk/ai";
377
+ *
378
+ * // Define a chat task
379
+ * export const myChat = chat.task({
380
+ * id: "my-chat",
381
+ * run: async ({ messages, signal }) => {
382
+ * return streamText({ model, messages, abortSignal: signal });
383
+ * },
384
+ * });
385
+ *
386
+ * // Pipe a stream manually (from inside a task)
387
+ * await chat.pipe(streamTextResult);
388
+ *
389
+ * // Create an access token (from a server action)
390
+ * const token = await chat.createAccessToken("my-chat");
391
+ * ```
392
+ */
393
+ exports.chat = {
394
+ /** Create a chat task. See {@link chatTask}. */
395
+ task: chatTask,
396
+ /** Pipe a stream to the chat transport. See {@link pipeChat}. */
397
+ pipe: pipeChat,
398
+ /** Create a public access token for a chat task. See {@link createChatAccessToken}. */
399
+ createAccessToken: createChatAccessToken,
400
+ };
401
+ /**
402
+ * Writes a turn-complete control chunk to the chat output stream.
403
+ * The frontend transport intercepts this to close the ReadableStream for the current turn.
404
+ * @internal
405
+ */
406
+ async function writeTurnCompleteChunk(chatId) {
407
+ const { waitUntilComplete } = streams_js_1.streams.writer(exports.CHAT_STREAM_KEY, {
408
+ spanName: "turn complete",
409
+ collapsed: true,
410
+ execute: ({ write }) => {
411
+ write({ type: "__trigger_turn_complete" });
412
+ },
413
+ });
414
+ await waitUntilComplete();
415
+ }
416
+ /**
417
+ * Extracts the text content of the last user message from a UIMessage array.
418
+ * Returns undefined if no user message is found.
419
+ * @internal
420
+ */
421
+ function extractLastUserMessageText(messages) {
422
+ for (let i = messages.length - 1; i >= 0; i--) {
423
+ const msg = messages[i];
424
+ if (msg.role !== "user")
425
+ continue;
426
+ // UIMessage uses parts array
427
+ if (msg.parts) {
428
+ const textParts = msg.parts
429
+ .filter((p) => p.type === "text" && p.text)
430
+ .map((p) => p.text);
431
+ if (textParts.length > 0) {
432
+ return textParts.join("\n");
433
+ }
434
+ }
435
+ break;
436
+ }
437
+ return undefined;
438
+ }
56
439
  //# sourceMappingURL=ai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../../src/v3/ai.ts"],"names":[],"mappings":";;;AAAA,6CAO8B;AAC9B,2BAAoG;AACpG,+CAAyC;AAEzC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAgC5C,SAAS,YAAY,CAMnB,IAA4F,EAC5F,OAA8B;IAI9B,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CACb,8IAA8I,CAC/I,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,gBAAW,EAAC;QACjC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,iCAAiC,CAAC,IAAI,CAAC;QACpD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAChC,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEpF,OAAO,MAAM,IAAI;iBACd,cAAc,CAAC,KAAmC,EAAE;gBACnD,QAAQ,EAAE;oBACR,CAAC,YAAY,CAAC,EAAE,iBAAiB;iBAClC;aACF,CAAC;iBACD,MAAM,EAAE,CAAC;QACd,CAAC;QACD,GAAG,OAAO;KACX,CAAC,CAAC;IAEH,OAAO,cAEkB,CAAC;AAC5B,CAAC;AAED,SAAS,0BAA0B;IACjC,MAAM,IAAI,GAAG,sBAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,iCAAiC,CACxC,IAA6C;IAE7C,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,6EAA6E;QAC7E,IAAI,cAAc,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YACpF,OAAO,IAAA,eAAU,EAAE,IAAI,CAAC,MAAc,CAAC,YAAY,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,wEAAwE;QACxE,IAAI,IAAA,qBAAgB,EAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO,IAAA,cAAS,EAAC,IAAI,CAAC,MAAa,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;QACzB,OAAO,IAAA,eAAU,EAAC,IAAI,CAAC,UAAyB,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;AACJ,CAAC;AAEY,QAAA,EAAE,GAAG;IAChB,IAAI,EAAE,YAAY;IAClB,kBAAkB,EAAE,0BAA0B;CAC/C,CAAC"}
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../../src/v3/ai.ts"],"names":[],"mappings":";;;AAAA,6CAY8B;AAE9B,2BAA4H;AAC5H,4CAA4D;AAC5D,uCAAiC;AACjC,+CAAyC;AACzC,6CAAuC;AACvC,2CAAyC;AACzC,2CAAqC;AACrC,2DAI6B;AAiJpB,wGAnJP,2CAAuB,OAmJO;AAAE,oGAlJhC,uCAAmB,OAkJgC;AA/IrD,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAgC5C,SAAS,YAAY,CAMnB,IAA4F,EAC5F,OAA8B;IAI9B,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CACb,8IAA8I,CAC/I,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,gBAAW,EAAC;QACjC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,iCAAiC,CAAC,IAAI,CAAC;QACpD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAChC,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEpF,OAAO,MAAM,IAAI;iBACd,cAAc,CAAC,KAAmC,EAAE;gBACnD,QAAQ,EAAE;oBACR,CAAC,YAAY,CAAC,EAAE,iBAAiB;iBAClC;aACF,CAAC;iBACD,MAAM,EAAE,CAAC;QACd,CAAC;QACD,GAAG,OAAO;KACX,CAAC,CAAC;IAEH,OAAO,cAEkB,CAAC;AAC5B,CAAC;AAED,SAAS,0BAA0B;IACjC,MAAM,IAAI,GAAG,sBAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,iCAAiC,CACxC,IAA6C;IAE7C,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,6EAA6E;QAC7E,IAAI,cAAc,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YACpF,OAAO,IAAA,eAAU,EAAE,IAAI,CAAC,MAAc,CAAC,YAAY,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,wEAAwE;QACxE,IAAI,IAAA,qBAAgB,EAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO,IAAA,cAAS,EAAC,IAAI,CAAC,MAAa,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;QACzB,OAAO,IAAA,eAAU,EAAC,IAAI,CAAC,UAAyB,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;AACJ,CAAC;AAEY,QAAA,EAAE,GAAG;IAChB,IAAI,EAAE,YAAY;IAClB,kBAAkB,EAAE,0BAA0B;CAC/C,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,qBAAqB,CAC5B,MAA6B;IAE7B,OAAO,cAAI,CAAC,wBAAwB,CAAC,MAAgB,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAChF,CAAC;AAED,8EAA8E;AAC9E,wCAAwC;AACxC,8EAA8E;AAE9E;;;;GAIG;AACU,QAAA,eAAe,GAAG,mCAAgB,CAAC;AAoEhD,qDAAqD;AACrD,MAAM,aAAa,GAAG,oBAAO,CAAC,KAAK,CAAsB,EAAE,EAAE,EAAE,2CAAuB,EAAE,CAAC,CAAC;AAC1F,MAAM,SAAS,GAAG,oBAAO,CAAC,KAAK,CAAmC,EAAE,EAAE,EAAE,uCAAmB,EAAE,CAAC,CAAC;AAE/F;;;;;GAKG;AACH,SAAS,gBAAgB,CAA6B,QAAoB;IACxE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO,GAAG,CAAC;QACvD,OAAO;YACL,GAAG,GAAG;YACN,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE;gBACjC,sEAAsE;gBACtE,qEAAqE;gBACrE,gEAAgE;gBAChE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;gBACtD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;SACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,IAAI,cAAc,GAAG,CAAC,CAAC;AAgCvB,SAAS,qBAAqB,CAAC,KAAc;IAC3C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,mBAAmB,IAAI,KAAK;QAC5B,OAAQ,KAAa,CAAC,iBAAiB,KAAK,UAAU,CACvD,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,aAAa,IAAI,KAAK,CAAC;AACtF,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAQ,KAAa,CAAC,SAAS,KAAK,UAAU,CAAC;AACvG,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,KAAK,UAAU,QAAQ,CACrB,MAA8E,EAC9E,OAAyB;IAEzB,cAAc,EAAE,CAAC;IACjB,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,uBAAe,CAAC;IAExD,IAAI,MAAwD,CAAC;IAE7D,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;IACtC,CAAC;SAAM,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/D,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CACb,2EAA2E;YACzE,uCAAuC,CAC1C,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAsB,EAAE,CAAC;IAC1C,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;QACtB,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,oBAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3E,MAAM,iBAAiB,EAAE,CAAC;AAC5B,CAAC;AA6DD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAS,QAAQ,CACf,OAAqC;IAErC,MAAM,EACJ,GAAG,EAAE,OAAO,EACZ,QAAQ,GAAG,GAAG,EACd,WAAW,GAAG,IAAI,EAClB,oBAAoB,GAAG,EAAE,EACzB,GAAG,WAAW,EACf,GAAG,OAAO,CAAC;IAEZ,OAAO,IAAA,sBAAU,EAA4C;QAC3D,GAAG,WAAW;QACd,GAAG,EAAE,KAAK,EAAE,OAA4B,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;YACjE,yEAAyE;YACzE,MAAM,UAAU,GAAG,WAAK,CAAC,aAAa,EAAE,CAAC;YACzC,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACpE,CAAC;YAED,IAAI,kBAAkB,GAAG,OAAO,CAAC;YAEjC,iEAAiE;YACjE,yEAAyE;YACzE,IAAI,qBAAkD,CAAC;YAEvD,sDAAsD;YACtD,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE;gBACpC,qBAAqB,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,IAAI,SAAS,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;oBAC3C,sDAAsD;oBACtD,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,GAAG,kBAAkB,CAAC;oBACzF,MAAM,eAAe,GAAG,0BAA0B,CAAC,UAAU,CAAC,CAAC;oBAE/D,MAAM,cAAc,GAAe;wBACjC,aAAa,EAAE,IAAI,GAAG,CAAC;wBACvB,wBAAwB,EAAE,kBAAkB,CAAC,MAAM;wBACnD,uBAAuB,EAAE,MAAM;wBAC/B,cAAc,EAAE,kBAAkB,CAAC,OAAO;wBAC1C,CAAC,+BAA0B,CAAC,UAAU,CAAC,EAAE,wBAAwB;wBACjE,CAAC,+BAA0B,CAAC,WAAW,CAAC,EAAE,WAAW;qBACtD,CAAC;oBAEF,IAAI,eAAe,EAAE,CAAC;wBACpB,cAAc,CAAC,mBAAmB,CAAC,GAAG,eAAe,CAAC;wBAEtD,+DAA+D;wBAC/D,MAAM,OAAO,GACX,eAAe,CAAC,MAAM,GAAG,EAAE;4BACzB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;4BACtC,CAAC,CAAC,eAAe,CAAC;wBACtB,MAAM,CAAC,MAAM,CACX,cAAc,EACd,IAAA,wBAAmB,EAAC;4BAClB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;4BAC7C,KAAK,EAAE,UAAU;yBAClB,CAAC,CACH,CAAC;oBACJ,CAAC;oBAED,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;wBAC/B,cAAc,CAAC,kBAAkB,CAAC;4BAChC,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBACnF,CAAC;oBAED,MAAM,UAAU,GAAG,MAAM,kBAAM,CAAC,eAAe,CAC7C,aAAa,IAAI,GAAG,CAAC,EAAE,EACvB,KAAK,IAAI,EAAE;wBACT,cAAc,GAAG,CAAC,CAAC;wBAEnB,6CAA6C;wBAC7C,MAAM,cAAc,GAAG,IAAI,eAAe,EAAE,CAAC;wBAC7C,qBAAqB,GAAG,cAAc,CAAC;wBAEvC,4CAA4C;wBAC5C,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC;wBACzC,MAAM,YAAY,GAAG,SAAS,CAAC;wBAC/B,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;wBAE3E,+CAA+C;wBAC/C,MAAM,eAAe,GAA0B,EAAE,CAAC;wBAClD,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;4BACtC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBAC5B,CAAC,CAAC,CAAC;wBAEH,8CAA8C;wBAC9C,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;wBAC/C,MAAM,aAAa,GAAG,MAAM,IAAA,2BAAsB,EAAC,SAAS,CAAC,CAAC;wBAE9D,IAAI,CAAC;4BACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;gCAC3B,GAAG,QAAQ;gCACX,QAAQ,EAAE,aAAa;gCACvB,UAAU,EAAE,SAAS;gCACrB,UAAU,EAAE,YAAY;gCACxB,MAAM,EAAE,cAAc;gCACtB,YAAY;gCACZ,UAAU;6BACX,CAAC,CAAC;4BAEH,wEAAwE;4BACxE,yEAAyE;4BACzE,IAAI,cAAc,KAAK,CAAC,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;gCAC1D,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;4BAClF,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,+CAA+C;4BAC/C,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gCAC1D,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;oCACtB,OAAO,MAAM,CAAC,CAAC,+BAA+B;gCAChD,CAAC;gCACD,sDAAsD;4BACxD,CAAC;iCAAM,CAAC;gCACN,MAAM,KAAK,CAAC;4BACd,CAAC;wBACH,CAAC;gCAAS,CAAC;4BACT,MAAM,CAAC,GAAG,EAAE,CAAC;wBACf,CAAC;wBAED,IAAI,SAAS,CAAC,OAAO;4BAAE,OAAO,MAAM,CAAC;wBAErC,kEAAkE;wBAClE,MAAM,sBAAsB,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;wBAExD,sEAAsE;wBACtE,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAC/B,kBAAkB,GAAG,eAAe,CAAC,CAAC,CAAE,CAAC;4BACzC,OAAO,UAAU,CAAC;wBACpB,CAAC;wBAED,qEAAqE;wBACrE,2DAA2D;wBAC3D,IAAI,oBAAoB,GAAG,CAAC,EAAE,CAAC;4BAC7B,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC;gCACpC,SAAS,EAAE,oBAAoB,GAAG,IAAI;gCACtC,QAAQ,EAAE,gBAAgB;6BAC3B,CAAC,CAAC;4BAEH,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gCACZ,iDAAiD;gCACjD,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC;gCACjC,OAAO,UAAU,CAAC;4BACpB,CAAC;wBACH,CAAC;wBAED,2EAA2E;wBAC3E,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC;4BACpC,OAAO,EAAE,WAAW;4BACpB,QAAQ,EAAE,qBAAqB;yBAChC,CAAC,CAAC;wBAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;4BACb,gEAAgE;4BAChE,OAAO,MAAM,CAAC;wBAChB,CAAC;wBAED,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC;wBACjC,OAAO,UAAU,CAAC;oBACpB,CAAC,EACD;wBACE,UAAU,EAAE,cAAc;qBAC3B,CACF,CAAC;oBAEF,IAAI,UAAU,KAAK,MAAM;wBAAE,OAAO;oBAClC,6CAA6C;gBAC/C,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACU,QAAA,IAAI,GAAG;IAClB,gDAAgD;IAChD,IAAI,EAAE,QAAQ;IACd,iEAAiE;IACjE,IAAI,EAAE,QAAQ;IACd,uFAAuF;IACvF,iBAAiB,EAAE,qBAAqB;CACzC,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,sBAAsB,CAAC,MAAe;IACnD,MAAM,EAAE,iBAAiB,EAAE,GAAG,oBAAO,CAAC,MAAM,CAAC,uBAAe,EAAE;QAC5D,QAAQ,EAAE,eAAe;QACzB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;YACrB,KAAK,CAAC,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;IACH,MAAM,iBAAiB,EAAE,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,SAAS,0BAA0B,CAAC,QAAqB;IACvD,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QACzB,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAElC,6BAA6B;QAC7B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK;iBACxB,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;iBAC/C,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAc,CAAC,CAAC;YACrC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,MAAM;IACR,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}