Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
05b1b02
feat: add @trigger.dev/ai package with TriggerChatTransport
cursoragent Feb 15, 2026
e8e748f
test: add comprehensive unit tests for TriggerChatTransport
cursoragent Feb 15, 2026
3569bb3
refactor: polish TriggerChatTransport implementation
cursoragent Feb 15, 2026
382879d
test: add abort signal, multiple sessions, and body merging tests
cursoragent Feb 15, 2026
2f2df38
chore: add changeset for @trigger.dev/ai package
cursoragent Feb 15, 2026
bc0efed
refactor: remove internal ChatSessionState from public exports
cursoragent Feb 15, 2026
a481b50
feat: support dynamic accessToken function for token refresh
cursoragent Feb 15, 2026
fdaa673
refactor: avoid double-resolving accessToken in sendMessages
cursoragent Feb 15, 2026
3a887e4
feat: add chat transport and AI chat helpers to @trigger.dev/sdk
cursoragent Feb 15, 2026
33191c4
test: move chat transport tests to @trigger.dev/sdk
cursoragent Feb 15, 2026
93be9e9
refactor: delete packages/ai/ — moved to @trigger.dev/sdk subpaths
cursoragent Feb 15, 2026
bedab77
chore: update changeset to target @trigger.dev/sdk
cursoragent Feb 15, 2026
8d98af7
fix: address CodeRabbit review feedback
cursoragent Feb 15, 2026
53dd6ed
docs(ai): add AI Chat with useChat guide
cursoragent Feb 15, 2026
5107479
feat(reference): add ai-chat Next.js reference project
cursoragent Feb 15, 2026
e4c3812
fix(reference): use compatible @ai-sdk v3 packages, await convertToMo…
cursoragent Feb 15, 2026
4fb677c
Use a single run with iterative waitpoint token completions
ericallam Feb 21, 2026
489b5cf
Added tool example
ericallam Feb 21, 2026
a477f13
expose a useTriggerChatTransport hook
ericallam Feb 21, 2026
233be53
use input streams and rename chatTask and chatState to chat.task and …
ericallam Mar 3, 2026
008a75d
add stopping support and fix issue with the OpenAI responses API and …
ericallam Mar 4, 2026
98fa609
Add warmTimeoutInSeconds option
ericallam Mar 4, 2026
545453d
Add clientData support
ericallam Mar 4, 2026
14a2810
provide already converted UIMessages to the run function for better dx
ericallam Mar 4, 2026
f604f5a
Added better telemetry support to view turns
ericallam Mar 4, 2026
9810609
Fix double looping when resuming from an input stream waitpoint
ericallam Mar 4, 2026
e3f67ea
Add some pending message support in the example
ericallam Mar 4, 2026
8a23d34
Accumulate messages in the task, allowing us to only have to send use…
ericallam Mar 5, 2026
bf5169b
build full example with persisting messages, adding necessary hooks, …
ericallam Mar 5, 2026
109c2f8
Add ai chat to the sidebar for now
ericallam Mar 5, 2026
a44df8c
remove postinstall hook
ericallam Mar 5, 2026
8ab7a2d
feat: add onTurnStart hook, lastEventId support, and stream resume de…
ericallam Mar 5, 2026
37fb621
Minor fixes around reconnecting streams
ericallam Mar 6, 2026
fac2ad8
update pnpm link file
ericallam Mar 6, 2026
f73238d
fixed chat tests
ericallam Mar 6, 2026
741bca4
use locals for the chat pipe counter instead of a module global
ericallam Mar 6, 2026
3033461
Add triggerOptions to the transport, auto-tag with the chat ID
ericallam Mar 6, 2026
0f8d7c0
Make clientData typesafe and pass to all chat.task hooks
ericallam Mar 6, 2026
91fb072
feat: add chat.local for per-run typed data with Proxy access and dir…
ericallam Mar 6, 2026
60eee88
feat(chat): add stop handling, abort cleanup, continuation support, a…
ericallam Mar 7, 2026
41fec40
Some improvements to the example ai-chat
ericallam Mar 7, 2026
fc07575
feat(chat): expose typed chat.stream, add deepResearch subtask exampl…
ericallam Mar 8, 2026
bf389f4
feat(ai): pass chat context and toolCallId to subtasks, add typed ai.…
ericallam Mar 8, 2026
74a916a
feat(chat): add preload support, dynamic tools, and preload-specific …
ericallam Mar 9, 2026
6c03822
docs: add mermaid architecture diagrams for ai-chat system
ericallam Mar 9, 2026
61a9bb2
docs: add sequence diagrams to ai-chat guide
ericallam Mar 9, 2026
fe4e4ad
feat(chat): auto-hydrate chat.local values in ai.tool subtasks
ericallam Mar 9, 2026
cb92f69
feat(chat): add chat.defer(), preload toggle, TTFB measurement, and f…
ericallam Mar 9, 2026
28ae59e
fix(reference): replace hand-rolled HTML stripping with turndown
ericallam Mar 9, 2026
0dd697e
feat(streams): add inputStream.waitWithWarmup(), warm timeout config …
ericallam Mar 9, 2026
69f2e1b
feat(chat): add composable primitives, raw task example, and task mod…
ericallam Mar 10, 2026
1abad0d
Introduce the chat session API and better docs organization
ericallam Mar 10, 2026
7e8de7b
Add support for toUIMessageStream() options
ericallam Mar 10, 2026
5355349
Add metadata to the streamText call
ericallam Mar 12, 2026
a98ed9e
feat(chat): add chat.prompt API with provider registry support
ericallam Mar 23, 2026
fb6a9b6
refactor: rename warmTimeout to idleTimeout across chat APIs
ericallam Mar 23, 2026
44c323f
feat: support message compaction
ericallam Mar 24, 2026
3eb0f21
better compaction support in our other chat variants
ericallam Mar 24, 2026
3ec1789
feat(chat): add compaction option, pendingMessages steering, and useP…
ericallam Mar 25, 2026
5a9bb26
Add a writer to easily write chunks in callbacks
ericallam Mar 26, 2026
d3c9dcd
feat(ai): add triggerAndSubscribe method and use it in ai.tool
ericallam Mar 26, 2026
142f9fd
feat(chat): add chat.inject() for background context injection and ch…
ericallam Mar 26, 2026
f138883
feat(sdk): ToolSet typing for toolFromTask, ai.toolExecute, deprecate…
ericallam Mar 27, 2026
eec88d9
Add run-scoped PAT renewal for chat transport
ericallam Mar 27, 2026
2e40239
feat(sdk): ctx on chat.task hooks; ai-chat E2B sandbox; docs patterns
ericallam Mar 27, 2026
d92ed7a
feat(sdk): add onChatSuspend/onChatResume hooks, exitAfterPreloadIdle…
ericallam Mar 28, 2026
e6a723c
Add support for triggering from the backend
ericallam Mar 28, 2026
751df0f
chat.task -> chat.agent
ericallam Mar 30, 2026
517d00b
feat: upgrade streamdown to v2.5.0 with custom Trigger.dev Shiki theme
ericallam Apr 1, 2026
f76bda1
playground ui tweaks
ericallam Apr 1, 2026
d343999
Some design tweaks, improvements to playground options, rename unname…
ericallam Apr 1, 2026
7b35e95
Add the chat client and strip agent crumbs
ericallam Apr 1, 2026
37d04f2
Add server-to-server chat support and subagent support to the playgro…
ericallam Apr 2, 2026
1471cf5
add agent mcp tools
ericallam Apr 2, 2026
2424435
Add support for optionally validating UI messages
ericallam Apr 2, 2026
1f4d2d3
Support for upgrading an agent to a new version
ericallam Apr 3, 2026
47f0c79
Add run agent view
ericallam Apr 10, 2026
2dcda54
feat(chat): add stopGeneration, fix onTurnComplete/onFinishPromise, a…
ericallam Apr 11, 2026
57b0380
fix(sdk): inject prepareStep in toStreamTextOptions even without chat…
ericallam Apr 13, 2026
fa47721
feat(chat): allow generateMessageId in uiMessageStreamOptions, auto-p…
ericallam Apr 14, 2026
33caebf
feat(chat): tool approvals support — ID-matched message replacement, …
ericallam Apr 14, 2026
ce6b373
fix: restore applyPrepareMessages call after agentcrumbs strip
ericallam Apr 14, 2026
869a0b8
prevent preloads from firing twice when in React strictMode
ericallam Apr 14, 2026
d6d299c
feat(chat): add chat.response API for persistent data parts, transien…
ericallam Apr 14, 2026
57bb71b
feat(chat): add hydrateMessages, chat.history, and custom actions
ericallam Apr 15, 2026
4f8b566
fix(chat): prevent useChat resume from hanging on completed turns
ericallam Apr 15, 2026
555c532
fix pnpm lock file
ericallam Apr 16, 2026
b561cd6
feat(ai-chat): add askUser tool for HITL testing, verify TRI-8556 fix
ericallam Apr 17, 2026
4db2f17
chore(ai-chat): remove test-big-error trigger from onValidateMessages
ericallam Apr 17, 2026
43a2757
feat(chat): multi-tab coordination via BroadcastChannel
ericallam Apr 17, 2026
8757d24
fix(ai-chat): defer multi-tab broadcasts, disable streamdown word ani…
ericallam Apr 17, 2026
c14aafe
feat(core): add runInMockTaskContext test infrastructure
ericallam Apr 18, 2026
63be34d
feat(sdk): add mockChatAgent test harness with locals DI
ericallam Apr 18, 2026
73efe47
feat(chat): expose finishReason on turn-complete events
ericallam Apr 18, 2026
23317d3
feat(chat): add chat.endRun()
ericallam Apr 18, 2026
b656738
fix(chat): include "action" in ChatTaskPayload.trigger type
ericallam Apr 18, 2026
bf50389
feat(core): add skill resource catalog + SkillManifest schemas
ericallam Apr 18, 2026
6310ef0
feat(sdk): add skills.define + chat.skills runtime wiring
ericallam Apr 18, 2026
321d0a7
feat(cli): built-in skill bundler for trigger dev + deploy
ericallam Apr 18, 2026
9c62199
feat(sdk,cli,core,build): phase 1 of agent skills
ericallam Apr 18, 2026
1e17d04
fix(cli): skills bundler resolves caller-relative paths + correct dev…
ericallam Apr 18, 2026
8e7d068
WIP chat.store primitive
ericallam Apr 19, 2026
6034982
feat(sdk,core): Session client SDK + hello-world smoke test
ericallam Apr 20, 2026
1e16248
feat(sdk,core): Session channel SDK toolkits + waitpoints — client side
ericallam Apr 23, 2026
8aec280
feat(sdk): chat.agent → Sessions migration (phases B + C + min E)
ericallam Apr 23, 2026
3138f89
feat(sdk): server-side ChatStream / AgentChat -> Sessions (phase D)
ericallam Apr 23, 2026
c140c3e
fix(sdk,chat): route pipeChat through session.out + chat-agent smoke …
ericallam Apr 23, 2026
5f60cfd
test(sdk,core): session-aware mockChatAgent harness + chat.test.ts mocks
ericallam Apr 23, 2026
cc1c85c
docs(architecture): chat.agent over Sessions reference
ericallam Apr 23, 2026
6c41b8d
feat(cli): MCP agentChat tool → Sessions migration
ericallam Apr 23, 2026
ef72090
feat(webapp,sdk): dashboard AgentView → session streams
ericallam Apr 23, 2026
0e2463d
feat(sdk,ai-chat): skills runtime subpath + ai-chat browser test bridge
ericallam Apr 23, 2026
1659731
feat(sdk,webapp,ai-chat): end-to-end browser UI smoke on sessions
ericallam Apr 23, 2026
d928fae
feat(sdk,core): drop legacy chat stream-ID constants
ericallam Apr 23, 2026
1e1f8b4
fix(sdk,chat): make isStreaming optional in reconnectToStream short-c…
ericallam Apr 24, 2026
cc791b5
fix(webapp): use getRequestAbortSignal() for dashboard stream routes
ericallam Apr 24, 2026
d563600
refactor(sdk): extract browser-safe chat types into ai-shared
ericallam Apr 25, 2026
2f83d2c
feat(sdk,webapp): X-Peek-Settled opt-in fast-close on session.out
ericallam Apr 25, 2026
1ea612c
feat(sdk,webapp): X-Peek-Settled fast-close (webapp + docs)
ericallam Apr 25, 2026
7c3274e
feat(sdk,playground,ai-chat): chat.agent on Sessions-as-run-manager
ericallam Apr 27, 2026
9ce0134
ignore claude subdirs
ericallam Apr 28, 2026
7280934
fix sdk build for new context field
ericallam Apr 28, 2026
32036c7
fix(core): buffer session-stream chunks even when handlers exist
ericallam Apr 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/ai-chat-sandbox-and-ctx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@trigger.dev/sdk": patch
---

