Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
217 commits
Select commit Hold shift + click to select a range
0f932eb
Add @trigger.dev/ai package with chat transport and tests
cursoragent Feb 14, 2026
af510e6
Document and demo @trigger.dev/ai useChat transport
cursoragent Feb 14, 2026
092c2ba
Add ai compatibility tests and preserve sdk behavior
cursoragent Feb 14, 2026
7c0476c
Use function declaration style in ai.tool execute callback
cursoragent Feb 14, 2026
babf007
Add changelog for new @trigger.dev/ai package
cursoragent Feb 14, 2026
60f2a32
Add custom mapper and trigger options transport test
cursoragent Feb 14, 2026
b30a66b
Add factory constructor coverage for chat transport
cursoragent Feb 14, 2026
58b43ec
Track exact SSE event IDs for chat reconnect
cursoragent Feb 14, 2026
cf1b5c7
Add compile-time DX tests for chat transport types
cursoragent Feb 14, 2026
b511566
Cleanup run-store entries when chat streams finish
cursoragent Feb 14, 2026
d706534
Test reconnect null behavior after completed streams
cursoragent Feb 14, 2026
cc2be18
Cover async run store implementations in chat transport tests
cursoragent Feb 14, 2026
5d5a757
Test default stream fallback path in chat transport
cursoragent Feb 14, 2026
b53b61b
Add package README for @trigger.dev/ai usage
cursoragent Feb 14, 2026
d02edc3
Deprecate sdk ai import path in favor of @trigger.dev/ai
cursoragent Feb 14, 2026
70d297c
Test stream key URL encoding in chat transport
cursoragent Feb 14, 2026
9974f22
Guard reconnect against fetch setup failures
cursoragent Feb 14, 2026
390e53c
Document custom payload mapping and run store options
cursoragent Feb 14, 2026
ffb91a1
Support async payload and trigger option resolvers
cursoragent Feb 14, 2026
7d17be7
Document advanced chat transport mapping and run store options
cursoragent Feb 14, 2026
889194a
Cover typed stream definition ids in transport tests
cursoragent Feb 14, 2026
63e98c2
Add sdk parity test against @trigger.dev/ai helper
cursoragent Feb 14, 2026
d79c586
Cover static trigger options path in chat transport
cursoragent Feb 14, 2026
df877ee
Cover mapper and trigger option resolver failure paths
cursoragent Feb 15, 2026
3f1d98f
Support async onTriggeredRun callbacks in chat transport
cursoragent Feb 15, 2026
e8222f7
Document onTriggeredRun callback option in streams guide
cursoragent Feb 15, 2026
bc1a10c
Ignore onTriggeredRun callback failures during streaming
cursoragent Feb 15, 2026
bff60e1
Clarify reconnect lifecycle behavior in transport docs
cursoragent Feb 15, 2026
3766c73
Recommend @trigger.dev/ai in trigger-sdk README
cursoragent Feb 15, 2026
302df5e
Normalize tuple-style headers in transport request mapping
cursoragent Feb 15, 2026
dc48c61
Add factory payload inference type-level coverage
cursoragent Feb 15, 2026
19909ea
Allow tuple header inputs in transport send options
cursoragent Feb 15, 2026
5d24c69
Document supported header input formats for transport
cursoragent Feb 15, 2026
7a3db86
Assert onTriggeredRun receives initial run state snapshot
cursoragent Feb 15, 2026
b7c2b2e
Expand ai package changelog with transport capabilities
cursoragent Feb 15, 2026
f9dcafa
Export explicit send/reconnect option helper types
cursoragent Feb 15, 2026
c0fa995
Test preview branch and timeout header propagation
cursoragent Feb 15, 2026
bc9e06c
Strengthen async run store interaction assertions
cursoragent Feb 15, 2026
6843732
Document exported request option helper aliases
cursoragent Feb 15, 2026
e69a1d2
Add sdk patch changeset for ai package guidance
cursoragent Feb 15, 2026
5d492d6
Document exported transport option helper types in streams docs
cursoragent Feb 15, 2026
227290b
Pass immutable run-state snapshot to onTriggeredRun
cursoragent Feb 15, 2026
5efba13
Cleanup inactive reconnect state entries on access
cursoragent Feb 15, 2026
1f49bc2
Add optional onError callback for non-fatal transport issues
cursoragent Feb 15, 2026
f235e1d
Update ai changelog with latest transport enhancements
cursoragent Feb 15, 2026
6ead0d0
Cover reconnect and tracking phases in onError callback tests
cursoragent Feb 15, 2026
a4bab4c
Add type-level coverage for onError callback payload
cursoragent Feb 15, 2026
d870c19
Add type coverage for custom run store options
cursoragent Feb 15, 2026
677debc
Export header normalization helper for advanced integrations
cursoragent Feb 15, 2026
4cf0b97
Add type coverage for onError option wiring
cursoragent Feb 15, 2026
6f4b9f0
Document onError callback payload fields
cursoragent Feb 15, 2026
8f5c16a
Report send-phase errors through onError callback
cursoragent Feb 15, 2026
dc01fab
Note phase-aware onError reporting in ai changelog
cursoragent Feb 15, 2026
add5ed3
Keep exported header normalization helper as supported API
cursoragent Feb 15, 2026
8e1821c
Assert normalized object headers are copied immutably
cursoragent Feb 15, 2026
0e403de
Verify duplicate header keys use last value on normalization
cursoragent Feb 15, 2026
6100c6e
Use shared transport error type in reportError
cursoragent Feb 15, 2026
d0b3119
Cover non-Error mapper failures in onError reporting
cursoragent Feb 15, 2026
a7cba36
Cover non-Error trigger option failures in onError reporting
cursoragent Feb 15, 2026
d729344
Cover non-Error trigger task failures in onError reporting
cursoragent Feb 15, 2026
b76c8b5
Cover non-Error reconnect failures in onError reporting
cursoragent Feb 15, 2026
afd9df5
Cover non-Error onTriggeredRun failures in onError reporting
cursoragent Feb 15, 2026
58b6dc3
Document non-Error normalization in onError changelog notes
cursoragent Feb 15, 2026
1c50671
Clarify onError normalization behavior in streams docs
cursoragent Feb 15, 2026
2236e0f
Ensure onError failures never mask mapper errors
cursoragent Feb 15, 2026
065d933
Ensure onError failures do not mask trigger option/task errors
cursoragent Feb 15, 2026
ebd39aa
Verify reconnect flow tolerates onError callback failures
cursoragent Feb 15, 2026
8e0dcd4
Harden consumeTrackingStream error callback coverage
cursoragent Feb 15, 2026
4b4953c
Report stream subscribe failures through onError lifecycle
cursoragent Feb 15, 2026
9790990
Cover non-Error stream subscription failures in onError reporting
cursoragent Feb 15, 2026
a1d32c4
Assert stream subscribe cleanup transitions run state
cursoragent Feb 15, 2026
e97fc5c
Refactor run-state cleanup into shared transport helper
cursoragent Feb 15, 2026
fe5cd3d
Use immutable run-state updates in tracking and cleanup paths
cursoragent Feb 15, 2026
e782303
Cover async run-store cleanup on stream subscribe failures
cursoragent Feb 15, 2026
bf7bee8
Assert onError remains silent on successful chat streams
cursoragent Feb 15, 2026
0779d54
Assert reconnect non-error paths do not invoke onError
cursoragent Feb 15, 2026
0323712
Assert reconnect success path does not invoke onError
cursoragent Feb 15, 2026
90198de
Preserve thrown string when stream subscribe onError callback fails
cursoragent Feb 15, 2026
382577f
Avoid masking transport failures when run-store cleanup fails
cursoragent Feb 15, 2026
b912e4f
Document best-effort run-store cleanup error semantics
cursoragent Feb 15, 2026
654bab0
Cover cleanup delete failures across stream subscribe and reconnect
cursoragent Feb 15, 2026
ed2207f
Cover consumeTracking cleanup failures without masking root errors
cursoragent Feb 15, 2026
c441984
Cover completion path behavior when cleanup delete fails
cursoragent Feb 15, 2026
e0219ce
Cover consumeTracking root errors when cleanup and onError both fail
cursoragent Feb 15, 2026
d4266a6
Cover combined cleanup and onError failure resilience paths
cursoragent Feb 15, 2026
fc3d9b8
Cover completion path behavior when cleanup set fails
cursoragent Feb 15, 2026
43205f7
Attempt run-store delete even when inactive-state write fails
cursoragent Feb 15, 2026
aab79a0
Document dual-step best-effort run-store cleanup behavior
cursoragent Feb 15, 2026
7eb4f5d
Cover cleanup set+delete dual failure path during stream subscribe
cursoragent Feb 15, 2026
3c24068
Cover reconnect path when cleanup set and delete both fail
cursoragent Feb 15, 2026
526b66f
Cover completion path when cleanup set and delete both fail
cursoragent Feb 15, 2026
50b9407
Cover consumeTracking path when cleanup set and delete both fail
cursoragent Feb 15, 2026
677fc06
Cover reconnect behavior when cleanup and onError all fail
cursoragent Feb 15, 2026
4006a68
Handle inactive reconnect cleanup delete failures non-fatally
cursoragent Feb 15, 2026
864125c
Cover inactive reconnect cleanup string failures and normalization
cursoragent Feb 15, 2026
eaf59f2
Cover inactive reconnect cleanup delete failures without onError
cursoragent Feb 15, 2026
9cf96d9
Cover inactive reconnect string cleanup failures without onError
cursoragent Feb 15, 2026
87f92e7
Document reconnect inactive-cleanup error reporting semantics
cursoragent Feb 15, 2026
8e8f3e0
Cover consumeTracking behavior when cleanup and onError all fail
cursoragent Feb 15, 2026
8dffb95
Cover reconnect after completion with dual cleanup-step failures
cursoragent Feb 15, 2026
0a5d8cf
Assert cleanup set failures still drive delete attempts
cursoragent Feb 15, 2026
3732bd6
Cover retry behavior for inactive reconnect cleanup failures
cursoragent Feb 15, 2026
2b6723e
Retry inactive reconnect cleanup after string delete failures
cursoragent Feb 15, 2026
bec4401
Assert full run-state transition snapshots on stream completion
cursoragent Feb 15, 2026
d604b94
Assert inactive reconnect cleanup never attempts stream fetch
cursoragent Feb 15, 2026
5f6e78b
Document retry behavior for stale inactive reconnect cleanup
cursoragent Feb 15, 2026
fa195ff
Cover object cleanup-delete normalization for inactive reconnect
cursoragent Feb 15, 2026
81d62b5
Assert active reconnect delete failures retry via inactive cleanup path
cursoragent Feb 15, 2026
80dcd2d
Cover repeated inactive cleanup failures with per-attempt onError
cursoragent Feb 15, 2026
89ec29d
Cover reconnect delete string failures on active cleanup path
cursoragent Feb 15, 2026
63454ef
Cover repeated inactive cleanup failures without onError
cursoragent Feb 15, 2026
42a2535
Track cleanup delete attempts in reconnect retry tests
cursoragent Feb 15, 2026
7e0eb51
Extract inactive reconnect cleanup into dedicated helper
cursoragent Feb 15, 2026
5307d73
Cover active reconnect cleanup delete failures without onError
cursoragent Feb 15, 2026
6903526
Document reconnect behavior when onError is omitted
cursoragent Feb 15, 2026
82f8950
Cover stream URL encoding for trigger run IDs
cursoragent Feb 15, 2026
5eeafc2
Cover trailing slash normalization for transport baseURL
cursoragent Feb 15, 2026
c12315f
Cover baseURL path-prefix support for trigger and stream routes
cursoragent Feb 15, 2026
a736fa9
Normalize baseURL once for trigger and stream endpoints
cursoragent Feb 15, 2026
8be2472
Cover baseURL path-prefix trailing slash normalization
cursoragent Feb 15, 2026
fcb140b
Assert baseURL trailing-slash normalization for trigger endpoint
cursoragent Feb 15, 2026
e2438ab
Cover prefixed baseURL plus run/stream URL encoding
cursoragent Feb 15, 2026
b44b4e5
Document baseURL normalization semantics for transport endpoints
cursoragent Feb 15, 2026
7d75401
Cover inactive string cleanup retries without onError callback
cursoragent Feb 15, 2026
b38d231
Trim baseURL whitespace before endpoint normalization
cursoragent Feb 15, 2026
c132ca4
Add baseURL whitespace trim path-prefix transport test
cursoragent Feb 15, 2026
29a8d6e
Add trimmed baseURL prefixed encoding transport coverage
cursoragent Feb 15, 2026
4ae1207
Validate normalized baseURL cannot be empty
cursoragent Feb 15, 2026
edeed64
Add factory-path baseURL empty validation coverage
cursoragent Feb 15, 2026
3a9047b
Validate baseURL is an absolute URL
cursoragent Feb 15, 2026
9afa035
Require http(s) protocol for chat transport baseURL
cursoragent Feb 15, 2026
915573c
Cover uppercase HTTP baseURL protocol handling
cursoragent Feb 15, 2026
db22f32
Reject baseURL query and hash components
cursoragent Feb 15, 2026
7f4cca5
Cover accepted https baseURL validation paths
cursoragent Feb 15, 2026
39492e6
Reject credential-bearing baseURL values
cursoragent Feb 15, 2026
ae2942e
Document baseURL validation in ai package changeset
cursoragent Feb 15, 2026
861e42a
Cover trimmed query-bearing baseURL rejection paths
cursoragent Feb 15, 2026
cb701f2
Cover trimmed hash and credential baseURL rejection
cursoragent Feb 15, 2026
c970ff0
Cover uppercase HTTPS baseURL acceptance paths
cursoragent Feb 15, 2026
c00d630
Add explicit baseURL examples to ai docs
cursoragent Feb 15, 2026
2f1c683
Cover ws and wss baseURL protocol rejection
cursoragent Feb 15, 2026
d56f58d
Document ws and wss baseURL rejection examples
cursoragent Feb 15, 2026
5a017a7
Refactor baseURL validation into focused helpers
cursoragent Feb 15, 2026
341e345
Cover trimmed ws and wss baseURL rejection
cursoragent Feb 15, 2026
9c3228b
Document exact baseURL validation error messages
cursoragent Feb 15, 2026
8309d57
Cover baseURL validation error precedence
cursoragent Feb 15, 2026
be5487f
Cover hash-over-credential validation precedence
cursoragent Feb 15, 2026
b9eb04c
Cover factory acceptance for uppercase HTTP baseURL
cursoragent Feb 15, 2026
1f7a165
Document case-insensitive baseURL protocol matching
cursoragent Feb 15, 2026
b751ad8
Centralize baseURL validation error messages
cursoragent Feb 15, 2026
2a60d1d
Document deterministic baseURL validation ordering
cursoragent Feb 15, 2026
9863544
Note baseURL validation ordering in changeset
cursoragent Feb 15, 2026
7d3eac2
Cover whitespace-wrapped uppercase HTTP baseURL acceptance
cursoragent Feb 15, 2026
5db7fb7
Cover whitespace uppercase HTTPS baseURL acceptance
cursoragent Feb 15, 2026
0cb113b
Cover runtime uppercase HTTP baseURL prefix normalization
cursoragent Feb 15, 2026
c69808e
Expand baseURL precedence coverage for mixed invalid inputs
cursoragent Feb 15, 2026
b4f5a8b
Add baseURL validation ordering examples to docs
cursoragent Feb 15, 2026
4d0270d
Cover omitted baseURL default constructor paths
cursoragent Feb 15, 2026
e6e6bee
Cover newline and tab baseURL whitespace trimming
cursoragent Feb 15, 2026
3aa5ad1
Cover non-breaking-space baseURL normalization paths
cursoragent Feb 15, 2026
bf05b94
Document default baseURL behavior when omitted
cursoragent Feb 15, 2026
ed520b6
Cover empty-after-NBSP baseURL validation paths
cursoragent Feb 15, 2026
e92a84e
Expand changeset notes for baseURL defaults and protocol casing
cursoragent Feb 15, 2026
2644de5
Reject internal whitespace in normalized baseURL values
cursoragent Feb 15, 2026
0aa2edb
Prioritize internal-whitespace baseURL validation
cursoragent Feb 15, 2026
a70ecde
Cover internal tab characters in baseURL validation
cursoragent Feb 15, 2026
6e8c236
Document internal-tab baseURL invalid examples
cursoragent Feb 15, 2026
6363e7e
Cover percent-encoded whitespace baseURL acceptance
cursoragent Feb 15, 2026
43cf6c9
Cover percent-encoded delimiter paths in baseURL validation
cursoragent Feb 15, 2026
c8bdcd9
Cover carriage-return baseURL whitespace validation
cursoragent Feb 15, 2026
c82bf64
Hoist baseURL internal-whitespace regex constant
cursoragent Feb 15, 2026
666b991
Cover trimmed wrapper query/hash validation path
cursoragent Feb 15, 2026
4432ba4
Cover wrapped percent-encoded delimiter baseURL paths
cursoragent Feb 15, 2026
0d4cc70
Reject invisible separator characters in baseURL
cursoragent Feb 15, 2026
dec91eb
Cover BOM wrapper and internal BOM baseURL handling
cursoragent Feb 15, 2026
b3bd45c
Cover vertical-tab baseURL whitespace validation
cursoragent Feb 15, 2026
168cf85
Cover form-feed baseURL whitespace validation
cursoragent Feb 15, 2026
b72e6b6
Cover internal-space baseURL validation paths
cursoragent Feb 15, 2026
fcec4c1
Document internal-whitespace regex intent
cursoragent Feb 15, 2026
722f9ed
Clarify invisible separator handling in baseURL docs
cursoragent Feb 15, 2026
e1ada23
Cover narrow no-break-space baseURL validation
cursoragent Feb 15, 2026
c8e6599
Cover line-separator baseURL whitespace validation
cursoragent Feb 15, 2026
9bb67ad
Cover paragraph-separator baseURL whitespace validation
cursoragent Feb 15, 2026
99d96a4
Cover BOM-wrapped uppercase HTTP baseURL acceptance
cursoragent Feb 15, 2026
958ed8b
Cover internal non-breaking-space baseURL rejection
cursoragent Feb 15, 2026
2c92d07
Cover word-joiner baseURL whitespace validation
cursoragent Feb 15, 2026
8d074d7
Cover zero-width-non-joiner baseURL whitespace validation
cursoragent Feb 15, 2026
2df81ff
Cover zero-width-joiner baseURL whitespace validation
cursoragent Feb 15, 2026
fb71d5a
Cover word-joiner wrapper baseURL rejection
cursoragent Feb 15, 2026
9fa12b0
Cover zero-width-space wrapper baseURL rejection
cursoragent Feb 15, 2026
140fc20
Cover zero-width-non-joiner wrapper baseURL rejection
cursoragent Feb 15, 2026
9baa514
Cover zero-width-joiner wrapper baseURL rejection
cursoragent Feb 15, 2026
abdddac
Add invisible-separator precedence coverage and docs example
cursoragent Feb 15, 2026
1a2f243
Document rejection of invisible-separator baseURL wrappers
cursoragent Feb 15, 2026
2c7f40c
Fix docs to list exact internal-whitespace error message
cursoragent Feb 15, 2026
06322fd
Cover additional unicode whitespace baseURL rejections
cursoragent Feb 15, 2026
f96b545
Cover unicode-trimmable baseURL wrappers in acceptance tests
cursoragent Feb 15, 2026
195f5f3
Cover newline-tab wrapped baseURL acceptance
cursoragent Feb 15, 2026
bed3c81
Cover empty-after-trim unicode wrapper baseURL validation
cursoragent Feb 15, 2026
25f4cde
Document unicode wrapper trimming and empty-after-trim behavior
cursoragent Feb 15, 2026
7924efb
Cover additional unicode spacing baseURL rejections
cursoragent Feb 15, 2026
ae87637
Cover additional unicode wrapper trimming acceptance
cursoragent Feb 15, 2026
a9fd293
Cover additional empty-after-trim unicode wrapper baseURLs
cursoragent Feb 15, 2026
cc0b1d6
Document expanded unicode whitespace coverage in release notes
cursoragent Feb 15, 2026
3e7fe1f
Cover newline-tab wrapped invalid baseURL validation paths
cursoragent Feb 15, 2026
bcd5a3a
Cover newline-tab wrapped websocket protocol validation
cursoragent Feb 15, 2026
17a1975
Document trimmed-wrapper hash and credential baseURL rejections
cursoragent Feb 15, 2026
d1e9220
Cover unicode-wrapped baseURL path-prefix runtime normalization
cursoragent Feb 15, 2026
28becff
Reject mongolian-vowel-separator baseURL invisible whitespace
cursoragent Feb 15, 2026
842d83b
Cover mongolian separator precedence in mixed-invalid baseURLs
cursoragent Feb 15, 2026
79a2d39
Cover mongolian separator slash-wrapper validation behavior
cursoragent Feb 15, 2026
7caa78f
Cover hair-space baseURL wrapper and internal validation
cursoragent Feb 15, 2026
a3dbae6
Cover thin-space baseURL wrapper and internal validation
cursoragent Feb 15, 2026
580b986
Cover punctuation-space baseURL wrapper and internal validation
cursoragent Feb 15, 2026
2ce01e1
Cover six-per-em-space baseURL wrapper and internal validation
cursoragent Feb 15, 2026
7fe37c2
Cover em-space baseURL wrapper and internal validation
cursoragent Feb 15, 2026
65d96e7
Document expanded unicode-space baseURL coverage in release notes
cursoragent Feb 15, 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
5 changes: 5 additions & 0 deletions .changeset/chilled-cougars-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Document and guide AI users toward `@trigger.dev/ai` as the recommended package for AI SDK integrations, while keeping `@trigger.dev/sdk/ai` for backwards compatibility.
24 changes: 24 additions & 0 deletions .changeset/curly-radios-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
"@trigger.dev/ai": minor
---

