# @trigger.dev/sdk ## 4.8.3 ### Patch Changes - Fix reloading a chat mid-turn after its access token was refreshed. A token refresh during a streaming turn persisted a resume cursor from the middle of the turn, so a reload resumed past chunks the page needed and failed to rebuild the assistant message ("No tool invocation found for tool call ID"). The persisted cursor now stays at the start of the turn until it completes, so a reload replays the whole turn. ([`9fd1de656`](https://github.com/triggerdotdev/trigger.dev/commit/9fd1de656eb9f96968f43525966a4cc8f5f71348)) - Add private-beta OIDC authentication for deployed Cloud tasks, with an AWS credential provider and environment-specific setup instructions. Install `@aws-sdk/client-sts` to use `@trigger.dev/sdk/oidc/aws`, upgrade your deployment CLI, and redeploy. Contact us to enable access for your organization. ([`65352bc90`](https://github.com/triggerdotdev/trigger.dev/commit/65352bc90aff3788f466569997f2f6a24229ff5a)) - Updated dependencies: - `@trigger.dev/core@4.8.3` ## 4.8.2 ### Patch Changes - Fix `chat.inject` messages added from a tool mid-turn being saved before the assistant's response. They now stay after the tool result, where the model saw them, so the next turn keeps the same prompt prefix. If you roll `@trigger.dev/sdk` back to an earlier version, chats saved by this version lose these mid-turn `chat.inject` messages from the model's context, though the chat history shown in the UI keeps them. ([`fc33769a5`](https://github.com/triggerdotdev/trigger.dev/commit/fc33769a559a69cae687354413b2316bf9fd0bf3)) - The bundled `trigger-cost-savings` skill now notes that a webhook delivery starts no run when no subscriber's filter matches, so it costs no compute. ([#5051](https://github.com/triggerdotdev/trigger.dev/pull/5051)) - Stream a sub-agent's reply through a parent tool call with `chat.forwardSubAgent`. Each chunk is written to the parent chat once and the tool resolves with the sub-agent's final message, so streaming a sub-agent costs bytes in proportion to its reply. Yielding `stream.messages()` snapshots resends the whole message on every chunk, which grows with the square of the reply. ([`bdc994c4d`](https://github.com/triggerdotdev/trigger.dev/commit/bdc994c4d3f80d047b4d0a830cca81330912f8c2)) ```ts execute: async ({ topic }, { toolCallId, abortSignal }) => { const stream = await researcher.sendMessage(topic, { abortSignal }); return await chat.forwardSubAgent(stream, { toolCallId }); }, ``` Render it while it runs with `useSubAgentMessages()` from `@trigger.dev/sdk/chat/react` (or `createSubAgentMessages()` outside React). - Fix a `chat.agent` turn failing after a head start that ended with two or more parallel tool calls. When those tools finished out of call order, the agent sent their results to the model twice on the next step, and the provider rejected the request (Anthropic: "each tool_use must have a single result"). Each handed-over tool result is now sent once. ([`d06ee5825`](https://github.com/triggerdotdev/trigger.dev/commit/d06ee5825baf1d92202604f4ebc1107a01a1aad6)) - Use short-lived run tokens for supported SDK operations inside deployed tasks when available, retaining environment-key compatibility for unsupported operations and missing or expired tokens. Explicit credentials still take precedence. Public-token helpers use server-side minting with run tokens rather than signing locally. ([`5a1c14239`](https://github.com/triggerdotdev/trigger.dev/commit/5a1c14239bcedf85570c8392835bda07482e222e)) Project and organization queries, and branch overrides targeting another PREVIEW or DEVELOPMENT environment, keep using compatibility credentials. Branch headers do not change credential selection in STAGING or PRODUCTION. Chat subscriptions reread implicit credentials for each connection. - Updated dependencies: - `@trigger.dev/core@4.8.2` ## 4.8.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.8.1` ## 4.8.0 ### Minor Changes - 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`](https://github.com/triggerdotdev/trigger.dev/commit/d6955ee9f31b0b1a3af55bb8fbbc77ba68bcb3f7)) 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`](https://github.com/triggerdotdev/trigger.dev/commit/d6955ee9f31b0b1a3af55bb8fbbc77ba68bcb3f7)) ```ts 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(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. - 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`](https://github.com/triggerdotdev/trigger.dev/commit/6e715da7709c48eedd134d52645d825b3569e0ff)) ```ts 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. - 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`](https://github.com/triggerdotdev/trigger.dev/commit/1586c4a3f7638837a0615453f6e5b5d9b92491a4)) ```ts 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. ### Patch Changes - 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`](https://github.com/triggerdotdev/trigger.dev/commit/bd7cc35252d25223859a3e8f696de05cc6527bc7)) - 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()`. If the Hookdeck project's header prefix was changed, pass it as `webhooks.hookdeck({ headerPrefix })` so retries keep deduplicating. ([`51b39fbc6`](https://github.com/triggerdotdev/trigger.dev/commit/51b39fbc6ff0eeeda78fd292d974e7aaa747a086)) - Updated dependencies: - `@trigger.dev/core@4.8.0` ## 4.7.6 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.7.6` ## 4.7.5 ### Patch Changes - Manage custom metric dashboards from code. `query.dashboards` lists, creates, updates and deletes custom dashboards and their widgets, and every widget query is checked when it is saved. The MCP server adds `create_dashboard` and `set_dashboard_widgets`, so your AI assistant can build a dashboard for you. ([`252624c92`](https://github.com/triggerdotdev/trigger.dev/commit/252624c92077a8326e9b68f7b6713beca173d8b1)) ```ts import { query } from "@trigger.dev/sdk"; await query.dashboards.create({ title: "Email tasks", widgets: [ { title: "Total runs", query: "SELECT count() AS total FROM runs", display: { type: "bignumber", column: "total", aggregation: "sum" }, }, ], }); ``` - Redact span content before it leaves the worker. `telemetry.spanProcessors` in `trigger.config.ts` runs your own span processors ahead of every export, to Trigger.dev and to your own exporters, so you can redact or drop span content before it reaches the run trace. `chat.agent` also takes a `telemetry` option to stop recording the user's message and `clientData` on its spans. ([`32b36b143`](https://github.com/triggerdotdev/trigger.dev/commit/32b36b1433dddb4f9d2cbd4c0320b146c7d6c858)) ```ts export default defineConfig({ telemetry: { spanProcessors: [new MyRedactingSpanProcessor()] }, }); chat.agent({ id: "my-chat", telemetry: { recordUserMessage: false, recordClientData: false }, run: async ({ messages, signal, streamText }) => streamText({ model, messages, abortSignal: signal }), }); ``` - Updated dependencies: - `@trigger.dev/core@4.7.5` ## 4.7.4 ### Patch Changes - Override a concurrency limit's `perKey` for a single `concurrencyKey`: `concurrencyLimits.override(name, { concurrencyKey, perKey, ttl })` caps that one key under that one limit for a while (7 days by default, 30 at most), `reset(name, { concurrencyKey })` clears it, and `retrieve(name, { concurrencyKey })` shows the key's bound and when the override expires. ([`c49fd05f4`](https://github.com/triggerdotdev/trigger.dev/commit/c49fd05f44119ec2a036afaabaad8f9e148a3db6)) - `runs.replay()` now takes options, so you can replay a run with a different payload, metadata, tags, queue, machine, version, delay and other trigger options. Anything you leave out comes from the original run, as before, and the payload is serialized like `trigger()`, so values like `Date` and `BigInt` keep their types. ([`ff2aa236e`](https://github.com/triggerdotdev/trigger.dev/commit/ff2aa236eb986b938e8e04cec3898b24aed4ec3f)) ```ts import { runs } from "@trigger.dev/sdk"; await runs.replay("run_1234", { payload: { userId: "user_456" }, tags: ["replayed"], delay: "10m", }); ``` - Updated dependencies: - `@trigger.dev/core@4.7.4` ## 4.7.3 ### Patch Changes - Stopping a `chat.agent` turn whose `run()` returns a `streamText` result no longer sends an `error` chunk with "An unexpected error occurred". The turn ends quietly again and the run stays alive for the next message. ([`64c3ba13c`](https://github.com/triggerdotdev/trigger.dev/commit/64c3ba13cbe02cc89667c87df2515c5ec592d424)) - `chat.createStartSessionAction`, `chat.headStart` and `chat.startHeadStart` now accept `tags` for the Session itself, so chat sessions can be filtered by tag on the Sessions page. `triggerConfig.tags` still tags the session's runs. ([`9dbc5f984`](https://github.com/triggerdotdev/trigger.dev/commit/9dbc5f984f064202eda137ad9a00a14d9d6baad4)) ```ts await startChatSession({ chatId, clientData, tags: [`org:${org.slug}`, `user:${user.id}`], }); ``` - Updated dependencies: - `@trigger.dev/core@4.7.3` ## 4.7.2 ### Patch Changes - `chat.agent` now sends parallel tool results to the model in the order the tools were called, the same order the next turn's history uses. Models that bind their thinking to the exact conversation (Claude Sonnet 5.5, Claude Opus 5.5, Claude Fable 5.1) no longer lose a turn's reasoning, or fail the request on accounts that enforce the check, when its tools finish out of order. ([`760737258`](https://github.com/triggerdotdev/trigger.dev/commit/76073725801988056d23bbdde76831d81e671cd7)) - Recovering a long unfinished `chat.agent` response on a continuation run no longer blocks the worker. Rebuilding the response from its streamed chunks now takes time linear in its length and yields to the event loop as it goes, so heartbeats keep firing and the run is not killed mid-replay. Capturing the response at the end of a long turn gets the same speedup. ([`93c63c685`](https://github.com/triggerdotdev/trigger.dev/commit/93c63c6859648521792bd4d2cd7c0c5966eef991)) - Updated dependencies: - `@trigger.dev/core@4.7.2` ## 4.7.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.7.1` ## 4.7.0 ### Minor Changes - Chat agents can now scope concurrency per session. Pass `concurrencyKey` (for example, your chat ID or tenant ID) and trigger-time named limits via `triggerConfig.concurrency` when starting a chat session, from `chat.createStartSessionAction`, the `AgentChat` client, or a handover. Keys are never defaulted, so a session without one shares the task's keyless pool. ([`ea9758117`](https://github.com/triggerdotdev/trigger.dev/commit/ea9758117bc4abb3e2d09deeab36d5c113c8496c)) ```ts const start = chat.createStartSessionAction("support-chat", { triggerConfig: { concurrencyKey: user.id }, }); ``` - Concurrency limits can now be paused and resumed, just like queues: `concurrencyLimits.pause(name)` stops every run holding the limit from being dequeued while keeping its configured bounds, and `concurrencyLimits.resume(name)` starts them again. ([`fa94febb6`](https://github.com/triggerdotdev/trigger.dev/commit/fa94febb6ee1f8ebd288698535b6b7ccaf3aa038)) ```ts import { concurrencyLimits } from "@trigger.dev/sdk"; await concurrencyLimits.pause("openai"); await concurrencyLimits.resume("openai"); ``` - Control a task's concurrency with the new `concurrency` option, and share limits across tasks with named concurrency limits. An inline shape caps the task itself; `concurrencyLimit()` declares a limit any task can hold (up to two named limits per task), and a trigger call can switch a run's named limits with its own `concurrency` option. ([`ea9758117`](https://github.com/triggerdotdev/trigger.dev/commit/ea9758117bc4abb3e2d09deeab36d5c113c8496c)) ```ts import { concurrencyLimit, task } from "@trigger.dev/sdk"; export const openaiLimit = concurrencyLimit({ name: "openai", total: 25 }); export const generateSummary = task({ id: "generate-summary", concurrency: [{ perKey: 1, total: 5 }, openaiLimit], run: async (payload) => {}, }); ``` `perKey` caps each `concurrencyKey` pool and `total` caps across everything, keys or not. The queue-level `concurrencyLimit` option keeps working unchanged and is deprecated in favor of `concurrency`. Enforcement happens server-side; servers without support accept the option but do not enforce it yet. Manage limits at runtime with the new `concurrencyLimits` namespace: `list()` and `retrieve(name)` report each limit's bounds plus its live `running` and `queued` counts, `override(name, { perKey, total })` changes only the given bounds (overriding `total` to `0` pauses the limit), and `reset(name)` restores the declared values. Queue reads (`queues.list()` and `queues.retrieve()`) now report a `version` that discriminates the shape: `V1` queues keep today's fields (their own `concurrencyLimit` and its override state), while `V2` queues (tasks declared with `concurrency`) carry no queue-level concurrency, since their limits are read and overridden through `concurrencyLimits` (a task's inline limit under its derived `task/` name). Existing reads keep compiling: a `V2` queue reports `concurrencyLimit` as null and `concurrency` as undefined. ### Patch Changes - Add an optional `onSettled` callback to `TriggerChatTransport.sendAction()` so callers can confirm that their action's input was processed, independently of whether the response stream closes. ([#4956](https://github.com/triggerdotdev/trigger.dev/pull/4956)) - Chat agents now return to a durable wait when a session wake does not deliver a matching message. This prevents resumed runs from staying active until their maximum duration and preserves the configured turn timeout across repeated wakes. ([`e6ec2c4e8`](https://github.com/triggerdotdev/trigger.dev/commit/e6ec2c4e8d5450668c95eaf84c1567c9eb9abb87)) - Deprecate `queues.overrideConcurrencyLimit` and `queues.resetConcurrencyLimit`. These operate on the legacy model where a queue carried its own concurrency limit; declare concurrency with the task `concurrency` option and manage it with `concurrencyLimits.override` and `concurrencyLimits.reset` instead. ([`414e5a268`](https://github.com/triggerdotdev/trigger.dev/commit/414e5a268683389bd6d66b4b7b0991bd62dd9438)) - Chat streams now report `Stream stalled: no records received` after five retries of a connected stream that sends no records. Network failures and browser wakeups retain automatic recovery. Healthy tool calls with no records for about six minutes also reach this silence limit. Watch subscriptions remain unlimited, and caller cancellation still closes cleanly. ([#4949](https://github.com/triggerdotdev/trigger.dev/pull/4949)) - Steering messages now remain in context across agent steps and keep their original position in saved conversations, including custom response data written between steps. ([`5619acf26`](https://github.com/triggerdotdev/trigger.dev/commit/5619acf266f6cd5fa1370cabf48e2da7ec468383)) - Updated dependencies: - `@trigger.dev/core@4.7.0` ## 4.6.3 ### Patch Changes - Thrown error `cause` chains are now captured and shown. When a task throws an error that wraps another one, the run's error in the dashboard, the CLI dev output, and failure alerts all carry the chain instead of only the outermost message. ([`4f36f614b`](https://github.com/triggerdotdev/trigger.dev/commit/4f36f614b7937f9419900bef4080c42cd34b292b)) ```ts throw new Error("Could not sync the customer", { cause: originalError }); ``` The chain is flattened outermost first, capped at five causes, and cycle safe. It also rides on the `error` of API and realtime run records as a `causes` array, and `triggerAndWait` and `triggerAndSubscribe` rebuild it as a native `cause` on the error they hand back, so `err.cause` works in your own catch blocks. - Keep summarized assistant steps and tool results out of future `chat.agent()` model context after inner compaction, while preserving the full visible conversation. ([`fc77bfc9a`](https://github.com/triggerdotdev/trigger.dev/commit/fc77bfc9a2005159b64f0f51777f4ab8e79ba6a9)) - Updated dependencies: - `@trigger.dev/core@4.6.3` ## 4.6.2 ### Patch Changes - Show warm idle time and durable waits separately in chat agent traces. Durable waits now open the waitpoint inspector while waiting and after completion. Message span names are shorter, and repeated session IDs no longer crowd message-wait and default output-stream spans. ([`0754931cc`](https://github.com/triggerdotdev/trigger.dev/commit/0754931cca708fc7334470b81c0f446afed7ef0a)) - chat.agent: the between-turns compaction check now receives the last step's token usage (the context the model actually held) instead of the turn's sum over every tool-calling step, so a single tool-using turn no longer compacts a short conversation. The summed figure is still available as `turnUsage` on the event. A head-start handover whose pending tool call completes under the same message id now replaces its spliced partial in the model lane directly instead of falling back to a full reconversion. ([`04c837569`](https://github.com/triggerdotdev/trigger.dev/commit/04c8375696bacab65ad7bb2d9cf2b9df616b1343)) - Validate resource IDs when creating scoped public tokens. Explicitly empty IDs are now rejected instead of being interpreted as type-wide permissions. ([`22f8fb2b5`](https://github.com/triggerdotdev/trigger.dev/commit/22f8fb2b5b1d05ac1741facb87873454b7805eac)) - Updated dependencies: - `@trigger.dev/core@4.6.2` ## 4.6.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.6.1` ## 4.6.0 ### Minor Changes - Actions can now become turns. `onAction` edits history with `chat.history`; to answer after the edit, return `chat.turn()` and a turn runs on the edited history with everything a turn has: the agent's system prompt and tools, steering, compaction, injected instructions, `onTurnStart` and `onTurnComplete`, and persistence. A regenerate is `chat.history.slice(0, -1); return chat.turn();`. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) ```ts onAction: async ({ action }) => { if (action.type === "regenerate") { chat.history.slice(0, -1); return chat.turn(); } if (action.type === "undo") chat.history.slice(0, -2); // edit only }, ``` Returning a `StreamTextResult`, `string` or `UIMessage` from `onAction` is no longer supported and now fails with an error pointing to `chat.turn()`. A response produced that way skipped every turn guarantee, and its delivery to the browser was unreliable: the frontend never read the stream `transport.sendAction` returned, so a regenerate that appeared to work on the server did not render. History edits made by an action are still persisted as before: platform-managed snapshots are written after the edit, and apps with their own store mirror the edit themselves. - End a chat conversation from inside the agent with `chat.close({ reason })`. The session row is closed, further sends are refused with HTTP 409, and the run exits without scheduling a continuation, so a budget cap, a completed goal, or a signed-out user can stop the conversation rather than only the current run. ([`0a23814a0`](https://github.com/triggerdotdev/trigger.dev/commit/0a23814a0896205da227520bd417bd490a017379)) ```ts chat.agent({ id: "budgeted-agent", run: async ({ messages, signal }) => streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }), onBeforeTurnComplete: async ({ chatId }) => { if (await overBudget(chatId)) { chat.close({ reason: "Monthly budget reached" }); } }, }); ``` The current turn still streams in full. Decide the close before the turn ends (`run()`, `prepareStep`, `onBeforeTurnComplete`) so the closed state rides out on that turn's final record and the user sees it as soon as the answer finishes. `TriggerChatTransport` picks the close up from the response stream or from a refused send, exposes it as `transport.sessionStatus(chatId)` plus `transport.sessionClosedReason(chatId)`, and stops sending and reconnecting. Closing a session from outside with `sessions.close()` now also reaches a live run, so an idle or suspended agent exits on its next wake instead of waiting out its idle timeout. Writes to a closed session's named side channels are refused with the same 409. - `run()` now receives a `streamText` with your agent's managed options already applied, so they cannot be lost by leaving out the spread: ([#4884](https://github.com/triggerdotdev/trigger.dev/pull/4884)) ```ts run: async ({ messages, signal, streamText }) => streamText({ model, messages, abortSignal: signal }); ``` Spreading `chat.toStreamTextOptions()` still works and is equivalent. The difference is what happens when your options collide with the managed ones. Passing `tools` after the spread replaces the skill tools, and passing your own `prepareStep` replaces the managed one, which silently switches off steering, compaction and injected context. The managed `streamText` merges tools and composes `prepareStep` instead, so neither can be turned off by accident. `system` can be set at the call site, on `chat.agent({ system })`, or through `chat.prompt.set()`, but only in one of them: setting it in two places throws, because no single shape merges two system values across every supported AI SDK version, and dropping one silently is the failure this seam exists to prevent. Injected instructions append to whichever one is in play. `chat.agent()` also takes `registry`, `cacheControl` and `systemProviderOptions` now, so a managed prompt's model and its cache breakpoint no longer have to be passed at the call site. `chat.toStreamTextOptions()` applies them as well, so spreading it into the `streamText` imported from `ai` stays equivalent to the one `run()` receives. `chat.headStart` and `chat.startHeadStart` hand their `run` the same thing, carrying the options the handover protocol depends on. There it matters more: re-setting `messages`, `prompt`, `stopWhen` or `abortSignal` after a spread breaks the handover rather than degrading a feature, and nothing caught it. On the managed one those four keys are a type error; `tools` is yours to pass. - `chat.agent` persists a conversation through a `TranscriptStorage`: an adapter with `load` and `save` that the runtime drives after every turn, failed turn and history-changing action. The platform snapshot stays the default; bring your own to write the conversation to your database as it happens. Each save carries both the changes since the last one (so a row store writes only what changed, and an undo is one `truncateAfter`) and the whole transcript as it now stands (so a document store writes it as-is with no state of its own). ([#4896](https://github.com/triggerdotdev/trigger.dev/pull/4896)) ```ts chat.agent({ id: "my-chat", storage: myTranscriptStorage, run: async ({ messages, signal, streamText }) => streamText({ model, messages, abortSignal: signal }), }); ``` `chat.createLoadTranscriptAction(storage)` and `useLoadTranscript` read the conversation back the same way for every storage, and `runTranscriptStorageTests` from `@trigger.dev/sdk/ai/test` checks an implementation against the contract. Compaction summaries and `chat.inject` context now survive a continuation run, and crash recovery runs for every agent, including one that owns its own context. `hydrateMessages` is deprecated in favour of `loadContext` on a storage. The snapshot format is now version 2, which older SDK versions cannot read. - Actions are sent through `useChat` so a turn that follows one renders like any turn. `TriggerChatTransport` recognises `body.action` on a `useChat` request and sends it as an action, so `sendMessage(undefined, { body: { action } })` or `regenerate({ body: { action } })` sends the action and `useChat` owns the response: it streams into the message list, `status` and `error` behave as for a message, and `stop` works. `useChatActions({ sendMessage })` in `@trigger.dev/sdk/chat/react` is a two-line convenience over that. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) ```tsx const { sendMessage } = useChat({ id: chatId, transport }); const { sendAction } = useChatActions({ sendMessage }); sendAction({ type: "regenerate" }); ``` Previously the frontend docs said `useChat` consumed the stream `transport.sendAction` returns; it never did, so an action's answer was never rendered by an app following them. `transport.sendAction` still returns a stream that callers outside `useChat` must read, and now accepts `{ abortSignal, metadata }`, with per-action metadata merged over the transport's `clientData`. - Trigger.dev now uses Zod 4 by default. Projects using Zod 3.25.56 or later 3.x releases remain supported. ([#4039](https://github.com/triggerdotdev/trigger.dev/pull/4039)) Zod remains a runtime dependency of packages that execute schemas, so existing and new installations continue to receive it automatically. The matching peer dependency range allows package managers to reuse either a compatible Zod 3 or Zod 4 installation from your project. ### Patch Changes - Chat sessions can now be pinned to a deployment, so a conversation keeps talking to the agent version its release shipped with, and follows the pin on its own when your app redeploys. Opt out with `triggerConfig: { externalDeploymentId: null }` or `versionSkew: "hold"`. Also fixes `AgentChat` ignoring `maxDuration`, `region` and `lockToVersion`, and a restored `AgentChat` session never picking up a new deployment id. ([`1133ad45e`](https://github.com/triggerdotdev/trigger.dev/commit/1133ad45e7c1edbc2ff053678e37146c155521ef)) - `chat.agent`: a `chat.history` edit made in `onTurnComplete` after a failed turn is now kept. Previously the edit was applied only when the turn succeeded, so a failure record or a card the hook closed on the error path never reached the transcript. ([`3f67c71c0`](https://github.com/triggerdotdev/trigger.dev/commit/3f67c71c0c68ea53ba1859b4e31054cc5d52293a)) - `chat.agent`: after a Head Start turn whose handed-over tool call was followed by more tool steps, the next turn no longer fails with `tool_use ids must be unique`. The runtime kept the warm step's pending tool call in the model context alongside the completed response that already contained it. ([`8b72e6c06`](https://github.com/triggerdotdev/trigger.dev/commit/8b72e6c0616b1570d57f35b5e2a736791ad3c6f0)) - `chat.agent`: a continuation boot no longer re-dispatches the message that resumed it, and a turn with no new user message no longer calls the model. Previously a resumed run could answer the same message twice, and the second attempt failed against providers that reject a trailing assistant message, overwriting an answer that had already completed. ([`35e57e785`](https://github.com/triggerdotdev/trigger.dev/commit/35e57e785c6c80ee22329c597287ff88a3486e4e)) - `chat.agent`: a run that recovers a session with more than one in-flight user message no longer drops the unanswered ones if it restarts mid-recovery. Recovered messages now hold the resume cursor until each has been answered, so a restart re-answers the rest instead of resuming past them. Previously the cursor could advance past messages that were only held in memory, so a crash before they were dispatched lost them. ([#4907](https://github.com/triggerdotdev/trigger.dev/pull/4907)) - Reading a page of a chat agent's conversation no longer downloads the whole conversation. The saved transcript now carries an index, so asking for the most recent messages fetches only those messages, and history loads in roughly constant time however long the chat gets. ([`b7e86f2af`](https://github.com/triggerdotdev/trigger.dev/commit/b7e86f2afe1b1b4e38f1f2f00222eb172e2d0ee3)) A paged read also returns only the conversation itself. The model-side context an agent keeps, its compacted history and any injected context, is no longer included, so it cannot reach a browser through a load-transcript server action. The built-in storage is deliberately basic about long conversations: once an agent has compacted, it keeps roughly the last hundred messages and drops the rest, so what it rewrites each turn stops growing. A conversation that never compacts is kept whole. If your app renders history further back than that, give the agent your own transcript storage. The saved format has changed and an older SDK cannot read it, so a deployment rolled back to an earlier version will not find a readable transcript for conversations the newer version already saved, and those conversations continue from the live stream tail instead. Roll forward rather than back, or keep your own transcript storage. - `useTriggerChatTransport` now picks up changes to `accessToken`, `startSession` and `fetch` on re-render, so a chat that stays mounted while the surrounding page changes no longer keeps sending to the endpoint captured on first render. ([`9ae9c1ae4`](https://github.com/triggerdotdev/trigger.dev/commit/9ae9c1ae43a91e21afcc6e2c97c4b63b9b0bff71)) - Steering messages are now kept in the conversation when you drive turns yourself with `chat.createSession()` or `chat.MessageAccumulator`. Previously a message that arrived mid-answer shaped that answer and then existed nowhere: it was missing from `turn.uiMessages`, so an app persisting from there never stored it, missing from `turn.messages`, so every later turn answered as though it had never been sent, and it was not queued as its own turn either. It now lands in both, the same way it does on `chat.agent`. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) - Injected system context is merged into a single instruction block, so it works on every supported AI SDK version. Note that a cached system prompt gives up its cache entry for as long as an injection is live, since the cached prefix has changed. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) - `chat.inject()` with `role: "system"` now works. It previously put the system message into the conversation, which AI SDK 7 rejects for every provider: the next turn died with a generic "An error occurred." and persisted an empty assistant message, so the agent looked like it had stopped answering. System-role context is now appended to the model's instructions, which is also the only way to inject context the agent treats as trusted. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) Two things to know. Instructions are delivered by `chat.toStreamTextOptions()`, so a `run()` that calls `streamText` without spreading it does not receive a system-role injection. The conversational lane has no such requirement. And an injection applies to the next turn only, rather than repeating on every turn that follows it. Every inference call in that turn sees it, so a `run()` that builds options more than once gets the same instructions each time. An instruction injected after an action has run, and before the next message, reaches that next turn rather than the one after it. - A failed write to a realtime or chat session stream no longer crashes the process running it, and a dropped chat session output write is now logged instead of swallowed. ([`fb25c0149`](https://github.com/triggerdotdev/trigger.dev/commit/fb25c0149c6c734f942f6f41210b197ed4b1f736)) - Undo, edit and regenerate now survive a run ending. History rolled back from `onAction` was only kept in the running worker's memory, so the rollback held while that worker stayed warm and then reverted on the next continuation. The undone messages came back, minutes later, with no error. This also holds when the turn before the action failed: the rollback used to be written against the cursor from before that turn, so a continuation could replay output the failed turn had already superseded. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) - Reduce sensitive values in CLI and SDK diagnostics, secure files created by `trigger env pull`, and remove credentials from collected Git remote metadata. ([`ff05824c1`](https://github.com/triggerdotdev/trigger.dev/commit/ff05824c1bdf1c2276d202ed84328c948cc290a3)) - Server-side `AgentChat` streams now reconnect when the connection drops mid-turn instead of ending with a truncated reply, and a turn that still cannot be resumed ends with an error rather than a silent truncation. ([`8bf27a629`](https://github.com/triggerdotdev/trigger.dev/commit/8bf27a62937b5858f4963d65a9d7802982f1724e)) - Session public tokens can now be narrowed to one stream: `read: { sessions: "chat_123:out" }` grants read access to that session's `.out` channel only, without access to the session record or its other channels. ([`33cf5701b`](https://github.com/triggerdotdev/trigger.dev/commit/33cf5701b4536012d45e365761c4a36067ea5f1d)) - Fixes storage of large trigger payloads for task ids containing a slash, which could fail the trigger with an "Invalid packet storage path" error. It affected ids that started or ended with a slash, contained two slashes in a row, or contained a `.` or `..` path component. The storage path is now built from a generated id rather than from the task id, so no task id can produce an unusable one, and payloads that are already stored are still read from where they were written. ([`ed37e19c9`](https://github.com/triggerdotdev/trigger.dev/commit/ed37e19c9f70495ba2a067245f8a4a83aaace2c3)) - Steering messages injected mid-answer are now part of the conversation, both for your hooks and for the model on later turns. Previously they reached the model for the answer they steered and reached the browser, but nothing else: `onTurnComplete` never saw them, so an app storing its own transcript lost the instruction the answer was shaped by, and it vanished from the conversation on reload. The model also forgot the instruction from the next turn onwards, answering as though the message had never been sent, while the chat UI still showed it. This holds when the steered turn fails part-way, and when `pendingMessages.prepare` reshapes the message: later turns now see the same form the steered turn did, not the original message. ([#4816](https://github.com/triggerdotdev/trigger.dev/pull/4816)) Approving a tool call no longer undoes compaction. A tool-approval continuation used to rebuild the model's context from the full conversation, so a chat that had been summarised to fit the context window was sent the whole transcript again on the next call, and could go over the limit it had just been compacted to avoid. If you worked around this by saving steering messages as they arrive, in `pendingMessages.onReceived` for example, that write now duplicates the one you get from `newUIMessages`. Drop it, or skip messages you have already stored. - Reloading a chat while the agent is still answering now shows the message being answered. Previously the incoming message was only persisted once the turn finished, so a refresh mid-answer showed the reply arriving with no question above it. ([`986811008`](https://github.com/triggerdotdev/trigger.dev/commit/9868110089cb08817801bc4e1026dd6c781be1be)) Adds `chat.deferBeforeOutput()` for app-owned writes that the next page load has to see. Like `chat.defer()` the work is not awaited by the hook that registers it, so it runs alongside the model and costs no time to first token, but the answer is held until it lands. Use it for the conversation or message write you previously had to `await` in `onTurnStart`, as long as nothing else in the turn reads that write back: it orders the write against what the frontend can see, not against the model, so a tool that reads the same row still needs an awaited write. - chat.agent transcript fixes: a turn that errors before the model produces any content no longer stores an empty assistant message, an error thrown without a message now shows a generic error instead of a blank one, and a custom transcript storage no longer needs to preserve exact message JSON for a compaction to survive a continuation. ([#4910](https://github.com/triggerdotdev/trigger.dev/pull/4910)) - Updated dependencies: - `@trigger.dev/core@4.6.0` ## 4.5.16 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.5.16` ## 4.5.15 ### Patch Changes - Stop shipping compiled test files in the published packages. The `*.test.ts` sources were being emitted into `dist`, adding dead weight to every install and leaving modules that `require("vitest")` (not a dependency) inside the tarball, which tripped tooling that walks every file in a package. ([#4833](https://github.com/triggerdotdev/trigger.dev/pull/4833)) - Named side channels on a Session: durable, two-way realtime streams that outlive a single run and are shared across runs. Open a channel with `sessions.open(id).channel(name)` (or `chat.channel(name)` inside a `chat.agent`) to get an `.in`/`.out` pair addressed by name rather than the reserved default pair. Writing a side channel's `.in` does not wake or trigger a run, so a channel can carry out-of-band data (a stream of frames, a control signal) that many clients read while the agent produces it. ([#4815](https://github.com/triggerdotdev/trigger.dev/pull/4815)) ```ts // Inside a chat.agent: stream frames on a named channel, wakes nothing const frames = chat.channel("screenshots"); await frames.out.append(frame); frames.in.on((control) => { /* client control, no suspend */ }); ``` Declare channel record types once with `sessions.defineChannel(...)` and infer them on both the producer and the consumer, including `useSessionStreamChannel` in React. Channels get a default retention that keeps them bounded, overridable per channel. - Session `triggerConfig.tags` now accepts up to 10 tags, matching the run tag limit. Previously it was capped at 5, which for `chat.agent` left room for only 4 of your own tags after the automatic `chat:{chatId}` tag. ([#4832](https://github.com/triggerdotdev/trigger.dev/pull/4832)) - Updated dependencies: - `@trigger.dev/core@4.5.15` ## 4.5.14 ### Patch Changes - Subscribe to a realtime stream from its latest record instead of replaying the whole history. Pass `from: "latest"` to `useRealtimeStream`, `streams.read()`, or `fetchStream` to start at the current tail (the latest record, then live updates) instead of replaying (a live "last value" view), and `maxParts` to keep the accumulated `parts` array bounded. A reconnect or remount resumes from the last record it saw, so no records are missed and none are replayed. `from: "latest"` needs a server that supports it; older servers safely fall back to a full replay. ([#4811](https://github.com/triggerdotdev/trigger.dev/pull/4811)) `useRealtimeStream` also gains a `lastEventId` option and returns the `lastEventId` of the last part seen, so you can persist the cursor (for example across a page reload) and resume exactly where you left off. An `onParts` callback delivers each throttled batch of parts with their event ids. ```tsx const { parts, lastEventId } = useRealtimeStream(runId, "frames", { from: "latest", // skip history, start at the current tail maxParts: 1, // keep only the most recent frame lastEventId: savedCursor, // resume from a persisted cursor onParts: (batch) => save(batch.at(-1)?.id), // track the cursor accessToken, }); ``` - Updated dependencies: - `@trigger.dev/core@4.5.14` ## 4.5.13 ### Patch Changes - Fixed a chat agent hanging after an interrupted turn: when a run was killed mid-answer (out of memory, crash, or eviction) and only the one message it was answering was still outstanding, the new run never replied to it. That message is now re-answered on the new run. ([#4768](https://github.com/triggerdotdev/trigger.dev/pull/4768)) - Browser chats now keep the active turn open across page reloads when older completion records are replayed. ([#4643](https://github.com/triggerdotdev/trigger.dev/pull/4643)) - Add `chat.endAndContinue()` so fully hand-rolled custom chat agents can hand a conversation off to a fresh run on the latest deployed task version while preserving unconsumed Session input. ([#4647](https://github.com/triggerdotdev/trigger.dev/pull/4647)) - Fix chat transport discarding the next turn after stopping generation. `skipToTurnComplete` is now reset when a new message or action is sent, so a message sent after `stopGeneration` streams normally instead of leaving the chat stuck in a streaming state. ([#4744](https://github.com/triggerdotdev/trigger.dev/pull/4744)) - Custom chat agents now validate and parse client data declared with `chat.withClientData({ schema })` before passing it to agent code. ([#4646](https://github.com/triggerdotdev/trigger.dev/pull/4646)) - Fixes a message sent while the agent was mid-answer being lost if the run then crashed. The cursor written at the end of each turn could point past a message that had arrived during that turn but had not been answered yet, so the next boot skipped it and no error was raised anywhere. Such a message is now held until a turn actually takes it. ([#4795](https://github.com/triggerdotdev/trigger.dev/pull/4795)) This also removes the in-memory buffer those messages used to sit in, on both `chat.agent` and `chat.createSession()`, so a message waiting for its turn is durable rather than only present in the worker that received it. - A message that arrives mid-turn and is not injected into that turn is now answered as the next turn, instead of being dropped. This is what the `pendingMessages` docs have always described, and it applies to the default too: configuring `pendingMessages` without a `shouldInject` declines every batch, which previously meant every mid-turn message was lost with no error at either end. ([#4795](https://github.com/triggerdotdev/trigger.dev/pull/4795)) ```ts chat.agent({ id: "my-chat", pendingMessages: { onReceived: ({ message }) => logger.info("arrived mid-turn", { id: message.id }), // Only interrupt once the agent has started calling tools. shouldInject: ({ steps }) => steps.length > 0, }, run: async ({ messages, signal }) => streamText({ model, messages, abortSignal: signal, // Required for injection. Without it nothing injects, and every // mid-turn message is answered as the next turn instead. ...chat.toStreamTextOptions(), }), }); ``` A declined message keeps its place in the queue, so it survives a crash and is answered by whichever run picks the conversation up. An injected one is consumed at the moment it is injected, so it is never also answered as a later turn. - Fixes a case where a chat could silently lose a message. If a message arrived while the agent was between turns and a stop arrived after it, the cursor the next boot resumed from could point past that message, so it was never answered and no error was raised. This affected `chat.agent`, not just custom agents. ([#4644](https://github.com/triggerdotdev/trigger.dev/pull/4644)) Fixes a recovered answer being cut off. After a crash the agent replays the message it had not answered yet, but it was replaying the stop that arrived after that message too, so the turn answering it was aborted the moment it began. A stop is now only applied to the turn that was live when it arrived. That holds however the stop got there: sent after the last completed turn, or sent to a chat whose most recent turn was completed by an older version of the SDK. One limitation to know about: the recovered answer is persisted correctly, but a chat page that stayed open across the crash keeps showing the partial answer it had already received. Reload the page to see the full recovered answer. Also fixes a retried send being answered twice. When a send was retried and its idempotency claim was lost, the agent could consume the same message a second time. Custom agent loops can now inspect pending chat input without consuming it, and consume one record at a time, with `chat.messages.hasPending()` and `chat.messages.next()`. Records carry stable identifiers so a redelivery is recognisable. ```ts if (await chat.messages.hasPending()) { const record = await chat.messages.next({ timeoutInSeconds: 0 }); if (record) handle(record.payload); } ``` `hasPending()` answers for messages alone, so a message sitting behind a stop, or behind a record this version of the SDK does not recognise, still reports as pending and is still delivered. Anything the agent has no consumer for is discarded rather than left where it would make every message queued behind it undeliverable. `chat.messages.next()` returning `undefined` means no message became consumable before the timeout. `chat.writeTurnComplete()`'s `sessionInEventId` is the cursor that is safe to resume from, not the sequence of the record the turn answered. It is held back behind any message still waiting to be handled, so a value below the record you just handled is expected. - Updated dependencies: - `@trigger.dev/core@4.5.13` ## 4.5.12 ### Patch Changes - Define stable execution windows on declarative scheduled tasks. Schedule API responses now expose both the nominal CRON time and its assigned time, while the dashboard shows configured windows and upcoming assignments. ([#4572](https://github.com/triggerdotdev/trigger.dev/pull/4572)) - Pin runs to the deployment your calling code came from, so an old release never triggers tasks from a new one: set `TRIGGER_EXTERNAL_DEPLOYMENT_ID` to the id you deployed with, or `TRIGGER_AUTOMATIC_SKEW_VERSION_PROTECTION=1` to detect the commit automatically on Vercel and most CI systems. Runs triggered before that deployment finishes building wait for it, then start pinned. ([#4664](https://github.com/triggerdotdev/trigger.dev/pull/4664)) - Updated dependencies: - `@trigger.dev/core@4.5.12` ## 4.5.11 ### Patch Changes - Chat in the browser now reconnects when the connection drops mid-turn, instead of leaving the reply stuck as if it were still generating. Reports can be fetched as structured data with the `json` format, and the shortest report period is now one minute (`1m`, `30m`, `1h`, `7d`). The `mint-token` command's help is clearer too: a token minted without `--cap` is read-only, and `--ttl` shows the correct maximum lifetime of 7 days. ([#4418](https://github.com/triggerdotdev/trigger.dev/pull/4418)) - Watch-mode chat streams now survive quiet windows and page reloads, and a reply cut off by a lost connection shows an error instead of appearing finished. Aborting a resumed subscription only closes your local stream — call `stopGeneration(chatId)` or pass `stopOnAbort: true` to stop the run. Also fixed a race where quickly restarting a stream could break stop and reconnect, and stopping a chat now hands it back to your other tabs instead of leaving them read-only. ([#4516](https://github.com/triggerdotdev/trigger.dev/pull/4516)) - Updated dependencies: - `@trigger.dev/core@4.5.11` ## 4.5.10 ### Patch Changes - `debounce` now works when you pass an array of items to `batchTrigger` or `batchTriggerAndWait`, and when you trigger from `useTaskTrigger`. Previously the option was accepted by the types and dropped before the request was sent, so every trigger created its own run instead of collapsing onto the debounce key. ([#4520](https://github.com/triggerdotdev/trigger.dev/pull/4520)) ```ts await myTask.batchTrigger([ { payload: { id: "a" }, options: { debounce: { key: "same-key", delay: "30s" } }, }, { payload: { id: "b" }, options: { debounce: { key: "same-key", delay: "30s" } }, }, ]); ``` The streaming (async iterable) forms of the batch calls were already forwarding `debounce` correctly. - Fix a preloaded `chat.agent` run dropping an in-flight message when it retries after an out-of-memory error. The message being processed when the run hit the OOM is now recovered and re-run on the retry, instead of being skipped while the run waited for a new message. ([#4349](https://github.com/triggerdotdev/trigger.dev/pull/4349)) - `AgentChat.reconnect()` now settles promptly when reconnecting to an idle chat instead of holding the connection open for the full long-poll window. Also upgrades the S2 streamstore client to 0.25 and moves realtime streams to S2's current hosts. ([#4349](https://github.com/triggerdotdev/trigger.dev/pull/4349)) - Allow task-scoped environment API keys to run batch operations for their permitted tasks. The SDK declares the batch's task set before creation, and `@trigger.dev/core/v3/apiKeys` now exports the additional-key format helper. ([#4389](https://github.com/triggerdotdev/trigger.dev/pull/4389)) - Refresh package builds for TypeScript 7 compatibility while preserving existing runtime entry points. Projects using `emitDecoratorMetadata()` with TypeScript 7 can install the `@typescript/typescript6` compatibility package alongside it; the package remains optional, so installing the Trigger.dev CLI does not install an additional compiler. ([#4318](https://github.com/triggerdotdev/trigger.dev/pull/4318)) - Updated dependencies: - `@trigger.dev/core@4.5.10` ## 4.5.9 ### Patch Changes - Correct the `expirationTime` docs on `auth.createPublicToken` and the trigger-token helpers: a number is a Unix timestamp in seconds, not milliseconds. ([#4388](https://github.com/triggerdotdev/trigger.dev/pull/4388)) - Updated dependencies: - `@trigger.dev/core@4.5.9` ## 4.5.8 ### Patch Changes - Preserve the partial assistant message when a chat turn's model stream fails mid-response. `chat.agent` now passes the recovered partial to `onTurnComplete`, and `chat.createSession`'s `turn.complete()` keeps it before rethrowing, instead of dropping the streamed-so-far output. ([#4348](https://github.com/triggerdotdev/trigger.dev/pull/4348)) - Allow additional environment API keys to create scoped public access tokens through the Trigger.dev API. Use server-issued public access tokens for batch operations so environment-scoped API keys can read batch results. ([#4387](https://github.com/triggerdotdev/trigger.dev/pull/4387)) - Updated dependencies: - `@trigger.dev/core@4.5.8` ## 4.5.7 ### Patch Changes - Custom chat agent loops get two ergonomic wins for owning the turn loop. ([#4304](https://github.com/triggerdotdev/trigger.dev/pull/4304)) `chat.writeTurnComplete()` now returns the turn boundary's resume cursors (`lastEventId` for the output stream and `sessionInEventId` for the input stream), so you can persist them straight from the task instead of round-tripping them back from the client. ```ts const { lastEventId, sessionInEventId } = await chat.writeTurnComplete(); await db.chats.update(chatId, { lastEventId, sessionInEventId }); ``` `chat.pipeAndCapture()` no longer throws when a stream is stopped or fails. It now returns a `PipeAndCaptureResult` whose `message` holds any partial output captured before the stop or failure, alongside a typed `status` (`"complete" | "aborted" | "error"`) and, on failure, the `error`. Read the message off the result: ```ts const { message, status, error } = await chat.pipeAndCapture(result, { signal, }); if (message) conversation.addResponse(message); if (status === "error") logger.error("turn failed", { error }); ``` Note: `pipeAndCapture` previously resolved to `UIMessage | undefined`. Update call sites to read `.message` from the returned result. - Suppress a build-time warning that could appear in Vite-based projects when the optional `@ai-sdk/otel` package is not installed. ([#4188](https://github.com/triggerdotdev/trigger.dev/pull/4188)) - Updated dependencies: - `@trigger.dev/core@4.5.7` ## 4.5.6 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.5.6` ## 4.5.5 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.5.5` ## 4.5.4 ### Patch Changes - Fix a `chat.agent` message-loss race where sending a message right after an action (such as an undo) could drop the follow-up's response from the UI until a refresh. ([#4234](https://github.com/triggerdotdev/trigger.dev/pull/4234)) - Updated dependencies: - `@trigger.dev/core@4.5.4` ## 4.5.3 ### Patch Changes - Fix TS2742 ("inferred type cannot be named") when exporting a `chat.agent` from a project with declaration emit: `ChatTaskWirePayload` and `ChatInputChunk` are now declared in the public `@trigger.dev/sdk/chat` subpath, so inferred agent types emit portable declarations and the wire types are directly importable. ([#4218](https://github.com/triggerdotdev/trigger.dev/pull/4218)) - Updated dependencies: - `@trigger.dev/core@4.5.3` ## 4.5.2 ### Patch Changes - Add SDK and API client helpers for run bulk actions. ([#4105](https://github.com/triggerdotdev/trigger.dev/pull/4105)) - Fix chat turns that throw (for example from an `onTurnStart` hook) leaking their message listener, which lost or duplicated messages sent during later turns. ([#4176](https://github.com/triggerdotdev/trigger.dev/pull/4176)) - Fix `chat.agent` and `chat.createSession` permanently dropping user messages when several arrived during a single turn: every buffered message is now dispatched as its own turn instead of only the first. ([#4176](https://github.com/triggerdotdev/trigger.dev/pull/4176)) - Fix chat continuation runs replaying already-answered messages: turns delivered while the run was suspended now advance the session.in resume cursor, so a new run picks up exactly where the previous one left off. ([#4176](https://github.com/triggerdotdev/trigger.dev/pull/4176)) - Fix `chat.createSession` swallowing a message sent shortly after stopping a turn: the turn's message listener now detaches when the stream settles, so those messages run as the next turn. ([#4176](https://github.com/triggerdotdev/trigger.dev/pull/4176)) - Add an `onEvent` callback to `TriggerChatTransport` / `useTriggerChatTransport` that emits typed lifecycle events for sends, stream connects, first chunk, and turn completion. Send-success metrics, time-to-first-token, and "sent but never answered" watchdogs become a few lines of client code. ([#4187](https://github.com/triggerdotdev/trigger.dev/pull/4187)) ```ts onEvent: (event) => { if (event.type === "message-sent") metrics.timing("chat.send_ms", event.durationMs); if (event.type === "first-chunk") metrics.timing("chat.ttft_ms", event.sinceSendMs ?? 0); }, ``` - Large batch payloads now offload to object storage instead of riding inline in the trigger request. `batchTrigger` and `batchTriggerAndWait` (and the by-id and by-task variants) offload any per-item payload over 128KB before sending, the same way single `trigger` and `triggerAndWait` already do, so a big batch no longer blows past the API body limit. ([#4165](https://github.com/triggerdotdev/trigger.dev/pull/4165)) - Updated dependencies: - `@trigger.dev/core@4.5.2` ## 4.5.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.5.1` ## 4.5.0 ### 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](https://github.com/triggerdotdev/trigger.dev/pull/3629)) ```ts 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(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](https://trigger.dev/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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) ```ts 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`](https://sdk.vercel.ai/docs/ai-sdk-ui/transport) (`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` 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](https://trigger.dev/docs/ai/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](https://trigger.dev/docs/ai-chat/overview) 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](https://github.com/triggerdotdev/trigger.dev/pull/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. ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/3542)) ```ts 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](https://trigger.dev/docs/ai-chat/overview) for the full surface — Sessions powers the durable, resumable chat runtime described there. ### Patch Changes - `@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](https://github.com/triggerdotdev/trigger.dev/pull/3937)) - 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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) ```ts const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract", }); chat.skills.set([await pdfSkill.local()]); ``` Built on the [AI SDK cookbook pattern](https://ai-sdk.dev/cookbook/guides/agent-skills) — portable across providers. SDK + CLI only for now; dashboard-editable `SKILL.md` text is on the roadmap. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3833)) - 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](https://github.com/triggerdotdev/trigger.dev/pull/3546)) ```ts 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. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3891)) - Fix `chat.agent` / `AgentChat` when the agent is deployed to a Trigger.dev preview branch. The realtime message-append and stream-subscribe calls now send the `x-trigger-branch` header (sourced from the same resolver `sessions.start` uses), so messaging a preview-branch chat agent no longer fails with `x-trigger-branch header required for preview env`. ([#4018](https://github.com/triggerdotdev/trigger.dev/pull/4018)) - 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](https://github.com/triggerdotdev/trigger.dev/pull/3790)) ```ts chat.agent({ tools: { readFile, search }, run: async ({ messages, tools, signal }) => streamText({ model, messages, tools, abortSignal: signal }), }); ``` Also exports `InferChatUIMessageFromTools` to derive the chat `UIMessage` type (typed tool parts) directly from a tool set. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3907)) - Fix Head Start handovers breaking when a `chat.agent` also defines a `prepareMessages` hook. A handover hands the first turn's pending tool call to the agent as a tool-approval round whose trailing tool message must reach the model untouched. A `prepareMessages` hook that rewrites the last message (for example the recommended prompt-caching breakpoint) could disturb it, so the turn failed with "tool_use ids were found without tool_result". The agent now preserves that approval tail across `prepareMessages`, so caching and Head Start compose cleanly. ([#4018](https://github.com/triggerdotdev/trigger.dev/pull/4018)) - `chat.headStart` now accepts an `apiClient` option (base URL + access token), so the head-start route can create the session and trigger the agent run against a different project/environment than the warm server's ambient Trigger config. Useful when your `chat.agent` lives in a separate project from the app serving the route. Mirrors the `apiClient` option on `chat.createStartSessionAction`; your LLM provider keys stay in the `run` callback and are unaffected. ([#4018](https://github.com/triggerdotdev/trigger.dev/pull/4018)) ```ts export const POST = chat.headStart({ agentId: "my-agent", apiClient: { baseURL, accessToken }, run: async ({ chat }) => streamText({ ...chat.toStreamTextOptions({ tools }), model: anthropic("claude-sonnet-4-6"), }), }); ``` - `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](https://github.com/triggerdotdev/trigger.dev/pull/3963)) In a `chat.customAgent` loop, consume the handover on turn 0: ```ts 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. - Fix `chat.headStart` when `hydrateMessages` is registered. The warm route's step-1 partial now reaches the agent's accumulator on the hydrate path, so `onTurnComplete` carries the full first turn (the head-start user message included), tool-call handovers resume from step 2 instead of re-running step 1, and the assistant `messageId` stays stable across the handover. ([#3907](https://github.com/triggerdotdev/trigger.dev/pull/3907)) - Preserve reasoning parts across the `chat.headStart` handover. Extended-thinking models' step-1 reasoning now lands in the durable session history (and `onTurnComplete`) under the same assistant `messageId`, with provider metadata intact so Anthropic thinking signatures survive replays. ([#3907](https://github.com/triggerdotdev/trigger.dev/pull/3907)) - Add `triggerConfig` support to `chat.headStart()` and `chat.openSession()`, so the auto-triggered handover-prepare run inherits tags, queue, machine, and other session trigger options the same way `chat.createStartSessionAction()` does. The `chat:{chatId}` tag is prepended automatically. ([#3963](https://github.com/triggerdotdev/trigger.dev/pull/3963)) ```ts export const POST = chat.headStart({ agentId: "my-agent", triggerConfig: { tags: ["org:acme"], queue: "chat" }, run: async ({ chat }) => streamText({ ...chat.toStreamTextOptions(), model }), }); ``` Because the session is created once on the first head-start turn and is idempotent on the chat id, this is the only place to set those options for a head-start chat's lifetime. `chat.createStartSessionAction()` now also forwards `maxDuration`, `region`, and `lockToVersion` so both session entry points stay consistent. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) - Fix `chat.agent` HITL continuations on reasoning-heavy turns. Two changes that work together: ([#3719](https://github.com/triggerdotdev/trigger.dev/pull/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: [] }` 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: ```ts 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. - Type `chat.createStartSessionAction` against your chat agent so `clientData` is typed end-to-end on the first turn: ([#3684](https://github.com/triggerdotdev/trigger.dev/pull/3684)) ```ts 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. - `chat.createStartSessionAction` now accepts an `apiClient` option, so you can scope a chat session start to a specific environment's API config (`baseURL` / `accessToken`) without setting a global `TRIGGER_SECRET_KEY`. Useful when one server starts chats across more than one environment. ([#4018](https://github.com/triggerdotdev/trigger.dev/pull/4018)) ```ts const startSession = chat.createStartSessionAction("my-chat", { apiClient: { baseURL, accessToken }, }); await startSession({ chatId, clientData }); ``` - 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](https://github.com/triggerdotdev/trigger.dev/pull/3952)) ```ts // 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. - `useTriggerChatTransport` now recovers when restored session state points at a session that no longer exists in the current environment ([#3816](https://github.com/triggerdotdev/trigger.dev/pull/3816)) - 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](https://github.com/triggerdotdev/trigger.dev/pull/3920)) - Three fixes for custom agent loops (`chat.customAgent`, `chat.createSession`, and hand-rolled `MessageAccumulator` loops): ([#3936](https://github.com/triggerdotdev/trigger.dev/pull/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". - 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](https://github.com/triggerdotdev/trigger.dev/pull/3785)) Payload uploads use the same resolved `ApiClient` as the trigger call (including `requestOptions.clientConfig`), not only the global `apiClientManager.client` — so custom `baseURL`, access token, and preview branch apply to both presign and trigger. - 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](https://github.com/triggerdotdev/trigger.dev/pull/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. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3810)) - Add `region` to the runs list / retrieve API: filter runs by region (`runs.list({ region: "..." })` / `filter[region]=`) and read each run's executing region from the new `region` field on the response. ([#3612](https://github.com/triggerdotdev/trigger.dev/pull/3612)) - 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](https://github.com/triggerdotdev/trigger.dev/pull/3683)) ```ts 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"] }); ``` - 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](https://github.com/triggerdotdev/trigger.dev/pull/3970)) - Updated dependencies: - `@trigger.dev/core@4.5.0` ## 4.5.0-rc.7 ### Patch Changes - `@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](https://github.com/triggerdotdev/trigger.dev/pull/3937)) - `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](https://github.com/triggerdotdev/trigger.dev/pull/3963)) In a `chat.customAgent` loop, consume the handover on turn 0: ```ts 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. - Add `triggerConfig` support to `chat.headStart()` and `chat.openSession()`, so the auto-triggered handover-prepare run inherits tags, queue, machine, and other session trigger options the same way `chat.createStartSessionAction()` does. The `chat:{chatId}` tag is prepended automatically. ([#3963](https://github.com/triggerdotdev/trigger.dev/pull/3963)) ```ts export const POST = chat.headStart({ agentId: "my-agent", triggerConfig: { tags: ["org:acme"], queue: "chat" }, run: async ({ chat }) => streamText({ ...chat.toStreamTextOptions(), model }), }); ``` Because the session is created once on the first head-start turn and is idempotent on the chat id, this is the only place to set those options for a head-start chat's lifetime. `chat.createStartSessionAction()` now also forwards `maxDuration`, `region`, and `lockToVersion` so both session entry points stay consistent. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3952)) ```ts // 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](https://github.com/triggerdotdev/trigger.dev/pull/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". - 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](https://github.com/triggerdotdev/trigger.dev/pull/3970)) - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.7` ## 4.5.0-rc.6 ### Patch Changes - 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](https://github.com/triggerdotdev/trigger.dev/pull/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](https://github.com/triggerdotdev/trigger.dev/pull/3907)) - Fix `chat.headStart` when `hydrateMessages` is registered. The warm route's step-1 partial now reaches the agent's accumulator on the hydrate path, so `onTurnComplete` carries the full first turn (the head-start user message included), tool-call handovers resume from step 2 instead of re-running step 1, and the assistant `messageId` stays stable across the handover. ([#3907](https://github.com/triggerdotdev/trigger.dev/pull/3907)) - Preserve reasoning parts across the `chat.headStart` handover. Extended-thinking models' step-1 reasoning now lands in the durable session history (and `onTurnComplete`) under the same assistant `messageId`, with provider metadata intact so Anthropic thinking signatures survive replays. ([#3907](https://github.com/triggerdotdev/trigger.dev/pull/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](https://github.com/triggerdotdev/trigger.dev/pull/3920)) - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.6` ## 4.5.0-rc.5 ### Patch Changes - 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](https://github.com/triggerdotdev/trigger.dev/pull/3833)) - `useTriggerChatTransport` now recovers when restored session state points at a session that no longer exists in the current environment ([#3816](https://github.com/triggerdotdev/trigger.dev/pull/3816)) - 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](https://github.com/triggerdotdev/trigger.dev/pull/3785)) Payload uploads use the same resolved `ApiClient` as the trigger call (including `requestOptions.clientConfig`), not only the global `apiClientManager.client` — so custom `baseURL`, access token, and preview branch apply to both presign and trigger. - 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](https://github.com/triggerdotdev/trigger.dev/pull/3810)) - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.5` ## 4.5.0-rc.4 ### Patch Changes - 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](https://github.com/triggerdotdev/trigger.dev/pull/3790)) ```ts chat.agent({ tools: { readFile, search }, run: async ({ messages, tools, signal }) => streamText({ model, messages, tools, abortSignal: signal }), }); ``` Also exports `InferChatUIMessageFromTools` to derive the chat `UIMessage` type (typed tool parts) directly from a tool set. - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.4` ## 4.5.0-rc.3 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.3` ## 4.5.0-rc.2 ### Patch Changes - Fix `chat.agent` HITL continuations on reasoning-heavy turns. Two changes that work together: ([#3719](https://github.com/triggerdotdev/trigger.dev/pull/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: [] }` 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: ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/3683)) ```ts 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/core@4.5.0-rc.2` ## 4.5.0-rc.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.1` ## 4.5.0-rc.0 ### 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](https://github.com/triggerdotdev/trigger.dev/pull/3629)) ```ts 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(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](https://trigger.dev/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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) ```ts 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`](https://sdk.vercel.ai/docs/ai-sdk-ui/transport) (`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` 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](https://trigger.dev/docs/ai/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](https://trigger.dev/docs/ai-chat/overview) 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](https://github.com/triggerdotdev/trigger.dev/pull/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. ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/3542)) ```ts 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](https://trigger.dev/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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) ```ts const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract", }); chat.skills.set([await pdfSkill.local()]); ``` Built on the [AI SDK cookbook pattern](https://ai-sdk.dev/cookbook/guides/agent-skills) — 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](https://github.com/triggerdotdev/trigger.dev/pull/3546)) ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/3543)) - Type `chat.createStartSessionAction` against your chat agent so `clientData` is typed end-to-end on the first turn: ([#3684](https://github.com/triggerdotdev/trigger.dev/pull/3684)) ```ts 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](https://github.com/triggerdotdev/trigger.dev/pull/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]=`) and read each run's executing region from the new `region` field on the response. ([#3612](https://github.com/triggerdotdev/trigger.dev/pull/3612)) - Updated dependencies: - `@trigger.dev/core@4.5.0-rc.0` ## 4.4.6 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.4.6` ## 4.4.5 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.4.5` ## 4.4.4 ### Patch Changes - Define and manage AI prompts with `prompts.define()`. Create typesafe prompt templates with variables, resolve them at runtime, and manage versions and overrides from the dashboard without redeploying. ([#3244](https://github.com/triggerdotdev/trigger.dev/pull/3244)) - Add support for setting TTL (time-to-live) defaults at the task level and globally in trigger.config.ts, with per-trigger overrides still taking precedence ([#3196](https://github.com/triggerdotdev/trigger.dev/pull/3196)) - Adapted the CLI API client to propagate the trigger source via http headers. ([#3241](https://github.com/triggerdotdev/trigger.dev/pull/3241)) - Updated dependencies: - `@trigger.dev/core@4.4.4` ## 4.4.3 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.4.3` ## 4.4.2 ### Patch Changes - Add input streams for bidirectional communication with running tasks. Define typed input streams with `streams.input({ id })`, then consume inside tasks via `.wait()` (suspends the process), `.once()` (waits for next message), or `.on()` (subscribes to a continuous stream). Send data from backends with `.send(runId, data)` or from frontends with the new `useInputStreamSend` React hook. ([#3146](https://github.com/triggerdotdev/trigger.dev/pull/3146)) Upgrade S2 SDK from 0.17 to 0.22 with support for custom endpoints (s2-lite) via the new `endpoints` configuration, `AppendRecord.string()` API, and `maxInflightBytes` session option. - fix(sdk): batch triggerAndWait variants now return correct run.taskIdentifier instead of unknown ([#3080](https://github.com/triggerdotdev/trigger.dev/pull/3080)) - Add PAYLOAD_TOO_LARGE error to handle graceful recovery of sending batch trigger items with payloads that exceed the maximum payload size ([#3137](https://github.com/triggerdotdev/trigger.dev/pull/3137)) - Updated dependencies: - `@trigger.dev/core@4.4.2` ## 4.4.1 ### Patch Changes - Add OTEL metrics pipeline for task workers. Workers collect process CPU/memory, Node.js runtime metrics (event loop utilization, event loop delay, heap usage), and user-defined custom metrics via `otel.metrics.getMeter()`. Metrics are exported to ClickHouse with 10-second aggregation buckets and 1m/5m rollups, and are queryable through the dashboard query engine with typed attribute columns, `prettyFormat()` for human-readable values, and AI query support. ([#3061](https://github.com/triggerdotdev/trigger.dev/pull/3061)) - Updated dependencies: - `@trigger.dev/core@4.4.1` ## 4.4.0 ### Minor Changes - Added `query.execute()` which lets you query your Trigger.dev data using TRQL (Trigger Query Language) and returns results as typed JSON rows or CSV. It supports configurable scope (environment, project, or organization), time filtering via `period` or `from`/`to` ranges, and a `format` option for JSON or CSV output. ([#3060](https://github.com/triggerdotdev/trigger.dev/pull/3060)) ```typescript import { query } from "@trigger.dev/sdk"; import type { QueryTable } from "@trigger.dev/sdk"; // Basic untyped query const result = await query.execute( "SELECT run_id, status FROM runs LIMIT 10", ); // Type-safe query using QueryTable to pick specific columns const typedResult = await query.execute< QueryTable<"runs", "run_id" | "status" | "triggered_at"> >("SELECT run_id, status, triggered_at FROM runs LIMIT 10"); typedResult.results.forEach((row) => { console.log(row.run_id, row.status); // Fully typed }); // Aggregation query with inline types const stats = await query.execute<{ status: string; count: number }>( "SELECT status, COUNT(*) as count FROM runs GROUP BY status", { scope: "project", period: "30d" }, ); // CSV export const csv = await query.execute("SELECT run_id, status FROM runs", { format: "csv", period: "7d", }); console.log(csv.results); // Raw CSV string ``` ### Patch Changes - Add `maxDelay` option to debounce feature. This allows setting a maximum time limit for how long a debounced run can be delayed, ensuring execution happens within a specified window even with continuous triggers. ([#2984](https://github.com/triggerdotdev/trigger.dev/pull/2984)) ```typescript await myTask.trigger(payload, { debounce: { key: "my-key", delay: "5s", maxDelay: "30m", // Execute within 30 minutes regardless of continuous triggers }, }); ``` - Aligned the SDK's `getRunIdForOptions` logic with the Core package to handle semantic targets (`root`, `parent`) in root tasks. ([#2874](https://github.com/triggerdotdev/trigger.dev/pull/2874)) - Export `AnyOnStartAttemptHookFunction` type to allow defining `onStartAttempt` hooks for individual tasks. ([#2966](https://github.com/triggerdotdev/trigger.dev/pull/2966)) - Fixed a minor issue in the deployment command on distinguishing between local builds for the cloud vs local builds for self-hosting setups. ([#3070](https://github.com/triggerdotdev/trigger.dev/pull/3070)) - Updated dependencies: - `@trigger.dev/core@4.4.0` ## 4.3.3 ### Patch Changes - Add support for AI SDK v6 (Vercel AI SDK) ([#2919](https://github.com/triggerdotdev/trigger.dev/pull/2919)) - Updated peer dependency to allow `ai@^6.0.0` alongside v4 and v5 - Updated internal code to handle async validation from AI SDK v6's Schema type - Expose user-provided idempotency key and scope in task context. `ctx.run.idempotencyKey` now returns the original key passed to `idempotencyKeys.create()` instead of the hash, and `ctx.run.idempotencyKeyScope` shows the scope ("run", "attempt", or "global"). ([#2903](https://github.com/triggerdotdev/trigger.dev/pull/2903)) - Updated dependencies: - `@trigger.dev/core@4.3.3` ## 4.3.2 ### Patch Changes - Improve batch trigger error messages, especially when rate limited ([#2837](https://github.com/triggerdotdev/trigger.dev/pull/2837)) - Updated dependencies: - `@trigger.dev/core@4.3.2` ## 4.3.1 ### Patch Changes - feat: Support for new batch trigger system ([#2779](https://github.com/triggerdotdev/trigger.dev/pull/2779)) - feat(sdk): Support debouncing runs when triggering with new debounce options ([#2794](https://github.com/triggerdotdev/trigger.dev/pull/2794)) - Added support for idempotency reset ([#2777](https://github.com/triggerdotdev/trigger.dev/pull/2777)) - Updated dependencies: - `@trigger.dev/core@4.3.1` ## 4.3.0 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.3.0` ## 4.2.0 ### Patch Changes - fix(sdk): Re-export schemaTask types to prevent the TypeScript error TS2742: The inferred type of 'task' cannot be named without a reference to '@trigger.dev/core/v3'. This is likely not portable. ([#2735](https://github.com/triggerdotdev/trigger.dev/pull/2735)) - feat: add ability to set custom resource properties through trigger.config.ts or via the OTEL_RESOURCE_ATTRIBUTES env var ([#2704](https://github.com/triggerdotdev/trigger.dev/pull/2704)) - Updated dependencies: - `@trigger.dev/core@4.2.0` ## 4.1.2 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.1.2` ## 4.1.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.1.1` ## 4.1.0 ### Minor Changes - Realtime streams v2 ([#2632](https://github.com/triggerdotdev/trigger.dev/pull/2632)) - Prevent uncaught errors in the `onSuccess`, `onComplete`, and `onFailure` lifecycle hooks from failing attempts/runs. ([#2515](https://github.com/triggerdotdev/trigger.dev/pull/2515)) Deprecated the `onStart` lifecycle hook (which only fires before the `run` function on the first attempt). Replaced with `onStartAttempt` that fires before the run function on every attempt: ```ts export const taskWithOnStartAttempt = task({ id: "task-with-on-start-attempt", onStartAttempt: async ({ payload, ctx }) => { //... }, run: async (payload: any, { ctx }) => { //... }, }); // Default a global lifecycle hook using tasks tasks.onStartAttempt(({ ctx, payload, task }) => { console.log( `Run ${ctx.run.id} started on task ${task} attempt ${ctx.run.attempt.number}`, ctx.run, ); }); ``` If you want to execute code before just the first attempt, you can use the `onStartAttempt` function and check `ctx.run.attempt.number === 1`: ```ts /trigger/on-start-attempt.ts export const taskWithOnStartAttempt = task({ id: "task-with-on-start-attempt", onStartAttempt: async ({ payload, ctx }) => { if (ctx.run.attempt.number === 1) { console.log("Run started on attempt 1", ctx.run); } }, }); ``` ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.1.0` ## 4.0.7 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.7` ## 4.0.6 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.6` ## 4.0.5 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.5` ## 4.0.4 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.4` ## 4.0.3 ### Patch Changes - Added the heartbeats.yield utility to allow tasks that do continuous CPU-heavy work to heartbeat and continue running ([#2489](https://github.com/triggerdotdev/trigger.dev/pull/2489)) - Updated dependencies: - `@trigger.dev/core@4.0.3` ## 4.0.2 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.2` ## 4.0.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.1` ## 4.0.0 ### Major Changes - Trigger.dev v4 release. Please see our upgrade to v4 docs to view the full changelog: https://trigger.dev/docs/upgrade-to-v4 ([#1869](https://github.com/triggerdotdev/trigger.dev/pull/1869)) ### Patch Changes - fix: importing from runEngine/index.js breaks non-node runtimes ([#2328](https://github.com/triggerdotdev/trigger.dev/pull/2328)) - Run Engine 2.0 (alpha) ([#1575](https://github.com/triggerdotdev/trigger.dev/pull/1575)) - fix: Logging large objects is now much more performant and uses less memory ([#2263](https://github.com/triggerdotdev/trigger.dev/pull/2263)) - New internal idempotency implementation for trigger and batch trigger to prevent request retries from duplicating work ([#2256](https://github.com/triggerdotdev/trigger.dev/pull/2256)) - When you create a Waitpoint token using `wait.createToken()` you get a URL back that can be used to complete it by making an HTTP POST request. ([#2025](https://github.com/triggerdotdev/trigger.dev/pull/2025)) - feat: Support AI SDK 5.0. `ai.tool` now accepts either a schemaTask or a task with a provided jsonSchema ([#2396](https://github.com/triggerdotdev/trigger.dev/pull/2396)) - External Trace Correlation & OpenTelemetry Package Updates. ([#2334](https://github.com/triggerdotdev/trigger.dev/pull/2334)) | Package | Previous Version | New Version | Change Type | | ----------------------------------------- | ---------------- | ----------- | ------------------------------------ | | `@opentelemetry/api` | 1.9.0 | 1.9.0 | No change (stable API) | | `@opentelemetry/api-logs` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/core` | - | 2.0.1 | New dependency | | `@opentelemetry/exporter-logs-otlp-http` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/exporter-trace-otlp-http` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/instrumentation` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/instrumentation-fetch` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/resources` | 1.25.1 | 2.0.1 | Major update | | `@opentelemetry/sdk-logs` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/sdk-node` | 0.52.1 | - | Removed (functionality consolidated) | | `@opentelemetry/sdk-trace-base` | 1.25.1 | 2.0.1 | Major update | | `@opentelemetry/sdk-trace-node` | 1.25.1 | 2.0.1 | Major update | | `@opentelemetry/semantic-conventions` | 1.25.1 | 1.36.0 | Minor update | ### External trace correlation and propagation We will now correlate your external traces with trigger.dev traces and logs when using our external exporters: ```ts import { defineConfig } from "@trigger.dev/sdk"; import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; export default defineConfig({ project: process.env.TRIGGER_PROJECT_REF, dirs: ["./src/trigger"], telemetry: { logExporters: [ new OTLPLogExporter({ url: "https://api.axiom.co/v1/logs", headers: { Authorization: `Bearer ${process.env.AXIOM_TOKEN}`, "X-Axiom-Dataset": "test", }, }), ], exporters: [ new OTLPTraceExporter({ url: "https://api.axiom.co/v1/traces", headers: { Authorization: `Bearer ${process.env.AXIOM_TOKEN}`, "X-Axiom-Dataset": "test", }, }), ], }, maxDuration: 3600, }); ``` You can also now propagate your external trace context when calling back into your own backend infra from inside a trigger.dev task: ```ts import { otel, task } from "@trigger.dev/sdk"; import { context, propagation } from "@opentelemetry/api"; async function callNextjsApp() { return await otel.withExternalTrace(async () => { const headersObject = {}; // Now context.active() refers to your external trace context propagation.inject(context.active(), headersObject); const result = await fetch( "http://localhost:3000/api/demo-call-from-trigger", { headers: new Headers(headersObject), method: "POST", body: JSON.stringify({ message: "Hello from Trigger.dev", }), }, ); return result.json(); }); } export const myTask = task({ id: "my-task", run: async (payload: any) => { await callNextjsApp(); }, }); ``` - Add jsonSchema support when indexing tasks ([#2353](https://github.com/triggerdotdev/trigger.dev/pull/2353)) - Fixed an issue with realtime streams that timeout and resume streaming dropping chunks ([#1993](https://github.com/triggerdotdev/trigger.dev/pull/1993)) - Added and cleaned up the run ctx param: ([#2322](https://github.com/triggerdotdev/trigger.dev/pull/2322)) - New optional properties `ctx.run.parentTaskRunId` and `ctx.run.rootTaskRunId` reference the current run's root/parent ID. - Removed deprecated properties from `ctx` - Added a new `ctx.deployment` object that contains information about the deployment associated with the run. We also update `metadata.root` and `metadata.parent` to work even when the run is a "root" run (meaning it doesn't have a parent or a root associated run). This now works: ```ts metadata.root.set("foo", "bar"); metadata.parent.set("baz", 1); metadata.current().foo; // "bar" metadata.current().baz; // 1 ``` - The envvars.list() and retrieve() functions receive isSecret for each value. Secret values are always redacted. ([#1942](https://github.com/triggerdotdev/trigger.dev/pull/1942)) - Fix issue where realtime streams would cut off after 5 minutes ([#1952](https://github.com/triggerdotdev/trigger.dev/pull/1952)) - Deprecate toolTask and replace with `ai.tool(mySchemaTask)` ([#1863](https://github.com/triggerdotdev/trigger.dev/pull/1863)) - Display clickable links in Cursor terminal ([#1998](https://github.com/triggerdotdev/trigger.dev/pull/1998)) - Removes the `releaseConcurrencyOnWaitpoint` option on queues and the `releaseConcurrency` option on various wait functions. Replaced with the following default behavior: ([#2284](https://github.com/triggerdotdev/trigger.dev/pull/2284)) - Concurrency is never released when a run is first blocked via a waitpoint, at either the env or queue level. - Concurrency is always released when a run is checkpointed and shutdown, at both the env and queue level. Additionally, environment concurrency limits now have a new "Burst Factor", defaulting to 2.0x. The "Burst Factor" allows the environment-wide concurrency limit to be higher than any individual queue's concurrency limit. For example, if you have an environment concurrency limit of 100, and a Burst Factor of 2.0x, then you can execute up to 200 runs concurrently, but any one task/queue can still only execute 100 runs concurrently. We've done some work cleaning up the run statuses. The new statuses are: - `PENDING_VERSION`: Task is waiting for a version update because it cannot execute without additional information (task, queue, etc.) - `QUEUED`: Task is waiting to be executed by a worker - `DEQUEUED`: Task has been dequeued and is being sent to a worker to start executing. - `EXECUTING`: Task is currently being executed by a worker - `WAITING`: Task has been paused by the system, and will be resumed by the system - `COMPLETED`: Task has been completed successfully - `CANCELED`: Task has been canceled by the user - `FAILED`: Task has failed to complete, due to an error in the system - `CRASHED`: Task has crashed and won't be retried, most likely the worker ran out of resources, e.g. memory or storage - `SYSTEM_FAILURE`: Task has failed to complete, due to an error in the system - `DELAYED`: Task has been scheduled to run at a specific time - `EXPIRED`: Task has expired and won't be executed - `TIMED_OUT`: Task has reached it's maxDuration and has been stopped We've removed the following statuses: - `WAITING_FOR_DEPLOY`: This is no longer used, and is replaced by `PENDING_VERSION` - `FROZEN`: This is no longer used, and is replaced by `WAITING` - `INTERRUPTED`: This is no longer used - `REATTEMPTING`: This is no longer used, and is replaced by `EXECUTING` We've also added "boolean" helpers to runs returned via the API and from Realtime: - `isQueued`: Returns true when the status is `QUEUED`, `PENDING_VERSION`, or `DELAYED` - `isExecuting`: Returns true when the status is `EXECUTING`, `DEQUEUED`. These count against your concurrency limits. - `isWaiting`: Returns true when the status is `WAITING`. These do not count against your concurrency limits. - `isCompleted`: Returns true when the status is any of the completed statuses. - `isCanceled`: Returns true when the status is `CANCELED` - `isFailed`: Returns true when the status is any of the failed statuses. - `isSuccess`: Returns true when the status is `COMPLETED` This change adds the ability to easily detect which runs are being counted against your concurrency limit by filtering for both `EXECUTING` or `DEQUEUED`. - Add onCancel lifecycle hook ([#2022](https://github.com/triggerdotdev/trigger.dev/pull/2022)) - Provide realtime skipColumns option via untamperable public access tokens ([#2201](https://github.com/triggerdotdev/trigger.dev/pull/2201)) - Removed triggerAndPoll. It was never recommended so it's been removed. ([#2379](https://github.com/triggerdotdev/trigger.dev/pull/2379)) - Improve metadata flushing efficiency by collapsing operations ([#2106](https://github.com/triggerdotdev/trigger.dev/pull/2106)) - Upgrade to zod 3.25.76 ([#2352](https://github.com/triggerdotdev/trigger.dev/pull/2352)) - Specify a region override when triggering a run ([#2366](https://github.com/triggerdotdev/trigger.dev/pull/2366)) - Added runs.list filtering for queue and machine ([#2277](https://github.com/triggerdotdev/trigger.dev/pull/2277)) - maintain proper context in metadata.root and parent getters ([#1917](https://github.com/triggerdotdev/trigger.dev/pull/1917)) - v4: New lifecycle hooks ([#1817](https://github.com/triggerdotdev/trigger.dev/pull/1817)) - Updated dependencies: - `@trigger.dev/core@4.0.0` ## 4.0.0-v4-beta.28 ### Patch Changes - feat: Support AI SDK 5.0. `ai.tool` now accepts either a schemaTask or a task with a provided jsonSchema ([#2396](https://github.com/triggerdotdev/trigger.dev/pull/2396)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.28` ## 4.0.0-v4-beta.27 ### Patch Changes - External Trace Correlation & OpenTelemetry Package Updates. ([#2334](https://github.com/triggerdotdev/trigger.dev/pull/2334)) | Package | Previous Version | New Version | Change Type | | ----------------------------------------- | ---------------- | ----------- | ------------------------------------ | | `@opentelemetry/api` | 1.9.0 | 1.9.0 | No change (stable API) | | `@opentelemetry/api-logs` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/core` | - | 2.0.1 | New dependency | | `@opentelemetry/exporter-logs-otlp-http` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/exporter-trace-otlp-http` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/instrumentation` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/instrumentation-fetch` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/resources` | 1.25.1 | 2.0.1 | Major update | | `@opentelemetry/sdk-logs` | 0.52.1 | 0.203.0 | Major update | | `@opentelemetry/sdk-node` | 0.52.1 | - | Removed (functionality consolidated) | | `@opentelemetry/sdk-trace-base` | 1.25.1 | 2.0.1 | Major update | | `@opentelemetry/sdk-trace-node` | 1.25.1 | 2.0.1 | Major update | | `@opentelemetry/semantic-conventions` | 1.25.1 | 1.36.0 | Minor update | ### External trace correlation and propagation We will now correlate your external traces with trigger.dev traces and logs when using our external exporters: ```ts import { defineConfig } from "@trigger.dev/sdk"; import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; export default defineConfig({ project: process.env.TRIGGER_PROJECT_REF, dirs: ["./src/trigger"], telemetry: { logExporters: [ new OTLPLogExporter({ url: "https://api.axiom.co/v1/logs", headers: { Authorization: `Bearer ${process.env.AXIOM_TOKEN}`, "X-Axiom-Dataset": "test", }, }), ], exporters: [ new OTLPTraceExporter({ url: "https://api.axiom.co/v1/traces", headers: { Authorization: `Bearer ${process.env.AXIOM_TOKEN}`, "X-Axiom-Dataset": "test", }, }), ], }, maxDuration: 3600, }); ``` You can also now propagate your external trace context when calling back into your own backend infra from inside a trigger.dev task: ```ts import { otel, task } from "@trigger.dev/sdk"; import { context, propagation } from "@opentelemetry/api"; async function callNextjsApp() { return await otel.withExternalTrace(async () => { const headersObject = {}; // Now context.active() refers to your external trace context propagation.inject(context.active(), headersObject); const result = await fetch( "http://localhost:3000/api/demo-call-from-trigger", { headers: new Headers(headersObject), method: "POST", body: JSON.stringify({ message: "Hello from Trigger.dev", }), }, ); return result.json(); }); } export const myTask = task({ id: "my-task", run: async (payload: any) => { await callNextjsApp(); }, }); ``` - Add jsonSchema support when indexing tasks ([#2353](https://github.com/triggerdotdev/trigger.dev/pull/2353)) - Removed triggerAndPoll. It was never recommended so it's been removed. ([#2379](https://github.com/triggerdotdev/trigger.dev/pull/2379)) - Upgrade to zod 3.25.76 ([#2352](https://github.com/triggerdotdev/trigger.dev/pull/2352)) - Specify a region override when triggering a run ([#2366](https://github.com/triggerdotdev/trigger.dev/pull/2366)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.27` ## 4.0.0-v4-beta.26 ### Patch Changes - fix: importing from runEngine/index.js breaks non-node runtimes ([#2328](https://github.com/triggerdotdev/trigger.dev/pull/2328)) - Added and cleaned up the run ctx param: ([#2322](https://github.com/triggerdotdev/trigger.dev/pull/2322)) - New optional properties `ctx.run.parentTaskRunId` and `ctx.run.rootTaskRunId` reference the current run's root/parent ID. - Removed deprecated properties from `ctx` - Added a new `ctx.deployment` object that contains information about the deployment associated with the run. We also update `metadata.root` and `metadata.parent` to work even when the run is a "root" run (meaning it doesn't have a parent or a root associated run). This now works: ```ts metadata.root.set("foo", "bar"); metadata.parent.set("baz", 1); metadata.current().foo; // "bar" metadata.current().baz; // 1 ``` - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.26` ## 4.0.0-v4-beta.25 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.25` ## 4.0.0-v4-beta.24 ### Patch Changes - Removes the `releaseConcurrencyOnWaitpoint` option on queues and the `releaseConcurrency` option on various wait functions. Replaced with the following default behavior: ([#2284](https://github.com/triggerdotdev/trigger.dev/pull/2284)) - Concurrency is never released when a run is first blocked via a waitpoint, at either the env or queue level. - Concurrency is always released when a run is checkpointed and shutdown, at both the env and queue level. Additionally, environment concurrency limits now have a new "Burst Factor", defaulting to 2.0x. The "Burst Factor" allows the environment-wide concurrency limit to be higher than any individual queue's concurrency limit. For example, if you have an environment concurrency limit of 100, and a Burst Factor of 2.0x, then you can execute up to 200 runs concurrently, but any one task/queue can still only execute 100 runs concurrently. We've done some work cleaning up the run statuses. The new statuses are: - `PENDING_VERSION`: Task is waiting for a version update because it cannot execute without additional information (task, queue, etc.) - `QUEUED`: Task is waiting to be executed by a worker - `DEQUEUED`: Task has been dequeued and is being sent to a worker to start executing. - `EXECUTING`: Task is currently being executed by a worker - `WAITING`: Task has been paused by the system, and will be resumed by the system - `COMPLETED`: Task has been completed successfully - `CANCELED`: Task has been canceled by the user - `FAILED`: Task has failed to complete, due to an error in the system - `CRASHED`: Task has crashed and won't be retried, most likely the worker ran out of resources, e.g. memory or storage - `SYSTEM_FAILURE`: Task has failed to complete, due to an error in the system - `DELAYED`: Task has been scheduled to run at a specific time - `EXPIRED`: Task has expired and won't be executed - `TIMED_OUT`: Task has reached it's maxDuration and has been stopped We've removed the following statuses: - `WAITING_FOR_DEPLOY`: This is no longer used, and is replaced by `PENDING_VERSION` - `FROZEN`: This is no longer used, and is replaced by `WAITING` - `INTERRUPTED`: This is no longer used - `REATTEMPTING`: This is no longer used, and is replaced by `EXECUTING` We've also added "boolean" helpers to runs returned via the API and from Realtime: - `isQueued`: Returns true when the status is `QUEUED`, `PENDING_VERSION`, or `DELAYED` - `isExecuting`: Returns true when the status is `EXECUTING`, `DEQUEUED`. These count against your concurrency limits. - `isWaiting`: Returns true when the status is `WAITING`. These do not count against your concurrency limits. - `isCompleted`: Returns true when the status is any of the completed statuses. - `isCanceled`: Returns true when the status is `CANCELED` - `isFailed`: Returns true when the status is any of the failed statuses. - `isSuccess`: Returns true when the status is `COMPLETED` This change adds the ability to easily detect which runs are being counted against your concurrency limit by filtering for both `EXECUTING` or `DEQUEUED`. - Added runs.list filtering for queue and machine ([#2277](https://github.com/triggerdotdev/trigger.dev/pull/2277)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.24` ## 4.0.0-v4-beta.23 ### Patch Changes - fix: Logging large objects is now much more performant and uses less memory ([#2263](https://github.com/triggerdotdev/trigger.dev/pull/2263)) - New internal idempotency implementation for trigger and batch trigger to prevent request retries from duplicating work ([#2256](https://github.com/triggerdotdev/trigger.dev/pull/2256)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.23` ## 4.0.0-v4-beta.22 ### Patch Changes - Provide realtime skipColumns option via untamperable public access tokens ([#2201](https://github.com/triggerdotdev/trigger.dev/pull/2201)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.22` ## 4.0.0-v4-beta.21 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.21` ## 4.0.0-v4-beta.20 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.20` ## 4.0.0-v4-beta.19 ### Patch Changes - Improve metadata flushing efficiency by collapsing operations ([#2106](https://github.com/triggerdotdev/trigger.dev/pull/2106)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.19` ## 4.0.0-v4-beta.18 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.18` ## 4.0.0-v4-beta.17 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.17` ## 4.0.0-v4-beta.16 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.16` ## 4.0.0-v4-beta.15 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.15` ## 4.0.0-v4-beta.14 ### Patch Changes - When you create a Waitpoint token using `wait.createToken()` you get a URL back that can be used to complete it by making an HTTP POST request. ([#2025](https://github.com/triggerdotdev/trigger.dev/pull/2025)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.14` ## 4.0.0-v4-beta.13 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.13` ## 4.0.0-v4-beta.12 ### Patch Changes - Display clickable links in Cursor terminal ([#1998](https://github.com/triggerdotdev/trigger.dev/pull/1998)) - Add onCancel lifecycle hook ([#2022](https://github.com/triggerdotdev/trigger.dev/pull/2022)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.12` ## 4.0.0-v4-beta.11 ### Patch Changes - Fixed an issue with realtime streams that timeout and resume streaming dropping chunks ([#1993](https://github.com/triggerdotdev/trigger.dev/pull/1993)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.11` ## 4.0.0-v4-beta.10 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.10` ## 4.0.0-v4-beta.9 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.9` ## 4.0.0-v4-beta.8 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.8` ## 4.0.0-v4-beta.7 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.7` ## 4.0.0-v4-beta.6 ### Patch Changes - Fix issue where realtime streams would cut off after 5 minutes ([#1952](https://github.com/triggerdotdev/trigger.dev/pull/1952)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.6` ## 4.0.0-v4-beta.5 ### Patch Changes - The envvars.list() and retrieve() functions receive isSecret for each value. Secret values are always redacted. ([#1942](https://github.com/triggerdotdev/trigger.dev/pull/1942)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.5` ## 4.0.0-v4-beta.4 ### Patch Changes - maintain proper context in metadata.root and parent getters ([#1917](https://github.com/triggerdotdev/trigger.dev/pull/1917)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.4` ## 4.0.0-v4-beta.3 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.3` ## 4.0.0-v4-beta.2 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.2` ## 4.0.0-v4-beta.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.1` ## 4.0.0-v4-beta.0 ### Major Changes - Trigger.dev v4 release. Please see our upgrade to v4 docs to view the full changelog: https://trigger.dev/docs/upgrade-to-v4 ([#1869](https://github.com/triggerdotdev/trigger.dev/pull/1869)) ### Patch Changes - Run Engine 2.0 (alpha) ([#1575](https://github.com/triggerdotdev/trigger.dev/pull/1575)) - Deprecate toolTask and replace with `ai.tool(mySchemaTask)` ([#1863](https://github.com/triggerdotdev/trigger.dev/pull/1863)) - v4: New lifecycle hooks ([#1817](https://github.com/triggerdotdev/trigger.dev/pull/1817)) - Updated dependencies: - `@trigger.dev/core@4.0.0-v4-beta.0` ## 3.3.17 ### Patch Changes - Add support for two-phase deployments and task version pinning ([#1739](https://github.com/triggerdotdev/trigger.dev/pull/1739)) - Updated dependencies: - `@trigger.dev/core@3.3.17` ## 3.3.16 ### Patch Changes - You can add Alerts in the dashboard. One of these is a webhook, which this change greatly improves. ([#1703](https://github.com/triggerdotdev/trigger.dev/pull/1703)) The main change is that there's now an SDK function to verify and parse them (similar to Stripe SDK). ```ts const event = await webhooks.constructEvent( request, process.env.ALERT_WEBHOOK_SECRET!, ); ``` If the signature you provide matches the one from the dashboard when you create the webhook, you will get a nicely typed object back for these three types: - "alert.run.failed" - "alert.deployment.success" - "alert.deployment.failed" - Updated dependencies: - `@trigger.dev/core@3.3.16` ## 3.3.15 ### Patch Changes - Detect ffmpeg OOM errors, added manual OutOfMemoryError ([#1694](https://github.com/triggerdotdev/trigger.dev/pull/1694)) - Updated dependencies: - `@trigger.dev/core@3.3.15` ## 3.3.14 ### Patch Changes - Added the ability to retry runs that fail with an Out Of Memory (OOM) error on a larger machine. ([#1691](https://github.com/triggerdotdev/trigger.dev/pull/1691)) - Updated dependencies: - `@trigger.dev/core@3.3.14` ## 3.3.13 ### Patch Changes - Fixed issue with asResponse and withResponse not working on runs.retrieve ([#1648](https://github.com/triggerdotdev/trigger.dev/pull/1648)) - Updated dependencies: - `@trigger.dev/core@3.3.13` ## 3.3.12 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.3.12` ## 3.3.11 ### Patch Changes - Add support for specifying machine preset at trigger time. Works with any trigger function: ([#1608](https://github.com/triggerdotdev/trigger.dev/pull/1608)) ```ts // Same as usual, will use the machine preset on childTask, defaults to "small-1x" await childTask.trigger({ message: "Hello, world!" }); // This will override the task's machine preset and any defaults. Works with all trigger functions. await childTask.trigger( { message: "Hello, world!" }, { machine: "small-2x" }, ); await childTask.triggerAndWait( { message: "Hello, world!" }, { machine: "small-2x" }, ); await childTask.batchTrigger([ { payload: { message: "Hello, world!" }, options: { machine: "micro" } }, { payload: { message: "Hello, world!" }, options: { machine: "large-1x" } }, ]); await childTask.batchTriggerAndWait([ { payload: { message: "Hello, world!" }, options: { machine: "micro" } }, { payload: { message: "Hello, world!" }, options: { machine: "large-1x" } }, ]); await tasks.trigger( "child", { message: "Hello, world!" }, { machine: "small-2x" }, ); await tasks.batchTrigger("child", [ { payload: { message: "Hello, world!" }, options: { machine: "micro" } }, { payload: { message: "Hello, world!" }, options: { machine: "large-1x" } }, ]); ``` - Updated dependencies: - `@trigger.dev/core@3.3.11` ## 3.3.10 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.3.10` ## 3.3.9 ### Patch Changes - Adding ability to update parent run metadata from child runs/tasks ([#1563](https://github.com/triggerdotdev/trigger.dev/pull/1563)) - Updated dependencies: - `@trigger.dev/core@3.3.9` ## 3.3.8 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.3.8` ## 3.3.7 ### Patch Changes - - Fixes an issue in streams where "chunks" could get split across multiple reads ([#1549](https://github.com/triggerdotdev/trigger.dev/pull/1549)) - Fixed stopping the run subscription after a run is finished, when using useRealtimeRun or useRealtimeRunWithStreams - Added an `onComplete` callback to `useRealtimeRun` and `useRealtimeRunWithStreams` - Optimized the run subscription to reduce unnecessary updates - Updated dependencies: - `@trigger.dev/core@3.3.7` ## 3.3.6 ### Patch Changes - Realtime streams now powered by electric. Also, this change fixes a realtime bug that was causing too many re-renders, even on records that didn't change ([#1541](https://github.com/triggerdotdev/trigger.dev/pull/1541)) - Add option to trigger batched items sequentially, and default to parallel triggering which is faster ([#1536](https://github.com/triggerdotdev/trigger.dev/pull/1536)) - Updated dependencies: - `@trigger.dev/core@3.3.6` ## 3.3.5 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.3.5` ## 3.3.4 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.3.4` ## 3.3.3 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.3.3` ## 3.3.2 ### Patch Changes - Add one-time use public tokens to trigger and batch trigger ([#1515](https://github.com/triggerdotdev/trigger.dev/pull/1515)) - Fix for waiting for realtime streams to finish ([#1520](https://github.com/triggerdotdev/trigger.dev/pull/1520)) - Updated dependencies: - `@trigger.dev/core@3.3.2` ## 3.3.1 ### Patch Changes - Fixed the missing icons in trigger spans ([#1506](https://github.com/triggerdotdev/trigger.dev/pull/1506)) - Public access token scopes with just tags or just a batch can now access runs that have those tags or are in the batch. Previously, the only way to access a run was to have a specific scope for that exact run. ([#1511](https://github.com/triggerdotdev/trigger.dev/pull/1511)) - Updated dependencies: - `@trigger.dev/core@3.3.1` ## 3.3.0 ### Minor Changes - Improved Batch Triggering: ([#1502](https://github.com/triggerdotdev/trigger.dev/pull/1502)) - The new Batch Trigger endpoint is now asynchronous and supports up to 500 runs per request. - The new endpoint also supports triggering multiple different tasks in a single batch request (support in the SDK coming soon). - The existing `batchTrigger` method now supports the new endpoint, and shouldn't require any changes to your code. - Idempotency keys now expire after 24 hours, and you can customize the expiration time when creating a new key by using the `idempotencyKeyTTL` parameter: ```ts await myTask.batchTrigger([{ payload: { foo: "bar" } }], { idempotencyKey: "my-key", idempotencyKeyTTL: "60s", }); // Works for individual items as well: await myTask.batchTrigger([ { payload: { foo: "bar" }, options: { idempotencyKey: "my-key", idempotencyKeyTTL: "60s" }, }, ]); // And `trigger`: await myTask.trigger( { foo: "bar" }, { idempotencyKey: "my-key", idempotencyKeyTTL: "60s" }, ); ``` ### Breaking Changes - We've removed the `idempotencyKey` option from `triggerAndWait` and `batchTriggerAndWait`, because it can lead to permanently frozen runs in deployed tasks. We're working on upgrading our entire system to support idempotency keys on these methods, and we'll re-add the option once that's complete. ### Patch Changes - Added new batch.trigger and batch.triggerByTask methods that allows triggering multiple different tasks in a single batch: ([#1502](https://github.com/triggerdotdev/trigger.dev/pull/1502)) ```ts import { batch } from "@trigger.dev/sdk/v3"; import type { myTask1, myTask2 } from "./trigger/tasks"; // Somewhere in your backend code const response = await batch.trigger([ { id: "task1", payload: { foo: "bar" } }, { id: "task2", payload: { baz: "qux" } }, ]); for (const run of response.runs) { if (run.ok) { console.log(run.output); } else { console.error(run.error); } } ``` Or if you are inside of a task, you can use `triggerByTask`: ```ts import { batch, task, runs } from "@trigger.dev/sdk/v3"; export const myParentTask = task({ id: "myParentTask", run: async () => { const response = await batch.triggerByTask([ { task: myTask1, payload: { foo: "bar" } }, { task: myTask2, payload: { baz: "qux" } }, ]); const run1 = await runs.retrieve(response.runs[0]); console.log(run1.output); // typed as { foo: string } const run2 = await runs.retrieve(response.runs[1]); console.log(run2.output); // typed as { baz: string } const response2 = await batch.triggerByTaskAndWait([ { task: myTask1, payload: { foo: "bar" } }, { task: myTask2, payload: { baz: "qux" } }, ]); if (response2.runs[0].ok) { console.log(response2.runs[0].output); // typed as { foo: string } } if (response2.runs[1].ok) { console.log(response2.runs[1].output); // typed as { baz: string } } }, }); export const myTask1 = task({ id: "myTask1", run: async () => { return { foo: "bar", }; }, }); export const myTask2 = task({ id: "myTask2", run: async () => { return { baz: "qux", }; }, }); ``` - Added ability to subscribe to a batch of runs using runs.subscribeToBatch ([#1502](https://github.com/triggerdotdev/trigger.dev/pull/1502)) - Updated dependencies: - `@trigger.dev/core@3.3.0` ## 3.2.2 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.2.2` ## 3.2.1 ### Patch Changes - React hooks now all accept accessToken and baseURL options so the use of the Provider is no longer necessary ([#1486](https://github.com/triggerdotdev/trigger.dev/pull/1486)) - Upgrade zod to latest (3.23.8) ([#1484](https://github.com/triggerdotdev/trigger.dev/pull/1484)) - Realtime streams ([#1470](https://github.com/triggerdotdev/trigger.dev/pull/1470)) - Updated dependencies: - `@trigger.dev/core@3.2.1` ## 3.2.0 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.2.0` ## 3.1.2 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.1.2` ## 3.1.1 ### Patch Changes - Remove browser export condition - not necessary with the react-hooks package that uses core ([#1455](https://github.com/triggerdotdev/trigger.dev/pull/1455)) - Updated dependencies: - `@trigger.dev/core@3.1.1` ## 3.1.0 ### Minor Changes - Access run status updates in realtime, from your server or from your frontend ([#1402](https://github.com/triggerdotdev/trigger.dev/pull/1402)) ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.1.0` ## 3.0.13 ### Patch Changes - README updates ([#1408](https://github.com/triggerdotdev/trigger.dev/pull/1408)) - Updated dependencies: - `@trigger.dev/core@3.0.13` ## 3.0.12 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.0.12` ## 3.0.11 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.0.11` ## 3.0.10 ### Patch Changes - Adding maxDuration to tasks to allow timing out runs after they exceed a certain number of seconds ([#1377](https://github.com/triggerdotdev/trigger.dev/pull/1377)) - Updated dependencies: - `@trigger.dev/core@3.0.10` ## 3.0.9 ### Patch Changes - Removed the inline-code accessory from the logs when calling trigger or batchTrigger from a run ([#1364](https://github.com/triggerdotdev/trigger.dev/pull/1364)) - Updated dependencies: - `@trigger.dev/core@3.0.9` ## 3.0.8 ### Patch Changes - Add Run metadata to allow for storing up to 4KB of data on a run and update it during the run ([#1357](https://github.com/triggerdotdev/trigger.dev/pull/1357)) - Updated dependencies: - `@trigger.dev/core@3.0.8` ## 3.0.7 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@3.0.7` ## 3.0.6 ### Patch Changes - e79f0cc84: runs.retrieve() now includes details about related runs (root, parent, and children) as well how how the runs were triggered and if they are in a batch - Updated dependencies [4e0bc485a] - @trigger.dev/core@3.0.6 ## 3.0.5 ### Patch Changes - @trigger.dev/core@3.0.5 ## 3.0.4 ### Patch Changes - 4adc773c7: Auto-resolve payload/output presigned urls when retrieving a run with runs.retrieve - Updated dependencies [4adc773c7] - @trigger.dev/core@3.0.4 ## 3.0.3 ### Patch Changes - Updated dependencies [3d53d4c08] - @trigger.dev/core@3.0.3 ## 3.0.2 ### Patch Changes - @trigger.dev/core@3.0.2 ## 3.0.1 ### Patch Changes - 3aa581179: Fixing false-positive package version mismatches - Updated dependencies [3aa581179] - @trigger.dev/core@3.0.1 ## 3.0.0 ### Major Changes - cf13fbdf3: Release 3.0.0 - 395abe1b9: Updates to support Trigger.dev v3 ### Patch Changes - b66d5525e: add machine config and secure zod connection - 9491a1649: Implement task.onSuccess/onFailure and config.onSuccess/onFailure - b271742dc: Configurable log levels in the config file and via env var - 0591db5f2: Fixes for continuing after waits - f9ec66c56: New Build System - 8cae1d087: Fix trigger functions for custom queues - 3a1b0c486: v3: Environment variable management API and SDK, along with resolveEnvVars CLI hook - 979bee50d: Fix return type of runs.retrieve, and allow passing the type of the task to runs.retrieve - b68012f81: Make msw a normal dependency (for now) to fix Module Not Found error in Next.js. It turns out that webpack will "hoist" dynamically imported modules and attempt to resolve them at build time, even though it's an optional peer dep: https://x.com/maverickdotdev/status/1782465214308319404 - 203e00208: Add runs.retrieve management API method to get info about a run by run ID - 1b90ffbb8: v3: Usage tracking - 51bb4c887: Fix for calling trigger and passing a custom queue - 4986bfda2: Export queue from the SDK - 086a0f95c: Extract common trigger code into internal functions and add a tasks.batchTriggerAndWait function - 4f95c9de4: v3: recover from server rate limiting errors in a more reliable way - 0591db5f2: Rollback to try and fix some dependent attempt issues - 8578c9b28: Support self-hosters pushing to a custom registry when running deploy - 0e77e7ef7: v3: Trigger delayed runs and reschedule them - ecf1110ab: v3: Export AbortTaskRunError from @trigger.dev/sdk/v3 - f854cb90e: Added replayRun function to the SDK - 44e1b8754: Improve the SDK function types and expose a new APIError instead of the APIResult type - 55264657d: You can now add tags to runs and list runs using them - 6d9dfbc75: Add configure function to be able to configure the SDK manually - ecef19966: Use global setTimeout to ensure cross-runtime support - 719c0a0b9: Fixed incorrect span timings around checkpoints by implementing a precise wall clock that resets after restores - 4986bfda2: Adding task with a triggerSource of schedule - e9a63a486: Lock SDK and CLI deps on exact core version - 374edef02: Updates the `trigger`, `batchTrigger` and their `*AndWait` variants to use the first parameter for the payload/items, and the second parameter for options. Before: ```ts await yourTask.trigger({ payload: { foo: "bar" }, options: { idempotencyKey: "key_1234" }, }); await yourTask.triggerAndWait({ payload: { foo: "bar" }, options: { idempotencyKey: "key_1234" }, }); await yourTask.batchTrigger({ items: [{ payload: { foo: "bar" } }, { payload: { foo: "baz" } }], }); await yourTask.batchTriggerAndWait({ items: [{ payload: { foo: "bar" } }, { payload: { foo: "baz" } }], }); ``` After: ```ts await yourTask.trigger({ foo: "bar" }, { idempotencyKey: "key_1234" }); await yourTask.triggerAndWait({ foo: "bar" }, { idempotencyKey: "key_1234" }); await yourTask.batchTrigger([ { payload: { foo: "bar" } }, { payload: { foo: "baz" } }, ]); await yourTask.batchTriggerAndWait([ { payload: { foo: "bar" } }, { payload: { foo: "baz" } }, ]); ``` We've also changed the API of the `triggerAndWait` result. Before, if the subtask that was triggered finished with an error, we would automatically "rethrow" the error in the parent task. Now instead we're returning a `TaskRunResult` object that allows you to discriminate between successful and failed runs in the subtask: Before: ```ts try { const result = await yourTask.triggerAndWait({ foo: "bar" }); // result is the output of your task console.log("result", result); } catch (error) { // handle subtask errors here } ``` After: ```ts const result = await yourTask.triggerAndWait({ foo: "bar" }); if (result.ok) { console.log(`Run ${result.id} succeeded with output`, result.output); } else { console.log(`Run ${result.id} failed with error`, result.error); } ``` - 26093896d: When using idempotency keys, triggerAndWait and batchTriggerAndWait will still work even if the existing runs have already been completed (or even partially completed, in the case of batchTriggerAndWait) - TaskRunExecutionResult.id is now the run friendlyId, not the attempt friendlyId - A single TaskRun can now have many batchItems, in the case of batchTriggerAndWait while using idempotency keys - A run’s idempotencyKey is now added to the ctx as well as the TaskEvent and displayed in the span view - When resolving batchTriggerAndWait, the runtimes no longer reject promises, leading to an error in the parent task - b68012f81: Move to our global system from AsyncLocalStorage for the current task context storage - c9e1a3e9c: Remove unimplemented batchOptions - cf13fbdf3: Add triggerAndWait().unwrap() to more easily get at the output or throw the subtask error - 3f8b6d8fc: v2: Better handle recovering from platform communication errors by auto-yielding back to the platform in case of temporary API failures - 1281d40e4: When a v2 run hits the rate limit, reschedule with the reset date - ba71f959e: Management SDK overhaul and adding the runs.list API - 7c36a1a4b: v3: Adding SDK functions for triggering tasks in a typesafe way, without importing task file - f93eae300: Dynamically import superjson and fix some bundling issues - c405ae711: Added timezone support to schedules - 34ca7667d: v3: Include presigned urls for downloading large payloads and outputs when using runs.retrieve - 8ba998794: Added declarative cron schedules - f854cb90e: Added cancelRun to the SDK - 4986bfda2: Added a new global - Task Catalog - to better handle task metadata - b68012f81: Extracting out all the non-SDK related features from the main @trigger.dev/core/v3 export - 8578c9b28: Remove msw and retry.interceptFetch - Updated dependencies [ed2a26c86] - Updated dependencies [c702d6a9c] - Updated dependencies [9882d66f8] - Updated dependencies [b66d5525e] - Updated dependencies [e3db25739] - Updated dependencies [9491a1649] - Updated dependencies [1670c4c41] - Updated dependencies [b271742dc] - Updated dependencies [cf13fbdf3] - Updated dependencies [dbda820a7] - Updated dependencies [4986bfda2] - Updated dependencies [eb6012628] - Updated dependencies [f9ec66c56] - Updated dependencies [f7d32b83b] - Updated dependencies [09413a62a] - Updated dependencies [3a1b0c486] - Updated dependencies [203e00208] - Updated dependencies [b4f9b70ae] - Updated dependencies [1b90ffbb8] - Updated dependencies [5cf90da72] - Updated dependencies [9af2570da] - Updated dependencies [7ea8532cc] - Updated dependencies [1477a2e30] - Updated dependencies [4f95c9de4] - Updated dependencies [83dc87155] - Updated dependencies [d490bc5cb] - Updated dependencies [e3cf456c6] - Updated dependencies [14c2bdf89] - Updated dependencies [9491a1649] - Updated dependencies [0ed93a748] - Updated dependencies [8578c9b28] - Updated dependencies [0e77e7ef7] - Updated dependencies [e417aca87] - Updated dependencies [568da0178] - Updated dependencies [c738ef39c] - Updated dependencies [ece6ca678] - Updated dependencies [f854cb90e] - Updated dependencies [0e919f56f] - Updated dependencies [44e1b8754] - Updated dependencies [55264657d] - Updated dependencies [6d9dfbc75] - Updated dependencies [e337b2165] - Updated dependencies [719c0a0b9] - Updated dependencies [4986bfda2] - Updated dependencies [e30beb779] - Updated dependencies [68d32429b] - Updated dependencies [374edef02] - Updated dependencies [e04d44866] - Updated dependencies [26093896d] - Updated dependencies [55d1f8c67] - Updated dependencies [c405ae711] - Updated dependencies [9e5382951] - Updated dependencies [b68012f81] - Updated dependencies [098932ea9] - Updated dependencies [68d32429b] - Updated dependencies [9835f4ec5] - Updated dependencies [3f8b6d8fc] - Updated dependencies [fde939a30] - Updated dependencies [1281d40e4] - Updated dependencies [ba71f959e] - Updated dependencies [395abe1b9] - Updated dependencies [03b104a3d] - Updated dependencies [f93eae300] - Updated dependencies [5ae3da6b4] - Updated dependencies [c405ae711] - Updated dependencies [34ca7667d] - Updated dependencies [8ba998794] - Updated dependencies [62c9a5b71] - Updated dependencies [392453e8a] - Updated dependencies [8578c9b28] - Updated dependencies [6a379e4e9] - Updated dependencies [f854cb90e] - Updated dependencies [584c7da5d] - Updated dependencies [4986bfda2] - Updated dependencies [e69ffd314] - Updated dependencies [b68012f81] - Updated dependencies [39885a427] - Updated dependencies [8578c9b28] - Updated dependencies [e69ffd314] - Updated dependencies [8578c9b28] - Updated dependencies [f04041744] - Updated dependencies [d934feb02] - @trigger.dev/core@3.0.0 ## 3.0.0-beta.55 ### Patch Changes - 0591db5f2: Fixes for continuing after waits - @trigger.dev/core@3.0.0-beta.55 - @trigger.dev/core-backend@3.0.0-beta.55 ## 3.0.0-beta.54 ### Patch Changes - 728eeeff6: Rollback to try and fix some dependent attempt issues - @trigger.dev/core@3.0.0-beta.54 - @trigger.dev/core-backend@3.0.0-beta.54 ## 3.0.0-beta.53 ### Patch Changes - Updated dependencies [5cf90da72] - @trigger.dev/core@3.0.0-beta.53 - @trigger.dev/core-backend@3.0.0-beta.53 ## 3.0.0-beta.52 ### Patch Changes - 8cae1d087: Fix trigger functions for custom queues - Updated dependencies [9882d66f8] - Updated dependencies [09413a62a] - @trigger.dev/core@3.0.0-beta.52 - @trigger.dev/core-backend@3.0.0-beta.52 ## 3.0.0-beta.51 ### Patch Changes - 979bee50d: Fix return type of runs.retrieve, and allow passing the type of the task to runs.retrieve - 086a0f95c: Extract common trigger code into internal functions and add a tasks.batchTriggerAndWait function - 55264657d: You can now add tags to runs and list runs using them - Updated dependencies [55264657d] - @trigger.dev/core@3.0.0-beta.51 - @trigger.dev/core-backend@3.0.0-beta.51 ## 3.0.0-beta.50 ### Patch Changes - 8ba998794: Added declarative cron schedules - Updated dependencies [8ba998794] - @trigger.dev/core@3.0.0-beta.50 - @trigger.dev/core-backend@3.0.0-beta.50 ## 3.0.0-beta.49 ### Patch Changes - Updated dependencies [dbda820a7] - Updated dependencies [e417aca87] - Updated dependencies [d934feb02] - @trigger.dev/core@3.0.0-beta.49 - @trigger.dev/core-backend@3.0.0-beta.49 ## 3.0.0-beta.48 ### Patch Changes - ecf1110ab: v3: Export AbortTaskRunError from @trigger.dev/sdk/v3 - @trigger.dev/core@3.0.0-beta.48 - @trigger.dev/core-backend@3.0.0-beta.48 ## 3.0.0-beta.47 ### Patch Changes - 4f95c9de4: v3: recover from server rate limiting errors in a more reliable way - Updated dependencies [4f95c9de4] - Updated dependencies [e04d44866] - @trigger.dev/core@3.0.0-beta.47 - @trigger.dev/core-backend@3.0.0-beta.47 ## 3.0.0-beta.46 ### Patch Changes - Updated dependencies [14c2bdf89] - @trigger.dev/core@3.0.0-beta.46 - @trigger.dev/core-backend@3.0.0-beta.46 ## 3.0.0-beta.45 ### Patch Changes - 0e77e7ef7: v3: Trigger delayed runs and reschedule them - Updated dependencies [0e77e7ef7] - Updated dependencies [568da0178] - Updated dependencies [5ae3da6b4] - @trigger.dev/core@3.0.0-beta.45 - @trigger.dev/core-backend@3.0.0-beta.45 ## 3.0.0-beta.44 ### Patch Changes - Updated dependencies [39885a427] - @trigger.dev/core@3.0.0-beta.44 - @trigger.dev/core-backend@3.0.0-beta.44 ## 3.0.0-beta.43 ### Patch Changes - 34ca7667d: v3: Include presigned urls for downloading large payloads and outputs when using runs.retrieve - Updated dependencies [34ca7667d] - @trigger.dev/core@3.0.0-beta.43 - @trigger.dev/core-backend@3.0.0-beta.43 ## 3.0.0-beta.42 ### Patch Changes - ecef19966: Use global setTimeout to ensure cross-runtime support - @trigger.dev/core@3.0.0-beta.42 - @trigger.dev/core-backend@3.0.0-beta.42 ## 3.0.0-beta.41 ### Patch Changes - 7c36a1a4b: v3: Adding SDK functions for triggering tasks in a typesafe way, without importing task file - @trigger.dev/core@3.0.0-beta.41 - @trigger.dev/core-backend@3.0.0-beta.41 ## 3.0.0-beta.40 ### Patch Changes - Updated dependencies [55d1f8c67] - Updated dependencies [098932ea9] - Updated dependencies [9835f4ec5] - @trigger.dev/core@3.0.0-beta.40 - @trigger.dev/core-backend@3.0.0-beta.40 ## 3.0.0-beta.39 ### Patch Changes - @trigger.dev/core@3.0.0-beta.39 - @trigger.dev/core-backend@3.0.0-beta.39 ## 3.0.0-beta.38 ### Patch Changes - 1b90ffbb8: v3: Usage tracking - c405ae711: Added timezone support to schedules - Updated dependencies [1b90ffbb8] - Updated dependencies [0ed93a748] - Updated dependencies [c405ae711] - Updated dependencies [c405ae711] - @trigger.dev/core@3.0.0-beta.38 - @trigger.dev/core-backend@3.0.0-beta.38 ## 3.0.0-beta.37 ### Patch Changes - Updated dependencies [68d32429b] - Updated dependencies [68d32429b] - @trigger.dev/core@3.0.0-beta.37 - @trigger.dev/core-backend@3.0.0-beta.37 ## 3.0.0-beta.36 ### Patch Changes - 51bb4c887: Fix for calling trigger and passing a custom queue - ba71f959e: Management SDK overhaul and adding the runs.list API - Updated dependencies [b4f9b70ae] - Updated dependencies [ba71f959e] - @trigger.dev/core@3.0.0-beta.36 - @trigger.dev/core-backend@3.0.0-beta.36 ## 3.0.0-beta.35 ### Patch Changes - Updated dependencies [ece6ca678] - Updated dependencies [e69ffd314] - Updated dependencies [e69ffd314] - @trigger.dev/core@3.0.0-beta.35 - @trigger.dev/core-backend@3.0.0-beta.35 ## 3.0.0-beta.34 ### Patch Changes - 3a1b0c486: v3: Environment variable management API and SDK, along with resolveEnvVars CLI hook - 3f8b6d8fc: v2: Better handle recovering from platform communication errors by auto-yielding back to the platform in case of temporary API failures - 1281d40e4: When a v2 run hits the rate limit, reschedule with the reset date - Updated dependencies [3a1b0c486] - Updated dependencies [3f8b6d8fc] - Updated dependencies [1281d40e4] - @trigger.dev/core@3.0.0-beta.34 - @trigger.dev/core-backend@3.0.0-beta.34 ## 3.0.0-beta.33 ### Patch Changes - Updated dependencies [6a379e4e9] - @trigger.dev/core@3.0.0-beta.33 - @trigger.dev/core-backend@3.0.0-beta.33 ## 3.0.0-beta.32 ### Patch Changes - @trigger.dev/core@3.0.0-beta.32 - @trigger.dev/core-backend@3.0.0-beta.32 ## 3.0.0-beta.31 ### Patch Changes - @trigger.dev/core@3.0.0-beta.31 - @trigger.dev/core-backend@3.0.0-beta.31 ## 3.0.0-beta.30 ### Patch Changes - Updated dependencies [1477a2e30] - Updated dependencies [0e919f56f] - @trigger.dev/core@3.0.0-beta.30 - @trigger.dev/core-backend@3.0.0-beta.30 ## 3.0.0-beta.29 ### Patch Changes - @trigger.dev/core@3.0.0-beta.29 - @trigger.dev/core-backend@3.0.0-beta.29 ## 3.0.0-beta.28 ### Patch Changes - 6d9dfbc75: Add configure function to be able to configure the SDK manually - Updated dependencies [d490bc5cb] - Updated dependencies [6d9dfbc75] - @trigger.dev/core@3.0.0-beta.28 - @trigger.dev/core-backend@3.0.0-beta.28 ## 3.0.0-beta.27 ### Patch Changes - 203e00208: Add runs.retrieve management API method to get info about a run by run ID - Updated dependencies [1670c4c41] - Updated dependencies [203e00208] - @trigger.dev/core@3.0.0-beta.27 - @trigger.dev/core-backend@3.0.0-beta.27 ## 3.0.0-beta.26 ### Patch Changes - @trigger.dev/core@3.0.0-beta.26 - @trigger.dev/core-backend@3.0.0-beta.26 ## 3.0.0-beta.25 ### Patch Changes - Updated dependencies [e337b2165] - Updated dependencies [9e5382951] - @trigger.dev/core@3.0.0-beta.25 - @trigger.dev/core-backend@3.0.0-beta.25 ## 3.0.0-beta.24 ### Patch Changes - Updated dependencies [83dc87155] - @trigger.dev/core@3.0.0-beta.24 - @trigger.dev/core-backend@3.0.0-beta.24 ## 3.0.0-beta.23 ### Patch Changes - @trigger.dev/core@3.0.0-beta.23 - @trigger.dev/core-backend@3.0.0-beta.23 ## 3.0.0-beta.22 ### Patch Changes - @trigger.dev/core@3.0.0-beta.22 - @trigger.dev/core-backend@3.0.0-beta.22 ## 3.0.0-beta.21 ### Patch Changes - 9491a1649: Implement task.onSuccess/onFailure and config.onSuccess/onFailure - Updated dependencies [9491a1649] - Updated dependencies [9491a1649] - @trigger.dev/core@3.0.0-beta.21 - @trigger.dev/core-backend@3.0.0-beta.21 ## 3.0.0-beta.20 ### Patch Changes - Updated dependencies [e3db25739] - @trigger.dev/core@3.0.0-beta.20 - @trigger.dev/core-backend@3.0.0-beta.20 ## 3.0.0-beta.19 ### Patch Changes - e9a63a486: Lock SDK and CLI deps on exact core version - @trigger.dev/core@3.0.0-beta.19 - @trigger.dev/core-backend@3.0.0-beta.19 ## 3.0.0-beta.18 ### Patch Changes - b68012f81: Make msw a normal dependency (for now) to fix Module Not Found error in Next.js. It turns out that webpack will "hoist" dynamically imported modules and attempt to resolve them at build time, even though it's an optional peer dep: https://x.com/maverickdotdev/status/1782465214308319404 - b68012f81: Move to our global system from AsyncLocalStorage for the current task context storage - b68012f81: Extracting out all the non-SDK related features from the main @trigger.dev/core/v3 export - Updated dependencies [b68012f81] - Updated dependencies [b68012f81] - @trigger.dev/core@3.0.0-beta.18 - @trigger.dev/core-backend@3.0.0-beta.18 ## 3.0.0-beta.17 ### Patch Changes - @trigger.dev/core@3.0.0-beta.17 - @trigger.dev/core-backend@3.0.0-beta.17 ## 3.0.0-beta.16 ### Patch Changes - Updated dependencies [ed2a26c86] - @trigger.dev/core@3.0.0-beta.16 - @trigger.dev/core-backend@3.0.0-beta.16 ## 3.0.0-beta.15 ### Patch Changes - 374edef02: Updates the `trigger`, `batchTrigger` and their `*AndWait` variants to use the first parameter for the payload/items, and the second parameter for options. Before: ```ts await yourTask.trigger({ payload: { foo: "bar" }, options: { idempotencyKey: "key_1234" }, }); await yourTask.triggerAndWait({ payload: { foo: "bar" }, options: { idempotencyKey: "key_1234" }, }); await yourTask.batchTrigger({ items: [{ payload: { foo: "bar" } }, { payload: { foo: "baz" } }], }); await yourTask.batchTriggerAndWait({ items: [{ payload: { foo: "bar" } }, { payload: { foo: "baz" } }], }); ``` After: ```ts await yourTask.trigger({ foo: "bar" }, { idempotencyKey: "key_1234" }); await yourTask.triggerAndWait({ foo: "bar" }, { idempotencyKey: "key_1234" }); await yourTask.batchTrigger([ { payload: { foo: "bar" } }, { payload: { foo: "baz" } }, ]); await yourTask.batchTriggerAndWait([ { payload: { foo: "bar" } }, { payload: { foo: "baz" } }, ]); ``` We've also changed the API of the `triggerAndWait` result. Before, if the subtask that was triggered finished with an error, we would automatically "rethrow" the error in the parent task. Now instead we're returning a `TaskRunResult` object that allows you to discriminate between successful and failed runs in the subtask: Before: ```ts try { const result = await yourTask.triggerAndWait({ foo: "bar" }); // result is the output of your task console.log("result", result); } catch (error) { // handle subtask errors here } ``` After: ```ts const result = await yourTask.triggerAndWait({ foo: "bar" }); if (result.ok) { console.log(`Run ${result.id} succeeded with output`, result.output); } else { console.log(`Run ${result.id} failed with error`, result.error); } ``` - 26093896d: When using idempotency keys, triggerAndWait and batchTriggerAndWait will still work even if the existing runs have already been completed (or even partially completed, in the case of batchTriggerAndWait) - TaskRunExecutionResult.id is now the run friendlyId, not the attempt friendlyId - A single TaskRun can now have many batchItems, in the case of batchTriggerAndWait while using idempotency keys - A run’s idempotencyKey is now added to the ctx as well as the TaskEvent and displayed in the span view - When resolving batchTriggerAndWait, the runtimes no longer reject promises, leading to an error in the parent task - Updated dependencies [374edef02] - Updated dependencies [26093896d] - Updated dependencies [62c9a5b71] - @trigger.dev/core@3.0.0-beta.15 - @trigger.dev/core-backend@3.0.0-beta.15 ## 3.0.0-beta.14 ### Patch Changes - c9e1a3e9c: Remove unimplemented batchOptions - Updated dependencies [584c7da5d] - @trigger.dev/core@3.0.0-beta.14 - @trigger.dev/core-backend@3.0.0-beta.14 ## 3.0.0-beta.13 ### Patch Changes - 4986bfda2: Export queue from the SDK - 44e1b8754: Improve the SDK function types and expose a new APIError instead of the APIResult type - 4986bfda2: Adding task with a triggerSource of schedule - 4986bfda2: Added a new global - Task Catalog - to better handle task metadata - Updated dependencies [4986bfda2] - Updated dependencies [44e1b8754] - Updated dependencies [4986bfda2] - Updated dependencies [fde939a30] - Updated dependencies [03b104a3d] - Updated dependencies [4986bfda2] - @trigger.dev/core@3.0.0-beta.13 - @trigger.dev/core-backend@3.0.0-beta.13 ## 3.0.0-beta.12 ### Patch Changes - @trigger.dev/core@3.0.0-beta.12 - @trigger.dev/core-backend@3.0.0-beta.12 ## 3.0.0-beta.11 ### Patch Changes - @trigger.dev/core@3.0.0-beta.11 - @trigger.dev/core-backend@3.0.0-beta.11 ## 3.0.0-beta.7 ### Patch Changes - f854cb90e: Added replayRun function to the SDK - f854cb90e: Added cancelRun to the SDK - Updated dependencies [f854cb90e] - Updated dependencies [f854cb90e] - @trigger.dev/core@3.0.0-beta.7 - @trigger.dev/core-backend@3.0.0-beta.7 ## 3.0.0-beta.6 ### Patch Changes - Updated dependencies [7ea8532cc] - @trigger.dev/core@3.0.0-beta.6 - @trigger.dev/core-backend@3.0.0-beta.6 ## 3.0.0-beta.5 ### Patch Changes - Updated dependencies [eb6012628] - @trigger.dev/core@3.0.0-beta.5 - @trigger.dev/core-backend@3.0.0-beta.5 ## 3.0.0-beta.4 ### Patch Changes - @trigger.dev/core@3.0.0-beta.4 - @trigger.dev/core-backend@3.0.0-beta.4 ## 3.0.0-beta.3 ### Patch Changes - b271742dc: Configurable log levels in the config file and via env var - Updated dependencies [c702d6a9c] - Updated dependencies [b271742dc] - Updated dependencies [9af2570da] - @trigger.dev/core@3.0.0-beta.3 - @trigger.dev/core-backend@3.0.0-beta.3 ## 3.0.0-beta.2 ### Patch Changes - Updated dependencies [e3cf456c6] - @trigger.dev/core@3.0.0-beta.2 - @trigger.dev/core-backend@3.0.0-beta.2 ## 3.0.0-beta.1 ### Patch Changes - b66d5525e: add machine config and secure zod connection - 719c0a0b9: Fixed incorrect span timings around checkpoints by implementing a precise wall clock that resets after restores - f93eae300: Dynamically import superjson and fix some bundling issues - Updated dependencies [b66d5525e] - Updated dependencies [719c0a0b9] - Updated dependencies [f93eae300] - @trigger.dev/core@3.0.0-beta.1 - @trigger.dev/core-backend@3.0.0-beta.1 ## 3.0.0-beta.0 ### Major Changes - 395abe1b9: Updates to support Trigger.dev v3 ### Patch Changes - Updated dependencies [395abe1b9] - @trigger.dev/core@3.0.0-beta.0 - @trigger.dev/core-backend@3.0.0-beta.0 ## 2.3.18 ### Patch Changes - @trigger.dev/core@2.3.18 - @trigger.dev/core-backend@2.3.18 ## 2.3.17 ### Patch Changes - dd879c8e: Updated run, run statuses and event endpoints to v2 to get full run statuses - @trigger.dev/core@2.3.17 - @trigger.dev/core-backend@2.3.17 ## 2.3.16 ### Patch Changes - Updated dependencies [583da458] - @trigger.dev/core@2.3.16 - @trigger.dev/core-backend@2.3.16 ## 2.3.15 ### Patch Changes - 6c4047cf: Fix an issue where runs were stuck executing when a child task failed and the parent task retried - @trigger.dev/core@2.3.15 - @trigger.dev/core-backend@2.3.15 ## 2.3.14 ### Patch Changes - @trigger.dev/core@2.3.14 - @trigger.dev/core-backend@2.3.14 ## 2.3.13 ### Patch Changes - a93b554f: Make it clear that schedules are UTC by appending "UTC" to the end. - 0f342cd1: Don't show duplicate Job warning if it's an internal job - @trigger.dev/core@2.3.13 - @trigger.dev/core-backend@2.3.13 ## 2.3.12 ### Patch Changes - 129f023d: Fix for eventTrigger source not getting passed through - 38f5a903: Don't auto-yield with no-op tasks (e.g. logs) that are subtasks - ff4ff869: You can pass an Error() instead of properties to all of the `io.logger` functions - @trigger.dev/core@2.3.12 - @trigger.dev/core-backend@2.3.12 ## 2.3.11 ### Patch Changes - @trigger.dev/core@2.3.11 - @trigger.dev/core-backend@2.3.11 ## 2.3.10 ### Patch Changes - 8277f4d2: Use correct overload param when invoking a job outside of a run #802 - 73cb8839: Fixed invoke inferred payload types #830 - @trigger.dev/core@2.3.10 - @trigger.dev/core-backend@2.3.10 ## 2.3.9 ### Patch Changes - f7bf25f0: feat: Add ability to cancel all runs for job from SDK - Updated dependencies [740b7b23] - @trigger.dev/core@2.3.9 - @trigger.dev/core-backend@2.3.9 ## 2.3.8 ### Patch Changes - @trigger.dev/core@2.3.8 - @trigger.dev/core-backend@2.3.8 ## 2.3.7 ### Patch Changes - @trigger.dev/core@2.3.7 - @trigger.dev/core-backend@2.3.7 ## 2.3.6 ### Patch Changes - @trigger.dev/core@2.3.6 - @trigger.dev/core-backend@2.3.6 ## 2.3.5 ### Patch Changes - @trigger.dev/core@2.3.5 - @trigger.dev/core-backend@2.3.5 ## 2.3.4 ### Patch Changes - 6a3c563f: Fixed Job.attachToClient - @trigger.dev/core@2.3.4 - @trigger.dev/core-backend@2.3.4 ## 2.3.3 ### Patch Changes - @trigger.dev/core@2.3.3 - @trigger.dev/core-backend@2.3.3 ## 2.3.2 ### Patch Changes - @trigger.dev/core@2.3.2 - @trigger.dev/core-backend@2.3.2 ## 2.3.1 ### Patch Changes - f3efcc0c: Moved Logger to core-backend, no longer importing node:buffer in core/react - Updated dependencies [f3efcc0c] - @trigger.dev/core-backend@2.3.1 - @trigger.dev/core@2.3.1 ## 2.3.0 ### Minor Changes - 17f6f29d: Support for Deno, Bun and Cloudflare workers, as well as conditionally exporting ESM versions of the package instead of just commonjs. Cloudflare worker support requires the node compat flag turned on (https://developers.cloudflare.com/workers/runtime-apis/nodejs/) ### Patch Changes - Updated dependencies [17f6f29d] - @trigger.dev/core-backend@2.3.0 - @trigger.dev/core@2.3.0 ## 2.2.11 ### Patch Changes - de652c1d: Fix Shopify task types and KV `get()` return types - @trigger.dev/core@2.2.11 - @trigger.dev/core-backend@2.2.11 ## 2.2.10 ### Patch Changes - @trigger.dev/core@2.2.10 - @trigger.dev/core-backend@2.2.10 ## 2.2.9 ### Patch Changes - 1dcd87a2: Fix: `Key-Value Store` keys will now be URI encoded - 6ebd435e: Feature: Run execution concurrency limits - Updated dependencies [6ebd435e] - @trigger.dev/core@2.2.9 - @trigger.dev/core-backend@2.2.9 ## 2.2.8 ### Patch Changes - 067e19fe: - Simplify `Webhook Triggers` and use the new HTTP Endpoints - Add a `Key-Value Store` for use in and outside of Jobs - Add a `@trigger.dev/shopify` package - 096151c0: Fix `@trigger.dev/shopify` imports, enhance docs, and suppress HTTP Endpoint warnings - Updated dependencies [067e19fe] - @trigger.dev/core@2.2.8 - @trigger.dev/core-backend@2.2.8 ## 2.2.7 ### Patch Changes - 756024da: Add support for listening to run notifications - Updated dependencies [756024da] - @trigger.dev/core@2.2.7 - @trigger.dev/core-backend@2.2.7 ## 2.2.6 ### Patch Changes - cb1825bf: OpenAI support for 4.16.0 - cb1825bf: Add support for background polling and use that in OpenAI integration to power assistants - d0217344: Add `io.sendEvents()` - cb1825bf: Adding support for waitForEvent - Updated dependencies [cb1825bf] - Updated dependencies [cb1825bf] - Updated dependencies [d0217344] - @trigger.dev/core@2.2.6 - @trigger.dev/core-backend@2.2.6 ## 2.2.5 ### Patch Changes - 7e57f1f3: [TRI-1449] Display warning message when duplicate job IDs are detected - cf8f9946: Add `io.random()` which wraps `Math.random()` in a Task with helpful options. - a74716a1: Added waitForRequest built-in tasks - 620b8383: Added invokeTrigger(), which allows jobs to be manually invoked - 4a0f030e: Adding no-cache to our client fetch to fix Next.js POST caching - f4275e50: verifyRequestSignature – added an error if the passed in secret is undefined or empty - Updated dependencies [620b8383] - Updated dependencies [578d2e54] - @trigger.dev/core@2.2.5 - @trigger.dev/core-backend@2.2.5 ## 2.2.4 ### Patch Changes - c1710ae7: Creates a new package @trigger.dev/core-backend that includes code shared between @trigger.dev/sdk and the Trigger.dev server - 9c4be40a: use idempotency-key as event-id for dynamic-trigger registrations - Updated dependencies [c1710ae7] - @trigger.dev/core-backend@2.2.4 - @trigger.dev/core@2.2.4 ## 2.2.3 ### Patch Changes - 6e1b8a11: implement functionality to cancel job runs triggered by a given eventId. - c4533c36: set error messages in runTask and executeJob - Updated dependencies [6e1b8a11] - @trigger.dev/core@2.2.3 ## 2.2.2 ### Patch Changes - @trigger.dev/core@2.2.2 ## 2.2.1 ### Patch Changes - 044d38e3: Auto-yield run execution to help prevent duplicate task executions - Updated dependencies [044d38e3] - Updated dependencies [abc9737a] - @trigger.dev/core@2.2.1 ## 2.2.0 ### Minor Changes - 975c5f1d: Drop support for Node v16, require Node >= 18. This allows us to use native fetch in our SDK which paves the way for multi-platform support. ### Patch Changes - Updated dependencies [975c5f1d] - Updated dependencies [50e3d9e4] - Updated dependencies [59a94c71] - @trigger.dev/core@2.2.0 ## 2.1.9 ### Patch Changes - 9a187f9e: upgrade zod to 3.22.3 - 2e9452ab: allow cancelling jobs from trigger-client - Updated dependencies [9a187f9e] - @trigger.dev/core@2.1.9 ## 2.1.8 ### Patch Changes - 6a992a19: First release of `@trigger.dev/replicate` integration with remote callback support. - ab9e4a98: Send client version back to the server via headers - ab9e4a98: Better performance when resuming a run, especially one with a large amount of tasks - Updated dependencies [6a992a19] - Updated dependencies [ab9e4a98] - Updated dependencies [ab9e4a98] - @trigger.dev/core@2.1.8 ## 2.1.7 ### Patch Changes - @trigger.dev/core@2.1.7 ## 2.1.6 ### Patch Changes - @trigger.dev/core@2.1.6 ## 2.1.5 ### Patch Changes - @trigger.dev/core@2.1.5 ## 2.1.4 ### Patch Changes - ad14983e: You can create statuses in your Jobs that can then be read using React hooks - 15f17d27: First release of `@trigger.dev/linear` integration. `io.runTask()` error handlers can now prevent further retries. - 50137a6f: Decouple zod - c0dfa804: Add support for Bring Your Own Auth - Updated dependencies [ad14983e] - Updated dependencies [50137a6f] - Updated dependencies [c0dfa804] - @trigger.dev/core@2.1.4 ## 2.1.3 ### Patch Changes - Fix for bad publish - Updated dependencies: - `@trigger.dev/core@2.1.3` ## 2.1.2 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@2.1.2` ## 2.1.1 ### Patch Changes - Errors now bubbled up. OpenAI background retrying improved ([#468](https://github.com/triggerdotdev/trigger.dev/pull/468)) - Updated dependencies: - `@trigger.dev/core@2.1.1` ## 2.1.0 ### Minor Changes - Integrations are now simpler and support authentication during webhook registration ([`878da3c0`](https://github.com/triggerdotdev/trigger.dev/commit/878da3c01f0a4dfaf33a1f8943a7ad4eed8b8877)) ### Patch Changes - Updated dependencies: - `@trigger.dev/core@2.1.0` ## 2.1.0-beta.1 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@2.1.0-beta.1` ## 2.1.0-beta.0 ### Minor Changes - Integrations are now simpler and support authentication during webhook registration ([`878da3c0`](https://github.com/triggerdotdev/trigger.dev/commit/878da3c01f0a4dfaf33a1f8943a7ad4eed8b8877)) ### Patch Changes - Updated dependencies: - `@trigger.dev/core@2.1.0-beta.0` ## 2.0.14 ### Patch Changes - Updated dependencies: - `@trigger.dev/core@2.0.14` ## 2.0.13 ### Patch Changes - Only use cached tasks if they are completed, otherwise retrying tasks will be considered successful ([`916a3536`](https://github.com/triggerdotdev/trigger.dev/commit/916a353660e251946d76bdf565c26b7801d3beb8)) - Updated dependencies: - `@trigger.dev/core@2.0.13` ## 2.0.12 ### Patch Changes - @trigger.dev/core@2.0.12 ## 2.0.11 ### Patch Changes - ac98219b: Adding the ability to cancel events that were sent with a delayed delivery - 302bd02f: Issue #377: only expose the external eventId in the API - b5db9f5e: Adding MIT license - 3ce53970: Support disabling jobs using the `enabled` flag - Updated dependencies [302bd02f] - Updated dependencies [b5db9f5e] - @trigger.dev/core@2.0.11 ## 2.0.10 ### Patch Changes - b1b9321a: Fixed IO not setting the cached task key correctly, resulting in unnecessary API calls to trigger.dev - b1b9321a: Deprecated queue options in the job and removed startPosition - Updated dependencies [b1b9321a] - @trigger.dev/core@2.0.10 ## 2.0.9 ### Patch Changes - Updated dependencies [33184a81] - @trigger.dev/core@2.0.9 ## 2.0.8 ### Patch Changes - @trigger.dev/core@2.0.8 ## 2.0.7 ### Patch Changes - Updated dependencies [fa3a22eb] - @trigger.dev/core@2.0.7 ## 2.0.6 ### Patch Changes - Updated dependencies [59075f5f] - @trigger.dev/core@2.0.6 ## 2.0.5 ### Patch Changes - @trigger.dev/core@2.0.5 ## 2.0.4 ### Patch Changes - 96384991: Adding the validate endpoint action to be able to add an endpoint first in the dashboard - Updated dependencies [96384991] - @trigger.dev/core@2.0.4 ## 2.0.3 ### Patch Changes - @trigger.dev/core@2.0.3 ## 2.0.2 ### Patch Changes - 0a790de2: core version changed to 1.0.0. Dependencies for core set to ^1.0.0 - ee99191f: Sync all package versions - Updated dependencies [0a790de2] - Updated dependencies [ee99191f] - @trigger.dev/core@2.0.2 ## 2.0.1 ### Patch Changes - aa9fe7d4: core made public. The react and sdk packages now have it as a dependency. - Updated dependencies [aa9fe7d4] - @trigger.dev/core@0.0.5 ## 2.0.0 ### Major Changes - 99316df8: Preparing packages for V2 ### Patch Changes - acaae993: run context jsdocs - 92233f2e: @trigger.dev/core is now a separate package - cca7da9d: Better docs for io.try - 9138976d: Multiple eventname support in eventDispatcher - 486d6818: IO Logging now respects the job and client logLevel, and only outputs locally when ioLogLocalEnabled is true - 24542d4e: Adding support for trigger source in the run context, and make sure dynamic trigger runs are preprocessed so they have a chance of populating run properties - c34a02c0: Improved OpenAI task errors - 5ee0b188: Don't return the apiKey when they don't match - 28914b87: Creating the init CLI package - 722fe7b7: registerCron and unregisterCron jsdocs - 1961b994: added defineJob in TriggerClient - 1dc42dae: Added support for Runs being canceled - d6310a79: Set duplex "half" when creating fetch based Request objects when they have a body - 817b4ed1: Endpoint registration and indexing now is only initiated outside of clients - f01af9c0: Upgrade to zod 3.21.4 - 6d4922f4: api.trigger.dev is now the default cloud url - 34ccf345: Add support for task errors and task retrying - b314178d: Added getEvent(), getRun() and getRuns() methods to the client - 69af845a: Make isRetry context property backwards compatible and add it to the TriggerContext type - c83443a4: io.runTask jsdocs - 8e147dbe: io.sendEvent jsdocs - 2cbf50b1: deliverAt and timestamp event properties are now dates - 92233f2e: Packages move to @latest - b4167a38: Fixed the eventTrigger name - 931be399: cronTrigger jsdocs - facae926: Fix for a console warning about "encoding" with node-fetch - 6d04f6c6: Add default retry settings for integrations tasks - a11ddf65: Added JSDocs related to logging - ba446524: intervalTrigger() jsdocs - 6c869466: Fixed responses from the PING action to match expected schema - f2f4d4b8: Adding more granular error messages around unauthorized requests - e4b0b1e3: Added support for backgroundFetch - 094f6f5a: jsdocs for DynamicTrigger and DynamicSchedule - 2c0ea0c1: Set Node version to 16.8 and above - e26923eb: backgroundFetch jsdocs - 0066971b: added isRetry in context run - c83443a4: registerTrigger jsdocs - 99c6cd03: io.registerInterval and io.unregisterInterval jsdocs - 3ee396d7: Creating the typeform integration package - 7e2d48ac: Removed the url option for TriggerClient - 86dbd5d1: Added JSdocs for io.wait and io.logger - f160b34b: isTriggerError jsdocs - aaa70a9a: eventTrigger() jsdocs - 61ed1fb2: Adding support for output properties on tasks - 01cf5f3b: io.try jsdocs - 9351c051: Initial Stripe integration - 953e7fc9: Added human readable cron expression property to cron triggers - 0012bb21: All logs are now structured logs - 807b9d4c: Added jsdocs for TriggerClient() and sendEvent() - 64477f6b: Adding some type helpers for getting the payload and IO types from jobs and triggers - 7f6bf992: Show the params to updateSource in the dashboard - 767e09ee: Added io.integration.runTask and initial @trigger.dev/supabase integration - 917a70fb: Added JSdocs for Job ## 2.0.0-next.22 ### Patch Changes - 64477f6b: Adding some type helpers for getting the payload and IO types from jobs and triggers ## 2.0.0-next.21 ### Patch Changes - 9351c051: Initial Stripe integration ## 2.0.0-next.20 ### Patch Changes - b314178d: Added getEvent(), getRun() and getRuns() methods to the client ## 2.0.0-next.19 ### Patch Changes - 767e09ee: Added io.integration.runTask and initial @trigger.dev/supabase integration ## 2.0.0-next.18 ### Patch Changes - 1961b994: added defineJob in TriggerClient - 69af845a: Make isRetry context property backwards compatible and add it to the TriggerContext type - 0066971b: added isRetry in context run ## 2.0.0-next.17 ### Patch Changes - 7f6bf992: Show the params to updateSource in the dashboard ## 2.0.0-next.16 ### Patch Changes - 1dc42dae: Added support for Runs being canceled - d6310a79: Set duplex "half" when creating fetch based Request objects when they have a body - 0012bb21: All logs are now structured logs ## 2.0.0-next.15 ### Patch Changes - 2c0ea0c1: Set Node version to 16.8 and above ## 2.0.0-next.14 ### Patch Changes - c34a02c0: Improved OpenAI task errors - 61ed1fb2: Adding support for output properties on tasks ## 2.0.0-next.13 ### Patch Changes - 5ee0b188: Don't return the apiKey when they don't match ## 2.0.0-next.12 ### Patch Changes - f01af9c0: Upgrade to zod 3.21.4 ## 2.0.0-next.11 ### Patch Changes - 931be399: cronTrigger jsdocs - ba446524: intervalTrigger() jsdocs - 094f6f5a: jsdocs for DynamicTrigger and DynamicSchedule - 3ee396d7: Creating the typeform integration package ## 2.0.0-next.10 ### Patch Changes - 6d4922f4: api.trigger.dev is now the default cloud url ## 2.0.0-next.9 ### Patch Changes - acaae993: run context jsdocs - aaa70a9a: eventTrigger() jsdocs ## 2.0.0-next.8 ### Patch Changes - cca7da9d: Better docs for io.try - 722fe7b7: registerCron and unregisterCron jsdocs - c83443a4: io.runTask jsdocs - c83443a4: registerTrigger jsdocs - 99c6cd03: io.registerInterval and io.unregisterInterval jsdocs - f160b34b: isTriggerError jsdocs - 01cf5f3b: io.try jsdocs ## 2.0.0-next.7 ### Patch Changes - 2cbf50b1: deliverAt and timestamp event properties are now dates - e26923eb: backgroundFetch jsdocs ## 2.0.0-next.6 ### Patch Changes - 486d6818: IO Logging now respects the job and client logLevel, and only outputs locally when ioLogLocalEnabled is true - 8e147dbe: io.sendEvent jsdocs - a11ddf65: Added JSDocs related to logging - 6c869466: Fixed responses from the PING action to match expected schema - 86dbd5d1: Added JSdocs for io.wait and io.logger - 953e7fc9: Added human readable cron expression property to cron triggers - 807b9d4c: Added jsdocs for TriggerClient() and sendEvent() - 917a70fb: Added JSdocs for Job ## 2.0.0-next.5 ### Patch Changes - 7e2d48ac: Removed the url option for TriggerClient ## 2.0.0-next.4 ### Patch Changes - f2f4d4b8: Adding more granular error messages around unauthorized requests ## 2.0.0-next.3 ### Patch Changes - 24542d4e: Adding support for trigger source in the run context, and make sure dynamic trigger runs are preprocessed so they have a chance of populating run properties ## 2.0.0-next.2 ### Patch Changes - 28914b87: Creating the init CLI package - 817b4ed1: Endpoint registration and indexing now is only initiated outside of clients - e4b0b1e3: Added support for backgroundFetch ## 2.0.0-next.1 ### Patch Changes - Add support for task errors and task retrying - b4167a38: Fixed the eventTrigger name ## 2.0.0-next.0 ### Major Changes - 53c9bd56: Preparing packages for V2 ## 0.2.22 ### Patch Changes - ab512157: Fixed an error message - 1673d452: Added kv storage to persist data in between runs and between workflows - 0b67b51a: Fix ESM error by dynamically importing ESM packages (chalk, terminal-link, etc.) - f39bc44e: SDK now passes through the project ID from the env var ## 0.2.22-next.0 ### Patch Changes - ab512157: Fixed an error message - 1673d452: Added kv storage to persist data in between runs and between workflows - 0b67b51a: Fix ESM error by dynamically importing ESM packages (chalk, terminal-link, etc.) - f39bc44e: SDK now passes through the project ID from the env var ## 0.2.21 ### Patch Changes - c5084209: Fix for metadata capture when using npm/yarn ## 0.2.20 ### Patch Changes - 5ec71980: Send additional metadata about a workflow when initializing the host ## 0.2.19 ### Patch Changes - b5724195: Fixed issue where default webhook schema wasn't being used which caused an error ## 0.2.18 ### Patch Changes - c72120ea: Removed accidental log statement ## 0.2.17 ### Patch Changes - 3a2cf0dd: Fixed the missing error message when logging invalid API key and improved the error message ## 0.2.16 ### Patch Changes - ee20f921: Make the schema an optional param for customEvent and webhookEvent - 4f47d031: Give a better error message when the API key is invalid - 87a3bbee: Added a more helpful error message when missing an API key - 51f9bc9d: Added handly links to the dashboard in log feedback - 0932ae7d: Log out when a run first starts as well ## 0.2.16-next.3 ### Patch Changes - Give a better error message when the API key is invalid ## 0.2.16-next.2 ### Patch Changes - 87a3bbee: Added a more helpful error message when missing an API key ## 0.2.16-next.1 ### Patch Changes - 0932ae7d: Log out when a run first starts as well ## 0.2.16-next.0 ### Patch Changes - ee20f921: Make the schema an optional param for customEvent and webhookEvent - 51f9bc9d: Added handly links to the dashboard in log feedback ## 0.2.15 ### Patch Changes - 6b53aeb: New integrations service compatibility - 9eeacee: Fix: pass in the id from sendEvent through to the API call ## 0.2.15-next.0 ### Patch Changes - 6b53aeb: New integrations service compatibility ## 0.2.14 ### Patch Changes - 179afbb: Automatically pickup on the TRIGGER_WSS_URL for the wss endpoint ## 0.2.13 ### Patch Changes - 710bcc2: Handle errors when calling listen and provide some log feedback ## 0.2.12 ### Patch Changes - 2a51c5a: Generate and send JSON Schema for custom and webhook events - 0d2d9a0: Added runOnce and runOnceLocalOnly to support running idempotent actions - 0e4ec8d: Added views and view submission support to Slack integration ## 0.2.12-next.0 ### Patch Changes - 2a51c5a: Generate and send JSON Schema for custom and webhook events - 0d2d9a0: Added runOnce and runOnceLocalOnly to support running idempotent actions - 0e4ec8d: Added views and view submission support to Slack integration ## 0.2.11 ### Patch Changes - 52d21ac: Added support for delaying delivery when sending custom events - b290410: Slack blocks support ## 0.2.10 ### Patch Changes - e37a200: Added lastRunAt to the scheduleEvent payload - e63d354: Added isTest to TriggerContext ## 0.2.9 ### Patch Changes - 039321f: Improved types for the Resend integration ## 0.2.8 ### Patch Changes - ddf4255: Added support for webhookEvent trigger - 2fd9e4f: Added retry options to fetch ## 0.2.7 ### Patch Changes - 39b167e: Better handle event parsing errors from Zod ## 0.2.6 ### Patch Changes - f316c6e: Add ability to use fetch without having to use context param - c69c370: Added context.fetch to make generic fetch requests using Trigger.dev ## 0.2.5 ### Patch Changes - 6673798: Bundling common-schemas into @trigger.dev/sdk ## 0.2.4 ### Patch Changes - 0b17912: Updated dependency to @trigger.dev/core@0.1.0 ## 0.2.3 ### Patch Changes - ce0d4b9: When posting a message to Slack, you must explicitly specify either channelId or channelName ## 0.2.2 ### Patch Changes - 7f26548: Added some logging messages (and disabled any messages by default) - 5de2a1a: Fixed issue with workflow runs not completing when the run function returned undefined or null - d3c593c: Added triggerTTL option that prevents old events from running a workflow ## 0.2.1 ### Patch Changes - 7d23a7b: Added the sendEvent function ## 0.2.0 ### Minor Changes - 8b7b8a8: Added scheduled events ## 0.1.2 ### Patch Changes - ae042a7: Providers is now a public package: @trigger.dev/providers ## 0.1.1 ### Patch Changes - bcda9c8: Initial publish of the @trigger.dev packages