Add `TaskRunContext` (`ctx`) to all `chat.task` lifecycle events, `CompactedEvent`, and `ChatTaskRunPayload`. Export `TaskRunContext` from `@trigger.dev/sdk`.

42 changes: 42 additions & 0 deletions .changeset/ai-sdk-chat-transport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
"@trigger.dev/sdk": minor
---

Add AI SDK chat transport integration via two new subpath exports:

**`@trigger.dev/sdk/chat`** (frontend, browser-safe):
- `TriggerChatTransport` — custom `ChatTransport` for the AI SDK's `useChat` hook that runs chat completions as durable Trigger.dev tasks
- `createChatTransport()` — factory function

```tsx
import { useChat } from "@ai-sdk/react";
import { TriggerChatTransport } from "@trigger.dev/sdk/chat";

const { messages, sendMessage } = useChat({
transport: new TriggerChatTransport({
task: "my-chat-task",
accessToken,
}),
});
```

**`@trigger.dev/sdk/ai`** (backend, extends existing `ai.tool`/`ai.currentToolOptions`):
- `chatTask()` — pre-typed task wrapper with auto-pipe support
- `pipeChat()` — pipe a `StreamTextResult` or stream to the frontend
- `CHAT_STREAM_KEY` — the default stream key constant
- `ChatTaskPayload` type

