Trigger.dev Release Notes
58 release notes curated from 27 sources by the Releasebot Team. Last updated: May 29, 2026
- May 29, 2026
- Date parsed from source:May 29, 2026
- First seen by Releasebot:May 29, 2026
build-supervisor-wide-events.rc4
Trigger.dev adds start_time emission on wide events for supervisor.
feat(supervisor): emit start_time on wide events
Original source - May 23, 2026
- Date parsed from source:May 23, 2026
- First seen by Releasebot:May 23, 2026
trigger.dev v4.5.0-rc.2
Trigger.dev releases v4.5.0-rc.2 with smarter agent message handling, slimmer continuation payloads, and a new TriggerClient for running multiple SDK clients side by side. It also fixes chat agent HITL continuations on reasoning-heavy turns.
trigger.dev v4.5.0-rc.2
Upgrade
npx trigger.dev@latest update # npm pnpm dlx trigger.dev@latest update # pnpm yarn dlx trigger.dev@latest update # yarn bunx trigger.dev@latest update # bunSelf-hosted Docker image:
ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.2Release notes
Read the full release notes: https://trigger.dev/changelog/v4-5-0-rc-2
What's changed
Improvements
The per-turn merge now overlays the wire copy's tool-part state advancement onto the agent's existing chain — state + the matching resolution field (output / errorText / approval) come from the wire, everything else (text, reasoning, tool input, provider metadata) stays whatever the snapshot or hydrateMessages returned. Previously a full-message replace overwrote those fields with whatever the client shipped, so a slimmed wire copy landed a tool call with no arguments on the next LLM call. Covers output-available / output-error (HITL addToolOutput) and approval-responded / output-denied (approval flow).
TriggerChatTransport.sendMessages and AgentChat.sendRaw now slim assistant messages that carry advanced tool parts. The wire payload is just { id, role, parts: [<state + resolution field>] } for submit-message continuations; everything else passes through. Reasoning blobs and full tool inputs no longer ride the wire on every addToolOutput / addToolApproveResponse, so continuation payloads stay well under the .in/append cap on long agent loops.
Add TriggerClient for running multiple SDK clients side-by-side, each with its own auth, preview branch, and baseURL. Useful when a single process needs to trigger tasks or read runs across multiple projects, environments, or preview branches without mutating shared global state. (#3683)
Bug fixes
Fix chat.agent HITL continuations on reasoning-heavy turns. Two changes that work together: (#3719)
All packages: v4.5.0-rc.2
@trigger.dev/build, @trigger.dev/core, @trigger.dev/plugins, @trigger.dev/python, @trigger.dev/react-hooks, @trigger.dev/redis-worker, @trigger.dev/rsc, @trigger.dev/schema-to-json, @trigger.dev/sdk, trigger.dev
Full changelog: v4.4.0.2...v4.5.0-rc.2
Original source All of your release notes in one feed
Join Releasebot and get updates from Trigger.dev and hundreds of other software products.
- May 23, 2026
- Date parsed from source:May 23, 2026
- First seen by Releasebot:May 23, 2026
v.docker.4.5.0-rc.2: chore: release v4.5.0-rc.2 (#3702)
Trigger.dev improves chat agent HITL continuations by preserving tool-state changes while slimming wire payloads to avoid oversized loops, and adds TriggerClient for running multiple SDK clients with separate auth, preview branch, and baseURL.
Summary
3 improvements, 1 bug fix.
Improvements
The per-turn merge now overlays the wire copy's tool-part state
advancement onto the agent's existing chain — state + the matching
resolution field (output / errorText / approval) come from the
wire, everything else (text, reasoning, tool input, provider metadata)
stays whatever the snapshot or hydrateMessages returned. Previously a
full-message replace overwrote those fields with whatever the client
shipped, so a slimmed wire copy landed a tool call with no arguments
on the next LLM call. Covers output-available / output-error (HITL
addToolOutput) and approval-responded / output-denied (approval
flow).TriggerChatTransport.sendMessages and AgentChat.sendRaw now slim
assistant messages that carry advanced tool parts. The wire payload is
just { id, role, parts: [<state + resolution field>] } for
submit-message continuations; everything else passes through.
Reasoning blobs and full tool inputs no longer ride the wire on every
addToolOutput / addToolApproveResponse, so continuation payloads
stay well under the .in/append cap on long agent loops.Add TriggerClient for running multiple SDK clients side-by-side,
each with its own auth, preview branch, and baseURL. Useful when a
single process needs to trigger tasks or read runs across multiple
projects, environments, or preview branches without mutating shared
global state.
(#3683)Bug fixes
Fix chat.agent HITL continuations on reasoning-heavy turns. Two
changes that work together:
(#3719)Raw changeset output
⚠️⚠️⚠️⚠️⚠️⚠️
main is currently in pre mode so this branch has prereleases
rather than normal releases. If you want to exit prereleases, run
changeset pre exit on main.⚠️️⚠️⚠️⚠️⚠️⚠️
Releases
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Fix chat.agent HITL continuations on reasoning-heavy turns. Two
changes that work together:
(#3719)The per-turn merge now overlays the wire copy's tool-part state
advancement onto the agent's existing chain — state + the matching
resolution field (output / errorText / approval) come from the
wire, everything else (text, reasoning, tool input, provider metadata)
stays whatever the snapshot or hydrateMessages returned. Previously a
full-message replace overwrote those fields with whatever the client
shipped, so a slimmed wire copy landed a tool call with no arguments
on the next LLM call. Covers output-available / output-error (HITL
addToolOutput) and approval-responded / output-denied (approval
flow).TriggerChatTransport.sendMessages and AgentChat.sendRaw now slim
assistant messages that carry advanced tool parts. The wire payload is
just { id, role, parts: [<state + resolution field>] } for
submit-message continuations; everything else passes through.
Reasoning blobs and full tool inputs no longer ride the wire on every
addToolOutput / addToolApproveResponse, so continuation payloads
stay well under the .in/append cap on long agent loops.Note: onValidateMessages receives the slim wire on HITL turns. If you
call validateUIMessages from ai against the full messages array it
will reject the slim assistant; filter to user messages (or skip on HITL
turns) — see the updated docstring on onValidateMessages for the
recommended pattern.For hydrateMessages hooks that persist the chain, this release also
adds a small helper to the @trigger.dev/sdk/ai surface:import { chat, upsertIncomingMessage } from "@trigger.dev/sdk/ai"; chat.agent({ hydrateMessages: async ({ chatId, trigger, incomingMessages }) => { const record = await db.chat.findUnique({ where: { id: chatId } }); const stored = record?.messages ?? []; if (upsertIncomingMessage(stored, { trigger, incomingMessages })) { await db.chat.update({ where: { id: chatId }, data: { messages: stored } }); } return stored; }, });It pushes fresh user messages by id, no-ops on HITL continuations (the
incoming shares an id with the existing assistant — the runtime overlays
the new tool-state advance), and skips on non-submit-message triggers.
Returns true if it mutated stored so the caller knows whether to
persist.Net effect: chat.addToolOutput(...) /
chat.addToolApproveResponse(...) on multi-step reasoning agents
(OpenAI Responses with store: false, Anthropic extended thinking,
etc.) no longer blows the cap and no longer corrupts the LLM input.Add TriggerClient for running multiple SDK clients side-by-side,
each with its own auth, preview branch, and baseURL. Useful when a
single process needs to trigger tasks or read runs across multiple
projects, environments, or preview branches without mutating shared
global state.
(#3683)import { TriggerClient } from "@trigger.dev/sdk"; const prod = new TriggerClient({ accessToken: process.env.TRIGGER_PROD_KEY }); const preview = new TriggerClient({ accessToken: process.env.TRIGGER_PREVIEW_KEY, previewBranch: "signup-flow", }); await prod.tasks.trigger("send-email", payload); await preview.runs.list({ status: ["COMPLETED"] });Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
trigger.dev v4.5.0-rc.1
Trigger.dev ships v4.5.0-rc.1 with bug fixes for missing chat.agent skills, more reliable skill folder bundling, and a fix for COULD_NOT_FIND_EXECUTOR when tasks are loaded with await import() inside another task.
Upgrade
npx [email protected] update pnpm dlx [email protected] update yarn dlx [email protected] update bunx [email protected] update Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.1Release notes
Read the full release notes: https://trigger.dev/changelog/v4-5-0-rc-1
What's changed
Bug fixes
Fix chat.agent skills silently missing in trigger dev for projects whose task files read process.env at module top level (e.g. a third-party SDK client initialized at import). Skill folders now bundle into .trigger/skills/ reliably regardless of which env vars are set when the CLI launches. (#3690)
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id. (#3688)
All packages: v4.5.0-rc.1
@trigger.dev/build, @trigger.dev/core, @trigger.dev/plugins, @trigger.dev/python, @trigger.dev/react-hooks, @trigger.dev/redis-worker, @trigger.dev/rsc, @trigger.dev/schema-to-json, @trigger.dev/sdk, trigger.dev
Full changelog: v4.4.0.1...v4.5.0-rc.1
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
trigger.dev v4.5.0-rc.0
Trigger.dev ships a major release focused on AI chat and prompt tooling, with code-defined versioned prompts, dashboard overrides, durable sessions, multi-turn chat resilience, and tighter Vercel AI SDK integration. It also adds region filtering, improved retries, and bug fixes.
Upgrade
npx [email protected] update pnpm dlx [email protected] update yarn dlx [email protected] update bunx [email protected] updateSelf-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.0
What's changed
Improvements
AI Prompts — define prompt templates as code alongside your tasks, version them on deploy, and override the text or model from the dashboard without redeploying. Prompts integrate with the Vercel AI SDK via toAISDKTelemetry() (links every generation span back to the prompt) and with chat.agent via chat.prompt.set() + chat.toStreamTextOptions(). (#3629)
Code-defined, deploy-versioned templates — define with prompts.define({ id, model, config, variables, content }). Every deploy creates a new version visible in the dashboard. Mustache-style placeholders ({{var}}, {{#cond}}...{{/cond}}) with Zod / ArkType / Valibot-typed variables.
Dashboard overrides — change a prompt's text or model from the dashboard without redeploying. Overrides take priority over the deployed "current" version and are environment-scoped (dev / staging / production independent).
Resolve API — prompt.resolve(vars, { version?, label? }) returns the compiled text, resolved model, version, and labels. Standalone prompts.resolve<typeof handle>(slug, vars) for cross-file resolution with full type inference on slug and variable shape.
AI SDK integration — spread resolved.toAISDKTelemetry({ ...extra }) into any generateText / streamText call and every generation span links to the prompt in the dashboard alongside its input variables, model, tokens, and cost.
chat.agent integration — chat.prompt.set(resolved) stores the resolved prompt run-scoped; chat.toStreamTextOptions({ registry }) pulls system, model (resolved via the AI SDK provider registry), temperature / maxTokens / etc., and telemetry into a single spread for streamText.
Management SDK — prompts.list(), prompts.versions(slug), prompts.promote(slug, version), prompts.createOverride(slug, body), prompts.updateOverride(slug, body), prompts.removeOverride(slug), prompts.reactivateOverride(slug, version).
Dashboard — prompts list with per-prompt usage sparklines; per-prompt detail with Template / Details / Versions / Generations / Metrics tabs. AI generation spans get a custom inspector showing the linked prompt's metadata, input variables, and template content alongside model, tokens, cost, and the message thread.
Adds onBoot to chat.agent — a lifecycle hook that fires once per worker process picking up the chat. Runs for the initial run, preloaded runs, AND reactive continuation runs (post-cancel, crash, endRun, requestUpgrade, OOM retry), before any other hook. Use it to initialize chat.local, open per-process resources, or re-hydrate state from your DB on continuation — anywhere the SAME run picking up after suspend/resume isn't enough. (#3543)
AI SDK useChat integration — a custom ChatTransport (useTriggerChatTransport) plugs straight into Vercel AI SDK's useChat hook. Text streaming, tool calls, reasoning, and data-* parts all work natively over Trigger.dev's realtime streams. No custom API routes needed.
First-turn fast path (chat.headStart) — opt-in handler that runs the first turn's streamText step in your warm server process while the agent run boots in parallel, cutting cold-start TTFC by roughly half (measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step 2+ (tool execution, persistence, hooks) so heavy deps stay where they belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit, Remix, Workers, etc.; bridge to Express/Fastify/Koa via chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.
Multi-turn durability via Sessions — every chat is backed by a durable Session that outlives any individual run. Conversations resume across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks. sessions.list enumerates chats for inbox-style UIs.
Auto-accumulated history, delta-only wire — the backend accumulates the full conversation across turns; clients only ship the new message each turn. Long chats never hit the 512 KiB body cap. Register hydrateMessages to be the source of truth yourself.
Lifecycle hooks — onPreload, onChatStart, onValidateMessages, hydrateMessages, onTurnStart, onBeforeTurnComplete, onTurnComplete, onChatSuspend, onChatResume — for persistence, validation, and post-turn work.
Stop generation — client-driven transport.stopGeneration(chatId) aborts mid-stream; the run stays alive for the next message, partial response is captured, and aborted parts (stuck partial-call tools, in-progress reasoning) are auto-cleaned.
Tool approvals (HITL) — tools with needsApproval: true pause until the user approves or denies via addToolApprovalResponse. The runtime reconciles the updated assistant message by ID and continues streamText.
Steering and background injection — pendingMessages injects user messages between tool-call steps so users can steer the agent mid-execution; chat.inject() + chat.defer() adds context from background work (self-review, RAG, safety checks) between turns.
Actions — non-turn frontend commands (undo, rollback, regenerate, edit) sent via transport.sendAction. Fire hydrateMessages + onAction only — no turn hooks, no run(). onAction can return a StreamTextResult for a model response, or void for side-effect-only.
Typed state primitives — chat.local<T> for per-run state accessible from hooks, run(), tools, and subtasks (auto-serialized through ai.toolExecute); chat.store for typed shared data between agent and client; chat.history for reading and mutating the message chain; clientDataSchema for typed clientData in every hook.
chat.toStreamTextOptions() — one spread into streamText wires up versioned system Prompts, model resolution, telemetry metadata, compaction, steering, and background injection.
Multi-tab coordination — multiTab: true + useMultiTabChat prevents duplicate sends and syncs state across browser tabs via BroadcastChannel. Non-active tabs go read-only with live updates.
Network resilience — built-in indefinite retry with bounded backoff, reconnect on online / tab refocus / bfcache restore, Last-Event-ID mid-stream resume. No app code needed.
Sessions — a durable, run-aware stream channel keyed on a stable externalId. A Session is the unit of state that owns a multi-run conversation: messages flow through .in, responses through .out, both survive run boundaries. Sessions back the new chat.agent runtime, and you can build on them directly for any pattern that needs durable bi-directional streaming across runs. (#3542)
Add ai.toolExecute(task) so you can wire a Trigger subtask in as the execute handler of an AI SDK tool() while defining description and inputSchema yourself — useful when you want full control over the tool surface and just need Trigger's subtask machinery for the body. (#3546)
Type chat.createStartSessionAction against your chat agent so clientData is typed end-to-end on the first turn: (#3684)
Add region to the runs list / retrieve API: filter runs by region (runs.list({ region: "..." }) / filter[region]=<masterQueue>) and read each run's executing region from the new region field on the response. (#3612)
Add TRIGGER_BUILD_SKIP_REWRITE_TIMESTAMP=1 escape hatch for local self-hosted builds whose buildx driver doesn't support rewrite-timestamp alongside push (e.g. orbstack's default docker driver). (#3618)
Reject overlong idempotencyKey values at the API boundary so they no longer trip an internal size limit on the underlying unique index and surface as a generic 500. Inputs are capped at 2048 characters — well above what idempotencyKeys.create() produces (a 64-character hash) and above any realistic raw key. Applies to tasks.trigger, tasks.batchTrigger, batch.create (Phase 1 streaming batches), wait.createToken, wait.forDuration, and the input/session stream waitpoint endpoints. Over-limit requests now return a structured 400 instead. (#3560)
AI SDK useChat integration — a custom ChatTransport (useTriggerChatTransport) plugs straight into Vercel AI SDK's useChat hook. Text streaming, tool calls, reasoning, and data-* parts all work natively over Trigger.dev's realtime streams. No custom API routes needed.
First-turn fast path (chat.headStart) — opt-in handler that runs the first turn's streamText step in your warm server process while the agent run boots in parallel, cutting cold-start TTFC by roughly half (measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step 2+ (tool execution, persistence, hooks) so heavy deps stay where they belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit, Remix, Workers, etc.; bridge to Express/Fastify/Koa via chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.
Multi-turn durability via Sessions — every chat is backed by a durable Session that outlives any individual run. Conversations resume across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks. sessions.list enumerates chats for inbox-style UIs.
Auto-accumulated history, delta-only wire — the backend accumulates the full conversation across turns; clients only ship the new message each turn. Long chats never hit the 512 KiB body cap. Register hydrateMessages to be the source of truth yourself.
Lifecycle hooks — onPreload, onChatStart, onValidateMessages, hydrateMessages, onTurnStart, onBeforeTurnComplete, onTurnComplete, onChatSuspend, onChatResume — for persistence, validation, and post-turn work.
Stop generation — client-driven transport.stopGeneration(chatId) aborts mid-stream; the run stays alive for the next message, partial response is captured, and aborted parts (stuck partial-call tools, in-progress reasoning) are auto-cleaned.
Tool approvals (HITL) — tools with needsApproval: true pause until the user approves or denies via addToolApprovalResponse. The runtime reconciles the updated assistant message by ID and continues streamText.
Steering and background injection — pendingMessages injects user messages between tool-call steps so users can steer the agent mid-execution; chat.inject() + chat.defer() adds context from background work (self-review, RAG, safety checks) between turns.
Actions — non-turn frontend commands (undo, rollback, regenerate, edit) sent via transport.sendAction. Fire hydrateMessages + onAction only — no turn hooks, no run(). onAction can return a StreamTextResult for a model response, or void for side-effect-only.
Typed state primitives — chat.local<T> for per-run state accessible from hooks, run(), tools, and subtasks (auto-serialized through ai.toolExecute); chat.store for typed shared data between agent and client; chat.history for reading and mutating the message chain; clientDataSchema for typed clientData in every hook.
chat.toStreamTextOptions() — one spread into streamText wires up versioned system Prompts, model resolution, telemetry metadata, compaction, steering, and background injection.
Multi-tab coordination — multiTab: true + useMultiTabChat prevents duplicate sends and syncs state across browser tabs via BroadcastChannel. Non-active tabs go read-only with live updates.
Network resilience — built-in indefinite retry with bounded backoff, reconnect on online / tab refocus / bfcache restore, Last-Event-ID mid-stream resume. No app code needed.
Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry policy instead of failing the run on the first segfault. SIGSEGV in Node tasks is frequently non-deterministic (native addon races, JIT/GC interaction, near-OOM in native code, host issues), so retrying on a fresh process often succeeds. The retry is gated by the task's existing retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and uncaught exceptions already use — so tasks without a retry policy still fail fast. (#3552)
The public interfaces for a plugin system. Initially consolidated authentication and authorization interfaces. (#3499)
Add MollifierBuffer and MollifierDrainer primitives for trigger burst smoothing. (#3614)
Bug fixes
Fix LocalsKey<T> type incompatibility across dual-package builds. The phantom value-type brand no longer uses a module-level unique symbol, so a single TypeScript compilation that resolves the type from both the ESM and CJS outputs (which can happen under certain pnpm hoisting layouts) no longer sees two structurally-incompatible variants of the same type. (#3626)
All packages: v4.5.0-rc.0
@trigger.dev/build, @trigger.dev/core, @trigger.dev/plugins, @trigger.dev/python, @trigger.dev/react-hooks, @trigger.dev/redis-worker, @trigger.dev/rsc, @trigger.dev/schema-to-json, @trigger.dev/sdk, trigger.dev
Full changelog: v4.4.0.0...v4.5.0-rc.0
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
v.docker.4.5.0-rc.1: chore: release v4.5.0-rc.1 (#3691)
Trigger.dev fixes two runtime and CLI bugs, making chat.agent skills bundle reliably in trigger dev and resolving COULD_NOT_FIND_EXECUTOR when tasks are loaded with await import() from inside another task. This prerelease also updates related packages.
Summary
2 bug fixes.
Bug fixes
Fix chat.agent skills silently missing in trigger dev for projects whose task files read process.env at module top level (e.g. a third-party SDK client initialized at import). Skill folders now bundle into .trigger/skills/ reliably regardless of which env vars are set when the CLI launches.
(#3690)
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id.
(#3688)
Raw changeset output
⚠️⚠️⚠️⚠️⚠️⚠️
main is currently in pre mode so this branch has prereleases rather than normal releases. If you want to exit prereleases, run changeset pre exit on main.
⚠️⚠️⚠️⚠️⚠️⚠️
Releases
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
Patch Changes
Fix chat.agent skills silently missing in trigger dev for projects whose task files read process.env at module top level (e.g. a third-party SDK client initialized at import). Skill folders now bundle into .trigger/skills/ reliably regardless of which env vars are set when the CLI launches.
(#3690)
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id.
(#3688)
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id.
(#3688)
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
v.docker.4.5.0-rc.0: chore: release v4.5.0-rc.0 (#3563)
Trigger.dev releases major AI chat and prompt tooling, adding code-defined versioned prompts, durable Sessions for multi-turn chats, Vercel AI SDK useChat integration, agent lifecycle hooks, tool approvals, skills, and broader reliability and API improvements.
Summary
44 improvements, 1 bug fix.
Improvements
AI Prompts — define prompt templates as code alongside your tasks,
version them on deploy, and override the text or model from the
dashboard without redeploying. Prompts integrate with the Vercel AI SDK
via toAISDKTelemetry() (links every generation span back to the
prompt) and with chat.agent via chat.prompt.set() +
chat.toStreamTextOptions().
(#3629)Code-defined, deploy-versioned templates — define with
prompts.define({ id, model, config, variables, content }). Every
deploy creates a new version visible in the dashboard. Mustache-style
placeholders ({{var}}, {{#cond}}...{{/cond}}) with Zod / ArkType /
Valibot-typed variables.Dashboard overrides — change a prompt's text or model from the
dashboard without redeploying. Overrides take priority over the deployed
"current" version and are environment-scoped (dev / staging / production
independent).Resolve API — prompt.resolve(vars, { version?, label? }) returns
the compiled text, resolved model, version, and labels. Standalone
prompts.resolve<typeof handle>(slug, vars) for cross-file resolution
with full type inference on slug and variable shape.AI SDK integration — spread resolved.toAISDKTelemetry({ ...extra }) into any generateText / streamText call and every generation
span links to the prompt in the dashboard alongside its input variables,
model, tokens, and cost.chat.agent integration — chat.prompt.set(resolved) stores the
resolved prompt run-scoped; chat.toStreamTextOptions({ registry })
pulls system, model (resolved via the AI SDK provider registry),
temperature / maxTokens / etc., and telemetry into a single spread
for streamText.Management SDK — prompts.list(), prompts.versions(slug),
prompts.promote(slug, version), prompts.createOverride(slug, body),
prompts.updateOverride(slug, body), prompts.removeOverride(slug),
prompts.reactivateOverride(slug, version).Dashboard — prompts list with per-prompt usage sparklines;
per-prompt detail with Template / Details / Versions / Generations /
Metrics tabs. AI generation spans get a custom inspector showing the
linked prompt's metadata, input variables, and template content
alongside model, tokens, cost, and the message thread.Adds onBoot to chat.agent — a lifecycle hook that fires once per
worker process picking up the chat. Runs for the initial run, preloaded
runs, AND reactive continuation runs (post-cancel, crash, endRun,
requestUpgrade, OOM retry), before any other hook. Use it to
initialize chat.local, open per-process resources, or re-hydrate state
from your DB on continuation — anywhere the SAME run picking up after
suspend/resume isn't enough.
(#3543)AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.Sessions — a durable, run-aware stream channel keyed on a stable
externalId. A Session is the unit of state that owns a multi-run
conversation: messages flow through .in, responses through .out,
both survive run boundaries. Sessions back the new chat.agent runtime,
and you can build on them directly for any pattern that needs durable
bi-directional streaming across runs.
(#3542)Add ai.toolExecute(task) so you can wire a Trigger subtask in as the
execute handler of an AI SDK tool() while defining description and
inputSchema yourself — useful when you want full control over the tool
surface and just need Trigger's subtask machinery for the body.
(#3546)Type chat.createStartSessionAction against your chat agent so
clientData is typed end-to-end on the first turn:
(#3684)Add region to the runs list / retrieve API: filter runs by region
(runs.list({ region: "..." }) / filter[region]=<masterQueue>) and
read each run's executing region from the new region field on the
response.
(#3612)Add TRIGGER_BUILD_SKIP_REWRITE_TIMESTAMP=1 escape hatch for local
self-hosted builds whose buildx driver doesn't support
rewrite-timestamp alongside push (e.g. orbstack's default docker
driver).
(#3618)Reject overlong idempotencyKey values at the API boundary so they no
longer trip an internal size limit on the underlying unique index and
surface as a generic 500. Inputs are capped at 2048 characters — well
above what idempotencyKeys.create() produces (a 64-character hash) and
above any realistic raw key. Applies to tasks.trigger,
tasks.batchTrigger, batch.create (Phase 1 streaming batches),
wait.createToken, wait.forDuration, and the input/session stream
waitpoint endpoints. Over-limit requests now return a structured 400
instead.
(#3560)AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry
policy instead of failing the run on the first segfault. SIGSEGV in Node
tasks is frequently non-deterministic (native addon races, JIT/GC
interaction, near-OOM in native code, host issues), so retrying on a
fresh process often succeeds. The retry is gated by the task's existing
retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and
uncaught exceptions already use — so tasks without a retry policy still
fail fast.
(#3552)The public interfaces for a plugin system. Initially consolidated
authentication and authorization interfaces.
(#3499)Add MollifierBuffer and MollifierDrainer primitives for trigger burst
smoothing.
(#3614)Bug fixes
Fix LocalsKey<T> type incompatibility across dual-package builds.
The phantom value-type brand no longer uses a module-level unique symbol, so a single TypeScript compilation that resolves the type from
both the ESM and CJS outputs (which can happen under certain pnpm
hoisting layouts) no longer sees two structurally-incompatible variants
of the same type.
(#3626)Raw changeset output
⚠️⚠️⚠️⚠️⚠️⚠️
main is currently in pre mode so this branch has prereleases
rather than normal releases. If you want to exit prereleases, run
changeset pre exit on main.
⚠️⚠️⚠️⚠️⚠️⚠️Releases
@trigger.dev/[email protected]
Minor Changes
AI Prompts — define prompt templates as code alongside your tasks,
version them on deploy, and override the text or model from the
dashboard without redeploying. Prompts integrate with the Vercel AI SDK
via toAISDKTelemetry() (links every generation span back to the
prompt) and with chat.agent via chat.prompt.set() +
chat.toStreamTextOptions().
(#3629)import { prompts } from "@trigger.dev/sdk"; import { generateText } from "ai"; import { openai } from "@ai-sdk/openai"; import { z } from "zod"; export const supportPrompt = prompts.define({ id: "customer-support", model: "gpt-4o", config: { temperature: 0.7 }, variables: z.object({ customerName: z.string(), plan: z.string(), issue: z.string(), }), content: `You are a support agent for Acme. Customer: {{customerName}} ({{plan}} plan) Issue: {{issue}}`, }); const resolved = await supportPrompt.resolve({ customerName: "Alice", plan: "Pro", issue: "Can't access billing", }); const result = await generateText({ model: openai(resolved.model ?? "gpt-4o"), system: resolved.text, prompt: "Can't access billing", ...resolved.toAISDKTelemetry(), });What you get:
Code-defined, deploy-versioned templates — define with
prompts.define({ id, model, config, variables, content }). Every
deploy creates a new version visible in the dashboard. Mustache-style
placeholders ({{var}}, {{#cond}}...{{/cond}}) with Zod / ArkType /
Valibot-typed variables.Dashboard overrides — change a prompt's text or model from the
dashboard without redeploying. Overrides take priority over the deployed
"current" version and are environment-scoped (dev / staging / production
independent).Resolve API — prompt.resolve(vars, { version?, label? }) returns
the compiled text, resolved model, version, and labels. Standalone
prompts.resolve<typeof handle>(slug, vars) for cross-file resolution
with full type inference on slug and variable shape.AI SDK integration — spread resolved.toAISDKTelemetry({ ...extra }) into any generateText / streamText call and every generation
span links to the prompt in the dashboard alongside its input variables,
model, tokens, and cost.chat.agent integration — chat.prompt.set(resolved) stores the
resolved prompt run-scoped; chat.toStreamTextOptions({ registry })
pulls system, model (resolved via the AI SDK provider registry),
temperature / maxTokens / etc., and telemetry into a single spread
for streamText.Management SDK — prompts.list(), prompts.versions(slug),
prompts.promote(slug, version), prompts.createOverride(slug, body),
prompts.updateOverride(slug, body), prompts.removeOverride(slug),
prompts.reactivateOverride(slug, version).Dashboard — prompts list with per-prompt usage sparklines;
per-prompt detail with Template / Details / Versions / Generations /
Metrics tabs. AI generation spans get a custom inspector showing the
linked prompt's metadata, input variables, and template content
alongside model, tokens, cost, and the message thread.See /docs/ai/prompts for the full
reference — template syntax, version resolution order, override
workflow, and type utilities (PromptHandle, PromptIdentifier,
PromptVariables).Adds onBoot to chat.agent — a lifecycle hook that fires once per
worker process picking up the chat. Runs for the initial run, preloaded
runs, AND reactive continuation runs (post-cancel, crash, endRun,
requestUpgrade, OOM retry), before any other hook. Use it to
initialize chat.local, open per-process resources, or re-hydrate state
from your DB on continuation — anywhere the SAME run picking up after
suspend/resume isn't enough.
(#3543)const userContext = chat.local<{ name: string; plan: string }>({ id: "userContext" }); export const myChat = chat.agent({ id: "my-chat", onBoot: async ({ clientData, continuation }) => { const user = await db.user.findUnique({ where: { id: clientData.userId } }); userContext.init({ name: user.name, plan: user.plan }); }, run: async ({ messages, signal }) => streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }), });Use onBoot (not onChatStart) for state setup that must run every
time a worker picks up the chat — onChatStart fires once per chat and
won't run on continuation, leaving chat.local uninitialized when
run() tries to use it.AI Agents — run AI SDK chat completions as durable Trigger.dev
agents instead of fragile API routes. Define an agent in one function,
point useChat at it from React, and the conversation survives page
refreshes, network blips, and process restarts.
(#3543)import { chat } from "@trigger.dev/sdk/ai"; import { streamText } from "ai"; import { openai } from "@ai-sdk/openai"; export const myChat = chat.agent({ id: "my-chat", run: async ({ messages, signal }) => streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }), });import { useChat } from "@ai-sdk/react"; import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react"; const transport = useTriggerChatTransport({ task: "my-chat", accessToken, startSession }); const { messages, sendMessage } = useChat({ transport });What you get:
AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.See /docs/ai-chat for the
full surface — quick start, three backend approaches (chat.agent,
chat.createSession, raw task), persistence and code-sandbox patterns,
type-level guides, and API reference.Add read primitives to chat.history for HITL flows:
getPendingToolCalls(), getResolvedToolCalls(),
extractNewToolResults(message), getChain(), and
findMessage(messageId). These lift the accumulator-walking logic that
customers building human-in-the-loop tools were re-implementing into the
SDK. (#3543)Use getPendingToolCalls() to gate fresh user turns while a tool call
is awaiting an answer. Use extractNewToolResults(message) to dedup
tool results when persisting to your own store — the helper returns only
the parts whose toolCallId is not already resolved on the chain.const pending = chat.history.getPendingToolCalls(); if (pending.length > 0) { // an addToolOutput is expected before a new user message } onTurnComplete: async ({ responseMessage }) => { const newResults = chat.history.extractNewToolResults(responseMessage); for (const r of newResults) { await db.toolResults.upsert({ id: r.toolCallId, output: r.output, errorText: r.errorText }); } };Sessions — a durable, run-aware stream channel keyed on a stable
externalId. A Session is the unit of state that owns a multi-run
conversation: messages flow through .in, responses through .out,
both survive run boundaries. Sessions back the new chat.agent runtime,
and you can build on them directly for any pattern that needs durable
bi-directional streaming across runs.
(#3542)import { sessions, tasks } from "@trigger.dev/sdk"; // Trigger a task and subscribe to its session output in one call const { runId, stream } = await tasks.triggerAndSubscribe("my-task", payload, { externalId: "user-456", }); for await (const chunk of stream) { // ... } // Enumerate existing sessions (powers inbox-style UIs without a // separate index) for await (const s of sessions.list({ type: "chat.agent", tag: "user:user-456" })) { console.log(s.id, s.externalId, s.createdAt, s.closedAt); }See /docs/ai-chat/overview
for the full surface — Sessions powers the durable, resumable chat
runtime described there.Patch Changes
Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and
any helper scripts/references next to your task code, register it with
skills.define({ id, path }), and the CLI bundles it into the deploy
image automatically — no trigger.config.ts changes. The agent gets a
one-line summary in its system prompt and discovers full instructions on
demand via loadSkill, with bash and readFile tools scoped
per-skill (path-traversal guards, output caps, abort-signal
propagation).
(#3543)const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.Add ai.toolExecute(task) so you can wire a Trigger subtask in as the
execute handler of an AI SDK tool() while defining description and
inputSchema yourself — useful when you want full control over the tool
surface and just need Trigger's subtask machinery for the body.
(#3546)const myTool = tool({ description: "...", inputSchema: z.object({ ... }), execute: ai.toolExecute(mySubtask), });ai.tool(task) (toolFromTask) keeps doing the all-in-one wrap and now
aligns its return type with AI SDK's ToolSet. Minimum ai peer raised
to ^6.0.116 to avoid cross-version ToolSet mismatches in monorepos.Stamp gen_ai.conversation.id (the chat id) on every span and metric
emitted from inside a chat.task or chat.agent run. Lets you filter
dashboard spans, runs, and metrics by the chat conversation that
produced them — independent of the run boundary, so multi-run chats
correlate cleanly. No code changes required on the user side.
(#3543)Type chat.createStartSessionAction against your chat agent so
clientData is typed end-to-end on the first turn:
(#3684)import { chat } from "@trigger.dev/sdk/ai"; import type { myChat } from "@/trigger/chat"; export const startChatSession = chat.createStartSessionAction("my-chat"); // In the browser, threaded from the transport's typed startSession callback: const transport = useTriggerChatTransport({ task: "my-chat", startSession: ({ chatId, clientData }) => startChatSession({ chatId, clientData }), // ... });ChatStartSessionParams gains a typed clientData field — folded into
the first run's payload.metadata so onPreload / onChatStart see
the same shape per-turn metadata carries via the transport. The opaque
session-level metadata field is unchanged.Unit-test chat.agent definitions offline with mockChatAgent from
@trigger.dev/sdk/ai/test. Drives a real agent's turn loop in-process —
no network, no task runtime — so you can send messages, actions, and
stop signals via driver methods, inspect captured output chunks, and
verify hooks fire. Pairs with MockLanguageModelV3 from ai/test for
model mocking. setupLocals lets you pre-seed locals (DB clients,
service stubs) before run() starts.
(#3543)The broader runInMockTaskContext harness it's built on lives at
@trigger.dev/core/v3/test — useful for unit-testing any task code, not
just chat.Add region to the runs list / retrieve API: filter runs by region
(runs.list({ region: "..." }) / filter[region]=<masterQueue>) and
read each run's executing region from the new region field on the
response.
(#3612)Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and
any helper scripts/references next to your task code, register it with
skills.define({ id, path }), and the CLI bundles it into the deploy
image automatically — no trigger.config.ts changes. The agent gets a
one-line summary in its system prompt and discovers full instructions on
demand via loadSkill, with bash and readFile tools scoped
per-skill (path-traversal guards, output caps, abort-signal
propagation).
(#3543)const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.Updated dependencies:
@trigger.dev/[email protected]
[email protected]Patch Changes
Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and
any helper scripts/references next to your task code, register it with
skills.define({ id, path }), and the CLI bundles it into the deploy
image automatically — no trigger.config.ts changes. The agent gets a
one-line summary in its system prompt and discovers full instructions on
demand via loadSkill, with bash and readFile tools scoped
per-skill (path-traversal guards, output caps, abort-signal
propagation).
(#3543)const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.Add TRIGGER_BUILD_SKIP_REWRITE_TIMESTAMP=1 escape hatch for local
self-hosted builds whose buildx driver doesn't support
rewrite-timestamp alongside push (e.g. orbstack's default docker
driver).
(#3618)The CLI MCP server's agent-chat tools (start_agent_chat,
send_agent_message, close_agent_chat) now run on the new Sessions
primitive, so AI assistants driving a chat.agent get the same
idempotent-by-chatId, durable-across-runs behavior the browser
transport gets. Required PAT scopes go from write:inputStreams to
read:sessions + write:sessions.
(#3546)MCP list_runs tool: add a region filter input and surface each
run's executing region in the formatted summary.
(#3612)Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and
any helper scripts/references next to your task code, register it with
skills.define({ id, path }), and the CLI bundles it into the deploy
image automatically — no trigger.config.ts changes. The agent gets a
one-line summary in its system prompt and discovers full instructions on
demand via loadSkill, with bash and readFile tools scoped
per-skill (path-traversal guards, output caps, abort-signal
propagation).
(#3543)const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.Reject overlong idempotencyKey values at the API boundary so they no
longer trip an internal size limit on the underlying unique index and
surface as a generic 500. Inputs are capped at 2048 characters — well
above what idempotencyKeys.create() produces (a 64-character hash) and
above any realistic raw key. Applies to tasks.trigger,
tasks.batchTrigger, batch.create (Phase 1 streaming batches),
wait.createToken, wait.forDuration, and the input/session stream
waitpoint endpoints. Over-limit requests now return a structured 400
instead.
(#3560)AI Agents — run AI SDK chat completions as durable Trigger.dev
agents instead of fragile API routes. Define an agent in one function,
point useChat at it from React, and the conversation survives page
refreshes, network blips, and process restarts.
(#3543)import { chat } from "@trigger.dev/sdk/ai"; import { streamText } from "ai"; import { openai } from "@ai-sdk/openai"; export const myChat = chat.agent({ id: "my-chat", run: async ({ messages, signal }) => streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }), });import { useChat } from "@ai-sdk/react"; import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react"; const transport = useTriggerChatTransport({ task: "my-chat", accessToken, startSession }); const { messages, sendMessage } = useChat({ transport });What you get:
AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.See /docs/ai-chat for the
full surface — quick start, three backend approaches (chat.agent,
chat.createSession, raw task), persistence and code-sandbox patterns,
type-level guides, and API reference.Stamp gen_ai.conversation.id (the chat id) on every span and metric
emitted from inside a chat.task or chat.agent run. Lets you filter
dashboard spans, runs, and metrics by the chat conversation that
produced them — independent of the run boundary, so multi-run chats
correlate cleanly. No code changes required on the user side.
(#3543)Fix LocalsKey<T> type incompatibility across dual-package builds.
The phantom value-type brand no longer uses a module-level unique symbol, so a single TypeScript compilation that resolves the type from
both the ESM and CJS outputs (which can happen under certain pnpm
hoisting layouts) no longer sees two structurally-incompatible variants
of the same type.
(#3626)Unit-test chat.agent definitions offline with mockChatAgent from
@trigger.dev/sdk/ai/test. Drives a real agent's turn loop in-process —
no network, no task runtime — so you can send messages, actions, and
stop signals via driver methods, inspect captured output chunks, and
verify hooks fire. Pairs with MockLanguageModelV3 from ai/test for
model mocking. setupLocals lets you pre-seed locals (DB clients,
service stubs) before run() starts.
(#3543)The broader runInMockTaskContext harness it's built on lives at
@trigger.dev/core/v3/test — useful for unit-testing any task code, not
just chat.Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry
policy instead of failing the run on the first segfault. SIGSEGV in Node
tasks is frequently non-deterministic (native addon races, JIT/GC
interaction, near-OOM in native code, host issues), so retrying on a
fresh process often succeeds. The retry is gated by the task's existing
retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and
uncaught exceptions already use — so tasks without a retry policy still
fail fast.
(#3552)Add region to the runs list / retrieve API: filter runs by region
(runs.list({ region: "..." }) / filter[region]=<masterQueue>) and
read each run's executing region from the new region field on the
response.
(#3612)Sessions — a durable, run-aware stream channel keyed on a stable
externalId. A Session is the unit of state that owns a multi-run
conversation: messages flow through .in, responses through .out,
both survive run boundaries. Sessions back the new chat.agent runtime,
and you can build on them directly for any pattern that needs durable
bi-directional streaming across runs.
(#3542)import { sessions, tasks } from "@trigger.dev/sdk"; // Trigger a task and subscribe to its session output in one call const { runId, stream } = await tasks.triggerAndSubscribe("my-task", payload, { externalId: "user-456", }); for await (const chunk of stream) { // ... } // Enumerate existing sessions (powers inbox-style UIs without a // separate index) for await (const s of sessions.list({ type: "chat.agent", tag: "user:user-456" })) { console.log(s.id, s.externalId, s.createdAt, s.closedAt); }See /docs/ai-chat/overview
for the full surface — Sessions powers the durable, resumable chat
runtime described there.@trigger.dev/[email protected]
Patch Changes
The public interfaces for a plugin system. Initially consolidated
authentication and authorization interfaces.
(#3499)Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Add MollifierBuffer and MollifierDrainer primitives for trigger burst
smoothing.
(#3614)MollifierBuffer (accept, pop, ack, requeue, fail,
evaluateTrip) is a per-env FIFO over Redis with atomic Lua transitions
for status tracking. evaluateTrip is a sliding-window trip evaluator
the webapp gate uses to detect per-env trigger bursts.MollifierDrainer pops entries through a polling loop with a
user-supplied handler. The loop survives transient Redis errors via
capped exponential backoff (up to 5s), and per-env pop failures don't
poison the rest of the batch — one env's blip is logged and counted as
failed for that tick. Rotation is two-level: orgs at the top, envs
within each org. The buffer maintains mollifier:orgs and
mollifier:org-envs:${orgId} atomically with per-env queues, so the
drainer walks orgs → envs directly without an in-memory cache. The
maxOrgsPerTick option (default 500) caps how many orgs are scheduled
per tick; for each picked org, one env is popped (rotating round-robin
within the org). An org with N envs gets the same per-tick scheduling
slot as an org with 1 env, so tenant-level drainage throughput is
determined by org count rather than env count.Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]Patch Changes
Updated dependencies:
@trigger.dev/[email protected]Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
helm-v4.5.0-rc.1: chore: release v4.5.0-rc.1 (#3691)
Trigger.dev fixes two runtime issues in prerelease updates, restoring chat.agent skill bundling in trigger dev and resolving COULD_NOT_FIND_EXECUTOR for tasks loaded with await import() inside another task run.
Summary
2 bug fixes.
Bug fixes
Fix chat.agent skills silently missing in trigger dev for projects whose task files read process.env at module top level (e.g. a third-party SDK client initialized at import). Skill folders now bundle into .trigger/skills/ reliably regardless of which env vars are set when the CLI launches.
(#3690)
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id.
(#3688)
Raw changeset output
⚠️⚠️⚠️⚠️⚠️⚠️
main is currently in pre mode so this branch has prereleases rather than normal releases. If you want to exit prereleases, run changeset pre exit on main.
⚠️⚠️⚠️⚠️⚠️⚠️
Releases
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
Patch Changes
Fix chat.agent skills silently missing in trigger dev for projects whose task files read process.env at module top level (e.g. a third-party SDK client initialized at import). Skill folders now bundle into .trigger/skills/ reliably regardless of which env vars are set when the CLI launches.
(#3690)
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id.
(#3688)
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Fix COULD_NOT_FIND_EXECUTOR when a task's definition is loaded via await import(...) from inside another task's run(). The runtime workers now register such tasks with a sentinel file context, and the catalog logs a one-time warning per task id.
(#3688)
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
@trigger.dev/[email protected]
Patch Changes
Updated dependencies:
@trigger.dev/[email protected]
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
helm-v4.5.0-rc.0: chore: release v4.5.0-rc.0 (#3563)
Trigger.dev adds AI Prompts, durable chat.agent sessions, and a richer AI SDK integration with useChat transport, headStart, tool approvals, and multi-turn resilience. It also brings new workflow hooks, session APIs, region filtering, and a few reliability fixes.
Summary
44 improvements, 1 bug fix.
Improvements
AI Prompts — define prompt templates as code alongside your tasks,
version them on deploy, and override the text or model from the
dashboard without redeploying. Prompts integrate with the Vercel AI SDK
via toAISDKTelemetry() (links every generation span back to the
prompt) and with chat.agent via chat.prompt.set() +
chat.toStreamTextOptions().
(#3629)
Code-defined, deploy-versioned templates — define with
prompts.define({ id, model, config, variables, content }). Every
deploy creates a new version visible in the dashboard. Mustache-style
placeholders ({{var}}, {{#cond}}...{{/cond}}) with Zod / ArkType /
Valibot-typed variables.
Dashboard overrides — change a prompt's text or model from the
dashboard without redeploying. Overrides take priority over the deployed
"current" version and are environment-scoped (dev / staging / production
independent).
Resolve API — prompt.resolve(vars, { version?, label? }) returns
the compiled text, resolved model, version, and labels. Standalone
prompts.resolve<typeof handle>(slug, vars) for cross-file resolution
with full type inference on slug and variable shape.
AI SDK integration — spread resolved.toAISDKTelemetry({ ...extra }) into any generateText / streamText call and every generation
span links to the prompt in the dashboard alongside its input variables,
model, tokens, and cost.
chat.agent integration — chat.prompt.set(resolved) stores the
resolved prompt run-scoped; chat.toStreamTextOptions({ registry })
pulls system, model (resolved via the AI SDK provider registry),
temperature / maxTokens / etc., and telemetry into a single spread
for streamText.
Management SDK — prompts.list(), prompts.versions(slug),
prompts.promote(slug, version), prompts.createOverride(slug, body),
prompts.updateOverride(slug, body), prompts.removeOverride(slug),
prompts.reactivateOverride(slug, version).
Dashboard — prompts list with per-prompt usage sparklines;
per-prompt detail with Template / Details / Versions / Generations /
Metrics tabs. AI generation spans get a custom inspector showing the
linked prompt's metadata, input variables, and template content
alongside model, tokens, cost, and the message thread.
Adds onBoot to chat.agent — a lifecycle hook that fires once per
worker process picking up the chat. Runs for the initial run, preloaded
runs, AND reactive continuation runs (post-cancel, crash, endRun,
requestUpgrade, OOM retry), before any other hook. Use it to
initialize chat.local, open per-process resources, or re-hydrate state
from your DB on continuation — anywhere the SAME run picking up after
suspend/resume isn't enough.
(#3543)
AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.
First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.
Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.
Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.
Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.
Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.
Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.
Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.
Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.
Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.
chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.
Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.
Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.
Sessions — a durable, run-aware stream channel keyed on a stable
externalId. A Session is the unit of state that owns a multi-run
conversation: messages flow through .in, responses through .out,
both survive run boundaries. Sessions back the new chat.agent runtime,
and you can build on them directly for any pattern that needs durable
bi-directional streaming across runs.
(#3542)
Add ai.toolExecute(task) so you can wire a Trigger subtask in as the
execute handler of an AI SDK tool() while defining description and
inputSchema yourself — useful when you want full control over the tool
surface and just need Trigger's subtask machinery for the body.
(#3546)
Type chat.createStartSessionAction against your chat agent so
clientData is typed end-to-end on the first turn:
(#3684)
Add region to the runs list / retrieve API: filter runs by region
(runs.list({ region: "..." }) / filter[region]=<masterQueue>) and
read each run's executing region from the new region field on the
response.
(#3612)
Add TRIGGER_BUILD_SKIP_REWRITE_TIMESTAMP=1 escape hatch for local
self-hosted builds whose buildx driver doesn't support
rewrite-timestamp alongside push (e.g. orbstack's default docker
driver).
(#3618)
Reject overlong idempotencyKey values at the API boundary so they no
longer trip an internal size limit on the underlying unique index and
surface as a generic 500. Inputs are capped at 2048 characters — well
above what idempotencyKeys.create() produces (a 64-character hash) and
above any realistic raw key. Applies to tasks.trigger,
tasks.batchTrigger, batch.create (Phase 1 streaming batches),
wait.createToken, wait.forDuration, and the input/session stream
waitpoint endpoints. Over-limit requests now return a structured 400
instead.
(#3560)
AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.
First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.
Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.
Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.
Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.
Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.
Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.
Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.
Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.
Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.
chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.
Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.
Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.
Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry
policy instead of failing the run on the first segfault. SIGSEGV in Node
tasks is frequently non-deterministic (native addon races, JIT/GC
interaction, near-OOM in native code, host issues), so retrying on a
fresh process often succeeds. The retry is gated by the task's existing
retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and
uncaught exceptions already use — so tasks without a retry policy still
fail fast.
(#3552)
The public interfaces for a plugin system. Initially consolidated
authentication and authorization interfaces.
(#3499)
Add MollifierBuffer and MollifierDrainer primitives for trigger burst
smoothing.
(#3614)
Bug fixes
Fix LocalsKey<T> type incompatibility across dual-package builds.
The phantom value-type brand no longer uses a module-level unique symbol, so a single TypeScript compilation that resolves the type from
both the ESM and CJS outputs (which can happen under certain pnpm
hoisting layouts) no longer sees two structurally-incompatible variants
of the same type.
(#3626)
Raw changeset output
⚠️⚠️⚠️⚠️⚠️⚠️
main is currently in pre mode so this branch has prereleases
rather than normal releases. If you want to exit prereleases, run
changeset pre exit on main.
⚠️⚠️⚠️⚠️⚠️⚠️
Releases
@trigger.dev/[email protected]
Minor Changes
AI Prompts — define prompt templates as code alongside your tasks,
version them on deploy, and override the text or model from the
dashboard without redeploying. Prompts integrate with the Vercel AI SDK
via toAISDKTelemetry() (links every generation span back to the
prompt) and with chat.agent via chat.prompt.set() +
chat.toStreamTextOptions().
(#3629)
import { prompts } from "@trigger.dev/sdk";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
export const supportPrompt = prompts.define({
id: "customer-support",
model: "gpt-4o",
config: { temperature: 0.7 },
variables: z.object({
customerName: z.string(),
plan: z.string(),
issue: z.string(),
}),
content:You are a support agent for Acme. Customer: {{customerName}} ({{plan}} plan) Issue: {{issue}},
});
const resolved = await supportPrompt.resolve({
customerName: "Alice",
plan: "Pro",
issue: "Can't access billing",
});
const result = await generateText({
model: openai(resolved.model ?? "gpt-4o"),
system: resolved.text,
prompt: "Can't access billing",
...resolved.toAISDKTelemetry(),
});
What you get:
Code-defined, deploy-versioned templates — define with
prompts.define({ id, model, config, variables, content }). Every
deploy creates a new version visible in the dashboard. Mustache-style
placeholders ({{var}}, {{#cond}}...{{/cond}}) with Zod / ArkType /
Valibot-typed variables.
Dashboard overrides — change a prompt's text or model from the
dashboard without redeploying. Overrides take priority over the deployed
"current" version and are environment-scoped (dev / staging / production
independent).
Resolve API — prompt.resolve(vars, { version?, label? }) returns
the compiled text, resolved model, version, and labels. Standalone
prompts.resolve<typeof handle>(slug, vars) for cross-file resolution
with full type inference on slug and variable shape.
AI SDK integration — spread resolved.toAISDKTelemetry({ ...extra }) into any generateText / streamText call and every generation
span links to the prompt in the dashboard alongside its input variables,
model, tokens, and cost.
chat.agent integration — chat.prompt.set(resolved) stores the
resolved prompt run-scoped; chat.toStreamTextOptions({ registry })
pulls system, model (resolved via the AI SDK provider registry),
temperature / maxTokens / etc., and telemetry into a single spread
for streamText.
Management SDK — prompts.list(), prompts.versions(slug),
prompts.promote(slug, version), prompts.createOverride(slug, body),
prompts.updateOverride(slug, body), prompts.removeOverride(slug),
prompts.reactivateOverride(slug, version).
Dashboard — prompts list with per-prompt usage sparklines;
per-prompt detail with Template / Details / Versions / Generations /
Metrics tabs. AI generation spans get a custom inspector showing the
linked prompt's metadata, input variables, and template content
alongside model, tokens, cost, and the message thread.
See /docs/ai/prompts for the full
reference — template syntax, version resolution order, override
workflow, and type utilities (PromptHandle, PromptIdentifier,
PromptVariables).
Adds onBoot to chat.agent — a lifecycle hook that fires once per
worker process picking up the chat. Runs for the initial run, preloaded
runs, AND reactive continuation runs (post-cancel, crash, endRun,
requestUpgrade, OOM retry), before any other hook. Use it to
initialize chat.local, open per-process resources, or re-hydrate state
from your DB on continuation — anywhere the SAME run picking up after
suspend/resume isn't enough.
(#3543)
const userContext = chat.local<{ name: string; plan: string }>({ id:
"userContext" });
export const myChat = chat.agent({
id: "my-chat",
onBoot: async ({ clientData, continuation }) => {
const user = await db.user.findUnique({ where: { id: clientData.userId }
});
userContext.init({ name: user.name, plan: user.plan });
},
run: async ({ messages, signal }) =>
streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }),
});Use onBoot (not onChatStart) for state setup that must run every time a worker picks up the chat — onChatStart fires once per chat and won't run on continuation, leaving chat.local uninitialized when run() tries to use it. AI Agents — run AI SDK chat completions as durable Trigger.dev agents instead of fragile API routes. Define an agent in one function, point useChat at it from React, and the conversation survives page refreshes, network blips, and process restarts. (#3543) import { chat } from "@trigger.dev/sdk/ai"; import { streamText } from "ai"; import { openai } from "@ai-sdk/openai"; export const myChat = chat.agent({ id: "my-chat", run: async ({ messages, signal }) => streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }), });import { useChat } from "@ai-sdk/react"; import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react"; const transport = useTriggerChatTransport({ task: "my-chat", accessToken, startSession }); const { messages, sendMessage } = useChat({ transport });What you get:
AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.
First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.
Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.
Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.
Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.
Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.
Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.
Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.
Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.
Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.
chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.
Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.
Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.
See /docs/ai-chat for the
full surface — quick start, three backend approaches (chat.agent,
chat.createSession, raw task), persistence and code-sandbox patterns,
type-level guides, and API reference.
Add read primitives to chat.history for HITL flows:
getPendingToolCalls(), getResolvedToolCalls(),
extractNewToolResults(message), getChain(), and
findMessage(messageId). These lift the accumulator-walking logic that
customers building human-in-the-loop tools were re-implementing into the
SDK. (#3543)
Use getPendingToolCalls() to gate fresh user turns while a tool call
is awaiting an answer. Use extractNewToolResults(message) to dedup
tool results when persisting to your own store — the helper returns only
the parts whose toolCallId is not already resolved on the chain.const pending = chat.history.getPendingToolCalls(); if (pending.length > 0) { // an addToolOutput is expected before a new user message } onTurnComplete: async ({ responseMessage }) => { const newResults = chat.history.extractNewToolResults(responseMessage); for (const r of newResults) { await db.toolResults.upsert({ id: r.toolCallId, output: r.output, errorText: r.errorText }); } };Sessions — a durable, run-aware stream channel keyed on a stable
externalId. A Session is the unit of state that owns a multi-run
conversation: messages flow through .in, responses through .out,
both survive run boundaries. Sessions back the new chat.agent runtime,
and you can build on them directly for any pattern that needs durable
bi-directional streaming across runs.
(#3542)
import { sessions, tasks } from "@trigger.dev/sdk";
// Trigger a task and subscribe to its session output in one call
const { runId, stream } = await tasks.triggerAndSubscribe("my-task",
payload, {
externalId: "user-456",
});
for await (const chunk of stream) {
// ...
}
// Enumerate existing sessions (powers inbox-style UIs without a
separate index)
for await (const s of sessions.list({ type: "chat.agent", tag:
"user:user-456" })) {
console.log(s.id, s.externalId, s.createdAt, s.closedAt);
}See /docs/ai-chat/overview for the full surface — Sessions powers the durable, resumable chat runtime described there. Patch Changes Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543) const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.
Add ai.toolExecute(task) so you can wire a Trigger subtask in as the
execute handler of an AI SDK tool() while defining description and
inputSchema yourself — useful when you want full control over the tool
surface and just need Trigger's subtask machinery for the body.
(#3546)
const myTool = tool({
description: "...",
inputSchema: z.object({ ... }),
execute: ai.toolExecute(mySubtask),
});
ai.tool(task) (toolFromTask) keeps doing the all-in-one wrap and now
aligns its return type with AI SDK's ToolSet. Minimum ai peer raised
to ^6.0.116 to avoid cross-version ToolSet mismatches in monorepos.
Stamp gen_ai.conversation.id (the chat id) on every span and metric
emitted from inside a chat.task or chat.agent run. Lets you filter
dashboard spans, runs, and metrics by the chat conversation that
produced them — independent of the run boundary, so multi-run chats
correlate cleanly. No code changes required on the user side.
(#3543)
Type chat.createStartSessionAction against your chat agent so
clientData is typed end-to-end on the first turn:
(#3684)
import { chat } from "@trigger.dev/sdk/ai";
import type { myChat } from "@/trigger/chat";
export const startChatSession = chat.createStartSessionAction("my-chat");
// In the browser, threaded from the transport's typed startSession
callback:
const transport = useTriggerChatTransport({
task: "my-chat",
startSession: ({ chatId, clientData }) => startChatSession({ chatId,
clientData }),
// ...
});ChatStartSessionParams gains a typed clientData field — folded into the first run's payload.metadata so onPreload / onChatStart see the same shape per-turn metadata carries via the transport. The opaque session-level metadata field is unchanged. Unit-test chat.agent definitions offline with mockChatAgent from @trigger.dev/sdk/ai/test. Drives a real agent's turn loop in-process — no network, no task runtime — so you can send messages, actions, and stop signals via driver methods, inspect captured output chunks, and verify hooks fire. Pairs with MockLanguageModelV3 from ai/test for model mocking. setupLocals lets you pre-seed locals (DB clients, service stubs) before run() starts. (#3543) The broader runInMockTaskContext harness it's built on lives at @trigger.dev/core/v3/test — useful for unit-testing any task code, not just chat. Add region to the runs list / retrieve API: filter runs by region (runs.list({ region: "..." }) / filter[region]=<masterQueue>) and read each run's executing region from the new region field on the response. (#3612) Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543) const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.
Updated dependencies:
@trigger.dev/[email protected]
[email protected]
Patch Changes
Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and
any helper scripts/references next to your task code, register it with
skills.define({ id, path }), and the CLI bundles it into the deploy
image automatically — no trigger.config.ts changes. The agent gets a
one-line summary in its system prompt and discovers full instructions on
demand via loadSkill, with bash and readFile tools scoped
per-skill (path-traversal guards, output caps, abort-signal
propagation).
(#3543)
const pdfSkill = skills.define({ id: "pdf-extract", path:
"./skills/pdf-extract" });
chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook pattern — portable across providers. SDK + CLI only for now; dashboard-editable SKILL.md text is on the roadmap. Add TRIGGER_BUILD_SKIP_REWRITE_TIMESTAMP=1 escape hatch for local self-hosted builds whose buildx driver doesn't support rewrite-timestamp alongside push (e.g. orbstack's default docker driver). (#3618) The CLI MCP server's agent-chat tools (start_agent_chat, send_agent_message, close_agent_chat) now run on the new Sessions primitive, so AI assistants driving a chat.agent get the same idempotent-by-chatId, durable-across-runs behavior the browser transport gets. Required PAT scopes go from write:inputStreams to read:sessions + write:sessions. (#3546) MCP list_runs tool: add a region filter input and surface each run's executing region in the formatted summary. (#3612) Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543) const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" }); chat.skills.set([await pdfSkill.local()]);Built on the AI SDK cookbook
pattern — portable
across providers. SDK + CLI only for now; dashboard-editable SKILL.md
text is on the roadmap.
Reject overlong idempotencyKey values at the API boundary so they no
longer trip an internal size limit on the underlying unique index and
surface as a generic 500. Inputs are capped at 2048 characters — well
above what idempotencyKeys.create() produces (a 64-character hash) and
above any realistic raw key. Applies to tasks.trigger,
tasks.batchTrigger, batch.create (Phase 1 streaming batches),
wait.createToken, wait.forDuration, and the input/session stream
waitpoint endpoints. Over-limit requests now return a structured 400
instead.
(#3560)
AI Agents — run AI SDK chat completions as durable Trigger.dev
agents instead of fragile API routes. Define an agent in one function,
point useChat at it from React, and the conversation survives page
refreshes, network blips, and process restarts.
(#3543)
import { chat } from "@trigger.dev/sdk/ai";
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
export const myChat = chat.agent({
id: "my-chat",
run: async ({ messages, signal }) =>
streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }),
});```tsx import { useChat } from "@ai-sdk/react"; import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react"; const transport = useTriggerChatTransport({ task: "my-chat", accessToken, startSession }); const { messages, sendMessage } = useChat({ transport });What you get:
AI SDK useChat integration — a custom
ChatTransport
(useTriggerChatTransport) plugs straight into Vercel AI SDK's
useChat hook. Text streaming, tool calls, reasoning, and data-*
parts all work natively over Trigger.dev's realtime streams. No custom
API routes needed.
First-turn fast path (chat.headStart) — opt-in handler that runs
the first turn's streamText step in your warm server process while the
agent run boots in parallel, cutting cold-start TTFC by roughly half
(measured 2801ms → 1218ms on claude-sonnet-4-6). The agent owns step
2+ (tool execution, persistence, hooks) so heavy deps stay where they
belong. Web Fetch handler works natively in Next.js, Hono, SvelteKit,
Remix, Workers, etc.; bridge to Express/Fastify/Koa via
chat.toNodeListener. New @trigger.dev/sdk/chat-server subpath.
Multi-turn durability via Sessions — every chat is backed by a
durable Session that outlives any individual run. Conversations resume
across page refreshes, idle timeout, crashes, and deploys; resume: true reconnects via lastEventId so clients only see new chunks.
sessions.list enumerates chats for inbox-style UIs.
Auto-accumulated history, delta-only wire — the backend
accumulates the full conversation across turns; clients only ship the
new message each turn. Long chats never hit the 512 KiB body cap.
Register hydrateMessages to be the source of truth yourself.
Lifecycle hooks — onPreload, onChatStart,
onValidateMessages, hydrateMessages, onTurnStart,
onBeforeTurnComplete, onTurnComplete, onChatSuspend,
onChatResume — for persistence, validation, and post-turn work.
Stop generation — client-driven transport.stopGeneration(chatId)
aborts mid-stream; the run stays alive for the next message, partial
response is captured, and aborted parts (stuck partial-call tools,
in-progress reasoning) are auto-cleaned.
Tool approvals (HITL) — tools with needsApproval: true pause
until the user approves or denies via addToolApprovalResponse. The
runtime reconciles the updated assistant message by ID and continues
streamText.
Steering and background injection — pendingMessages injects user
messages between tool-call steps so users can steer the agent
mid-execution; chat.inject() + chat.defer() adds context from
background work (self-review, RAG, safety checks) between turns.
Actions — non-turn frontend commands (undo, rollback, regenerate,
edit) sent via transport.sendAction. Fire hydrateMessages +
onAction only — no turn hooks, no run(). onAction can return a
StreamTextResult for a model response, or void for side-effect-only.
Typed state primitives — chat.local<T> for per-run state
accessible from hooks, run(), tools, and subtasks (auto-serialized
through ai.toolExecute); chat.store for typed shared data between
agent and client; chat.history for reading and mutating the message
chain; clientDataSchema for typed clientData in every hook.
chat.toStreamTextOptions() — one spread into streamText wires
up versioned system Prompts,
model resolution, telemetry metadata, compaction, steering, and
background injection.
Multi-tab coordination — multiTab: true + useMultiTabChat
prevents duplicate sends and syncs state across browser tabs via
BroadcastChannel. Non-active tabs go read-only with live updates.
Network resilience — built-in indefinite retry with bounded
backoff, reconnect on online / tab refocus / bfcache restore,
Last-Event-ID mid-stream resume. No app code needed.
See /docs/ai-chat for the
full surface — quick start, three backend approaches (chat.agent,
chat.createSession, raw task), persistence and code-sandbox patterns,
type-level guides, and API reference.
Stamp gen_ai.conversation.id (the chat id) on every span and metric
emitted from inside a chat.task or chat.agent run. Lets you filter
dashboard spans, runs, and metrics by the chat conversation that
produced them — independent of the run boundary, so multi-run chats
correlate cleanly. No code changes required on the user side.
(#3543)
Fix LocalsKey<T> type incompatibility across dual-package builds.
The phantom value-type brand no longer uses a module-level unique symbol, so a single TypeScript compilation that resolves the type from
both the ESM and CJS outputs (which can happen under certain pnpm
hoisting layouts) no longer sees two structurally-incompatible variants
of the same type.
(#3626)
Unit-test chat.agent definitions offline with mockChatAgent from
@trigger.dev/sdk/ai/test. Drives a real agent's turn loop in-process —
no network, no task runtime — so you can send messages, actions, and
stop signals via driver methods, inspect captured output chunks, and
verify hooks fire. Pairs with MockLanguageModelV3 from ai/test for
model mocking. setupLocals lets you pre-seed locals (DB clients,
service stubs) before run() starts.
(#3543)
The broader runInMockTaskContext harness it's built on lives at
@trigger.dev/core/v3/test — useful for unit-testing any task code, not
just chat.
Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry
policy instead of failing the run on the first segfault. SIGSEGV in Node
tasks is frequently non-deterministic (native addon races, JIT/GC
interaction, near-OOM in native code, host issues), so retrying on a
fresh process often succeeds. The retry is gated by the task's existing
retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and
uncaught exceptions already use — so tasks without a retry policy still
fail fast.
(#3552)
Add region to the runs list / retrieve API: filter runs by region
(runs.list({ region: "..." }) / filter[region]=<masterQueue>) and
read each run's executing region from the new region field on the
response.
(#3612)
Sessions — a durable, run-aware stream channel keyed on a stable
externalId. A Session is the unit of state that owns a multi-run
conversation: messages flow through .in, responses through .out,
both survive run boundaries. Sessions back the new chat.agent runtime,
and you can build on them directly for any pattern that needs durable
bi-directional streaming across runs.
(#3542)
import { sessions, tasks } from "@trigger.dev/sdk";
// Trigger a task and subscribe to its session output in one call
const { runId, stream } = await tasks.triggerAndSubscribe("my-task",
payload, {
externalId: "user-456",
});
for await (const chunk of stream) {
// ...
}
// Enumerate existing sessions (powers inbox-style UIs without a
separate index)
for await (const s of sessions.list({ type: "chat.agent", tag:
"user:user-456" })) {
console.log(s.id, s.externalId, s.createdAt, s.closedAt);
}
Original sourceSee /docs/ai-chat/overview for the full surface — Sessions powers the durable, resumable chat runtime described there. @trigger.dev/[email protected] Patch Changes The public interfaces for a plugin system. Initially consolidated authentication and authorization interfaces. (#3499) Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Add MollifierBuffer and MollifierDrainer primitives for trigger burst smoothing. (#3614) MollifierBuffer (accept, pop, ack, requeue, fail, evaluateTrip) is a per-env FIFO over Redis with atomic Lua transitions for status tracking. evaluateTrip is a sliding-window trip evaluator the webapp gate uses to detect per-env trigger bursts. MollifierDrainer pops entries through a polling loop with a user-supplied handler. The loop survives transient Redis errors via capped exponential backoff (up to 5s), and per-env pop failures don't poison the rest of the batch — one env's blip is logged and counted as failed for that tick. Rotation is two-level: orgs at the top, envs within each org. The buffer maintains mollifier:orgs and mollifier:org-envs:${orgId} atomically with per-env queues, so the drainer walks orgs → envs directly without an in-memory cache. The maxOrgsPerTick option (default 500) caps how many orgs are scheduled per tick; for each picked org, one env is popped (rotating round-robin within the org). An org with N envs gets the same per-tick scheduling slot as an org with 1 env, so tenant-level drainage throughput is determined by org count rather than env count. Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Updated dependencies: @trigger.dev/[email protected] @trigger.dev/[email protected] Patch Changes Updated dependencies: @trigger.dev/[email protected] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
build-supervisor-wide-events.rc3
Trigger.dev forwards Baggage outbound on compute calls.
feat(supervisor): forward Baggage outbound on compute calls
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
build-supervisor-wide-events.rc2
Trigger.dev refactors Supervisor State with first-class op and kind support.
refactor(supervisor): op + kind first-class on State
Original source - May 20, 2026
- Date parsed from source:May 20, 2026
- First seen by Releasebot:May 22, 2026
build-supervisor-wide-events.rc1
Trigger.dev adds wide events on snapshot lifecycle.
feat(supervisor): wide events on snapshot lifecycle
Original source - May 19, 2026
- Date parsed from source:May 19, 2026
- First seen by Releasebot:May 19, 2026
build-supervisor-wide-events.rc0
Trigger.dev fixes supervisor event review issues and adds a noisy-routes flag.
fix(supervisor): wide-event review fixes + noisy-routes flag + socket…
Original source - May 17, 2026
- Date parsed from source:May 17, 2026
- First seen by Releasebot:May 17, 2026
build-realtimestreams-dedupe: fix(webapp): dedupe realtimeStreams array push on stream create
Trigger.dev fixes a task run stream update bug to prevent duplicate realtime stream entries and hot-looped writes.
The PUT handler unconditionally appended streamId to TaskRun.realtimeStreams on every call, so repeat inits for the same (run, streamId) hot-looped a row UPDATE and bloated the array. Read first and only push when the streamId isn't already present, matching the existing append handler.
Original source - May 12, 2026
- Date parsed from source:May 12, 2026
- First seen by Releasebot:May 12, 2026
trigger.dev v4.4.6
Trigger.dev ships v4.4.6 with faster failure handling for uncaught exceptions and fixes a dev worker CPU spin issue after CLI disconnects, improving reliability for self-hosted and local development workflows.
trigger.dev v4.4.6
Upgrade
npx trigger.dev@latest update # npm pnpm dlx trigger.dev@latest update # pnpm yarn dlx trigger.dev@latest update # yarn bunx trigger.dev@latest update # bun Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.4.6Release notes
Read the full release notes: https://trigger.dev/changelog/v4-4-6
What's changed
ImprovementsFail attempts on uncaught exceptions instead of hanging to MAX_DURATION_EXCEEDED. A Node EventEmitter (e.g. node-redis) emitting "error" with no .on("error", ...) listener escalates to uncaughtException, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status FAILED, and respect the task's normal retry policy. You should still attach .on("error", ...) listeners to long-lived clients to handle errors gracefully. (#3529)
Bug fixesFix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned trigger-dev-run-worker (and indexer) processes were caught in an uncaughtException feedback loop: a periodic IPC send via process.send would throw ERR_IPC_CHANNEL_CLOSED once the parent closed the channel, which re-entered the same handler that itself called process.send, scheduled via setImmediate and amplified by source-map-support's prepareStackTrace. Fixed by (1) silently dropping packets in ZodIpcConnection when the channel is disconnected, (2) adding a process.on("disconnect", ...) handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all uncaughtException-path process.send calls in a safeSend guard that checks process.connected and swallows synchronous throws. (#3491)
All packages: v4.4.6
@trigger.dev/build, @trigger.dev/core, @trigger.dev/python, @trigger.dev/react-hooks, @trigger.dev/redis-worker, @trigger.dev/rsc, @trigger.dev/schema-to-json, @trigger.dev/sdk, trigger.dev
Contributors
Eric Allam, @nicktrn, James Ritchie, @isshaddad, @d-cs, github-actions[bot], Matt Aitken, Saadi Myftija, Oskar Otwinowski
Full changelog: v4.4.5...v4.4.6
Original source
Curated by the Releasebot team
Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.
Similar to Trigger.dev with recent updates:
- Smokeball release notes125 release notes · Latest May 13, 2026
- Cosmolex release notes20 release notes · Latest Jul 30, 2025
- PracticePanther release notes34 release notes · Latest Apr 8, 2026
- Salesforce release notes14 release notes · Latest May 1, 2026
- Microsoft release notes569 release notes · Latest May 28, 2026
- Zoom release notes145 release notes · Latest May 18, 2026