@alexkroman1/aai-ui 0.12.2 → 1.0.2

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.
Files changed (68) hide show
  1. package/dist/_react-test-utils.d.ts +86 -0
  2. package/dist/audio.js +4 -5
  3. package/dist/build-default-client.d.ts +1 -0
  4. package/dist/{_components → components}/button.d.ts +4 -4
  5. package/dist/{_components → components}/button.js +28 -5
  6. package/dist/components/chat-view.d.ts +38 -0
  7. package/dist/components/chat-view.js +102 -0
  8. package/dist/{_components → components}/controls.d.ts +1 -1
  9. package/dist/{_components → components}/controls.js +8 -5
  10. package/dist/{_components → components}/message-list.d.ts +2 -2
  11. package/dist/components/message-list.js +149 -0
  12. package/dist/components/sidebar-layout.d.ts +21 -0
  13. package/dist/components/sidebar-layout.js +43 -0
  14. package/dist/{_components → components}/start-screen.d.ts +4 -4
  15. package/dist/{_components → components}/start-screen.js +17 -8
  16. package/dist/{_components → components}/tool-call-block.d.ts +5 -6
  17. package/dist/components/tool-call-block.js +3 -0
  18. package/dist/components/tool-config-context.d.ts +22 -0
  19. package/dist/context.d.ts +23 -0
  20. package/dist/context.js +39 -0
  21. package/dist/default-client/assets/audio-DH9LpexG.js +1 -0
  22. package/dist/default-client/assets/capture-processor-C26lSiVr.js +53 -0
  23. package/dist/default-client/assets/default-client-AeJhjHfj.js +49 -0
  24. package/dist/default-client/assets/default-client-BK1ItCvw.css +2 -0
  25. package/dist/default-client/assets/playback-processor-dSA8Im99.js +101 -0
  26. package/dist/default-client/default-client.html +15 -0
  27. package/dist/default-client.d.ts +2 -0
  28. package/dist/define-client.d.ts +72 -24
  29. package/dist/define-client.js +71 -45
  30. package/dist/hooks.d.ts +5 -0
  31. package/dist/hooks.js +55 -0
  32. package/dist/index.d.ts +15 -37
  33. package/dist/index.js +11 -18
  34. package/dist/session-core.d.ts +70 -0
  35. package/dist/session-core.js +437 -0
  36. package/dist/tool-call-block-CCuChsFm.js +131 -0
  37. package/dist/types.d.ts +19 -22
  38. package/package.json +24 -18
  39. package/styles.css +3 -33
  40. package/dist/_components/app.d.ts +0 -23
  41. package/dist/_components/app.js +0 -41
  42. package/dist/_components/chat-view.d.ts +0 -29
  43. package/dist/_components/chat-view.js +0 -61
  44. package/dist/_components/error-banner.d.ts +0 -21
  45. package/dist/_components/error-banner.js +0 -27
  46. package/dist/_components/message-bubble.d.ts +0 -23
  47. package/dist/_components/message-bubble.js +0 -35
  48. package/dist/_components/message-list.js +0 -76
  49. package/dist/_components/sidebar-layout.d.ts +0 -21
  50. package/dist/_components/sidebar-layout.js +0 -36
  51. package/dist/_components/state-indicator.d.ts +0 -29
  52. package/dist/_components/state-indicator.js +0 -37
  53. package/dist/_components/thinking-indicator.d.ts +0 -16
  54. package/dist/_components/thinking-indicator.js +0 -34
  55. package/dist/_components/tool-call-block.js +0 -118
  56. package/dist/_components/tool-icons.d.ts +0 -17
  57. package/dist/_components/tool-icons.js +0 -128
  58. package/dist/_components/transcript.d.ts +0 -25
  59. package/dist/_components/transcript.js +0 -35
  60. package/dist/client-context.d.ts +0 -33
  61. package/dist/client-context.js +0 -15
  62. package/dist/client-handler.d.ts +0 -43
  63. package/dist/session-CWB7vmqz.js +0 -429
  64. package/dist/session.d.ts +0 -69
  65. package/dist/session.js +0 -2
  66. package/dist/signals.d.ts +0 -120
  67. package/dist/signals.js +0 -161
  68. package/dist/types.test-d.d.ts +0 -7
