Skip to content

trigger.dev v4.8.0

Choose a tag to compare

@github-actions github-actions released this 23 Oct 10:03
· 14 commits to main since this release
1ca7cfd

trigger.dev v4.8.0

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

Release notes

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

What's changed

Improvements

  • Route verified webhooks into agent sessions with chat.event({ endpoint, key }), and connect external chat surfaces with chat.channels.custom({ endpoint }). Both subscribe to a shared webhook endpoint, so an agent and your other webhook tasks can use the same provider URL. Channels support reply delivery, session binding, conversation seeding, and lifecycle reactions, and a failed turn posts a short line instead of the error (errorMessage sets it, as a string or a function of the failure). Use chat.createWatchToken() to watch a session from another surface. (d6955ee9f)

    A connector can also stream replies natively (stream()), mirror the session's state into the surface (lifecycle()), show tool calls as they run (progress()), stop a running turn from the surface (onControl()), post approvals and tool controls and resume the run from a verified click, download files only the surface can read (download()), and acknowledge or fold in messages that arrive mid-turn (received(), pendingMessages).

  • Add hosted webhooks: declare an endpoint once with webhooks.endpoint.define({ id, source }) and Trigger.dev hosts its URL, verifies every request, and routes each event to the endpoint's subscribers. Subscribe tasks with webhook({ endpoint, filter, onEvent }), each with its own type-safe filter, and pause a run until a matching webhook arrives with webhooks.waiter.create() and webhooks.waiter.wait(). (d6955ee9f)

    export const stripe = webhooks.endpoint.define({
    id: "stripe",
    source: webhooks.stripe(),
    });
    
    export const fulfill = webhook({
    id: "fulfill",
    endpoint: stripe,
    filter: "event.type == 'checkout.session.completed'",
    onEvent: async ({ event }) => {},
    });
    
    const waiter = await webhooks.waiter.create(stripe, {
    match: { "event.data.object.metadata.orderId": order.id },
    });
    const { event } = await webhooks.waiter.wait(waiter).unwrap();

    Sources cover presets (webhooks.stripe(), webhooks.github(), webhooks.svix(), webhooks.discord(), and others), named providers (webhooks.clerk(), webhooks.shopify(), and more) and webhooks.custom<T>(config), and most carry a setup prompt an AI coding agent can follow to register the endpoint. Retries are deduplicated on the provider's own event or delivery id where it sends one. Filters, keys and waiter match paths share the event., header. and webhook. namespaces, and filters accept == null / != null presence checks and event any (...) over a payload that is an array of events. webhook() takes task() options such as queue, machine and retry. The HTTP API lists endpoints and deliveries, replays deliveries, and creates and cancels waiters, and both it and the MCP server can read an endpoint's setup prompt and generate or store its signing secret.

  • The generate_webhook_secret and set_webhook_secret MCP tools take an optional previousSecretTtlSeconds to keep accepting a webhook endpoint's old signing secret while the provider switches to the new one (up to 7 days), and report when the old secret stops working. (98adb6662)

  • Realtime streams now reconnect and resume when the stream backend reports a failed read mid-stream, instead of ending early as if the stream had finished. This affects runs.subscribeToRun with streams, useRealtimeRunWithStreams, and chat streams. (23730b034)

  • HMAC webhook verifier configs accept additionalSignatureHeaders: more headers that can carry a signature, matched as alternatives to signatureHeader. Providers that send a second signature during a secret rotation (Hookdeck's x-hookdeck-signature-2) keep verifying through the rotation. (08d1ddbd3)

  • Add webhooks.hookdeck(), a source for deliveries relayed through a Hookdeck connection. It verifies the x-hookdeck-signature header with the project's signing secret, keeps verifying while the secret is being rolled (Hookdeck sends the previous secret's signature in x-hookdeck-signature-2), and deduplicates retries on x-hookdeck-eventid. The event is the original provider's payload, so pass its type: webhooks.hookdeck<Stripe.Event>(). If the Hookdeck project's header prefix was changed, pass it as webhooks.hookdeck({ headerPrefix }) so retries keep deduplicating. (51b39fbc6)

  • Add @trigger.dev/linear: turn a chat.agent into a Linear agent. Assign it an issue or @mention it, and Linear's agent session becomes a durable Trigger.dev session: the reply posts back to Linear, tool calls show as activities, linearPlanTool() keeps the plan Linear shows as a checklist, and approvals are Approve and Deny options that resume the run. (1586c4a3f)

    import { linear, webhookSource } from "@trigger.dev/linear";
    
    const linearEvents = webhooks.endpoint.define({
    id: "linear",
    source: webhookSource(),
    });
    
    export const triage = chat.agent({
    id: "triage",
    channels: [
      linear({
        id: "linear",
        endpoint: linearEvents,
        token: process.env.LINEAR_ACCESS_TOKEN!,
      }),
    ],
    run: async ({ messages, signal, streamText }) =>
      streamText({ model, messages, abortSignal: signal }),
    });

    The first turn gets the issue's context and earlier comments, images and PDFs in the issue reach the model, a Stop in Linear winds the turn down, and errorMessage sets the text a failed turn shows.

  • Add @trigger.dev/slack: turn a chat.agent into a native Slack agent. Each DM or channel thread is a durable session, the reply streams into the thread with the turn's tool calls shown as a plan, approvals are Approve and Deny buttons, and Slack's stop button stops the turn. (6e715da77)

    import { appMentions, slack, webhookSource } from "@trigger.dev/slack";
    
    const slackEvents = webhooks.endpoint.define({
    id: "slack",
    source: webhookSource(),
    });
    
    export const support = chat.agent({
    id: "support",
    channels: [
      slack({
        id: "slack",
        endpoint: slackEvents,
        token: process.env.SLACK_BOT_TOKEN!,
        startOn: appMentions(),
      }),
    ],
    run: async ({ messages, signal, streamText }) =>
      streamText({ model, messages, abortSignal: signal }),
    });

    startOn decides which channel messages start a session (appMentions() answers when the agent is @mentioned). Images and PDFs people share reach the model, messages sent while the agent is answering can be folded into the reply, tools can post their own buttons, and ownWorkspaceOnly ignores Slack Connect guests.

  • The streamText passed to a chat.agent's run() now turns AI SDK telemetry on by default, so each model step and tool call shows up as a span in the run trace even when the agent doesn't store a prompt with chat.prompt.set(). An agent with telemetry: { recordUserMessage: false } gets these spans without prompt and response content, including when it stores a prompt (whose variables are left out of the span metadata). Pass experimental_telemetry: { isEnabled: false } at the call site to turn them off, or recordInputs: false / recordOutputs: false to keep them without content. (bd7cc3525)

