@trigger.dev/sdk 4.5.12 → 4.5.14
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 +154 -20
- package/dist/commonjs/v3/ai.js +1241 -387
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +7 -2
- package/dist/commonjs/v3/chat.js +22 -7
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/chat.test.js +13 -4
- package/dist/commonjs/v3/chat.test.js.map +1 -1
- package/dist/commonjs/v3/envvars.js.map +1 -1
- package/dist/commonjs/v3/sessions.d.ts +4 -10
- package/dist/commonjs/v3/sessions.js +73 -47
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/streams.js +1 -0
- package/dist/commonjs/v3/streams.js.map +1 -1
- package/dist/commonjs/v3/test/mock-chat-agent.js +1 -0
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/commonjs/v3/test/test-session-handle.js +22 -23
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai.d.ts +154 -20
- package/dist/esm/v3/ai.js +1239 -387
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +7 -2
- package/dist/esm/v3/chat.js +22 -7
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/chat.test.js +13 -4
- package/dist/esm/v3/chat.test.js.map +1 -1
- package/dist/esm/v3/envvars.js.map +1 -1
- package/dist/esm/v3/sessions.d.ts +4 -10
- package/dist/esm/v3/sessions.js +73 -47
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/streams.js +1 -0
- package/dist/esm/v3/streams.js.map +1 -1
- package/dist/esm/v3/test/mock-chat-agent.js +2 -1
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/esm/v3/test/test-session-handle.js +23 -24
- package/dist/esm/v3/test/test-session-handle.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/client-protocol.mdx +8 -3
- package/docs/ai-chat/custom-agents.mdx +181 -46
- package/docs/ai-chat/patterns/recovery-boot.mdx +9 -2
- package/docs/ai-chat/patterns/version-upgrades.mdx +26 -6
- package/docs/ai-chat/pending-messages.mdx +5 -3
- package/docs/ai-chat/reference.mdx +26 -10
- package/docs/ai-chat/types.mdx +5 -1
- package/docs/deployment/atomic-deployment.mdx +12 -0
- package/docs/deployment/overview.mdx +7 -1
- package/docs/deployment/version-skew-protection.mdx +430 -0
- package/docs/github-actions.mdx +33 -5
- package/docs/github-integration.mdx +12 -0
- package/docs/realtime/auth.mdx +18 -0
- package/docs/realtime/react-hooks/session-stream.mdx +109 -0
- package/docs/realtime/react-hooks/streams.mdx +71 -3
- package/docs/self-hosting/env/webapp.mdx +1 -0
- package/docs/self-hosting/security.mdx +1 -1
- package/docs/tasks/streams.mdx +3 -0
- package/docs/vercel-integration.mdx +43 -9
- package/docs/versioning.mdx +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Read a session channel in React"
|
|
3
|
+
sidebarTitle: "Session streams"
|
|
4
|
+
description: "Subscribe to a session's output or input channel from React with useSessionStream: accumulate records, resume from a cursor, and read only the latest."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**`useSessionStream` subscribes to one channel of a [session](/ai-chat/sessions) and updates a `records` array as new records arrive.** It reads the `out` channel by default (the agent's output) or `in` (the input channel). It is read-only; `useSession` is reserved for two-way (read and write) communication.
|
|
8
|
+
|
|
9
|
+
<Note>
|
|
10
|
+
Requires a Public Access Token with the `read:sessions:{id}` scope. See [Realtime
|
|
11
|
+
auth](/realtime/auth) for generating one.
|
|
12
|
+
</Note>
|
|
13
|
+
|
|
14
|
+
## Basic usage
|
|
15
|
+
|
|
16
|
+
Pass the session id (or external id) and an `accessToken`. The hook returns the `records` received so far, the last control record, the cursor of the last record seen, and any error:
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
"use client";
|
|
20
|
+
|
|
21
|
+
import { useSessionStream } from "@trigger.dev/react-hooks";
|
|
22
|
+
|
|
23
|
+
export function SessionViewer({
|
|
24
|
+
sessionId,
|
|
25
|
+
accessToken,
|
|
26
|
+
}: {
|
|
27
|
+
sessionId: string;
|
|
28
|
+
accessToken: string;
|
|
29
|
+
}) {
|
|
30
|
+
const { records, error } = useSessionStream<string>(sessionId, { accessToken });
|
|
31
|
+
|
|
32
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
33
|
+
|
|
34
|
+
return <div>{records.join("")}</div>;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Options
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
const { records, lastEventId, lastControl, error, stop } = useSessionStream(sessionId, {
|
|
42
|
+
accessToken: "pk_...", // Required: public access token with read:sessions:{id}
|
|
43
|
+
io: "out", // Optional: "out" (default) or "in"
|
|
44
|
+
from: "beginning", // Optional: "beginning" (default) or "latest"
|
|
45
|
+
maxRecords: 100, // Optional: keep only the most recent N records (default: unbounded)
|
|
46
|
+
lastEventId: undefined, // Optional: resume cursor
|
|
47
|
+
timeoutInSeconds: 60, // Optional: close after this long with no new data (default: 60)
|
|
48
|
+
throttleInMs: 16, // Optional: throttle record updates (default: 16ms)
|
|
49
|
+
onRecords: (batch) => {}, // Optional: callback per throttled batch, each with its event id
|
|
50
|
+
onControl: (event) => {}, // Optional: callback for control records (e.g. turn-complete)
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The return value:
|
|
55
|
+
|
|
56
|
+
- **`records`**: every data record received so far, in arrival order. Control records are delivered to `onControl` instead.
|
|
57
|
+
- **`lastEventId`**: the cursor of the last record seen. Persist it and pass it back as the `lastEventId` option to resume.
|
|
58
|
+
- **`lastControl`**: the last control record (for example `turn-complete`).
|
|
59
|
+
- **`stop`**: abort the subscription, keeping the records received so far.
|
|
60
|
+
|
|
61
|
+
## Start from the latest record
|
|
62
|
+
|
|
63
|
+
By default the hook replays the channel history, then live-tails. Pass `from: "latest"` to start at the current tail (the latest record, then live updates) instead of replaying, and `maxRecords` to bound memory:
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
const { records } = useSessionStream<{ url: string }>(sessionId, {
|
|
67
|
+
accessToken,
|
|
68
|
+
io: "out",
|
|
69
|
+
from: "latest", // start at the latest record, then live updates
|
|
70
|
+
maxRecords: 1, // keep just the most recent record
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
<Note>
|
|
75
|
+
`from: "latest"` requires a server that supports it. Against an older server a client that passes
|
|
76
|
+
it degrades safely to a full replay.
|
|
77
|
+
</Note>
|
|
78
|
+
|
|
79
|
+
## Resume from a cursor
|
|
80
|
+
|
|
81
|
+
The hook resumes automatically across a component remount. A full page reload clears in-memory state, so to resume there, persist the returned `lastEventId` and pass it back on the next load. The channel then continues after that record with no replay and no gap:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const cursorKey = `session-cursor:${sessionId}:out`; // scope the key to this session and channel
|
|
85
|
+
const saved = localStorage.getItem(cursorKey) ?? undefined;
|
|
86
|
+
|
|
87
|
+
const { records, lastEventId } = useSessionStream<string>(sessionId, {
|
|
88
|
+
accessToken,
|
|
89
|
+
lastEventId: saved,
|
|
90
|
+
onRecords: (batch) => localStorage.setItem(cursorKey, batch.at(-1)!.id),
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## React to control records
|
|
95
|
+
|
|
96
|
+
Control records (such as `turn-complete`) never enter `records`. Handle them with `onControl`, or read the latest from `lastControl`:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
const { records, lastControl } = useSessionStream<string>(sessionId, {
|
|
100
|
+
accessToken,
|
|
101
|
+
onControl: (event) => {
|
|
102
|
+
if (event.subtype === "turn-complete") {
|
|
103
|
+
console.log("The turn is complete");
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
For an expiring token on a long-lived subscription, pass `refreshAccessToken` (see [Realtime auth](/realtime/auth)). To read a session channel outside React, use [`session.out.read()`](/ai-chat/sessions).
|
|
@@ -130,16 +130,84 @@ export function AIStreamViewer({
|
|
|
130
130
|
The `useRealtimeStream` hook accepts the following options:
|
|
131
131
|
|
|
132
132
|
```tsx
|
|
133
|
-
const { parts, error } = useRealtimeStream(streamOrRunId, streamKeyOrOptions, {
|
|
133
|
+
const { parts, lastEventId, error } = useRealtimeStream(streamOrRunId, streamKeyOrOptions, {
|
|
134
134
|
accessToken: "pk_...", // Required: Public access token
|
|
135
135
|
baseURL: "https://api.trigger.dev", // Optional: Custom API URL
|
|
136
136
|
timeoutInSeconds: 60, // Optional: Timeout (default: 60)
|
|
137
|
-
|
|
137
|
+
from: "beginning", // Optional: "beginning" (default) or "latest"
|
|
138
|
+
maxParts: 100, // Optional: keep only the most recent N parts (default: unbounded)
|
|
139
|
+
lastEventId: undefined, // Optional: resume cursor (takes precedence over startIndex)
|
|
140
|
+
startIndex: 0, // Optional: start from a specific chunk index
|
|
138
141
|
throttleInMs: 16, // Optional: Throttle updates (default: 16ms)
|
|
139
|
-
onData: (chunk) => {}, // Optional:
|
|
142
|
+
onData: (chunk) => {}, // Optional: callback for each chunk
|
|
143
|
+
onParts: (batch) => {}, // Optional: callback per throttled batch, each with its event id
|
|
144
|
+
refreshAccessToken: async () => "pk_...", // Optional: mint a fresh token on expiry
|
|
140
145
|
});
|
|
141
146
|
```
|
|
142
147
|
|
|
148
|
+
The hook returns `lastEventId`, the cursor of the last part it received. Persist it and pass it back as the `lastEventId` option to resume later.
|
|
149
|
+
|
|
150
|
+
### Live view: start from the latest record
|
|
151
|
+
|
|
152
|
+
By default a subscriber replays the whole stream history, then live-tails. Pass `from: "latest"` to start at the current tail (the latest record, then live updates) instead of replaying, and `maxParts` to keep memory bounded. Together they give a last-value view:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
"use client";
|
|
156
|
+
|
|
157
|
+
import { useRealtimeStream } from "@trigger.dev/react-hooks";
|
|
158
|
+
|
|
159
|
+
export function LatestFrame({ runId, accessToken }: { runId: string; accessToken: string }) {
|
|
160
|
+
const { parts } = useRealtimeStream<{ url: string }>(runId, "frames", {
|
|
161
|
+
accessToken,
|
|
162
|
+
from: "latest", // start at the latest frame, then live updates
|
|
163
|
+
maxParts: 1, // keep just the most recent frame
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const frame = parts.at(-1);
|
|
167
|
+
return frame ? <img src={frame.url} alt="latest frame" /> : null;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
<Note>
|
|
172
|
+
`from: "latest"` requires a server that supports it. Against an older server a client that passes
|
|
173
|
+
it degrades safely to a full replay.
|
|
174
|
+
</Note>
|
|
175
|
+
|
|
176
|
+
### Resume across a page reload
|
|
177
|
+
|
|
178
|
+
The hook resumes automatically across a component remount. A full page reload clears in-memory
|
|
179
|
+
state, so to resume there, persist the returned `lastEventId` and pass it back on the next load. The
|
|
180
|
+
subscription then continues after that record with no replay and no gap:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
const cursorKey = `frames-cursor:${runId}`; // scope the key to this stream
|
|
184
|
+
const saved = localStorage.getItem(cursorKey) ?? undefined;
|
|
185
|
+
|
|
186
|
+
const { parts, lastEventId } = useRealtimeStream<{ url: string }>(runId, "frames", {
|
|
187
|
+
accessToken,
|
|
188
|
+
lastEventId: saved, // resume where the previous session left off
|
|
189
|
+
onParts: (batch) => localStorage.setItem(cursorKey, batch.at(-1)!.id),
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Refresh an expired access token
|
|
194
|
+
|
|
195
|
+
Public access tokens are short-lived. For a long-running subscription, pass `refreshAccessToken` to
|
|
196
|
+
mint a fresh token when the server rejects the connection with a 401/403. The subscription re-mints
|
|
197
|
+
once and reconnects; with no refresher, auth errors stay terminal:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
const { parts } = useRealtimeStream<{ url: string }>(runId, "frames", {
|
|
201
|
+
accessToken,
|
|
202
|
+
refreshAccessToken: async () => {
|
|
203
|
+
const res = await fetch("/api/realtime-token"); // your backend mints a fresh public token
|
|
204
|
+
return (await res.json()).token;
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`refreshAccessToken` is also available on [`useApiClient` and `TriggerAuthContext`](/realtime/auth), so every hook under a provider shares one refresher.
|
|
210
|
+
|
|
143
211
|
### Using Default Stream
|
|
144
212
|
|
|
145
213
|
You can omit the stream key to use the default stream:
|
|
@@ -184,6 +184,7 @@ mode: "wide"
|
|
|
184
184
|
| `MACHINE_PRESETS_OVERRIDE_PATH` | No | — | Path to machine presets override file. See [machine overrides](/self-hosting/overview#machine-overrides). |
|
|
185
185
|
| `APP_ENV` | No | `NODE_ENV` | App environment. Used for things like the title tag. |
|
|
186
186
|
| `ADMIN_EMAILS` | No | — | Regex of user emails to automatically promote to admin on signup. Does not apply to existing users. |
|
|
187
|
+
| `ADMIN_DASHBOARD_ENABLED` | No | 1 | Set to anything other than `1` or `true` to disable the admin dashboard and user impersonation on this instance. |
|
|
187
188
|
| `EVENT_LOOP_MONITOR_ENABLED` | No | 1 | Node.js event loop lag monitor. |
|
|
188
189
|
|
|
189
190
|
## Multi-Provider Object Storage
|
|
@@ -15,7 +15,7 @@ We take the security of Trigger.dev seriously, for both Cloud and self-hosted de
|
|
|
15
15
|
<Steps>
|
|
16
16
|
<Step title="Choose a private channel">
|
|
17
17
|
- **GitHub (preferred):** open a private report from the repository's **Security** tab using **"Report a vulnerability"** ([direct link](https://github.com/triggerdotdev/trigger.dev/security/advisories/new)).
|
|
18
|
-
- **Email:** `security
|
|
18
|
+
- **Email:** `security@trigger.dev`
|
|
19
19
|
</Step>
|
|
20
20
|
<Step title="Include the details">
|
|
21
21
|
A description and impact, steps to reproduce (a proof of concept helps), affected versions/components, and any suggested fix.
|
package/docs/tasks/streams.mdx
CHANGED
|
@@ -144,9 +144,12 @@ With options:
|
|
|
144
144
|
const stream = await aiStream.read(runId, {
|
|
145
145
|
timeoutInSeconds: 60, // Stop if no data for 60 seconds
|
|
146
146
|
startIndex: 10, // Start from the 10th chunk
|
|
147
|
+
from: "latest", // Or skip history and read only new records from now
|
|
147
148
|
});
|
|
148
149
|
```
|
|
149
150
|
|
|
151
|
+
Pass `from: "latest"` to start at the current tail and receive only records appended after the read connects, instead of replaying from the beginning.
|
|
152
|
+
|
|
150
153
|
#### Appending to a Stream
|
|
151
154
|
|
|
152
155
|
Use the defined stream's `append()` method to add a single chunk:
|
|
@@ -5,7 +5,7 @@ description: "Automatically deploy your tasks whenever you deploy to Vercel."
|
|
|
5
5
|
|
|
6
6
|
## How it works
|
|
7
7
|
|
|
8
|
-
The Vercel integration connects your Vercel project to your Trigger.dev project so that every Vercel deployment automatically triggers a Trigger.dev deployment. It also syncs environment variables from Vercel into Trigger.dev and
|
|
8
|
+
The Vercel integration connects your Vercel project to your Trigger.dev project so that every Vercel deployment automatically triggers a Trigger.dev deployment. It also syncs environment variables from Vercel into Trigger.dev, and sets up [version skew protection](/deployment/version-skew-protection) so your app and tasks stay in sync.
|
|
9
9
|
|
|
10
10
|
This eliminates the need to manually run the `trigger.dev deploy` command or maintain custom CI/CD workflows for Vercel-based projects.
|
|
11
11
|
|
|
@@ -42,8 +42,7 @@ You can connect Vercel from two entry points:
|
|
|
42
42
|
</Step>
|
|
43
43
|
|
|
44
44
|
<Step title="Configure build options">
|
|
45
|
-
Optionally adjust [build options](#build-options) for
|
|
46
|
-
env var discovery.
|
|
45
|
+
Optionally adjust [build options](#build-options) for env var pulling and new env var discovery.
|
|
47
46
|
</Step>
|
|
48
47
|
|
|
49
48
|
<Step title="Connect GitHub">
|
|
@@ -99,7 +98,7 @@ The integration syncs environment variables in both directions:
|
|
|
99
98
|
|
|
100
99
|
The following variables are excluded from the Vercel → Trigger.dev sync:
|
|
101
100
|
|
|
102
|
-
- `TRIGGER_SECRET_KEY`, `TRIGGER_VERSION`, `TRIGGER_PREVIEW_BRANCH` (managed by Trigger.dev)
|
|
101
|
+
- `TRIGGER_SECRET_KEY`, `TRIGGER_API_URL`, `TRIGGER_VERSION`, `TRIGGER_PREVIEW_BRANCH`, `TRIGGER_AUTOMATIC_SKEW_VERSION_PROTECTION` (managed by Trigger.dev)
|
|
103
102
|
- Sensitive/secret-type variables (Vercel API limitation)
|
|
104
103
|
|
|
105
104
|
You can control sync behavior per-variable from your project's Vercel settings. Deselecting a variable prevents its value from being updated during future syncs.
|
|
@@ -120,8 +119,41 @@ You can control sync behavior per-variable from your project's Vercel settings.
|
|
|
120
119
|
|
|
121
120
|
If you use [Supabase Branching](https://supabase.com/docs/guides/deployment/branching) or [Neon Database Branching](https://neon.tech/docs/guides/branching-intro) for preview environments, disable syncing for database env vars on the Environment Variables page and use the [syncSupabaseEnvVars](/config/extensions/syncEnvVars#syncsupabaseenvvars) or [syncNeonEnvVars](/config/extensions/syncEnvVars#syncneonenvvars) build extensions instead. These extensions automatically resolve the correct branch-specific credentials at build time.
|
|
122
121
|
|
|
122
|
+
## Version skew protection
|
|
123
|
+
|
|
124
|
+
Your Vercel app and your tasks are deployed separately, so there is always a window where a new app can trigger tasks built from older code. [Version skew protection](/deployment/version-skew-protection) closes that window: each Trigger.dev deployment is tagged with your commit SHA, your app sends the same SHA when it triggers, and every run is pinned to the deployment built from the same commit. Runs triggered before the task build finishes wait for it rather than running on the previous version.
|
|
125
|
+
|
|
126
|
+
The integration sets this up for you:
|
|
127
|
+
|
|
128
|
+
- It sets `TRIGGER_AUTOMATIC_SKEW_VERSION_PROTECTION=1` on your Vercel project when you connect it, and re-asserts it on every build — so existing projects pick it up on their next deployment.
|
|
129
|
+
- It passes your commit SHA as the deployment's external id.
|
|
130
|
+
- `VERCEL_GIT_COMMIT_SHA` is available at runtime on Vercel, so the SDK finds the matching id with no work from you.
|
|
131
|
+
|
|
132
|
+
There is nothing to enable, and it works in production, staging and preview alike. Nothing is gated: your Vercel deployment is never held back.
|
|
133
|
+
|
|
134
|
+
<Note>
|
|
135
|
+
Version skew protection requires the `@trigger.dev/sdk` release that introduces external
|
|
136
|
+
deployment ids. Check the [release
|
|
137
|
+
notes](https://github.com/triggerdotdev/trigger.dev/releases) for the exact version, or just use
|
|
138
|
+
the latest. On an older SDK no id is sent and your runs execute on the current version, with no
|
|
139
|
+
warning.
|
|
140
|
+
</Note>
|
|
141
|
+
|
|
142
|
+
To opt out, set `TRIGGER_AUTOMATIC_SKEW_VERSION_PROTECTION` to `0` on your Vercel project. The integration only writes the variable when it is absent, so a value you set is never overwritten.
|
|
143
|
+
|
|
123
144
|
## Atomic deployments
|
|
124
145
|
|
|
146
|
+
<Warning>
|
|
147
|
+
**Automatic atomic deployments are deprecated.** Use [version skew
|
|
148
|
+
protection](/deployment/version-skew-protection) instead — it needs no second Vercel deployment,
|
|
149
|
+
never gates your app's deploy, doesn't touch `Auto-assign Custom Production Domains`, and covers
|
|
150
|
+
staging and preview as well as production.
|
|
151
|
+
|
|
152
|
+
Nothing is being switched off. The setting stays in your project's Vercel settings, keeps working,
|
|
153
|
+
and remains the way to hold your Vercel deployment back until your tasks have built. New
|
|
154
|
+
connections have it off by default.
|
|
155
|
+
</Warning>
|
|
156
|
+
|
|
125
157
|
Atomic deployments ensure your Vercel app and Trigger.dev tasks are deployed in sync. When enabled, Trigger.dev gates your Vercel deployment until the task build completes, then triggers a Vercel redeployment with the correct `TRIGGER_VERSION` set. This guarantees your app always uses the matching version of your tasks.
|
|
126
158
|
|
|
127
159
|
```mermaid
|
|
@@ -152,15 +184,16 @@ sequenceDiagram
|
|
|
152
184
|
TD->>TD: Promote build
|
|
153
185
|
```
|
|
154
186
|
|
|
155
|
-
Atomic deployments are
|
|
187
|
+
Atomic deployments are off by default for new connections. Projects that already had them enabled keep them enabled until you turn them off. Enabling them asks you to confirm first.
|
|
156
188
|
|
|
157
189
|
<Note>
|
|
158
190
|
When atomic deployments are enabled, the integration automatically disables `Auto-assign Custom
|
|
159
191
|
Production Domains` on your Vercel project. This is required so that Vercel doesn't promote a
|
|
160
|
-
deployment before the Trigger.dev build is ready.
|
|
192
|
+
deployment before the Trigger.dev build is ready. If you turn atomic deployments off, re-enable
|
|
193
|
+
that setting in Vercel or promote deployments yourself.
|
|
161
194
|
</Note>
|
|
162
195
|
|
|
163
|
-
Previously, setting up atomic deployments with Vercel required custom GitHub Actions workflows. The Vercel integration automates this entirely. For more details on how atomic deployments work, see [Atomic deploys](/deployment/atomic-deployment).
|
|
196
|
+
Previously, setting up atomic deployments with Vercel required custom GitHub Actions workflows. The Vercel integration automates this entirely. For more details on how atomic deployments work, see [Atomic deploys](/deployment/atomic-deployment). For how to move off them, see [replacing automatic atomic deployments](/deployment/version-skew-protection#replacing-automatic-atomic-deployments).
|
|
164
197
|
|
|
165
198
|
## Environment mapping
|
|
166
199
|
|
|
@@ -184,7 +217,7 @@ If your Vercel project has a custom environment, you can select which one maps t
|
|
|
184
217
|
|
|
185
218
|
You can configure the following settings per-environment from your project's Vercel settings:
|
|
186
219
|
|
|
187
|
-
- **Atomic deployments
|
|
220
|
+
- **Atomic deployments** (deprecated): Controls whether Trigger.dev gates and redeploys your Vercel deployment to keep it in sync. Off by default for new connections — use [version skew protection](/deployment/version-skew-protection) instead.
|
|
188
221
|
- **Pull env vars before build**: When enabled, Trigger.dev pulls the latest environment variables from Vercel before each build. Enabled for production, staging, and preview by default.
|
|
189
222
|
- **Discover new env vars**: When enabled, new environment variables found in Vercel that don't yet exist in Trigger.dev are created automatically during builds. Only available for environments that also have env var pulling enabled. Enabled for production, staging, and preview by default.
|
|
190
223
|
|
|
@@ -201,7 +234,8 @@ Disconnecting stops automatic deployments, environment variable syncing, and dep
|
|
|
201
234
|
|
|
202
235
|
## Related
|
|
203
236
|
|
|
237
|
+
- [Version skew protection](/deployment/version-skew-protection)
|
|
204
238
|
- [GitHub integration](/github-integration)
|
|
205
|
-
- [Atomic deploys](/deployment/atomic-deployment)
|
|
239
|
+
- [Atomic deploys](/deployment/atomic-deployment) (deprecated for Vercel)
|
|
206
240
|
- [Environment variables](/deploy-environment-variables)
|
|
207
241
|
- [Preview branches](/deployment/preview-branches)
|
package/docs/versioning.mdx
CHANGED
|
@@ -47,6 +47,8 @@ So a task run will continue running on the version it was locked to. We do this
|
|
|
47
47
|
|
|
48
48
|
Every deployment creates a new version of all tasks for that environment.
|
|
49
49
|
|
|
50
|
+
Because your application and your tasks deploy separately, a release of your app can briefly trigger tasks that belong to a different version. [Version skew protection](/deployment/version-skew-protection) pins each run to the deployment built from the same commit, once your app sends the id it was deployed with.
|
|
51
|
+
|
|
50
52
|
## Retries and reattempts
|
|
51
53
|
|
|
52
54
|
When a task has an uncaught error it will [retry](/errors-retrying), assuming you have not set `maxAttempts` to 0. Retries are locked to the original version of the run.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trigger.dev/sdk",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.14",
|
|
4
4
|
"description": "trigger.dev Node.JS SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@opentelemetry/api": "1.9.1",
|
|
68
68
|
"@opentelemetry/semantic-conventions": "1.41.1",
|
|
69
|
-
"@trigger.dev/core": "4.5.
|
|
69
|
+
"@trigger.dev/core": "4.5.14",
|
|
70
70
|
"uncrypto": "^0.1.3"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|