@trigger.dev/sdk 4.5.16 → 4.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/imports/ai-runtime-cjs.cjs.map +1 -1
- package/dist/commonjs/imports/ai-runtime.js +2 -0
- package/dist/commonjs/v3/ai-shared.d.ts +15 -0
- package/dist/commonjs/v3/ai-shared.js +35 -1
- package/dist/commonjs/v3/ai-shared.js.map +1 -1
- package/dist/commonjs/v3/ai.d.ts +311 -25
- package/dist/commonjs/v3/ai.js +1633 -380
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/auth.d.ts +10 -4
- package/dist/commonjs/v3/auth.js.map +1 -1
- package/dist/commonjs/v3/chat-client.d.ts +11 -2
- package/dist/commonjs/v3/chat-client.js +227 -111
- package/dist/commonjs/v3/chat-client.js.map +1 -1
- package/dist/commonjs/v3/chat-react.d.ts +88 -0
- package/dist/commonjs/v3/chat-react.js +130 -1
- package/dist/commonjs/v3/chat-react.js.map +1 -1
- package/dist/commonjs/v3/chat-server.d.ts +42 -6
- package/dist/commonjs/v3/chat-server.js +52 -7
- package/dist/commonjs/v3/chat-server.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +92 -10
- package/dist/commonjs/v3/chat.js +328 -73
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/chatSnapshotIo.d.ts +2 -0
- package/dist/commonjs/v3/chatSnapshotIo.js +173 -0
- package/dist/commonjs/v3/chatSnapshotIo.js.map +1 -0
- package/dist/commonjs/v3/chatVersionSkew.d.ts +12 -0
- package/dist/commonjs/v3/chatVersionSkew.js +30 -0
- package/dist/commonjs/v3/chatVersionSkew.js.map +1 -0
- package/dist/commonjs/v3/externalDeploymentId.d.ts +23 -0
- package/dist/commonjs/v3/externalDeploymentId.js +43 -0
- package/dist/commonjs/v3/externalDeploymentId.js.map +1 -0
- package/dist/commonjs/v3/retry.d.ts +4 -0
- package/dist/commonjs/v3/retry.js +22 -13
- package/dist/commonjs/v3/retry.js.map +1 -1
- package/dist/commonjs/v3/sessions.d.ts +15 -2
- package/dist/commonjs/v3/sessions.js +12 -1
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/shared.js +30 -36
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/test/index.d.ts +1 -0
- package/dist/commonjs/v3/test/index.js +3 -1
- package/dist/commonjs/v3/test/index.js.map +1 -1
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +47 -4
- package/dist/commonjs/v3/test/mock-chat-agent.js +116 -10
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/commonjs/v3/test/test-session-handle.js +6 -0
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
- package/dist/commonjs/v3/test/transcript-storage-tests.d.ts +40 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.js +258 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.js.map +1 -0
- package/dist/commonjs/v3/transcriptStorage.d.ts +261 -0
- package/dist/commonjs/v3/transcriptStorage.js +374 -0
- package/dist/commonjs/v3/transcriptStorage.js.map +1 -0
- 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-shared.d.ts +15 -0
- package/dist/esm/v3/ai-shared.js +33 -0
- package/dist/esm/v3/ai-shared.js.map +1 -1
- package/dist/esm/v3/ai.d.ts +311 -25
- package/dist/esm/v3/ai.js +1625 -377
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/auth.d.ts +10 -4
- package/dist/esm/v3/auth.js.map +1 -1
- package/dist/esm/v3/chat-client.d.ts +11 -2
- package/dist/esm/v3/chat-client.js +228 -112
- package/dist/esm/v3/chat-client.js.map +1 -1
- package/dist/esm/v3/chat-react.d.ts +88 -0
- package/dist/esm/v3/chat-react.js +127 -1
- package/dist/esm/v3/chat-react.js.map +1 -1
- package/dist/esm/v3/chat-server.d.ts +42 -6
- package/dist/esm/v3/chat-server.js +53 -8
- package/dist/esm/v3/chat-server.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +92 -10
- package/dist/esm/v3/chat.js +329 -74
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/chatSnapshotIo.d.ts +2 -0
- package/dist/esm/v3/chatSnapshotIo.js +165 -0
- package/dist/esm/v3/chatSnapshotIo.js.map +1 -0
- package/dist/esm/v3/chatVersionSkew.d.ts +12 -0
- package/dist/esm/v3/chatVersionSkew.js +27 -0
- package/dist/esm/v3/chatVersionSkew.js.map +1 -0
- package/dist/esm/v3/externalDeploymentId.d.ts +23 -0
- package/dist/esm/v3/externalDeploymentId.js +38 -0
- package/dist/esm/v3/externalDeploymentId.js.map +1 -0
- package/dist/esm/v3/retry.d.ts +4 -0
- package/dist/esm/v3/retry.js +14 -8
- package/dist/esm/v3/retry.js.map +1 -1
- package/dist/esm/v3/sessions.d.ts +15 -2
- package/dist/esm/v3/sessions.js +11 -1
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/shared.js +17 -23
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/test/index.d.ts +1 -0
- package/dist/esm/v3/test/index.js +1 -0
- package/dist/esm/v3/test/index.js.map +1 -1
- package/dist/esm/v3/test/mock-chat-agent.d.ts +47 -4
- package/dist/esm/v3/test/mock-chat-agent.js +118 -12
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/esm/v3/test/test-session-handle.js +6 -0
- package/dist/esm/v3/test/test-session-handle.js.map +1 -1
- package/dist/esm/v3/test/transcript-storage-tests.d.ts +40 -0
- package/dist/esm/v3/test/transcript-storage-tests.js +255 -0
- package/dist/esm/v3/test/transcript-storage-tests.js.map +1 -0
- package/dist/esm/v3/transcriptStorage.d.ts +261 -0
- package/dist/esm/v3/transcriptStorage.js +360 -0
- package/dist/esm/v3/transcriptStorage.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/actions.mdx +55 -23
- package/docs/ai-chat/anatomy.mdx +47 -27
- package/docs/ai-chat/backend.mdx +125 -48
- package/docs/ai-chat/background-injection.mdx +122 -19
- package/docs/ai-chat/client-protocol.mdx +5 -4
- package/docs/ai-chat/compaction.mdx +13 -7
- package/docs/ai-chat/custom-agents.mdx +23 -0
- package/docs/ai-chat/fast-starts.mdx +27 -20
- package/docs/ai-chat/frontend.mdx +19 -14
- package/docs/ai-chat/how-it-works.mdx +1 -1
- package/docs/ai-chat/lifecycle-hooks.mdx +6 -2
- package/docs/ai-chat/migrating-from-a-route-handler.mdx +16 -14
- package/docs/ai-chat/migrating-from-hydrate-messages.mdx +299 -0
- package/docs/ai-chat/patterns/database-persistence.mdx +24 -9
- package/docs/ai-chat/patterns/native-compaction.mdx +310 -0
- package/docs/ai-chat/patterns/persistence-and-replay.mdx +34 -23
- package/docs/ai-chat/patterns/skills.mdx +7 -10
- package/docs/ai-chat/patterns/version-upgrades.mdx +79 -6
- package/docs/ai-chat/pending-messages.mdx +3 -3
- package/docs/ai-chat/prompt-caching.mdx +23 -25
- package/docs/ai-chat/quick-start.mdx +11 -11
- package/docs/ai-chat/reference.mdx +69 -10
- package/docs/ai-chat/sessions.mdx +6 -1
- package/docs/ai-chat/side-channels.mdx +1 -1
- package/docs/ai-chat/testing.mdx +2 -1
- package/docs/ai-chat/tools.mdx +18 -13
- package/docs/ai-chat/transcript-storage.mdx +247 -0
- package/docs/ai-chat/upgrade-guide.mdx +2 -2
- package/docs/apikeys.mdx +27 -45
- package/docs/cli-env-commands.mdx +114 -0
- package/docs/cli-projects-commands.mdx +62 -0
- package/docs/cli-runs-commands.mdx +94 -0
- package/docs/config/extensions/syncEnvVars.mdx +6 -0
- package/docs/deploy-environment-variables.mdx +23 -2
- package/docs/deployment/overview.mdx +4 -8
- package/docs/deployment/preview-branches.mdx +4 -4
- package/docs/deployment/version-skew-protection.mdx +62 -0
- package/docs/introduction.mdx +58 -152
- package/docs/manual-setup.mdx +7 -7
- package/docs/mcp-tools.mdx +9 -0
- package/docs/quick-start.mdx +3 -3
- package/docs/realtime/auth.mdx +1 -1
- package/docs/reports.mdx +157 -0
- package/docs/self-hosting/security.mdx +17 -0
- package/docs/tasks/scheduled.mdx +24 -0
- package/docs/triggering.mdx +1 -1
- package/docs/troubleshooting-zod.mdx +158 -0
- package/package.json +4 -4
- package/skills/trigger-authoring-chat-agent/SKILL.md +41 -29
- package/skills/trigger-chat-agent-advanced/SKILL.md +54 -19
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Transcript storage"
|
|
3
|
+
sidebarTitle: "Transcript storage"
|
|
4
|
+
description: "Where a chat.agent conversation is kept: the UIMessages the runtime saves, the platform default, reading history back, and bringing your own database through the TranscriptStorage adapter."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Why a conversation needs a home
|
|
8
|
+
|
|
9
|
+
A `chat.agent` conversation outlives a single run. One run answers many turns and survives the idle gaps between them, but a run does end eventually (a version upgrade, its turn limit, a crash), and the next message then boots a fresh run with nothing in memory (see [How it works](/ai-chat/how-it-works)). For that new run to answer in context, the conversation so far has to be read back from somewhere durable. The same store is what a page reload and the dashboard read to show history.
|
|
10
|
+
|
|
11
|
+
That somewhere is a **transcript storage**. You get one by default with no setup: the platform keeps the conversation as a snapshot in object storage, the same blob the Sessions view in the dashboard renders. Bring your own when you want the conversation in your own database instead.
|
|
12
|
+
|
|
13
|
+
## What gets saved
|
|
14
|
+
|
|
15
|
+
The transcript is a list of **`UIMessage`s**, keyed by `chatId`. A `UIMessage` is the rich, renderable message the frontend works with: an `id`, a `role`, and an array of `parts` (text, reasoning, tool calls and their results, and any custom `data-*` parts). It is the same shape your React app holds and the same shape the dashboard renders, so what you store is exactly what a user sees.
|
|
16
|
+
|
|
17
|
+
<Note>
|
|
18
|
+
`UIMessage`s are not what the model reads. Each turn the runtime derives a `ModelMessage[]` from the transcript, the flattened `{ role, content }` form an LLM takes, and hands it to your `run()` as `messages`. The transcript storage never deals in `ModelMessage`s. It holds the UI messages; the model's view is derived from them.
|
|
19
|
+
</Note>
|
|
20
|
+
|
|
21
|
+
Keeping the UI shape is deliberate. It is lossless (a tool call and its result survive as parts), it is what renders, and the model's view can be rebuilt from it. Two things cannot be rebuilt from the messages alone, so the runtime hands them to the storage as well:
|
|
22
|
+
|
|
23
|
+
- **`state`**: an opaque record for what the model saw that the transcript does not capture, a [compaction](/ai-chat/compaction) summary and [injected context](/ai-chat/background-injection). Store it as-is and give it back on load.
|
|
24
|
+
- **cursors**: the stream positions the next run resumes from. Persist them opaquely; a storage never reads them.
|
|
25
|
+
|
|
26
|
+
So a save is: the messages, a `state` blob, and two cursors. Nothing else.
|
|
27
|
+
|
|
28
|
+
## The default storage
|
|
29
|
+
|
|
30
|
+
Do nothing and you get the platform snapshot: the whole conversation written to object storage after each change, read back when a run continues. It is the blob the dashboard's Sessions view renders, and it needs no configuration.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
34
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
35
|
+
|
|
36
|
+
export const myChat = chat.agent({
|
|
37
|
+
id: "my-chat",
|
|
38
|
+
run: async ({ messages, signal, streamText }) =>
|
|
39
|
+
streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal }),
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The default rewrites the whole conversation on every turn. That is fine for most chats and costs one write. When it stops being fine, or when you want the conversation in a database you already run, you bring your own.
|
|
44
|
+
|
|
45
|
+
## Bring your own storage
|
|
46
|
+
|
|
47
|
+
Set `storage` on the agent to persist the conversation yourself:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
51
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
52
|
+
import { myTranscriptStorage } from "./transcript-storage";
|
|
53
|
+
|
|
54
|
+
export const myChat = chat.agent({
|
|
55
|
+
id: "my-chat",
|
|
56
|
+
storage: myTranscriptStorage,
|
|
57
|
+
run: async ({ messages, signal, streamText }) =>
|
|
58
|
+
streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal }),
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Reasons to:
|
|
63
|
+
|
|
64
|
+
- **Your database is the source of truth.** History lives next to the rest of your data, queryable, backed up, and deletable on your terms.
|
|
65
|
+
- **Cheaper writes on long chats.** A row-per-message store writes only what changed on a turn instead of rewriting the whole conversation.
|
|
66
|
+
- **Render history in one query** from your own tables, the same `load` the runtime uses.
|
|
67
|
+
- **Own the model's context** for branching, trust boundaries, or rollback (see [Owning the model's context](#owning-the-models-context)).
|
|
68
|
+
|
|
69
|
+
The runtime drives the storage. You never decide when to write, what a regenerate means for your rows, or how a crash mid-answer is recovered. Those decisions are the same for every backend, so they live in the runtime; your job is to store what it hands you and give it back.
|
|
70
|
+
|
|
71
|
+
## The interface
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
type TranscriptStorage<TClientData = unknown> = {
|
|
75
|
+
load(
|
|
76
|
+
scope: { chatId: string; clientData: TClientData },
|
|
77
|
+
opts?: { limit?: number; before?: string }
|
|
78
|
+
): Promise<{
|
|
79
|
+
messages: UIMessage[];
|
|
80
|
+
state: unknown | null;
|
|
81
|
+
cursors?: { lastOutEventId?: string; lastInEventId?: string };
|
|
82
|
+
nextCursor?: string;
|
|
83
|
+
}>;
|
|
84
|
+
|
|
85
|
+
save(
|
|
86
|
+
ctx: {
|
|
87
|
+
chatId: string;
|
|
88
|
+
clientData: TClientData;
|
|
89
|
+
turn: number;
|
|
90
|
+
trigger: "submit-message" | "regenerate-message" | "action";
|
|
91
|
+
runId: string;
|
|
92
|
+
ctx: TaskRunContext;
|
|
93
|
+
},
|
|
94
|
+
changeset: {
|
|
95
|
+
reason: "turn-start" | "turn-complete" | "turn-error" | "action" | "compaction" | "recovery";
|
|
96
|
+
changes: TranscriptChange[];
|
|
97
|
+
transcript: { entries: Array<{ id: string; final: boolean; message: UIMessage }>; state: unknown | null };
|
|
98
|
+
cursors?: { lastOutEventId?: string; lastInEventId?: string };
|
|
99
|
+
}
|
|
100
|
+
): Promise<void>;
|
|
101
|
+
|
|
102
|
+
loadContext?(
|
|
103
|
+
scope: { chatId: string; clientData: TClientData },
|
|
104
|
+
event: LoadContextEvent
|
|
105
|
+
): Promise<UIMessage[]>;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
type TranscriptChange =
|
|
109
|
+
| { op: "put"; message: UIMessage; final?: boolean }
|
|
110
|
+
| { op: "remove"; id: string }
|
|
111
|
+
| { op: "truncateAfter"; afterId: string }
|
|
112
|
+
| { op: "state"; value: unknown | null };
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`load` returns the conversation. `save` records a change to it. `loadContext` is optional and covered [below](#owning-the-models-context). All the types are exported from `@trigger.dev/sdk/ai`.
|
|
116
|
+
|
|
117
|
+
`scope` is the tenant of a read: the `chatId` and the `clientData` your app passed. `ctx` on a save is the same plus the run it happened in. `clientData` is how the runtime hands you the tenant; use it to scope or authorize where your backend needs to.
|
|
118
|
+
|
|
119
|
+
## What the runtime hands `save`
|
|
120
|
+
|
|
121
|
+
A changeset carries the same save two ways, and a storage uses whichever suits its shape.
|
|
122
|
+
|
|
123
|
+
`changes` is the ordered list of what changed since the last save. A row-per-message store applies them, as one transaction where the backend supports one:
|
|
124
|
+
|
|
125
|
+
| Change | Meaning |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| `put` | Upsert by `message.id`. An unknown id appends at the end; a known id is replaced in place. `final` is `false` for a partial answer captured from a turn that failed or was stopped, and `true` otherwise. |
|
|
128
|
+
| `remove` | Delete by id. A no-op for an unknown id. |
|
|
129
|
+
| `truncateAfter` | Drop every message ordered after `afterId`. This is what an undo or a regenerate becomes. A no-op for an unknown id. |
|
|
130
|
+
| `state` | Replace the runtime's opaque record; `null` clears it. |
|
|
131
|
+
|
|
132
|
+
`transcript` is the whole conversation as it stands after those changes, `entries` plus `state`. A store that keeps the conversation as one document (object storage, a key-value store, a JSON column) writes it as-is and keeps no state of its own between saves. The default storage is exactly that: it serialises `transcript` and rewrites the blob.
|
|
133
|
+
|
|
134
|
+
The changes are the intent, spelled out. A normal turn is two `put`s, the user's message and the assistant's answer, split across the turn's two saves. A steering message the user sent mid-turn is another `put` in the same changeset. An undo through `chat.history.slice(0, -2)` is one `truncateAfter`. A regenerate is a `truncateAfter` and a `put`. A tool approval that updates the assistant message in place is one `put` for that id. Messages are addressed by id; how you order rows is your concern.
|
|
135
|
+
|
|
136
|
+
Every turn saves twice. The `turn-start` save carries the message being answered, before the model runs. The `turn-complete` save carries the answer. Both `put` the same user message id, and a `put` upserts, so a storage that applies changes in order needs no special handling for the repeat.
|
|
137
|
+
|
|
138
|
+
The `turn-start` save is what makes a reload during an answer show the question that is being answered. It leaves `cursors` on the previous turn's position, because the answer's own cursor does not exist yet, so a reload mid-answer still resumes from the last completed turn rather than skipping chunks it never received.
|
|
139
|
+
|
|
140
|
+
A few properties worth knowing:
|
|
141
|
+
|
|
142
|
+
- The `turn-start` save runs alongside the model rather than before it, so it costs no time to first token. Nothing from the turn reaches the browser until it settles, which is what makes the question durable before the answer can render. A save that fails or runs long lets the answer through rather than stalling the conversation.
|
|
143
|
+
- The `turn-complete` save happens after the turn's answer has reached the browser, so it never delays the response. The runtime awaits each `save` before the run suspends.
|
|
144
|
+
- A `save` that throws is logged and the turn continues. The changes fold into the next changeset, and every change is idempotent, so a retried changeset converges on the same result.
|
|
145
|
+
- A `load` that throws boots the run from the durable stream's recent tail rather than failing.
|
|
146
|
+
|
|
147
|
+
## Reading the transcript
|
|
148
|
+
|
|
149
|
+
`load` is the one read for every backend, the default included. Call it on your server, scoped to the signed-in user through `clientData`, and pass the result to the browser:
|
|
150
|
+
|
|
151
|
+
```ts app/actions.ts
|
|
152
|
+
"use server";
|
|
153
|
+
import { chat, defaultStorage } from "@trigger.dev/sdk/ai";
|
|
154
|
+
|
|
155
|
+
export const loadTranscript = chat.createLoadTranscriptAction(defaultStorage, { limit: 50 });
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```tsx app/chat/[chatId]/ChatPage.tsx
|
|
159
|
+
"use client";
|
|
160
|
+
import { useLoadTranscript, useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
|
|
161
|
+
import { loadTranscript } from "@/app/actions";
|
|
162
|
+
|
|
163
|
+
export function ChatPage({ chatId }: { chatId: string }) {
|
|
164
|
+
const transport = useTriggerChatTransport({ task: "my-chat", accessToken, startSession });
|
|
165
|
+
const { messages, isLoading, nextCursor } = useLoadTranscript(chatId, loadTranscript, {
|
|
166
|
+
transport,
|
|
167
|
+
});
|
|
168
|
+
if (isLoading) return <Spinner />;
|
|
169
|
+
return <ChatView chatId={chatId} initialMessages={messages} transport={transport} />;
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
<Warning>
|
|
174
|
+
The action receives `chatId` from the browser, so authorize it before returning: check that the signed-in user owns this chat. `defaultStorage` loads purely by `chatId` and does no tenant check of its own, so an exported action with no authorization lets any authenticated user read any chat's transcript. A custom storage can enforce tenancy inside `load` using `clientData`, but the server action is still the place to reject a `chatId` the caller may not read.
|
|
175
|
+
</Warning>
|
|
176
|
+
|
|
177
|
+
`limit` returns the most recent messages and a `nextCursor`; pass it as `before` for the page before that one. With the default storage, a paged read is served by the platform, so a long conversation is not downloaded in full to render its last fifty messages. A paged read returns the transcript only: `state` is always `null`, because the model lane is not part of what a page renders, and the platform reads just the bytes holding that page rather than the whole conversation. The runtime reads the state separately when it restores context at boot. When you pass `transport` and it already knows the session, the hook seeds its resume cursor from the transcript, so the live subscription opens just past the persisted history instead of replaying it.
|
|
178
|
+
|
|
179
|
+
Swap `defaultStorage` for your own storage and nothing else about the read changes.
|
|
180
|
+
|
|
181
|
+
<Warning>
|
|
182
|
+
The saved format changed in this release, and an older SDK cannot read it. Rolling a deployment back to a version from before this release means its runs will not find a readable transcript for conversations already saved by the newer one, and will continue from the live stream tail instead, so earlier history is lost for those conversations. Roll forward rather than back, or keep your own transcript storage.
|
|
183
|
+
</Warning>
|
|
184
|
+
|
|
185
|
+
The default storage is deliberately basic about long conversations. Once compaction has run, it keeps roughly the last hundred messages and drops the rest, so what it rewrites on each save stops growing. A conversation that never compacts is kept whole. If your app renders history further back than that, give the agent your own storage and keep the messages yourself.
|
|
186
|
+
|
|
187
|
+
## Owning the model's context
|
|
188
|
+
|
|
189
|
+
By default the model's context each turn is the transcript the runtime accumulated, converted to `ModelMessage`s. A storage that declares `loadContext` takes that over: the runtime calls it on every turn and action, with the messages the frontend sent and the transcript the runtime had, and uses the `UIMessage`s it returns as the conversation (converting them to `ModelMessage`s the same way). Reach for it when your database decides what the model sees, for branching conversations, a trust boundary where the browser's history is not to be believed, or a curated context window.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
const storage: TranscriptStorage<{ userId: string }> = {
|
|
193
|
+
load: (scope, opts) => rows.load(scope, opts),
|
|
194
|
+
save: (ctx, changeset) => rows.save(ctx, changeset),
|
|
195
|
+
loadContext: async ({ chatId, clientData }, { incomingMessages }) => {
|
|
196
|
+
const branch = await rows.activeBranch(chatId, clientData.userId);
|
|
197
|
+
return [...branch, ...incomingMessages];
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`save` keeps receiving every change, and crash recovery keeps running. This is the replacement for the deprecated [`hydrateMessages`](/ai-chat/lifecycle-hooks#hydratemessages) hook; setting both `hydrateMessages` and `storage` on an agent is a startup error.
|
|
203
|
+
|
|
204
|
+
## Writing your own storage
|
|
205
|
+
|
|
206
|
+
The contract is small and the conformance suite checks it. Point the suite at a factory for your storage and run it under vitest or jest:
|
|
207
|
+
|
|
208
|
+
```ts transcript-storage.test.ts
|
|
209
|
+
import { runTranscriptStorageTests } from "@trigger.dev/sdk/ai/test";
|
|
210
|
+
import { postgresTranscriptStorage } from "./transcript-storage";
|
|
211
|
+
|
|
212
|
+
runTranscriptStorageTests(() => postgresTranscriptStorage(process.env.TEST_DATABASE_URL!));
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The suite covers appends and in-place replacement, idempotent `remove` and `truncateAfter`, `state` round-trips, cursors, replaying the same changeset twice, paging, and chat isolation. `memoryTranscriptStorage()` is the reference implementation, and it is handy in your own tests to see exactly what the runtime hands a storage.
|
|
216
|
+
|
|
217
|
+
A few things to get right:
|
|
218
|
+
|
|
219
|
+
- Pick one view and stay with it. Apply `changes` if you store rows, write `transcript` if you store a document; don't mix them within one save.
|
|
220
|
+
- `put` for a known id replaces the message in place; position and ordering don't change.
|
|
221
|
+
- Order is the message's position in the transcript. A document store gets it from `transcript.entries`. A row store needs an order column set once, when a `put` first inserts an id, following the order the `put`s arrive in, and left unchanged when a later `put` replaces that id in place. Don't sort by a write timestamp: a replaced message has to keep its place, and a steering message sent mid-turn sorts before the answer it shaped even though its row is written later.
|
|
222
|
+
- `truncateAfter` and `remove` are idempotent. Applying a changeset twice gives the same result as applying it once.
|
|
223
|
+
- `load` with no options returns the whole conversation in order. With `limit`, return the most recent messages and a `nextCursor` (the id of the oldest returned message) when earlier messages exist.
|
|
224
|
+
- Scope reads and writes by `clientData` where your backend enforces tenancy.
|
|
225
|
+
|
|
226
|
+
## Guarantees and limits
|
|
227
|
+
|
|
228
|
+
- Crash recovery of a half-written answer is runtime-owned in every configuration. It comes from the durable session stream, which no application database can reconstruct. A storage holds settled turns; the runtime overlays the recovered tail and hands it to `save` like any other change.
|
|
229
|
+
- Bringing your own database does not remove platform custody. Session streams still hold message content for their retention window.
|
|
230
|
+
- The default storage rewrites the whole conversation each turn. A row-per-message storage writes only what changed. That is the reason to plug in your own.
|
|
231
|
+
|
|
232
|
+
## Migrating from hydrateMessages
|
|
233
|
+
|
|
234
|
+
`hydrateMessages` keeps working with a one-time deprecation warning. Crash recovery runs for it, but the runtime does not write to your store on its behalf. The move, in short:
|
|
235
|
+
|
|
236
|
+
1. Implement `TranscriptStorage` over your existing tables. The writes you did in hooks become `save`; the read your hook did becomes `load`. Add `loadContext` only if your database decides what the model sees each turn.
|
|
237
|
+
2. Set `storage` on the agent and remove `hydrateMessages`. Setting both is an error.
|
|
238
|
+
3. Delete the recovery, compaction and cursor code the runtime now owns, and run `runTranscriptStorageTests` against your implementation.
|
|
239
|
+
|
|
240
|
+
The [migration guide](/ai-chat/migrating-from-hydrate-messages) walks through each step with code, and lists what to delete from each hook.
|
|
241
|
+
|
|
242
|
+
## See also
|
|
243
|
+
|
|
244
|
+
- [Persistence and replay](/ai-chat/patterns/persistence-and-replay): how the runtime rebuilds a conversation when a new run boots
|
|
245
|
+
- [Database persistence](/ai-chat/patterns/database-persistence): the hook-based pattern and how it relates
|
|
246
|
+
- [Actions](/ai-chat/actions#actions-and-persistence): what an undo or regenerate becomes in the changeset
|
|
247
|
+
- [Compaction](/ai-chat/compaction): the summary the runtime keeps in `state`
|
|
@@ -298,8 +298,8 @@ and direct API consumers.
|
|
|
298
298
|
fire at the same lifecycle points.
|
|
299
299
|
- `onAction` is still defined the same way, but its semantics changed
|
|
300
300
|
in the [May 6 prerelease](/ai-chat/changelog) — actions are no longer
|
|
301
|
-
turns
|
|
302
|
-
|
|
301
|
+
turns. To answer after an action's edit, return `chat.turn()`; returning
|
|
302
|
+
a `StreamTextResult` is no longer supported.
|
|
303
303
|
- `chat.customAgent({...})` and the `chat.createSession(payload, ...)`
|
|
304
304
|
helper for building a session loop manually inside a custom agent.
|
|
305
305
|
- `chat.defer` (deferred work) and `chat.history` (imperative history
|
package/docs/apikeys.mdx
CHANGED
|
@@ -10,17 +10,35 @@ 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
|
+
## Create an API key
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Create a separate named key for each service or integration that accesses Trigger.dev.
|
|
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. Every team member has their own Development environment, so create local-development keys in your own environment.
|
|
18
18
|
|
|
19
19
|
<Note>
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
Creating and revoking keys requires permission to manage API keys for the selected environment.
|
|
21
|
+
The dashboard disables these actions when your role does not have permission.
|
|
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
|
+
|
|
24
42
|
## Configure the SDK
|
|
25
43
|
|
|
26
44
|
Set `TRIGGER_SECRET_KEY` in your backend environment. The SDK reads it automatically for operations such as triggering tasks and retrieving runs.
|
|
@@ -49,38 +67,12 @@ await tasks.trigger<typeof sendEmail>("send-email", {
|
|
|
49
67
|
If you self-host Trigger.dev, set `TRIGGER_API_URL` or pass `baseURL` to `configure`:
|
|
50
68
|
|
|
51
69
|
```bash .env
|
|
52
|
-
TRIGGER_SECRET_KEY="
|
|
70
|
+
TRIGGER_SECRET_KEY="tr_prod_sk_…"
|
|
53
71
|
TRIGGER_API_URL="https://trigger.example.com"
|
|
54
72
|
```
|
|
55
73
|
|
|
56
74
|
The default API URL is `https://api.trigger.dev`.
|
|
57
75
|
|
|
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
|
-
|
|
84
76
|
## Access presets
|
|
85
77
|
|
|
86
78
|
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).
|
|
@@ -124,28 +116,18 @@ Revoking a key takes effect immediately and cannot be reversed. Requests using t
|
|
|
124
116
|
|
|
125
117
|
Removing a team member does not revoke keys they created. Review and revoke their keys separately when their access changes.
|
|
126
118
|
|
|
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
|
-
|
|
137
119
|
## Create public access tokens
|
|
138
120
|
|
|
139
121
|
API keys can be used to create scoped [Public Access Tokens](/realtime/auth) using `auth.createPublicToken()`.
|
|
140
122
|
|
|
141
|
-
|
|
123
|
+
Use `@trigger.dev/sdk` version 4.5.8 or later to create public tokens with environment API keys. Public tokens have the following restrictions:
|
|
142
124
|
|
|
143
125
|
- The token must request at least one scope.
|
|
144
126
|
- Its scopes cannot exceed the key's access.
|
|
145
127
|
- Its expiration cannot exceed 30 days.
|
|
146
128
|
|
|
147
129
|
<Note>
|
|
148
|
-
Revoking or expiring an API key does not revoke tokens it already created. Those tokens remain valid until their own expiration
|
|
130
|
+
Revoking or expiring an API key does not revoke tokens it already created. Those tokens remain valid until their own expiration.
|
|
149
131
|
</Note>
|
|
150
132
|
|
|
151
133
|
## Target Preview and Development branches
|
|
@@ -163,7 +145,7 @@ The SDK sends the branch automatically. When calling the API directly, send the
|
|
|
163
145
|
|
|
164
146
|
Self-hosted installations support multiple keys with **No restrictions**. The restricted access presets are available in Trigger.dev Cloud.
|
|
165
147
|
|
|
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
|
|
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. Upgrade the instance before creating public tokens with an environment API key.
|
|
167
149
|
|
|
168
150
|
## Security recommendations
|
|
169
151
|
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "CLI env commands"
|
|
3
|
+
sidebarTitle: "env"
|
|
4
|
+
description: "List, get, set, and pull environment variables for a Trigger.dev project."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import CommonOptions from "/snippets/cli-options-common.mdx";
|
|
8
|
+
import ConfigFileOptions from "/snippets/cli-options-config-file.mdx";
|
|
9
|
+
import ProjectRefOptions from "/snippets/cli-options-project-ref.mdx";
|
|
10
|
+
import BranchOptions from "/snippets/cli-options-branch.mdx";
|
|
11
|
+
|
|
12
|
+
These commands manage environment variables on a project environment. They default to `prod`. Use `--env staging` or `--env preview` (with `--branch`) for the other environments. There is no `dev` target: local `trigger dev` reads your local `.env`.
|
|
13
|
+
|
|
14
|
+
<CodeGroup>
|
|
15
|
+
|
|
16
|
+
```bash npm
|
|
17
|
+
npx trigger.dev@latest env list
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```bash pnpm
|
|
21
|
+
pnpm dlx trigger.dev@latest env list
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```bash yarn
|
|
25
|
+
yarn dlx trigger.dev@latest env list
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
</CodeGroup>
|
|
29
|
+
|
|
30
|
+
## env list
|
|
31
|
+
|
|
32
|
+
Lists user-set environment variables. `TRIGGER_` system variables are omitted. Values are hidden unless you pass `--show-values`.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx trigger.dev@latest env list
|
|
36
|
+
npx trigger.dev@latest env list --show-values
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
<ParamField body="Show values" type="--show-values">
|
|
40
|
+
Print the actual values, including secrets.
|
|
41
|
+
</ParamField>
|
|
42
|
+
|
|
43
|
+
## env get
|
|
44
|
+
|
|
45
|
+
Prints one variable. `--raw` prints only the value, with no banner or extra text, so you can capture it in a script.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx trigger.dev@latest env get MY_VAR
|
|
49
|
+
npx trigger.dev@latest env get MY_VAR --raw
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
<ParamField body="Name" type="<name>">
|
|
53
|
+
The name of the environment variable.
|
|
54
|
+
</ParamField>
|
|
55
|
+
|
|
56
|
+
<ParamField body="Raw" type="--raw">
|
|
57
|
+
Print only the value.
|
|
58
|
+
</ParamField>
|
|
59
|
+
|
|
60
|
+
## env set
|
|
61
|
+
|
|
62
|
+
Creates the variable if it does not exist, and overwrites the value if it does. Empty or whitespace-only values are rejected.
|
|
63
|
+
|
|
64
|
+
Updating an existing secret without `--secret` changes the value and leaves it secret. Pass `--secret` when you first create a secret, or when you want a non-secret variable to become one.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx trigger.dev@latest env set MY_VAR my-value
|
|
68
|
+
npx trigger.dev@latest env set STRIPE_KEY sk_live_abc --secret
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
<ParamField body="Name" type="<name>">
|
|
72
|
+
The name of the environment variable.
|
|
73
|
+
</ParamField>
|
|
74
|
+
|
|
75
|
+
<ParamField body="Value" type="<value>">
|
|
76
|
+
The value to set. Cannot be empty.
|
|
77
|
+
</ParamField>
|
|
78
|
+
|
|
79
|
+
<ParamField body="Secret" type="--secret">
|
|
80
|
+
Store the value as a secret, so it cannot be read back.
|
|
81
|
+
</ParamField>
|
|
82
|
+
|
|
83
|
+
## env pull
|
|
84
|
+
|
|
85
|
+
Writes the project's environment variables to a local file. Defaults to `.env.local`. Fails if the file already exists unless you pass `--force`.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx trigger.dev@latest env pull
|
|
89
|
+
npx trigger.dev@latest env pull --output .env.trigger --force
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
<ParamField body="Output" type="-o, --output <file>">
|
|
93
|
+
The file to write. Defaults to `.env.local`.
|
|
94
|
+
</ParamField>
|
|
95
|
+
|
|
96
|
+
<ParamField body="Force" type="--force">
|
|
97
|
+
Overwrite the output file if it exists.
|
|
98
|
+
</ParamField>
|
|
99
|
+
|
|
100
|
+
## Options
|
|
101
|
+
|
|
102
|
+
<ParamField body="Environment" type="--env | -e">
|
|
103
|
+
The environment to use: `prod`, `staging` or `preview`. Defaults to `prod`.
|
|
104
|
+
</ParamField>
|
|
105
|
+
|
|
106
|
+
<ConfigFileOptions />
|
|
107
|
+
<ProjectRefOptions />
|
|
108
|
+
<BranchOptions />
|
|
109
|
+
|
|
110
|
+
### Common options
|
|
111
|
+
|
|
112
|
+
These options are available on most commands.
|
|
113
|
+
|
|
114
|
+
<CommonOptions />
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "CLI projects commands"
|
|
3
|
+
sidebarTitle: "projects"
|
|
4
|
+
description: "Create, inspect, and rename Trigger.dev projects from the terminal."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import CommonOptions from "/snippets/cli-options-common.mdx";
|
|
8
|
+
|
|
9
|
+
These commands act on the organizations and projects your account can access, so run
|
|
10
|
+
[`login`](/cli-login-commands) first.
|
|
11
|
+
|
|
12
|
+
## projects create
|
|
13
|
+
|
|
14
|
+
Creates a project. You are prompted for the organization and name when the options are omitted.
|
|
15
|
+
|
|
16
|
+
<CodeGroup>
|
|
17
|
+
|
|
18
|
+
```bash npm
|
|
19
|
+
npx trigger.dev@latest projects create
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash pnpm
|
|
23
|
+
pnpm dlx trigger.dev@latest projects create
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```bash yarn
|
|
27
|
+
yarn dlx trigger.dev@latest projects create
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
</CodeGroup>
|
|
31
|
+
|
|
32
|
+
<ParamField body="Organization" type="--org | -o">
|
|
33
|
+
The organization slug or ID to create the project in.
|
|
34
|
+
</ParamField>
|
|
35
|
+
|
|
36
|
+
<ParamField body="Name" type="--name | -n">
|
|
37
|
+
The name of the new project.
|
|
38
|
+
</ParamField>
|
|
39
|
+
|
|
40
|
+
## projects get
|
|
41
|
+
|
|
42
|
+
Prints the name, ref, slug, organization, default runtime and region of a project.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx trigger.dev@latest projects get proj_abc123
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## projects rename
|
|
49
|
+
|
|
50
|
+
Renames a project. The project ref does not change.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx trigger.dev@latest projects rename proj_abc123 "My new name"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Options
|
|
57
|
+
|
|
58
|
+
### Common options
|
|
59
|
+
|
|
60
|
+
These options are available on most commands.
|
|
61
|
+
|
|
62
|
+
<CommonOptions />
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "CLI runs commands"
|
|
3
|
+
sidebarTitle: "runs"
|
|
4
|
+
description: "Use these commands to list, inspect, replay and cancel runs from your terminal."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import CommonOptions from "/snippets/cli-options-common.mdx";
|
|
8
|
+
import ConfigFileOptions from "/snippets/cli-options-config-file.mdx";
|
|
9
|
+
import ProjectRefOptions from "/snippets/cli-options-project-ref.mdx";
|
|
10
|
+
import BranchOptions from "/snippets/cli-options-branch.mdx";
|
|
11
|
+
|
|
12
|
+
## runs list
|
|
13
|
+
|
|
14
|
+
Lists runs, newest first, in a table of ID, task, status, version, created time and duration.
|
|
15
|
+
|
|
16
|
+
<CodeGroup>
|
|
17
|
+
|
|
18
|
+
```bash npm
|
|
19
|
+
npx trigger.dev@latest runs list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash pnpm
|
|
23
|
+
pnpm dlx trigger.dev@latest runs list
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```bash yarn
|
|
27
|
+
yarn dlx trigger.dev@latest runs list
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
</CodeGroup>
|
|
31
|
+
|
|
32
|
+
<ParamField body="Limit" type="--limit">
|
|
33
|
+
The number of runs to list, up to 100. Defaults to 20.
|
|
34
|
+
</ParamField>
|
|
35
|
+
|
|
36
|
+
<ParamField body="Status" type="--status">
|
|
37
|
+
Only show runs with this status, e.g. `FAILED`.
|
|
38
|
+
</ParamField>
|
|
39
|
+
|
|
40
|
+
<ParamField body="Task" type="--task">
|
|
41
|
+
Only show runs for this task identifier.
|
|
42
|
+
</ParamField>
|
|
43
|
+
|
|
44
|
+
<ParamField body="Tag" type="--tag">
|
|
45
|
+
Only show runs with this tag.
|
|
46
|
+
</ParamField>
|
|
47
|
+
|
|
48
|
+
<ParamField body="Cursor" type="--cursor">
|
|
49
|
+
The pagination cursor printed at the end of the previous page.
|
|
50
|
+
</ParamField>
|
|
51
|
+
|
|
52
|
+
## runs get
|
|
53
|
+
|
|
54
|
+
Prints the status, version, tags, timings, duration, cost and error of a single run.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx trigger.dev@latest runs get run_abc123
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## runs replay
|
|
61
|
+
|
|
62
|
+
Triggers a new run with the same payload as an existing one, using the latest version of the task.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx trigger.dev@latest runs replay run_abc123
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## runs cancel
|
|
69
|
+
|
|
70
|
+
Cancels a run that has not finished yet. You are asked to confirm first.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx trigger.dev@latest runs cancel run_abc123
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
<ParamField body="Skip confirmation" type="--yes | -y">
|
|
77
|
+
Cancel without the confirmation prompt. Required in non-interactive environments such as CI.
|
|
78
|
+
</ParamField>
|
|
79
|
+
|
|
80
|
+
## Options
|
|
81
|
+
|
|
82
|
+
<ParamField body="Environment" type="--env | -e">
|
|
83
|
+
The environment to use: `dev`, `prod`, `staging` or `preview`. Defaults to `prod`.
|
|
84
|
+
</ParamField>
|
|
85
|
+
|
|
86
|
+
<ConfigFileOptions />
|
|
87
|
+
<ProjectRefOptions />
|
|
88
|
+
<BranchOptions />
|
|
89
|
+
|
|
90
|
+
### Common options
|
|
91
|
+
|
|
92
|
+
These options are available on most commands.
|
|
93
|
+
|
|
94
|
+
<CommonOptions />
|
|
@@ -63,6 +63,12 @@ export default defineConfig({
|
|
|
63
63
|
|
|
64
64
|
In this example we're using env vars from [Infisical](https://infisical.com).
|
|
65
65
|
|
|
66
|
+
<Tip>
|
|
67
|
+
Infisical also offers a native [Secret Sync](/deploy-environment-variables#infisical-secret-sync)
|
|
68
|
+
that pushes secrets to Trigger.dev without a build extension or a redeploy. Use `syncEnvVars` when
|
|
69
|
+
you want to resolve secrets at deploy time in code, or for a service without a native sync.
|
|
70
|
+
</Tip>
|
|
71
|
+
|
|
66
72
|
```ts trigger.config.ts
|
|
67
73
|
import { defineConfig } from "@trigger.dev/sdk";
|
|
68
74
|
import { syncEnvVars } from "@trigger.dev/build/extensions/core";
|