Server changes

These changes affect the self-hosted Docker image and Trigger.dev Cloud:

  • When regenerating an environment's API key you can now revoke the previous key immediately instead of keeping it working for 24 hours. Use this when a key may have leaked.
  • Set KUBERNETES_POD_RESERVED_SOURCE_PORTS on the supervisor (for example 50080,50081) to stop runs using those ports for outbound connections, which is useful to avoid port clashes.
  • Rotating a webhook endpoint's signing secret can keep the old one valid for a while, so you can rotate without failing deliveries that are still signed with it. The rotate and regenerate dialogs let you choose how long the old secret stays valid (up to 7 days, 24 hours by default). The rotate-secret and secret endpoints accept an optional previousSecretTtlSeconds and return previousSecretExpiresAt. With no value, the old secret stops working immediately, as before.
  • Alerts are now checked every minute instead of every 5–10 minutes, so they raise and recover sooner.
  • Run traces and trace APIs load faster for older runs.
  • The API keys page now always lists your root API key, masked to its last 4 characters when it's hidden, so you can regenerate it and revoke the previous key. When the root key is hidden, the page points you to creating an API key for your backend.
  • Runs whose deployment has no compute template now go to containers when they are triggered, instead of first passing through the compute worker queue.
  • Runs now get a TRIGGER_DASHBOARD_URL environment variable with the dashboard's address, so a task can link to its run (${TRIGGER_DASHBOARD_URL}/runs/${ctx.run.id}) on any Trigger.dev instance. A TRIGGER_DASHBOARD_URL you set on the project still wins.
  • Creating an alert works without the dashboard agent.
  • Small fixes to creating and editing alerts.
  • Alerts sent to Slack channels connected through a removed Slack installation deliver again.
  • The supervisor no longer trusts certificates issued under the compromised emSign (eMudhra) certificate authorities.

All packages: v4.8.0

@trigger.dev/build, @trigger.dev/core, @trigger.dev/linear, @trigger.dev/python, @trigger.dev/react-hooks, @trigger.dev/redis-worker, @trigger.dev/rsc, @trigger.dev/schema-to-json, @trigger.dev/sdk, @trigger.dev/slack, trigger.dev

Contributors

Eric Allam, Chris Arderne, triggerdotdev-the-inspector[bot], @nicktrn, @Mariefay, Wes Mason, @d-cs, @isshaddad, Katia Bulatova, Oskar Otwinowski, Saadi Myftija, github-actions[bot], João Dias, mintlify[bot], pullfrog[bot], James Ritchie, @D-K-P, claude[bot], @jack, Matt Aitken, @brentshulman-silkline

Full changelog: v4.7.0...v4.8.0