@@ -1,429 +0,0 @@
1
- import { errorMessage } from "@alexkroman1/aai/utils";
2
- import { ReadyConfigSchema, ServerMessageSchema } from "@alexkroman1/aai/protocol";
3
- //#region client-handler.ts
4
- /**
5
- * Handles server→client messages and updates reactive Preact signals
6
- * accordingly (state transitions, transcripts, messages, audio playback).
7
- *
8
- * @internal Exported for testing only.
9
- */
10
- var ClientHandler = class {
11
- #state;
12
- #messages;
13
- #toolCalls;
14
- #userUtterance;
15
- #agentUtterance;
16
- #error;
17
- #voiceIO;
18
- #batch;
19
- /** Incremented on each turn boundary — stale async callbacks compare against this. */
20
- #generation = 0;
21
- /** Accumulated chat_delta text for real-time display. */
22
- #deltaAccum = "";
23
- constructor(opts) {
24
- this.#state = opts.state;
25
- this.#messages = opts.messages;
26
- this.#toolCalls = opts.toolCalls;
27
- this.#userUtterance = opts.userUtterance;
28
- this.#agentUtterance = opts.agentUtterance;
29
- this.#error = opts.error;
30
- this.#voiceIO = opts.voiceIO;
31
- this.#batch = opts.batch;
32
- }
33
- /** Single entry point for all server→client session events. */
34
- event(e) {
35
- switch (e.type) {
36
- case "speech_started":
37
- this.#userUtterance.value = "";
38
- break;
39
- case "speech_stopped": break;
40
- case "transcript":
41
- this.#userUtterance.value = e.text;
42
- break;
43
- case "turn":
44
- this.#generation++;
45
- this.#deltaAccum = "";
46
- this.#batch(() => {
47
- this.#userUtterance.value = null;
48
- this.#messages.value = [...this.#messages.value, {
49
- role: "user",
50
- content: e.text
51
- }];
52
- this.#state.value = "thinking";
53
- });
54
- break;
55
- case "chat_delta":
56
- this.#deltaAccum += (this.#deltaAccum ? " " : "") + e.text;
57
- this.#agentUtterance.value = this.#deltaAccum;
58
- break;
59
- case "chat":
60
- this.#deltaAccum = "";
61
- this.#batch(() => {
62
- this.#agentUtterance.value = null;
63
- this.#messages.value = [...this.#messages.value, {
64
- role: "assistant",
65
- content: e.text
66
- }];
67
- });
68
- break;
69
- case "tool_call_start":
70
- this.#toolCalls.value = [...this.#toolCalls.value, {
71
- toolCallId: e.toolCallId,
72
- toolName: e.toolName,
73
- args: e.args,
74
- status: "pending",
75
- afterMessageIndex: this.#messages.value.length - 1
76
- }];
77
- break;
78
- case "tool_call_done": {
79
- const tcs = this.#toolCalls.value;
80
- const idx = tcs.findIndex((tc) => tc.toolCallId === e.toolCallId);
81
- if (idx !== -1) {
82
- const updated = [...tcs];
83
- const existing = updated[idx];
84
- if (existing) updated[idx] = {
85
- ...existing,
86
- status: "done",
87
- result: e.result
88
- };
89
- this.#toolCalls.value = updated;
90
- }
91
- break;
92
- }
93
- case "tts_done":
94
- this.#state.value = "listening";
95
- break;
96
- case "cancelled":
97
- this.#generation++;
98
- this.#voiceIO()?.flush();
99
- this.#batch(() => {
100
- this.#userUtterance.value = null;
101
- this.#agentUtterance.value = null;
102
- this.#state.value = "listening";
103
- });
104
- break;
105
- case "reset":
106
- this.#generation++;
107
- this.#voiceIO()?.flush();
108
- this.#batch(() => {
109
- this.#messages.value = [];
110
- this.#toolCalls.value = [];
111
- this.#userUtterance.value = null;
112
- this.#agentUtterance.value = null;
113
- this.#error.value = null;
114
- this.#state.value = "listening";
115
- });
116
- break;
117
- case "error":
118
- console.error("Agent error:", e.message);
119
- this.#batch(() => {
120
- this.#error.value = {
121
- code: e.code,
122
- message: e.message
123
- };
124
- this.#state.value = "error";
125
- });
126
- break;
127
- default: break;
128
- }
129
- }
130
- /** Enqueue a PCM16 audio chunk for playback. Transitions state to `"speaking"` on the first chunk. */
131
- playAudioChunk(chunk) {
132
- if (this.#state.value === "error") return;
133
- if (this.#state.value !== "speaking") this.#state.value = "speaking";
134
- if (chunk.buffer instanceof ArrayBuffer) this.#voiceIO()?.enqueue(chunk.buffer);
135
- }
136
- /**
137
- * Signal that the server has finished sending audio for this turn.
138
- * Waits for the audio queue to drain, then transitions state to `"listening"`.
139
- * Uses the `#generation` counter to discard stale completions from interrupted turns.
140
- */
141
- playAudioDone() {
142
- const gen = this.#generation;
143
- const io = this.#voiceIO();
144
- if (io) io.done().then(() => {
145
- if (this.#generation !== gen) return;
146
- this.#state.value = "listening";
147
- }).catch((err) => {
148
- console.warn("Audio playback done failed:", err);
149
- });
150
- else this.#state.value = "listening";
151
- }
152
- /**
153
- * Dispatch an incoming WebSocket message (text or binary).
154
- *
155
- * Returns the parsed config if the message is a `config` message,
156
- * otherwise `null`.
157
- */
158
- handleMessage(data) {
159
- if (data instanceof ArrayBuffer) {
160
- this.playAudioChunk(new Uint8Array(data));
161
- return null;
162
- }
163
- let msg;
164
- try {
165
- const parsed = ServerMessageSchema.safeParse(JSON.parse(data));
166
- if (!parsed.success) {
167
- console.warn("Ignoring invalid server message:", parsed.error.message);
168
- return null;
169
- }
170
- msg = parsed.data;
171
- } catch {
172
- return null;
173
- }
174
- if (msg.type === "config") {
175
- const { type: _, sessionId, ...config } = msg;
176
- const parsed = ReadyConfigSchema.safeParse(config);
177
- if (!parsed.success) {
178
- console.warn("Unsupported server config:", parsed.error.message);
179
- return null;
180
- }
181
- return sessionId ? {
182
- ...parsed.data,
183
- sessionId
184
- } : parsed.data;
185
- }
186
- if (msg.type === "audio_done") {
187
- this.playAudioDone();
188
- return null;
189
- }
190
- this.event(msg);
191
- return null;
192
- }
193
- };
194
- //#endregion
195
- //#region session.ts
196
- const WS_OPEN = 1;
197
- /**
198
- * Initialize audio capture and playback after the server sends a ready config.
199
- *
200
- * Lifecycle: dynamically import audio modules → request microphone access →
201
- * register AudioWorklet processors → create a `VoiceIO` instance → send
202
- * `audio_ready` to the server → transition state to `"listening"`.
203
- *
204
- * Uses the connection `generation` counter to detect if `connect()` was called
205
- * while awaiting async operations; if so, the stale VoiceIO is closed immediately
206
- * to prevent it from being assigned to a newer connection.
207
- *
208
- * On failure (e.g. microphone permission denied, WebSocket closed mid-setup),
209
- * sets the error state and transitions to `"error"`.
210
- *
211
- * @param conn - The shared mutable connection state (WebSocket, VoiceIO, generation).
212
- * @param msg - The `ReadyConfig` from the server containing audio sample rates.
213
- * @param deps.send - Send a typed client message over the WebSocket.
214
- * @param deps.sendBinary - Send raw binary audio data over the WebSocket.
215
- * @param deps.state - Reactive state signal for the agent's current state.
216
- * @param deps.error - Reactive signal for session errors.
217
- * @param deps.batch - Batching function for grouping reactive updates.
218
- */
219
- async function initAudioCapture(conn, msg, deps) {
220
- if (conn.audioSetupInFlight) return;
221
- conn.audioSetupInFlight = true;
222
- const gen = conn.generation;
223
- try {
224
- const [{ createVoiceIO }, captureWorklet, playbackWorklet] = await Promise.all([
225
- import("./audio.js"),
226
- import("./worklets/capture-processor.js").then((m) => m.default),
227
- import("./worklets/playback-processor.js").then((m) => m.default)
228
- ]);
229
- const io = await createVoiceIO({
230
- sttSampleRate: msg.sampleRate,
231
- ttsSampleRate: msg.ttsSampleRate,
232
- captureWorkletSrc: captureWorklet,
233
- playbackWorkletSrc: playbackWorklet,
234
- onMicData: (pcm16) => {
235
- try {
236
- deps.sendBinary(pcm16);
237
- } catch {
238
- console.debug("[aai-ui] sendBinary dropped: connection closed");
239
- }
240
- }
241
- });
242
- if (conn.generation !== gen || !conn.ws || conn.ws.readyState !== WS_OPEN) {
243
- io.close();
244
- return;
245
- }
246
- conn.voiceIO = io;
247
- deps.send({ type: "audio_ready" });
248
- deps.state.value = "listening";
249
- } catch (err) {
250
- if (conn.generation !== gen || !conn.ws || conn.ws.readyState !== WS_OPEN) return;
251
- deps.batch(() => {
252
- deps.error.value = {
253
- code: "audio",
254
- message: `Microphone access failed: ${errorMessage(err)}`
255
- };
256
- deps.state.value = "error";
257
- });
258
- } finally {
259
- conn.audioSetupInFlight = false;
260
- }
261
- }
262
- function buildWsUrl(platformUrl, resume, sessionId) {
263
- const wsUrl = new URL("websocket", platformUrl.endsWith("/") ? platformUrl : `${platformUrl}/`);
264
- wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
265
- if (sessionId) wsUrl.searchParams.set("sessionId", sessionId);
266
- else if (resume) wsUrl.searchParams.set("resume", "1");
267
- return wsUrl;
268
- }
269
- /**
270
- * Create a voice session that connects to an AAI server via WebSocket.
271
- *
272
- * Uses plain JSON text frames and binary audio frames for communication.
273
- *
274
- * @param options - Session configuration including the platform server URL.
275
- * @returns A {@link VoiceSession} handle for controlling the session.
276
- *
277
- * @public
278
- */
279
- function createVoiceSession(options) {
280
- const WS = options.WebSocket ?? WebSocket;
281
- const reactive = options.reactiveFactory ?? ((initial) => ({ value: initial }));
282
- const batchFn = options.batch ?? ((fn) => fn());
283
- const state = reactive("disconnected");
284
- const messages = reactive([]);
285
- const toolCalls = reactive([]);
286
- const userUtterance = reactive(null);
287
- const agentUtterance = reactive(null);
288
- const error = reactive(null);
289
- const disconnected = reactive(null);
290
- const conn = {
291
- ws: null,
292
- voiceIO: null,
293
- audioSetupInFlight: false,
294
- generation: 0
295
- };
296
- let connectionController = null;
297
- let hasConnected = false;
298
- function cleanupAudio() {
299
- conn.audioSetupInFlight = false;
300
- conn.voiceIO?.close();
301
- conn.voiceIO = null;
302
- }
303
- function resetState() {
304
- batchFn(() => {
305
- messages.value = [];
306
- toolCalls.value = [];
307
- userUtterance.value = null;
308
- agentUtterance.value = null;
309
- error.value = null;
310
- });
311
- }
312
- function send(msg) {
313
- if (conn.ws && conn.ws.readyState === WS_OPEN) conn.ws.send(JSON.stringify(msg));
314
- }
315
- function sendBinary(data) {
316
- if (conn.ws && conn.ws.readyState === WS_OPEN) conn.ws.send(data);
317
- }
318
- const audioDeps = {
319
- send,
320
- sendBinary,
321
- state,
322
- error,
323
- batch: batchFn
324
- };
325
- function connect(opts) {
326
- disconnected.value = null;
327
- state.value = "connecting";
328
- connectionController?.abort();
329
- cleanupAudio();
330
- conn.ws?.close();
331
- conn.ws = null;
332
- conn.generation++;
333
- const controller = new AbortController();
334
- connectionController = controller;
335
- const { signal: sig } = controller;
336
- if (opts?.signal) opts.signal.addEventListener("abort", () => disconnect(), { signal: sig });
337
- const resumeId = !hasConnected ? options.resumeSessionId : void 0;
338
- const socket = new WS(buildWsUrl(options.platformUrl, hasConnected, resumeId).toString());
339
- socket.binaryType = "arraybuffer";
340
- conn.ws = socket;
341
- const handler = new ClientHandler({
342
- state,
343
- messages,
344
- toolCalls,
345
- userUtterance,
346
- agentUtterance,
347
- error,
348
- voiceIO: () => conn.voiceIO,
349
- batch: batchFn
350
- });
351
- socket.addEventListener("open", () => {
352
- state.value = "ready";
353
- }, { signal: sig });
354
- socket.addEventListener("message", (event) => {
355
- const config = handler.handleMessage(event.data);
356
- if (config) {
357
- if (config.sessionId) options.onSessionId?.(config.sessionId);
358
- const isReconnect = hasConnected;
359
- hasConnected = true;
360
- initAudioCapture(conn, config, audioDeps).catch((err) => {
361
- audioDeps.batch(() => {
362
- audioDeps.error.value = {
363
- code: "audio",
364
- message: `Audio capture failed: ${errorMessage(err)}`
365
- };
366
- audioDeps.state.value = "error";
367
- });
368
- });
369
- if (isReconnect && messages.value.length > 0) send({
370
- type: "history",
371
- messages: messages.value.map((m) => ({
372
- role: m.role,
373
- content: m.content
374
- }))
375
- });
376
- }
377
- }, { signal: sig });
378
- socket.addEventListener("close", () => {
379
- if (sig.aborted) return;
380
- controller.abort();
381
- disconnected.value = { intentional: false };
382
- cleanupAudio();
383
- state.value = "disconnected";
384
- }, { signal: sig });
385
- }
386
- function cancel() {
387
- conn.voiceIO?.flush();
388
- state.value = "listening";
389
- send({ type: "cancel" });
390
- }
391
- function reset() {
392
- conn.voiceIO?.flush();
393
- if (conn.ws && conn.ws.readyState === WS_OPEN) {
394
- send({ type: "reset" });
395
- return;
396
- }
397
- resetState();
398
- disconnect();
399
- connect();
400
- }
401
- function disconnect() {
402
- connectionController?.abort();
403
- connectionController = null;
404
- cleanupAudio();
405
- conn.ws?.close();
406
- conn.ws = null;
407
- state.value = "disconnected";
408
- disconnected.value = { intentional: true };
409
- }
410
- return {
411
- state,
412
- messages,
413
- toolCalls,
414
- userUtterance,
415
- agentUtterance,
416
- error,
417
- disconnected,
418
- connect,
419
- cancel,
420
- resetState,
421
- reset,
422
- disconnect,
423
- [Symbol.dispose]() {
424
- disconnect();
425
- }
426
- };
427
- }
428
- //#endregion
429
- export { ClientHandler as n, createVoiceSession as t };
package/dist/session.d.ts DELETED
@@ -1,69 +0,0 @@
1
- import type { AgentState, ChatMessage, Reactive, SessionError, ToolCallInfo, VoiceSessionOptions } from "./types.ts";
2
- export { ClientHandler } from "./client-handler.ts";
3
- export type { AgentState, ChatMessage, Reactive, SessionError, SessionErrorCode, ToolCallInfo, VoiceSessionOptions, WebSocketConstructor, } from "./types.ts";
4
- /**
5
- * A reactive voice session that manages WebSocket communication,
6
- * audio capture/playback, and agent state transitions.
7
- *
8
- * Uses plain JSON text frames and binary audio frames for communication
9
- * and native WebSocket for the connection.
10
- *
11
- * Implements `Disposable` for resource cleanup via `using`.
12
- *
13
- * @public
14
- */
15
- export type VoiceSession = {
16
- /** Current agent state (connecting, listening, thinking, etc.). */
17
- readonly state: Reactive<AgentState>;
18
- /** Chat message history for the session. */
19
- readonly messages: Reactive<ChatMessage[]>;
20
- /** Active tool calls for the current turn. */
21
- readonly toolCalls: Reactive<ToolCallInfo[]>;
22
- /**
23
- * Live user utterance from STT/VAD.
24
- * `null` = not speaking, `""` = speech detected but no text yet,
25
- * non-empty string = partial/final transcript text.
26
- */
27
- readonly userUtterance: Reactive<string | null>;
28
- /**
29
- * Streaming agent response text.
30
- * `null` = not speaking, non-empty string = accumulated delta text.
31
- * Cleared when the final `chat` message arrives.
32
- */
33
- readonly agentUtterance: Reactive<string | null>;
34
- /** Current session error, or `null` if no error. */
35
- readonly error: Reactive<SessionError | null>;
36
- /** Disconnection info, or `null` if connected. */
37
- readonly disconnected: Reactive<{
38
- intentional: boolean;
39
- } | null>;
40
- /**
41
- * Open a WebSocket connection to the server and begin audio capture.
42
- *
43
- * @param options - Optional connection options. `signal` is an AbortSignal that, when aborted, disconnects the session.
44
- */
45
- connect(options?: {
46
- signal?: AbortSignal;
47
- }): void;
48
- /** Cancel the current agent turn and discard in-flight TTS audio. */
49
- cancel(): void;
50
- /** Clear messages, transcript, and error state without disconnecting. */
51
- resetState(): void;
52
- /** Reset the session: clear state and reconnect. */
53
- reset(): void;
54
- /** Close the WebSocket and release all audio resources. */
55
- disconnect(): void;
56
- /** Alias for `disconnect` for use with `using`. */
57
- [Symbol.dispose](): void;
58
- };
59
- /**
60
- * Create a voice session that connects to an AAI server via WebSocket.
61
- *
62
- * Uses plain JSON text frames and binary audio frames for communication.
63
- *
64
- * @param options - Session configuration including the platform server URL.
65
- * @returns A {@link VoiceSession} handle for controlling the session.
66
- *
67
- * @public
68
- */
69
- export declare function createVoiceSession(options: VoiceSessionOptions): VoiceSession;
package/dist/session.js DELETED
@@ -1,2 +0,0 @@
1
- import { n as ClientHandler, t as createVoiceSession } from "./session-CWB7vmqz.js";
2
- export { ClientHandler, createVoiceSession };
package/dist/signals.d.ts DELETED
@@ -1,120 +0,0 @@
1
- import { type Signal } from "@preact/signals";
2
- import type { ComponentChildren, JSX, RefObject } from "preact";
3
- import type { VoiceSession } from "./session.ts";
4
- import type { ToolCallInfo } from "./types.ts";
5
- /**
6
- * Reactive session controls wrapping a {@link VoiceSession} with Preact signals.
7
- *
8
- * Components access reactive data via `session` (e.g. `session.state`,
9
- * `session.messages`). UI-only state (`started`, `running`) and actions
10
- * (`start`, `toggle`, `reset`) live directly on this object.
11
- *
12
- * @public
13
- */
14
- export type SessionSignals = {
15
- /** The underlying voice session — all reactive data lives here. */
16
- session: VoiceSession;
17
- /** Whether the session has been started by the user. */
18
- started: Signal<boolean>;
19
- /** Whether the session is currently running (connected or connecting). */
20
- running: Signal<boolean>;
21
- /** Dispose the reactive effect that tracks error state. */
22
- dispose(): void;
23
- /** Start the session for the first time (sets `started` and `running`). */
24
- start(): void;
25
- /** Toggle between connected and disconnected states. */
26
- toggle(): void;
27
- /** Reset the session: clear state and reconnect. */
28
- reset(): void;
29
- /** Alias for `dispose` for use with `using`. */
30
- [Symbol.dispose](): void;
31
- };
32
- /**
33
- * Wrap a {@link VoiceSession} in Preact signals for reactive UI binding.
34
- *
35
- * Creates higher-level controls (start, toggle, reset) on top of the raw
36
- * session, and automatically sets `running` to `false` when the session
37
- * enters an error state.
38
- *
39
- * @param session - The voice session to wrap.
40
- * @returns A {@link SessionSignals} object for use in Preact components.
41
- *
42
- * @public
43
- */
44
- export declare function createSessionControls(session: VoiceSession): SessionSignals;
45
- /**
46
- * Preact context provider that makes session signals available to descendant
47
- * components via {@link useSession}.
48
- *
49
- * @param props - Provider props. `value` is the session signals to provide. `children` are child components that may consume the context.
50
- * @returns A Preact VNode wrapping children in the session context.
51
- *
52
- * @public
53
- */
54
- export declare function SessionProvider({ value, children, }: {
55
- value: SessionSignals;
56
- children?: ComponentChildren;
57
- }): JSX.Element;
58
- /**
59
- * Hook to access session signals from within a {@link SessionProvider}.
60
- *
61
- * @returns The {@link SessionSignals} from the nearest provider.
62
- * @throws If called outside of a `SessionProvider`.
63
- *
64
- * @public
65
- */
66
- export declare function useSession(): SessionSignals;
67
- /**
68
- * Hook that fires a callback exactly once for each newly completed tool call.
69
- *
70
- * Handles deduplication internally — safe to use with `useState` setters
71
- * without worrying about duplicates. The `result` argument is the parsed
72
- * JSON result from the tool (or the raw string if parsing fails).
73
- *
74
- * Automatically resets tracking when the session is reset (toolCalls cleared).
75
- *
76
- * @example
77
- * ```tsx
78
- * // Filter by tool name with a typed result:
79
- * useToolResult<Recipe>("get_recipe", (result, toolCall) => {
80
- * setRecipe(result);
81
- * });
82
- *
83
- * // Receive all tool results (untyped):
84
- * useToolResult((toolName, result, toolCall) => {
85
- * console.log(toolName, result);
86
- * });
87
- * ```
88
- *
89
- * @public
90
- */
91
- export declare function useToolResult<R = unknown>(toolName: string, callback: (result: R, toolCall: ToolCallInfo) => void): void;
92
- /**
93
- * Hook that fires a callback exactly once for each newly completed tool call.
94
- *
95
- * @param callback - Called once per completed tool call with the tool name,
96
- * parsed result, and full {@link ToolCallInfo}.
97
- *
98
- * @public
99
- */
100
- export declare function useToolResult(callback: (toolName: string, result: unknown, toolCall: ToolCallInfo) => void): void;
101
- /**
102
- * Hook that fires a callback when a new tool call starts (status: "pending").
103
- *
104
- * Use this to show a loading/skeleton UI immediately when the agent invokes
105
- * a tool, rather than waiting for the full result. The callback receives the
106
- * tool name, parsed arguments, and the full {@link ToolCallInfo}.
107
- *
108
- * @param callback - Called once per new tool call at start time.
109
- *
110
- * @public
111
- */
112
- export declare function useToolCallStart(callback: (toolName: string, args: Record<string, unknown>, toolCall: ToolCallInfo) => void): void;
113
- /**
114
- * Auto-scroll a container to the bottom when messages, tool calls,
115
- * or utterances change. Returns a ref to attach to a sentinel `<div>`
116
- * at the bottom of the scrollable area.
117
- *
118
- * @public
119
- */
120
- export declare function useAutoScroll(): RefObject<HTMLDivElement>;