@trigger.dev/sdk 0.0.0-prerelease-20260908122921 → 0.0.0-prerelease-streamfix-20260909094302
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/imports/ai-runtime-cjs.cjs.map +1 -1
- package/dist/commonjs/imports/ai-runtime.js +0 -2
- package/dist/commonjs/v3/ai.d.ts +16 -199
- package/dist/commonjs/v3/ai.js +102 -983
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat-client.d.ts +2 -3
- package/dist/commonjs/v3/chat-client.js +5 -31
- package/dist/commonjs/v3/chat-client.js.map +1 -1
- package/dist/commonjs/v3/chat-react.d.ts +0 -34
- package/dist/commonjs/v3/chat-react.js +1 -47
- package/dist/commonjs/v3/chat-react.js.map +1 -1
- package/dist/commonjs/v3/chat-server.d.ts +6 -42
- package/dist/commonjs/v3/chat-server.js +7 -52
- package/dist/commonjs/v3/chat-server.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +10 -81
- package/dist/commonjs/v3/chat.js +46 -292
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/sessions.d.ts +2 -15
- package/dist/commonjs/v3/sessions.js +1 -12
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/shared.js +36 -30
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +0 -43
- package/dist/commonjs/v3/test/mock-chat-agent.js +0 -90
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/commonjs/v3/test/test-session-handle.js +0 -6
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/imports/ai-runtime.d.ts +2 -2
- package/dist/esm/imports/ai-runtime.js +2 -2
- package/dist/esm/imports/ai-runtime.js.map +1 -1
- package/dist/esm/v3/ai.d.ts +16 -199
- package/dist/esm/v3/ai.js +103 -984
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat-client.d.ts +2 -3
- package/dist/esm/v3/chat-client.js +5 -31
- package/dist/esm/v3/chat-client.js.map +1 -1
- package/dist/esm/v3/chat-react.d.ts +0 -34
- package/dist/esm/v3/chat-react.js +1 -46
- package/dist/esm/v3/chat-react.js.map +1 -1
- package/dist/esm/v3/chat-server.d.ts +6 -42
- package/dist/esm/v3/chat-server.js +8 -53
- package/dist/esm/v3/chat-server.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +10 -81
- package/dist/esm/v3/chat.js +47 -293
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/sessions.d.ts +2 -15
- package/dist/esm/v3/sessions.js +1 -11
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/shared.js +23 -17
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/test/mock-chat-agent.d.ts +0 -43
- package/dist/esm/v3/test/mock-chat-agent.js +2 -92
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/esm/v3/test/test-session-handle.js +0 -6
- package/dist/esm/v3/test/test-session-handle.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/actions.mdx +23 -55
- package/docs/ai-chat/anatomy.mdx +3 -3
- package/docs/ai-chat/backend.mdx +48 -125
- package/docs/ai-chat/background-injection.mdx +19 -67
- package/docs/ai-chat/client-protocol.mdx +4 -5
- package/docs/ai-chat/compaction.mdx +7 -11
- package/docs/ai-chat/custom-agents.mdx +0 -23
- package/docs/ai-chat/fast-starts.mdx +20 -27
- package/docs/ai-chat/frontend.mdx +14 -17
- package/docs/ai-chat/migrating-from-a-route-handler.mdx +14 -16
- package/docs/ai-chat/patterns/skills.mdx +10 -7
- package/docs/ai-chat/patterns/version-upgrades.mdx +6 -79
- package/docs/ai-chat/pending-messages.mdx +3 -3
- package/docs/ai-chat/prompt-caching.mdx +25 -23
- package/docs/ai-chat/quick-start.mdx +11 -11
- package/docs/ai-chat/reference.mdx +5 -12
- package/docs/ai-chat/sessions.mdx +1 -6
- package/docs/ai-chat/testing.mdx +1 -2
- package/docs/ai-chat/tools.mdx +13 -18
- package/docs/ai-chat/upgrade-guide.mdx +2 -2
- package/docs/apikeys.mdx +45 -27
- package/docs/deployment/overview.mdx +8 -4
- package/docs/deployment/preview-branches.mdx +4 -4
- package/docs/deployment/version-skew-protection.mdx +0 -62
- package/docs/manual-setup.mdx +7 -7
- package/docs/mcp-tools.mdx +0 -9
- package/docs/quick-start.mdx +3 -3
- package/docs/realtime/auth.mdx +1 -1
- package/docs/self-hosting/security.mdx +0 -5
- package/docs/tasks/scheduled.mdx +0 -24
- package/docs/triggering.mdx +1 -1
- package/package.json +4 -4
- package/skills/trigger-authoring-chat-agent/SKILL.md +27 -38
- package/skills/trigger-chat-agent-advanced/SKILL.md +12 -31
- package/dist/commonjs/v3/chatVersionSkew.d.ts +0 -12
- package/dist/commonjs/v3/chatVersionSkew.js +0 -30
- package/dist/commonjs/v3/chatVersionSkew.js.map +0 -1
- package/dist/commonjs/v3/externalDeploymentId.d.ts +0 -23
- package/dist/commonjs/v3/externalDeploymentId.js +0 -43
- package/dist/commonjs/v3/externalDeploymentId.js.map +0 -1
- package/dist/esm/v3/chatVersionSkew.d.ts +0 -12
- package/dist/esm/v3/chatVersionSkew.js +0 -27
- package/dist/esm/v3/chatVersionSkew.js.map +0 -1
- package/dist/esm/v3/externalDeploymentId.d.ts +0 -23
- package/dist/esm/v3/externalDeploymentId.js +0 -38
- package/dist/esm/v3/externalDeploymentId.js.map +0 -1
- package/docs/ai-chat/patterns/native-compaction.mdx +0 -310
- package/docs/reports.mdx +0 -157
- package/docs/troubleshooting-zod.mdx +0 -158
package/docs/apikeys.mdx
CHANGED
|
@@ -10,35 +10,17 @@ description: "Authenticate backend requests with environment-specific API keys."
|
|
|
10
10
|
environment variable, never commit them to source control, and never expose them in frontend code.
|
|
11
11
|
</Warning>
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Find your API keys
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Open your project in the dashboard, select an environment, and open the [**API keys**](https://cloud.trigger.dev/_/apikeys) page.
|
|
16
16
|
|
|
17
|
-
API keys belong to one environment. A Development key cannot access Production, and a Production key cannot access Staging.
|
|
17
|
+
API keys belong to one environment. A Development key cannot access Production, and a Production key cannot access Staging.
|
|
18
18
|
|
|
19
19
|
<Note>
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
Every team member has their own Development environment and keys. Copy the Development key from
|
|
21
|
+
your own API keys page so local requests run against your machine.
|
|
22
22
|
</Note>
|
|
23
23
|
|
|
24
|
-
<Steps titleSize="h3">
|
|
25
|
-
<Step title="Open the API keys page">
|
|
26
|
-
Select the project and environment the integration needs to access, then open [**API keys**](https://cloud.trigger.dev/_/apikeys).
|
|
27
|
-
</Step>
|
|
28
|
-
<Step title="Create the key">
|
|
29
|
-
Click **New API key**, enter a descriptive name, and optionally set an expiration date. Names can
|
|
30
|
-
contain up to 64 characters.
|
|
31
|
-
</Step>
|
|
32
|
-
<Step title="Choose its access">
|
|
33
|
-
Select the narrowest access preset that supports the integration. For task-aware presets, choose
|
|
34
|
-
all tasks or up to 10 task identifiers.
|
|
35
|
-
</Step>
|
|
36
|
-
<Step title="Copy and store the secret">
|
|
37
|
-
Copy the key into your secret manager or backend environment. Trigger.dev shows the complete
|
|
38
|
-
value only once.
|
|
39
|
-
</Step>
|
|
40
|
-
</Steps>
|
|
41
|
-
|
|
42
24
|
## Configure the SDK
|
|
43
25
|
|
|
44
26
|
Set `TRIGGER_SECRET_KEY` in your backend environment. The SDK reads it automatically for operations such as triggering tasks and retrieving runs.
|
|
@@ -67,12 +49,38 @@ await tasks.trigger<typeof sendEmail>("send-email", {
|
|
|
67
49
|
If you self-host Trigger.dev, set `TRIGGER_API_URL` or pass `baseURL` to `configure`:
|
|
68
50
|
|
|
69
51
|
```bash .env
|
|
70
|
-
TRIGGER_SECRET_KEY="
|
|
52
|
+
TRIGGER_SECRET_KEY="tr_prod_…"
|
|
71
53
|
TRIGGER_API_URL="https://trigger.example.com"
|
|
72
54
|
```
|
|
73
55
|
|
|
74
56
|
The default API URL is `https://api.trigger.dev`.
|
|
75
57
|
|
|
58
|
+
## Create a key
|
|
59
|
+
|
|
60
|
+
Create a separate key for each service or integration that accesses Trigger.dev.
|
|
61
|
+
|
|
62
|
+
<Note>
|
|
63
|
+
Creating and revoking keys requires permission to manage API keys for the selected environment.
|
|
64
|
+
The dashboard disables these actions when your role does not have permission.
|
|
65
|
+
</Note>
|
|
66
|
+
|
|
67
|
+
<Steps titleSize="h3">
|
|
68
|
+
<Step title="Open the API keys page">
|
|
69
|
+
Select the project and environment the integration needs to access, then open [**API keys**](https://cloud.trigger.dev/_/apikeys).
|
|
70
|
+
</Step>
|
|
71
|
+
<Step title="Create the key">
|
|
72
|
+
Click **New API key**, enter a descriptive name, and optionally set an expiration date. Names can
|
|
73
|
+
contain up to 64 characters.
|
|
74
|
+
</Step>
|
|
75
|
+
<Step title="Choose its access">
|
|
76
|
+
Select an access preset. For task-aware presets, choose all tasks or up to 10 task identifiers.
|
|
77
|
+
</Step>
|
|
78
|
+
<Step title="Copy and store the secret">
|
|
79
|
+
Copy the key into your secret manager or backend environment. Trigger.dev shows the complete
|
|
80
|
+
value only once.
|
|
81
|
+
</Step>
|
|
82
|
+
</Steps>
|
|
83
|
+
|
|
76
84
|
## Access presets
|
|
77
85
|
|
|
78
86
|
Access presets define what a key can do. Some presets require a paid plan. The dashboard shows which presets your organization can use — see [pricing](https://trigger.dev/pricing).
|
|
@@ -116,18 +124,28 @@ Revoking a key takes effect immediately and cannot be reversed. Requests using t
|
|
|
116
124
|
|
|
117
125
|
Removing a team member does not revoke keys they created. Review and revoke their keys separately when their access changes.
|
|
118
126
|
|
|
127
|
+
## Root keys
|
|
128
|
+
|
|
129
|
+
<Warning>
|
|
130
|
+
Root keys are legacy, and are likely to be deprecated in the future. We recommend against using them.
|
|
131
|
+
</Warning>
|
|
132
|
+
|
|
133
|
+
Each environment has a single legacy root key. It can be regenerated, which creates a new value immediately. The previous root key remains valid for 24 hours so you can update services without downtime, then stops authenticating.
|
|
134
|
+
|
|
135
|
+
Public access tokens signed with the previous root key remain valid until the earlier of their own expiration and the end of the 24-hour grace period.
|
|
136
|
+
|
|
119
137
|
## Create public access tokens
|
|
120
138
|
|
|
121
139
|
API keys can be used to create scoped [Public Access Tokens](/realtime/auth) using `auth.createPublicToken()`.
|
|
122
140
|
|
|
123
|
-
|
|
141
|
+
To do so with the newer non-root keys, you must use `@trigger.dev/sdk` version 4.5.8 or later. Creating public tokens with non-root keys has the following restrictions:
|
|
124
142
|
|
|
125
143
|
- The token must request at least one scope.
|
|
126
144
|
- Its scopes cannot exceed the key's access.
|
|
127
145
|
- Its expiration cannot exceed 30 days.
|
|
128
146
|
|
|
129
147
|
<Note>
|
|
130
|
-
Revoking or expiring an API key does not revoke tokens it already created. Those tokens remain valid until their own expiration.
|
|
148
|
+
Revoking or expiring an API key does not revoke tokens it already created. Those tokens remain valid until their own expiration, unless the environment's root key is regenerated.
|
|
131
149
|
</Note>
|
|
132
150
|
|
|
133
151
|
## Target Preview and Development branches
|
|
@@ -145,7 +163,7 @@ The SDK sends the branch automatically. When calling the API directly, send the
|
|
|
145
163
|
|
|
146
164
|
Self-hosted installations support multiple keys with **No restrictions**. The restricted access presets are available in Trigger.dev Cloud.
|
|
147
165
|
|
|
148
|
-
Keep your instance and SDK current before creating keys. Calling a public-token API with a key on a server that does not support server-minted tokens returns an upgrade error
|
|
166
|
+
Keep your instance and SDK current before creating keys. Calling a public-token API with a key on a server that does not support server-minted tokens returns an upgrade error; use the root key until the server is upgraded.
|
|
149
167
|
|
|
150
168
|
## Security recommendations
|
|
151
169
|
|
|
@@ -69,10 +69,14 @@ Now if you visit your Trigger.dev dashboard you should see the new version deplo
|
|
|
69
69
|
|
|
70
70
|
## Triggering deployed tasks
|
|
71
71
|
|
|
72
|
-
Once you have deployed your tasks,
|
|
72
|
+
Once you have deployed your tasks, you can trigger tasks exactly the same way you did locally, but with the "PROD" API key:
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
Copy the API key from the dashboard and set the `TRIGGER_SECRET_KEY` environment variable, and then any tasks you trigger will run against the deployed version:
|
|
73
77
|
|
|
74
78
|
```txt .env
|
|
75
|
-
TRIGGER_SECRET_KEY="
|
|
79
|
+
TRIGGER_SECRET_KEY="tr_prod_abc123"
|
|
76
80
|
```
|
|
77
81
|
|
|
78
82
|
Now you can trigger your tasks:
|
|
@@ -176,10 +180,10 @@ This will create an entirely new version of your tasks for the `staging` environ
|
|
|
176
180
|
|
|
177
181
|

|
|
178
182
|
|
|
179
|
-
|
|
183
|
+
Now you can trigger tasks against the staging environment by setting the `TRIGGER_SECRET_KEY` environment variable to the staging API key:
|
|
180
184
|
|
|
181
185
|
```txt .env
|
|
182
|
-
TRIGGER_SECRET_KEY="
|
|
186
|
+
TRIGGER_SECRET_KEY="tr_stg_abcd123"
|
|
183
187
|
```
|
|
184
188
|
|
|
185
189
|
For additional environments beyond `prod` and `staging`, you can use [preview branches](/deployment/preview-branches), which allow you to create isolated environments for each branch of your code.
|
|
@@ -15,7 +15,7 @@ The process to use preview branches looks like this:
|
|
|
15
15
|
|
|
16
16
|
1. Create a preview branch
|
|
17
17
|
2. Deploy to the preview branch (1+ times)
|
|
18
|
-
3.
|
|
18
|
+
3. Trigger runs using your Preview API key (`TRIGGER_SECRET_KEY`) and the branch name (`TRIGGER_PREVIEW_BRANCH`).
|
|
19
19
|
4. Archive the preview branch when the branch is done.
|
|
20
20
|
|
|
21
21
|
There are two main ways to do this:
|
|
@@ -41,12 +41,12 @@ For full details see our [pricing page](https://trigger.dev/pricing).
|
|
|
41
41
|
|
|
42
42
|
## Triggering runs and using the SDK
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Before we talk about how to deploy to preview branches, one important thing to understand is that you must set the `TRIGGER_PREVIEW_BRANCH` environment variable as well as the `TRIGGER_SECRET_KEY` environment variable.
|
|
45
45
|
|
|
46
46
|
When deploying to somewhere that supports `process.env` (like Node.js runtimes) you can just set the environment variables:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
TRIGGER_SECRET_KEY="
|
|
49
|
+
TRIGGER_SECRET_KEY="tr_preview_1234567890"
|
|
50
50
|
TRIGGER_PREVIEW_BRANCH="your-branch-name"
|
|
51
51
|
```
|
|
52
52
|
|
|
@@ -57,7 +57,7 @@ import { configure } from "@trigger.dev/sdk";
|
|
|
57
57
|
import { myTask } from "./trigger/myTasks";
|
|
58
58
|
|
|
59
59
|
configure({
|
|
60
|
-
secretKey: "
|
|
60
|
+
secretKey: "tr_preview_1234567890", // WARNING: Never actually hardcode your secret key like this
|
|
61
61
|
previewBranch: "your-branch-name",
|
|
62
62
|
});
|
|
63
63
|
|
|
@@ -276,68 +276,6 @@ An empty or whitespace-only value counts as "not supplied" rather than an error,
|
|
|
276
276
|
|
|
277
277
|
Batch triggers carry the id too. `batchTrigger` resolves it per item exactly as `trigger` does, and it survives the asynchronous materialisation of batch items — so a large batch triggered during a deploy waits and releases item by item, each pinned to the deployment its calling code came from.
|
|
278
278
|
|
|
279
|
-
## Chat sessions
|
|
280
|
-
|
|
281
|
-
[Chat agents](/ai-chat/overview) are covered by the same mechanism, with one difference: the id belongs to the **session**, not to a single trigger. It is resolved wherever you start the session — your server action, your route handler, `sessions.start()` — using the same order of precedence as a task trigger, and stored on the session. Every run that session goes on to schedule carries it: the first run, each continuation after an idle suspend, and each recovery after a crash.
|
|
282
|
-
|
|
283
|
-
That is what you want for a conversation. A chat started by one release of your app keeps talking to the agent build that release shipped with, however many turns and however many runs that takes.
|
|
284
|
-
|
|
285
|
-
Chats need the same two halves as tasks, and no more: a deployment carrying an id, and an app that sends the same one (explicitly, through `TRIGGER_EXTERNAL_DEPLOYMENT_ID`, or through [automatic discovery](#automatic-discovery)). There is nothing chat-specific to switch on, so an app already pinning its task runs gets pinned chats with no code change.
|
|
286
|
-
|
|
287
|
-
```ts
|
|
288
|
-
// app/actions.ts
|
|
289
|
-
"use server";
|
|
290
|
-
import { chat } from "@trigger.dev/sdk/ai";
|
|
291
|
-
import type { myChat } from "@/trigger/chat";
|
|
292
|
-
|
|
293
|
-
// No chat-specific setup: the id is discovered per call, exactly as it is for `trigger()`.
|
|
294
|
-
export const startChatSession = chat.createStartSessionAction<typeof myChat>("my-chat");
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
Three things follow from the pin living on the session:
|
|
298
|
-
|
|
299
|
-
- **Starting the session again refreshes it, and the conversation follows.** `sessions.start()` is idempotent on `chatId` and rewrites the stored config, so when your transport calls `startSession` after a redeploy, the session re-pins. A **running** agent then hands the conversation over at the next turn boundary, so the next message is answered by the deployment you just named — not several turns later when the old run happens to end. The turn already in flight finishes on the code it started on. Set [`versionSkew: "hold"`](/ai-chat/patterns/version-upgrades#staying-put) on an agent that should stay put instead.
|
|
300
|
-
- **There is one pin per `chatId`.** If the same conversation is open in two tabs on two different releases of your app, whichever called `startSession` most recently sets the pin for both.
|
|
301
|
-
- **A parked chat is waiting, not broken.** A run pinned to a deployment that hasn't landed parks, and every message sent meanwhile is stored durably and delivered once the deployment arrives. Nothing is lost — but nothing answers either, so tell the user. Re-pinning does not release a parked run: it keeps waiting for the deployment it was created for. If that deployment never lands, the run waits until its park deadline elapses, and the next message after that starts a fresh run on the session's current pin. Pass `pendingVersion` through your `startSession` callback and the transport emits a `run-pending-version` event:
|
|
302
|
-
|
|
303
|
-
```tsx
|
|
304
|
-
const transport = useTriggerChatTransport({
|
|
305
|
-
task: "my-chat",
|
|
306
|
-
accessToken: ({ chatId }) => mintChatAccessToken(chatId),
|
|
307
|
-
startSession: ({ chatId, clientData }) => startChatSession({ chatId, clientData }),
|
|
308
|
-
onEvent: (event) => {
|
|
309
|
-
if (event.type === "run-pending-version") setDeploying(true);
|
|
310
|
-
if (event.type === "first-chunk") setDeploying(false);
|
|
311
|
-
},
|
|
312
|
-
});
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
The event repeats on every message sent while the chat is parked, so a notice driven off it stays accurate. Its `source` says where the park was learned: `start` from creating the session, `send` from an append, `head-start` from the route's response header, and `upgrade` when a session followed its pin onto a deployment that hasn't landed yet — that last one arrives as soon as the handoff happens, without waiting for another message.
|
|
316
|
-
|
|
317
|
-
[Head Start](/ai-chat/fast-starts#head-start) softens this considerably: turn 1 runs in your own warm process, so a parked deployment costs nothing until step 2. The handover signal is durable, so the agent picks the turn up where it left off once the deployment lands. The transport emits `run-pending-version` with `source: "head-start"` for that case, and `chat.startHeadStart` returns `pendingVersion` for the detached flow.
|
|
318
|
-
|
|
319
|
-
### Opting a chat out
|
|
320
|
-
|
|
321
|
-
Pass `null` and that chat is never pinned, whatever the environment says:
|
|
322
|
-
|
|
323
|
-
```ts
|
|
324
|
-
export const startChatSession = chat.createStartSessionAction<typeof myChat>("my-chat", {
|
|
325
|
-
triggerConfig: { externalDeploymentId: null },
|
|
326
|
-
});
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
Use this for a conversation that should always run on the current version — a long-lived support thread, say — while the rest of your chats stay pinned. To turn pinning off everywhere instead, set `TRIGGER_AUTOMATIC_SKEW_VERSION_PROTECTION` to `0` and don't set `TRIGGER_EXTERNAL_DEPLOYMENT_ID`.
|
|
330
|
-
|
|
331
|
-
### Escaping the pin from inside the agent
|
|
332
|
-
|
|
333
|
-
[`chat.requestUpgrade()`](/ai-chat/patterns/version-upgrades) clears the session's external deployment id as part of the handoff, so the new run is free to land on the current version. Pass a target to move to a specific deployment instead:
|
|
334
|
-
|
|
335
|
-
```ts
|
|
336
|
-
chat.requestUpgrade({ externalDeploymentId: clientData.commitSha });
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
Either way the change is persisted on the session, so the next continuation doesn't fall back to the id the agent just rejected. `lockToVersion` is a separate, explicit pin and is never cleared — `requestUpgrade()` cannot escape it, which is also why a session using it never follows its external deployment id automatically.
|
|
340
|
-
|
|
341
279
|
## Waiting and expiry
|
|
342
280
|
|
|
343
281
|
When a run arrives with an id that isn't deployed yet, it doesn't fail — it **waits**. This is the ordinary case, not an edge case: your app frequently goes live a few seconds before your task build finishes.
|
package/docs/manual-setup.mdx
CHANGED
|
@@ -55,15 +55,15 @@ bun add -D @trigger.dev/build@latest
|
|
|
55
55
|
|
|
56
56
|
## Environment variables
|
|
57
57
|
|
|
58
|
-
For local development,
|
|
58
|
+
For local development, you need to set up the `TRIGGER_SECRET_KEY` environment variable. This key authenticates your application with Trigger.dev.
|
|
59
59
|
|
|
60
|
-
1.
|
|
61
|
-
2.
|
|
62
|
-
3.
|
|
63
|
-
4.
|
|
60
|
+
1. Go to your project dashboard in Trigger.dev
|
|
61
|
+
2. Navigate to the "API Keys" page
|
|
62
|
+
3. Copy the **DEV** secret key
|
|
63
|
+
4. Add it to your local environment file:
|
|
64
64
|
|
|
65
|
-
```bash
|
|
66
|
-
TRIGGER_SECRET_KEY=
|
|
65
|
+
```bash
|
|
66
|
+
TRIGGER_SECRET_KEY=tr_dev_xxxxxxxxxx
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
### Self-hosted instances
|
package/docs/mcp-tools.mdx
CHANGED
|
@@ -189,15 +189,6 @@ Execute a single widget query from a built-in dashboard. Use `list_dashboards` f
|
|
|
189
189
|
- `"Run the total runs widget from the overview dashboard"`
|
|
190
190
|
- `"Show me the LLM cost over time from the AI dashboard"`
|
|
191
191
|
|
|
192
|
-
### get_report
|
|
193
|
-
|
|
194
|
-
Render an interpreted [health report](/reports) — a deterministic verdict, not a raw panel — as text with sparklines. The `health` report answers whether work is flowing, whether the runs that start are healthy, and whether the telemetry is fresh, with a headline verdict and a suggested next action. Returns markdown by default, or ANSI when `color` is set. Read-only.
|
|
195
|
-
|
|
196
|
-
**Example usage:**
|
|
197
|
-
- `"Is my production project healthy?"`
|
|
198
|
-
- `"Run the health report for the last 24 hours"`
|
|
199
|
-
- `"Why are my runs backing up?"`
|
|
200
|
-
|
|
201
192
|
## Dev Server Tools
|
|
202
193
|
|
|
203
194
|
### start_dev_server
|
package/docs/quick-start.mdx
CHANGED
|
@@ -26,7 +26,7 @@ Help me add Trigger.dev to this project.
|
|
|
26
26
|
- Install the "Hello World" example task when prompted.
|
|
27
27
|
3. Run `npx trigger.dev@latest dev` to start the dev server.
|
|
28
28
|
4. Once the dev server is running, test the example task from the Trigger.dev dashboard.
|
|
29
|
-
5.
|
|
29
|
+
5. Set TRIGGER_SECRET_KEY in my .env file (or .env.local for Next.js). I can find it on the API Keys page in the dashboard.
|
|
30
30
|
6. Ask me what framework I'm using and show me how to trigger the task from my backend code.
|
|
31
31
|
|
|
32
32
|
If I've already run init and want the MCP server, run: npx trigger.dev@latest install-mcp
|
|
@@ -70,10 +70,10 @@ Sign up at [Trigger.dev Cloud](https://cloud.trigger.dev) (or [self-host](/self-
|
|
|
70
70
|
|
|
71
71
|
## Triggering tasks from your app
|
|
72
72
|
|
|
73
|
-
The test page in the dashboard
|
|
73
|
+
The test page in the dashboard is great for verifying your task works. To trigger tasks from your own code, you'll need to set the `TRIGGER_SECRET_KEY` environment variable. Grab it from the API Keys page in the dashboard and add it to your `.env` file.
|
|
74
74
|
|
|
75
75
|
```bash .env
|
|
76
|
-
TRIGGER_SECRET_KEY=
|
|
76
|
+
TRIGGER_SECRET_KEY=tr_dev_...
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
See [Triggering](/triggering) for the full guide, or jump straight to framework-specific setup for [Next.js](/guides/frameworks/nextjs), [Remix](/guides/frameworks/remix), or [Node.js](/guides/frameworks/nodejs).
|
package/docs/realtime/auth.mdx
CHANGED
|
@@ -131,7 +131,7 @@ const publicToken = await auth.createPublicToken({
|
|
|
131
131
|
- If `expirationTime` is a number, it will be treated as a Unix timestamp in **seconds**
|
|
132
132
|
- If `expirationTime` is a `Date`, it will be treated as a date
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
When using non-root API keys (recommended), the expiration cannot be more than 30 days in the future.
|
|
135
135
|
|
|
136
136
|
The format used for a time span is the same as the [jose package](https://github.com/panva/jose), which is a number followed by a unit. Valid units are: "sec", "secs", "second", "seconds", "s", "minute", "minutes", "min", "mins", "m", "hour", "hours", "hr", "hrs", "h", "day", "days", "d", "week", "weeks", "w", "year", "years", "yr", "yrs", and "y". It is not possible to specify months. 365.25 days is used as an alias for a year. If the string is suffixed with "ago", or prefixed with a "-", the resulting time span gets subtracted from the current unix timestamp. A "from now" suffix can also be used for readability when adding to the current unix timestamp.
|
|
137
137
|
|
|
@@ -6,11 +6,6 @@ sidebarTitle: "Security"
|
|
|
6
6
|
|
|
7
7
|
We take the security of Trigger.dev seriously, for both Cloud and self-hosted deployments. This page covers how to report a vulnerability, what to expect, and how to stay informed about security releases.
|
|
8
8
|
|
|
9
|
-
<Note>
|
|
10
|
-
Unlike Trigger.dev Cloud, the self-hosted setup is optimized for single-tenant use, with code and
|
|
11
|
-
users you trust. It is not designed to run untrusted code or untrusted payloads.
|
|
12
|
-
</Note>
|
|
13
|
-
|
|
14
9
|
<Warning>
|
|
15
10
|
Do not report security vulnerabilities through public GitHub issues, pull requests, or Discord. Use one of the private channels below.
|
|
16
11
|
</Warning>
|
package/docs/tasks/scheduled.mdx
CHANGED
|
@@ -184,30 +184,6 @@ const createdSchedule = await schedules.create({
|
|
|
184
184
|
is the assigned time the run will actually start.
|
|
185
185
|
</Note>
|
|
186
186
|
|
|
187
|
-
### Free-plan minimum window
|
|
188
|
-
|
|
189
|
-
Schedules created while an organization is on a free plan run no more than once per hour and use a minimum 60-minute window.
|
|
190
|
-
|
|
191
|
-
- The minimum applies to the **cron cadence**: creating or deploying a schedule whose cron fires more often than once an hour is rejected with an actionable error. Change the cron expression or upgrade before saving.
|
|
192
|
-
- Omitted, zero (`"0m"` / `"0%"`), or smaller windows are treated as the 60-minute minimum. A larger configured window still wins, subject to the usual cap at the next cron occurrence.
|
|
193
|
-
- The policy applies to **all environment types**, including Development.
|
|
194
|
-
- It is captured when the schedule is created. Existing schedules — and schedules created while paid, even after a later downgrade — are **grandfathered** and keep running unchanged.
|
|
195
|
-
- Upgrading does not immediately rewrite existing schedules. A free-created restriction is cleared the next time the schedule is saved (imperative/dashboard) or redeployed (declarative) while the organization is paying.
|
|
196
|
-
- No runs are ever skipped or coalesced: unsupported high-frequency schedules are rejected at create/update time rather than silently thinned out.
|
|
197
|
-
- Self-hosted deployments, and any case where the billing plan can't be determined, are unrestricted.
|
|
198
|
-
|
|
199
|
-
When a schedule is subject to this policy, the API returns an `appliedSchedulePolicy` object alongside the configured `window`:
|
|
200
|
-
|
|
201
|
-
```json
|
|
202
|
-
{
|
|
203
|
-
"window": "0m",
|
|
204
|
-
"appliedSchedulePolicy": {
|
|
205
|
-
"minimumWindowSeconds": 3600,
|
|
206
|
-
"reason": "free_schedule"
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
187
|
## Supported cron syntax
|
|
212
188
|
|
|
213
189
|
```
|
package/docs/triggering.mdx
CHANGED
|
@@ -27,7 +27,7 @@ Trigger tasks **from inside a another task**:
|
|
|
27
27
|
|
|
28
28
|
## Triggering from your backend
|
|
29
29
|
|
|
30
|
-
When you trigger a task from your backend code,
|
|
30
|
+
When you trigger a task from your backend code, you need to set the `TRIGGER_SECRET_KEY` environment variable. If you're [using a preview branch](/deployment/preview-branches), you also need to set the `TRIGGER_PREVIEW_BRANCH` environment variable. You can find the value on the API keys page in the Trigger.dev dashboard. [More info on API keys](/apikeys).
|
|
31
31
|
|
|
32
32
|
If a single process needs to trigger across multiple projects, environments, or preview branches, use [`new TriggerClient({...})`](/management/multiple-clients) for each target instead of relying on the global env vars.
|
|
33
33
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trigger.dev/sdk",
|
|
3
|
-
"version": "0.0.0-prerelease-
|
|
3
|
+
"version": "0.0.0-prerelease-streamfix-20260909094302",
|
|
4
4
|
"description": "trigger.dev Node.JS SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@opentelemetry/api": "1.9.1",
|
|
71
71
|
"@opentelemetry/semantic-conventions": "1.41.1",
|
|
72
|
-
"@trigger.dev/core": "0.0.0-prerelease-
|
|
72
|
+
"@trigger.dev/core": "0.0.0-prerelease-streamfix-20260909094302",
|
|
73
73
|
"uncrypto": "^0.1.3"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
@@ -82,13 +82,13 @@
|
|
|
82
82
|
"tshy": "^4.1.3",
|
|
83
83
|
"tsx": "4.17.0",
|
|
84
84
|
"typescript": "7.0.2",
|
|
85
|
-
"zod": "
|
|
85
|
+
"zod": "3.25.76"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"@ai-sdk/otel": ">=1.0.0-0 <2",
|
|
89
89
|
"ai": "^5.0.0 || ^6.0.0 || >=7.0.0-canary <8",
|
|
90
90
|
"react": "^18.0 || ^19.0",
|
|
91
|
-
"zod": "^3.
|
|
91
|
+
"zod": "^3.0.0 || ^4.0.0"
|
|
92
92
|
},
|
|
93
93
|
"peerDependenciesMeta": {
|
|
94
94
|
"@ai-sdk/otel": {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: trigger-authoring-chat-agent
|
|
3
3
|
description: >
|
|
4
4
|
Author and run a durable AI chat agent with chat.agent from @trigger.dev/sdk/ai: the per-turn
|
|
5
|
-
run loop, why you MUST
|
|
6
|
-
|
|
5
|
+
run loop, why you MUST spread ...chat.toStreamTextOptions() first, returning a StreamTextResult
|
|
6
|
+
vs calling chat.pipe(), the two server actions (chat.createStartSessionAction +
|
|
7
7
|
auth.createPublicToken), and wiring useChat to useTriggerChatTransport. Load this when building,
|
|
8
8
|
modifying, or debugging a chat backend (the agent task or its lifecycle hooks) or its React
|
|
9
9
|
transport, when declaring typed tools or custom data parts, or when migrating a plain AI SDK
|
|
@@ -47,9 +47,10 @@ import { anthropic } from "@ai-sdk/anthropic";
|
|
|
47
47
|
|
|
48
48
|
export const myChat = chat.agent({
|
|
49
49
|
id: "my-chat",
|
|
50
|
-
|
|
51
|
-
run: async ({ messages, signal, streamText }) =>
|
|
50
|
+
run: async ({ messages, signal }) =>
|
|
52
51
|
streamText({
|
|
52
|
+
// Spread this FIRST. See "Common mistakes".
|
|
53
|
+
...chat.toStreamTextOptions(),
|
|
53
54
|
model: anthropic("claude-sonnet-4-5"),
|
|
54
55
|
messages,
|
|
55
56
|
abortSignal: signal,
|
|
@@ -120,22 +121,16 @@ inside nested helpers, call `await chat.pipe(result)` from anywhere in the task
|
|
|
120
121
|
`run` resolve `void`.
|
|
121
122
|
|
|
122
123
|
```ts
|
|
123
|
-
import { chat, type ChatStreamText } from "@trigger.dev/sdk/ai";
|
|
124
|
-
import { anthropic } from "@ai-sdk/anthropic";
|
|
125
|
-
import type { ModelMessage } from "ai";
|
|
126
|
-
|
|
127
124
|
export const agentChat = chat.agent({
|
|
128
125
|
id: "agent-chat",
|
|
129
|
-
run: async ({ messages
|
|
130
|
-
await runAgentLoop(messages
|
|
126
|
+
run: async ({ messages }) => {
|
|
127
|
+
await runAgentLoop(messages); // don't return; pipe inside
|
|
131
128
|
},
|
|
132
129
|
});
|
|
133
130
|
|
|
134
|
-
|
|
135
|
-
// managed options. `ChatStreamText` (from `@trigger.dev/sdk/ai`) types the parameter.
|
|
136
|
-
// `chat.toStreamTextOptions()` is the alternative when threading it down is impractical.
|
|
137
|
-
async function runAgentLoop(messages: ModelMessage[], streamText: ChatStreamText) {
|
|
131
|
+
async function runAgentLoop(messages: ModelMessage[]) {
|
|
138
132
|
const result = streamText({
|
|
133
|
+
...chat.toStreamTextOptions(),
|
|
139
134
|
model: anthropic("claude-sonnet-4-5"),
|
|
140
135
|
messages,
|
|
141
136
|
});
|
|
@@ -143,10 +138,10 @@ async function runAgentLoop(messages: ModelMessage[], streamText: ChatStreamText
|
|
|
143
138
|
}
|
|
144
139
|
```
|
|
145
140
|
|
|
146
|
-
### 2. Typed tools (declare on config AND
|
|
141
|
+
### 2. Typed tools (declare on config AND spread back)
|
|
147
142
|
|
|
148
143
|
Declare tools on `chat.agent({ tools })`, read them back typed from the `run()` payload, and pass
|
|
149
|
-
that set
|
|
144
|
+
that set to `chat.toStreamTextOptions({ tools })`. One declaration flows everywhere.
|
|
150
145
|
|
|
151
146
|
```ts
|
|
152
147
|
import { tool, stepCountIs } from "ai";
|
|
@@ -163,11 +158,11 @@ const tools = {
|
|
|
163
158
|
export const myChat = chat.agent({
|
|
164
159
|
id: "my-chat",
|
|
165
160
|
tools, // so toModelOutput survives across turns
|
|
166
|
-
run: async ({ messages, tools, signal
|
|
161
|
+
run: async ({ messages, tools, signal }) =>
|
|
167
162
|
streamText({
|
|
163
|
+
...chat.toStreamTextOptions({ tools }), // same set, handed back typed
|
|
168
164
|
model: anthropic("claude-sonnet-4-5"),
|
|
169
165
|
messages,
|
|
170
|
-
tools, // same set, handed back typed
|
|
171
166
|
abortSignal: signal,
|
|
172
167
|
stopWhen: stepCountIs(15),
|
|
173
168
|
}),
|
|
@@ -208,8 +203,8 @@ export const myChat = chat
|
|
|
208
203
|
onTurnStart: async ({ uiMessages, writer }) => {
|
|
209
204
|
writer.write({ type: "data-turn-status", data: { status: "preparing" } });
|
|
210
205
|
},
|
|
211
|
-
run: async ({ messages, tools, signal
|
|
212
|
-
streamText({ model, messages,
|
|
206
|
+
run: async ({ messages, tools, signal }) =>
|
|
207
|
+
streamText({ ...chat.toStreamTextOptions({ tools }), model, messages, abortSignal: signal }),
|
|
213
208
|
});
|
|
214
209
|
```
|
|
215
210
|
|
|
@@ -233,13 +228,13 @@ first message. Suspend/resume use `onChatSuspend` / `onChatResume`. Config optio
|
|
|
233
228
|
`uiMessageStreamOptions`, and `exitAfterPreloadIdle`. There is no generic `retry`; `chat.agent`
|
|
234
229
|
runs with `maxAttempts: 1` internally.
|
|
235
230
|
|
|
236
|
-
Stop
|
|
231
|
+
Stop is load-bearing: the `signal` passed to `run` aborts on stop or cancel. Forward it as
|
|
237
232
|
`abortSignal` to `streamText`, or the Stop button updates the UI while the model keeps generating
|
|
238
233
|
server-side.
|
|
239
234
|
|
|
240
235
|
```ts
|
|
241
|
-
run: async ({ messages, signal
|
|
242
|
-
streamText({ model, messages, abortSignal: signal, stopWhen: stepCountIs(15) });
|
|
236
|
+
run: async ({ messages, signal }) =>
|
|
237
|
+
streamText({ ...chat.toStreamTextOptions(), model, messages, abortSignal: signal, stopWhen: stepCountIs(15) });
|
|
243
238
|
```
|
|
244
239
|
|
|
245
240
|
### 6. Migrating from a plain AI SDK `streamText` route
|
|
@@ -248,30 +243,24 @@ There is no API route in this model. The transport replaces the route round-trip
|
|
|
248
243
|
|
|
249
244
|
- Delete the route handler. Move per-request auth into the two server actions from Setup step 2.
|
|
250
245
|
- Move the `streamText` call into `run`. It already receives pre-converted `ModelMessage[]`.
|
|
251
|
-
- Return the `StreamTextResult` (it auto-pipes) and
|
|
246
|
+
- Return the `StreamTextResult` (it auto-pipes) and add `...chat.toStreamTextOptions()` first.
|
|
252
247
|
- On the client, swap the `api` URL for `useTriggerChatTransport`; `useChat` stays the same shape.
|
|
253
248
|
|
|
254
249
|
## Common mistakes
|
|
255
250
|
|
|
256
|
-
- **CRITICAL:
|
|
251
|
+
- **CRITICAL: forgetting `...chat.toStreamTextOptions()`.**
|
|
257
252
|
```ts
|
|
258
253
|
// Wrong - compaction / steering / background injection silently no-op
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
run: async ({ messages, signal, streamText }) => streamText({ model, messages, abortSignal: signal });
|
|
254
|
+
return streamText({ model, messages, abortSignal: signal });
|
|
255
|
+
// Correct - spread FIRST so explicit overrides win
|
|
256
|
+
return streamText({ ...chat.toStreamTextOptions(), model, messages, abortSignal: signal });
|
|
263
257
|
```
|
|
264
|
-
|
|
265
|
-
injection, the system prompt from `chat.prompt()
|
|
266
|
-
|
|
267
|
-
`...chat.toStreamTextOptions()` does the same job by hand, and is what a custom agent has to use,
|
|
268
|
-
since it has no `run` argument. A `chat.headStart` route gets a bound `streamText` too, and there it
|
|
269
|
-
also owns `messages`, `prompt`, `stopWhen` and `abortSignal`. Spreading it and then re-setting
|
|
270
|
-
`tools` or `prepareStep` replaces the managed ones; the run argument's `streamText` merges `tools`
|
|
271
|
-
and composes `prepareStep` instead.
|
|
258
|
+
It wires the `prepareStep` callback behind compaction, mid-turn steering, and background
|
|
259
|
+
injection, injects the system prompt from `chat.prompt()`, resolves the registry model, and adds
|
|
260
|
+
telemetry. Omitting it makes all of those silently no-op with no error.
|
|
272
261
|
|
|
273
262
|
- **Declaring tools only on `streamText`.** Also declare them on `chat.agent({ tools })`, read them
|
|
274
|
-
back from `run`, and pass
|
|
263
|
+
back from `run`, and pass `chat.toStreamTextOptions({ tools })`. Otherwise each tool's
|
|
275
264
|
`toModelOutput` runs on turn 1 but is dropped when history is re-converted on later turns.
|
|
276
265
|
|
|
277
266
|
- **Not forwarding `signal` for stop.** Without `abortSignal: signal`, Stop updates the UI but the
|