Add a new `@trigger.dev/ai` package with:

- `ai.tool(...)` and `ai.currentToolOptions()` helpers for AI SDK tool calling ergonomics
- a typed `TriggerChatTransport` that plugs into AI SDK UI `useChat()` and runs chat backends as Trigger.dev tasks
- rich default task payloads (`chatId`, trigger metadata, messages, request context) with optional payload mapping
- reconnect-aware stream handling on top of Trigger.dev Realtime Streams v2
- strict `baseURL` normalization/validation (trimming, path-safe slash handling, absolute `http(s)` URLs only, no query/hash/credentials)
- rejection of internal whitespace characters in normalized `baseURL` values
- rejection of internal invisible separator characters (e.g. zero-width/BOM characters) in normalized `baseURL` values
- rejection of invisible separator wrappers around otherwise valid `baseURL` values (for example `\u200B...` and `\u2060...`)
- support for trimming additional unicode wrapper whitespace (`\u1680`, `\u3000`) while still rejecting
values that normalize to empty after trimming
- expanded unicode whitespace handling coverage to include figure space (`\u2007`) and medium
mathematical space (`\u205F`) for both wrapper trimming and internal-whitespace rejection
- expanded invisible-separator rejection coverage to include mongolian vowel separator (`\u180E`)
in both wrapper and internal `baseURL` positions
- expanded unicode spacing coverage to include hair space (`\u200A`), thin space (`\u2009`),
punctuation space (`\u2008`), six-per-em space (`\u2006`), and em space (`\u2003`)
- deterministic baseURL validation error ordering for multi-issue inputs (internal whitespace → protocol → query/hash → credentials)
- explicit default `baseURL` behavior (`https://api.trigger.dev`) and case-insensitive `HTTP(S)` protocol acceptance
9 changes: 6 additions & 3 deletions docs/tasks/schemaTask.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ await myTask.trigger({ name: "Alice", age: 30, dob: "2020-01-01" }); // this is

