Document and demo @trigger.dev/ai useChat transport

Co-authored-by: Eric Allam <eric@trigger.dev>
This commit is contained in:
Cursor Agent
2026-02-14 23:19:36 +00:00
parent 0f932eb6ef
commit af510e668a
9 changed files with 365 additions and 58 deletions
+3 -3
View File
@@ -81,7 +81,7 @@ await myTask.trigger({ name: "Alice", age: 30, dob: "2020-01-01" }); // this is
The `ai.tool` function allows you to create an AI tool from an existing `schemaTask` to use with the Vercel [AI SDK](https://vercel.com/docs/ai-sdk):
```ts
import { ai } from "@trigger.dev/sdk/ai";
import { ai } from "@trigger.dev/ai";
import { schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";
import { generateText } from "ai";
@@ -118,7 +118,7 @@ You can also pass the `experimental_toToolResultContent` option to the `ai.tool`
```ts
import { openai } from "@ai-sdk/openai";
import { Sandbox } from "@e2b/code-interpreter";
import { ai } from "@trigger.dev/sdk/ai";
import { ai } from "@trigger.dev/ai";
import { schemaTask } from "@trigger.dev/sdk";
import { generateObject } from "ai";
import { z } from "zod";
@@ -183,7 +183,7 @@ export const chartTool = ai.tool(chartTask, {
You can access the current tool execution options inside the task run function using the `ai.currentToolOptions()` function:
```ts
import { ai } from "@trigger.dev/sdk/ai";
import { ai } from "@trigger.dev/ai";
import { schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";
+89
View File
@@ -517,6 +517,95 @@ const { parts, error } = useRealtimeStream(streamDef, runId, {
});
```
## AI SDK `useChat` transport with Trigger.dev tasks
If you want to use AI SDK UI's `useChat()` on the frontend and run the backend as a Trigger.dev task,
use the `@trigger.dev/ai` transport.
### Install
```bash
npm add @trigger.dev/ai @ai-sdk/react ai
```
### Define a typed stream
```ts
// app/streams.ts
import { streams } from "@trigger.dev/sdk";
import { UIMessageChunk } from "ai";
export const aiStream = streams.define<UIMessageChunk>({
id: "ai",
});
```
### Create a task that accepts rich chat transport payload
```ts
// trigger/chat-task.ts
import { openai } from "@ai-sdk/openai";
import type { TriggerChatTransportPayload } from "@trigger.dev/ai";
import { task } from "@trigger.dev/sdk";
import { convertToModelMessages, streamText, UIMessage } from "ai";
import { aiStream } from "@/app/streams";
type ChatPayload = TriggerChatTransportPayload<UIMessage>;
export const aiChatTask = task({
id: "ai-chat",
run: async (payload: ChatPayload) => {
const result = streamText({
model: openai("gpt-4o"),
messages: convertToModelMessages(payload.messages),
});
const { waitUntilComplete } = aiStream.pipe(result.toUIMessageStream());
await waitUntilComplete();
},
});
```
### Use `useChat()` with Trigger chat transport
```tsx
"use client";
import { useChat } from "@ai-sdk/react";
import { TriggerChatTransport } from "@trigger.dev/ai";
import { aiStream } from "@/app/streams";
export function Chat({ triggerToken }: { triggerToken: string }) {
const chat = useChat({
transport: new TriggerChatTransport({
task: "ai-chat",
stream: aiStream,
accessToken: triggerToken,
timeoutInSeconds: 120,
}),
});
return (
<form
onSubmit={(event) => {
event.preventDefault();
chat.sendMessage({ text: "Hello!" });
}}
>
<button type="submit">Send</button>
</form>
);
}
```
The default payload sent to your task is a rich, typed object that includes:
- `chatId`
- `trigger` (`"submit-message"` or `"regenerate-message"`)
- `messageId`
- `messages`
- `request` (`headers`, `body`, and `metadata`)
## Complete Example: AI Streaming
### Define the stream