@trigger.dev/sdk 4.8.0-webhooks.20261020092920 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/v3/ai.d.ts +2 -1
- package/dist/commonjs/v3/ai.js +18 -1
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/webhooks.d.ts +11 -3
- package/dist/commonjs/v3/webhooks.js +17 -1
- package/dist/commonjs/v3/webhooks.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai.d.ts +2 -1
- package/dist/esm/v3/ai.js +18 -1
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/webhooks.d.ts +11 -3
- package/dist/esm/v3/webhooks.js +17 -1
- package/dist/esm/v3/webhooks.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai/prompts.mdx +9 -6
- package/docs/ai-chat/backend.mdx +10 -7
- package/docs/ai-chat/chat-local.mdx +4 -4
- package/docs/ai-chat/client-protocol.mdx +6 -3
- package/docs/ai-chat/fast-starts.mdx +1 -1
- package/docs/ai-chat/overview.mdx +4 -3
- package/docs/ai-chat/patterns/database-persistence.mdx +3 -3
- package/docs/ai-chat/patterns/native-compaction.mdx +6 -6
- package/docs/ai-chat/patterns/redacting-telemetry.mdx +5 -5
- package/docs/ai-chat/patterns/sub-agents.mdx +1 -1
- package/docs/ai-chat/patterns/version-upgrades.mdx +3 -3
- package/docs/ai-chat/pending-messages.mdx +1 -1
- package/docs/ai-chat/reference.mdx +4 -4
- package/docs/ai-chat/side-channels.mdx +2 -2
- package/docs/ai-chat/types.mdx +5 -5
- package/docs/apikeys.mdx +1 -1
- package/docs/database-connections.mdx +2 -2
- package/docs/deploy-environment-variables.mdx +19 -0
- package/docs/introduction.mdx +104 -24
- package/docs/mcp-tools.mdx +5 -4
- package/docs/self-hosting/env/supervisor.mdx +1 -0
- package/docs/self-hosting/env/webapp.mdx +24 -0
- package/docs/self-hosting/overview.mdx +2 -0
- package/docs/webhooks/channels.mdx +29 -7
- package/docs/webhooks/connect.mdx +14 -7
- package/docs/webhooks/deliveries.mdx +8 -5
- package/docs/webhooks/filters.mdx +8 -4
- package/docs/webhooks/human-in-the-loop.mdx +9 -6
- package/docs/webhooks/linear.mdx +2 -5
- package/docs/webhooks/overview.mdx +16 -4
- package/docs/webhooks/session-routing.mdx +8 -5
- package/docs/webhooks/slack.mdx +44 -19
- package/docs/webhooks/sources.mdx +36 -7
- package/docs/webhooks/waiters.mdx +0 -4
- package/package.json +2 -2
package/docs/apikeys.mdx
CHANGED
|
@@ -83,7 +83,7 @@ Access presets define what a key can do. On the Free and Hobby plans only the **
|
|
|
83
83
|
| **Task operator** | Trigger all or selected tasks and inspect or operate on their runs |
|
|
84
84
|
| **Observer** | Read runs, tasks, batches, logs, traces, queues, errors, and webhooks |
|
|
85
85
|
| **Operator** | Observe and operate on runs, queues, errors, and webhooks, and trigger tasks |
|
|
86
|
-
| **Webhooks only** | Read and write [webhooks](/webhooks/overview)
|
|
86
|
+
| **Webhooks only** | Read and write [webhooks](/webhooks/overview). Replaying deliveries that trigger tasks and creating webhook waiters require task or waitpoint scopes |
|
|
87
87
|
| **Waitpoints only** | Create, list, and retrieve [waitpoint tokens](/wait-for-token). No task or run access |
|
|
88
88
|
| **Deploy only** | Deploy versions, sync environment variables, and manage Preview branches |
|
|
89
89
|
| **Variables only** | Read and write environment variables in this environment |
|
|
@@ -176,13 +176,13 @@ A chat agent runs one long-lived worker per conversation and suspends between me
|
|
|
176
176
|
|
|
177
177
|
```ts /trigger/chat.ts
|
|
178
178
|
import { chat } from "@trigger.dev/sdk/ai";
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
import { openai } from "@ai-sdk/openai";
|
|
181
181
|
import { prisma } from "@/lib/db";
|
|
182
182
|
|
|
183
183
|
export const myChat = chat.agent({
|
|
184
184
|
id: "my-chat",
|
|
185
|
-
run: async ({ messages, clientData, signal }) => {
|
|
185
|
+
run: async ({ messages, clientData, signal, streamText }) => {
|
|
186
186
|
const user = await prisma.user.findUnique({ where: { id: clientData.userId } });
|
|
187
187
|
// The connection is back in the pool before the model stream starts.
|
|
188
188
|
return streamText({
|
|
@@ -192,6 +192,25 @@ The context object provides:
|
|
|
192
192
|
|
|
193
193
|
For more information about the context object, see the [Context documentation](/context).
|
|
194
194
|
|
|
195
|
+
#### Linking to a run in the dashboard
|
|
196
|
+
|
|
197
|
+
Trigger.dev sets `TRIGGER_DASHBOARD_URL` on every run, in development and deployed environments. Its value is the dashboard's address without a trailing slash, so it also points at your own instance when you self-host. Append `/runs/<runId>` to link to a run:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import { task } from "@trigger.dev/sdk";
|
|
201
|
+
|
|
202
|
+
export const reportTask = task({
|
|
203
|
+
id: "report-task",
|
|
204
|
+
run: async (payload, { ctx }) => {
|
|
205
|
+
const runUrl = `${process.env.TRIGGER_DASHBOARD_URL}/runs/${ctx.run.id}`;
|
|
206
|
+
|
|
207
|
+
console.log(`View this run: ${runUrl}`);
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The `/runs/<runId>` link checks that the viewer is a member of the run's organization, then redirects to the full run page. If you set your own `TRIGGER_DASHBOARD_URL` environment variable on the project, your value is used instead.
|
|
213
|
+
|
|
195
214
|
### Sync env vars from another service
|
|
196
215
|
|
|
197
216
|
There are two ways to pull secrets from another service into Trigger.dev: a native **Secret Sync** (currently [Infisical](https://infisical.com)), or the `syncEnvVars` build extension for any other service.
|
package/docs/introduction.mdx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Trigger.dev docs"
|
|
3
3
|
sidebarTitle: "Introduction"
|
|
4
|
-
description: "Build and run durable AI agents and workflows in TypeScript. Long-running tasks with retries, queues, observability, and elastic scaling. Open source and self-hostable."
|
|
4
|
+
description: "Build and run durable AI agents and workflows in TypeScript. Long-running tasks with retries, queues, webhooks, observability, and elastic scaling. Open source and self-hostable."
|
|
5
5
|
mode: "center"
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -11,8 +11,8 @@ import AgentSetupPrompt from "/snippets/agent-setup-prompt.mdx";
|
|
|
11
11
|
<Card title="Quick start" icon="rocket" href="/quick-start" color="#A8FF53">
|
|
12
12
|
Go from zero to your first task in 3 minutes.
|
|
13
13
|
</Card>
|
|
14
|
-
<Card title="Build AI agents" icon="robot" href="/
|
|
15
|
-
|
|
14
|
+
<Card title="Build AI agents" icon="robot" href="/ai-chat/overview" color="#a855f7">
|
|
15
|
+
Durable, multi-turn agents with `chat.agent`, from your frontend to Slack and Linear.
|
|
16
16
|
</Card>
|
|
17
17
|
<Card title="AI coding assistants" icon="wand-magic-sparkles" href="/building-with-ai" color="#3B82F6">
|
|
18
18
|
Let Claude Code, Cursor and Windsurf write correct Trigger.dev code with the MCP server, Skills and rules.
|
|
@@ -28,48 +28,124 @@ import AgentSetupPrompt from "/snippets/agent-setup-prompt.mdx";
|
|
|
28
28
|
|
|
29
29
|
## What is Trigger.dev?
|
|
30
30
|
|
|
31
|
-
Trigger.dev is the open source platform for building and running durable AI agents and workflows in TypeScript.
|
|
31
|
+
Trigger.dev is the open source platform for building and running durable AI agents and workflows in TypeScript. You write tasks and agents in your existing codebase, and they run on Trigger.dev with retries, queues, waits, full tracing, and elastic scaling. There's no execution timeout, and no queue or worker infrastructure for you to build.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Trigger.dev's core is Apache-2.0 licensed. [Self-host it](/self-hosting/overview) on your own infrastructure, or let [Trigger.dev Cloud](https://cloud.trigger.dev) run it for you.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
## Build agents with `chat.agent`
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
A `chat.agent` runs each conversation as one durable task. It wakes when a message arrives and idles between turns, and its state survives page refreshes, deploys, and crashes. Turn lifecycle, resuming a stream mid-reply, and approvals are handled for you, and your frontend connects with the AI SDK's `useChat`, with no API routes to write.
|
|
38
|
+
|
|
39
|
+
```ts trigger/chat.ts
|
|
40
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
41
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
42
|
+
|
|
43
|
+
export const supportAgent = chat.agent({
|
|
44
|
+
id: "support-agent",
|
|
45
|
+
run: async ({ messages, signal, streamText }) =>
|
|
46
|
+
streamText({
|
|
47
|
+
model: anthropic("claude-sonnet-4-5"),
|
|
48
|
+
messages,
|
|
49
|
+
abortSignal: signal,
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
<CardGroup cols={3}>
|
|
55
|
+
<Card title="Agent quick start" icon="rocket" href="/ai-chat/quick-start">
|
|
56
|
+
Build a chat agent and its frontend end to end.
|
|
57
|
+
</Card>
|
|
58
|
+
<Card title="Sessions" icon="layer-group" href="/ai-chat/sessions">
|
|
59
|
+
Each conversation's durable state and two-way stream, across all its runs.
|
|
60
|
+
</Card>
|
|
61
|
+
<Card title="Tools" icon="screwdriver-wrench" href="/ai-chat/tools">
|
|
62
|
+
Declare tools on your agent and get them back typed in `run()`.
|
|
63
|
+
</Card>
|
|
64
|
+
<Card title="Human in the loop" icon="hand" href="/ai-chat/patterns/human-in-the-loop">
|
|
65
|
+
Pause a tool call for approval and resume when a person decides.
|
|
66
|
+
</Card>
|
|
67
|
+
<Card title="Slack agents" icon="slack" href="/webhooks/slack">
|
|
68
|
+
Turn an agent into a native Slack agent with `@trigger.dev/slack`.
|
|
69
|
+
</Card>
|
|
70
|
+
<Card title="Linear agents" icon="list-check" href="/webhooks/linear">
|
|
71
|
+
Assign Linear issues to an agent with `@trigger.dev/linear`.
|
|
72
|
+
</Card>
|
|
73
|
+
</CardGroup>
|
|
74
|
+
|
|
75
|
+
Version your [prompts](/ai/prompts) in code and change them from the dashboard, and see every model step and tool call, with tokens, cost and latency, in [AI observability](/ai/observability).
|
|
76
|
+
|
|
77
|
+
## Run work
|
|
38
78
|
|
|
39
79
|
<CardGroup cols={2}>
|
|
40
80
|
<Card title="Writing tasks" icon="pen-to-square" href="/tasks/overview" color="#A8FF53">
|
|
41
|
-
The durable functions at the core of Trigger.dev
|
|
81
|
+
The durable functions at the core of Trigger.dev, written in your existing codebase.
|
|
42
82
|
</Card>
|
|
43
83
|
<Card title="Triggering tasks" icon="bullseye-pointer" href="/triggering" color="#3b82f6">
|
|
44
|
-
Trigger a task from your backend, your frontend,
|
|
84
|
+
Trigger a task from your backend, your frontend, or another task.
|
|
45
85
|
</Card>
|
|
46
86
|
<Card title="Runs" icon="play" href="/runs" color="#28bf5c">
|
|
47
|
-
Every execution of a task is a run, with its status, retries, and
|
|
87
|
+
Every execution of a task is a run, with its status, retries, logs and trace.
|
|
88
|
+
</Card>
|
|
89
|
+
<Card title="Realtime" icon="bolt" href="/realtime/overview" color="#F43F5E">
|
|
90
|
+
Stream run status and LLM output to your frontend with React hooks.
|
|
91
|
+
</Card>
|
|
92
|
+
</CardGroup>
|
|
93
|
+
|
|
94
|
+
## React to events
|
|
95
|
+
|
|
96
|
+
<CardGroup cols={2}>
|
|
97
|
+
<Card title="Webhooks" icon="webhook" href="/webhooks/overview" color="#a855f7">
|
|
98
|
+
Hosted, verified endpoints for Stripe, GitHub and more, delivered to your tasks and agents.
|
|
99
|
+
</Card>
|
|
100
|
+
<Card title="Scheduled tasks" icon="clock" href="/tasks/scheduled" color="#f6cd46">
|
|
101
|
+
Run a task on a cron schedule, with timezone support.
|
|
102
|
+
</Card>
|
|
103
|
+
<Card title="Webhook waiters" icon="bell" href="/webhooks/waiters" color="#3b82f6">
|
|
104
|
+
Pause a run until a matching webhook arrives, like a payment confirmation.
|
|
48
105
|
</Card>
|
|
49
|
-
<Card title="
|
|
50
|
-
|
|
106
|
+
<Card title="Waits" icon="hourglass" href="/wait" color="#28bf5c">
|
|
107
|
+
Pause a run for a duration, until a date, or until a token is completed. A waiting run doesn't use compute.
|
|
51
108
|
</Card>
|
|
52
109
|
</CardGroup>
|
|
53
110
|
|
|
54
|
-
##
|
|
111
|
+
## Run in production
|
|
55
112
|
|
|
56
|
-
|
|
113
|
+
<CardGroup cols={2}>
|
|
114
|
+
<Card title="Queues & concurrency" icon="layer-group" href="/queues" color="#3b82f6">
|
|
115
|
+
Control how many runs execute at once, globally or per tenant.
|
|
116
|
+
</Card>
|
|
117
|
+
<Card title="Machines" icon="microchip" href="/machines" color="#a855f7">
|
|
118
|
+
Choose the CPU and memory each task runs on.
|
|
119
|
+
</Card>
|
|
120
|
+
<Card title="Deployment" icon="cloud-arrow-up" href="/deployment/overview" color="#28bf5c">
|
|
121
|
+
Atomic, versioned deploys, with preview branches and environments.
|
|
122
|
+
</Card>
|
|
123
|
+
<Card title="Errors & retries" icon="arrows-rotate" href="/errors-retrying" color="#F43F5E">
|
|
124
|
+
Retry failed attempts automatically, and decide what happens when a task throws.
|
|
125
|
+
</Card>
|
|
126
|
+
<Card title="Logs, traces & metrics" icon="chart-line" href="/logging" color="#f6cd46">
|
|
127
|
+
A full trace of every run, with your logs and spans.
|
|
128
|
+
</Card>
|
|
129
|
+
<Card title="Query & dashboards" icon="table" href="/observability/query" color="#A8FF53">
|
|
130
|
+
Query your runs with TRQL, and build dashboards from the results.
|
|
131
|
+
</Card>
|
|
132
|
+
</CardGroup>
|
|
57
133
|
|
|
58
|
-
##
|
|
134
|
+
## Frequently asked questions
|
|
59
135
|
|
|
60
|
-
|
|
136
|
+
**Can I use Trigger.dev for background jobs, not just AI?** Yes. The same durable tasks, queues, retries, and [cron schedules](/tasks/scheduled) run any background job or workflow, with or without AI.
|
|
61
137
|
|
|
62
|
-
|
|
138
|
+
**How long can a run take?** As long as it needs. Runs have no maximum duration by default, and you can set a [`maxDuration`](/runs/max-duration) for a project, a task, or a single run to cap it.
|
|
63
139
|
|
|
64
|
-
Trigger.dev
|
|
140
|
+
**Do my serverless function timeouts apply?** No. Tasks run on Trigger.dev, not inside your serverless functions, so your platform's function timeout isn't in the execution path. Your backend triggers the task and returns.
|
|
65
141
|
|
|
66
|
-
|
|
142
|
+
**Can I receive webhooks without running a server?** Yes. Declare a [webhook endpoint](/webhooks/overview) in your code, and Trigger.dev hosts its URL, verifies each request, and delivers the event to your tasks and agents.
|
|
67
143
|
|
|
68
|
-
**How do I add human-in-the-loop approval
|
|
144
|
+
**How do I add human-in-the-loop approval?** Pause the run on a [waitpoint](/wait-for-token) until a person approves, or use a [chat agent's approvals](/ai-chat/patterns/human-in-the-loop) for tool calls. A waiting run doesn't use compute, so it can wait minutes or days.
|
|
69
145
|
|
|
70
146
|
**Does Trigger.dev support tool calling and MCP?** Yes. Agents call the tools you define, and the [MCP server](/building-with-ai) lets AI coding assistants trigger tasks, deploy, and read run traces.
|
|
71
147
|
|
|
72
|
-
**Can I
|
|
148
|
+
**Can I self-host?** Yes. Trigger.dev is open source. Read the [self-hosting overview](/self-hosting/overview), or set it up with [Docker](/self-hosting/docker) or [Kubernetes](/self-hosting/kubernetes).
|
|
73
149
|
|
|
74
150
|
## Getting help
|
|
75
151
|
|
|
@@ -85,7 +161,7 @@ We'd love to hear from you or give you a hand getting started. Here are some way
|
|
|
85
161
|
Our Discord is the best place to get help with any questions about Trigger.dev.
|
|
86
162
|
</Card>
|
|
87
163
|
<Card
|
|
88
|
-
title="Follow us on X
|
|
164
|
+
title="Follow us on X"
|
|
89
165
|
icon={
|
|
90
166
|
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 512 512">
|
|
91
167
|
<path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z" />
|
|
@@ -112,7 +188,7 @@ We'd love to hear from you or give you a hand getting started. Here are some way
|
|
|
112
188
|
href="https://github.com/triggerdotdev/trigger.dev"
|
|
113
189
|
color="#fbbf24"
|
|
114
190
|
>
|
|
115
|
-
Check
|
|
191
|
+
Check out our GitHub repo, and give us a star if you like what we're doing.
|
|
116
192
|
</Card>
|
|
117
193
|
</CardGroup>
|
|
118
194
|
|
|
@@ -122,12 +198,16 @@ We'd love to hear from you or give you a hand getting started. Here are some way
|
|
|
122
198
|
|
|
123
199
|
**Current major version:** v4 (`@trigger.dev/sdk` 4.x). Documentation under `/docs/v2` and `/docs/v3` describes superseded versions and should not be used.
|
|
124
200
|
|
|
125
|
-
**Execution model:** tasks run on Trigger.dev infrastructure, not inside your serverless functions, so a platform function timeout is not in the execution path.
|
|
201
|
+
**Execution model:** tasks run on Trigger.dev infrastructure, not inside your serverless functions, so a platform function timeout is not in the execution path. Runs have no maximum duration by default; `maxDuration` caps a run's compute time for a project, a task, or a single run, and `timeout.None` removes the cap.
|
|
126
202
|
|
|
127
203
|
**Deploys:** each deploy is an atomic version. A run already in progress is not affected by code shipped after it started.
|
|
128
204
|
|
|
129
205
|
**Durability and retries:** retries are automatic and configurable. A failed attempt is retried according to the task's retry settings; once retries are exhausted the run ends terminally as `FAILED`, and some crashes (for example out of memory) end the run as `CRASHED` without a retry. Idempotency keys deduplicate the task triggers and waits you key, so the same key runs once instead of again.
|
|
130
206
|
|
|
207
|
+
**Agents:** `chat.agent` is imported from `@trigger.dev/sdk/ai`, not from `@trigger.dev/sdk`. Inside `run()`, call the `streamText` passed in the run options. It records each model step and tool call as a span by default. Slack and Linear agents use the `@trigger.dev/slack` and `@trigger.dev/linear` packages, and `slack()` requires a `startOn` filter (`appMentions()` answers @mentions).
|
|
208
|
+
|
|
209
|
+
**Webhooks:** `webhooks.endpoint.define()` declares a hosted, verified endpoint that syncs on `trigger dev` and on deploy; `webhook()` subscribes a task with a filter, and `webhooks.waiter` pauses a run until a matching event arrives. Both come from `@trigger.dev/sdk`.
|
|
210
|
+
|
|
131
211
|
**License:** the platform core is Apache-2.0 and the `@trigger.dev/sdk` package is MIT, permissive open source, not fair-code or source-available. Some features are gated, but the open source core is not relicensed or held back.
|
|
132
212
|
|
|
133
213
|
**LLM observability coverage:** only Vercel AI SDK calls (`generateText`, `streamText`, `generateObject`) are recorded as spans. Raw `fetch` calls and provider SDKs used directly are not captured.
|
package/docs/mcp-tools.mdx
CHANGED
|
@@ -4,8 +4,6 @@ sidebarTitle: "Tools"
|
|
|
4
4
|
description: "Learn about how to use the tools available in the Trigger.dev MCP Server"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaNote from "/snippets/webhooks-beta-note.mdx";
|
|
8
|
-
|
|
9
7
|
## Documentation and Search Tools
|
|
10
8
|
|
|
11
9
|
### search_docs
|
|
@@ -352,8 +350,6 @@ Append one record to a named side channel's `in` stream. Sends control input to
|
|
|
352
350
|
|
|
353
351
|
## Webhook Tools
|
|
354
352
|
|
|
355
|
-
<WebhooksBetaNote />
|
|
356
|
-
|
|
357
353
|
Set up and debug [hosted webhook endpoints](/webhooks/overview). Endpoint ids start with `wh_` and delivery ids with `whd_`; endpoint tools also accept an endpoint's declared id. The same operations are on the [Webhooks API](/management/webhooks/list-endpoints).
|
|
358
354
|
|
|
359
355
|
### list_webhook_endpoints
|
|
@@ -415,6 +411,10 @@ Generate a new signing secret for an endpoint and return it once, for providers
|
|
|
415
411
|
|
|
416
412
|
**Parameters:**
|
|
417
413
|
- `endpointId` (required): the endpoint's declared id (such as `payments`) or `wh_` id
|
|
414
|
+
- `previousSecretTtlSeconds` (optional): keep accepting the replaced secret for this many seconds (up to 604800, 7 days) while the provider switches to the new one. Omit it, or pass `0`, to replace the secret immediately, for example when it leaked. The response says when the old secret stops working.
|
|
415
|
+
|
|
416
|
+
**Example usage:**
|
|
417
|
+
- `"Rotate the GitHub endpoint's secret and keep the old one working for a day"`
|
|
418
418
|
|
|
419
419
|
### set_webhook_secret
|
|
420
420
|
|
|
@@ -423,6 +423,7 @@ Store a signing secret or public key the provider issued, such as Stripe's `whse
|
|
|
423
423
|
**Parameters:**
|
|
424
424
|
- `endpointId` (required): the endpoint's declared id (such as `payments`) or `wh_` id
|
|
425
425
|
- `secret` (required): the secret or public key
|
|
426
|
+
- `previousSecretTtlSeconds` (optional): keep accepting the replaced secret for this many seconds (up to 604800, 7 days) while the provider switches to the new one. Omit it, or pass `0`, to replace the secret immediately, for example when it leaked. The response says when the old secret stops working.
|
|
426
427
|
|
|
427
428
|
<Callout type="warning">
|
|
428
429
|
`replay_webhook_delivery`, `generate_webhook_secret` and `set_webhook_secret` are write operations and are not available in readonly mode.
|
|
@@ -52,6 +52,7 @@ mode: "wide"
|
|
|
52
52
|
| `KUBERNETES_IMAGE_PULL_SECRETS` | No | — | Image pull secrets (CSV). |
|
|
53
53
|
| `KUBERNETES_EPHEMERAL_STORAGE_SIZE_LIMIT` | No | 10Gi | Ephemeral storage size limit. Applies to all runs. |
|
|
54
54
|
| `KUBERNETES_EPHEMERAL_STORAGE_SIZE_REQUEST` | No | 2Gi | Ephemeral storage size request. Applies to all runs. |
|
|
55
|
+
| `KUBERNETES_POD_RESERVED_SOURCE_PORTS` | No | — | Ports runs never use as the source port of an outbound connection, so they can't clash with services on those ports. CSV of ports or ranges, e.g. `50080,50081` or `50080-50090`. Sets the pod's `net.ipv4.ip_local_reserved_ports` sysctl. |
|
|
55
56
|
| **Metrics** | | | |
|
|
56
57
|
| `METRICS_ENABLED` | No | true | Enable metrics. |
|
|
57
58
|
| `METRICS_COLLECT_DEFAULTS` | No | true | Collect default metrics. |
|
|
@@ -192,6 +192,18 @@ mode: "wide"
|
|
|
192
192
|
| `RUN_ENGINE_DEFAULT_MAX_TTL` | No | — | Maximum TTL for all runs (e.g. "14d"). Runs without a TTL use this as default; runs with a larger TTL are clamped. |
|
|
193
193
|
| `MAXIMUM_DEV_QUEUE_SIZE` | No | — | Maximum queued runs per queue in development environments. |
|
|
194
194
|
| `MAXIMUM_DEPLOYED_QUEUE_SIZE` | No | — | Maximum queued runs per queue in deployed (staging/prod) environments. |
|
|
195
|
+
| **Webhooks** | | | |
|
|
196
|
+
| `WEBHOOK_ENABLED` | No | 0 | Set to `1` to run hosted webhooks: ingest, delivery and waiters. See [Webhooks](#webhooks). |
|
|
197
|
+
| `WEBHOOK_REDIS_HOST` | No | localhost | A node of the Redis cluster webhooks use for their queue and waiters. It must run in cluster mode. |
|
|
198
|
+
| `WEBHOOK_REDIS_PORT` | No | 6379 | Port of that node. |
|
|
199
|
+
| `WEBHOOK_REDIS_USERNAME` | No | — | Webhooks Redis username. |
|
|
200
|
+
| `WEBHOOK_REDIS_PASSWORD` | No | — | Webhooks Redis password. |
|
|
201
|
+
| `WEBHOOK_REDIS_TLS_DISABLED` | No | `REDIS_TLS_DISABLED` | Set to `true` to connect to the webhooks Redis without TLS. |
|
|
202
|
+
| `WEBHOOK_INGRESS_ORIGIN` | No | `API_ORIGIN` | Public origin of the webhook URLs, for when you serve them from their own host. |
|
|
203
|
+
| `WEBHOOK_INGRESS_BODY_SIZE_LIMIT_MB` | No | 1 | Largest webhook request body accepted, in MB. |
|
|
204
|
+
| `WEBHOOK_DATABASE_URL` | No | `DATABASE_URL` | A separate PostgreSQL database for webhook endpoints and deliveries. |
|
|
205
|
+
| `WEBHOOK_DELIVERY_RETENTION_DAYS` | No | 30 | How many days of deliveries the dashboard and API show. It doesn't delete anything: deliveries are kept for `WEBHOOK_DELIVERY_STORAGE_DAYS`, or longer when this is higher. |
|
|
206
|
+
| `WEBHOOK_DELIVERY_STORAGE_DAYS` | No | 30 | How long deliveries are stored before they're deleted. Must be one of `3`, `7`, `30`, `90`, `180` or `365`; any other value stops the webapp from starting. |
|
|
195
207
|
| **Misc** | | | |
|
|
196
208
|
| `TRIGGER_TELEMETRY_DISABLED` | No | — | Disable telemetry. |
|
|
197
209
|
| `NODE_MAX_OLD_SPACE_SIZE` | No | 8192 | Maximum memory allocation for Node.js heap in MiB (e.g. "4096" for 4GB). |
|
|
@@ -202,6 +214,18 @@ mode: "wide"
|
|
|
202
214
|
| `ADMIN_DASHBOARD_ENABLED` | No | 1 | Set to anything other than `1` or `true` to disable the admin dashboard and user impersonation on this instance. |
|
|
203
215
|
| `EVENT_LOOP_MONITOR_ENABLED` | No | 1 | Node.js event loop lag monitor. |
|
|
204
216
|
|
|
217
|
+
## Webhooks
|
|
218
|
+
|
|
219
|
+
Hosted webhooks are off on a self-hosted instance until you turn them on:
|
|
220
|
+
|
|
221
|
+
1. Run a Redis (or Valkey) cluster for webhooks and point `WEBHOOK_REDIS_HOST` and `WEBHOOK_REDIS_PORT` at one of its nodes. The webhook engine connects in cluster mode, so a standalone Redis won't work.
|
|
222
|
+
2. Set `WEBHOOK_ENABLED=1` on the webapp.
|
|
223
|
+
3. Give organizations access with the `hasWebhooksAccess` feature flag: turn it on for everyone on the admin dashboard's **Global Feature Flags** page, or for one organization from its feature flags on the **Organizations** page. An organization without it doesn't see Webhooks in the dashboard, and its deploys don't sync endpoints.
|
|
224
|
+
|
|
225
|
+
Webhook URLs are served from `WEBHOOK_INGRESS_ORIGIN`, which defaults to `API_ORIGIN`, so providers need to reach that origin from the internet.
|
|
226
|
+
|
|
227
|
+
The Docker Compose setup only passes the variables listed under the webapp service's `environment` in `hosting/docker/webapp/docker-compose.yml`, so add the webhook variables there. With the Helm chart, set them in `webapp.extraEnvVars`.
|
|
228
|
+
|
|
205
229
|
## Multi-Provider Object Storage
|
|
206
230
|
|
|
207
231
|
The object storage system supports multiple S3-compatible providers (R2, S3, GCS, MinIO, etc.) using protocol prefixes. This enables migrating between providers without breaking existing runs.
|
|
@@ -121,6 +121,8 @@ You own a custom base image. It must provide:
|
|
|
121
121
|
|
|
122
122
|
A `DEPLOY_BUILD_BASE_IMAGES` image needs everything the base image provides, plus `python3`, `make` and `g++`. Build extensions that add image instructions are replayed on it. Without an entry, the build stage uses the published build image, except for projects whose build extensions add image instructions: those build from your base image and install the toolchain with `apt-get`, so that base must be Debian-based. To avoid the published images entirely, set both variables.
|
|
123
123
|
|
|
124
|
+
A custom image is yours to harden. Deploys on the published images remove trust in publicly compromised certificate authorities and point Node.js and Python at the OS trust store. Stages built on a custom image get neither, and run with the certificate settings the image ships with. Keeping a custom image patched, trust store included, is your responsibility.
|
|
125
|
+
|
|
124
126
|
<Warning>
|
|
125
127
|
`image.pkgs` and build extensions that run `apt-get` (such as `aptGet` and `playwright`) assume a
|
|
126
128
|
Debian base. On other distributions, install those packages in your base image instead.
|
|
@@ -4,10 +4,6 @@ description: "Point Slack (or any chat surface) at an agent: messages become tur
|
|
|
4
4
|
sidebarTitle: "Channels"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaBanner from "/snippets/webhooks-beta-banner.mdx";
|
|
8
|
-
|
|
9
|
-
<WebhooksBetaBanner />
|
|
10
|
-
|
|
11
7
|
A [session route](/webhooks/session-routing) delivers a verified event to an agent as an [action](/ai-chat/actions): the agent reacts, and the response is a side effect. A **channel** is the other half: the webhook IS the chat surface. Inbound messages become **turns** (the normal `run()` loop), and the agent's reply is posted **back** to the surface. A Slack thread becomes a real conversation with the agent, exactly like the browser chat, just a different frontend.
|
|
12
8
|
|
|
13
9
|
List channels on a [`chat.agent`](/ai-chat/overview) alongside (or instead of) `events`:
|
|
@@ -15,14 +11,21 @@ List channels on a [`chat.agent`](/ai-chat/overview) alongside (or instead of) `
|
|
|
15
11
|
```ts
|
|
16
12
|
import { webhooks } from "@trigger.dev/sdk";
|
|
17
13
|
import { chat } from "@trigger.dev/sdk/ai";
|
|
18
|
-
import { slack, webhookSource } from "@trigger.dev/slack";
|
|
14
|
+
import { appMentions, slack, webhookSource } from "@trigger.dev/slack";
|
|
19
15
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
20
16
|
|
|
21
17
|
const slackEvents = webhooks.endpoint.define({ id: "slack", source: webhookSource() });
|
|
22
18
|
|
|
23
19
|
export const supportAgent = chat.agent({
|
|
24
20
|
id: "support-agent",
|
|
25
|
-
channels: [
|
|
21
|
+
channels: [
|
|
22
|
+
slack({
|
|
23
|
+
id: "support-slack",
|
|
24
|
+
endpoint: slackEvents,
|
|
25
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
26
|
+
startOn: appMentions(),
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
26
29
|
run: async ({ messages, streamText }) =>
|
|
27
30
|
streamText({ model: anthropic("claude-sonnet-4-5"), messages }),
|
|
28
31
|
});
|
|
@@ -74,6 +77,25 @@ An event that `inbound` maps to an empty message (no text, and no file or data p
|
|
|
74
77
|
|
|
75
78
|
List the connector in `chat.agent({ channels: [mySurface] })`, which subscribes the agent to the endpoint with the id `agentId:connectorId`. Other subscribers on the endpoint keep receiving its deliveries.
|
|
76
79
|
|
|
80
|
+
## When a turn fails
|
|
81
|
+
|
|
82
|
+
When a turn fails (the model or provider returns an error, or the turn throws), the channel shows a short line instead of the error: "Something went wrong answering this. Try again." by default, or the connector's `errorMessage`. If the reply had partly streamed, the line goes after that text. The error is logged on the run, and `outbound` receives it as `reply.error`, so you can render a failure differently.
|
|
83
|
+
|
|
84
|
+
`errorMessage` is a fixed string, or a function that builds the line from the failure. It receives the `error`, the `partialText` streamed before it failed, the triggering `event` (undefined on a turn the channel didn't start), the `runId`, the `chatId`, and the `defaultMessage`. Return nothing, or throw, to fall back to the default line.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
slack({
|
|
88
|
+
id: "slack",
|
|
89
|
+
endpoint: slackEvents,
|
|
90
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
91
|
+
startOn: appMentions(),
|
|
92
|
+
errorMessage: ({ error, runId }) =>
|
|
93
|
+
error.message.includes("rate limit")
|
|
94
|
+
? "I'm getting a lot of requests right now. Try again in a minute."
|
|
95
|
+
: `Something went wrong answering this. Try again, or share ref ${runId} with support.`,
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
77
99
|
## Stopping a turn from the channel
|
|
78
100
|
|
|
79
101
|
A connector can map an event to a control with `onControl`. Returning `{ kind: "stop" }` while a turn is running aborts it through the run's `stopSignal`, exactly like the browser's stop button: the partial reply posts with `stopped: true` and the event is consumed instead of running as a turn. `linear()` and `slack()` map their stop buttons this way; a custom connector might map a `/stop` command:
|
|
@@ -92,7 +114,7 @@ When nothing is running, the event is handled by `inbound` as an ordinary messag
|
|
|
92
114
|
Two more hooks let a connector mirror the session into a surface that has its own notion of an agent, the way `slack()` does:
|
|
93
115
|
|
|
94
116
|
- `lifecycle(state, ctx)` reports `working` when a turn starts (and every 50 minutes while it runs), `waiting` when it pauses on a human decision, `idle` when it ends for any reason, and `closed` on `chat.close()`. `ctx.firstTurn` and `ctx.prompt` are there to title a new conversation. Calls are serialized, so an older report never lands after a newer one.
|
|
95
|
-
- `stream(ctx)`, with `delivery: "stream"`, returns a per-turn transport `{ text(delta), progress?(event), end(outcome) }`. The runtime feeds it the reply's markdown deltas and tool progress, then calls `end({ stopped, pending, errorText? })` once. Resolve `{ delivered: true }` when the reply reached the surface, and the runtime does not post it again. Call `ctx.opened(ref)` once the surface has created the stream message: the ref is saved with the session while the turn runs, and if the worker dies mid-stream the next one calls the connector's `endInterruptedStream(ref, ctx)` before it answers, so the old stream does not look like it is still being written.
|
|
117
|
+
- `stream(ctx)`, with `delivery: "stream"`, returns a per-turn transport `{ text(delta), progress?(event), end(outcome) }`. The runtime feeds it the reply's markdown deltas and tool progress, then calls `end({ stopped, pending, errorText? })` once, with the connector's error line as `errorText` when the turn failed. Resolve `{ delivered: true }` when the reply reached the surface, and the runtime does not post it again. Call `ctx.opened(ref)` once the surface has created the stream message: the ref is saved with the session while the turn runs, and if the worker dies mid-stream the next one calls the connector's `endInterruptedStream(ref, ctx)` before it answers, so the old stream does not look like it is still being written.
|
|
96
118
|
|
|
97
119
|
## Bound sessions
|
|
98
120
|
|
|
@@ -4,10 +4,6 @@ description: "Register an endpoint's URL and signing secret with the provider, b
|
|
|
4
4
|
sidebarTitle: "Connect a provider"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaBanner from "/snippets/webhooks-beta-banner.mdx";
|
|
8
|
-
|
|
9
|
-
<WebhooksBetaBanner />
|
|
10
|
-
|
|
11
7
|
Connect a provider to an [endpoint](/webhooks/overview) by registering the endpoint's URL with the provider and giving Trigger.dev the credential that verifies its requests.
|
|
12
8
|
|
|
13
9
|
Deploy the project or start `trigger dev` first. Once the CLI finds the endpoint, it appears on the environment's **Webhooks** page. The **Signing secret** column shows **Ready** when the endpoint can verify deliveries and **Needs secret** until then. Every delivery is rejected while an endpoint needs its secret.
|
|
@@ -22,8 +18,8 @@ The prompt tells the agent to use the Trigger.dev MCP server (`npx trigger.dev@l
|
|
|
22
18
|
| --- | --- |
|
|
23
19
|
| `list_webhook_endpoints` | Lists the environment's endpoints, with their URL and whether a secret is set. |
|
|
24
20
|
| `get_webhook_endpoint_details` | Reads one endpoint: URL, subscribers and their filters, secret state, and the setup prompt. |
|
|
25
|
-
| `generate_webhook_secret` | Generates a signing secret and returns it once, for providers where you choose the secret. |
|
|
26
|
-
| `set_webhook_secret` | Stores a secret the provider issued. |
|
|
21
|
+
| `generate_webhook_secret` | Generates a signing secret and returns it once, for providers where you choose the secret. Optionally keeps accepting the old secret (`previousSecretTtlSeconds`). |
|
|
22
|
+
| `set_webhook_secret` | Stores a secret the provider issued. Optionally keeps accepting the old secret (`previousSecretTtlSeconds`). |
|
|
27
23
|
|
|
28
24
|
Without the MCP server, the same operations are available on the REST API with the environment's secret key:
|
|
29
25
|
|
|
@@ -78,7 +74,18 @@ The verify token answers the URL check. The signing secret verifies event delive
|
|
|
78
74
|
|
|
79
75
|
Choose **Rotate signing secret** to replace a provider-supplied secret. For a secret you generate, choose **Regenerate secret**, copy the new value, and update the provider's configuration. Use **Rotate public key** when replacing an asymmetric provider's key.
|
|
80
76
|
|
|
77
|
+
Both dialogs ask how long to keep accepting the old secret: **Stop immediately**, 1 hour, 24 hours (the default) or 7 days. Until then, deliveries signed with either secret verify, so you can update the provider without failing any. Choose **Stop immediately** if the old secret leaked.
|
|
78
|
+
|
|
79
|
+
Through the MCP tools or the REST API, pass `previousSecretTtlSeconds` (at most 604800, 7 days). The response's `previousSecretExpiresAt` says when the old secret stops working. Without it, the old secret stops working straight away:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
curl -X POST "https://api.trigger.dev/api/v1/webhooks/endpoints/github/rotate-secret" \
|
|
83
|
+
-H "Authorization: Bearer $TRIGGER_SECRET_KEY" \
|
|
84
|
+
-H "Content-Type: application/json" \
|
|
85
|
+
-d '{"previousSecretTtlSeconds": 3600}'
|
|
86
|
+
```
|
|
87
|
+
|
|
81
88
|
<Warning>
|
|
82
89
|
Trigger.dev stores credentials encrypted and doesn't display saved values. Copy a generated secret
|
|
83
|
-
before closing the dialog.
|
|
90
|
+
before closing the dialog.
|
|
84
91
|
</Warning>
|
|
@@ -4,10 +4,6 @@ description: "Inspect webhook payloads, where each delivery went, and the runs i
|
|
|
4
4
|
sidebarTitle: "Deliveries and endpoints"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaBanner from "/snippets/webhooks-beta-banner.mdx";
|
|
8
|
-
|
|
9
|
-
<WebhooksBetaBanner />
|
|
10
|
-
|
|
11
7
|
**A delivery records a verified webhook event and what happened to it at each subscriber.** Find deliveries on an endpoint's **Deliveries** tab. A run that a delivery triggered links back to it, and to its endpoint, from the run's **Detail** tab.
|
|
12
8
|
|
|
13
9
|
## Endpoints
|
|
@@ -85,7 +81,14 @@ Trigger.dev uses the endpoint and idempotency key to deduplicate incoming events
|
|
|
85
81
|
|
|
86
82
|
A retry after the delivery window expires can create another delivery record. If the task-run idempotency window is still active, routing returns the existing run instead of starting another one.
|
|
87
83
|
|
|
88
|
-
When the source maps a provider event ID, that ID becomes the key
|
|
84
|
+
When the source maps a provider event ID, that ID becomes the key, so the provider's own retries of an event are recognised as duplicates:
|
|
85
|
+
|
|
86
|
+
| Key | Sources |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| A header | GitHub (`X-GitHub-Delivery`), Svix and Autumn (`svix-id`), Standard Webhooks, Loops and Granola (`webhook-id`), Linear (`Linear-Delivery`), PagerDuty (`X-Webhook-Id`), Jira (`X-Atlassian-Webhook-Identifier`), Zendesk (`X-Zendesk-Webhook-Invocation-Id`), Attio (`Idempotency-Key`), Shopify (`X-Shopify-Webhook-Id`), Hookdeck (`X-Hookdeck-Eventid`, or `<prefix>-eventid` with a custom header prefix) |
|
|
89
|
+
| A body field | Stripe, Notion, Vercel, Intercom, WorkOS, Metronome, Mux, Langfuse and Plain (`id`), Square, Slack and Typeform (`event_id`), Firecrawl (`webhookId`) |
|
|
90
|
+
|
|
91
|
+
The other named sources (Zoom, Calendly, Sentry, DocuSign, ElevenLabs, Vapi, Retell, Tailscale, Infisical, PlanetScale, Supabase, Discord) use the fallback below.
|
|
89
92
|
|
|
90
93
|
If the source doesn't map an event ID, the key is derived from the raw body, timestamp, and signature. A retry with a different timestamp or signature can therefore produce a different key. For a [custom source](/webhooks/sources#custom-providers), set `idempotencyField` to a stable event identifier when the provider supplies one.
|
|
91
94
|
|
|
@@ -4,10 +4,6 @@ description: "Choose which verified webhook events reach each subscriber, by pay
|
|
|
4
4
|
sidebarTitle: "Filters"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaBanner from "/snippets/webhooks-beta-banner.mdx";
|
|
8
|
-
|
|
9
|
-
<WebhooksBetaBanner />
|
|
10
|
-
|
|
11
7
|
**A filter selects which verified deliveries reach a subscriber.** Each subscriber on an [endpoint](/webhooks/overview) has its own filter, so one delivery can start one task and skip another. A delivery no subscriber takes is recorded with status `FILTERED`, so you can inspect it in the dashboard.
|
|
12
8
|
|
|
13
9
|
## Add a filter
|
|
@@ -98,6 +94,8 @@ Paths must have non-empty segments. `event.data.amount` is valid; `event.`, `eve
|
|
|
98
94
|
|
|
99
95
|
Values are strings in single quotes (`'created'`), numbers (`10000`), booleans (`true`), or `null`. Use a list of these values with `in` and `not in`.
|
|
100
96
|
|
|
97
|
+
A `null` value checks presence. `event.issue.pull_request != null` matches events that have the field, and `== null` matches events where it is missing or `null`. It works on any field, including fields your event type marks as required, because a missing field compares equal to `null`.
|
|
98
|
+
|
|
101
99
|
### Comparing two fields
|
|
102
100
|
|
|
103
101
|
Equality and comparison operators also accept a field path on the right-hand side:
|
|
@@ -114,6 +112,12 @@ event.billing.country == event.shipping.country
|
|
|
114
112
|
event.items any ( quantity > 0 )
|
|
115
113
|
```
|
|
116
114
|
|
|
115
|
+
When the payload itself is an array, as with providers that batch several events into one request (Tailscale, for example), quantify over `event`:
|
|
116
|
+
|
|
117
|
+
```text Filter expression
|
|
118
|
+
event any ( type == 'nodeCreated' )
|
|
119
|
+
```
|
|
120
|
+
|
|
117
121
|
### Spacing
|
|
118
122
|
|
|
119
123
|
Separate paths, operators, and values with one space. Parentheses may touch what they enclose, as in `(event.amount > 0)` and `any (quantity > 0)`. Lists and quoted strings may contain spaces (`['opened', 'closed']`, `'Fix the build'`). These forms work with both the TypeScript validator and the deployment parser.
|
|
@@ -4,10 +4,6 @@ sidebarTitle: "Human-in-the-loop"
|
|
|
4
4
|
description: "Pause an agent mid-turn to get a human decision from the channel (Slack approve/deny), then resume with the answer."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaBanner from "/snippets/webhooks-beta-banner.mdx";
|
|
8
|
-
|
|
9
|
-
<WebhooksBetaBanner />
|
|
10
|
-
|
|
11
7
|
**An agent on a [channel](/webhooks/channels) can pause a turn to get a human decision, then resume once someone answers in the thread.** It posts controls into the conversation and picks up where it left off once someone clicks, with the decision merged into the turn. This is the channel counterpart of browser [human-in-the-loop](/ai-chat/patterns/human-in-the-loop): the same no-`execute` tool, but the controls live in Slack (or your own surface) instead of a React component. The [`slack()`](/webhooks/slack) connector ships Approve and Deny buttons out of the box.
|
|
12
8
|
|
|
13
9
|
## How it works
|
|
@@ -41,7 +37,7 @@ Out of the box, `slack()` posts Approve and Deny buttons for any pending no-`exe
|
|
|
41
37
|
```ts trigger/support-agent.ts
|
|
42
38
|
import { webhooks } from "@trigger.dev/sdk";
|
|
43
39
|
import { chat } from "@trigger.dev/sdk/ai";
|
|
44
|
-
import { slack, webhookSource } from "@trigger.dev/slack";
|
|
40
|
+
import { appMentions, slack, webhookSource } from "@trigger.dev/slack";
|
|
45
41
|
import { tool } from "ai";
|
|
46
42
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
47
43
|
import { z } from "zod";
|
|
@@ -60,7 +56,14 @@ const requestApproval = tool({
|
|
|
60
56
|
|
|
61
57
|
export const supportAgent = chat.agent({
|
|
62
58
|
id: "support-agent",
|
|
63
|
-
channels: [
|
|
59
|
+
channels: [
|
|
60
|
+
slack({
|
|
61
|
+
id: "support-slack",
|
|
62
|
+
endpoint: slackEvents,
|
|
63
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
64
|
+
startOn: appMentions(),
|
|
65
|
+
}),
|
|
66
|
+
],
|
|
64
67
|
tools: { requestApproval },
|
|
65
68
|
run: async ({ messages, tools, streamText }) =>
|
|
66
69
|
streamText({
|
package/docs/webhooks/linear.mdx
CHANGED
|
@@ -4,10 +4,6 @@ description: "Turn a chat.agent into a Linear agent: assign it an issue or @ment
|
|
|
4
4
|
sidebarTitle: "Linear agents"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import WebhooksBetaBanner from "/snippets/webhooks-beta-banner.mdx";
|
|
8
|
-
|
|
9
|
-
<WebhooksBetaBanner />
|
|
10
|
-
|
|
11
7
|
Linear opens an **agent session** when someone @mentions your app in an issue or delegates (assigns) an issue to it. `linear()` from `@trigger.dev/linear` is a [channel](/webhooks/channels) connector for those sessions: each one becomes a durable Trigger.dev [session](/ai-chat/sessions), the user's prompt runs as a turn, and the agent's work shows up in Linear as thoughts, actions, a plan, an approval card when it needs a decision, and a response when it is done.
|
|
12
8
|
|
|
13
9
|
```ts
|
|
@@ -67,7 +63,7 @@ linear({ id: "linear", endpoint: linearEvents, token, context: { guidance: false
|
|
|
67
63
|
| Turn starts | An ephemeral `thought` ("Looking into this...") |
|
|
68
64
|
| A tool is called | An ephemeral `action` with the tool name and input, then the same action with its `result` |
|
|
69
65
|
| The reply is ready | A `response` with the reply as markdown |
|
|
70
|
-
| The turn fails | An `error` |
|
|
66
|
+
| The turn fails | An `error` saying "Something went wrong answering this. Try again." (`errorMessage` changes it) |
|
|
71
67
|
| A tool needs a human decision | An `elicitation` with Approve and Deny options, or the tool's own options from `interactions` (see [Approvals and choices](#approvals-and-choices)) |
|
|
72
68
|
| The user picks an option | A `thought` recording the decision ("Approved by Jane.", "Jane chose "High".") |
|
|
73
69
|
| A prompt arrives while the agent works | A `thought` ("Got it, I'll take that into account.") as soon as it arrives (see [Prompts sent while the agent is working](#prompts-sent-while-the-agent-is-working)) |
|
|
@@ -176,6 +172,7 @@ The first Linear turn binds the session to the agent session ([bound sessions](/
|
|
|
176
172
|
| `approvals` | `{ [toolName]: (input, call) => { title?, body } }` | Custom approval card body per tool. Default lays the tool input out as markdown. |
|
|
177
173
|
| `interactions` | `{ [toolName]: (call) => { title?, body, options } }` | A tool's own select card; the chosen option resolves the tool to `{ selected }`. |
|
|
178
174
|
| `receivedThought` | `string`, function or `null` | Thought posted as soon as a prompt arrives while the agent is working. Default "Got it, I'll take that into account.", null for none. |
|
|
175
|
+
| `errorMessage` | `string \| (ctx) => string` | The error activity's text when a turn fails, fixed or built from the failure ([details](/webhooks/channels#when-a-turn-fails)). Default "Something went wrong answering this. Try again." |
|
|
179
176
|
| `ack` | message, `null`, or function | The first thought. Pass `null` to post nothing before the response. |
|
|
180
177
|
| `inbound` / `outbound` | functions | Map the event to the turn, and the reply to an activity. |
|
|
181
178
|
| `delivery` | `"final"` or `"stream"` | `"final"` (default) posts the response when the turn ends. `"stream"` also posts ephemeral thoughts as the reply streams. |
|