```ts
import { chatTask } from "@trigger.dev/sdk/ai";
import { streamText, convertToModelMessages } from "ai";

export const myChatTask = chatTask({
id: "my-chat-task",
run: async ({ messages }) => {
return streamText({
model: openai("gpt-4o"),
messages: convertToModelMessages(messages),
});
},
});
```
5 changes: 5 additions & 0 deletions .changeset/ai-tool-execute-helper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Add `ai.toolExecute(task)` so you can pass Trigger's subtask/metadata wiring as the `execute` handler to AI SDK `tool()` while defining `description` and `inputSchema` yourself. Refactors `ai.tool()` to share the same internal handler.
6 changes: 6 additions & 0 deletions .changeset/ai-tool-toolset-typing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@trigger.dev/sdk": patch
---

Align `ai.tool()` (`toolFromTask`) with the AI SDK `ToolSet` shape: Zod-backed tasks use static `tool()`; returns are asserted as `Tool & ToolSet[string]`. Raise the SDK's minimum `ai` devDependency 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).

5 changes: 5 additions & 0 deletions .changeset/chat-agent-action-trigger-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Include `"action"` in the `ChatTaskPayload.trigger` union. `run()` is invoked with `trigger: "action"` after `onAction` processes a typed action, but the type previously omitted it. Users can now cleanly short-circuit the LLM call for actions that don't need a response (e.g. user-initiated compaction): `if (trigger === "action") return;`.
5 changes: 5 additions & 0 deletions .changeset/chat-agent-end-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Add `chat.endRun()` — exits the run after the current turn completes, without the upgrade-required signal that `chat.requestUpgrade()` sends. Use when an agent finishes its work on its own terms (one-shot responses, goal achieved, budget exhausted) instead of waiting idle for the next user message. Call from `run()`, `chat.defer()`, `onBeforeTurnComplete`, or `onTurnComplete`.
5 changes: 5 additions & 0 deletions .changeset/chat-agent-finish-reason.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Expose `finishReason` on `TurnCompleteEvent` and `BeforeTurnCompleteEvent`. Surfaces the AI SDK's `FinishReason` (`"stop" | "tool-calls" | "length" | ...`) so hooks can distinguish a normal turn end from one paused on a pending tool call (HITL flows like `ask_user`). Undefined for manual `pipeChat()` or aborted streams.
16 changes: 16 additions & 0 deletions .changeset/chat-agent-skills-phase-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@trigger.dev/sdk": patch
"@trigger.dev/core": patch
"@trigger.dev/build": patch
"trigger.dev": patch
---

