Skip to content

Commit 51841e8

Browse files
committed
Add triggerOptions to the transport, auto-tag with the chat ID
1 parent 8e05e75 commit 51841e8

File tree

4 files changed

+76
-257
lines changed

4 files changed

+76
-257
lines changed

.scratch/plan-graceful-oversized-batch-items.md

Lines changed: 0 additions & 257 deletions
This file was deleted.

docs/guides/ai-chat.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,10 @@ function ChatClient({ chatId, initialMessages, initialSessions }) {
488488
`resume: true` causes `useChat` to call `reconnectToStream` on the transport when the component mounts. The transport uses the session's `lastEventId` to skip past already-seen stream events, so the frontend only receives new data. Only enable `resume` when there are existing messages — for brand new chats, there's nothing to reconnect to.
489489
</Info>
490490

491+
<Warning>
492+
In React strict mode (enabled by default in Next.js dev), you may see a `TypeError: Cannot read properties of undefined (reading 'state')` in the console when using `resume`. This is a [known bug in the AI SDK](https://github.com/vercel/ai/issues/8477) caused by React strict mode double-firing the resume effect. The error is caught internally and **does not affect functionality** — streaming and message display work correctly. It only appears in development and will not occur in production builds.
493+
</Warning>
494+
491495
### Full example
492496

493497
Putting it all together — a complete chat app with server-side persistence, session reconnection, and stream resumption:
@@ -762,6 +766,32 @@ run: async ({ messages, signal }) => {
762766
| `metadata` | `Record<string, unknown>` || Default metadata for every request |
763767
| `sessions` | `Record<string, {...}>` || Restore sessions from storage |
764768
| `onSessionChange` | `(chatId, session \| null) => void` || Fires when session state changes |
769+
| `triggerOptions` | `{...}` || Options for the initial task trigger (see below) |
770+
771+
#### triggerOptions
772+
773+
Options forwarded to the Trigger.dev API when starting a new run. Only applies to the first message — subsequent messages reuse the same run.
774+
775+
A `chat:{chatId}` tag is automatically added to every run.
776+
777+
| Option | Type | Description |
778+
|--------|------|-------------|
779+
| `tags` | `string[]` | Additional tags for the run (merged with auto-tags, max 5 total) |
780+
| `queue` | `string` | Queue name for the run |
781+
| `maxAttempts` | `number` | Maximum retry attempts |
782+
| `machine` | `"micro" \| "small-1x" \| ...` | Machine preset for the run |
783+
| `priority` | `number` | Priority (lower = higher priority) |
784+
785+
```ts
786+
const transport = useTriggerChatTransport({
787+
task: "my-chat",
788+
accessToken: getChatToken,
789+
triggerOptions: {
790+
tags: ["user:123"],
791+
queue: "chat-queue",
792+
},
793+
});
794+
```
765795

766796
### useTriggerChatTransport
767797

packages/trigger-sdk/src/v3/chat.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,37 @@ export type TriggerChatTransportOptions = {
151151
chatId: string,
152152
session: { runId: string; publicAccessToken: string; lastEventId?: string } | null
153153
) => void;
154+
155+
/**
156+
* Options forwarded to the Trigger.dev API when starting a new run.
157+
* Only applies to the first message — subsequent messages reuse the same run.
158+
*
159+
* A `chat:{chatId}` tag is automatically added to every run.
160+
*
161+
* @example
162+
* ```ts
163+
* new TriggerChatTransport({
164+
* task: "my-chat",
165+
* accessToken,
166+
* triggerOptions: {
167+
* tags: ["user:123"],
168+
* queue: "chat-queue",
169+
* },
170+
* });
171+
* ```
172+
*/
173+
triggerOptions?: {
174+
/** Additional tags for the run. A `chat:{chatId}` tag is always added automatically. */
175+
tags?: string[];
176+
/** Queue name for the run. */
177+
queue?: string;
178+
/** Maximum retry attempts. */
179+
maxAttempts?: number;
180+
/** Machine preset for the run. */
181+
machine?: "micro" | "small-1x" | "small-2x" | "medium-1x" | "medium-2x" | "large-1x" | "large-2x";
182+
/** Priority (lower = higher priority). */
183+
priority?: number;
184+
};
154185
};
155186

156187
/**
@@ -202,6 +233,7 @@ export class TriggerChatTransport implements ChatTransport<UIMessage> {
202233
private readonly extraHeaders: Record<string, string>;
203234
private readonly streamTimeoutSeconds: number;
204235
private readonly defaultMetadata: Record<string, unknown> | undefined;
236+
private readonly triggerOptions: TriggerChatTransportOptions["triggerOptions"];
205237
private _onSessionChange:
206238
| ((
207239
chatId: string,
@@ -223,6 +255,7 @@ export class TriggerChatTransport implements ChatTransport<UIMessage> {
223255
this.extraHeaders = options.headers ?? {};
224256
this.streamTimeoutSeconds = options.streamTimeoutSeconds ?? DEFAULT_STREAM_TIMEOUT_SECONDS;
225257
this.defaultMetadata = options.metadata;
258+
this.triggerOptions = options.triggerOptions;
226259
this._onSessionChange = options.onSessionChange;
227260

228261
// Restore sessions from external storage
@@ -303,10 +336,20 @@ export class TriggerChatTransport implements ChatTransport<UIMessage> {
303336
const currentToken = await this.resolveAccessToken();
304337
const apiClient = new ApiClient(this.baseURL, currentToken);
305338

339+
// Auto-tag with chatId; merge with user-provided tags (API limit: 5 tags)
340+
const autoTags = [`chat:${chatId}`];
341+
const userTags = this.triggerOptions?.tags ?? [];
342+
const tags = [...autoTags, ...userTags].slice(0, 5);
343+
306344
const triggerResponse = await apiClient.triggerTask(this.taskId, {
307345
payload,
308346
options: {
309347
payloadType: "application/json",
348+
tags,
349+
queue: this.triggerOptions?.queue ? { name: this.triggerOptions.queue } : undefined,
350+
maxAttempts: this.triggerOptions?.maxAttempts,
351+
machine: this.triggerOptions?.machine,
352+
priority: this.triggerOptions?.priority,
310353
},
311354
});
312355

references/ai-chat/src/components/chat-app.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ export function ChatApp({
6262
baseURL: process.env.NEXT_PUBLIC_TRIGGER_API_URL,
6363
sessions: initialSessions,
6464
onSessionChange: handleSessionChange,
65+
triggerOptions: {
66+
tags: ["user:user_123"],
67+
},
6568
});
6669

6770
// Load messages when active chat changes

0 commit comments

Comments
 (0)