@trigger.dev/sdk 4.7.3 → 4.8.0-webhooks.20261015065339
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 +560 -8
- package/dist/commonjs/v3/ai.js +2263 -178
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +23 -0
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/concurrencyLimits.d.ts +37 -7
- package/dist/commonjs/v3/concurrencyLimits.js +38 -70
- package/dist/commonjs/v3/concurrencyLimits.js.map +1 -1
- package/dist/commonjs/v3/index.d.ts +3 -1
- package/dist/commonjs/v3/index.js +23 -17
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/modelFileDownload.d.ts +10 -0
- package/dist/commonjs/v3/modelFileDownload.js +164 -0
- package/dist/commonjs/v3/modelFileDownload.js.map +1 -0
- package/dist/commonjs/v3/runs.d.ts +22 -1
- package/dist/commonjs/v3/runs.js +6 -3
- package/dist/commonjs/v3/runs.js.map +1 -1
- package/dist/commonjs/v3/test/index.d.ts +2 -1
- package/dist/commonjs/v3/test/index.js +4 -1
- package/dist/commonjs/v3/test/index.js.map +1 -1
- package/dist/commonjs/v3/test/mock-channel-connector.d.ts +172 -0
- package/dist/commonjs/v3/test/mock-channel-connector.js +173 -0
- package/dist/commonjs/v3/test/mock-channel-connector.js.map +1 -0
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +81 -1
- package/dist/commonjs/v3/test/mock-chat-agent.js +137 -10
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/commonjs/v3/transcriptStorage.d.ts +44 -1
- package/dist/commonjs/v3/transcriptStorage.js +24 -0
- package/dist/commonjs/v3/transcriptStorage.js.map +1 -1
- package/dist/commonjs/v3/webhookWaiters.d.ts +80 -0
- package/dist/commonjs/v3/webhookWaiters.js +156 -0
- package/dist/commonjs/v3/webhookWaiters.js.map +1 -0
- package/dist/commonjs/v3/webhooks.d.ts +178 -2
- package/dist/commonjs/v3/webhooks.js +322 -1
- package/dist/commonjs/v3/webhooks.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai.d.ts +560 -8
- package/dist/esm/v3/ai.js +2257 -178
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +23 -0
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/concurrencyLimits.d.ts +37 -7
- package/dist/esm/v3/concurrencyLimits.js +38 -70
- package/dist/esm/v3/concurrencyLimits.js.map +1 -1
- package/dist/esm/v3/index.d.ts +3 -1
- package/dist/esm/v3/index.js +1 -0
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/modelFileDownload.d.ts +10 -0
- package/dist/esm/v3/modelFileDownload.js +161 -0
- package/dist/esm/v3/modelFileDownload.js.map +1 -0
- package/dist/esm/v3/runs.d.ts +22 -1
- package/dist/esm/v3/runs.js +6 -3
- package/dist/esm/v3/runs.js.map +1 -1
- package/dist/esm/v3/test/index.d.ts +2 -1
- package/dist/esm/v3/test/index.js +2 -1
- package/dist/esm/v3/test/index.js.map +1 -1
- package/dist/esm/v3/test/mock-channel-connector.d.ts +172 -0
- package/dist/esm/v3/test/mock-channel-connector.js +170 -0
- package/dist/esm/v3/test/mock-channel-connector.js.map +1 -0
- package/dist/esm/v3/test/mock-chat-agent.d.ts +81 -1
- package/dist/esm/v3/test/mock-chat-agent.js +137 -11
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/esm/v3/transcriptStorage.d.ts +44 -1
- package/dist/esm/v3/transcriptStorage.js +24 -0
- package/dist/esm/v3/transcriptStorage.js.map +1 -1
- package/dist/esm/v3/webhookWaiters.d.ts +80 -0
- package/dist/esm/v3/webhookWaiters.js +149 -0
- package/dist/esm/v3/webhookWaiters.js.map +1 -0
- package/dist/esm/v3/webhooks.d.ts +178 -2
- package/dist/esm/v3/webhooks.js +318 -1
- package/dist/esm/v3/webhooks.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/actions.mdx +6 -1
- package/docs/ai-chat/backend.mdx +34 -0
- package/docs/ai-chat/patterns/sub-agents.mdx +33 -0
- package/docs/ai-chat/pending-messages.mdx +2 -0
- package/docs/ai-chat/reference.mdx +50 -2
- package/docs/apikeys.mdx +3 -3
- package/docs/billing-limits.mdx +1 -1
- package/docs/cli-env-commands.mdx +5 -4
- package/docs/cli-init-commands.mdx +27 -1
- package/docs/cli-login-commands.mdx +20 -0
- package/docs/cli-projects-commands.mdx +13 -1
- package/docs/cli-runs-commands.mdx +3 -2
- package/docs/cli-update-commands.mdx +9 -3
- package/docs/cli-whoami-commands.mdx +12 -0
- package/docs/concurrency.mdx +32 -0
- package/docs/config/extensions/audioWaveform.mdx +4 -1
- package/docs/config/extensions/overview.mdx +2 -0
- package/docs/config/extensions/prismaExtension.mdx +2 -3
- package/docs/config/extensions/puppeteer.mdx +3 -5
- package/docs/config/extensions/pythonExtension.mdx +9 -1
- package/docs/config/extensions/syncEnvVars.mdx +6 -0
- package/docs/deploy-environment-variables.mdx +1 -1
- package/docs/deployment/atomic-deployment.mdx +2 -0
- package/docs/deployment/dev-branches.mdx +5 -5
- package/docs/deployment/overview.mdx +8 -7
- package/docs/deployment/preview-branches.mdx +6 -3
- package/docs/errors-retrying.mdx +4 -4
- package/docs/how-it-works.mdx +5 -5
- package/docs/introduction.mdx +6 -0
- package/docs/limits.mdx +26 -8
- package/docs/logging.mdx +1 -1
- package/docs/machines.mdx +1 -1
- package/docs/mcp-introduction.mdx +8 -7
- package/docs/mcp-tools.mdx +91 -1
- package/docs/migrating-from-v3.mdx +1 -1
- package/docs/observability/dashboards.mdx +2 -0
- package/docs/observability/query.mdx +6 -2
- package/docs/private-networking/aws-console-setup.mdx +1 -1
- package/docs/private-networking/overview.mdx +1 -1
- package/docs/quick-start.mdx +3 -40
- package/docs/realtime/auth.mdx +1 -1
- package/docs/realtime/backend/input-streams.mdx +159 -0
- package/docs/realtime/backend/streams.mdx +25 -10
- package/docs/realtime/how-it-works.mdx +1 -1
- package/docs/realtime/react-hooks/overview.mdx +1 -1
- package/docs/realtime/react-hooks/streams.mdx +2 -2
- package/docs/realtime/react-hooks/subscribe.mdx +19 -3
- package/docs/realtime/react-hooks/triggering.mdx +2 -2
- package/docs/realtime/react-hooks/use-wait-token.mdx +1 -1
- package/docs/realtime/run-object.mdx +47 -24
- package/docs/replaying.mdx +26 -1
- package/docs/reports.mdx +4 -2
- package/docs/run-tests.mdx +2 -2
- package/docs/run-usage.mdx +3 -3
- package/docs/runs/heartbeats.mdx +2 -2
- package/docs/runs/list-best-practices.mdx +234 -0
- package/docs/runs/metadata.mdx +7 -10
- package/docs/runs.mdx +18 -8
- package/docs/self-hosting/env/supervisor.mdx +2 -0
- package/docs/self-hosting/env/webapp.mdx +5 -0
- package/docs/self-hosting/overview.mdx +26 -0
- package/docs/tags.mdx +6 -0
- package/docs/tasks/scheduled.mdx +11 -5
- package/docs/triggering.mdx +8 -0
- package/docs/troubleshooting-alerts.mdx +102 -3
- package/docs/troubleshooting.mdx +1 -1
- package/docs/upgrading-packages.mdx +3 -3
- package/docs/vercel-integration.mdx +13 -3
- package/docs/versioning.mdx +1 -1
- package/docs/wait-for-token.mdx +3 -3
- package/docs/webhooks/channels.mdx +128 -0
- package/docs/webhooks/connect.mdx +80 -0
- package/docs/webhooks/deliveries.mdx +92 -0
- package/docs/webhooks/filters.mdx +109 -0
- package/docs/webhooks/human-in-the-loop.mdx +149 -0
- package/docs/webhooks/linear.mdx +185 -0
- package/docs/webhooks/overview.mdx +99 -0
- package/docs/webhooks/session-routing.mdx +132 -0
- package/docs/webhooks/slack.mdx +360 -0
- package/docs/webhooks/sources.mdx +217 -0
- package/docs/webhooks/waiters.mdx +170 -0
- package/package.json +3 -2
package/dist/esm/v3/webhooks.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { Webhook } from "@trigger.dev/core/v3";
|
|
1
|
+
import { Webhook, resourceCatalog } from "@trigger.dev/core/v3";
|
|
2
2
|
import { subtle } from "../imports/uncrypto.js";
|
|
3
|
+
import { cancelWebhookWaiter, createWebhookWaiter, waitForWebhookWaiter, } from "./webhookWaiters.js";
|
|
4
|
+
import { createTask } from "./shared.js";
|
|
5
|
+
import { discordVerifierConfig, githubVerifierConfig, squareVerifierConfig, standardWebhooksVerifierConfig, stripeVerifierConfig, svixVerifierConfig, webhookProviderConfigs, webhookSetupPrompts, } from "@trigger.dev/core/webhooks";
|
|
3
6
|
/**
|
|
4
7
|
* The type of error thrown when a webhook fails to parse or verify
|
|
5
8
|
*/
|
|
@@ -11,12 +14,326 @@ export class WebhookError extends Error {
|
|
|
11
14
|
}
|
|
12
15
|
/** Header name used for webhook signatures */
|
|
13
16
|
const SIGNATURE_HEADER_NAME = "x-trigger-signature-hmacsha256";
|
|
17
|
+
// ── Source producers (presets carry the event type) ──
|
|
18
|
+
export const webhookSources = {
|
|
19
|
+
custom(config, options) {
|
|
20
|
+
if (config.scheme === "url-secret" && config.placement === "path") {
|
|
21
|
+
throw new Error('webhooks.custom(): url-secret verification cannot use placement "path" on the hosted ingress URL. Use placement "query" or a header-based scheme.');
|
|
22
|
+
}
|
|
23
|
+
// Roll-your-own webhooks: you control both ends, so offer paste AND generate.
|
|
24
|
+
return {
|
|
25
|
+
provider: "custom",
|
|
26
|
+
verifier: {
|
|
27
|
+
kind: "config",
|
|
28
|
+
config,
|
|
29
|
+
...(options?.response ? { response: options.response } : {}),
|
|
30
|
+
},
|
|
31
|
+
secretProvisioning: "either",
|
|
32
|
+
...(options?.setupPrompt ? { setupPrompt: options.setupPrompt } : {}),
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
// Stripe: `Stripe-Signature: t=…,v1=…` (comma-kv), signed `{t}.{body}`, hex.
|
|
36
|
+
// Defaults to a minimal event shape; pass the official type for full typing: stripe<Stripe.Event>().
|
|
37
|
+
stripe(opts) {
|
|
38
|
+
return {
|
|
39
|
+
provider: "stripe",
|
|
40
|
+
verifier: { kind: "preset", preset: "stripe", config: stripeVerifierConfig(opts) },
|
|
41
|
+
secretProvisioning: "provider",
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
// GitHub: `X-Hub-Signature-256: sha256=<hex>` (prefixed), signed raw body.
|
|
45
|
+
// Defaults to an open shape; pass your event type for full typing: github<MyPushEvent>().
|
|
46
|
+
github() {
|
|
47
|
+
return {
|
|
48
|
+
provider: "github",
|
|
49
|
+
verifier: { kind: "preset", preset: "github", config: githubVerifierConfig() },
|
|
50
|
+
secretProvisioning: "integrator",
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
// Svix family (Svix, Clerk, Resend): `svix-signature: v1,<b64> v1,<b64>` (space-list),
|
|
54
|
+
// signed `{id}.{timestamp}.{body}`, base64; the `whsec_` secret is base64-decoded. Providers that
|
|
55
|
+
// send the spec's `webhook-*` header names instead use `standardWebhooks()`.
|
|
56
|
+
svix() {
|
|
57
|
+
return {
|
|
58
|
+
provider: "svix",
|
|
59
|
+
verifier: { kind: "preset", preset: "svix", config: svixVerifierConfig() },
|
|
60
|
+
secretProvisioning: "provider",
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
// Standard Webhooks (Composio, and any provider implementing the spec directly): the Svix scheme under
|
|
64
|
+
// the spec's `webhook-id` / `webhook-timestamp` / `webhook-signature` header names.
|
|
65
|
+
standardWebhooks() {
|
|
66
|
+
return {
|
|
67
|
+
provider: "standard-webhooks",
|
|
68
|
+
verifier: {
|
|
69
|
+
kind: "preset",
|
|
70
|
+
preset: "standard-webhooks",
|
|
71
|
+
config: standardWebhooksVerifierConfig(),
|
|
72
|
+
},
|
|
73
|
+
secretProvisioning: "provider",
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
// Square: bare base64 signature over `{notificationURL}{body}` (URL template var, no separator).
|
|
77
|
+
square() {
|
|
78
|
+
return {
|
|
79
|
+
provider: "square",
|
|
80
|
+
verifier: { kind: "preset", preset: "square", config: squareVerifierConfig() },
|
|
81
|
+
secretProvisioning: "provider",
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
/**
|
|
85
|
+
* Discord: asymmetric Ed25519 over `{timestamp}{body}`. The "secret" stored on the endpoint is the
|
|
86
|
+
* application PUBLIC KEY (hex by default); there is no shared secret. Discord's response contract
|
|
87
|
+
* is declared as data on the artifact: the `{ type: 0 }` PING sent when the URL is saved is answered
|
|
88
|
+
* with a bodiless 204 and never recorded, accepted events are acknowledged with 204, and a bad
|
|
89
|
+
* signature gets 401.
|
|
90
|
+
*/
|
|
91
|
+
discord(opts = {}) {
|
|
92
|
+
return {
|
|
93
|
+
provider: "discord",
|
|
94
|
+
verifier: {
|
|
95
|
+
kind: "preset",
|
|
96
|
+
preset: "discord",
|
|
97
|
+
config: discordVerifierConfig(opts),
|
|
98
|
+
handshake: { matchPath: "type", matchValue: "0", respondStatus: 204 },
|
|
99
|
+
response: { acceptedStatus: 204, rejectedStatus: 401 },
|
|
100
|
+
},
|
|
101
|
+
secretProvisioning: "provider",
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
/**
|
|
105
|
+
* Per-provider producers over shared presets. Each is a thin wrapper: same verifier config as the
|
|
106
|
+
* preset it references, differing only in `provider` (routing + picker identity) and who provisions
|
|
107
|
+
* the secret. Pass the provider's own published type for full typing, e.g. clerk<WebhookEvent>().
|
|
108
|
+
*/
|
|
109
|
+
clerk() {
|
|
110
|
+
return {
|
|
111
|
+
provider: "clerk",
|
|
112
|
+
verifier: { kind: "preset", preset: "svix", config: svixVerifierConfig() },
|
|
113
|
+
secretProvisioning: "provider",
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
resend() {
|
|
117
|
+
return {
|
|
118
|
+
provider: "resend",
|
|
119
|
+
verifier: { kind: "preset", preset: "svix", config: svixVerifierConfig() },
|
|
120
|
+
secretProvisioning: "provider",
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
openai() {
|
|
124
|
+
return {
|
|
125
|
+
provider: "openai",
|
|
126
|
+
verifier: {
|
|
127
|
+
kind: "preset",
|
|
128
|
+
preset: "standard-webhooks",
|
|
129
|
+
config: standardWebhooksVerifierConfig(),
|
|
130
|
+
},
|
|
131
|
+
secretProvisioning: "provider",
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
replicate() {
|
|
135
|
+
return {
|
|
136
|
+
provider: "replicate",
|
|
137
|
+
verifier: {
|
|
138
|
+
kind: "preset",
|
|
139
|
+
preset: "standard-webhooks",
|
|
140
|
+
config: standardWebhooksVerifierConfig(),
|
|
141
|
+
},
|
|
142
|
+
secretProvisioning: "provider",
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
recallai() {
|
|
146
|
+
return {
|
|
147
|
+
provider: "recall-ai",
|
|
148
|
+
verifier: {
|
|
149
|
+
kind: "preset",
|
|
150
|
+
preset: "standard-webhooks",
|
|
151
|
+
config: standardWebhooksVerifierConfig(),
|
|
152
|
+
},
|
|
153
|
+
secretProvisioning: "provider",
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
brex() {
|
|
157
|
+
return {
|
|
158
|
+
provider: "brex",
|
|
159
|
+
verifier: { kind: "preset", preset: "svix", config: svixVerifierConfig() },
|
|
160
|
+
secretProvisioning: "provider",
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
composio() {
|
|
164
|
+
return {
|
|
165
|
+
provider: "composio",
|
|
166
|
+
verifier: {
|
|
167
|
+
kind: "preset",
|
|
168
|
+
preset: "standard-webhooks",
|
|
169
|
+
config: standardWebhooksVerifierConfig(),
|
|
170
|
+
},
|
|
171
|
+
secretProvisioning: "provider",
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
gitlab() {
|
|
175
|
+
return {
|
|
176
|
+
provider: "gitlab",
|
|
177
|
+
verifier: {
|
|
178
|
+
kind: "config",
|
|
179
|
+
config: { scheme: "shared-secret", placement: "header", fieldName: "x-gitlab-token" },
|
|
180
|
+
},
|
|
181
|
+
secretProvisioning: "integrator",
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
/**
|
|
185
|
+
* WhatsApp Cloud API (Meta): `X-Hub-Signature-256` HMAC over the raw body, keyed by the App Secret,
|
|
186
|
+
* which Meta issues and you paste in as the endpoint's signing secret (it cannot be generated here).
|
|
187
|
+
* Meta verifies the callback URL with a GET carrying `hub.mode`, `hub.verify_token` and
|
|
188
|
+
* `hub.challenge`; the endpoint answers it when the token equals the verify token generated in
|
|
189
|
+
* the endpoint's Connect panel, which you paste into Meta's Verify Token field.
|
|
190
|
+
*/
|
|
191
|
+
whatsapp() {
|
|
192
|
+
return {
|
|
193
|
+
provider: "whatsapp",
|
|
194
|
+
verifier: {
|
|
195
|
+
kind: "preset",
|
|
196
|
+
preset: "github",
|
|
197
|
+
config: githubVerifierConfig(),
|
|
198
|
+
getHandshake: {
|
|
199
|
+
matchParam: "hub.mode",
|
|
200
|
+
matchValue: "subscribe",
|
|
201
|
+
tokenParam: "hub.verify_token",
|
|
202
|
+
challengeParam: "hub.challenge",
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
secretProvisioning: "provider",
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
function producerName(provider) {
|
|
210
|
+
return provider.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
211
|
+
}
|
|
212
|
+
export const providerProducers = Object.fromEntries(Object.entries(webhookProviderConfigs)
|
|
213
|
+
// Zoom needs a computed URL-validation response that the hosted ingress does not support yet.
|
|
214
|
+
.filter(([provider]) => provider !== "slack" && provider !== "zoom")
|
|
215
|
+
.map(([provider, entry]) => [
|
|
216
|
+
producerName(provider),
|
|
217
|
+
() => {
|
|
218
|
+
const setupPrompt = webhookSetupPrompts[provider];
|
|
219
|
+
return {
|
|
220
|
+
provider,
|
|
221
|
+
verifier: { kind: "config", config: entry.config() },
|
|
222
|
+
secretProvisioning: entry.secretProvisioning,
|
|
223
|
+
...(setupPrompt ? { setupPrompt } : {}),
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
]));
|
|
227
|
+
/**
|
|
228
|
+
* Declare a webhook endpoint: one URL you register with the provider. Subscribe to it with
|
|
229
|
+
* `webhook({ endpoint })`, `chat.event({ endpoint })` or a channel connector, and wait on it with
|
|
230
|
+
* `webhooks.waiter.create(endpoint, ...)`. An endpoint with no subscribers still gets a URL.
|
|
231
|
+
*/
|
|
232
|
+
export function defineWebhookEndpoint(options) {
|
|
233
|
+
const { id, source, description, metadata } = options;
|
|
234
|
+
if (id.startsWith("wh_")) {
|
|
235
|
+
throw new Error(`webhooks.endpoint.define("${id}"): an endpoint id can't start with "wh_"; that prefix is reserved for generated endpoint ids.`);
|
|
236
|
+
}
|
|
237
|
+
const setupPrompt = source.setupPrompt ??
|
|
238
|
+
(source.verifier.kind === "preset"
|
|
239
|
+
? webhookSetupPrompts[source.verifier.preset]
|
|
240
|
+
: undefined);
|
|
241
|
+
resourceCatalog.registerWebhookEndpointMetadata({
|
|
242
|
+
id,
|
|
243
|
+
source: source.provider,
|
|
244
|
+
verifierArtifact: source.verifier,
|
|
245
|
+
...(description ? { description } : {}),
|
|
246
|
+
...(source.secretProvisioning ? { secretProvisioning: source.secretProvisioning } : {}),
|
|
247
|
+
...(setupPrompt ? { setupPrompt } : {}),
|
|
248
|
+
...(metadata ? { metadata } : {}),
|
|
249
|
+
});
|
|
250
|
+
return { id, source: source.provider };
|
|
251
|
+
}
|
|
252
|
+
export function webhook(options) {
|
|
253
|
+
const { id, endpoint, onEvent, filter } = options;
|
|
254
|
+
if (!endpoint?.id) {
|
|
255
|
+
throw new Error(`webhook("${id}"): an endpoint is required. Declare one with webhooks.endpoint.define() and pass it as { endpoint }.`);
|
|
256
|
+
}
|
|
257
|
+
const task = createTask({
|
|
258
|
+
id,
|
|
259
|
+
triggerSource: "webhook",
|
|
260
|
+
run: async (payload, runOptions) => {
|
|
261
|
+
await onEvent({
|
|
262
|
+
event: payload.event,
|
|
263
|
+
headers: new Headers(payload.headers ?? {}),
|
|
264
|
+
endpoint: payload.endpoint,
|
|
265
|
+
ctx: runOptions.ctx,
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
resourceCatalog.registerWebhookSubscriber({
|
|
270
|
+
endpointId: endpoint.id,
|
|
271
|
+
target: { type: "task", id, taskId: id, ...(filter ? { filter } : {}) },
|
|
272
|
+
});
|
|
273
|
+
return task;
|
|
274
|
+
}
|
|
275
|
+
// ── chat.event(): a session subscriber an agent claims via chat.agent({ events }). No handler. ──
|
|
276
|
+
// Carries the endpoint, a validated string `key`, and a `type` discriminant. The `key` validates
|
|
277
|
+
// against the event/header/webhook namespaces, like a filter path, and compiles to the stored
|
|
278
|
+
// {body.x} wire template.
|
|
279
|
+
export function chatEvent(options) {
|
|
280
|
+
const { id, endpoint, key, type, filter } = options;
|
|
281
|
+
if (!endpoint?.id) {
|
|
282
|
+
throw new Error(`chat.event("${id}"): an endpoint is required. Declare one with webhooks.endpoint.define() and pass it as { endpoint }.`);
|
|
283
|
+
}
|
|
284
|
+
// Record the descriptor as declared so the indexer can flag it if no agent ever claims it.
|
|
285
|
+
resourceCatalog.registerDeclaredSessionWebhook(id);
|
|
286
|
+
return {
|
|
287
|
+
id,
|
|
288
|
+
type: type ?? id,
|
|
289
|
+
key: normalizeKeyString(key),
|
|
290
|
+
endpointId: endpoint.id,
|
|
291
|
+
source: endpoint.source,
|
|
292
|
+
filter,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Compiles a key template to its stored form. Each placeholder names its namespace the way a filter
|
|
297
|
+
* path does: `{event.x}` reads the event body (stored as `{body.x}`), `{header.x}` a header and
|
|
298
|
+
* `{webhook.x}` the endpoint. A placeholder without one of those namespaces throws.
|
|
299
|
+
*/
|
|
300
|
+
export function normalizeKeyString(key) {
|
|
301
|
+
const namespaceAlternative = (alternative) => {
|
|
302
|
+
const trimmed = alternative.trim();
|
|
303
|
+
if (trimmed.startsWith("event."))
|
|
304
|
+
return `body.${trimmed.slice("event.".length)}`;
|
|
305
|
+
if (trimmed.startsWith("webhook.") || trimmed.startsWith("header."))
|
|
306
|
+
return trimmed;
|
|
307
|
+
const path = trimmed.startsWith("body.") ? trimmed.slice("body.".length) : trimmed;
|
|
308
|
+
throw new Error(`Invalid key "${key}": "{${trimmed}}" needs a namespace. Use {event.${path}} for the event body, {header.<name>} or {webhook.<field>}.`);
|
|
309
|
+
};
|
|
310
|
+
return key.replace(/\{([^{}]+)\}/g, (_match, path) => `{${path.split("||").map(namespaceAlternative).join(" || ")}}`);
|
|
311
|
+
}
|
|
14
312
|
/**
|
|
15
313
|
* Webhook utilities for handling incoming webhook requests
|
|
16
314
|
*/
|
|
17
315
|
export const webhooks = {
|
|
316
|
+
...providerProducers,
|
|
18
317
|
constructEvent,
|
|
19
318
|
SIGNATURE_HEADER_NAME,
|
|
319
|
+
custom: webhookSources.custom,
|
|
320
|
+
stripe: webhookSources.stripe,
|
|
321
|
+
github: webhookSources.github,
|
|
322
|
+
svix: webhookSources.svix,
|
|
323
|
+
standardWebhooks: webhookSources.standardWebhooks,
|
|
324
|
+
square: webhookSources.square,
|
|
325
|
+
discord: webhookSources.discord,
|
|
326
|
+
clerk: webhookSources.clerk,
|
|
327
|
+
resend: webhookSources.resend,
|
|
328
|
+
openai: webhookSources.openai,
|
|
329
|
+
replicate: webhookSources.replicate,
|
|
330
|
+
recallai: webhookSources.recallai,
|
|
331
|
+
brex: webhookSources.brex,
|
|
332
|
+
composio: webhookSources.composio,
|
|
333
|
+
gitlab: webhookSources.gitlab,
|
|
334
|
+
whatsapp: webhookSources.whatsapp,
|
|
335
|
+
endpoint: { define: defineWebhookEndpoint },
|
|
336
|
+
waiter: { create: createWebhookWaiter, wait: waitForWebhookWaiter, cancel: cancelWebhookWaiter },
|
|
20
337
|
};
|
|
21
338
|
async function constructEvent(request, secret) {
|
|
22
339
|
let payload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../../src/v3/webhooks.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../../src/v3/webhooks.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "4.
|
|
1
|
+
export const VERSION = "4.8.0-webhooks.20261015065339";
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/docs/ai-chat/actions.mdx
CHANGED
|
@@ -73,11 +73,16 @@ onAction: async ({ action }) => {
|
|
|
73
73
|
chat.history.slice(0, -1);
|
|
74
74
|
chat.inject([{ role: "system", content: "Answer formally this time." }]);
|
|
75
75
|
return chat.turn(); // with a one-shot instruction
|
|
76
|
+
|
|
77
|
+
case "ask":
|
|
78
|
+
return chat.turn(action.question); // answer a new user message
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
```
|
|
79
82
|
|
|
80
|
-
`
|
|
83
|
+
`chat.turn(message)` appends `message` (a string, or a `UIMessage`) to the history as a user message after the edit, and the turn answers it. That is how a button click becomes a question, such as a follow-up suggestion in [Slack](/webhooks/slack#buttons-that-send-the-agent-an-action).
|
|
84
|
+
|
|
85
|
+
Without a message, `run()` receives the edited history with no incoming user message, the same shape as a `regenerate-message` turn, and its `trigger` is `"action-turn"`, so a `run()` that returns early on `"action"` (the pre-May behaviour, when actions invoked `run()` directly) still answers. Returning anything other than `chat.turn()` or nothing is an error; a response can no longer be returned from `onAction` directly.
|
|
81
86
|
|
|
82
87
|
### Actions and persistence
|
|
83
88
|
|
package/docs/ai-chat/backend.mdx
CHANGED
|
@@ -497,6 +497,40 @@ Custom actions let the frontend send structured commands (undo, rollback, edit,
|
|
|
497
497
|
|
|
498
498
|
See [Actions](/ai-chat/actions).
|
|
499
499
|
|
|
500
|
+
### Webhook events and channels
|
|
501
|
+
|
|
502
|
+
Two `chat.agent()` options wire an agent to verified inbound webhooks. `events` claims [`chat.event(...)`](/webhooks/session-routing) descriptors: each verified delivery is routed to this agent's session and arrives at `onAction` as an action (not a turn), so [session routing](/webhooks/session-routing) decides which conversation it lands on. `channels` claims channel connectors that turn an external chat surface into a frontend for the agent: an inbound message runs as a turn through `run()` and the reply is posted back. `slack()` ships in `@trigger.dev/slack`, and `chat.channels.custom(...)` builds a connector for any endpoint without a preset.
|
|
503
|
+
|
|
504
|
+
```ts
|
|
505
|
+
import { webhooks } from "@trigger.dev/sdk";
|
|
506
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
507
|
+
import { slack, webhookSource } from "@trigger.dev/slack";
|
|
508
|
+
|
|
509
|
+
const slackEvents = webhooks.endpoint.define({ id: "slack", source: webhookSource() });
|
|
510
|
+
const stripe = webhooks.endpoint.define({ id: "stripe", source: webhooks.stripe() });
|
|
511
|
+
|
|
512
|
+
export const orderEvents = chat.event({
|
|
513
|
+
id: "order-events",
|
|
514
|
+
endpoint: stripe,
|
|
515
|
+
key: "{event.data.object.customer}",
|
|
516
|
+
type: "order.event",
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
export const myChat = chat.agent({
|
|
520
|
+
id: "my-chat",
|
|
521
|
+
events: [orderEvents],
|
|
522
|
+
channels: [slack({ id: "support-slack", endpoint: slackEvents, token: process.env.SLACK_BOT_TOKEN! })],
|
|
523
|
+
onAction: async ({ action }) => {
|
|
524
|
+
// A verified order-events delivery arrives here as an action.
|
|
525
|
+
},
|
|
526
|
+
run: async (payload) => {
|
|
527
|
+
// Inbound Slack messages run here as normal turns.
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
See [session routing](/webhooks/session-routing) and [channels](/webhooks/channels). For the interactive approvals layer, where a turn pauses on a human decision (buttons in the thread) and resumes on the click, see [human-in-the-loop](/webhooks/human-in-the-loop).
|
|
533
|
+
|
|
500
534
|
### Chat history
|
|
501
535
|
|
|
502
536
|
Imperative API for reading and modifying the accumulated message history. Works from any hook (`onAction`, `onTurnStart`, `onBeforeTurnComplete`, `onTurnComplete`, `hydrateMessages`) or from `run()` and AI SDK tools.
|
|
@@ -134,6 +134,39 @@ The parent LLM naturally calls this tool multiple times:
|
|
|
134
134
|
2. `researchAgent({ conversationId: "competitors", message: "Go deeper on pricing" })` — same run, sub-agent has full context
|
|
135
135
|
3. `researchAgent({ conversationId: "new-topic", message: "..." })` — different ID = different sub-agent
|
|
136
136
|
|
|
137
|
+
## Limiting parallel sub-agents per session
|
|
138
|
+
|
|
139
|
+
Give every sub-agent task a shared named limit with a `perKey`, pass the parent session's id as each sub-agent's `concurrencyKey`, and raise that key's cap when the user picks a parallelism:
|
|
140
|
+
|
|
141
|
+
```ts trigger/limits.ts
|
|
142
|
+
import { concurrencyLimit } from "@trigger.dev/sdk";
|
|
143
|
+
|
|
144
|
+
// one sub-agent at a time per session unless a session is given more
|
|
145
|
+
export const subagentsLimit = concurrencyLimit({ name: "subagents", perKey: 1 });
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```ts trigger/research-agent.ts
|
|
149
|
+
export const researchAgent = chat.agent({
|
|
150
|
+
id: "research-agent",
|
|
151
|
+
concurrency: subagentsLimit,
|
|
152
|
+
// ...
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
// in the parent agent, once per session, when the user picks a parallelism of 3
|
|
158
|
+
await concurrencyLimits.override("subagents", { concurrencyKey: sessionId, perKey: 3 });
|
|
159
|
+
|
|
160
|
+
// every sub-agent for this session carries the session's key
|
|
161
|
+
const agent = new AgentChat({
|
|
162
|
+
agent: "research-agent",
|
|
163
|
+
id: conversationId,
|
|
164
|
+
triggerConfig: { concurrencyKey: sessionId },
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Three sub-agent runs for this session execute at once; a fourth waits. Other sessions keep the declared cap of one, and any tenant-level limit the sub-agent task also holds keeps applying. The override expires after 7 days by default (`ttl` sets it, up to 30 days), so a session that outlives that should call `override` again. See [Overriding a limit for one key](/concurrency#overriding-a-limit-for-one-key).
|
|
169
|
+
|
|
137
170
|
### Cross-turn persistence
|
|
138
171
|
|
|
139
172
|
Sub-agent conversations persist across **parent turns** because the `Map` lives in the parent's process heap. When the parent suspends and restores via snapshot, the heap is preserved — the Map still has the conversations, the sessions still have the run IDs.
|
|
@@ -12,6 +12,8 @@ By default (without `pendingMessages`), a message sent while the agent is respon
|
|
|
12
12
|
|
|
13
13
|
The `pendingMessages` option enables steering instead, injecting user messages between tool-call steps via the AI SDK's `prepareStep`. Messages that arrive during streaming are queued and injected at the next step boundary. A message that is not injected becomes the next turn instead, whether that is because `shouldInject` returned `false` or because there were no more step boundaries (single-step response or final text generation). The backend handles that, so no client-side re-send is involved.
|
|
14
14
|
|
|
15
|
+
Messages from a [channel](/webhooks/channels) such as [Slack](/webhooks/slack) are offered the same way, with `metadata.source` set to `"channel"` so `shouldInject` can tell them apart. A channel's stop control and approval clicks are never offered. The connector acknowledges a channel message as soon as it arrives (Slack reacts with 👀, Linear posts a thought), before `shouldInject` decides, so the acknowledgement is the same whether the message is folded in or answered next.
|
|
16
|
+
|
|
15
17
|
Use the `streamText` passed to your agent's `run` callback. It wires up pending-message injection automatically. If you import `streamText` directly from `ai`, spread `chat.toStreamTextOptions()` into its options to connect injection.
|
|
16
18
|
|
|
17
19
|
## How it works
|
|
@@ -47,7 +47,9 @@ Options for `chat.agent()`.
|
|
|
47
47
|
| `storage` | `TranscriptStorage` | `defaultStorage` | Where the conversation is persisted and read back. The platform snapshot by default; bring your own to write each change to your database. See [Transcript storage](/ai-chat/transcript-storage) |
|
|
48
48
|
| `hydrateMessages` | `(event: HydrateMessagesEvent) => UIMessage[] \| Promise<UIMessage[]>` | — | **Deprecated.** Load message history from backend, replacing the linear accumulator. Use `loadContext` on a `storage` instead; cannot be combined with `storage`. See [hydrateMessages](/ai-chat/lifecycle-hooks#hydratemessages) |
|
|
49
49
|
| `actionSchema` | `TaskSchema` | — | Schema for validating custom actions sent via `transport.sendAction()`. See [Actions](/ai-chat/actions) |
|
|
50
|
-
| `onAction` | `(event: ActionEvent) => Promise<void \| ActionTurn> \| void \| ActionTurn` | — | Handle custom actions. Actions are state edits: only `hydrateMessages` (or a storage's `loadContext`) + `onAction` fire. Return `chat.turn()` to run a turn on the edited history, or nothing for an edit only. See [Actions](/ai-chat/actions) |
|
|
50
|
+
| `onAction` | `(event: ActionEvent) => Promise<void \| ActionTurn> \| void \| ActionTurn` | — | Handle custom actions. Actions are state edits: only `hydrateMessages` (or a storage's `loadContext`) + `onAction` fire. Return `chat.turn()` to run a turn on the edited history (`chat.turn(message)` to answer a new user message), or nothing for an edit only. See [Actions](/ai-chat/actions) |
|
|
51
|
+
| `events` | `ChatEvent[]` | — | Webhook event descriptors (from `chat.event()`) whose verified deliveries are routed to this agent as actions and handled in `onAction`. See [session routing](/webhooks/session-routing). |
|
|
52
|
+
| `channels` | `ChannelConnector[]` | — | Channel connectors (for example `slack()`) that turn an external chat surface into a frontend for the agent: inbound messages run as turns and the reply posts back. See [channels](/webhooks/channels). |
|
|
51
53
|
| `onTurnStart` | `(event: TurnStartEvent) => Promise<void> \| void` | — | Fires every turn before `run()` |
|
|
52
54
|
| `onBeforeTurnComplete` | `(event: BeforeTurnCompleteEvent) => Promise<void> \| void` | — | Fires after response but before stream closes. Includes `writer`. |
|
|
53
55
|
| `onTurnComplete` | `(event: TurnCompleteEvent) => Promise<void> \| void` | — | Fires after each turn completes (stream closed) |
|
|
@@ -232,7 +234,7 @@ The persistence adapter set through `chat.agent({ storage })`. See [Transcript s
|
|
|
232
234
|
| Type | Shape |
|
|
233
235
|
| --- | --- |
|
|
234
236
|
| `TranscriptScope<TClientData>` | `{ chatId: string; clientData: TClientData }` |
|
|
235
|
-
| `TranscriptStorageContext<TClientData>` | `TranscriptScope` plus `{ turn: number; trigger: "submit-message" \| "regenerate-message" \| "action"; runId: string; ctx: TaskRunContext }` |
|
|
237
|
+
| `TranscriptStorageContext<TClientData>` | `TranscriptScope` plus `{ turn: number; trigger: "submit-message" \| "regenerate-message" \| "action" \| "action-turn"; source?: "client" \| "channel" \| "webhook"; connectorId?: string; runId: string; ctx: TaskRunContext }`. `action-turn` is the turn `chat.turn()` requested; `source` names the surface that drove the write |
|
|
236
238
|
| `TranscriptChange` | `{ op: "put"; message: UIMessage; final?: boolean }` \| `{ op: "remove"; id: string }` \| `{ op: "truncateAfter"; afterId: string }` \| `{ op: "state"; value: unknown \| null }` |
|
|
237
239
|
| `TranscriptChangeset` | `{ reason: "turn-complete" \| "turn-error" \| "action" \| "compaction" \| "recovery"; changes: TranscriptChange[]; transcript: TranscriptState; cursors?: TranscriptCursors }` |
|
|
238
240
|
| `TranscriptState` | `{ entries: Array<{ id: string; final: boolean; message: UIMessage }>; state: unknown \| null }`: the whole conversation after the changeset's changes, for stores that write one document |
|
|
@@ -275,6 +277,7 @@ Passed to the `onAction` callback. See [Actions](/ai-chat/actions).
|
|
|
275
277
|
| `clientData` | Typed by `clientDataSchema` | Custom data from the frontend |
|
|
276
278
|
| `uiMessages` | `UIMessage[]` | Accumulated UI messages (after hydration, if set) |
|
|
277
279
|
| `messages` | `ModelMessage[]` | Accumulated model messages (after hydration, if set) |
|
|
280
|
+
| `channel` | `{ connectorId, provider, event, deliveryId }` | For a channel action (a button the agent posted, such as a Slack `slackButton()`): the verified click event. Absent otherwise |
|
|
278
281
|
|
|
279
282
|
## TurnStartEvent
|
|
280
283
|
|
|
@@ -538,6 +541,8 @@ All methods available on the `chat` object from `@trigger.dev/sdk/ai`.
|
|
|
538
541
|
| Method | Description |
|
|
539
542
|
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
540
543
|
| `chat.agent(options)` | Create a chat agent |
|
|
544
|
+
| `chat.event(options)` | Declare an inbound webhook event descriptor an agent claims via `chat.agent({ events })`. See [session routing](/webhooks/session-routing). |
|
|
545
|
+
| `chat.channels.custom(options)` | Create a generic chat-frontend channel over any verified webhook source (you supply the egress). The `slack()` preset ships in `@trigger.dev/slack`. See [channels](/webhooks/channels). |
|
|
541
546
|
| `chat.createSession(payload, options)` | Create an async iterator for chat turns |
|
|
542
547
|
| `chat.pipe(source, options?)` | Pipe a stream to the frontend (from anywhere inside a task) |
|
|
543
548
|
| `chat.pipeAndCapture(source, options?)` | Pipe and capture the response; returns `{ message, status, error }` |
|
|
@@ -570,6 +575,49 @@ All methods available on the `chat` object from `@trigger.dev/sdk/ai`.
|
|
|
570
575
|
| `chat.withUIMessage(config?)` | Returns a [ChatBuilder](/ai-chat/types#chatbuilder) with a fixed `UIMessage` subtype. See [Types](/ai-chat/types) |
|
|
571
576
|
| `chat.withClientData({ schema })` | Returns a [ChatBuilder](/ai-chat/types#chatbuilder) with a fixed client data schema. See [Types](/ai-chat/types#typed-client-data-with-chatwithclientdata) |
|
|
572
577
|
|
|
578
|
+
## `chat.event`
|
|
579
|
+
|
|
580
|
+
Declare an inbound webhook event that an agent claims via [`events`](#chatagentoptions) on `chat.agent()`. It is a descriptor only, with no handler: it names the [endpoint](/webhooks/overview) it subscribes to, a `key` template that resolves each delivery to a durable [session](/ai-chat/sessions), and an optional `type` label (defaults to the descriptor `id`). Verified deliveries are routed to that session and arrive at `onAction` as a `{ type, event, source, headers, deliveryId, endpoint }` envelope, not as a chat turn. See [session routing](/webhooks/session-routing).
|
|
581
|
+
|
|
582
|
+
```ts
|
|
583
|
+
import { webhooks } from "@trigger.dev/sdk";
|
|
584
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
585
|
+
|
|
586
|
+
export const stripe = webhooks.endpoint.define({ id: "stripe", source: webhooks.stripe() });
|
|
587
|
+
|
|
588
|
+
export const orderEvents = chat.event({
|
|
589
|
+
id: "order-events",
|
|
590
|
+
endpoint: stripe,
|
|
591
|
+
key: "{event.data.object.customer}",
|
|
592
|
+
type: "order.event",
|
|
593
|
+
});
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
## `chat.channels.custom`
|
|
597
|
+
|
|
598
|
+
Create a generic chat-frontend channel on any [endpoint](/webhooks/overview), claimed via [`channels`](#chatagentoptions) on `chat.agent()`. You supply the session `key`, the `inbound` map from event to turn message, and your own `send` egress that posts the reply back, so the whole round-trip is under your control. Inbound messages run as normal turns and the reply is posted back. The `slack()` preset ships in `@trigger.dev/slack` and wires the egress for you. See [channels](/webhooks/channels), and the interactive approvals layer at [human-in-the-loop](/webhooks/human-in-the-loop).
|
|
599
|
+
|
|
600
|
+
```ts
|
|
601
|
+
import { webhooks } from "@trigger.dev/sdk";
|
|
602
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
603
|
+
|
|
604
|
+
const surface = webhooks.endpoint.define({
|
|
605
|
+
id: "my-surface",
|
|
606
|
+
source: webhooks.custom<MyEvent>({ /* verifier config */ }),
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
export const mySurface = chat.channels.custom({
|
|
610
|
+
id: "my-surface",
|
|
611
|
+
endpoint: surface,
|
|
612
|
+
key: "{event.conversationId}",
|
|
613
|
+
inbound: (event) => event.text,
|
|
614
|
+
send: async (message, ctx) => {
|
|
615
|
+
const ref = await postToMySurface(ctx.event, message.text, ctx.previousRef);
|
|
616
|
+
return { ref };
|
|
617
|
+
},
|
|
618
|
+
});
|
|
619
|
+
```
|
|
620
|
+
|
|
573
621
|
## `chat.withUIMessage`
|
|
574
622
|
|
|
575
623
|
Returns a [`ChatBuilder`](/ai-chat/types#chatbuilder) with a fixed `UIMessage` subtype. Chain `.withClientData()`, hook methods, and `.agent()`.
|
package/docs/apikeys.mdx
CHANGED
|
@@ -75,7 +75,7 @@ The default API URL is `https://api.trigger.dev`.
|
|
|
75
75
|
|
|
76
76
|
## Access presets
|
|
77
77
|
|
|
78
|
-
Access presets define what a key can do.
|
|
78
|
+
Access presets define what a key can do. On the Free and Hobby plans only the **No restrictions** preset is available. All other presets require the Pro or Enterprise plan.
|
|
79
79
|
|
|
80
80
|
| Preset | Access |
|
|
81
81
|
| --- | --- |
|
|
@@ -87,7 +87,7 @@ Access presets define what a key can do. Some presets require a paid plan. The d
|
|
|
87
87
|
| **Variables only** | Read and write environment variables in this environment |
|
|
88
88
|
| **No restrictions** | Full access to the environment |
|
|
89
89
|
|
|
90
|
-
**Trigger only** and **Task operator** can be restricted to selected tasks. Task restrictions use task identifiers, such as `send-email`. A request involving multiple tasks — such as a batch trigger — succeeds only when the key can access every task in the request, so a task-restricted key can batch-trigger only its selected tasks.
|
|
90
|
+
**Trigger only** and **Task operator** can be restricted to selected tasks, up to 10 tasks per key. Task restrictions use task identifiers, such as `send-email`. A request involving multiple tasks — such as a batch trigger — succeeds only when the key can access every task in the request, so a task-restricted key can batch-trigger only its selected tasks.
|
|
91
91
|
|
|
92
92
|
## Deploy with an API key
|
|
93
93
|
|
|
@@ -124,7 +124,7 @@ Use `@trigger.dev/sdk` version 4.5.8 or later to create public tokens with envir
|
|
|
124
124
|
|
|
125
125
|
- The token must request at least one scope.
|
|
126
126
|
- Its scopes cannot exceed the key's access.
|
|
127
|
-
- Its expiration cannot exceed 30 days.
|
|
127
|
+
- Its expiration cannot exceed 30 days (the default is 15 minutes).
|
|
128
128
|
|
|
129
129
|
<Note>
|
|
130
130
|
Revoking or expiring an API key does not revoke tokens it already created. Those tokens remain valid until their own expiration.
|
package/docs/billing-limits.mdx
CHANGED
|
@@ -49,7 +49,7 @@ When your organization's spend reaches the billing limit, billable environments
|
|
|
49
49
|
2. New runs can still be triggered and are queued, but they won't start executing. Queued runs incur no compute cost until they start.
|
|
50
50
|
3. You have **24 hours** to review and decide what to do.
|
|
51
51
|
|
|
52
|
-
If you don't act before the grace period ends,
|
|
52
|
+
If you don't act before the grace period ends, new triggers are rejected until you increase or remove the limit (limits also reset at the start of each billing cycle). Queued runs stay queued until you resolve the limit and choose to resume or cancel them. If the limit is still in place when a new billing cycle starts, queued runs resume automatically. Runs that have a TTL still expire if they stay queued past it.
|
|
53
53
|
|
|
54
54
|
<Note>
|
|
55
55
|
Billing limits are **soft limits**, not instantaneous hard caps. Usage is evaluated on a short
|