Skip to content

Commit 1e5a647

Browse files
committed
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.
1 parent bd9754d commit 1e5a647

6 files changed

Lines changed: 35 additions & 84 deletions

File tree

.changeset/agent-skills.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
"trigger.dev": patch
66
---
77

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).
99

10-
**SDK:**
10+
```ts
11+
const pdfSkill = skills.define({ id: "pdf-extract", path: "./skills/pdf-extract" });
1112

12-
- `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([await pdfSkill.local()]);
14+
```
1715

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.

.changeset/ai-tool-helpers.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22
"@trigger.dev/sdk": patch
33
---
44

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

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.

.changeset/chat-agent.md

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,7 @@
33
"@trigger.dev/core": patch
44
---
55

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

238
```ts
249
import { chat } from "@trigger.dev/sdk/ai";
@@ -32,35 +17,14 @@ export const myChat = chat.agent({
3217
});
3318
```
3419

35-
**`@trigger.dev/sdk/chat`** (frontend / browser):
36-
37-
- `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`.
43-
44-
**`@trigger.dev/sdk/chat/react`**:
45-
46-
- `useTriggerChatTransport({ task, accessToken, ... })` — memoized hook wrapping `TriggerChatTransport` for `useChat`.
20+
```tsx
21+
import { useChat } from "@ai-sdk/react";
22+
import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
4723

48-
## chat.agent fixes folded in
49-
50-
- `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`.
58-
- `packages/trigger-sdk/src/v3/chat-constants.ts` deleted.
59-
- 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+
```
6227

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

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

.changeset/mcp-agent-chat-sessions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
"trigger.dev": patch
33
---
44

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

.changeset/mock-chat-agent-test-harness.md

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,6 @@
33
"@trigger.dev/core": patch
44
---
55

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-processno 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.
77

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.

.changeset/sessions-primitive.md

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,12 @@
33
"@trigger.dev/sdk": patch
44
---
55

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

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.
8+
```ts
9+
const session = await sessions.create({ externalId: chatId, taskIdentifier: "my-task" });
10+
await session.in.send({ kind: "message", payload: "..." });
11+
for await (const chunk of session.out.read()) { /* ... */ }
12+
```
913

10-
## SDK
11-
12-
- `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

Comments
 (0)