Skip to content

Releases: triggerdotdev/trigger.dev

trigger.dev v4.5.0

Choose a tag to compare

@github-actions github-actions released this 02 Jul 10:32
86ef3c4

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.5.0

Release notes

Read the full release notes: https://trigger.dev/changelog/v4-5-0

What's changed

AI Agents (chat.agent)

Run Vercel AI SDK chat completions as durable Trigger.dev tasks instead of fragile API routes. A conversation runs as one long-lived task keyed on chatId, so it survives page refreshes, network blips, redeploys, and crashes, and every turn is a span in the dashboard.

import { chat } from "@trigger.dev/sdk/ai";
import { streamText, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";

export const myChat = chat.agent({
  id: "my-chat",
  run: async ({ messages, signal }) => {
    return streamText({
      ...chat.toStreamTextOptions(), // system prompt, compaction, steering, telemetry
      model: anthropic("claude-sonnet-4-5"),
      messages,
      abortSignal: signal,
      stopWhen: stepCountIs(15),
    });
  },
});

Sessions

The durable primitive underneath chat.agent, usable on its own: a run-aware, bidirectional stream channel keyed on a stable externalId whose .in / .out streams survive run boundaries (suspend, crash, idle-timeout, redeploy). One Session spans many runs, which makes it a good fit for agent inboxes and approval flows.

import { sessions } from "@trigger.dev/sdk";

// Create the session and trigger its first run (idempotent on externalId)
await sessions.start({
  type: "inbox",
  externalId: userId,
  taskIdentifier: "inbox-agent",
});

const session = sessions.open(userId);
await session.in.send({ text: "hello" });

const stream = await session.out.read({ signal: AbortSignal.timeout(30_000) });
for await (const chunk of stream) console.log(chunk); // durable across run swaps

AI Prompts

Define prompt templates as code, versioned on every deploy, and override the text or model from the dashboard without redeploying (environment-scoped). Each generation links back to its prompt version for usage, cost, and latency.

import { prompts } from "@trigger.dev/sdk";
import { z } from "zod";

export const supportPrompt = prompts.define({
  id: "customer-support",
  model: "gpt-4o",
  variables: z.object({ customerName: z.string(), issue: z.string() }),
  content: `You are a support agent for Acme.
Customer: {{customerName}}
Issue: {{issue}}`,
});

// Honors any active dashboard override, else the current deployed version
const resolved = await supportPrompt.resolve({ customerName: "Alice", issue: "Can't log in" });
// resolved.text, resolved.model, resolved.version

useChat integration

useTriggerChatTransport is a Vercel AI SDK ChatTransport that runs useChat over Trigger.dev realtime with no API routes. Text, tool calls, reasoning, and data-* parts stream natively, and it works with AI SDK v5, v6, and now v7.

First-turn fast path (chat.headStart)

Runs the first turn in your warm server process while the agent boots in parallel, cutting cold-start time-to-first-chunk roughly in half (measured ~2.8s to ~1.2s). Available via the new @trigger.dev/sdk/chat-server subpath.

Human-in-the-loop, stop, and steering

The agent control surface: tool approvals (needsApproval + addToolApprovalResponse), client-driven stop-generation, mid-execution steering (pendingMessages), and between-turn context injection (chat.inject / chat.defer), all durable across the conversation.

Agent Skills

skills.define({ id, path }) bundles a SKILL.md folder into your deploy image. The agent gets a one-line summary up front and loads the full instructions plus scoped bash / readFile tools on demand (progressive disclosure), so a capability is something the model reaches for rather than a pre-declared typed tool.

trigger skills for coding assistants

trigger skills installs version-pinned Trigger.dev skills plus a bundled docs snapshot into Claude Code, Cursor, GitHub Copilot, and Codex, so your assistant's Trigger.dev knowledge stays current with your installed SDK version. trigger init now offers to set up the MCP server and skills too.

Model library

A new Models page in the dashboard: a catalog of models grouped by provider with context window, capabilities, and input / output pricing per 1M tokens, plus a "Your models" tab showing per-model usage, cost, and cache-hit sparklines from your actual traffic.

Dev branches

Run multiple local trigger dev sessions in parallel (separate git worktrees or coding agents) without runs colliding, each isolated with its own dashboard, via trigger dev --branch <name>.

TriggerClient

An instantiable client so one process can trigger and read across projects, environments, and preview branches, each with its own auth and baseURL, with no shared global state.

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", { to: "user@example.com" });
await preview.runs.list({ status: ["COMPLETED"] });

SDK and runtime

  • AI SDK 7 support (v5 and v6 still supported), with OpenTelemetry telemetry auto-wired
  • Large trigger-payload offload: trigger payloads at or above 128KB upload to object storage automatically, using the same auth and baseURL as the trigger call
  • Region support on the runs API: filter runs by region and read each run's executing region (also on MCP list_runs)
  • Duplicate task-id detection: dev and deploy fail with a clear error instead of silently overwriting
  • envvars.upload gains an isSecret flag to import redacted secret variables
  • Retry hardening: TASK_MIDDLEWARE_ERROR now retries under the task's retry policy

All packages: v4.5.0

@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

Full changelog: v4.4.0...v4.5.0

trigger.dev v4.5.0-rc.7

Pre-release

Choose a tag to compare

@github-actions github-actions released this 17 Jun 12:19
015106d

Upgrade

npx trigger.dev@4.5.0-rc.7 update
pnpm dlx trigger.dev@4.5.0-rc.7 update
yarn dlx trigger.dev@4.5.0-rc.7 update 
bunx trigger.dev@4.5.0-rc.7 update

Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.7

Improvements

  • @trigger.dev/sdk now bundles the Trigger.dev agent skills and a curated snapshot of the docs those skills reference. The skills that trigger skills installs into your coding agent read this content from node_modules, so the guidance your AI assistant follows is pinned to the SDK version installed in your project and stays current across upgrades instead of going stale until the next reinstall. (#3937)

  • Running a CLI command like dev, deploy, preview, or update before initializing a project no longer crashes with a raw Cannot find matching package.json stack trace. The CLI now detects the missing project and points you to npx trigger.dev@latest init instead. (#3929)

  • The agent skills installed by trigger skills are now namespaced with a trigger- prefix (e.g. trigger-authoring-tasks, trigger-getting-started) so they don't collide with unrelated skills in your coding agent's skills directory. Adds a trigger-cost-savings skill for auditing and reducing compute spend (right-sizing machines, maxDuration, batching, debounce), and @trigger.dev/sdk now bundles the full Trigger.dev documentation so your agent can read the complete, version-pinned reference directly from node_modules. (#3970)

  • The run span API response now includes cachedCost and cacheCreationCost on the ai object, alongside the existing inputCost / outputCost / totalCost. inputCost reflects only the non-cached input, so these fields let you reconstruct the full cost breakdown for prompt-cached calls. (#3958)

  • chat.headStart now works with the chat.customAgent and chat.createSession backends, not only chat.agent. The warm step-1 response hands over to your loop the same way it does for a managed agent. (#3963)

    In a chat.customAgent loop, consume the handover on turn 0:

    const conversation = new chat.MessageAccumulator();
    const { isFinal, skipped } = await conversation.consumeHandover({ payload });
    if (skipped) return; // warm handler aborted, so exit without a turn
    if (isFinal) {
      await chat.writeTurnComplete(); // step 1 is the response, no streamText
    } else {
      const result = streamText({ model, messages: conversation.modelMessages, tools });
      // Pass originalMessages so the handed-over tool round merges into the
      // step-1 assistant instead of starting a new message.
      const response = await chat.pipeAndCapture(result, {
        originalMessages: conversation.uiMessages,
      });
      if (response) await conversation.addResponse(response);
    }

    With chat.createSession, the iterator surfaces it as turn.handover; call turn.complete() with no argument on a final handover. The lower-level chat.waitForHandover() and accumulator.applyHandover() are also exported for hand-rolled loops.

  • Cache your chat agent's system prompt with Anthropic prompt caching. chat.toStreamTextOptions() now emits the system prompt as a cacheable message when you opt in, so a large, stable system block is billed at cache-read rates on every turn instead of full price. (#3952)

    // at the streamText call site (Anthropic sugar)
    streamText({
      ...chat.toStreamTextOptions({ cacheControl: { type: "ephemeral" } }),
      messages,
    });
    
    // provider-agnostic equivalent
    chat.toStreamTextOptions({
      systemProviderOptions: { anthropic: { cacheControl: { type: "ephemeral" } } },
    });
    
    // or where the prompt is defined
    chat.prompt.set(SYSTEM_PROMPT, {
      providerOptions: { anthropic: { cacheControl: { type: "ephemeral" } } },
    });

    Without an option, system stays a plain string. Pairs with a prepareMessages cache breakpoint to cache the conversation prefix across turns too.

  • Three fixes for custom agent loops (chat.customAgent, chat.createSession, and hand-rolled MessageAccumulator loops): (#3936)

    • Continuation runs no longer replay already-answered user messages into the first turn. The .in resume cursor is now seeded before any listener attaches (the same boot logic chat.agent uses), so a chat that continues after a cancel, crash, or upgrade only sees genuinely new messages.
    • Steering a hand-rolled loop mid-stream no longer wipes the in-flight assistant response. chat.pipeAndCapture now stamps a server-generated message id on the stream, so a prepareStep injection keeps the partial text instead of replacing the message.
    • Task-backed tools (ai.toolExecute) now work from custom agent loops: the parent's session is threaded to the child run, so child tasks can stream progress into the chat with chat.stream.writer({ target: "root" }) instead of failing with "session handle is not initialized".

All packages: v4.5.0-rc.7

@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

Full changelog: v4.4.0.7...v4.5.0-rc.7

trigger.dev v4.5.0-rc.6

Pre-release

Choose a tag to compare

@github-actions github-actions released this 12 Jun 15:52
5fab8ca

Upgrade

npx trigger.dev@4.5.0-rc.6 update
pnpm dlx trigger.dev@4.5.0-rc.6 update
yarn dlx trigger.dev@4.5.0-rc.6 update 
bunx trigger.dev@4.5.0-rc.6 update

Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.6

chat.agent Improvements

  • Reliability fixes for chat.agent. A user message sent while the agent is streaming is no longer delivered twice (which could run a duplicate turn), input appends now carry an idempotency key so a retried send can't duplicate a message, stopping a generation clears the streaming state so a page reload doesn't replay the stopped turn, and runs can now carry the full set of dashboard tags instead of being silently truncated. onTurnComplete now fires on errored turns (with the thrown error attached) and the failed turn's user message is persisted so it isn't lost on the next run. Custom agents and manual chat.writeTurnComplete callers now trim the output stream, sending a custom action no longer leaves a second stream reader running, and a long-lived watch subscription no longer grows its dedupe set without bound. (#3891)
  • Continuation chat boots no longer stall for around 10 seconds before the first turn. The session.in resume cursor is now found with a non-blocking records read instead of draining an SSE long-poll (which always waited out its full 5 second inactivity window, twice per boot), the boot reads run concurrently, and chat snapshots carry the cursor so subsequent boots skip the scan entirely. (#3907)
  • Fix two chat.createSession() bugs: stopping a generation no longer wedges the run (the turn loop raced a totalUsage promise that never settles after a stop-abort), and continuation runs now wait for the next message instead of invoking the model with an empty prompt. (#3920)

Other improvements and fixes

  • trigger init now sets up your AI coding assistant as part of project setup: pick the MCP server, the agent skills, or both, then scaffold with the CLI or hand off to your assistant. Adds a new getting-started agent skill that teaches assistants how to bootstrap Trigger.dev (install the SDK, write trigger.config.ts, create a first task, run trigger dev), so the AI-driven setup path works end to end. It ships in the CLI alongside the existing skills, version-matched to your SDK. (#3872)
  • dev and deploy now fail with a clear error when two tasks are defined with the same id, including across different task types (e.g. a scheduled task and a regular task sharing an id). Previously the second definition silently overwrote the first, so one of the tasks would vanish with no warning. Task ids are detected as duplicates during indexing (naming each offending id and the files it was found in), and the same rule is enforced server-side when the background worker is registered. (#3865)
  • trigger skills installs Trigger.dev agent skills into your coding agent so it knows how to write tasks, schedules, realtime, and chat.agent code. The skills ship with the CLI and are copied into each tool's native skills directory (Claude Code, Cursor, GitHub Copilot, and Codex / AGENTS.md), and trigger dev offers to install them on first run. (#3868)

All packages: v4.5.0-rc.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

Full changelog: v4.4.0.6...v4.5.0-rc.6

trigger.dev v4.5.0-rc.5

Pre-release

Choose a tag to compare

@github-actions github-actions released this 05 Jun 13:14
a730faa

Upgrade

npx trigger.dev@4.5.0-rc.5 update
pnpm dlx trigger.dev@4.5.0-rc.5 update
yarn dlx trigger.dev@4.5.0-rc.5 update 
bunx trigger.dev@4.5.0-rc.5 update

Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.5

Highlights

  • Adds AI SDK 7 support. The ai peer range now includes v7, and the chat.agent / chat surfaces work against v7's ESM-only build. On v7, install @ai-sdk/otel alongside ai and the SDK registers it for you so experimental_telemetry spans keep flowing into your run traces (v7 stopped emitting them from ai core). v5 and v6 keep working unchanged. (#3833)
  • useTriggerChatTransport now recovers when restored session state points at a session that no longer exists in the current environment (#3816)

Improvements

  • The MCP server no longer tells the AI agent to wait for a run to complete after every trigger_task call. Waiting is now opt-in: the agent only waits when you ask it to (for example "trigger and then wait for it to finish"). This avoids burning tokens polling runs you didn't need to block on and keeps responses clearer. (#3838)
  • Update the bundled OpenTelemetry packages to their latest releases (@opentelemetry/sdk-node 0.218.0, @opentelemetry/core 2.7.1, @opentelemetry/host-metrics 0.38.3). (#3810)
  • envvars.upload now accepts an optional isSecret flag, letting you create the imported variables as secret (redacted) environment variables. When omitted, variables default to non-secret. (#3809)
  • Offload large trigger payloads to object storage before sending the trigger API request. The SDK uploads packets at or above the existing 128KB limit and sends an application/store pointer instead of embedding large JSON in the request body. TriggerTaskRequestBody now validates that application/store payloads are non-empty storage paths. (#3785)

Bug fixes

  • Fix @trigger.dev/core build: cast the underlying log record exporter when calling forceFlush so it typechecks against the updated OpenTelemetry LogRecordExporter type (which no longer declares forceFlush). (#3829)

All packages: v4.5.0-rc.5

@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.5...v4.5.0-rc.5

trigger.dev v4.5.0-rc.4

Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Jun 08:55
e0681d2

Upgrade

npx trigger.dev@4.5.0-rc.1 update
pnpm dlx trigger.dev@4.5.0-rc.1 update
yarn dlx trigger.dev@4.5.0-rc.1 update 
bunx trigger.dev@4.5.0-rc.1 update

Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.4

Highlights

  • Add a tools option to chat.agent. Declaring your tools here threads them into the SDK's internal convertToModelMessages, so each tool's toModelOutput is re-applied when prior-turn history is re-converted. (#3790)

Improvements

  • Bump @s2-dev/streamstore to 0.22.10 to fix a TASK_RUN_UNCAUGHT_EXCEPTION ("Invalid state: Unable to enqueue") when a chat.agent turn is aborted mid-stream. (#3792)
  • Coerce numeric concurrencyKey values to string at the API boundary across tasks.trigger, tasks.batchTrigger, and the Phase-2 streaming batch endpoint. (#3789)

All packages: v4.5.0-rc.4

@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.5.0-rc.3...v4.5.0-rc.4

trigger.dev v4.5.0-rc.3

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Jun 09:40
8f066ac

trigger.dev v4.5.0-rc.3

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.5.0-rc.3

Release notes

Read the full release notes: https://trigger.dev/changelog/v4-5-0-rc-3

What's changed

Improvements

  • Retry TASK_MIDDLEWARE_ERROR under the task's retry policy instead of failing the run on the first attempt. The error was already classified as retryable by shouldRetryError, but shouldLookupRetrySettings did not include it, so the retry flow fell through to fail_run. Fixes #3231. (#3676)

Bug fixes

  • Fix TypeError in unflattenAttributes when the input attribute map contains conflicting dotted key paths (e.g. both a.b set to a scalar and a.b.c set to a value). The path-walk loop now applies last-write-wins when a prior key wrote a primitive, null, or array at an intermediate slot, matching the existing precedent in AttributeFlattener.addAttribute. Callers no longer crash when handed malformed external attribute inputs. (#3762)
  • Fix external trace context leaking across runs on warm-started workers with processKeepAlive enabled. Every subsequent run's attempt span was being exported with the first run's traceId and parentSpanId, breaking causal-chain navigation in external APM tools. Runs without an external trace context are unaffected. (#3768)

All packages: v4.5.0-rc.3

@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.3...v4.5.0-rc.3

trigger.dev v4.5.0-rc.2

Pre-release

Choose a tag to compare

@github-actions github-actions released this 23 May 16:20
d34014d

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  # bun

Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.2

Release 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

trigger.dev v4.5.0-rc.1

Pre-release

Choose a tag to compare

@github-actions github-actions released this 21 May 15:46
0b5b817

Upgrade

npx trigger.dev@4.5.0-rc.1 update
pnpm dlx trigger.dev@4.5.0-rc.1 update
yarn dlx trigger.dev@4.5.0-rc.1 update 
bunx trigger.dev@4.5.0-rc.1 update

Self-hosted Docker image: ghcr.io/triggerdotdev/trigger.dev:v4.5.0-rc.1

Release 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

trigger.dev v4.5.0-rc.0

Pre-release

Choose a tag to compare

@github-actions github-actions released this 21 May 13:47
acfba02

Upgrade

npx trigger.dev@4.5.0-rc.0 update
pnpm dlx trigger.dev@4.5.0-rc.0 update
yarn dlx trigger.dev@4.5.0-rc.0 update 
bunx trigger.dev@4.5.0-rc.0 update

Self-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 APIprompt.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 integrationchat.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 SDKprompts.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 hooksonPreload, 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 injectionpendingMessages 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 primitiveschat.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 coordinationmultiTab: 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.
  • **Mul...
Read more

trigger.dev v4.4.6

Choose a tag to compare

@github-actions github-actions released this 12 May 10:38
41a486e

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.6

Release notes

Read the full release notes: https://trigger.dev/changelog/v4-4-6

What's changed

Improvements

  • Fail 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 fixes

  • Fix 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