From 19202c299668b385a2f3fc9d868d5677561f0bf0 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Thu, 21 May 2026 12:32:29 +0100 Subject: [PATCH] fix(references): repair ai-chat typecheck against current wire shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three categories of pre-existing typecheck errors in the reference project against the current SDK: - `payload.messages` (plural) → `payload.message` (singular, optional). The wire payload is now delta-only — one new message per trigger. Wrap as `payload.message ? [payload.message] : []` when handing off to `MessageAccumulator.addIncoming`, and read `msg.message` (not `msg.messages`) inside `chat.messages.on` handlers. - `clientData` on `onTurnStart` / `run` callbacks is typed as `?: TClientData` even when the agent declares a `clientDataSchema`. Use non-null assertion for now in cf-trust-test — the schema is validated at runtime before the hook fires. Worth narrowing the SDK type in a follow-up. - `stress-emit.parseConfig` typed against `UIMessage[]` but called with `ModelMessage[]` from the `run` callback. Retype against `ModelMessage[]` and extract text from `content` (string or array-of-parts). No SDK changes — all fixes are inside `references/ai-chat`. --- references/ai-chat/src/trigger/chat-client-test.ts | 2 +- references/ai-chat/src/trigger/chat.ts | 9 ++++----- references/ai-chat/src/trigger/stress-emit.ts | 14 ++++++++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/references/ai-chat/src/trigger/chat-client-test.ts b/references/ai-chat/src/trigger/chat-client-test.ts index 742246eca2a..a909034cfcf 100644 --- a/references/ai-chat/src/trigger/chat-client-test.ts +++ b/references/ai-chat/src/trigger/chat-client-test.ts @@ -272,7 +272,7 @@ export const orchestratorAgent = chat stop.reset(); const messages = await conversation.addIncoming( - currentPayload.messages, + currentPayload.message ? [currentPayload.message] : [], currentPayload.trigger, turn ); diff --git a/references/ai-chat/src/trigger/chat.ts b/references/ai-chat/src/trigger/chat.ts index 679a4b6d8a8..6033e9e3689 100644 --- a/references/ai-chat/src/trigger/chat.ts +++ b/references/ai-chat/src/trigger/chat.ts @@ -659,7 +659,7 @@ export const aiChatRaw = chat.customAgent({ stop.reset(); const messages = await conversation.addIncoming( - currentPayload.messages, + currentPayload.message ? [currentPayload.message] : [], currentPayload.trigger, turn ); @@ -678,8 +678,7 @@ export const aiChatRaw = chat.customAgent({ const combinedSignal = AbortSignal.any([runSignal, stop.signal]); const steeringSub = chat.messages.on(async (msg) => { - const lastMsg = msg.messages?.[msg.messages.length - 1]; - if (lastMsg) await conversation.steerAsync(lastMsg); + if (msg.message) await conversation.steerAsync(msg.message); }); const result = streamText({ @@ -1049,10 +1048,10 @@ export const cfTrustTestAgent = chat id: "cf-trust-test", idleTimeoutInSeconds: 60, onTurnStart: async ({ turn, clientData }) => { - logger.info("cf-trust-test turn", { turn, cf: clientData.__cf, userId: clientData.userId }); + logger.info("cf-trust-test turn", { turn, cf: clientData!.__cf, userId: clientData!.userId }); }, run: async ({ messages, clientData, signal }) => { - const cf = clientData.__cf; + const cf = clientData!.__cf; return streamText({ model: openai("gpt-4o-mini"), system: diff --git a/references/ai-chat/src/trigger/stress-emit.ts b/references/ai-chat/src/trigger/stress-emit.ts index b9300c6ae25..7443eb21315 100644 --- a/references/ai-chat/src/trigger/stress-emit.ts +++ b/references/ai-chat/src/trigger/stress-emit.ts @@ -10,7 +10,7 @@ // Defaults: 1000 chunks × 10 chars, single message. import { chat } from "@trigger.dev/sdk/ai"; -import { type UIMessage, simulateReadableStream, streamText } from "ai"; +import { type ModelMessage, simulateReadableStream, streamText } from "ai"; import { MockLanguageModelV3 } from "ai/test"; import type { LanguageModelV3StreamPart } from "@ai-sdk/provider"; @@ -20,10 +20,16 @@ type StressConfig = { manyMessages: boolean; }; -function parseConfig(messages: UIMessage[]): StressConfig { +function parseConfig(messages: ModelMessage[]): StressConfig { const lastUser = [...messages].reverse().find((m) => m.role === "user"); - const text = - lastUser?.parts?.[0]?.type === "text" ? lastUser.parts[0].text.trim() : ""; + const content = lastUser?.content; + let text = ""; + if (typeof content === "string") { + text = content.trim(); + } else if (Array.isArray(content)) { + const textPart = content.find((p) => p.type === "text"); + text = textPart && "text" in textPart ? textPart.text.trim() : ""; + } const parts = text.split(/\s+/); const chunkCount = Number(parts[0]); const chunkSize = Number(parts[1]);