The `ai.tool` function allows you to create an AI tool from an existing `schemaTask` to use with the Vercel [AI SDK](https://vercel.com/docs/ai-sdk):

> `@trigger.dev/ai` is the recommended import path. For backwards compatibility,
> `@trigger.dev/sdk/ai` continues to work.

```ts
import { ai } from "@trigger.dev/sdk/ai";
import { ai } from "@trigger.dev/ai";
import { schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";
import { generateText } from "ai";
Expand Down Expand Up @@ -118,7 +121,7 @@ You can also pass the `experimental_toToolResultContent` option to the `ai.tool`
```ts
import { openai } from "@ai-sdk/openai";
import { Sandbox } from "@e2b/code-interpreter";
import { ai } from "@trigger.dev/sdk/ai";
import { ai } from "@trigger.dev/ai";
import { schemaTask } from "@trigger.dev/sdk";
import { generateObject } from "ai";
import { z } from "zod";
Expand Down Expand Up @@ -183,7 +186,7 @@ export const chartTool = ai.tool(chartTask, {
You can access the current tool execution options inside the task run function using the `ai.currentToolOptions()` function:

```ts
import { ai } from "@trigger.dev/sdk/ai";
import { ai } from "@trigger.dev/ai";
import { schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";

Expand Down
236 changes: 236 additions & 0 deletions docs/tasks/streams.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,242 @@ const { parts, error } = useRealtimeStream(streamDef, runId, {
});
```

## AI SDK `useChat` transport with Trigger.dev tasks

If you want to use AI SDK UI's `useChat()` on the frontend and run the backend as a Trigger.dev task,
use the `@trigger.dev/ai` transport.

### Install

```bash
npm add @trigger.dev/ai @ai-sdk/react ai
```

### Define a typed stream

```ts
// app/streams.ts
import { streams } from "@trigger.dev/sdk";
import { UIMessageChunk } from "ai";

export const aiStream = streams.define<UIMessageChunk>({
id: "ai",
});
```

### Create a task that accepts rich chat transport payload

```ts
// trigger/chat-task.ts
import { openai } from "@ai-sdk/openai";
import type { TriggerChatTransportPayload } from "@trigger.dev/ai";
import { task } from "@trigger.dev/sdk";
import { convertToModelMessages, streamText, UIMessage } from "ai";
import { aiStream } from "@/app/streams";

type ChatPayload = TriggerChatTransportPayload<UIMessage>;

export const aiChatTask = task({
id: "ai-chat",
run: async (payload: ChatPayload) => {
const result = streamText({
model: openai("gpt-4o"),
messages: convertToModelMessages(payload.messages),
});

const { waitUntilComplete } = aiStream.pipe(result.toUIMessageStream());
await waitUntilComplete();
},
});
```

### Use `useChat()` with Trigger chat transport

```tsx
"use client";

import { useChat } from "@ai-sdk/react";
import { TriggerChatTransport } from "@trigger.dev/ai";
import { aiStream } from "@/app/streams";

export function Chat({ triggerToken }: { triggerToken: string }) {
const chat = useChat({
transport: new TriggerChatTransport({
task: "ai-chat",
stream: aiStream,
accessToken: triggerToken,
timeoutInSeconds: 120,
}),
});

return (
<form
onSubmit={(event) => {
event.preventDefault();
chat.sendMessage({ text: "Hello!" });
}}
>
<button type="submit">Send</button>
</form>
);
}
```

The default payload sent to your task is a rich, typed object that includes:

- `chatId`
- `trigger` (`"submit-message"` or `"regenerate-message"`)
- `messageId`
- `messages`
- `request` (`headers`, `body`, and `metadata`)

### Advanced transport options

`TriggerChatTransport` also supports:

- `payloadMapper` (sync or async) for custom task payload shapes
- `triggerOptions` as an object or resolver function (sync or async)
- `runStore` for custom reconnect-state persistence (including async stores)
- `onTriggeredRun` callback (sync or async) to persist or observe run IDs
- `onError` callback to observe non-fatal transport issues
- headers passed through transport can be object, `Headers`, or tuple arrays

`onError` receives phase-aware details (`payloadMapper`, `triggerOptions`, `triggerTask`,
`streamSubscribe`, `onTriggeredRun`, `consumeTrackingStream`, `reconnect`) plus `chatId`,
optional `runId`, and the underlying `error` (non-Error throws are normalized to `Error`
instances).

Run-store cleanup is handled as best effort, and cleanup failures won't mask the original
transport failure that triggered `onError`. Cleanup still attempts both persistence steps
(`set` inactive state and `delete`) even when one step fails.

```ts
import type { TriggerChatRunState, TriggerChatRunStore } from "@trigger.dev/ai";

class MemoryRunStore implements TriggerChatRunStore {
private runs = new Map<string, TriggerChatRunState>();

async get(chatId: string) {
return this.runs.get(chatId);
}

async set(state: TriggerChatRunState) {
this.runs.set(state.chatId, state);
}

async delete(chatId: string) {
this.runs.delete(chatId);
}
}
```

`reconnectToStream()` only resumes active streams. When a stream completes or errors,
the transport clears stored run state and future reconnect attempts return `null`.
If stale inactive reconnect state cannot be cleaned up, reconnect still returns `null` and
the failure is surfaced through `onError` with phase `reconnect`.
Subsequent reconnect calls will retry stale inactive-state cleanup until it succeeds.
If `onError` is omitted, reconnect still returns `null` and continues without callback reporting.

`baseURL` defaults to `https://api.trigger.dev` when omitted.
It supports optional path prefixes and trailing slashes; both trigger and stream URLs
are normalized consistently, surrounding whitespace is trimmed before normalization, and
the resulting value must not be empty. The value must also be a valid absolute URL using
the `http` or `https` protocol, without query parameters, hash fragments, or embedded
username/password credentials.
Protocol matching is case-insensitive (`HTTP://...` and `HTTPS://...` are accepted).

Examples:

- ✅ `https://api.trigger.dev`
- ✅ `https://api.trigger.dev/custom-prefix`
- ✅ ` https://api.trigger.dev/custom-prefix/// ` (trimmed + normalized)
- ✅ `\n\thttps://api.trigger.dev/custom-prefix/\t\n` (newline/tab wrappers trimmed)
- ✅ `https://api.trigger.dev/custom%20prefix` (percent-encoded whitespace)
- ✅ `https://api.trigger.dev/custom%3Fprefix%23segment` (percent-encoded `?` / `#`)
- ✅ `\u00A0https://api.trigger.dev/custom-prefix/\u00A0` (non-breaking-space wrapper trimmed)
- ✅ `\u1680https://api.trigger.dev/custom-prefix/\u1680` (ogham-space-mark wrapper trimmed)
- ✅ `\u2007https://api.trigger.dev/custom-prefix/\u2007` (figure-space wrapper trimmed)
- ✅ `\u200Ahttps://api.trigger.dev/custom-prefix/\u200A` (hair-space wrapper trimmed)
- ✅ `\u2009https://api.trigger.dev/custom-prefix/\u2009` (thin-space wrapper trimmed)
- ✅ `\u2008https://api.trigger.dev/custom-prefix/\u2008` (punctuation-space wrapper trimmed)
- ✅ `\u2006https://api.trigger.dev/custom-prefix/\u2006` (six-per-em-space wrapper trimmed)
- ✅ `\u2003https://api.trigger.dev/custom-prefix/\u2003` (em-space wrapper trimmed)
- ✅ `\u205Fhttps://api.trigger.dev/custom-prefix/\u205F` (medium-mathematical-space wrapper trimmed)
- ✅ `\u3000https://api.trigger.dev/custom-prefix/\u3000` (ideographic-space wrapper trimmed)
- ✅ `\uFEFFhttps://api.trigger.dev/custom-prefix/\uFEFF` (BOM wrapper trimmed)
- ❌ `\u2060https://api.trigger.dev/custom-prefix/\u2060` (word-joiner wrappers are rejected)
- ❌ `\u200Bhttps://api.trigger.dev/custom-prefix/\u200B` (zero-width-space wrappers are rejected)
- ❌ `\u200Chttps://api.trigger.dev/custom-prefix/\u200C` (zero-width-non-joiner wrappers are rejected)
- ❌ `\u200Dhttps://api.trigger.dev/custom-prefix/\u200D` (zero-width-joiner wrappers are rejected)
- ❌ `\u180Ehttps://api.trigger.dev/custom-prefix/\u180E` (mongolian-vowel-separator wrappers are rejected)
- ❌ `https://api.trigger.dev?foo=bar`
- ❌ `https://api.trigger.dev#fragment`
- ❌ `https://user:pass@api.trigger.dev`
- ❌ `ftp://api.trigger.dev`
- ❌ `ws://api.trigger.dev` / `wss://api.trigger.dev`
- ❌ `\u1680///\u1680` (empty after trimming wrapper whitespace)
- ❌ `\u2007///\u2007` (empty after trimming wrapper whitespace)
- ❌ `\u205F///\u205F` (empty after trimming wrapper whitespace)
- ❌ `\u180E///\u180E` (rejected as internal invisible-separator whitespace)
- ❌ `\u3000///\u3000` (empty after trimming wrapper whitespace)
- ❌ `\n\thttps://api.trigger.dev/base/?query=1\t\n` (query is still rejected after trimming wrappers)
- ❌ `\n\thttps://api.trigger.dev/base/#fragment\t\n` (hash is still rejected after trimming wrappers)
- ❌ `\n\thttps://user:pass@api.trigger.dev/base/\t\n` (credentials are still rejected after trimming wrappers)
- ❌ `\n\tws://api.trigger.dev\t\n` / `\n\twss://api.trigger.dev\t\n` (trimmed wrappers still reject websocket protocols)
- ❌ `https://api.trigger.dev/\ninternal`
- ❌ `https://api.trigger.dev/in valid`
- ❌ `https://api.trigger.dev/\tinternal`
- ❌ `https://api.trigger.dev/\vinternal`
- ❌ `https://api.trigger.dev/\finternal`
- ❌ `https://api.trigger.dev/\rinternal`
- ❌ `https://api.trigger.dev/\u200Binternal`
- ❌ `https://api.trigger.dev/\u200Cinternal`
- ❌ `https://api.trigger.dev/\u200Dinternal`
- ❌ `https://api.trigger.dev/\u1680internal`
- ❌ `https://api.trigger.dev/\u2007internal`
- ❌ `https://api.trigger.dev/\u200Ainternal`
- ❌ `https://api.trigger.dev/\u2009internal`
- ❌ `https://api.trigger.dev/\u2008internal`
- ❌ `https://api.trigger.dev/\u2006internal`
- ❌ `https://api.trigger.dev/\u2003internal`
- ❌ `https://api.trigger.dev/\u202Finternal`
- ❌ `https://api.trigger.dev/\u205Finternal`
- ❌ `https://api.trigger.dev/\u180Einternal`
- ❌ `https://api.trigger.dev/\u3000internal`
- ❌ `https://api.trigger.dev/\u2028internal`
- ❌ `https://api.trigger.dev/\u2029internal`
- ❌ `https://api.trigger.dev/\u2060internal`
- ❌ `https://api.trigger.dev/\uFEFFinternal`

Validation errors use these exact messages:

- `baseURL must not be empty`
- `baseURL must be a valid absolute URL`
- `baseURL must not contain internal whitespace characters`
- `baseURL must use http or https protocol`
- `baseURL must not include query parameters or hash fragments`
- `baseURL must not include username or password credentials`

The internal-whitespace error also applies to invisible separator characters
like `\u200B`, `\u200C`, `\u200D`, `\u2060`, and `\uFEFF`.

When multiple issues are present, validation order is deterministic:
internal whitespace → protocol → query/hash → credentials.

Examples of ordering:

- `ftp://example.com?x=1` → `baseURL must use http or https protocol`
- `https://user:pass@example.com?x=1` → `baseURL must not include query parameters or hash fragments`
- `ftp://user:pass@example.com/in valid?x=1` → `baseURL must not contain internal whitespace characters`
- `ftp://user:pass@example.com/\u2060invalid?x=1#fragment` → `baseURL must not contain internal whitespace characters`
- `ftp://user:pass@example.com/\u180Einvalid?x=1#fragment` → `baseURL must not contain internal whitespace characters`

For richer TypeScript ergonomics in app code, `@trigger.dev/ai` also exports:

- `TriggerChatHeadersInput`
- `TriggerChatSendMessagesOptions`
- `TriggerChatReconnectOptions`

## Complete Example: AI Streaming

### Define the stream
Expand Down
43 changes: 43 additions & 0 deletions packages/ai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# @trigger.dev/ai

## 4.3.3

### Added

- Introduced a new `@trigger.dev/ai` package.
- Added `ai.tool(...)` and `ai.currentToolOptions()` helpers for AI SDK tool ergonomics.
- Added `TriggerChatTransport` / `createTriggerChatTransport(...)` for AI SDK `useChat()` integrations powered by Trigger.dev tasks and Realtime Streams v2.
- Added rich default chat payload typing (`chatId`, `trigger`, `messageId`, `messages`, request context) and mapper hooks for custom payloads.
- Added support for async payload mappers, async trigger option resolvers, and async `onTriggeredRun` callbacks.
- Added support for tuple-style header input normalization and typing.
- Added reconnect lifecycle handling that cleans run state after completion/error and gracefully returns `null` when reconnect cannot be resumed.
- Added explicit helper option types for chat send/reconnect request inputs.
- Added optional `onError` callback support for observing non-fatal transport issues.
- Added phase-aware `onError` reporting across send, stream-subscribe, reconnect, and stream-consumption paths.
- Added normalization of non-Error throw values into Error instances before `onError` reporting.
- Added best-effort run-store cleanup so cleanup failures do not mask root transport errors.
- Improved best-effort run-store cleanup to attempt both inactive-state writes and deletes even if one step fails.
- Added reconnect cleanup error reporting for stale inactive state while still returning `null`.
- Added retry semantics for stale inactive reconnect cleanup on subsequent reconnect attempts.
- Added consistent baseURL normalization for trigger and stream endpoints (including path prefixes and trailing slashes).
- Added surrounding-whitespace trimming for `baseURL` before endpoint normalization.
- Added explicit validation that `baseURL` is non-empty after normalization.
- Added explicit validation that `baseURL` is a valid absolute URL.
- Added explicit validation that `baseURL` uses `http` or `https`.
- Added explicit validation that `baseURL` excludes query parameters and hash fragments.
- Added explicit validation that `baseURL` excludes username/password credentials.
- Added explicit validation that `baseURL` excludes internal whitespace/invisible separator characters (including zero-width/BOM characters).
- Clarified that invisible separator characters are rejected even when wrapped around an otherwise valid `baseURL`.
- Added explicit test/docs coverage for additional unicode-trimmable wrappers (`\u1680`, `\u3000`) and
confirmed empty-after-trim values still throw `baseURL must not be empty`.
- Expanded unicode whitespace coverage with `\u2007` (figure space) and `\u205F` (medium mathematical space)
across internal-whitespace rejection, wrapper trimming acceptance, and empty-after-trim validation.
- Expanded invisible-separator coverage to reject `\u180E` (mongolian vowel separator) in both
internal and wrapper `baseURL` positions.
- Expanded unicode space coverage to include `\u200A` (hair space), `\u2009` (thin space),
`\u2008` (punctuation space), `\u2006` (six-per-em space), and `\u2003` (em space)
across wrapper-trimming acceptance and internal-whitespace rejection scenarios.
- Documented that `HTTP://` and `HTTPS://` are accepted (case-insensitive protocol matching).
- Added deterministic validation ordering for multi-issue baseURL values
(internal whitespace → protocol → query/hash → credentials).
- Documented explicit default `baseURL` value (`https://api.trigger.dev`) when omitted.
Loading