@trigger.dev/sdk 4.5.1 → 4.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/v3/ai-shared.d.ts +3 -127
- package/dist/commonjs/v3/ai-shared.js.map +1 -1
- package/dist/commonjs/v3/ai.js +66 -22
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat-react.d.ts +1 -0
- package/dist/commonjs/v3/chat-react.js +4 -1
- package/dist/commonjs/v3/chat-react.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +204 -1
- package/dist/commonjs/v3/chat.js +203 -19
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/index.d.ts +1 -1
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/runs-bulk.test.d.ts +1 -0
- package/dist/commonjs/v3/runs-bulk.test.js +141 -0
- package/dist/commonjs/v3/runs-bulk.test.js.map +1 -0
- package/dist/commonjs/v3/runs.d.ts +23 -6
- package/dist/commonjs/v3/runs.js +87 -0
- package/dist/commonjs/v3/runs.js.map +1 -1
- package/dist/commonjs/v3/sessions.js +5 -2
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/shared.d.ts +2 -2
- package/dist/commonjs/v3/shared.js +79 -4
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/shared.test.js +37 -0
- package/dist/commonjs/v3/shared.test.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai-shared.d.ts +3 -127
- package/dist/esm/v3/ai-shared.js.map +1 -1
- package/dist/esm/v3/ai.js +66 -22
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat-react.d.ts +1 -0
- package/dist/esm/v3/chat-react.js +4 -1
- package/dist/esm/v3/chat-react.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +204 -1
- package/dist/esm/v3/chat.js +204 -20
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/index.d.ts +1 -1
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/runs-bulk.test.d.ts +1 -0
- package/dist/esm/v3/runs-bulk.test.js +139 -0
- package/dist/esm/v3/runs-bulk.test.js.map +1 -0
- package/dist/esm/v3/runs.d.ts +18 -1
- package/dist/esm/v3/runs.js +87 -0
- package/dist/esm/v3/runs.js.map +1 -1
- package/dist/esm/v3/sessions.js +5 -2
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/shared.d.ts +2 -2
- package/dist/esm/v3/shared.js +79 -5
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/shared.test.js +38 -1
- package/dist/esm/v3/shared.test.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/frontend.mdx +46 -0
- package/docs/ai-chat/pending-messages.mdx +3 -1
- package/docs/ai-chat/reference.mdx +20 -0
- package/docs/billing-limits.mdx +73 -0
- package/docs/github-repo.mdx +1 -1
- package/docs/how-to-reduce-your-spend.mdx +1 -14
- package/docs/limits.mdx +5 -0
- package/docs/quick-start.mdx +1 -1
- package/docs/self-hosting/docker.mdx +24 -1
- package/docs/self-hosting/env/webapp.mdx +6 -1
- package/docs/self-hosting/kubernetes.mdx +26 -0
- package/docs/self-hosting/overview.mdx +4 -1
- package/docs/self-hosting/security.mdx +50 -0
- package/docs/troubleshooting.mdx +4 -0
- package/package.json +2 -2
- package/docs/open-source-self-hosting.mdx +0 -541
|
@@ -15,6 +15,7 @@ export type UseTriggerChatTransportOptions<TTask extends AnyTask = AnyTask> = Om
|
|
|
15
15
|
task: TaskIdentifier<TTask>;
|
|
16
16
|
};
|
|
17
17
|
export type { InferChatUIMessage };
|
|
18
|
+
export type { ChatTransportEvent, ChatTransportSendSource } from "./chat.js";
|
|
18
19
|
/**
|
|
19
20
|
* React hook that creates and memoizes a `TriggerChatTransport` instance.
|
|
20
21
|
*
|
|
@@ -65,10 +65,13 @@ function useTriggerChatTransport(options) {
|
|
|
65
65
|
ref.current = new chat_js_1.TriggerChatTransport(options);
|
|
66
66
|
}
|
|
67
67
|
// Keep callbacks up to date without recreating the transport.
|
|
68
|
-
const { onSessionChange, clientData } = options;
|
|
68
|
+
const { onSessionChange, clientData, onEvent } = options;
|
|
69
69
|
(0, react_1.useEffect)(() => {
|
|
70
70
|
ref.current?.setOnSessionChange(onSessionChange);
|
|
71
71
|
}, [onSessionChange]);
|
|
72
|
+
(0, react_1.useEffect)(() => {
|
|
73
|
+
ref.current?.setOnEvent(onEvent);
|
|
74
|
+
}, [onEvent]);
|
|
72
75
|
// Keep `clientData` up to date so the transport's per-turn merge and
|
|
73
76
|
// `startSession` callback both see the latest value without
|
|
74
77
|
// reconstructing the transport.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-react.js","sourceRoot":"","sources":["../../../src/v3/chat-react.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;
|
|
1
|
+
{"version":3,"file":"chat-react.js","sourceRoot":"","sources":["../../../src/v3/chat-react.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,110 @@
|
|
|
22
22
|
* }
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
import type { ChatTransport, UIMessage, UIMessageChunk, ChatRequestOptions } from "ai";
|
|
25
|
+
import type { ChatTransport, ModelMessage, UIMessage, UIMessageChunk, ChatRequestOptions } from "ai";
|
|
26
|
+
/**
|
|
27
|
+
* The wire payload shape sent by `TriggerChatTransport`.
|
|
28
|
+
* Uses `metadata` to match the AI SDK's `ChatRequestOptions` field name.
|
|
29
|
+
*
|
|
30
|
+
* Slim wire: at most ONE message per record. The agent runtime
|
|
31
|
+
* reconstructs prior history at run boot from a durable S3 snapshot +
|
|
32
|
+
* `session.out` replay (or `hydrateMessages` if registered).
|
|
33
|
+
*
|
|
34
|
+
* Declared here (rather than the internal shared module) so `declaration:
|
|
35
|
+
* true` consumers can name inferred agent types via this public subpath.
|
|
36
|
+
*/
|
|
37
|
+
export type ChatTaskWirePayload<TMessage extends UIMessage = UIMessage, TMetadata = unknown> = {
|
|
38
|
+
/**
|
|
39
|
+
* The single message being delivered on this trigger. Set for:
|
|
40
|
+
* - `submit-message`: the new user message OR a tool-approval-responded
|
|
41
|
+
* assistant message (with `state: "approval-responded"` tool parts).
|
|
42
|
+
* - `regenerate-message`: omitted (the agent slices its own history).
|
|
43
|
+
* - `preload` / `close` / `action`: omitted.
|
|
44
|
+
* - `handover-prepare`: omitted (use `headStartMessages` instead).
|
|
45
|
+
*/
|
|
46
|
+
message?: TMessage;
|
|
47
|
+
/**
|
|
48
|
+
* Bespoke escape hatch for `chat.headStart`. The customer's HTTP route
|
|
49
|
+
* handler ships full `UIMessage[]` history at the very first turn — before
|
|
50
|
+
* any snapshot exists. The route handler isn't subject to the
|
|
51
|
+
* `MAX_APPEND_BODY_BYTES` cap on `/in/append` because it goes through the
|
|
52
|
+
* customer's own HTTP endpoint. Used ONLY by `trigger: "handover-prepare"`.
|
|
53
|
+
* Ignored on every other trigger.
|
|
54
|
+
*/
|
|
55
|
+
headStartMessages?: TMessage[];
|
|
56
|
+
chatId: string;
|
|
57
|
+
trigger: "submit-message" | "regenerate-message" | "preload" | "close" | "action"
|
|
58
|
+
/**
|
|
59
|
+
* The customer's `chat.handover` route handler kicked us off in
|
|
60
|
+
* parallel with the first-turn `streamText` running in the warm
|
|
61
|
+
* Next.js process. The run sits idle on `session.in` waiting for
|
|
62
|
+
* a `kind: "handover"` (continue from tool execution) or
|
|
63
|
+
* `kind: "handover-skip"` (handler finished pure-text, exit
|
|
64
|
+
* cleanly). See `chat.handover` in `@trigger.dev/sdk/chat-server`.
|
|
65
|
+
*/
|
|
66
|
+
| "handover-prepare";
|
|
67
|
+
messageId?: string;
|
|
68
|
+
metadata?: TMetadata;
|
|
69
|
+
/** Custom action payload when `trigger` is `"action"`. Validated against `actionSchema` on the backend. */
|
|
70
|
+
action?: unknown;
|
|
71
|
+
/** Whether this run is continuing an existing chat whose previous run ended. */
|
|
72
|
+
continuation?: boolean;
|
|
73
|
+
/** The run ID of the previous run (only set when `continuation` is true). */
|
|
74
|
+
previousRunId?: string;
|
|
75
|
+
/** Override idle timeout for this run (seconds). Set by transport.preload(). */
|
|
76
|
+
idleTimeoutInSeconds?: number;
|
|
77
|
+
/**
|
|
78
|
+
* The friendlyId of the Session primitive backing this chat. The
|
|
79
|
+
* transport opens (or lazy-creates) the session with
|
|
80
|
+
* `externalId = chatId` on first message, then sends this friendlyId
|
|
81
|
+
* through to the run so the agent can attach to `.in` / `.out`
|
|
82
|
+
* without needing to round-trip through the control plane again.
|
|
83
|
+
* Optional for backward-compat while the migration is in flight;
|
|
84
|
+
* required once the legacy run-scoped stream path is removed.
|
|
85
|
+
*/
|
|
86
|
+
sessionId?: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* One chunk on the chat input stream. `kind` discriminates the variants —
|
|
90
|
+
* a single ordered stream carries all the signals (`message`, `stop`,
|
|
91
|
+
* `handover`, `handover-skip`).
|
|
92
|
+
*/
|
|
93
|
+
export type ChatInputChunk<TMessage extends UIMessage = UIMessage, TMetadata = unknown> = {
|
|
94
|
+
kind: "message";
|
|
95
|
+
/** Full wire payload for a new user message or regeneration. */
|
|
96
|
+
payload: ChatTaskWirePayload<TMessage, TMetadata>;
|
|
97
|
+
} | {
|
|
98
|
+
kind: "stop";
|
|
99
|
+
/** Optional human-readable reason. */
|
|
100
|
+
message?: string;
|
|
101
|
+
} | {
|
|
102
|
+
/**
|
|
103
|
+
* Sent by `chat.headStart` when the customer's first-turn
|
|
104
|
+
* `streamText` finishes. The agent run (parked in
|
|
105
|
+
* `handover-prepare`) wakes, seeds its accumulators with
|
|
106
|
+
* `partialAssistantMessage`, and runs the normal turn loop.
|
|
107
|
+
* `isFinal: false` means step 1 ended in tool-calls (the agent
|
|
108
|
+
* executes them and continues); `isFinal: true` means step 1 was
|
|
109
|
+
* the complete response (the agent skips the LLM call).
|
|
110
|
+
*/
|
|
111
|
+
kind: "handover";
|
|
112
|
+
/** Customer's step-1 response messages (ModelMessage form). */
|
|
113
|
+
partialAssistantMessage: ModelMessage[];
|
|
114
|
+
/**
|
|
115
|
+
* The UI messageId the customer's handler used for its step-1
|
|
116
|
+
* assistant message, reused so post-handover chunks merge into
|
|
117
|
+
* the SAME assistant message on the browser side.
|
|
118
|
+
*/
|
|
119
|
+
messageId?: string;
|
|
120
|
+
isFinal: boolean;
|
|
121
|
+
} | {
|
|
122
|
+
/**
|
|
123
|
+
* Sent by `chat.headStart` only when the customer's handler
|
|
124
|
+
* ABORTS before producing a finishReason. The agent run exits
|
|
125
|
+
* cleanly without firing turn hooks.
|
|
126
|
+
*/
|
|
127
|
+
kind: "handover-skip";
|
|
128
|
+
};
|
|
26
129
|
/**
|
|
27
130
|
* Discriminator passed to per-endpoint `baseURL` and `fetch` callbacks.
|
|
28
131
|
*
|
|
@@ -52,6 +155,81 @@ export type ChatBaseURLResolver = (ctx: ChatTransportEndpointContext) => string;
|
|
|
52
155
|
* what `globalThis.fetch(url, init)` would have returned.
|
|
53
156
|
*/
|
|
54
157
|
export type ChatFetchOverride = (url: string, init: RequestInit, ctx: ChatTransportEndpointContext) => Promise<Response>;
|
|
158
|
+
/**
|
|
159
|
+
* Which transport path produced a send-lifecycle event: `useChat` sends,
|
|
160
|
+
* steering (`sendPendingMessage`), actions, stops, or the first-turn
|
|
161
|
+
* `headStart` POST.
|
|
162
|
+
*/
|
|
163
|
+
export type ChatTransportSendSource = "submit-message" | "regenerate-message" | "steer" | "action" | "stop" | "head-start";
|
|
164
|
+
/**
|
|
165
|
+
* Lifecycle events emitted through the transport's `onEvent` callback.
|
|
166
|
+
*
|
|
167
|
+
* Send events are terminal: `message-sent` fires when the append is
|
|
168
|
+
* durably acknowledged (2xx from the session input stream, after any
|
|
169
|
+
* internal token-refresh retries), `message-send-failed` when the send
|
|
170
|
+
* definitively failed. Response events follow the output stream:
|
|
171
|
+
* `stream-connected` when the SSE subscription opens, `first-chunk` on
|
|
172
|
+
* the first response chunk of a turn, `turn-completed` when the agent's
|
|
173
|
+
* turn-complete control record arrives, and `stream-error` when the
|
|
174
|
+
* stream fails unrecoverably.
|
|
175
|
+
*/
|
|
176
|
+
export type ChatTransportEvent = {
|
|
177
|
+
type: "message-sent";
|
|
178
|
+
chatId: string;
|
|
179
|
+
timestamp: number;
|
|
180
|
+
messageId?: string;
|
|
181
|
+
source: ChatTransportSendSource;
|
|
182
|
+
durationMs: number;
|
|
183
|
+
/** The append's idempotency key — also stored on the server-side record. */
|
|
184
|
+
partId?: string;
|
|
185
|
+
/** Serialized request body size in bytes. */
|
|
186
|
+
bodyBytes?: number;
|
|
187
|
+
} | {
|
|
188
|
+
type: "message-send-failed";
|
|
189
|
+
chatId: string;
|
|
190
|
+
timestamp: number;
|
|
191
|
+
messageId?: string;
|
|
192
|
+
source: ChatTransportSendSource;
|
|
193
|
+
error: Error;
|
|
194
|
+
status?: number;
|
|
195
|
+
durationMs: number;
|
|
196
|
+
partId?: string;
|
|
197
|
+
bodyBytes?: number;
|
|
198
|
+
} | {
|
|
199
|
+
type: "stream-connected";
|
|
200
|
+
chatId: string;
|
|
201
|
+
timestamp: number;
|
|
202
|
+
resumed: boolean;
|
|
203
|
+
/** The resume cursor the subscription connected from, if any. */
|
|
204
|
+
lastEventId?: string;
|
|
205
|
+
/** The last turn-producing send on this chat (client-side attribution). */
|
|
206
|
+
messageId?: string;
|
|
207
|
+
} | {
|
|
208
|
+
type: "stream-error";
|
|
209
|
+
chatId: string;
|
|
210
|
+
timestamp: number;
|
|
211
|
+
error: Error;
|
|
212
|
+
status?: number;
|
|
213
|
+
} | {
|
|
214
|
+
type: "first-chunk";
|
|
215
|
+
chatId: string;
|
|
216
|
+
timestamp: number;
|
|
217
|
+
chunkType?: string;
|
|
218
|
+
lastEventId?: string;
|
|
219
|
+
messageId?: string;
|
|
220
|
+
/** Milliseconds since the last turn-producing send on this chat (time to first token). */
|
|
221
|
+
sinceSendMs?: number;
|
|
222
|
+
} | {
|
|
223
|
+
type: "turn-completed";
|
|
224
|
+
chatId: string;
|
|
225
|
+
timestamp: number;
|
|
226
|
+
lastEventId?: string;
|
|
227
|
+
/** The agent's committed input-stream cursor from the turn-complete record. */
|
|
228
|
+
sessionInEventId?: string;
|
|
229
|
+
messageId?: string;
|
|
230
|
+
/** Milliseconds since the last turn-producing send on this chat (full turn latency). */
|
|
231
|
+
sinceSendMs?: number;
|
|
232
|
+
};
|
|
55
233
|
/**
|
|
56
234
|
* Arguments for the `accessToken` callback. The transport invokes this
|
|
57
235
|
* whenever it needs a fresh session-scoped PAT — initial use, and
|
|
@@ -204,6 +382,22 @@ export type TriggerChatTransportOptions<TClientData = unknown> = {
|
|
|
204
382
|
* ```
|
|
205
383
|
*/
|
|
206
384
|
fetch?: ChatFetchOverride;
|
|
385
|
+
/**
|
|
386
|
+
* Observability callback for transport lifecycle events (sends,
|
|
387
|
+
* stream connects, first chunk, turn completion). See
|
|
388
|
+
* {@link ChatTransportEvent} for the event catalog and semantics.
|
|
389
|
+
* Exceptions thrown by the callback are swallowed.
|
|
390
|
+
*
|
|
391
|
+
* @example Record send metrics:
|
|
392
|
+
* ```ts
|
|
393
|
+
* onEvent: (event) => {
|
|
394
|
+
* if (event.type === "message-sent") {
|
|
395
|
+
* metrics.timing("chat.send", event.durationMs);
|
|
396
|
+
* }
|
|
397
|
+
* },
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
onEvent?: (event: ChatTransportEvent) => void;
|
|
207
401
|
/** Additional headers included in every API request. */
|
|
208
402
|
headers?: Record<string, string>;
|
|
209
403
|
/**
|
|
@@ -305,9 +499,11 @@ export declare class TriggerChatTransport implements ChatTransport<UIMessage> {
|
|
|
305
499
|
private readonly headStart;
|
|
306
500
|
private coordinator;
|
|
307
501
|
private _onSessionChange;
|
|
502
|
+
private _onEvent;
|
|
308
503
|
private sessions;
|
|
309
504
|
private activeStreams;
|
|
310
505
|
private pendingStarts;
|
|
506
|
+
private lastTurnSends;
|
|
311
507
|
constructor(options: TriggerChatTransportOptions);
|
|
312
508
|
/**
|
|
313
509
|
* Eagerly create a Session and trigger its first run. Useful as a
|
|
@@ -382,6 +578,13 @@ export declare class TriggerChatTransport implements ChatTransport<UIMessage> {
|
|
|
382
578
|
getSession: (chatId: string) => ChatSessionPersistedState | undefined;
|
|
383
579
|
setSession(chatId: string, session: ChatSessionPersistedState): void;
|
|
384
580
|
setOnSessionChange(callback: ((chatId: string, session: ChatSessionPersistedState | null) => void) | undefined): void;
|
|
581
|
+
/** Update the `onEvent` callback without recreating the transport. */
|
|
582
|
+
setOnEvent(callback: ((event: ChatTransportEvent) => void) | undefined): void;
|
|
583
|
+
private emitEvent;
|
|
584
|
+
/** Run a send op, emitting the terminal message-sent / message-send-failed event. */
|
|
585
|
+
private sendWithEvents;
|
|
586
|
+
/** Attribution fields for response-side events. */
|
|
587
|
+
private turnAttribution;
|
|
385
588
|
/**
|
|
386
589
|
* Update the transport's `clientData`. Used by `useTriggerChatTransport`
|
|
387
590
|
* to keep the latest value reachable from inside `startSession` and
|
package/dist/commonjs/v3/chat.js
CHANGED
|
@@ -27,6 +27,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
27
27
|
exports.ChatStream = exports.AgentChat = exports.TriggerChatTransport = void 0;
|
|
28
28
|
exports.createChatTransport = createChatTransport;
|
|
29
29
|
const v3_1 = require("@trigger.dev/core/v3");
|
|
30
|
+
function byteLength(body) {
|
|
31
|
+
return new TextEncoder().encode(body).byteLength;
|
|
32
|
+
}
|
|
30
33
|
const chat_tab_coordinator_js_1 = require("./chat-tab-coordinator.js");
|
|
31
34
|
const ai_shared_js_1 = require("./ai-shared.js");
|
|
32
35
|
const DEFAULT_BASE_URL = "https://api.trigger.dev";
|
|
@@ -144,9 +147,13 @@ class TriggerChatTransport {
|
|
|
144
147
|
headStart;
|
|
145
148
|
coordinator = null;
|
|
146
149
|
_onSessionChange;
|
|
150
|
+
_onEvent;
|
|
147
151
|
sessions = new Map();
|
|
148
152
|
activeStreams = new Map();
|
|
149
153
|
pendingStarts = new Map();
|
|
154
|
+
// Last turn-producing send per chat — attribution source for the
|
|
155
|
+
// response-side events' `messageId` / `sinceSendMs`.
|
|
156
|
+
lastTurnSends = new Map();
|
|
150
157
|
constructor(options) {
|
|
151
158
|
this.taskId = options.task;
|
|
152
159
|
this.resolveAccessToken = options.accessToken;
|
|
@@ -162,6 +169,7 @@ class TriggerChatTransport {
|
|
|
162
169
|
this.streamTimeoutSeconds = options.streamTimeoutSeconds ?? DEFAULT_STREAM_TIMEOUT_SECONDS;
|
|
163
170
|
this.defaultMetadata = options.clientData;
|
|
164
171
|
this._onSessionChange = options.onSessionChange;
|
|
172
|
+
this._onEvent = options.onEvent;
|
|
165
173
|
this.watchMode = options.watch ?? false;
|
|
166
174
|
this.headStart = options.headStart;
|
|
167
175
|
if (options.multiTab && !this.watchMode) {
|
|
@@ -286,10 +294,15 @@ class TriggerChatTransport {
|
|
|
286
294
|
// Generated outside the closure so auth-retries reuse the same part id
|
|
287
295
|
// and the server-side dedupe sees one logical append.
|
|
288
296
|
const partId = crypto.randomUUID();
|
|
297
|
+
const serializedBody = this.serializeInputChunk({ kind: "message", payload: wirePayload });
|
|
289
298
|
const sendChatMessage = async (token) => {
|
|
290
|
-
await this.appendInputChunk(chatId, token,
|
|
299
|
+
await this.appendInputChunk(chatId, token, serializedBody, partId);
|
|
291
300
|
};
|
|
292
|
-
await this.
|
|
301
|
+
await this.sendWithEvents(chatId, trigger, {
|
|
302
|
+
messageId: messageId ?? messages.at(-1)?.id,
|
|
303
|
+
partId,
|
|
304
|
+
bodyBytes: byteLength(serializedBody),
|
|
305
|
+
}, () => this.callWithAuthRetry(chatId, state, sendChatMessage));
|
|
293
306
|
// Cancel any in-flight stream for this chat — the new turn supersedes it.
|
|
294
307
|
const activeStream = this.activeStreams.get(chatId);
|
|
295
308
|
if (activeStream) {
|
|
@@ -324,18 +337,27 @@ class TriggerChatTransport {
|
|
|
324
337
|
messageId: args.messageId,
|
|
325
338
|
metadata: args.metadata,
|
|
326
339
|
};
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
340
|
+
let response;
|
|
341
|
+
const serializedBody = JSON.stringify(wirePayload);
|
|
342
|
+
await this.sendWithEvents(args.chatId, "head-start", {
|
|
343
|
+
messageId: args.messageId ?? args.messages.at(-1)?.id,
|
|
344
|
+
bodyBytes: byteLength(serializedBody),
|
|
345
|
+
}, async () => {
|
|
346
|
+
response = await fetch(this.headStart, {
|
|
347
|
+
method: "POST",
|
|
348
|
+
headers: {
|
|
349
|
+
"Content-Type": "application/json",
|
|
350
|
+
...this.extraHeaders,
|
|
351
|
+
},
|
|
352
|
+
body: serializedBody,
|
|
353
|
+
signal: args.abortSignal,
|
|
354
|
+
});
|
|
355
|
+
if (!response.ok) {
|
|
356
|
+
const err = new Error(`chat.handover endpoint returned ${response.status} ${response.statusText}`);
|
|
357
|
+
err.status = response.status;
|
|
358
|
+
throw err;
|
|
359
|
+
}
|
|
335
360
|
});
|
|
336
|
-
if (!response.ok) {
|
|
337
|
-
throw new Error(`chat.handover endpoint returned ${response.status} ${response.statusText}`);
|
|
338
|
-
}
|
|
339
361
|
if (!response.body) {
|
|
340
362
|
throw new Error("chat.handover endpoint returned no response body");
|
|
341
363
|
}
|
|
@@ -389,7 +411,17 @@ class TriggerChatTransport {
|
|
|
389
411
|
notifyChange(chatId, state);
|
|
390
412
|
}
|
|
391
413
|
};
|
|
392
|
-
|
|
414
|
+
const emit = (event) => this.emitEvent(event);
|
|
415
|
+
const attribution = () => this.turnAttribution(chatId);
|
|
416
|
+
let sawFirstChunk = false;
|
|
417
|
+
emit({
|
|
418
|
+
type: "stream-connected",
|
|
419
|
+
chatId,
|
|
420
|
+
timestamp: Date.now(),
|
|
421
|
+
resumed: false,
|
|
422
|
+
messageId: this.lastTurnSends.get(chatId)?.messageId,
|
|
423
|
+
});
|
|
424
|
+
const piped = response.body
|
|
393
425
|
.pipeThrough(new TextDecoderStream())
|
|
394
426
|
.pipeThrough(parseUIMessageSseTransform())
|
|
395
427
|
.pipeThrough(new TransformStream({
|
|
@@ -398,6 +430,13 @@ class TriggerChatTransport {
|
|
|
398
430
|
const type = chunk.type;
|
|
399
431
|
if (type === TRIGGER_TURN_COMPLETE) {
|
|
400
432
|
clearStreaming();
|
|
433
|
+
emit({
|
|
434
|
+
type: "turn-completed",
|
|
435
|
+
chatId,
|
|
436
|
+
timestamp: Date.now(),
|
|
437
|
+
lastEventId: sessions.get(chatId)?.lastEventId,
|
|
438
|
+
...attribution(),
|
|
439
|
+
});
|
|
401
440
|
return; // drop — not a real UIMessageChunk
|
|
402
441
|
}
|
|
403
442
|
if (type === TRIGGER_SESSION_STATE) {
|
|
@@ -408,12 +447,61 @@ class TriggerChatTransport {
|
|
|
408
447
|
return; // drop
|
|
409
448
|
}
|
|
410
449
|
}
|
|
450
|
+
if (!sawFirstChunk) {
|
|
451
|
+
sawFirstChunk = true;
|
|
452
|
+
emit({
|
|
453
|
+
type: "first-chunk",
|
|
454
|
+
chatId,
|
|
455
|
+
timestamp: Date.now(),
|
|
456
|
+
chunkType: chunk?.type,
|
|
457
|
+
...attribution(),
|
|
458
|
+
});
|
|
459
|
+
}
|
|
411
460
|
controller.enqueue(chunk);
|
|
412
461
|
},
|
|
413
462
|
flush() {
|
|
414
463
|
clearStreaming();
|
|
415
464
|
},
|
|
416
465
|
}));
|
|
466
|
+
// Pump wrapper: a TransformStream can't observe upstream errors, so
|
|
467
|
+
// read here to emit stream-error (aborts close cleanly, matching the
|
|
468
|
+
// session subscribe path).
|
|
469
|
+
const pipedReader = piped.getReader();
|
|
470
|
+
return new ReadableStream({
|
|
471
|
+
async pull(controller) {
|
|
472
|
+
try {
|
|
473
|
+
const next = await pipedReader.read();
|
|
474
|
+
if (next.done) {
|
|
475
|
+
controller.close();
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
controller.enqueue(next.value);
|
|
479
|
+
}
|
|
480
|
+
catch (error) {
|
|
481
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
482
|
+
try {
|
|
483
|
+
controller.close();
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
/* already closed */
|
|
487
|
+
}
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
const errorStatus = error.status;
|
|
491
|
+
emit({
|
|
492
|
+
type: "stream-error",
|
|
493
|
+
chatId,
|
|
494
|
+
timestamp: Date.now(),
|
|
495
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
496
|
+
status: typeof errorStatus === "number" ? errorStatus : undefined,
|
|
497
|
+
});
|
|
498
|
+
controller.error(error);
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
cancel(reason) {
|
|
502
|
+
return pipedReader.cancel(reason);
|
|
503
|
+
},
|
|
504
|
+
});
|
|
417
505
|
}
|
|
418
506
|
/**
|
|
419
507
|
* Send a steering message during an active stream without disrupting
|
|
@@ -434,11 +522,12 @@ class TriggerChatTransport {
|
|
|
434
522
|
metadata: mergedMetadata,
|
|
435
523
|
};
|
|
436
524
|
const partId = crypto.randomUUID();
|
|
525
|
+
const serializedBody = this.serializeInputChunk({ kind: "message", payload: wirePayload });
|
|
437
526
|
const send = async (token) => {
|
|
438
|
-
await this.appendInputChunk(chatId, token,
|
|
527
|
+
await this.appendInputChunk(chatId, token, serializedBody, partId);
|
|
439
528
|
};
|
|
440
529
|
try {
|
|
441
|
-
await this.callWithAuthRetry(chatId, state, send);
|
|
530
|
+
await this.sendWithEvents(chatId, "steer", { messageId: message.id, partId, bodyBytes: byteLength(serializedBody) }, () => this.callWithAuthRetry(chatId, state, send));
|
|
442
531
|
return true;
|
|
443
532
|
}
|
|
444
533
|
catch {
|
|
@@ -464,6 +553,7 @@ class TriggerChatTransport {
|
|
|
464
553
|
? AbortSignal.any([options.abortSignal, abortController.signal])
|
|
465
554
|
: abortController.signal;
|
|
466
555
|
return this.subscribeToSessionStream(state, abortSignal, options.chatId, {
|
|
556
|
+
resumed: true,
|
|
467
557
|
sendStopOnAbort: !!options.abortSignal,
|
|
468
558
|
// Reconnect-on-reload opts into the server's settled-peek shortcut
|
|
469
559
|
// so the SSE doesn't hang for 60s when no turn is in flight. Active
|
|
@@ -482,11 +572,12 @@ class TriggerChatTransport {
|
|
|
482
572
|
if (!state)
|
|
483
573
|
return false;
|
|
484
574
|
const partId = crypto.randomUUID();
|
|
575
|
+
const serializedBody = this.serializeInputChunk({ kind: "stop" });
|
|
485
576
|
const send = async (token) => {
|
|
486
|
-
await this.appendInputChunk(chatId, token,
|
|
577
|
+
await this.appendInputChunk(chatId, token, serializedBody, partId);
|
|
487
578
|
};
|
|
488
579
|
try {
|
|
489
|
-
await this.callWithAuthRetry(chatId, state, send);
|
|
580
|
+
await this.sendWithEvents(chatId, "stop", { partId, bodyBytes: byteLength(serializedBody) }, () => this.callWithAuthRetry(chatId, state, send));
|
|
490
581
|
}
|
|
491
582
|
catch {
|
|
492
583
|
return false;
|
|
@@ -532,7 +623,7 @@ class TriggerChatTransport {
|
|
|
532
623
|
const send = async (token) => {
|
|
533
624
|
await this.appendInputChunk(chatId, token, body, partId);
|
|
534
625
|
};
|
|
535
|
-
await this.callWithAuthRetry(chatId, state, send);
|
|
626
|
+
await this.sendWithEvents(chatId, "action", { partId, bodyBytes: byteLength(body) }, () => this.callWithAuthRetry(chatId, state, send));
|
|
536
627
|
// Supersede any in-flight reader before subscribing — same as
|
|
537
628
|
// `sendMessages`. Two concurrent readers both write `state.lastEventId`
|
|
538
629
|
// and the slower one can regress the cursor, replaying records on the
|
|
@@ -568,6 +659,61 @@ class TriggerChatTransport {
|
|
|
568
659
|
setOnSessionChange(callback) {
|
|
569
660
|
this._onSessionChange = callback;
|
|
570
661
|
}
|
|
662
|
+
/** Update the `onEvent` callback without recreating the transport. */
|
|
663
|
+
setOnEvent(callback) {
|
|
664
|
+
this._onEvent = callback;
|
|
665
|
+
}
|
|
666
|
+
emitEvent(event) {
|
|
667
|
+
const cb = this._onEvent;
|
|
668
|
+
if (!cb)
|
|
669
|
+
return;
|
|
670
|
+
try {
|
|
671
|
+
cb(event);
|
|
672
|
+
}
|
|
673
|
+
catch {
|
|
674
|
+
// observability must never break the chat
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/** Run a send op, emitting the terminal message-sent / message-send-failed event. */
|
|
678
|
+
async sendWithEvents(chatId, source, extras, op) {
|
|
679
|
+
const startedAt = Date.now();
|
|
680
|
+
try {
|
|
681
|
+
await op();
|
|
682
|
+
const turnProducing = source === "submit-message" || source === "regenerate-message" || source === "head-start";
|
|
683
|
+
if (turnProducing) {
|
|
684
|
+
this.lastTurnSends.set(chatId, { messageId: extras.messageId, at: Date.now() });
|
|
685
|
+
}
|
|
686
|
+
this.emitEvent({
|
|
687
|
+
type: "message-sent",
|
|
688
|
+
chatId,
|
|
689
|
+
timestamp: Date.now(),
|
|
690
|
+
source,
|
|
691
|
+
durationMs: Date.now() - startedAt,
|
|
692
|
+
...extras,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
const status = error.status;
|
|
697
|
+
this.emitEvent({
|
|
698
|
+
type: "message-send-failed",
|
|
699
|
+
chatId,
|
|
700
|
+
timestamp: Date.now(),
|
|
701
|
+
source,
|
|
702
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
703
|
+
status: typeof status === "number" ? status : undefined,
|
|
704
|
+
durationMs: Date.now() - startedAt,
|
|
705
|
+
...extras,
|
|
706
|
+
});
|
|
707
|
+
throw error;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
/** Attribution fields for response-side events. */
|
|
711
|
+
turnAttribution(chatId) {
|
|
712
|
+
const lastSend = this.lastTurnSends.get(chatId);
|
|
713
|
+
if (!lastSend)
|
|
714
|
+
return {};
|
|
715
|
+
return { messageId: lastSend.messageId, sinceSendMs: Date.now() - lastSend.at };
|
|
716
|
+
}
|
|
571
717
|
/**
|
|
572
718
|
* Update the transport's `clientData`. Used by `useTriggerChatTransport`
|
|
573
719
|
* to keep the latest value reachable from inside `startSession` and
|
|
@@ -934,6 +1080,15 @@ class TriggerChatTransport {
|
|
|
934
1080
|
throw e;
|
|
935
1081
|
}
|
|
936
1082
|
}
|
|
1083
|
+
this.emitEvent({
|
|
1084
|
+
type: "stream-connected",
|
|
1085
|
+
chatId,
|
|
1086
|
+
timestamp: Date.now(),
|
|
1087
|
+
resumed: options?.resumed ?? false,
|
|
1088
|
+
lastEventId: state.lastEventId,
|
|
1089
|
+
messageId: this.lastTurnSends.get(chatId)?.messageId,
|
|
1090
|
+
});
|
|
1091
|
+
let sawFirstChunk = false;
|
|
937
1092
|
while (true) {
|
|
938
1093
|
let value;
|
|
939
1094
|
if (primed !== undefined) {
|
|
@@ -1005,12 +1160,22 @@ class TriggerChatTransport {
|
|
|
1005
1160
|
if (refreshedToken) {
|
|
1006
1161
|
state.publicAccessToken = refreshedToken;
|
|
1007
1162
|
}
|
|
1163
|
+
this.emitEvent({
|
|
1164
|
+
type: "turn-completed",
|
|
1165
|
+
chatId,
|
|
1166
|
+
timestamp: Date.now(),
|
|
1167
|
+
lastEventId: state.lastEventId,
|
|
1168
|
+
sessionInEventId: (0, v3_1.headerValue)(value.headers, v3_1.SESSION_IN_EVENT_ID_HEADER),
|
|
1169
|
+
...this.turnAttribution(chatId),
|
|
1170
|
+
});
|
|
1008
1171
|
state.isStreaming = false;
|
|
1009
1172
|
this.notifySessionChange(chatId, state);
|
|
1010
1173
|
this.coordinator?.release(chatId);
|
|
1011
1174
|
this.coordinator?.broadcastSession(chatId, {
|
|
1012
1175
|
lastEventId: state.lastEventId,
|
|
1013
1176
|
});
|
|
1177
|
+
// Re-arm per-turn events for watch mode's next turn.
|
|
1178
|
+
sawFirstChunk = false;
|
|
1014
1179
|
if (this.watchMode)
|
|
1015
1180
|
continue;
|
|
1016
1181
|
internalAbort.abort();
|
|
@@ -1027,6 +1192,17 @@ class TriggerChatTransport {
|
|
|
1027
1192
|
// JSON unwrap). Drop empty/malformed payloads defensively.
|
|
1028
1193
|
if (value.chunk == null)
|
|
1029
1194
|
continue;
|
|
1195
|
+
if (!sawFirstChunk) {
|
|
1196
|
+
sawFirstChunk = true;
|
|
1197
|
+
this.emitEvent({
|
|
1198
|
+
type: "first-chunk",
|
|
1199
|
+
chatId,
|
|
1200
|
+
timestamp: Date.now(),
|
|
1201
|
+
chunkType: value.chunk.type,
|
|
1202
|
+
lastEventId: value.id || undefined,
|
|
1203
|
+
...this.turnAttribution(chatId),
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1030
1206
|
controller.enqueue(value.chunk);
|
|
1031
1207
|
}
|
|
1032
1208
|
}
|
|
@@ -1040,6 +1216,14 @@ class TriggerChatTransport {
|
|
|
1040
1216
|
}
|
|
1041
1217
|
return;
|
|
1042
1218
|
}
|
|
1219
|
+
const errorStatus = error.status;
|
|
1220
|
+
this.emitEvent({
|
|
1221
|
+
type: "stream-error",
|
|
1222
|
+
chatId,
|
|
1223
|
+
timestamp: Date.now(),
|
|
1224
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
1225
|
+
status: typeof errorStatus === "number" ? errorStatus : undefined,
|
|
1226
|
+
});
|
|
1043
1227
|
controller.error(error);
|
|
1044
1228
|
}
|
|
1045
1229
|
finally {
|