Skip to content

Commit 1ea559a

Browse files
ericallamTrigger.dev RepoOps
authored andcommitted
docs: 4.8.0 follow-ups for agent examples, MCP secrets and self-hosted webhooks
Docs updates for 4.8.0: `chat.agent` examples use the `streamText` passed to `run()`, the webhook secret MCP tools document `previousSecretTtlSeconds`, self-hosting docs cover turning on webhooks and `KUBERNETES_POD_RESERVED_SOURCE_PORTS`, and the agents overview introduces channels. Mono-RevId: 3eb1ed33ef2e0e21cd1197391b71a3a7c57e9785
1 parent 8fbc76f commit 1ea559a

18 files changed

Lines changed: 114 additions & 85 deletions

‎docs/ai-chat/chat-local.mdx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Declare locals at module level with a unique `id`, then initialize them inside a
1616

1717
```ts
1818
import { chat } from "@trigger.dev/sdk/ai";
19-
import { streamText, tool, stepCountIs } from "ai";
19+
import { tool, stepCountIs } from "ai";
2020
import { anthropic } from "@ai-sdk/anthropic";
2121
import { z } from "zod";
2222
import { db } from "@/lib/db";
@@ -44,7 +44,7 @@ export const myChat = chat.agent({
4444
messageCount: user.messageCount,
4545
});
4646
},
47-
run: async ({ messages, signal }) => {
47+
run: async ({ messages, signal, streamText }) => {
4848
userContext.messageCount++;
4949

5050
return streamText({
@@ -88,7 +88,7 @@ When you use `ai.toolExecute()` inside AI SDK `tool()` to expose a subtask, chat
8888
```ts
8989
import { chat, ai } from "@trigger.dev/sdk/ai";
9090
import { schemaTask } from "@trigger.dev/sdk";
91-
import { streamText, tool } from "ai";
91+
import { tool, stepCountIs } from "ai";
9292
import { anthropic } from "@ai-sdk/anthropic";
9393
import { z } from "zod";
9494

@@ -115,7 +115,7 @@ export const myChat = chat.agent({
115115
onBoot: async ({ clientData }) => {
116116
userContext.init({ name: "Alice", plan: "pro" });
117117
},
118-
run: async ({ messages, signal }) => {
118+
run: async ({ messages, signal, streamText }) => {
119119
return streamText({
120120
model: anthropic("claude-sonnet-4-5"),
121121
messages,

‎docs/ai-chat/fast-starts.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const myChat = chat.agent({
8080
if (preloaded) return; // Already initialized in onPreload
8181
// ... fallback initialization for non-preloaded runs
8282
},
83-
run: async ({ messages, signal }) => {
83+
run: async ({ messages, signal, streamText }) => {
8484
return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal });
8585
},
8686
});

‎docs/ai-chat/overview.mdx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ See [Quick Start](/ai-chat/quick-start) for the matching server actions and a ru
5656

5757
## How it fits together
5858

59-
Three primitives, related but distinct:
59+
Four primitives, related but distinct:
6060

6161
- **Chat agents** — the SDK surface you define with [`chat.agent()`](/ai-chat/backend#chat-agent). Owns the turn loop, lifecycle hooks, and the response stream.
6262
- **Sessions** — the durable, bi-directional channel keyed on `chatId` that holds the conversation across run boundaries. A chat agent runs *on top of* a [Session](/ai-chat/sessions).
6363
- **Sub-agents** — Delegate work from one agent to another via [`AgentChat`](/ai-chat/patterns/sub-agents). The sub-agent runs as its own durable agent on its own session; its response streams back through the parent as preliminary tool results, so the frontend sees the sub-agent working inside the parent's tool card.
64+
- **Channels** connect an agent to a surface other than your frontend. [`slack()`](/webhooks/slack) and [`linear()`](/webhooks/linear) turn an agent into a Slack or Linear agent, and [`chat.channels.custom()`](/webhooks/channels) connects any chat surface that sends webhooks. Each conversation there is still a durable session, and the reply posts back to the surface.
6465

6566
## Next steps
6667

‎docs/ai-chat/patterns/database-persistence.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ export const myChat = chat.agent({
226226
}),
227227
]);
228228
},
229-
run: async ({ messages, signal }) => {
229+
run: async ({ messages, signal, streamText }) => {
230230
return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal });
231231
},
232232
});
@@ -254,7 +254,7 @@ End-to-end implementation across the three files involved: agent task, server ac
254254
<CodeGroup>
255255
```ts trigger/chat.ts
256256
import { chat } from "@trigger.dev/sdk/ai";
257-
import { streamText, stepCountIs } from "ai";
257+
import { stepCountIs } from "ai";
258258
import { anthropic } from "@ai-sdk/anthropic";
259259
import { z } from "zod";
260260
import { db } from "@/lib/db";
@@ -296,7 +296,7 @@ export const myChat = chat.agent({
296296
}),
297297
]);
298298
},
299-
run: async ({ messages, signal }) => {
299+
run: async ({ messages, signal, streamText }) => {
300300
return streamText({
301301
model: anthropic("claude-sonnet-4-5"),
302302
messages,

‎docs/ai-chat/patterns/native-compaction.mdx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ The fix: read the `appliedEdits` counts as they stream in `onStepFinish`, then a
3131

3232
```ts /trigger/native-persist.ts
3333
import { chat } from "@trigger.dev/sdk/ai";
34-
import { streamText, stepCountIs, tool, type UIMessage } from "ai";
34+
import { stepCountIs, tool, type UIMessage } from "ai";
3535
import { anthropic } from "@ai-sdk/anthropic";
3636
import { z } from "zod";
3737

@@ -75,7 +75,7 @@ export const nativePersist = chat.agent({
7575
id: "native-persist",
7676
idleTimeoutInSeconds: 120,
7777
tools: { fetchRecord },
78-
run: async ({ messages, chatId, tools, signal }) => {
78+
run: async ({ messages, chatId, tools, signal, streamText }) => {
7979
return streamText({
8080
model: anthropic("claude-sonnet-4-5"),
8181
messages,
@@ -132,7 +132,7 @@ OpenAI's `store: true` keeps the thread server-side and returns a `responseId`.
132132

133133
```ts /trigger/openai-store.ts
134134
import { chat } from "@trigger.dev/sdk/ai";
135-
import { streamText, stepCountIs, type ModelMessage } from "ai";
135+
import { stepCountIs, type ModelMessage } from "ai";
136136
import { openai } from "@ai-sdk/openai";
137137

138138
// Persist the stored-response handle between turns. Replace with your database.
@@ -151,7 +151,7 @@ function messagesSinceLastAssistant(messages: ModelMessage[]): ModelMessage[] {
151151
export const openaiStore = chat.agent({
152152
id: "openai-store",
153153
idleTimeoutInSeconds: 120,
154-
run: async ({ messages, chatId, signal }) => {
154+
run: async ({ messages, chatId, signal, streamText }) => {
155155
const native = nativeStore.get(chatId);
156156
const outbound = native ? messagesSinceLastAssistant(messages) : messages;
157157

@@ -186,7 +186,7 @@ A native handle is a per-provider cache. An OpenAI `previousResponseId` means no
186186

187187
```ts /trigger/resilient-chat.ts
188188
import { chat } from "@trigger.dev/sdk/ai";
189-
import { streamText, generateText, stepCountIs, generateId, type ModelMessage } from "ai";
189+
import { generateText, stepCountIs, generateId, type ModelMessage } from "ai";
190190
import { anthropic } from "@ai-sdk/anthropic";
191191
import { openai } from "@ai-sdk/openai";
192192

@@ -241,7 +241,7 @@ export const resilientChat = chat.agent({
241241
if (chatId) nativeStore.delete(chatId);
242242
},
243243

244-
run: async ({ messages, chatId, signal }) => {
244+
run: async ({ messages, chatId, signal, streamText }) => {
245245
let lastError: unknown;
246246
for (const providerId of FALLBACK_ORDER) {
247247
const native = nativeStore.get(chatId);

‎docs/ai-chat/patterns/sub-agents.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ const tools = { research: researchTool };
275275
export const myAgent = chat.agent({
276276
id: "orchestrator",
277277
tools, // declare here so toModelOutput survives across turns
278-
run: async ({ messages, tools, stopSignal }) => {
278+
run: async ({ messages, tools, stopSignal, streamText }) => {
279279
return streamText({
280280
model: anthropic("claude-sonnet-4-6"),
281281
messages,

‎docs/ai-chat/patterns/version-upgrades.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ On the agent side, declare which versions the current code supports:
100100

101101
```ts
102102
import { chat } from "@trigger.dev/sdk/ai";
103-
import { streamText } from "ai";
103+
104104
import { anthropic } from "@ai-sdk/anthropic";
105105

106106
// The set of frontend protocol versions this agent code supports.
@@ -121,7 +121,7 @@ export const myChat = chat
121121
chat.requestUpgrade();
122122
}
123123
},
124-
run: async ({ messages, signal }) => {
124+
run: async ({ messages, signal, streamText }) => {
125125
return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal });
126126
},
127127
});
@@ -183,7 +183,7 @@ export const myChat = chat
183183
chat.requestUpgrade();
184184
}
185185
},
186-
run: async ({ messages, signal }) => {
186+
run: async ({ messages, signal, streamText }) => {
187187
return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal });
188188
},
189189
});

‎docs/ai-chat/side-channels.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ Inside a `chat.agent` run, `chat.channel(...)` opens a channel on the current ru
3838

3939
```ts /trigger/browser-agent.ts
4040
import { chat } from "@trigger.dev/sdk/ai";
41-
import { streamText } from "ai";
41+
4242
import { screenshots } from "./channels";
4343

4444
export const browserAgent = chat.agent({
4545
id: "browser-agent",
46-
run: async ({ messages, signal }) => {
46+
run: async ({ messages, signal, streamText }) => {
4747
const frames = chat.channel(screenshots);
4848

4949
frames.in.on((control) => setPaused(control.paused)); // control: ViewportControl

‎docs/ai-chat/types.mdx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Call `withUIMessage` **once**, then chain `.agent({ ... })` instead of `chat.age
5656

5757
```ts
5858
import { chat } from "@trigger.dev/sdk/ai";
59-
import { streamText, tool } from "ai";
59+
import { tool } from "ai";
6060
import { anthropic } from "@ai-sdk/anthropic";
6161
import { z } from "zod";
6262
import type { MyChatUIMessage } from "./my-chat-types";
@@ -90,7 +90,7 @@ export const myChat = chat
9090
data: { status: "preparing" },
9191
});
9292
},
93-
run: async ({ messages, tools, signal }) => {
93+
run: async ({ messages, tools, signal, streamText }) => {
9494
// `tools` is myTools, typed, handed back on the payload
9595
return streamText({
9696
model: anthropic("claude-sonnet-4-5"),
@@ -156,7 +156,7 @@ export const myChat = chat
156156
// clientData is typed as { userId: string; model?: string }
157157
await initUser(clientData.userId);
158158
},
159-
run: async ({ messages, clientData, signal }) => {
159+
run: async ({ messages, clientData, signal, streamText }) => {
160160
return streamText({
161161
model: getModel(clientData.model),
162162
messages,
@@ -193,7 +193,7 @@ export const myChat = chat
193193
})
194194
.agent({
195195
id: "my-chat",
196-
run: async ({ messages, signal }) => {
196+
run: async ({ messages, signal, streamText }) => {
197197
return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal });
198198
},
199199
});
@@ -218,7 +218,7 @@ chat
218218
// Runs second — task-specific logic
219219
await createChatRecord(event.chatId);
220220
},
221-
run: async ({ messages, signal }) => {
221+
run: async ({ messages, signal, streamText }) => {
222222
return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal });
223223
},
224224
});

‎docs/ai/prompts.mdx‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ Prompts integrate with `chat.agent()` via `chat.prompt` — a run-scoped store f
219219
```ts
220220
import { chat } from "@trigger.dev/sdk/ai";
221221
import { prompts } from "@trigger.dev/sdk";
222-
import { streamText, createProviderRegistry } from "ai";
222+
import { createProviderRegistry, stepCountIs } from "ai";
223223
import { anthropic } from "@ai-sdk/anthropic";
224+
import { z } from "zod";
224225

225226
const registry = createProviderRegistry({ anthropic });
226227

@@ -234,13 +235,14 @@ const systemPrompt = prompts.define({
234235

235236
export const myChat = chat.agent({
236237
id: "my-chat",
238+
registry,
239+
clientDataSchema: z.object({ name: z.string() }),
237240
onChatStart: async ({ clientData }) => {
238241
const resolved = await systemPrompt.resolve({ name: clientData.name });
239242
chat.prompt.set(resolved);
240243
},
241-
run: async ({ messages, signal }) => {
244+
run: async ({ messages, signal, streamText }) => {
242245
return streamText({
243-
...chat.toStreamTextOptions({ registry }),
244246
messages,
245247
abortSignal: signal,
246248
stopWhen: stepCountIs(15),
@@ -249,9 +251,11 @@ export const myChat = chat.agent({
249251
});
250252
```
251253

254+
The `streamText` passed to `run()` applies the stored prompt: its system text, its model (resolved through the agent's `registry`), its `config`, and telemetry that links each generation to the prompt version. Options you pass at the call site win, apart from `system`, which throws when a prompt already sets one.
255+
252256
### chat.toStreamTextOptions()
253257

254-
Returns an options object ready to spread into `streamText()`. When a prompt is stored via `chat.prompt.set()`, it includes:
258+
Inside a `chat.agent` you don't need this: the `streamText` passed to `run()` applies the same options. Use `chat.toStreamTextOptions()` when you call `streamText` yourself, as in a [custom agent](/ai-chat/custom-agents). It returns an options object ready to spread into `streamText()`. When a prompt is stored via `chat.prompt.set()`, it includes:
255259

256260
- `system` — the compiled prompt text
257261
- `model` — resolved via the `registry` when provided
@@ -277,14 +281,13 @@ const options = chat.toStreamTextOptions();
277281
Access the stored prompt from anywhere in the run:
278282

279283
```ts
280-
run: async ({ messages, signal }) => {
284+
run: async ({ messages, signal, streamText }) => {
281285
const prompt = chat.prompt(); // Throws if not set
282286
console.log(prompt.text); // The compiled prompt
283287
console.log(prompt.model); // "anthropic:claude-sonnet-4-5"
284288
console.log(prompt.version); // 3
285289

286290
return streamText({
287-
...chat.toStreamTextOptions({ registry }),
288291
messages,
289292
abortSignal: signal,
290293
stopWhen: stepCountIs(15),

0 commit comments

Comments
 (0)