|
9 | 9 | type TaskSchema, |
10 | 10 | type TaskWithSchema, |
11 | 11 | } from "@trigger.dev/core/v3"; |
12 | | -import type { UIMessage } from "ai"; |
13 | | -import { dynamicTool, jsonSchema, JSONSchema7, Schema, Tool, ToolCallOptions, zodSchema } from "ai"; |
| 12 | +import type { ModelMessage, UIMessage } from "ai"; |
| 13 | +import { convertToModelMessages, dynamicTool, jsonSchema, JSONSchema7, Schema, Tool, ToolCallOptions, zodSchema } from "ai"; |
14 | 14 | import { auth } from "./auth.js"; |
15 | 15 | import { metadata } from "./metadata.js"; |
16 | 16 | import { streams } from "./streams.js"; |
@@ -182,12 +182,17 @@ type ChatTaskWirePayload<TMessage extends UIMessage = UIMessage> = { |
182 | 182 | /** |
183 | 183 | * The payload shape passed to the `chatTask` run function. |
184 | 184 | * |
185 | | - * The `metadata` field from the AI SDK transport is exposed as `clientData` |
186 | | - * to avoid confusion with Trigger.dev's run metadata. |
| 185 | + * - `messages` contains model-ready messages (converted via `convertToModelMessages`) — |
| 186 | + * pass these directly to `streamText`. |
| 187 | + * - `uiMessages` contains the raw `UIMessage[]` from the frontend. |
| 188 | + * - `clientData` contains custom data from the frontend (the `metadata` field from `sendMessage()`). |
187 | 189 | */ |
188 | | -export type ChatTaskPayload<TMessage extends UIMessage = UIMessage> = { |
189 | | - /** The conversation messages */ |
190 | | - messages: TMessage[]; |
| 190 | +export type ChatTaskPayload = { |
| 191 | + /** Model-ready messages — pass directly to `streamText({ messages })`. */ |
| 192 | + messages: ModelMessage[]; |
| 193 | + |
| 194 | + /** Raw UI messages from the frontend. */ |
| 195 | + uiMessages: UIMessage[]; |
191 | 196 |
|
192 | 197 | /** The unique identifier for the chat session */ |
193 | 198 | chatId: string; |
@@ -324,7 +329,7 @@ function isReadableStream(value: unknown): value is ReadableStream<unknown> { |
324 | 329 | * run: async (payload: ChatTaskPayload) => { |
325 | 330 | * const result = streamText({ |
326 | 331 | * model: openai("gpt-4o"), |
327 | | - * messages: convertToModelMessages(payload.messages), |
| 332 | + * messages: payload.messages, |
328 | 333 | * }); |
329 | 334 | * |
330 | 335 | * await chat.pipe(result); |
@@ -388,7 +393,7 @@ async function pipeChat( |
388 | 393 | * transport resumes the same run by sending the next message via input streams. |
389 | 394 | */ |
390 | 395 | export type ChatTaskOptions<TIdentifier extends string> = Omit< |
391 | | - TaskOptions<TIdentifier, ChatTaskPayload, unknown>, |
| 396 | + TaskOptions<TIdentifier, ChatTaskWirePayload, unknown>, |
392 | 397 | "run" |
393 | 398 | > & { |
394 | 399 | /** |
@@ -452,8 +457,8 @@ export type ChatTaskOptions<TIdentifier extends string> = Omit< |
452 | 457 | * run: async ({ messages, signal }) => { |
453 | 458 | * return streamText({ |
454 | 459 | * model: openai("gpt-4o"), |
455 | | - * messages: convertToModelMessages(messages), |
456 | | - * abortSignal: signal, // fires on stop or run cancel |
| 460 | + * messages, // already converted via convertToModelMessages |
| 461 | + * abortSignal: signal, |
457 | 462 | * }); |
458 | 463 | * }, |
459 | 464 | * }); |
@@ -503,14 +508,17 @@ function chatTask<TIdentifier extends string>( |
503 | 508 | pendingMessages.push(msg); |
504 | 509 | }); |
505 | 510 |
|
506 | | - // Remap wire payload to user-facing payload (metadata -> clientData) |
507 | | - const { metadata: wireMetadata, ...restWire } = currentWirePayload; |
| 511 | + // Convert wire payload to user-facing payload |
| 512 | + const { metadata: wireMetadata, messages: uiMessages, ...restWire } = currentWirePayload; |
| 513 | + const sanitized = sanitizeMessages(uiMessages); |
| 514 | + const modelMessages = await convertToModelMessages(sanitized); |
508 | 515 |
|
509 | 516 | try { |
510 | 517 | const result = await userRun({ |
511 | 518 | ...restWire, |
| 519 | + messages: modelMessages, |
| 520 | + uiMessages: sanitized, |
512 | 521 | clientData: wireMetadata, |
513 | | - messages: sanitizeMessages(currentWirePayload.messages), |
514 | 522 | signal: combinedSignal, |
515 | 523 | cancelSignal, |
516 | 524 | stopSignal, |
|
0 commit comments