Skip to content

chore: release v4.5.0#3563

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Open

chore: release v4.5.0#3563
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 12, 2026

Summary

6 improvements.

Improvements

  • chat.agent actions are no longer treated as turns. They fire hydrateMessages and onAction only — no onTurnStart / prepareMessages / onBeforeTurnComplete / onTurnComplete, no run(), no turn-counter increment. The trace span is named chat action instead of chat turn N. (#3543)
  • Adds the Sessions primitive — a durable, run-aware stream channel keyed (#3542)
  • Add ai.toolExecute(task) so you can wire a Trigger subtask in as the execute handler of an AI SDK tool() while defining description and inputSchema yourself — useful when you want full control over the tool surface and just need Trigger's subtask machinery for the body. (#3546)
  • Reject overlong idempotencyKey values at the API boundary so they no longer trip an internal size limit on the underlying unique index and surface as a generic 500. Inputs are capped at 2048 characters — well above what idempotencyKeys.create() produces (a 64-character hash) and above any realistic raw key. Applies to tasks.trigger, tasks.batchTrigger, batch.create (Phase 1 streaming batches), wait.createToken, wait.forDuration, and the input/session stream waitpoint endpoints. Over-limit requests now return a structured 400 instead. (#3560)
  • Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry policy instead of failing the run on the first segfault. SIGSEGV in Node tasks is frequently non-deterministic (native addon races, JIT/GC interaction, near-OOM in native code, host issues), so retrying on a fresh process often succeeds. The retry is gated by the task's existing retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and uncaught exceptions already use — so tasks without a retry policy still fail fast. (#3552)
  • The public interfaces for a plugin system. Initially consolidated authentication and authorization interfaces. (#3499)
Raw changeset output

Releases

@trigger.dev/sdk@4.5.0

Minor Changes

  • chat.agent actions are no longer treated as turns. They fire hydrateMessages and onAction only — no onTurnStart / prepareMessages / onBeforeTurnComplete / onTurnComplete, no run(), no turn-counter increment. The trace span is named chat action instead of chat turn N. (#3543)

    onAction can now return a StreamTextResult, string, or UIMessage to produce a model response from the action; returning void (the previous and now default) is side-effect-only.

    Migration: if you previously had run() branching on payload.trigger === "action", return your streamText(...) from onAction instead. If you persisted in onTurnComplete, do that work inside onAction. For any other state-only action, just remove your skip-the-model workaround — the default is now correct.

    // before
    onAction: async ({ action }) => {
      if (action.type === "regenerate") {
        chat.store.set({ skipModelCall: false });
        chat.history.slice(0, -1);
      }
    },
    run: async ({ messages, signal }) => {
      if (chat.store.get()?.skipModelCall) return;
      return streamText({ model, messages, abortSignal: signal });
    },
    
    // after
    onAction: async ({ action, messages, signal }) => {
      if (action.type === "regenerate") {
        chat.history.slice(0, -1);
        return streamText({ model, messages, abortSignal: signal });
      }
    },
    run: async ({ messages, signal }) =>
      streamText({ model, messages, abortSignal: signal }),
  • Adds onBoot to chat.agent — a lifecycle hook that fires once per worker process picking up the chat. Runs for the initial run, preloaded runs, AND reactive continuation runs (post-cancel, crash, endRun, requestUpgrade, OOM retry), before any other hook. Use it to initialize chat.local, open per-process resources, or re-hydrate state from your DB on continuation — anywhere the SAME run picking up after suspend/resume isn't enough. (#3543)

    const userContext = chat.local<{ name: string; plan: string }>({ id: "userContext" });
    
    export const myChat = chat.agent({
      id: "my-chat",
      onBoot: async ({ clientData, continuation }) => {
        const user = await db.user.findUnique({ where: { id: clientData.userId } });
        userContext.init({ name: user.name, plan: user.plan });
      },
      run: async ({ messages, signal }) =>
        streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }),
    });

    If you previously initialized chat.local in onChatStart, move it to onBootonChatStart is once-per-chat and won't fire on a continuation, leaving chat.local uninitialized when run() tries to use it. See the upgrade guide for the migration pattern.

  • Run AI chats as durable Trigger.dev tasks. Define the agent in one function, wire useChat to it from React, and the conversation survives page refreshes, network blips, and process restarts — with built-in support for tools, HITL approvals, multi-turn state, and stop-mid-stream cancellation. (#3543)

    import { chat } from "@trigger.dev/sdk/ai";
    import { streamText } from "ai";
    import { openai } from "@ai-sdk/openai";
    
    export const myChat = chat.agent({
      id: "my-chat",
      run: async ({ messages, signal }) =>
        streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }),
    });
    import { useChat } from "@ai-sdk/react";
    import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
    
    const transport = useTriggerChatTransport({ task: "my-chat", accessToken });
    const { messages, sendMessage } = useChat({ transport });

    Lifecycle hooks (onPreload, onTurnStart, onTurnComplete, etc.) cover the common needs around persistence, validation, and post-turn work. chat.store gives you a typed shared-data slot the agent and client both read and write. chat.endRun() exits cleanly when the agent decides it's done. The transport's watch mode lets a dashboard tab observe a run without driving it.

    Drops the pre-Sessions chat stream constants (CHAT_STREAM_KEY, CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID) — migrate to sessions.open(id).out / .in.

  • Add chat.headStart — an opt-in fast-path that runs the first turn's streamText step in your warm Next.js / Hono / Workers / Express handler while the trigger agent run boots in parallel. Cold-start TTFC drops by ~50% on the first message; the agent owns step 2+ (tool execution, persistence, hooks) so heavy deps stay where they belong. (#3543)

    // app/api/chat/route.ts (Next.js / any Web Fetch framework)
    import { chat } from "@trigger.dev/sdk/chat-server";
    import { streamText } from "ai";
    import { openai } from "@ai-sdk/openai";
    import { headStartTools } from "@/lib/chat-tools-schemas"; // schema-only
    
    export const POST = chat.headStart({
      agentId: "ai-chat",
      run: async ({ chat: chatHelper }) =>
        streamText({
          ...chatHelper.toStreamTextOptions({ tools: headStartTools }),
          model: openai("gpt-4o-mini"),
          system: "You are a helpful AI assistant.",
        }),
    });
    // browser — opt in by pointing the transport at your handler
    const transport = useTriggerChatTransport({
      task: "ai-chat",
      accessToken,
      headStart: "/api/chat", // first-turn-only; turn 2+ bypasses the endpoint
    });

    For Node-only frameworks (Express, Fastify, Koa, raw node:http) use chat.toNodeListener(handler) to bridge the Web Fetch handler to (req, res). Adds a new @trigger.dev/sdk/chat-server subpath; bundle stays Web Fetch–only with no node:* imports.

  • Add read primitives to chat.history for HITL flows: getPendingToolCalls(), getResolvedToolCalls(), extractNewToolResults(message), getChain(), and findMessage(messageId). These lift the accumulator-walking logic that customers building human-in-the-loop tools were re-implementing into the SDK. (#3543)

    Use getPendingToolCalls() to gate fresh user turns while a tool call is awaiting an answer. Use extractNewToolResults(message) to dedup tool results when persisting to your own store — the helper returns only the parts whose toolCallId is not already resolved on the chain.

    const pending = chat.history.getPendingToolCalls();
    if (pending.length > 0) {
      // an addToolOutput is expected before a new user message
    }
    
    onTurnComplete: async ({ responseMessage }) => {
      const newResults = chat.history.extractNewToolResults(responseMessage);
      for (const r of newResults) {
        await db.toolResults.upsert({ id: r.toolCallId, output: r.output, errorText: r.errorText });
      }
    };
  • Adds the Sessions primitive — a durable, run-aware stream channel keyed (#3542)
    on a stable externalId. Public SDK additions: tasks.triggerAndSubscribe()
    and the chat.agent runtime built on top of Sessions. See
    https://trigger.dev/docs/ai-chat/overview for the full feature surface.

Patch Changes

  • Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543)

    const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" });
    
    chat.skills.set([await pdfSkill.local()]);

    Built on the AI SDK cookbook pattern — portable across providers. SDK + CLI only for now; dashboard-editable SKILL.md text is on the roadmap.

  • Add ai.toolExecute(task) so you can wire a Trigger subtask in as the execute handler of an AI SDK tool() while defining description and inputSchema yourself — useful when you want full control over the tool surface and just need Trigger's subtask machinery for the body. (#3546)

    const myTool = tool({
      description: "...",
      inputSchema: z.object({ ... }),
      execute: ai.toolExecute(mySubtask),
    });

    ai.tool(task) (toolFromTask) keeps doing the all-in-one wrap and now aligns its return type with AI SDK's ToolSet. Minimum ai peer raised to ^6.0.116 to avoid cross-version ToolSet mismatches in monorepos.

  • chat.agent wire is now delta-only — clients ship at most one new message per .in/append instead of the full UIMessage[] history. The agent rebuilds prior history at run boot from a JSON snapshot in object storage plus a wait=0 replay of the session.out tail. Long chats stop hitting the 512 KiB body cap on /realtime/v1/sessions/{id}/in/append. Snapshot writes happen after every onTurnComplete, awaited so they survive idle suspend; reads happen only at run boot. Registering a hydrateMessages hook short-circuits both the snapshot read/write and the replay — the customer is the source of truth for history. (#3543)

    Custom transports that constructed ChatTaskWirePayload directly need to drop the messages: UIMessage[] field and use message?: UIMessage (singular). Built-in transports (TriggerChatTransport, AgentChat) handle the change below the customer-facing surface — most apps need no changes. Configure object-store env vars (OBJECT_STORE_*) on your webapp deployment if you haven't already; without an object store and without hydrateMessages, conversations don't survive run boundaries.

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

  • Unit-test chat.agent definitions offline with mockChatAgent from @trigger.dev/sdk/ai/test. Drives a real agent's turn loop in-process — no network, no task runtime — so you can send messages, actions, and stop signals via driver methods, inspect captured output chunks, and verify hooks fire. Pairs with MockLanguageModelV3 from ai/test for model mocking. setupLocals lets you pre-seed locals (DB clients, service stubs) before run() starts. (#3543)

    The broader runInMockTaskContext harness it's built on lives at @trigger.dev/core/v3/test — useful for unit-testing any task code, not just chat.

  • Updated dependencies:

    • @trigger.dev/core@4.5.0

@trigger.dev/build@4.5.0

Patch Changes

  • Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543)

    const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" });
    
    chat.skills.set([await pdfSkill.local()]);

    Built on the AI SDK cookbook pattern — portable across providers. SDK + CLI only for now; dashboard-editable SKILL.md text is on the roadmap.

  • Updated dependencies:

    • @trigger.dev/core@4.5.0

trigger.dev@4.5.0

Patch Changes

  • Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543)

    const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" });
    
    chat.skills.set([await pdfSkill.local()]);

    Built on the AI SDK cookbook pattern — portable across providers. SDK + CLI only for now; dashboard-editable SKILL.md text is on the roadmap.

  • The CLI MCP server's agent-chat tools (start_agent_chat, send_agent_message, close_agent_chat) now run on the new Sessions primitive, so AI assistants driving a chat.agent get the same idempotent-by-chatId, durable-across-runs behavior the browser transport gets. Required PAT scopes go from write:inputStreams to read:sessions + write:sessions. (#3546)

  • Updated dependencies:

    • @trigger.dev/core@4.5.0
    • @trigger.dev/build@4.5.0
    • @trigger.dev/schema-to-json@4.5.0

@trigger.dev/core@4.5.0

Patch Changes

  • Add Agent Skills for chat.agent. Drop a folder with a SKILL.md and any helper scripts/references next to your task code, register it with skills.define({ id, path }), and the CLI bundles it into the deploy image automatically — no trigger.config.ts changes. The agent gets a one-line summary in its system prompt and discovers full instructions on demand via loadSkill, with bash and readFile tools scoped per-skill (path-traversal guards, output caps, abort-signal propagation). (#3543)

    const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" });
    
    chat.skills.set([await pdfSkill.local()]);

    Built on the AI SDK cookbook pattern — portable across providers. SDK + CLI only for now; dashboard-editable SKILL.md text is on the roadmap.

  • Reject overlong idempotencyKey values at the API boundary so they no longer trip an internal size limit on the underlying unique index and surface as a generic 500. Inputs are capped at 2048 characters — well above what idempotencyKeys.create() produces (a 64-character hash) and above any realistic raw key. Applies to tasks.trigger, tasks.batchTrigger, batch.create (Phase 1 streaming batches), wait.createToken, wait.forDuration, and the input/session stream waitpoint endpoints. Over-limit requests now return a structured 400 instead. (#3560)

  • chat.agent wire is now delta-only — clients ship at most one new message per .in/append instead of the full UIMessage[] history. The agent rebuilds prior history at run boot from a JSON snapshot in object storage plus a wait=0 replay of the session.out tail. Long chats stop hitting the 512 KiB body cap on /realtime/v1/sessions/{id}/in/append. Snapshot writes happen after every onTurnComplete, awaited so they survive idle suspend; reads happen only at run boot. Registering a hydrateMessages hook short-circuits both the snapshot read/write and the replay — the customer is the source of truth for history. (#3543)

    Custom transports that constructed ChatTaskWirePayload directly need to drop the messages: UIMessage[] field and use message?: UIMessage (singular). Built-in transports (TriggerChatTransport, AgentChat) handle the change below the customer-facing surface — most apps need no changes. Configure object-store env vars (OBJECT_STORE_*) on your webapp deployment if you haven't already; without an object store and without hydrateMessages, conversations don't survive run boundaries.

  • Run AI chats as durable Trigger.dev tasks. Define the agent in one function, wire useChat to it from React, and the conversation survives page refreshes, network blips, and process restarts — with built-in support for tools, HITL approvals, multi-turn state, and stop-mid-stream cancellation. (#3543)

    import { chat } from "@trigger.dev/sdk/ai";
    import { streamText } from "ai";
    import { openai } from "@ai-sdk/openai";
    
    export const myChat = chat.agent({
      id: "my-chat",
      run: async ({ messages, signal }) =>
        streamText({ model: openai("gpt-4o"), messages, abortSignal: signal }),
    });
    import { useChat } from "@ai-sdk/react";
    import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
    
    const transport = useTriggerChatTransport({ task: "my-chat", accessToken });
    const { messages, sendMessage } = useChat({ transport });

    Lifecycle hooks (onPreload, onTurnStart, onTurnComplete, etc.) cover the common needs around persistence, validation, and post-turn work. chat.store gives you a typed shared-data slot the agent and client both read and write. chat.endRun() exits cleanly when the agent decides it's done. The transport's watch mode lets a dashboard tab observe a run without driving it.

    Drops the pre-Sessions chat stream constants (CHAT_STREAM_KEY, CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID) — migrate to sessions.open(id).out / .in.

  • Add ChatChunkTooLargeError and ApiClient methods for subscribing to session streams. Lays the groundwork for the upcoming chat.agent. (#3542)

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

  • Unit-test chat.agent definitions offline with mockChatAgent from @trigger.dev/sdk/ai/test. Drives a real agent's turn loop in-process — no network, no task runtime — so you can send messages, actions, and stop signals via driver methods, inspect captured output chunks, and verify hooks fire. Pairs with MockLanguageModelV3 from ai/test for model mocking. setupLocals lets you pre-seed locals (DB clients, service stubs) before run() starts. (#3543)

    The broader runInMockTaskContext harness it's built on lives at @trigger.dev/core/v3/test — useful for unit-testing any task code, not just chat.

  • Retry TASK_PROCESS_SIGSEGV task crashes under the user's retry policy instead of failing the run on the first segfault. SIGSEGV in Node tasks is frequently non-deterministic (native addon races, JIT/GC interaction, near-OOM in native code, host issues), so retrying on a fresh process often succeeds. The retry is gated by the task's existing retry config + maxAttempts — same path TASK_PROCESS_SIGTERM and uncaught exceptions already use — so tasks without a retry policy still fail fast. (#3552)

  • Adds the Sessions primitive — a durable, run-aware stream channel keyed (#3542)
    on a stable externalId. Public SDK additions: tasks.triggerAndSubscribe()
    and the chat.agent runtime built on top of Sessions. See
    https://trigger.dev/docs/ai-chat/overview for the full feature surface.

@trigger.dev/plugins@4.5.0

Patch Changes

  • The public interfaces for a plugin system. Initially consolidated authentication and authorization interfaces. (#3499)
  • Updated dependencies:
    • @trigger.dev/core@4.5.0

@trigger.dev/python@4.5.0

Patch Changes

  • Updated dependencies:
    • @trigger.dev/sdk@4.5.0
    • @trigger.dev/core@4.5.0
    • @trigger.dev/build@4.5.0

@trigger.dev/react-hooks@4.5.0

Patch Changes

  • Updated dependencies:
    • @trigger.dev/core@4.5.0

@trigger.dev/redis-worker@4.5.0

Patch Changes

  • Updated dependencies:
    • @trigger.dev/core@4.5.0

@trigger.dev/rsc@4.5.0

Patch Changes

  • Updated dependencies:
    • @trigger.dev/core@4.5.0

@trigger.dev/schema-to-json@4.5.0

Patch Changes

  • Updated dependencies:
    • @trigger.dev/core@4.5.0

@github-actions github-actions Bot changed the title chore: release chore: release v4.4.7 May 12, 2026
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@github-actions github-actions Bot changed the title chore: release v4.4.7 chore: release May 12, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 28fd35c to 9a0e7f8 Compare May 12, 2026 16:18
@github-actions github-actions Bot changed the title chore: release chore: release v4.4.7 May 12, 2026
@github-actions github-actions Bot changed the title chore: release v4.4.7 chore: release May 12, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 9a0e7f8 to e477aeb Compare May 12, 2026 17:38
@github-actions github-actions Bot changed the title chore: release chore: release v4.4.7 May 12, 2026
@github-actions github-actions Bot changed the title chore: release v4.4.7 chore: release May 13, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from e477aeb to 2dd9063 Compare May 13, 2026 22:45
@github-actions github-actions Bot changed the title chore: release chore: release v4.4.7 May 13, 2026
@github-actions github-actions Bot changed the title chore: release v4.4.7 chore: release May 14, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 2dd9063 to 7390aa8 Compare May 14, 2026 12:26
@github-actions github-actions Bot changed the title chore: release chore: release v4.4.7 May 14, 2026
@github-actions github-actions Bot changed the title chore: release v4.4.7 chore: release May 14, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 7390aa8 to 48d6326 Compare May 14, 2026 12:43
@github-actions github-actions Bot changed the title chore: release chore: release v4.5.0 May 14, 2026
@github-actions github-actions Bot changed the title chore: release v4.5.0 chore: release May 14, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 48d6326 to 830f8c9 Compare May 14, 2026 14:31
@github-actions github-actions Bot changed the title chore: release chore: release v4.5.0 May 14, 2026
@github-actions github-actions Bot changed the title chore: release v4.5.0 chore: release May 14, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 830f8c9 to be2f622 Compare May 14, 2026 15:25
@github-actions github-actions Bot changed the title chore: release chore: release v4.5.0 May 14, 2026
@github-actions github-actions Bot changed the title chore: release v4.5.0 chore: release May 14, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch from be2f622 to f428661 Compare May 14, 2026 16:00
@github-actions github-actions Bot changed the title chore: release chore: release v4.5.0 May 14, 2026
@github-actions github-actions Bot changed the title chore: release v4.5.0 chore: release May 14, 2026
@github-actions github-actions Bot force-pushed the changeset-release/main branch 2 times, most recently from f428661 to b5d0261 Compare May 14, 2026 16:57
@github-actions github-actions Bot changed the title chore: release chore: release v4.5.0 May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants