@trigger.dev/sdk 0.0.0-chat-prerelease-20260507131256 → 0.0.0-chat-prerelease-20260519091352
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/agentSkillsRuntime.js +53 -13
- package/dist/commonjs/v3/agentSkillsRuntime.js.map +1 -1
- package/dist/commonjs/v3/ai-shared.d.ts +24 -12
- package/dist/commonjs/v3/ai.d.ts +212 -130
- package/dist/commonjs/v3/ai.js +1153 -328
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat-client.d.ts +37 -1
- package/dist/commonjs/v3/chat-client.js +121 -63
- package/dist/commonjs/v3/chat-client.js.map +1 -1
- package/dist/commonjs/v3/chat-react.js +0 -2
- package/dist/commonjs/v3/chat-react.js.map +1 -1
- package/dist/commonjs/v3/chat-server.d.ts +16 -1
- package/dist/commonjs/v3/chat-server.js +65 -15
- package/dist/commonjs/v3/chat-server.js.map +1 -1
- package/dist/commonjs/v3/chat-server.test.js +6 -3
- package/dist/commonjs/v3/chat-server.test.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +76 -7
- package/dist/commonjs/v3/chat.js +126 -51
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/chat.test.js +173 -10
- package/dist/commonjs/v3/chat.test.js.map +1 -1
- package/dist/commonjs/v3/runs.d.ts +4 -0
- package/dist/commonjs/v3/sessions.d.ts +40 -0
- package/dist/commonjs/v3/sessions.js +100 -2
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/sessions.test.d.ts +1 -0
- package/dist/commonjs/v3/sessions.test.js +154 -0
- package/dist/commonjs/v3/sessions.test.js.map +1 -0
- package/dist/commonjs/v3/shared.d.ts +1 -1
- package/dist/commonjs/v3/shared.js +57 -32
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/streams.js +43 -2
- package/dist/commonjs/v3/streams.js.map +1 -1
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +96 -9
- package/dist/commonjs/v3/test/mock-chat-agent.js +137 -10
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/commonjs/v3/test/test-session-handle.d.ts +16 -1
- package/dist/commonjs/v3/test/test-session-handle.js +28 -0
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/agentSkillsRuntime.js +53 -13
- package/dist/esm/v3/agentSkillsRuntime.js.map +1 -1
- package/dist/esm/v3/ai-shared.d.ts +24 -12
- package/dist/esm/v3/ai.d.ts +212 -130
- package/dist/esm/v3/ai.js +1148 -330
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat-client.d.ts +37 -1
- package/dist/esm/v3/chat-client.js +122 -64
- package/dist/esm/v3/chat-client.js.map +1 -1
- package/dist/esm/v3/chat-react.js +0 -2
- package/dist/esm/v3/chat-react.js.map +1 -1
- package/dist/esm/v3/chat-server.d.ts +16 -1
- package/dist/esm/v3/chat-server.js +66 -16
- package/dist/esm/v3/chat-server.js.map +1 -1
- package/dist/esm/v3/chat-server.test.js +6 -3
- package/dist/esm/v3/chat-server.test.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +76 -7
- package/dist/esm/v3/chat.js +127 -52
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/chat.test.js +173 -10
- package/dist/esm/v3/chat.test.js.map +1 -1
- package/dist/esm/v3/runs.d.ts +4 -0
- package/dist/esm/v3/sessions.d.ts +40 -0
- package/dist/esm/v3/sessions.js +101 -3
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/sessions.test.d.ts +1 -0
- package/dist/esm/v3/sessions.test.js +152 -0
- package/dist/esm/v3/sessions.test.js.map +1 -0
- package/dist/esm/v3/shared.d.ts +1 -1
- package/dist/esm/v3/shared.js +57 -32
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/streams.js +43 -3
- package/dist/esm/v3/streams.js.map +1 -1
- package/dist/esm/v3/test/mock-chat-agent.d.ts +96 -9
- package/dist/esm/v3/test/mock-chat-agent.js +137 -10
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/esm/v3/test/test-session-handle.d.ts +16 -1
- package/dist/esm/v3/test/test-session-handle.js +28 -0
- package/dist/esm/v3/test/test-session-handle.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +2 -2
|
@@ -56,25 +56,42 @@ function truncate(s, limit) {
|
|
|
56
56
|
return s.slice(0, limit) + `\n…[truncated ${s.length - limit} bytes]`;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* Path-traversal guard: confirm `relative` resolves inside `root
|
|
60
|
-
* Throws if it escapes via
|
|
61
|
-
* absolute
|
|
59
|
+
* Path-traversal guard: confirm `relative` resolves inside `root`,
|
|
60
|
+
* even after symlinks are followed. Throws if it escapes via `..`, an
|
|
61
|
+
* absolute prefix, or a symlink that points outside. Returns the
|
|
62
|
+
* resolved real path.
|
|
63
|
+
*
|
|
64
|
+
* `fs.realpath` only works on paths that exist, so when the resolved
|
|
65
|
+
* path doesn't exist yet (e.g. writing a new file) we fall back to
|
|
66
|
+
* the lexical check — a non-existent path can't traverse a symlink
|
|
67
|
+
* to escape since the symlink doesn't exist either.
|
|
62
68
|
*/
|
|
63
|
-
function safeJoinInside(root, relative) {
|
|
69
|
+
async function safeJoinInside(root, relative) {
|
|
64
70
|
if (nodePath.isAbsolute(relative)) {
|
|
65
71
|
throw new Error(`Path must be relative to the skill directory: ${relative}`);
|
|
66
72
|
}
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
73
|
+
const realRoot = await fs.realpath(nodePath.resolve(root));
|
|
74
|
+
const resolved = nodePath.resolve(realRoot, relative);
|
|
75
|
+
let real = resolved;
|
|
76
|
+
try {
|
|
77
|
+
real = await fs.realpath(resolved);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (err.code !== "ENOENT") {
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
// Path doesn't exist yet; fall through with the lexical resolve.
|
|
84
|
+
}
|
|
85
|
+
const normalized = realRoot + nodePath.sep;
|
|
86
|
+
if (real !== realRoot && !real.startsWith(normalized)) {
|
|
70
87
|
throw new Error(`Path escapes the skill directory: ${relative}`);
|
|
71
88
|
}
|
|
72
|
-
return
|
|
89
|
+
return real;
|
|
73
90
|
}
|
|
74
91
|
async function readFileInSkill({ skillPath, relativePath, }) {
|
|
75
92
|
let absolute;
|
|
76
93
|
try {
|
|
77
|
-
absolute = safeJoinInside(skillPath, relativePath);
|
|
94
|
+
absolute = await safeJoinInside(skillPath, relativePath);
|
|
78
95
|
}
|
|
79
96
|
catch (err) {
|
|
80
97
|
return { error: err.message };
|
|
@@ -100,19 +117,42 @@ async function runBashInSkill({ skillPath, command, abortSignal, }) {
|
|
|
100
117
|
resolvePromise({ error: err.message });
|
|
101
118
|
return;
|
|
102
119
|
}
|
|
120
|
+
// Cap stdout/stderr accumulation at the byte budget so an
|
|
121
|
+
// LLM-generated command (`cat /dev/zero`, `yes`) can't OOM the
|
|
122
|
+
// worker. Track total seen length separately so the truncation
|
|
123
|
+
// notice still reports how much was dropped.
|
|
103
124
|
let stdout = "";
|
|
104
125
|
let stderr = "";
|
|
126
|
+
let stdoutSeen = 0;
|
|
127
|
+
let stderrSeen = 0;
|
|
128
|
+
const limit = DEFAULT_BASH_OUTPUT_BYTES;
|
|
105
129
|
child.stdout?.on("data", (chunk) => {
|
|
106
|
-
|
|
130
|
+
const text = chunk.toString();
|
|
131
|
+
stdoutSeen += text.length;
|
|
132
|
+
if (stdout.length >= limit)
|
|
133
|
+
return;
|
|
134
|
+
const remaining = limit - stdout.length;
|
|
135
|
+
stdout += text.length > remaining ? text.slice(0, remaining) : text;
|
|
107
136
|
});
|
|
108
137
|
child.stderr?.on("data", (chunk) => {
|
|
109
|
-
|
|
138
|
+
const text = chunk.toString();
|
|
139
|
+
stderrSeen += text.length;
|
|
140
|
+
if (stderr.length >= limit)
|
|
141
|
+
return;
|
|
142
|
+
const remaining = limit - stderr.length;
|
|
143
|
+
stderr += text.length > remaining ? text.slice(0, remaining) : text;
|
|
110
144
|
});
|
|
111
145
|
child.once("close", (code) => {
|
|
146
|
+
const stdoutFinal = stdoutSeen > stdout.length
|
|
147
|
+
? `${stdout}\n…[truncated ${stdoutSeen - stdout.length} bytes]`
|
|
148
|
+
: stdout;
|
|
149
|
+
const stderrFinal = stderrSeen > stderr.length
|
|
150
|
+
? `${stderr}\n…[truncated ${stderrSeen - stderr.length} bytes]`
|
|
151
|
+
: stderr;
|
|
112
152
|
resolvePromise({
|
|
113
153
|
exitCode: code,
|
|
114
|
-
stdout:
|
|
115
|
-
stderr:
|
|
154
|
+
stdout: stdoutFinal,
|
|
155
|
+
stderr: stderrFinal,
|
|
116
156
|
});
|
|
117
157
|
});
|
|
118
158
|
child.once("error", (err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentSkillsRuntime.js","sourceRoot":"","sources":["../../../src/v3/agentSkillsRuntime.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"agentSkillsRuntime.js","sourceRoot":"","sources":["../../../src/v3/agentSkillsRuntime.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,9 +24,31 @@ export declare const PENDING_MESSAGE_INJECTED_TYPE: "data-pending-message-inject
|
|
|
24
24
|
/**
|
|
25
25
|
* The wire payload shape sent by `TriggerChatTransport`.
|
|
26
26
|
* Uses `metadata` to match the AI SDK's `ChatRequestOptions` field name.
|
|
27
|
+
*
|
|
28
|
+
* Slim wire: at most ONE message per record. The agent runtime
|
|
29
|
+
* reconstructs prior history at run boot from a durable S3 snapshot +
|
|
30
|
+
* `session.out` replay (or `hydrateMessages` if registered). The wire is
|
|
31
|
+
* delta-only — see plan `vivid-humming-bonbon.md`.
|
|
27
32
|
*/
|
|
28
33
|
export type ChatTaskWirePayload<TMessage extends UIMessage = UIMessage, TMetadata = unknown> = {
|
|
29
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The single message being delivered on this trigger. Set for:
|
|
36
|
+
* - `submit-message`: the new user message OR a tool-approval-responded
|
|
37
|
+
* assistant message (with `state: "approval-responded"` tool parts).
|
|
38
|
+
* - `regenerate-message`: omitted (the agent slices its own history).
|
|
39
|
+
* - `preload` / `close` / `action`: omitted.
|
|
40
|
+
* - `handover-prepare`: omitted (use `headStartMessages` instead).
|
|
41
|
+
*/
|
|
42
|
+
message?: TMessage;
|
|
43
|
+
/**
|
|
44
|
+
* Bespoke escape hatch for `chat.headStart`. The customer's HTTP route
|
|
45
|
+
* handler ships full `UIMessage[]` history at the very first turn — before
|
|
46
|
+
* any snapshot exists. The route handler isn't subject to the
|
|
47
|
+
* `MAX_APPEND_BODY_BYTES` cap on `/in/append` because it goes through the
|
|
48
|
+
* customer's own HTTP endpoint. Used ONLY by `trigger: "handover-prepare"`.
|
|
49
|
+
* Ignored on every other trigger.
|
|
50
|
+
*/
|
|
51
|
+
headStartMessages?: TMessage[];
|
|
30
52
|
chatId: string;
|
|
31
53
|
trigger: "submit-message" | "regenerate-message" | "preload" | "close" | "action"
|
|
32
54
|
/**
|
|
@@ -58,16 +80,6 @@ export type ChatTaskWirePayload<TMessage extends UIMessage = UIMessage, TMetadat
|
|
|
58
80
|
* required once the legacy run-scoped stream path is removed.
|
|
59
81
|
*/
|
|
60
82
|
sessionId?: string;
|
|
61
|
-
/**
|
|
62
|
-
* Client-side `chat.store` value sent by the transport. Applied at turn
|
|
63
|
-
* start before `run()` fires, overwriting any in-memory store value on the
|
|
64
|
-
* agent (last-write-wins).
|
|
65
|
-
*
|
|
66
|
-
* The transport queues this via `setStore` / `applyStorePatch` and flushes
|
|
67
|
-
* it with the next `sendMessage`. On the agent you typically don't read
|
|
68
|
-
* this directly — it's applied into `chat.store` transparently.
|
|
69
|
-
*/
|
|
70
|
-
incomingStore?: unknown;
|
|
71
83
|
};
|
|
72
84
|
/**
|
|
73
85
|
* One chunk on the chat input stream. `kind` discriminates the variants —
|
|
@@ -148,7 +160,7 @@ export type ChatInputChunk<TMessage extends UIMessage = UIMessage, TMetadata = u
|
|
|
148
160
|
*/
|
|
149
161
|
export type InferChatClientData<TTask extends AnyTask> = TTask extends Task<string, ChatTaskWirePayload<any, infer TMetadata>, any> ? TMetadata : unknown;
|
|
150
162
|
/**
|
|
151
|
-
* Extracts the UI message type from a chat task (wire payload `
|
|
163
|
+
* Extracts the UI message type from a chat task (wire payload `message` items).
|
|
152
164
|
*
|
|
153
165
|
* @example
|
|
154
166
|
* ```ts
|
package/dist/commonjs/v3/ai.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyTask, type RealtimeDefinedInputStream, type RealtimeDefinedStream, Task, type inferSchemaIn, type inferSchemaOut, type TaskIdentifier, type TaskOptions, type TaskSchema, type TaskRunContext, type TaskWithSchema } from "@trigger.dev/core/v3";
|
|
1
|
+
import { AnyTask, type MachinePresetName, type RealtimeDefinedInputStream, type RealtimeDefinedStream, Task, type inferSchemaIn, type inferSchemaOut, type TaskIdentifier, type TaskOptions, type TaskSchema, type TaskRunContext, type TaskWithSchema } from "@trigger.dev/core/v3";
|
|
2
2
|
import type { FinishReason, ModelMessage, ToolSet, UIMessage, UIMessageChunk, UIMessageStreamOptions, LanguageModelUsage } from "ai";
|
|
3
3
|
import { Tool, ToolCallOptions } from "ai";
|
|
4
4
|
import { locals } from "./locals.js";
|
|
@@ -7,7 +7,6 @@ import type { ResolvedSkill } from "./skill.js";
|
|
|
7
7
|
import { type SessionTriggerConfig } from "@trigger.dev/core/v3";
|
|
8
8
|
/** Re-export for typing `ctx` in `chat.agent` hooks without importing `@trigger.dev/core`. */
|
|
9
9
|
export type { TaskRunContext } from "@trigger.dev/core/v3";
|
|
10
|
-
import { type ChatStorePatchOperation } from "@trigger.dev/core/v3/chat-client";
|
|
11
10
|
export type ToolCallExecutionOptions = {
|
|
12
11
|
toolCallId: string;
|
|
13
12
|
experimental_context?: unknown;
|
|
@@ -24,6 +23,9 @@ type ChatTurnContext<TClientData = unknown> = {
|
|
|
24
23
|
continuation: boolean;
|
|
25
24
|
clientData?: TClientData;
|
|
26
25
|
};
|
|
26
|
+
export declare function __setReadChatSnapshotImplForTests(impl: ReadChatSnapshotImpl | undefined): void;
|
|
27
|
+
export declare function __setWriteChatSnapshotImplForTests(impl: WriteChatSnapshotImpl | undefined): void;
|
|
28
|
+
export declare function __setReplaySessionOutTailImplForTests(impl: ReplaySessionOutTailImpl | undefined): void;
|
|
27
29
|
type ToolResultContent = Array<{
|
|
28
30
|
type: "text";
|
|
29
31
|
text: string;
|
|
@@ -132,29 +134,6 @@ export declare const ai: {
|
|
|
132
134
|
* ```
|
|
133
135
|
*/
|
|
134
136
|
declare function createChatAccessToken<TTask extends AnyTask>(taskId: TaskIdentifier<TTask>): Promise<string>;
|
|
135
|
-
/**
|
|
136
|
-
* Listener fired when the store value changes. `operations` is present for
|
|
137
|
-
* `patch()` updates and absent for `set()` (which is a full snapshot).
|
|
138
|
-
*/
|
|
139
|
-
export type ChatStoreChangeListener<TStore = unknown> = (value: TStore, operations?: ChatStorePatchOperation[]) => void;
|
|
140
|
-
/**
|
|
141
|
-
* Replace the entire store value with `value`. Emits a `store-snapshot`
|
|
142
|
-
* chunk on the chat output stream and fires all `onChange` listeners.
|
|
143
|
-
*/
|
|
144
|
-
declare function chatStoreSet<TStore = unknown>(value: TStore): void;
|
|
145
|
-
/**
|
|
146
|
-
* Apply RFC 6902 JSON Patch operations to the current store value.
|
|
147
|
-
* Emits a `store-delta` chunk on the chat output stream and fires all
|
|
148
|
-
* `onChange` listeners with the new value and the operations.
|
|
149
|
-
*/
|
|
150
|
-
declare function chatStorePatch(operations: ChatStorePatchOperation[]): void;
|
|
151
|
-
/** Get the current store value. Returns `undefined` if no value has been set. */
|
|
152
|
-
declare function chatStoreGet<TStore = unknown>(): TStore | undefined;
|
|
153
|
-
/**
|
|
154
|
-
* Subscribe to store changes for the current run. Returns an
|
|
155
|
-
* unsubscribe function.
|
|
156
|
-
*/
|
|
157
|
-
declare function chatStoreOnChange<TStore = unknown>(listener: ChatStoreChangeListener<TStore>): () => void;
|
|
158
137
|
/**
|
|
159
138
|
* A stream writer passed to chat lifecycle callbacks (`onPreload`, `onChatStart`,
|
|
160
139
|
* `onTurnStart`, `onTurnComplete`, `onCompacted`).
|
|
@@ -874,15 +853,68 @@ export type PreloadEvent<TClientData = unknown> = {
|
|
|
874
853
|
/** Stream writer — write custom `UIMessageChunk` parts to the chat stream. Lazy: no overhead if unused. */
|
|
875
854
|
writer: ChatWriter;
|
|
876
855
|
};
|
|
856
|
+
/**
|
|
857
|
+
* Event passed to the `onBoot` callback.
|
|
858
|
+
*
|
|
859
|
+
* Fires once at the start of every run boot — for the initial first-message
|
|
860
|
+
* run, for preloaded runs, AND for reactive continuation runs (post-cancel,
|
|
861
|
+
* post-crash, post-`endRun`, `chat.requestUpgrade`, OOM-retry attempts).
|
|
862
|
+
* Does NOT fire when the SAME run resumes from snapshot via the
|
|
863
|
+
* idle-window suspend/resume path — use `onChatResume` for that.
|
|
864
|
+
*
|
|
865
|
+
* Use this for per-process setup that needs to run every time a fresh
|
|
866
|
+
* worker picks up the chat: initialize `chat.local` state, open
|
|
867
|
+
* per-process resources (DB connections, sandboxes, etc.), or
|
|
868
|
+
* re-hydrate customer state from your DB on continuation.
|
|
869
|
+
*
|
|
870
|
+
* Ordering:
|
|
871
|
+
* - First message of a chat: `onBoot` → `onChatStart` → `onTurnStart` → `run()`
|
|
872
|
+
* - Preloaded run: `onBoot` → `onPreload` → (wait) → `onChatStart` → ...
|
|
873
|
+
* - Continuation run: `onBoot` → (wait for first message) → `onTurnStart` → `run()`
|
|
874
|
+
* (`onChatStart` does NOT fire on continuation runs)
|
|
875
|
+
*/
|
|
876
|
+
export type BootEvent<TClientData = unknown> = {
|
|
877
|
+
/** Task run context — same as `task({ run })` second-argument `ctx`. */
|
|
878
|
+
ctx: TaskRunContext;
|
|
879
|
+
/** The unique identifier for the chat session. */
|
|
880
|
+
chatId: string;
|
|
881
|
+
/** The Trigger.dev run ID for this run boot. */
|
|
882
|
+
runId: string;
|
|
883
|
+
/** A scoped access token for this chat run. Persist this for frontend reconnection. */
|
|
884
|
+
chatAccessToken: string;
|
|
885
|
+
/** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
|
|
886
|
+
clientData: TClientData;
|
|
887
|
+
/**
|
|
888
|
+
* True when this run is a reactive continuation — the prior run died
|
|
889
|
+
* (cancel / crash / `endRun` / `requestUpgrade` / OOM retry) and this
|
|
890
|
+
* fresh worker is taking over the chat. Branch on this to re-load
|
|
891
|
+
* customer-owned state from your DB.
|
|
892
|
+
*/
|
|
893
|
+
continuation: boolean;
|
|
894
|
+
/** Public id of the prior run when `continuation` is true. */
|
|
895
|
+
previousRunId?: string;
|
|
896
|
+
/** Whether this run was triggered as a preload. */
|
|
897
|
+
preloaded: boolean;
|
|
898
|
+
};
|
|
877
899
|
/**
|
|
878
900
|
* Event passed to the `onChatStart` callback.
|
|
901
|
+
*
|
|
902
|
+
* Fires exactly once per chat, on the very first user message of the chat's
|
|
903
|
+
* lifetime. Does NOT fire on continuation runs (post-`endRun`,
|
|
904
|
+
* post-waitpoint-timeout, `chat.requestUpgrade`) or on OOM-retry attempts —
|
|
905
|
+
* those are runs of an already-started chat.
|
|
879
906
|
*/
|
|
880
907
|
export type ChatStartEvent<TClientData = unknown> = {
|
|
881
908
|
/** Task run context — same as `task({ run })` second-argument `ctx`. */
|
|
882
909
|
ctx: TaskRunContext;
|
|
883
910
|
/** The unique identifier for the chat session. */
|
|
884
911
|
chatId: string;
|
|
885
|
-
/**
|
|
912
|
+
/**
|
|
913
|
+
* The initial model-ready messages for this conversation. Typically just
|
|
914
|
+
* the first user message (or empty if `chat.headStart` is in play and the
|
|
915
|
+
* seed message is supplied elsewhere). Since this hook only fires for the
|
|
916
|
+
* chat's very first message, there's no prior history to load here.
|
|
917
|
+
*/
|
|
886
918
|
messages: ModelMessage[];
|
|
887
919
|
/** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
|
|
888
920
|
clientData: TClientData;
|
|
@@ -890,9 +922,17 @@ export type ChatStartEvent<TClientData = unknown> = {
|
|
|
890
922
|
runId: string;
|
|
891
923
|
/** A scoped access token for this chat run. Persist this for frontend reconnection. */
|
|
892
924
|
chatAccessToken: string;
|
|
893
|
-
/**
|
|
925
|
+
/**
|
|
926
|
+
* @deprecated Always `false` — `onChatStart` no longer fires on continuation
|
|
927
|
+
* runs. Kept for backward compatibility; remove your `continuation` checks
|
|
928
|
+
* from `onChatStart` and rely on the contract (this hook fires exactly once
|
|
929
|
+
* per chat, on the very first message).
|
|
930
|
+
*/
|
|
894
931
|
continuation: boolean;
|
|
895
|
-
/**
|
|
932
|
+
/**
|
|
933
|
+
* @deprecated Always `undefined` — `onChatStart` no longer fires on
|
|
934
|
+
* continuation runs.
|
|
935
|
+
*/
|
|
896
936
|
previousRunId?: string;
|
|
897
937
|
/** Whether this run was preloaded before the first message. */
|
|
898
938
|
preloaded: boolean;
|
|
@@ -920,37 +960,6 @@ export type HydrateMessagesEvent<TClientData = unknown, TUIM extends UIMessage =
|
|
|
920
960
|
/** The ID of the previous run (if continuation). */
|
|
921
961
|
previousRunId?: string;
|
|
922
962
|
};
|
|
923
|
-
/**
|
|
924
|
-
* Event passed to the `hydrateStore` callback.
|
|
925
|
-
*
|
|
926
|
-
* Called at turn start — before `run()` fires and before any incoming store
|
|
927
|
-
* from the wire payload is applied. Return the authoritative store value
|
|
928
|
-
* for this turn; it becomes the initial value `chat.store.get()` sees.
|
|
929
|
-
*/
|
|
930
|
-
export type HydrateStoreEvent<TClientData = unknown, TStore = unknown> = {
|
|
931
|
-
/** The unique identifier for the chat session. */
|
|
932
|
-
chatId: string;
|
|
933
|
-
/** The turn number (0-indexed). */
|
|
934
|
-
turn: number;
|
|
935
|
-
/** The trigger type for this turn. */
|
|
936
|
-
trigger: "submit-message" | "regenerate-message" | "action" | "preload";
|
|
937
|
-
/**
|
|
938
|
-
* The in-memory store value from the previous turn of this run
|
|
939
|
-
* (`undefined` on turn 0 and after continuations).
|
|
940
|
-
*/
|
|
941
|
-
previousStore: TStore | undefined;
|
|
942
|
-
/**
|
|
943
|
-
* The store value the transport sent with this turn, if any.
|
|
944
|
-
* Usually set by client-side `setStore` / `applyStorePatch`.
|
|
945
|
-
*/
|
|
946
|
-
incomingStore: TStore | undefined;
|
|
947
|
-
/** Parsed client data from the transport metadata. */
|
|
948
|
-
clientData?: TClientData;
|
|
949
|
-
/** Whether this run is continuing from a previous run. */
|
|
950
|
-
continuation: boolean;
|
|
951
|
-
/** The ID of the previous run (if continuation). */
|
|
952
|
-
previousRunId?: string;
|
|
953
|
-
};
|
|
954
963
|
/**
|
|
955
964
|
* Event passed to the `onValidateMessages` callback.
|
|
956
965
|
*/
|
|
@@ -1109,6 +1118,23 @@ export type ChatSuspendEvent<TClientData = unknown, TUIM extends UIMessage = UIM
|
|
|
1109
1118
|
runId: string;
|
|
1110
1119
|
/** Custom data from the frontend. */
|
|
1111
1120
|
clientData?: TClientData;
|
|
1121
|
+
} | {
|
|
1122
|
+
/**
|
|
1123
|
+
* Suspend is happening on a continuation run that booted with no incoming
|
|
1124
|
+
* message (post-`endRun`, post-waitpoint-timeout, etc.) and is waiting
|
|
1125
|
+
* for the next session.in record before running any turn. Distinct from
|
|
1126
|
+
* `phase: "preload"` — the chat already started; `onPreload` has not
|
|
1127
|
+
* fired and will not fire on this run.
|
|
1128
|
+
*/
|
|
1129
|
+
phase: "continuation";
|
|
1130
|
+
/** Task run context. */
|
|
1131
|
+
ctx: TaskRunContext;
|
|
1132
|
+
/** The chat session ID. */
|
|
1133
|
+
chatId: string;
|
|
1134
|
+
/** The Trigger.dev run ID. */
|
|
1135
|
+
runId: string;
|
|
1136
|
+
/** Custom data from the frontend. */
|
|
1137
|
+
clientData?: TClientData;
|
|
1112
1138
|
} | {
|
|
1113
1139
|
/** Suspend is happening after a completed turn, waiting for the next message. */
|
|
1114
1140
|
phase: "turn";
|
|
@@ -1142,6 +1168,22 @@ export type ChatResumeEvent<TClientData = unknown, TUIM extends UIMessage = UIMe
|
|
|
1142
1168
|
runId: string;
|
|
1143
1169
|
/** Custom data from the frontend. */
|
|
1144
1170
|
clientData?: TClientData;
|
|
1171
|
+
} | {
|
|
1172
|
+
/**
|
|
1173
|
+
* First message arrived after continuation-wait suspension. Distinct
|
|
1174
|
+
* from `phase: "preload"` — the chat already started; this is a new
|
|
1175
|
+
* run picking up after a prior run ended (`endRun`, waitpoint timeout,
|
|
1176
|
+
* etc.).
|
|
1177
|
+
*/
|
|
1178
|
+
phase: "continuation";
|
|
1179
|
+
/** Task run context. */
|
|
1180
|
+
ctx: TaskRunContext;
|
|
1181
|
+
/** The chat session ID. */
|
|
1182
|
+
chatId: string;
|
|
1183
|
+
/** The Trigger.dev run ID. */
|
|
1184
|
+
runId: string;
|
|
1185
|
+
/** Custom data from the frontend. */
|
|
1186
|
+
clientData?: TClientData;
|
|
1145
1187
|
} | {
|
|
1146
1188
|
/** Next message arrived after turn suspension. */
|
|
1147
1189
|
phase: "turn";
|
|
@@ -1160,7 +1202,40 @@ export type ChatResumeEvent<TClientData = unknown, TUIM extends UIMessage = UIMe
|
|
|
1160
1202
|
/** Custom data from the frontend. */
|
|
1161
1203
|
clientData?: TClientData;
|
|
1162
1204
|
};
|
|
1163
|
-
export type ChatAgentOptions<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined, TUIMessage extends UIMessage = UIMessage, TActionSchema extends TaskSchema | undefined = undefined> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>, "run"> & {
|
|
1205
|
+
export type ChatAgentOptions<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined, TUIMessage extends UIMessage = UIMessage, TActionSchema extends TaskSchema | undefined = undefined> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>, "run" | "retry"> & {
|
|
1206
|
+
/**
|
|
1207
|
+
* Fallback machine preset to use when an attempt fails with an
|
|
1208
|
+
* out-of-memory (OOM) error. Setting this enables a single OOM retry:
|
|
1209
|
+
* the next attempt boots on the larger machine, and the chat picks
|
|
1210
|
+
* up via the standard continuation path (same `chatId` / Session,
|
|
1211
|
+
* accumulator rebuilds via `hydrateMessages` or post-`onTurnStart`
|
|
1212
|
+
* persisted state).
|
|
1213
|
+
*
|
|
1214
|
+
* Set `machine` (top-level `TaskOptions`) to control the *default*
|
|
1215
|
+
* machine the agent runs on. `oomMachine` is the *retry-only* swap.
|
|
1216
|
+
*
|
|
1217
|
+
* Note: an OOM retry restarts the entire turn from the top — the
|
|
1218
|
+
* model call and any in-flight tool executes re-run on the larger
|
|
1219
|
+
* machine. Make tool executes idempotent or persist results before
|
|
1220
|
+
* returning if you can't tolerate re-execution.
|
|
1221
|
+
*
|
|
1222
|
+
* Generic `retry` options are not exposed on `chat.agent` because
|
|
1223
|
+
* arbitrary retries against an LLM-driven loop tend to be expensive
|
|
1224
|
+
* and side-effecting. If you need richer retry semantics, drop down
|
|
1225
|
+
* to `chat.task` (the raw primitive).
|
|
1226
|
+
*
|
|
1227
|
+
* @example
|
|
1228
|
+
* ```ts
|
|
1229
|
+
* chat.agent({
|
|
1230
|
+
* id: "my-chat",
|
|
1231
|
+
* machine: "small-1x",
|
|
1232
|
+
* oomMachine: "medium-2x",
|
|
1233
|
+
* run: async ({ messages, signal }) =>
|
|
1234
|
+
* streamText({ model, messages, abortSignal: signal }),
|
|
1235
|
+
* });
|
|
1236
|
+
* ```
|
|
1237
|
+
*/
|
|
1238
|
+
oomMachine?: MachinePresetName;
|
|
1164
1239
|
/**
|
|
1165
1240
|
* Schema for validating `clientData` from the frontend.
|
|
1166
1241
|
* Accepts Zod, ArkType, Valibot, or any supported schema library.
|
|
@@ -1233,6 +1308,35 @@ export type ChatAgentOptions<TIdentifier extends string, TClientDataSchema exten
|
|
|
1233
1308
|
* the stream is automatically piped to the frontend.
|
|
1234
1309
|
*/
|
|
1235
1310
|
run: (payload: ChatTaskRunPayload<inferSchemaOut<TClientDataSchema>>) => Promise<unknown>;
|
|
1311
|
+
/**
|
|
1312
|
+
* Called once at the start of every run boot — for the initial run, for
|
|
1313
|
+
* preloaded runs, AND for reactive continuation runs (post-cancel /
|
|
1314
|
+
* crash / `endRun` / `requestUpgrade` / OOM retry).
|
|
1315
|
+
*
|
|
1316
|
+
* Use this for per-process setup that needs to run every time a fresh
|
|
1317
|
+
* worker picks up the chat: initialize `chat.local` state, open
|
|
1318
|
+
* per-process resources, or re-hydrate customer state from your DB
|
|
1319
|
+
* on continuation. Branch on `continuation` to decide whether to load
|
|
1320
|
+
* existing state vs. start fresh.
|
|
1321
|
+
*
|
|
1322
|
+
* Fires BEFORE `onPreload` (preloaded path) and `onChatStart`
|
|
1323
|
+
* (first-message path), so `chat.local` is safe to read in those hooks.
|
|
1324
|
+
*
|
|
1325
|
+
* Does NOT fire when the same run resumes from snapshot via the
|
|
1326
|
+
* idle-window suspend/resume path — use `onChatResume` for that.
|
|
1327
|
+
*
|
|
1328
|
+
* @example
|
|
1329
|
+
* ```ts
|
|
1330
|
+
* onBoot: async ({ chatId, clientData, continuation }) => {
|
|
1331
|
+
* const user = await db.user.findFirst({ where: { id: clientData.userId } });
|
|
1332
|
+
* userContext.init({ name: user.name, plan: user.plan });
|
|
1333
|
+
* if (continuation) {
|
|
1334
|
+
* // re-hydrate any per-chat in-memory state from your DB
|
|
1335
|
+
* }
|
|
1336
|
+
* }
|
|
1337
|
+
* ```
|
|
1338
|
+
*/
|
|
1339
|
+
onBoot?: (event: BootEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void;
|
|
1236
1340
|
/**
|
|
1237
1341
|
* Called when a preloaded run starts, before the first message arrives.
|
|
1238
1342
|
*
|
|
@@ -1249,9 +1353,16 @@ export type ChatAgentOptions<TIdentifier extends string, TClientDataSchema exten
|
|
|
1249
1353
|
*/
|
|
1250
1354
|
onPreload?: (event: PreloadEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void;
|
|
1251
1355
|
/**
|
|
1252
|
-
* Called
|
|
1356
|
+
* Called exactly once per chat, on the very first user message of the
|
|
1357
|
+
* chat's lifetime. Does NOT fire on continuation runs (post-`endRun`,
|
|
1358
|
+
* post-waitpoint-timeout, `chat.requestUpgrade`) or on OOM-retry attempts —
|
|
1359
|
+
* those are runs of an already-started chat.
|
|
1253
1360
|
*
|
|
1254
|
-
* Use this
|
|
1361
|
+
* Use this for one-time chat-setup work — creating the Chat DB row,
|
|
1362
|
+
* initializing per-chat in-memory state, minting resources tied to the
|
|
1363
|
+
* chat's lifetime. Safe to assume no prior history exists here.
|
|
1364
|
+
*
|
|
1365
|
+
* For per-turn work, use `onTurnStart`.
|
|
1255
1366
|
*
|
|
1256
1367
|
* @example
|
|
1257
1368
|
* ```ts
|
|
@@ -1323,43 +1434,6 @@ export type ChatAgentOptions<TIdentifier extends string, TClientDataSchema exten
|
|
|
1323
1434
|
* ```
|
|
1324
1435
|
*/
|
|
1325
1436
|
hydrateMessages?: (event: HydrateMessagesEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => TUIMessage[] | Promise<TUIMessage[]>;
|
|
1326
|
-
/**
|
|
1327
|
-
* Load the `chat.store` value for this turn from your backend.
|
|
1328
|
-
*
|
|
1329
|
-
* The store lives in memory on the agent instance for the lifetime of
|
|
1330
|
-
* the run. After a continuation (idle timeout, `chat.requestUpgrade`,
|
|
1331
|
-
* max turns), a new run starts with an empty store — this hook lets
|
|
1332
|
-
* you restore it from your own persistence layer.
|
|
1333
|
-
*
|
|
1334
|
-
* Runs at turn start, before `run()` fires. The returned value replaces
|
|
1335
|
-
* the in-memory store and is emitted as a `store-snapshot` chunk so the
|
|
1336
|
-
* frontend sees the initial value.
|
|
1337
|
-
*
|
|
1338
|
-
* If both `hydrateStore` and `incomingStore` (from the wire payload) are
|
|
1339
|
-
* present, `incomingStore` wins — it represents the client's latest
|
|
1340
|
-
* local state and follows AG-UI's last-write-wins policy.
|
|
1341
|
-
*
|
|
1342
|
-
* @example
|
|
1343
|
-
* ```ts
|
|
1344
|
-
* chat.agent({
|
|
1345
|
-
* id: "my-chat",
|
|
1346
|
-
* hydrateStore: async ({ chatId, previousRunId }) => {
|
|
1347
|
-
* return db.chatStore.findUnique({ where: { chatId } })?.value;
|
|
1348
|
-
* },
|
|
1349
|
-
* onTurnComplete: async ({ chatId }) => {
|
|
1350
|
-
* await db.chatStore.upsert({
|
|
1351
|
-
* where: { chatId },
|
|
1352
|
-
* update: { value: chat.store.get() },
|
|
1353
|
-
* create: { chatId, value: chat.store.get() },
|
|
1354
|
-
* });
|
|
1355
|
-
* },
|
|
1356
|
-
* run: async ({ messages, signal }) => {
|
|
1357
|
-
* return streamText({ model: openai("gpt-4o"), messages, abortSignal: signal });
|
|
1358
|
-
* },
|
|
1359
|
-
* });
|
|
1360
|
-
* ```
|
|
1361
|
-
*/
|
|
1362
|
-
hydrateStore?: (event: HydrateStoreEvent<inferSchemaOut<TClientDataSchema>>) => unknown | Promise<unknown>;
|
|
1363
1437
|
/**
|
|
1364
1438
|
* Called at the start of every turn, after message accumulation and `onChatStart` (turn 0),
|
|
1365
1439
|
* but before the `run` function executes.
|
|
@@ -1688,6 +1762,8 @@ export interface ChatBuilder<TUIMessage extends UIMessage = UIMessage, TClientDa
|
|
|
1688
1762
|
withClientData<TSchema extends TaskSchema>(config: {
|
|
1689
1763
|
schema: TSchema;
|
|
1690
1764
|
}): ChatBuilder<TUIMessage, TSchema>;
|
|
1765
|
+
/** Register a builder-level `onBoot` hook. Runs before the task-level hook if both are set. */
|
|
1766
|
+
onBoot(fn: (event: BootEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
|
|
1691
1767
|
/** Register a builder-level `onPreload` hook. Runs before the task-level hook if both are set. */
|
|
1692
1768
|
onPreload(fn: (event: PreloadEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
|
|
1693
1769
|
/** Register a builder-level `onChatStart` hook. Runs before the task-level hook if both are set. */
|
|
@@ -2255,8 +2331,11 @@ export type ChatLocal<T extends Record<string, unknown>> = T & {
|
|
|
2255
2331
|
/**
|
|
2256
2332
|
* Creates a per-run typed data object accessible from anywhere during task execution.
|
|
2257
2333
|
*
|
|
2258
|
-
* Declare at module level, then initialize inside
|
|
2259
|
-
*
|
|
2334
|
+
* Declare at module level, then initialize inside `onBoot` (recommended — fires
|
|
2335
|
+
* on every fresh worker including continuation runs). Do NOT initialize in
|
|
2336
|
+
* `onChatStart` alone: `onChatStart` only fires on the chat's very first
|
|
2337
|
+
* message, so `chat.local` would be uninitialized on continuation runs and
|
|
2338
|
+
* `run()` would throw.
|
|
2260
2339
|
*
|
|
2261
2340
|
* Multiple locals can coexist — each gets its own isolated run-scoped storage.
|
|
2262
2341
|
*
|
|
@@ -2273,7 +2352,7 @@ export type ChatLocal<T extends Record<string, unknown>> = T & {
|
|
|
2273
2352
|
*
|
|
2274
2353
|
* export const myChat = chat.agent({
|
|
2275
2354
|
* id: "my-chat",
|
|
2276
|
-
*
|
|
2355
|
+
* onBoot: async ({ clientData }) => {
|
|
2277
2356
|
* const prefs = await db.prefs.findUnique({ where: { userId: clientData.userId } });
|
|
2278
2357
|
* userPrefs.init(prefs ?? { theme: "dark", language: "en" });
|
|
2279
2358
|
* gameState.init({ score: 0, streak: 0 });
|
|
@@ -2314,6 +2393,22 @@ export type { InferChatClientData, InferChatUIMessage } from "./ai-shared.js";
|
|
|
2314
2393
|
/**
|
|
2315
2394
|
* Options for {@link createChatStartSessionAction}.
|
|
2316
2395
|
*/
|
|
2396
|
+
/**
|
|
2397
|
+
* Discriminator for per-endpoint `baseURL` / `fetch` callbacks on
|
|
2398
|
+
* `createChatStartSessionAction`.
|
|
2399
|
+
*
|
|
2400
|
+
* - `"sessions"` — `POST /api/v1/sessions` (session create + first run trigger).
|
|
2401
|
+
* - `"auth"` — `POST /api/v1/auth/jwt/claims` (only fired when
|
|
2402
|
+
* `tokenTTL` is set; otherwise the publicAccessToken from session create
|
|
2403
|
+
* is reused as-is).
|
|
2404
|
+
*/
|
|
2405
|
+
export type ChatStartSessionEndpoint = "sessions" | "auth";
|
|
2406
|
+
export type ChatStartSessionEndpointContext = {
|
|
2407
|
+
endpoint: ChatStartSessionEndpoint;
|
|
2408
|
+
chatId: string;
|
|
2409
|
+
};
|
|
2410
|
+
export type ChatStartSessionBaseURLResolver = (ctx: ChatStartSessionEndpointContext) => string;
|
|
2411
|
+
export type ChatStartSessionFetchOverride = (url: string, init: RequestInit, ctx: ChatStartSessionEndpointContext) => Promise<Response>;
|
|
2317
2412
|
export type CreateChatStartSessionActionOptions = {
|
|
2318
2413
|
/** TTL for the session-scoped public access token. @default "1h" */
|
|
2319
2414
|
tokenTTL?: string | number | Date;
|
|
@@ -2322,6 +2417,21 @@ export type CreateChatStartSessionActionOptions = {
|
|
|
2322
2417
|
* Per-call `params.triggerConfig` shallow-merges on top.
|
|
2323
2418
|
*/
|
|
2324
2419
|
triggerConfig?: Partial<SessionTriggerConfig>;
|
|
2420
|
+
/**
|
|
2421
|
+
* Override the Trigger.dev API base URL. String applies to both
|
|
2422
|
+
* `/api/v1/sessions` and `/api/v1/auth/jwt/claims`; function picks per
|
|
2423
|
+
* endpoint. When unset, falls back to `apiClientManager.baseURL`
|
|
2424
|
+
* (typically the `TRIGGER_API_URL` env var). Set this to route session
|
|
2425
|
+
* create through a trusted edge proxy that injects server-side signal
|
|
2426
|
+
* into `basePayload.metadata` before forwarding upstream.
|
|
2427
|
+
*/
|
|
2428
|
+
baseURL?: string | ChatStartSessionBaseURLResolver;
|
|
2429
|
+
/**
|
|
2430
|
+
* Per-request fetch override. Receives the resolved URL, RequestInit,
|
|
2431
|
+
* and endpoint context. Use for header injection, proxy routing, or
|
|
2432
|
+
* custom retry. Applies to both session-create and JWT-claims POSTs.
|
|
2433
|
+
*/
|
|
2434
|
+
fetch?: ChatStartSessionFetchOverride;
|
|
2325
2435
|
};
|
|
2326
2436
|
/**
|
|
2327
2437
|
* Params for the function returned by {@link createChatStartSessionAction}.
|
|
@@ -2432,34 +2542,6 @@ export declare const chat: {
|
|
|
2432
2542
|
*/
|
|
2433
2543
|
write(part: UIMessageChunk): void;
|
|
2434
2544
|
};
|
|
2435
|
-
/**
|
|
2436
|
-
* Typed, bidirectional shared data slot for the chat.
|
|
2437
|
-
*
|
|
2438
|
-
* Use from `chat.agent` hooks and `run()` to share state with the client.
|
|
2439
|
-
* Setting emits a `store-snapshot` chunk; patching emits `store-delta`.
|
|
2440
|
-
* The value persists across turns within the same run, and can be
|
|
2441
|
-
* restored after continuations via the `hydrateStore` config option.
|
|
2442
|
-
*
|
|
2443
|
-
* ```ts
|
|
2444
|
-
* chat.store.set({ plan: ["research", "draft", "review"] });
|
|
2445
|
-
* chat.store.patch([{ op: "replace", path: "/status", value: "done" }]);
|
|
2446
|
-
* const current = chat.store.get();
|
|
2447
|
-
* const off = chat.store.onChange((value, ops) => { ... });
|
|
2448
|
-
* ```
|
|
2449
|
-
*/
|
|
2450
|
-
store: {
|
|
2451
|
-
/** Replace the store value. Emits a `store-snapshot` chunk. */
|
|
2452
|
-
set: typeof chatStoreSet;
|
|
2453
|
-
/**
|
|
2454
|
-
* Apply RFC 6902 JSON Patch operations to the current value.
|
|
2455
|
-
* Emits a `store-delta` chunk.
|
|
2456
|
-
*/
|
|
2457
|
-
patch: typeof chatStorePatch;
|
|
2458
|
-
/** Read the current store value. Returns `undefined` if never set. */
|
|
2459
|
-
get: typeof chatStoreGet;
|
|
2460
|
-
/** Subscribe to store changes. Returns an unsubscribe function. */
|
|
2461
|
-
onChange: typeof chatStoreOnChange;
|
|
2462
|
-
};
|
|
2463
2545
|
/** Pre-built input stream for receiving messages from the transport. */
|
|
2464
2546
|
messages: RealtimeDefinedInputStream<ChatTaskWirePayload>;
|
|
2465
2547
|
/** Create a managed stop signal wired to the stop input stream. See {@link createStopSignal}. */
|