You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chore: rewrite consolidated changesets in user-facing changelog voice
The previous pass rolled 26 changesets into 8 but the consolidated
descriptions read like docs (full API surface dumps, multiple sections,
docs-style headers). Rewrote each so they fit a release-notes bullet
list — short, what-shipped framing, with one or two snippets where they
help, no exhaustive type / option enumeration.
Copy file name to clipboardExpand all lines: .changeset/agent-skills.md
+6-8Lines changed: 6 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,14 +5,12 @@
5
5
"trigger.dev": patch
6
6
---
7
7
8
-
Agent Skills — developer-authored folders (`SKILL.md`+ scripts/references/assets) bundled into the deploy image automatically and discovered by the chat agent via progressive disclosure. Built on the [AI SDK cookbook pattern](https://ai-sdk.dev/cookbook/guides/agent-skills) — portable across providers.
8
+
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).
-`skills.define({ id, path })` registers a skill with the resource catalog; the Trigger.dev CLI bundles the folder into `/app/.trigger/skills/{id}/` automatically — no `trigger.config.ts` changes, no build extension.
13
-
-`SkillHandle.local()` reads the bundled `SKILL.md` at runtime, parses frontmatter, returns a `ResolvedSkill`.
14
-
-`chat.skills.set([...])` stores resolved skills for the current run.
15
-
-`chat.toStreamTextOptions()` auto-injects the skills preamble into the system prompt and merges three tools — `loadSkill`, `readFile`, `bash` — scoped per-skill with path-traversal guards and output caps (64 KB stdout/stderr, 1 MB `readFile`). `bash` runs with `cwd` = skill directory; the turn's abort signal propagates.
16
-
-`@trigger.dev/sdk/ai/skills-runtime` subpath — the `bash` + `readFile` runtime primitives (backed by `node:child_process` + `node:fs/promises`) live here, not in `@trigger.dev/sdk/ai`. Fixes client-bundle build errors (`UnhandledSchemeError: Reading from "node:child_process"…`) that hit Next.js + Webpack when a browser page imports types from `@trigger.dev/sdk/ai` (for example `ChatUiMessage` via a shared tools file). The chat-agent factory loads the runtime lazily via a computed-string dynamic import, so server workers still get full skill support without any caller changes.
13
+
chat.skills.set([awaitpdfSkill.local()]);
14
+
```
17
15
18
-
This is the SDK + CLI layer only — no backend, no dashboard overrides yet. Dashboard-editable `SKILL.md` text and override flow are on the roadmap; `skill.resolve()` currently throws.
16
+
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.
Copy file name to clipboardExpand all lines: .changeset/ai-tool-helpers.md
+10-3Lines changed: 10 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,14 @@
2
2
"@trigger.dev/sdk": patch
3
3
---
4
4
5
-
AI SDK `tool()`helpers for Trigger subtasks:
5
+
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.
6
6
7
-
-`ai.toolExecute(task)` — pass Trigger's subtask/metadata wiring as the `execute` handler to AI SDK `tool()` while you define `description` and `inputSchema` yourself. `ai.tool()` is now refactored to share the same internal handler.
8
-
-`ai.tool(task)` (`toolFromTask`) aligns with AI SDK `ToolSet`: Zod-backed tasks use static `tool()`; returns are asserted as `Tool & ToolSet[string]`. Minimum `ai` devDependency raised to `^6.0.116` so emitted types resolve the same `ToolSet` as apps on AI SDK 6.0.x — avoids cross-version `ToolSet` mismatches in monorepos.
7
+
```ts
8
+
const myTool =tool({
9
+
description: "...",
10
+
inputSchema: z.object({ ... }),
11
+
execute: ai.toolExecute(mySubtask),
12
+
});
13
+
```
14
+
15
+
`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.
Copy file name to clipboardExpand all lines: .changeset/chat-agent.md
+9-45Lines changed: 9 additions & 45 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,22 +3,7 @@
3
3
"@trigger.dev/core": patch
4
4
---
5
5
6
-
`chat.agent` — durable AI chat as Trigger.dev tasks, with frontend wiring for the AI SDK's `useChat` hook. Built on top of the new Sessions primitive (separate changeset).
7
-
8
-
## SDK
9
-
10
-
**`@trigger.dev/sdk/ai`** (backend):
11
-
12
-
-`chat.agent({ id, run, ... })` — durable agent with full lifecycle hooks (`onPreload`, `onChatStart`, `onTurnStart`, `onBeforeTurnComplete`, `onTurnComplete`, `onCompacted`, `onValidateMessages`, `onAction`, `hydrateMessages`, `hydrateStore`). Auto-pipes a returned `streamText` result to the frontend.
13
-
-`chat.customAgent({ id, run })` — minimal protocol-level escape hatch; same session binding as `chat.agent`.
14
-
-`chat.withUIMessage<TUIMessage>().agent({...})` — generic-typed agent for custom `UIMessage` subtypes (typed `data-*` parts, tool maps, etc.). Ships `InferChatUIMessage`, generic `ChatUIMessageStreamOptions`, generic compaction + pending-message event types. `usePendingMessages` accepts a UI-message type parameter; `InferChatUIMessage` re-exported from `@trigger.dev/sdk/chat/react`.
15
-
-`chat.pipe(stream)` — pipe a `StreamTextResult` or stream from anywhere inside the agent.
16
-
-`chat.endRun()` — exit the run after the current turn completes, without the upgrade-required signal that `chat.requestUpgrade()` sends. Use for one-shot responses, agent-finished-its-work, or budget-exhausted exits.
17
-
-`chat.store` — typed, bidirectional shared data slot. `set` / `patch` (RFC 6902) / `get` / `onChange`; per-run scoped. Emits `store-snapshot` / `store-delta` chunks on the chat output stream. `hydrateStore` config for restore-on-continuation; `incomingStore` wire field for client-set data at turn start.
18
-
-`chat.sessionId` — getter for the friendlyId (`session_*`) of the run's backing Session. Throws outside chat.agent / chat.customAgent.
19
-
-`TaskRunContext` (`ctx`) on every lifecycle event, `CompactedEvent`, and `ChatTaskRunPayload`. `TaskRunContext` re-exported from `@trigger.dev/sdk`.
20
-
-`finishReason` on `TurnCompleteEvent` and `BeforeTurnCompleteEvent` — surfaces AI SDK's `FinishReason` (`"stop" | "tool-calls" | "length" | ...`) so hooks can distinguish a normal end from a paused-on-tool-call HITL flow. Undefined for manual `pipeChat()` or aborted streams.
21
-
-`ChatTaskPayload.trigger` includes `"action"`. Actions short-circuit the LLM call cleanly: `if (trigger === "action") return;`.
6
+
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.
-`TriggerChatTransport` — `ChatTransport` for `useChat`. Backed by Sessions: posts to `session.in/append`, subscribes to `session.out` SSE.
38
-
-`watch: true` option — read-only observation of an existing run. Keeps the internal stream open across `trigger:turn-complete` markers so a single `useChat` / `resumeStream` subscription observes every turn of a long-lived agent. Useful for dashboard viewers / debug UIs. Default `false` preserves interactive behavior.
39
-
-`RenewRunAccessTokenParams` includes the durable `sessionId` alongside `chatId` + `runId`. Renew handlers should mint with `read:sessions:{sessionId}` + `write:sessions:{sessionId}` scopes; renewing without session scopes throws the transport into a 401 loop on the first append after expiry.
40
-
- Run-scoped PAT renewal (`renewRunAccessToken`); fail fast on 401/403 for SSE without retry backoff. `isTriggerRealtimeAuthError` exported for auth-error detection.
41
-
-`transport.preload(chatId)` no longer calls `apiClient.createSession` from the browser — the server action returns `sessionId` in its result, matching how `sendMessages` already worked. Browser deployments using the `triggerTask` callback path therefore no longer need `write:sessions` on any browser-side token.
42
-
-`reconnectToStream` no longer requires callers to persist an `isStreaming` flag in `ChatSession` state — the short-circuit only triggers on explicit `isStreaming === false`.
-`chat.customAgent` now binds the session handle (previously only `chat.agent` set up the per-run `SessionHandle`, so any custom agent that called `chat.messages.*`, `chat.stream.*`, `chat.createSession`, or `chat.createStopSignal` threw `chat.agent session handle is not initialized`). `chat.customAgent` now wraps the user's `run` and opens the session via `payload.sessionId ?? payload.chatId` before invoking it.
51
-
- Stop mid-stream no longer hangs the turn loop. The AI SDK's `runResult.totalUsage` promise can stay unresolved indefinitely on aborted Anthropic streams; the await is now raced against a 2s timeout so a stuck `totalUsage` falls through to a non-fatal "usage unknown" path and the turn finalizes correctly.
52
-
53
-
## Cleanup
54
-
55
-
The pre-Sessions chat stream-ID constants are gone:
56
-
57
-
-`CHAT_STREAM_KEY`, `CHAT_MESSAGES_STREAM_ID`, `CHAT_STOP_STREAM_ID` are no longer exported from `@trigger.dev/sdk/ai` or `@trigger.dev/core/v3/chat-client`.
- The labels still contain the same string values — they're now opaque breadcrumbs rather than user-consumable constants. Behavior and telemetry attrs unchanged.
60
-
61
-
These constants only mattered before chat.agent moved onto the Session primitive. Customers who referenced them externally should migrate to `sessions.open(sessionId).out.writer(...)` / `sessions.open(sessionId).in.on(...)` — same primitives, now session-keyed.
24
+
const transport =useTriggerChatTransport({ task: "my-chat", accessToken });
25
+
const { messages, sendMessage } =useChat({ transport });
26
+
```
62
27
63
-
## Core
28
+
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.
64
29
65
-
- New `chat.store` chunk types and `applyChatStorePatch` helper exported from `@trigger.dev/core/v3/chat-client`.
66
-
-`RenewRunAccessTokenParams` payload extended with `sessionId`.
30
+
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`.
Copy file name to clipboardExpand all lines: .changeset/mcp-agent-chat-sessions.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,4 +2,4 @@
2
2
"trigger.dev": patch
3
3
---
4
4
5
-
Migrate the MCP `start_agent_chat` / `send_agent_message` / `close_agent_chat` tools onto the Session primitive. The CLI MCP server now upserts a backing Session via `POST /api/v1/sessions` on chat start, threads `sessionId` through the run payload, sends messages to `session.in` as `ChatInputChunk { kind, payload }` JSON, and subscribes to `session.out` at `/realtime/v1/sessions/{sessionId}/out`. Scopes expanded from `write:inputStreams` to `read:sessions` + `write:sessions`. Upgrade-required re-trigger keeps the same session and swaps only `runId`.
5
+
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`.
Copy file name to clipboardExpand all lines: .changeset/mock-chat-agent-test-harness.md
+2-12Lines changed: 2 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,16 +3,6 @@
3
3
"@trigger.dev/core": patch
4
4
---
5
5
6
-
Offline test harness for `chat.agent`— drive a real agent's turn loop in-process, no network, no task runtime. Pairs with `MockLanguageModelV3` from `ai/test` for model mocking.
6
+
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.
7
7
8
-
**`@trigger.dev/sdk/ai/test`:**
9
-
10
-
-`mockChatAgent(agent, options)` — drives a chat.agent definition end-to-end. Send messages, actions, and stop signals via driver methods; inspect captured output chunks; verify hooks fire.
11
-
-`setupLocals` option — pre-seed `locals` (database clients, service stubs) before the agent's `run()` starts, so hooks read the test instance via `locals.get()` without leaking through untrusted `clientData`.
12
-
13
-
**`@trigger.dev/core/v3/test`:**
14
-
15
-
-`runInMockTaskContext(fn, options)` — broader test harness for any task code. Installs in-memory managers for `locals`, `lifecycleHooks`, `runtime`, `inputStreams`, and `realtimeStreams`, plus a mock `TaskContext`. Drivers send data into input streams and inspect chunks written to output streams.
16
-
-`TestRunMetadataManager` — in-memory metadata manager used by the harness.
17
-
-`TestRealtimeStreamsManager.onWrite` hook — react to stream writes without polling.
18
-
-`drivers.locals.set()` exposed for direct DI.
8
+
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.
Copy file name to clipboardExpand all lines: .changeset/sessions-primitive.md
+7-15Lines changed: 7 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,20 +3,12 @@
3
3
"@trigger.dev/sdk": patch
4
4
---
5
5
6
-
Sessions — durable, task-bound, bidirectional channel pair that outlives any single run. Foundation for `chat.agent` (separate changeset) and any other "one identifier, many runs over time" workflow.
6
+
Add Sessions — a durable, task-bound, bidirectional channel pair that outlives any single run. One identifier (your `externalId`), many runs over time, with a stable `.in` channel clients can write to and a stable `.out` channel they can subscribe to. Powers `chat.agent` (separate changeset), and unblocks anything that needs "resume tomorrow" or "approval loop" workflows.
7
7
8
-
A `Session` row is keyed on `(env, externalId)` (idempotent upsert), task-bound (`taskIdentifier` + `triggerConfig` are required), and owns its current run via `currentRunId` + `currentRunVersion` (optimistic claim). Three trigger paths: session create, append-time probe (a new run is triggered if the previous one has terminated), and `end-and-continue` for in-task version handoffs.
-`SessionHandle` with two asymmetric channels mirroring run-scoped streams:
13
-
-`.in` (`SessionInputChannel`) mirrors `streams.input` — `on` / `once` / `peek` / `wait` / `waitWithIdleTimeout` for the task to consume, `send` for external clients to produce. `.wait` / `.waitWithIdleTimeout` suspend the run on a session-stream waitpoint; the run resumes when a record lands on `.in`.
14
-
-`.out` (`SessionOutputChannel`) mirrors `streams.define` — `append` / `pipe` / `writer` for the task to produce records (all route through direct-to-S2 for uniform parsed-object serialization), plus `read` for external SSE subscribers.
15
-
-`sessionStreams` global + `StandardSessionStreamManager` (SSE-backed tail + buffer keyed on `{sessionId, io}`, registered in dev/managed run workers).
16
-
-`SessionStreamInstance` for direct-to-S2 piping; `ApiClient.createSessionStreamWaitpoint` wiring.
17
-
18
-
## Core
19
-
20
-
-`SessionId` friendly-ID generator and Session schemas, exported from `@trigger.dev/core/v3/isomorphic` alongside `RunId`, `BatchId`, etc.
21
-
-`CreateSessionStreamWaitpoint` request/response schemas alongside the main Session CRUD.
22
-
-`SessionTriggerConfig` schema: `basePayload`, `machine`, `queue`, `tags`, `maxAttempts`, `idleTimeoutInSeconds`, plus `maxDuration` (per-run wall-clock cap, seconds), `lockToVersion` (pin every run to a specific worker version), and `region` (geographic scheduling). Each forwards to the matching field on `TaskRunOptions` when the run is triggered.
14
+
Inside the task, `.in.wait()` / `.waitWithIdleTimeout()` suspends the run on a session-stream waitpoint until the next record arrives. `.out.append` / `.pipe` / `.writer` produce records via direct-to-S2 writes.
0 commit comments