react-websocket 4.0.0 → 4.18.0
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/README.md +27 -3
- package/dist/ag-ui.cjs +421 -0
- package/dist/ag-ui.cjs.map +1 -0
- package/dist/ag-ui.d.cts +493 -0
- package/dist/ag-ui.d.ts +171 -0
- package/dist/ag-ui.js +418 -0
- package/dist/ag-ui.js.map +1 -0
- package/dist/core.cjs +689 -153
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +459 -53
- package/dist/core.d.ts +459 -53
- package/dist/core.js +686 -154
- package/dist/core.js.map +1 -1
- package/dist/devtools.cjs +186 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +32 -0
- package/dist/devtools.d.ts +32 -0
- package/dist/devtools.js +185 -0
- package/dist/devtools.js.map +1 -0
- package/dist/index.cjs +182 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +663 -48
- package/dist/index.d.ts +393 -22
- package/dist/index.js +178 -24
- package/dist/index.js.map +1 -1
- package/dist/outbox.cjs +222 -0
- package/dist/outbox.cjs.map +1 -0
- package/dist/outbox.d.cts +127 -0
- package/dist/outbox.d.ts +127 -0
- package/dist/outbox.js +219 -0
- package/dist/outbox.js.map +1 -0
- package/dist/replay.cjs +324 -0
- package/dist/replay.cjs.map +1 -0
- package/dist/replay.d.cts +124 -0
- package/dist/replay.d.ts +124 -0
- package/dist/replay.js +322 -0
- package/dist/replay.js.map +1 -0
- package/dist/tabs.cjs +336 -0
- package/dist/tabs.cjs.map +1 -0
- package/dist/tabs.d.cts +81 -0
- package/dist/tabs.d.ts +81 -0
- package/dist/tabs.js +335 -0
- package/dist/tabs.js.map +1 -0
- package/dist/timeline.d.cts +1 -216
- package/dist/types-BEecFqIB.d.cts +268 -0
- package/dist/webtransport.cjs +243 -0
- package/dist/webtransport.cjs.map +1 -0
- package/dist/webtransport.d.cts +67 -0
- package/dist/webtransport.d.ts +67 -0
- package/dist/webtransport.js +242 -0
- package/dist/webtransport.js.map +1 -0
- package/package.json +139 -3
package/dist/ag-ui.d.cts
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Where to connect: a URL, or a function that returns one (sync or async).
|
|
4
|
+
*
|
|
5
|
+
* A function is called before **every** connection attempt, including reconnects,
|
|
6
|
+
* so it can put a fresh auth token in the URL. If it throws or rejects, that counts
|
|
7
|
+
* as a failed attempt and is retried with backoff.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* createWebSocket(async () => `wss://api.example.com/live?token=${await getToken()}`);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
type UrlSource = string | (() => string | Promise<string>);
|
|
15
|
+
/**
|
|
16
|
+
* Connection state.
|
|
17
|
+
*
|
|
18
|
+
* - `idle`: not connected and not trying to be. Nobody is using the client yet, or everyone stopped.
|
|
19
|
+
* - `connecting`: the first attempt is in progress.
|
|
20
|
+
* - `open`: connected. `send()` goes out immediately.
|
|
21
|
+
* - `reconnecting`: the connection dropped (or an attempt failed) and a retry is scheduled or in progress.
|
|
22
|
+
* - `closed`: stopped for good, by `close()` or after giving up on reconnecting.
|
|
23
|
+
* It stays closed until `connect()` or `reconnect()` is called, or every hook unmounts. If
|
|
24
|
+
* nothing held it when it stopped, the next hook to mount starts it again.
|
|
25
|
+
*/
|
|
26
|
+
type Status = 'idle' | 'connecting' | 'open' | 'reconnecting' | 'closed';
|
|
27
|
+
/** The client's state as seen by React. A new object is created on every change. */
|
|
28
|
+
interface Snapshot<In> {
|
|
29
|
+
/** Connection state. */
|
|
30
|
+
readonly status: Status;
|
|
31
|
+
/** Most recent message (after `parse`/`json` and `schema`), kept across reconnects. */
|
|
32
|
+
readonly lastMessage: In | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Consecutive failed attempts since the last stable connection. A connection that closes
|
|
35
|
+
* within `reconnect.minUptime` of opening counts as failed. `0` while open.
|
|
36
|
+
*/
|
|
37
|
+
readonly attempt: number;
|
|
38
|
+
}
|
|
39
|
+
/** Details of a closed connection, from the browser's `CloseEvent`. */
|
|
40
|
+
interface CloseInfo {
|
|
41
|
+
/** Close code: `1000` is a normal close, `1006` an abnormal one (e.g. network loss), `4000`–`4999` are yours. */
|
|
42
|
+
readonly code: number;
|
|
43
|
+
/** Close reason sent by the side that closed the connection. Often empty. */
|
|
44
|
+
readonly reason: string;
|
|
45
|
+
/** Whether the closing handshake completed. */
|
|
46
|
+
readonly wasClean: boolean;
|
|
47
|
+
}
|
|
48
|
+
/** Options for `client.migrate()`. */
|
|
49
|
+
interface MigrateOptions {
|
|
50
|
+
/**
|
|
51
|
+
* Where to connect instead: a URL, or a function called before the connection, like the
|
|
52
|
+
* client's own `url`. Later reconnects go there too, until the client is closed, gives up or
|
|
53
|
+
* is torn down.
|
|
54
|
+
* @default the client's current URL
|
|
55
|
+
*/
|
|
56
|
+
url?: UrlSource;
|
|
57
|
+
/**
|
|
58
|
+
* Move at a random moment within this many ms, so that clients asked to move together don't
|
|
59
|
+
* all reconnect at once.
|
|
60
|
+
* @default 0
|
|
61
|
+
*/
|
|
62
|
+
within?: number;
|
|
63
|
+
}
|
|
64
|
+
/** Per-message options for `send()`. */
|
|
65
|
+
interface SendOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Drop the message instead of queueing it when the socket isn't open. For data that
|
|
68
|
+
* is stale by the time a reconnect finishes, such as player input or cursor positions.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
volatile?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Keep only the newest queued message with this key. Sending again with the same key
|
|
74
|
+
* while disconnected replaces the earlier one, which moves to the back of the queue
|
|
75
|
+
* (or of the `priority` messages, for a priority one).
|
|
76
|
+
* For state where only the latest value matters, such as "my position is now (x, y)".
|
|
77
|
+
*/
|
|
78
|
+
key?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Queue this message ahead of every message queued without `priority`, after earlier
|
|
81
|
+
* priority messages. For control messages that must not wait behind a backlog, such as
|
|
82
|
+
* cancel, interrupt or a token refresh. Messages sent from `open` listeners still go first.
|
|
83
|
+
*
|
|
84
|
+
* It only matters while the socket isn't open: once a message is handed to the browser,
|
|
85
|
+
* nothing can overtake it. To keep that buffer short, send bulky streams with `maxBuffered`.
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
priority?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Drop the message instead of sending it while more than this many bytes are already
|
|
91
|
+
* waiting in the browser's send buffer (`socket.bufferedAmount`). For high-rate streams on
|
|
92
|
+
* a slow link, such as audio frames or per-tick input, where a late message is worse than
|
|
93
|
+
* none. `send()` returns `false`, and `onDrop` isn't called.
|
|
94
|
+
*
|
|
95
|
+
* Only checked while the socket is open: a message queued while disconnected is sent on
|
|
96
|
+
* open regardless. `bufferedAmount` includes what you sent earlier in the same task, so set
|
|
97
|
+
* it well above one burst of messages.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* voice.send(frame, { volatile: true, maxBuffered: 64 * 1024 });
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
maxBuffered?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Drop the message instead of sending it if it has been queued for longer than this many
|
|
107
|
+
* ms, for messages that go stale during a long outage, such as "typing" or a price quote.
|
|
108
|
+
* Overrides `queue.maxAge`. Checked when the socket opens and whenever another message is
|
|
109
|
+
* queued; `onDrop` is called then.
|
|
110
|
+
*/
|
|
111
|
+
maxAge?: number;
|
|
112
|
+
/**
|
|
113
|
+
* Called if the message is dropped from the queue without being sent: replaced by a
|
|
114
|
+
* newer message with the same `key`, evicted by `queue.limit`, or older than `maxAge`. Not
|
|
115
|
+
* called when the queue is cleared because the client closed or gave up, or when `send()`
|
|
116
|
+
* drops the message right away (`volatile` while not open, or `maxBuffered`) and returns
|
|
117
|
+
* `false`.
|
|
118
|
+
*/
|
|
119
|
+
onDrop?: () => void;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Reported via the `error` event (and `onError`) when an incoming message can't be
|
|
123
|
+
* decoded by `parse`/`json` or fails `schema` validation. The message is not delivered.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* onError(error) {
|
|
128
|
+
* if (error instanceof MessageError) report(error.data, error.issues);
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare class MessageError extends Error {
|
|
133
|
+
/** The raw `event.data` that failed. */
|
|
134
|
+
readonly data: unknown;
|
|
135
|
+
/** Schema validation issues, when the message failed `schema`. */
|
|
136
|
+
readonly issues: ReadonlyArray<{
|
|
137
|
+
readonly message: string;
|
|
138
|
+
}> | undefined;
|
|
139
|
+
constructor(message: string, data: unknown, options?: {
|
|
140
|
+
cause?: unknown;
|
|
141
|
+
issues?: ReadonlyArray<{
|
|
142
|
+
readonly message: string;
|
|
143
|
+
}>;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/** Events emitted by a client. Subscribe with `client.on(type, listener)` or `useWebSocketEvent`. */
|
|
147
|
+
interface EventMap<In> {
|
|
148
|
+
/**
|
|
149
|
+
* The socket opened (initially or after a reconnect). Listeners run before queued
|
|
150
|
+
* messages are sent, so a handshake sent from here goes out first.
|
|
151
|
+
*/
|
|
152
|
+
open: (event: Event) => void;
|
|
153
|
+
/** A message arrived and passed `parse` and `schema`. */
|
|
154
|
+
message: (message: In, event: MessageEvent) => void;
|
|
155
|
+
/** A socket closed, whether it will be retried or not. */
|
|
156
|
+
close: (close: CloseInfo) => void;
|
|
157
|
+
/**
|
|
158
|
+
* A socket error `Event`, a {@link MessageError} for an undecodable or invalid message,
|
|
159
|
+
* or the `Error` thrown by the `WebSocket` constructor or a `url` function.
|
|
160
|
+
*/
|
|
161
|
+
error: (error: Event | MessageError | Error) => void;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* A WebSocket connection that reconnects, queues, decodes and can be shared.
|
|
165
|
+
* Create one with `createWebSocket()`.
|
|
166
|
+
*
|
|
167
|
+
* The connection is reference-counted: it opens when the first hook mounts (or
|
|
168
|
+
* `ready` is read) and closes one tick after the last hook unmounts. Calling
|
|
169
|
+
* `connect()` keeps it open regardless, until `close()`.
|
|
170
|
+
*
|
|
171
|
+
* @typeParam In - Type of incoming messages.
|
|
172
|
+
* @typeParam Out - Type accepted by `send()`.
|
|
173
|
+
*/
|
|
174
|
+
interface WebSocketClient<In = unknown, Out = unknown> {
|
|
175
|
+
/** The URL (or URL function) the client was created with. */
|
|
176
|
+
readonly url: UrlSource;
|
|
177
|
+
/**
|
|
178
|
+
* A promise that resolves once the socket has opened. Reading it starts an idle client.
|
|
179
|
+
*
|
|
180
|
+
* It stays resolved through automatic reconnects, so `use(client.ready)` shows a
|
|
181
|
+
* Suspense fallback only for the first connection, never on a network blip; use
|
|
182
|
+
* `status` to show reconnects. It rejects when the client gives up reconnecting, when
|
|
183
|
+
* `close()` is called, and during a server render. After that, `connect()` or
|
|
184
|
+
* `reconnect()` make it a new pending promise.
|
|
185
|
+
*
|
|
186
|
+
* It is safe to pass to React 19's `use()`: the same promise is returned until its state
|
|
187
|
+
* changes, and it carries `status`/`value`/`reason` so `use()` doesn't suspend when it is
|
|
188
|
+
* already settled.
|
|
189
|
+
*/
|
|
190
|
+
readonly ready: Promise<void>;
|
|
191
|
+
/** The current underlying `WebSocket`, if any. An escape hatch; prefer the client's methods. */
|
|
192
|
+
readonly socket: WebSocket | null;
|
|
193
|
+
/** Subscribe to snapshot changes. Compatible with `useSyncExternalStore`. Returns an unsubscribe function. */
|
|
194
|
+
subscribe(listener: () => void): () => void;
|
|
195
|
+
/** The current {@link Snapshot}. Returns the same object until something changes. */
|
|
196
|
+
getSnapshot(): Snapshot<In>;
|
|
197
|
+
/**
|
|
198
|
+
* Listen to an event. Returns an unsubscribe function. Listener errors are re-thrown
|
|
199
|
+
* asynchronously, so one failing listener doesn't break the others.
|
|
200
|
+
*/
|
|
201
|
+
on<K extends keyof EventMap<In>>(type: K, listener: EventMap<In>[K]): () => void;
|
|
202
|
+
/**
|
|
203
|
+
* Send a message (encoded with `serialize`/`json` if configured). If the socket isn't
|
|
204
|
+
* open, the message is queued and sent on open (see the `queue` option), unless
|
|
205
|
+
* `options.volatile` is set.
|
|
206
|
+
* @returns `true` if it was sent immediately, `false` if it was queued or dropped
|
|
207
|
+
* (`volatile` while not open, or `maxBuffered` while open).
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* game.send({ type: 'input', dx, dy }, { volatile: true }); // never replayed after a reconnect
|
|
212
|
+
* game.send({ type: 'position', x, y }, { key: 'position' }); // only the newest is queued
|
|
213
|
+
* game.send({ type: 'leave' }, { priority: true }); // ahead of everything already queued
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
send(message: Out, options?: SendOptions): boolean;
|
|
217
|
+
/**
|
|
218
|
+
* Start connecting, and keep the connection open even when no hook is using the
|
|
219
|
+
* client, until `close()` is called. Does nothing if already connecting or open.
|
|
220
|
+
*/
|
|
221
|
+
connect(): void;
|
|
222
|
+
/**
|
|
223
|
+
* Close the connection and stop reconnecting. The status becomes `closed` and the
|
|
224
|
+
* send queue is cleared. Mounted hooks stay mounted; call `connect()` or `reconnect()`
|
|
225
|
+
* to start again. Closed while no hook holds it, the next hook to mount starts it again.
|
|
226
|
+
*
|
|
227
|
+
* Like `WebSocket.close()`, it throws for a code or reason the socket rejects (browsers take
|
|
228
|
+
* `1000` or `3000`–`4999`, and a reason up to 123 bytes), and then nothing has changed.
|
|
229
|
+
* @param code - Close code. @default 1000
|
|
230
|
+
*/
|
|
231
|
+
close(code?: number, reason?: string): void;
|
|
232
|
+
/**
|
|
233
|
+
* Drop the current socket (if any) and connect again immediately, resetting the
|
|
234
|
+
* backoff. Also restarts a `closed` client.
|
|
235
|
+
*/
|
|
236
|
+
reconnect(): void;
|
|
237
|
+
/**
|
|
238
|
+
* Move to a new connection without a gap, for example when the server asks its clients to
|
|
239
|
+
* before a deploy. At a random moment within `options.within` ms, it opens a new connection
|
|
240
|
+
* (to `options.url`, if given) and, once that one is open, closes the current one with code
|
|
241
|
+
* `1000`. Until then the current connection keeps working, so the status stays `open` and
|
|
242
|
+
* `send()` doesn't queue.
|
|
243
|
+
*
|
|
244
|
+
* `open` listeners run for the new connection, as after any reconnect, so handshakes and
|
|
245
|
+
* topic subscriptions are sent again. Requests the old connection hadn't answered fail as on
|
|
246
|
+
* a lost connection. If the new connection fails before opening, the current one stays. If
|
|
247
|
+
* the client isn't open when the moment comes, only the URL changes, for the next attempt.
|
|
248
|
+
* A later call replaces one that hasn't moved yet.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* // The server sends { type: 'reconnect', within: 30000 } before it shuts down.
|
|
253
|
+
* live.on('message', message => {
|
|
254
|
+
* if (message.type === 'reconnect') live.migrate({ within: message.within, url: message.url });
|
|
255
|
+
* });
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
migrate(options?: MigrateOptions): void;
|
|
259
|
+
/**
|
|
260
|
+
* Hold the connection open until the returned function is called. This is what the
|
|
261
|
+
* hooks use; call it yourself to integrate with non-React code.
|
|
262
|
+
* @returns A release function (safe to call more than once).
|
|
263
|
+
*/
|
|
264
|
+
acquire(): () => void;
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/runs.d.ts
|
|
268
|
+
/**
|
|
269
|
+
* What happens to a run when its connection drops: `keep` resumes it on the next connection,
|
|
270
|
+
* for agents that keep working in the background; `cancel` aborts it and tells the server, for
|
|
271
|
+
* a chat answer nobody may be waiting for.
|
|
272
|
+
*/
|
|
273
|
+
type RunPolicy = 'keep' | 'cancel';
|
|
274
|
+
/** Where a run is: streaming events, or ended. */
|
|
275
|
+
type RunStatus = 'streaming' | 'done' | 'error' | 'aborted';
|
|
276
|
+
/** A run's state, reduced from its events. A new object on every change. */
|
|
277
|
+
interface AgentRun<T> {
|
|
278
|
+
readonly runId: string;
|
|
279
|
+
readonly status: RunStatus;
|
|
280
|
+
/** Reduced from the run's events with `reduce`, starting from `initial`. */
|
|
281
|
+
readonly value: T;
|
|
282
|
+
/** What `error` returned for the event that ended the run, when `status` is `'error'`. */
|
|
283
|
+
readonly error: unknown;
|
|
284
|
+
}
|
|
285
|
+
/** The subset of `Storage` that runs use, so `sessionStorage`, `localStorage` or your own fits. */
|
|
286
|
+
type RunStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
|
|
287
|
+
/** Runs that stream events and survive reconnects and reloads. Create with {@link createWebSocketRuns}. */
|
|
288
|
+
interface WebSocketRuns<Req, T> {
|
|
289
|
+
/** The client the runs stream on. */
|
|
290
|
+
readonly client: WebSocketClient<any, any>;
|
|
291
|
+
/**
|
|
292
|
+
* Start a run and return its `runId`. The start message is sent as soon as the socket is
|
|
293
|
+
* open, and the run is remembered until it ends. `initial` overrides the `initial` option for
|
|
294
|
+
* this run. A `runId` it already knows, streaming or ended, starts nothing: the server starts
|
|
295
|
+
* a run only once per id. `delete()` it first to use the id again.
|
|
296
|
+
*/
|
|
297
|
+
start(request: Req, options?: {
|
|
298
|
+
runId?: string;
|
|
299
|
+
policy?: RunPolicy;
|
|
300
|
+
initial?: T;
|
|
301
|
+
}): string;
|
|
302
|
+
/**
|
|
303
|
+
* Follow a run started elsewhere, such as in another tab or before a reload, from its first
|
|
304
|
+
* event. Does nothing for a run it already knows.
|
|
305
|
+
*/
|
|
306
|
+
attach(runId: string, options?: {
|
|
307
|
+
policy?: RunPolicy;
|
|
308
|
+
initial?: T;
|
|
309
|
+
}): void;
|
|
310
|
+
/** Stop a streaming run: send `cancel`, and make it `'aborted'`. */
|
|
311
|
+
abort(runId: string): void;
|
|
312
|
+
/** A run's state, or `undefined` for one it doesn't know. The same object until it changes. */
|
|
313
|
+
get(runId: string): AgentRun<T> | undefined;
|
|
314
|
+
/** Every run it knows, oldest first. A new array on every change. */
|
|
315
|
+
list(): readonly AgentRun<T>[];
|
|
316
|
+
/** Get notified when a run changes. Compatible with `useSyncExternalStore`. */
|
|
317
|
+
subscribe(listener: () => void): () => void;
|
|
318
|
+
/** Forget a run, aborting it first if it's streaming. */
|
|
319
|
+
delete(runId: string): void;
|
|
320
|
+
/** Stop following runs, and release the connection. Remembered runs stay remembered. */
|
|
321
|
+
dispose(): void;
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/ag-ui.d.ts
|
|
325
|
+
/** A JSON Patch (RFC 6902) operation, as in AG-UI's `STATE_DELTA` and `ACTIVITY_DELTA`. */
|
|
326
|
+
export interface JsonPatchOperation {
|
|
327
|
+
readonly op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';
|
|
328
|
+
/** A JSON Pointer (RFC 6901), such as `/items/0/name`. */
|
|
329
|
+
readonly path: string;
|
|
330
|
+
/** The source of `move` and `copy`. */
|
|
331
|
+
readonly from?: string;
|
|
332
|
+
/** The value to `add`, `replace` with or `test` for. */
|
|
333
|
+
readonly value?: unknown;
|
|
334
|
+
}
|
|
335
|
+
/** An AG-UI event: `type` is `'RUN_STARTED'`, `'TEXT_MESSAGE_CONTENT'`, `'STATE_DELTA'`, … */
|
|
336
|
+
export interface AgUiEvent {
|
|
337
|
+
readonly type: string;
|
|
338
|
+
readonly [field: string]: any;
|
|
339
|
+
}
|
|
340
|
+
/** A tool call on an assistant message, as in AG-UI. */
|
|
341
|
+
export interface AgUiToolCall {
|
|
342
|
+
readonly id: string;
|
|
343
|
+
readonly type: 'function';
|
|
344
|
+
readonly function: {
|
|
345
|
+
readonly name: string;
|
|
346
|
+
readonly arguments: string;
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
/** A message in an AG-UI thread. */
|
|
350
|
+
export interface AgUiMessage {
|
|
351
|
+
readonly id: string;
|
|
352
|
+
readonly role: 'developer' | 'system' | 'assistant' | 'user' | 'tool' | 'reasoning' | 'activity';
|
|
353
|
+
readonly content?: unknown;
|
|
354
|
+
readonly toolCalls?: readonly AgUiToolCall[];
|
|
355
|
+
/** For a `tool` message, the call it answers. */
|
|
356
|
+
readonly toolCallId?: string;
|
|
357
|
+
/** For an `activity` message. */
|
|
358
|
+
readonly activityType?: string;
|
|
359
|
+
readonly [field: string]: unknown;
|
|
360
|
+
}
|
|
361
|
+
/** AG-UI's `RunAgentInput`: what a run starts from. */
|
|
362
|
+
export interface RunAgentInput {
|
|
363
|
+
readonly threadId: string;
|
|
364
|
+
readonly runId: string;
|
|
365
|
+
readonly parentRunId?: string;
|
|
366
|
+
readonly state?: unknown;
|
|
367
|
+
readonly messages: readonly AgUiMessage[];
|
|
368
|
+
readonly tools: readonly unknown[];
|
|
369
|
+
readonly context: readonly unknown[];
|
|
370
|
+
readonly forwardedProps: unknown;
|
|
371
|
+
}
|
|
372
|
+
/** A thread's messages and shared state, reduced from AG-UI events. */
|
|
373
|
+
export interface AgUiThread<S = unknown> {
|
|
374
|
+
readonly messages: readonly AgUiMessage[];
|
|
375
|
+
/** The shared state, from `STATE_SNAPSHOT` and `STATE_DELTA`. */
|
|
376
|
+
readonly state: S;
|
|
377
|
+
/**
|
|
378
|
+
* `'running'` from `RUN_STARTED`, `'finished'` after `RUN_FINISHED`, `'error'` after
|
|
379
|
+
* `RUN_ERROR`, `'aborted'` when the run was stopped from this side.
|
|
380
|
+
*/
|
|
381
|
+
readonly status: 'idle' | 'running' | 'finished' | 'error' | 'aborted';
|
|
382
|
+
/** The step in progress, between `STEP_STARTED` and `STEP_FINISHED`. */
|
|
383
|
+
readonly step?: string;
|
|
384
|
+
/** From `RUN_ERROR`. */
|
|
385
|
+
readonly error?: {
|
|
386
|
+
readonly message: string;
|
|
387
|
+
readonly code?: string;
|
|
388
|
+
};
|
|
389
|
+
/** From `RUN_FINISHED`. */
|
|
390
|
+
readonly result?: unknown;
|
|
391
|
+
/**
|
|
392
|
+
* A `STATE_DELTA` couldn't be applied. `state` is the last good one, and later deltas are
|
|
393
|
+
* skipped until a `STATE_SNAPSHOT` arrives.
|
|
394
|
+
*/
|
|
395
|
+
readonly stale: boolean;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Apply a JSON Patch (RFC 6902) without changing `document`: what changes is copied, the rest is
|
|
399
|
+
* shared. Throws, leaving `document` as it was, if an operation can't be applied: a missing path,
|
|
400
|
+
* an index out of range, a pointer that doesn't start with `/`, or a failed `test`.
|
|
401
|
+
*/
|
|
402
|
+
export declare function applyPatch<T>(document: T, operations: readonly JsonPatchOperation[]): T;
|
|
403
|
+
/**
|
|
404
|
+
* Fold one AG-UI event into a thread, without changing it. Handles the run lifecycle, steps,
|
|
405
|
+
* text, tool calls and their results, reasoning, activity, and message and state snapshots and
|
|
406
|
+
* deltas. A `STATE_DELTA` that can't be applied marks the thread `stale` instead of throwing.
|
|
407
|
+
* Other events, such as `CUSTOM` and `RAW`, return the thread unchanged.
|
|
408
|
+
*
|
|
409
|
+
* Use it as a `reduce` function, or wrap it to handle events of your own.
|
|
410
|
+
*/
|
|
411
|
+
export declare function applyAgUiEvent<S>(thread: AgUiThread<S>, event: AgUiEvent): AgUiThread<S>;
|
|
412
|
+
/** What the server sends for each event of a run: its run, its offset (from 1), and the event. */
|
|
413
|
+
export interface AgUiEnvelope {
|
|
414
|
+
readonly runId: string;
|
|
415
|
+
readonly offset: number;
|
|
416
|
+
readonly event: AgUiEvent;
|
|
417
|
+
}
|
|
418
|
+
/** Options for {@link createAgUiAgent}. The message formats have defaults; see the guide. */
|
|
419
|
+
export interface AgUiAgentOptions<S, In, Out> {
|
|
420
|
+
/** The thread's id, sent in every `RunAgentInput`. A new random one by default. */
|
|
421
|
+
threadId?: string;
|
|
422
|
+
/** The shared state before the first `STATE_SNAPSHOT`, sent with the first run. */
|
|
423
|
+
state?: S;
|
|
424
|
+
/** Names where streaming runs are remembered across reloads. @default 'ag-ui' */
|
|
425
|
+
name?: string;
|
|
426
|
+
/** @default `{ type: 'run', runId, input }` */
|
|
427
|
+
run?: (input: RunAgentInput, runId: string) => Out;
|
|
428
|
+
/** @default `{ type: 'resume', runId, after }` */
|
|
429
|
+
resume?: (runId: string, after: number | undefined) => Out;
|
|
430
|
+
/** @default `{ type: 'cancel', runId }` */
|
|
431
|
+
cancel?: (runId: string) => Out;
|
|
432
|
+
/**
|
|
433
|
+
* The message that asks the server for a `STATE_SNAPSHOT`, sent when a `STATE_DELTA` can't
|
|
434
|
+
* be applied. Without it, the state stays `stale` until the server sends one by itself.
|
|
435
|
+
*/
|
|
436
|
+
resync?: (runId: string) => Out;
|
|
437
|
+
/** Recognize a run's event. @default messages shaped like {@link AgUiEnvelope} */
|
|
438
|
+
event?: (message: In) => AgUiEnvelope | null | undefined;
|
|
439
|
+
/** What happens to a run when its connection drops. @default 'keep' */
|
|
440
|
+
policy?: RunPolicy;
|
|
441
|
+
/** Where streaming runs are remembered. @default sessionStorage */
|
|
442
|
+
storage?: RunStorage | null;
|
|
443
|
+
}
|
|
444
|
+
/** An AG-UI agent over a WebSocket. Create with {@link createAgUiAgent}. */
|
|
445
|
+
export interface AgUiAgent<S> {
|
|
446
|
+
/** The client the runs stream on. */
|
|
447
|
+
readonly client: WebSocketClient<any, any>;
|
|
448
|
+
/** The runs underneath, from `createWebSocketRuns`. */
|
|
449
|
+
readonly runs: WebSocketRuns<RunAgentInput, AgUiThread<S>>;
|
|
450
|
+
/**
|
|
451
|
+
* Start a run with the thread so far plus `input.messages`, which show up in the thread right
|
|
452
|
+
* away. A run that's still streaming is aborted first. Returns the run's id.
|
|
453
|
+
*/
|
|
454
|
+
run(input?: {
|
|
455
|
+
messages?: readonly AgUiMessage[];
|
|
456
|
+
tools?: readonly unknown[];
|
|
457
|
+
context?: readonly unknown[];
|
|
458
|
+
forwardedProps?: unknown;
|
|
459
|
+
}, options?: {
|
|
460
|
+
policy?: RunPolicy;
|
|
461
|
+
}): string;
|
|
462
|
+
/** Stop the run that's streaming, if any. */
|
|
463
|
+
abort(): void;
|
|
464
|
+
/** The thread as of the latest run. The same object until it changes. */
|
|
465
|
+
getSnapshot(): AgUiThread<S>;
|
|
466
|
+
/** Get notified when the thread changes. Compatible with `useSyncExternalStore`. */
|
|
467
|
+
subscribe(listener: () => void): () => void;
|
|
468
|
+
/** Stop following runs, and release the connection. */
|
|
469
|
+
dispose(): void;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Run an [AG-UI](https://docs.ag-ui.com) agent over a WebSocket. Each run streams AG-UI events,
|
|
473
|
+
* which are folded into the thread's messages and shared state with {@link applyAgUiEvent}.
|
|
474
|
+
* Runs come from `createWebSocketRuns`, so they resume after a reconnect or a reload, and a
|
|
475
|
+
* state delta that can't be applied asks for a snapshot (`resync`).
|
|
476
|
+
*
|
|
477
|
+
* AG-UI doesn't define messages for WebSockets, so the defaults are small: the client sends
|
|
478
|
+
* `{ type: 'run', runId, input }`, `{ type: 'resume', runId, after }` and
|
|
479
|
+
* `{ type: 'cancel', runId }`, and the server sends `{ runId, offset, event }`, with `offset`
|
|
480
|
+
* counting each run's events from 1. Each option replaces one of them.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```ts
|
|
484
|
+
* import { createAgUiAgent } from 'react-websocket/ag-ui';
|
|
485
|
+
*
|
|
486
|
+
* export const agent = createAgUiAgent(createWebSocket(url, { json: true }));
|
|
487
|
+
*
|
|
488
|
+
* agent.run({ messages: [{ id: crypto.randomUUID(), role: 'user', content: 'Plan my week' }] });
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
export declare function createAgUiAgent<S = unknown, In = any, Out = any>(client: WebSocketClient<In, Out>, options?: AgUiAgentOptions<S, NoInfer<In>, NoInfer<Out>>): AgUiAgent<S>;
|
|
492
|
+
//#endregion
|
|
493
|
+
//# sourceMappingURL=ag-ui.d.cts.map
|
package/dist/ag-ui.d.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { RunPolicy, RunStorage, WebSocketClient, WebSocketRuns } from "./core.js";
|
|
2
|
+
//#region src/ag-ui.d.ts
|
|
3
|
+
/** A JSON Patch (RFC 6902) operation, as in AG-UI's `STATE_DELTA` and `ACTIVITY_DELTA`. */
|
|
4
|
+
export interface JsonPatchOperation {
|
|
5
|
+
readonly op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';
|
|
6
|
+
/** A JSON Pointer (RFC 6901), such as `/items/0/name`. */
|
|
7
|
+
readonly path: string;
|
|
8
|
+
/** The source of `move` and `copy`. */
|
|
9
|
+
readonly from?: string;
|
|
10
|
+
/** The value to `add`, `replace` with or `test` for. */
|
|
11
|
+
readonly value?: unknown;
|
|
12
|
+
}
|
|
13
|
+
/** An AG-UI event: `type` is `'RUN_STARTED'`, `'TEXT_MESSAGE_CONTENT'`, `'STATE_DELTA'`, … */
|
|
14
|
+
export interface AgUiEvent {
|
|
15
|
+
readonly type: string;
|
|
16
|
+
readonly [field: string]: any;
|
|
17
|
+
}
|
|
18
|
+
/** A tool call on an assistant message, as in AG-UI. */
|
|
19
|
+
export interface AgUiToolCall {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly type: 'function';
|
|
22
|
+
readonly function: {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly arguments: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** A message in an AG-UI thread. */
|
|
28
|
+
export interface AgUiMessage {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly role: 'developer' | 'system' | 'assistant' | 'user' | 'tool' | 'reasoning' | 'activity';
|
|
31
|
+
readonly content?: unknown;
|
|
32
|
+
readonly toolCalls?: readonly AgUiToolCall[];
|
|
33
|
+
/** For a `tool` message, the call it answers. */
|
|
34
|
+
readonly toolCallId?: string;
|
|
35
|
+
/** For an `activity` message. */
|
|
36
|
+
readonly activityType?: string;
|
|
37
|
+
readonly [field: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
/** AG-UI's `RunAgentInput`: what a run starts from. */
|
|
40
|
+
export interface RunAgentInput {
|
|
41
|
+
readonly threadId: string;
|
|
42
|
+
readonly runId: string;
|
|
43
|
+
readonly parentRunId?: string;
|
|
44
|
+
readonly state?: unknown;
|
|
45
|
+
readonly messages: readonly AgUiMessage[];
|
|
46
|
+
readonly tools: readonly unknown[];
|
|
47
|
+
readonly context: readonly unknown[];
|
|
48
|
+
readonly forwardedProps: unknown;
|
|
49
|
+
}
|
|
50
|
+
/** A thread's messages and shared state, reduced from AG-UI events. */
|
|
51
|
+
export interface AgUiThread<S = unknown> {
|
|
52
|
+
readonly messages: readonly AgUiMessage[];
|
|
53
|
+
/** The shared state, from `STATE_SNAPSHOT` and `STATE_DELTA`. */
|
|
54
|
+
readonly state: S;
|
|
55
|
+
/**
|
|
56
|
+
* `'running'` from `RUN_STARTED`, `'finished'` after `RUN_FINISHED`, `'error'` after
|
|
57
|
+
* `RUN_ERROR`, `'aborted'` when the run was stopped from this side.
|
|
58
|
+
*/
|
|
59
|
+
readonly status: 'idle' | 'running' | 'finished' | 'error' | 'aborted';
|
|
60
|
+
/** The step in progress, between `STEP_STARTED` and `STEP_FINISHED`. */
|
|
61
|
+
readonly step?: string;
|
|
62
|
+
/** From `RUN_ERROR`. */
|
|
63
|
+
readonly error?: {
|
|
64
|
+
readonly message: string;
|
|
65
|
+
readonly code?: string;
|
|
66
|
+
};
|
|
67
|
+
/** From `RUN_FINISHED`. */
|
|
68
|
+
readonly result?: unknown;
|
|
69
|
+
/**
|
|
70
|
+
* A `STATE_DELTA` couldn't be applied. `state` is the last good one, and later deltas are
|
|
71
|
+
* skipped until a `STATE_SNAPSHOT` arrives.
|
|
72
|
+
*/
|
|
73
|
+
readonly stale: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Apply a JSON Patch (RFC 6902) without changing `document`: what changes is copied, the rest is
|
|
77
|
+
* shared. Throws, leaving `document` as it was, if an operation can't be applied: a missing path,
|
|
78
|
+
* an index out of range, a pointer that doesn't start with `/`, or a failed `test`.
|
|
79
|
+
*/
|
|
80
|
+
export declare function applyPatch<T>(document: T, operations: readonly JsonPatchOperation[]): T;
|
|
81
|
+
/**
|
|
82
|
+
* Fold one AG-UI event into a thread, without changing it. Handles the run lifecycle, steps,
|
|
83
|
+
* text, tool calls and their results, reasoning, activity, and message and state snapshots and
|
|
84
|
+
* deltas. A `STATE_DELTA` that can't be applied marks the thread `stale` instead of throwing.
|
|
85
|
+
* Other events, such as `CUSTOM` and `RAW`, return the thread unchanged.
|
|
86
|
+
*
|
|
87
|
+
* Use it as a `reduce` function, or wrap it to handle events of your own.
|
|
88
|
+
*/
|
|
89
|
+
export declare function applyAgUiEvent<S>(thread: AgUiThread<S>, event: AgUiEvent): AgUiThread<S>;
|
|
90
|
+
/** What the server sends for each event of a run: its run, its offset (from 1), and the event. */
|
|
91
|
+
export interface AgUiEnvelope {
|
|
92
|
+
readonly runId: string;
|
|
93
|
+
readonly offset: number;
|
|
94
|
+
readonly event: AgUiEvent;
|
|
95
|
+
}
|
|
96
|
+
/** Options for {@link createAgUiAgent}. The message formats have defaults; see the guide. */
|
|
97
|
+
export interface AgUiAgentOptions<S, In, Out> {
|
|
98
|
+
/** The thread's id, sent in every `RunAgentInput`. A new random one by default. */
|
|
99
|
+
threadId?: string;
|
|
100
|
+
/** The shared state before the first `STATE_SNAPSHOT`, sent with the first run. */
|
|
101
|
+
state?: S;
|
|
102
|
+
/** Names where streaming runs are remembered across reloads. @default 'ag-ui' */
|
|
103
|
+
name?: string;
|
|
104
|
+
/** @default `{ type: 'run', runId, input }` */
|
|
105
|
+
run?: (input: RunAgentInput, runId: string) => Out;
|
|
106
|
+
/** @default `{ type: 'resume', runId, after }` */
|
|
107
|
+
resume?: (runId: string, after: number | undefined) => Out;
|
|
108
|
+
/** @default `{ type: 'cancel', runId }` */
|
|
109
|
+
cancel?: (runId: string) => Out;
|
|
110
|
+
/**
|
|
111
|
+
* The message that asks the server for a `STATE_SNAPSHOT`, sent when a `STATE_DELTA` can't
|
|
112
|
+
* be applied. Without it, the state stays `stale` until the server sends one by itself.
|
|
113
|
+
*/
|
|
114
|
+
resync?: (runId: string) => Out;
|
|
115
|
+
/** Recognize a run's event. @default messages shaped like {@link AgUiEnvelope} */
|
|
116
|
+
event?: (message: In) => AgUiEnvelope | null | undefined;
|
|
117
|
+
/** What happens to a run when its connection drops. @default 'keep' */
|
|
118
|
+
policy?: RunPolicy;
|
|
119
|
+
/** Where streaming runs are remembered. @default sessionStorage */
|
|
120
|
+
storage?: RunStorage | null;
|
|
121
|
+
}
|
|
122
|
+
/** An AG-UI agent over a WebSocket. Create with {@link createAgUiAgent}. */
|
|
123
|
+
export interface AgUiAgent<S> {
|
|
124
|
+
/** The client the runs stream on. */
|
|
125
|
+
readonly client: WebSocketClient<any, any>;
|
|
126
|
+
/** The runs underneath, from `createWebSocketRuns`. */
|
|
127
|
+
readonly runs: WebSocketRuns<RunAgentInput, AgUiThread<S>>;
|
|
128
|
+
/**
|
|
129
|
+
* Start a run with the thread so far plus `input.messages`, which show up in the thread right
|
|
130
|
+
* away. A run that's still streaming is aborted first. Returns the run's id.
|
|
131
|
+
*/
|
|
132
|
+
run(input?: {
|
|
133
|
+
messages?: readonly AgUiMessage[];
|
|
134
|
+
tools?: readonly unknown[];
|
|
135
|
+
context?: readonly unknown[];
|
|
136
|
+
forwardedProps?: unknown;
|
|
137
|
+
}, options?: {
|
|
138
|
+
policy?: RunPolicy;
|
|
139
|
+
}): string;
|
|
140
|
+
/** Stop the run that's streaming, if any. */
|
|
141
|
+
abort(): void;
|
|
142
|
+
/** The thread as of the latest run. The same object until it changes. */
|
|
143
|
+
getSnapshot(): AgUiThread<S>;
|
|
144
|
+
/** Get notified when the thread changes. Compatible with `useSyncExternalStore`. */
|
|
145
|
+
subscribe(listener: () => void): () => void;
|
|
146
|
+
/** Stop following runs, and release the connection. */
|
|
147
|
+
dispose(): void;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Run an [AG-UI](https://docs.ag-ui.com) agent over a WebSocket. Each run streams AG-UI events,
|
|
151
|
+
* which are folded into the thread's messages and shared state with {@link applyAgUiEvent}.
|
|
152
|
+
* Runs come from `createWebSocketRuns`, so they resume after a reconnect or a reload, and a
|
|
153
|
+
* state delta that can't be applied asks for a snapshot (`resync`).
|
|
154
|
+
*
|
|
155
|
+
* AG-UI doesn't define messages for WebSockets, so the defaults are small: the client sends
|
|
156
|
+
* `{ type: 'run', runId, input }`, `{ type: 'resume', runId, after }` and
|
|
157
|
+
* `{ type: 'cancel', runId }`, and the server sends `{ runId, offset, event }`, with `offset`
|
|
158
|
+
* counting each run's events from 1. Each option replaces one of them.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* import { createAgUiAgent } from 'react-websocket/ag-ui';
|
|
163
|
+
*
|
|
164
|
+
* export const agent = createAgUiAgent(createWebSocket(url, { json: true }));
|
|
165
|
+
*
|
|
166
|
+
* agent.run({ messages: [{ id: crypto.randomUUID(), role: 'user', content: 'Plan my week' }] });
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export declare function createAgUiAgent<S = unknown, In = any, Out = any>(client: WebSocketClient<In, Out>, options?: AgUiAgentOptions<S, NoInfer<In>, NoInfer<Out>>): AgUiAgent<S>;
|
|
170
|
+
//#endregion
|
|
171
|
+
//# sourceMappingURL=ag-ui.d.ts.map
|