Add agent skills — developer-authored folders (`SKILL.md` + scripts/references/assets) bundled into the deploy image automatically, 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.

**New:**
- `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.
- `SkillHandle.local()` reads the bundled `SKILL.md` at runtime, parses frontmatter, returns a `ResolvedSkill`.
- `chat.skills.set([...])` stores resolved skills for the current run.
- `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.

Phase 1 is SDK + CLI only — no backend, no dashboard overrides. Dashboard-editable `SKILL.md` text lands in Phase 2 (`skill.resolve()` currently throws).
9 changes: 9 additions & 0 deletions .changeset/chat-customagent-session-binding-and-stop-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@trigger.dev/sdk": patch
---

Three chat.agent fixes surfaced by smoke-testing the Sessions migration:

- **`chat.customAgent` now binds the session handle.** Previously only `chat.agent` set up the per-run `SessionHandle` in run-locals, 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` function and opens the session via `payload.sessionId ?? payload.chatId` before invoking it, matching `chat.agent`'s behavior.
- **Stop mid-stream no longer hangs the turn loop.** When the user aborts a turn, the AI SDK's `runResult.totalUsage` promise can stay unresolved indefinitely on Anthropic streams, blocking `onTurnComplete` / `writeTurnComplete` / the next-message wait. The await is now raced against a 2s timeout (mirroring the existing `onFinishPromise` race), so a stuck `totalUsage` falls through to a non-fatal "usage unknown" path and the turn finalizes correctly.
- **New `chat.sessionId` getter.** Returns the friendlyId (`session_*`) of the run's backing Session. Useful in `onPreload` / `onChatStart` / `onTurnComplete` for persisting the session id alongside `runId` so reloads can resume the same conversation. Throws if called outside a chat.agent / chat.customAgent run.
5 changes: 5 additions & 0 deletions .changeset/chat-reconnect-isstreaming-optional.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

`TriggerChatTransport.reconnectToStream` no longer requires callers to persist an `isStreaming` flag in `ChatSession` state. Previously, any falsy `isStreaming` (including `undefined` when the flag was dropped from persistence) short-circuited reconnect to `null` and left the UI hanging on incomplete streams. Now the short-circuit only triggers on an explicit `isStreaming === false`, so callers can drop the flag entirely and let the server decide via the session's own `.out` tail. Existing callers that still persist `isStreaming` are unaffected.
6 changes: 6 additions & 0 deletions .changeset/chat-run-pat-renewal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@trigger.dev/core": patch
"@trigger.dev/sdk": patch
---

Add run-scoped PAT renewal for chat transport (`renewRunAccessToken`), fail fast on 401/403 for SSE without retry backoff, and export `isTriggerRealtimeAuthError` for auth-error detection.
21 changes: 21 additions & 0 deletions .changeset/chat-store-primitive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
"@trigger.dev/sdk": patch
"@trigger.dev/core": patch
---

Add `chat.store` — a typed, bidirectional shared data slot on `chat.agent`. Agent-side foundation for TRI-8602. Independent of AG-UI — the same primitive will back the AG-UI `STATE_SNAPSHOT` / `STATE_DELTA` translator later.

**New on the agent:**
- `chat.store.set(value)` — replace, emits a `store-snapshot` chunk on the existing chat output stream.
- `chat.store.patch([...])` — RFC 6902 JSON Patch, emits a `store-delta` chunk.
- `chat.store.get()` — read the current value (scoped to the run).
- `chat.store.onChange((value, ops) => ...)` — subscribe to changes.
- `hydrateStore?: (event) => value` config on `chat.agent` — mirrors `hydrateMessages`; restore the store after a continuation from your own persistence layer.
- `ChatTaskWirePayload.incomingStore` — optional wire field applied at turn start before `run()` fires (last-write-wins over `hydrateStore`).

**New in core:**
- `store-snapshot` / `store-delta` chunk types and `applyChatStorePatch` helper exported from `@trigger.dev/core/v3/chat-client`.

The store lives in memory for the lifetime of the run and is persisted by the existing chat output stream plus the `hydrateStore` hook across continuations — no new infrastructure.

Client-side pieces (transport `getStore` / `setStore` / `applyStorePatch` / listeners, `AgentChat` accessors, `useChatStore` React hook, reference demo, docs) land in a follow-up.
8 changes: 8 additions & 0 deletions .changeset/chat-transport-session-renew-plus-preload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@trigger.dev/sdk": patch
---

`TriggerChatTransport` fixes for session-scoped auth and end-to-end UI smoke parity:

- `RenewRunAccessTokenParams` now includes the durable `sessionId` alongside `chatId` + `runId`. Server-side renew handlers should mint the renewed PAT with `read:sessions:{sessionId}` + `write:sessions:{sessionId}` scopes (in addition to the existing run scopes) so it keeps authenticating against the session `.in` append + `.out` subscribe endpoints. Renewing without session scopes sends the transport into a 401 loop on the first append after expiry.
- `transport.preload(chatId)` on the `triggerTask` callback path no longer calls `apiClient.createSession` from the browser. The server action (e.g. `chat.createTriggerAction`) creates the session with its secret key and returns the `sessionId` in its result, matching how `sendMessages` already worked. Browser deployments that use the `triggerTask` callback path therefore no longer need `write:sessions` on any browser-side token.
11 changes: 11 additions & 0 deletions .changeset/drop-legacy-chat-stream-constants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@trigger.dev/sdk": patch
"@trigger.dev/core": patch
---

Drop the pre-Sessions chat stream-ID constants from the public surface:

- `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`. Deletes `packages/trigger-sdk/src/v3/chat-constants.ts`.
- The `chat.stream.id` / `chat.messages.id` / `chat.stopSignal.id` labels still contain the same string values (`"chat"` / `"chat-messages"` / `"chat-stop"`) — now inlined as opaque breadcrumbs rather than user-consumable constants. Behavior and telemetry attrs are unchanged.

These constants only mattered before the chat.agent I/O moved onto the Session primitive — the SDK no longer writes to run-scoped `streams.writer(CHAT_STREAM_KEY, …)` / `streams.input(CHAT_*_STREAM_ID)` at all. Customers who still referenced them externally should migrate to `sessions.open(sessionId).out.writer(...)` / `sessions.open(sessionId).in.on(...)` — same primitives, now session-keyed.
5 changes: 5 additions & 0 deletions .changeset/dry-sloths-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Add `chat.withUIMessage<TUIMessage>()` for typed AI SDK `UIMessage` in chat task hooks, optional factory `streamOptions` merged with `uiMessageStreamOptions`, and `InferChatUIMessage` helper. Generic `ChatUIMessageStreamOptions`, compaction, and pending-message event types. `usePendingMessages` accepts a UI message type parameter; re-export `InferChatUIMessage` from `@trigger.dev/sdk/chat/react`.
5 changes: 5 additions & 0 deletions .changeset/mcp-agent-chat-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---

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`.
6 changes: 6 additions & 0 deletions .changeset/mock-chat-agent-setup-locals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@trigger.dev/sdk": patch
"@trigger.dev/core": patch
---

Add `setupLocals` option to `mockChatAgent` for dependency injection in tests. 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`. Also exposes `drivers.locals.set()` on `runInMockTaskContext`.
8 changes: 8 additions & 0 deletions .changeset/mock-chat-agent-test-harness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@trigger.dev/sdk": patch
"@trigger.dev/core": patch
---

Add `mockChatAgent` test harness at `@trigger.dev/sdk/ai/test` for unit-testing `chat.agent` definitions offline. Drives a real agent's turn loop without network or task runtime: 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.

Also adds `TestRunMetadataManager` to `@trigger.dev/core/v3/test` (in-memory metadata manager used by the harness), and exposes an `onWrite` hook on `TestRealtimeStreamsManager` so harnesses can react to stream writes without polling.
5 changes: 5 additions & 0 deletions .changeset/mock-task-context-test-infra.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---

Add `runInMockTaskContext` test harness at `@trigger.dev/core/v3/test` for unit-testing task code offline. Installs in-memory managers for `locals`, `lifecycleHooks`, `runtime`, `inputStreams`, and `realtimeStreams`, plus a mock `TaskContext`, so tasks can be driven end-to-end without hitting the Trigger.dev runtime. Provides drivers to send data into input streams and inspect chunks written to output streams.
11 changes: 11 additions & 0 deletions .changeset/session-sdk-toolkit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@trigger.dev/core": patch
"@trigger.dev/sdk": patch
---

Extend `SessionHandle` with two asymmetric channels mirroring the run-scoped streams primitives:

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

Adds the `sessionStreams` global + `StandardSessionStreamManager` (SSE-backed tail + buffer keyed on `{sessionId, io}`, registered in dev/managed run workers), `SessionStreamInstance` for direct-to-S2 piping, and `ApiClient.createSessionStreamWaitpoint` wiring.
5 changes: 5 additions & 0 deletions .changeset/skills-runtime-subpath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Split the skill-runtime primitives (`bash` + `readFile` tool implementations, backed by `node:child_process` + `node:fs/promises`) out of `@trigger.dev/sdk/ai` into a new `@trigger.dev/sdk/ai/skills-runtime` subpath. 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 now loads the runtime lazily via a computed-string dynamic import, so server workers still get full skill support without any caller changes.
23 changes: 23 additions & 0 deletions .changeset/trigger-chat-transport-watch-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
"@trigger.dev/sdk": patch
---

Add `watch` option to `TriggerChatTransport` for read-only observation of an existing chat run.

When set to `true`, the transport keeps its internal `ReadableStream` open across `trigger:turn-complete` control chunks instead of closing it after each turn. This lets a single `useChat` / `resumeStream` subscription observe every turn of a long-lived agent run — useful for dashboard viewers or debug UIs that only want to watch an existing conversation as it unfolds, rather than drive it.

```tsx
const transport = new TriggerChatTransport({
task: "my-chat-task",
accessToken: runScopedPat,
watch: true,
sessions: {
[chatId]: { runId, publicAccessToken: runScopedPat },
},
});

const { messages, resumeStream } = useChat({ id: chatId, transport });
useEffect(() => { resumeStream(); }, [resumeStream]);
```

Non-watch transports are unaffected — the default remains `false` and existing behavior (close on turn-complete so `useChat` can flip to `"ready"` between turns) is preserved for interactive playground-style flows.
Loading
Loading