@alexkroman1/aai-ui 7.0.0 → 8.0.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.
@@ -38,3 +38,6 @@ export { ToolConfigContext } from "./components/tool-config-context.ts";
38
38
  export { ApiUrlChip, SessionUrlChips, UiUrlChip } from "./components/url-chips.tsx";
39
39
  export { SessionProvider, ThemeProvider } from "./context.ts";
40
40
  export { VOICE_CAPTURE_CONSTRAINTS } from "./types.ts";
41
+ export { TRANSCRIBING_PLACEHOLDER } from "./use-user-transcript.ts";
42
+ export { DEFAULT_PROGRESS_POLL_MS } from "./use-workflow-progress.ts";
43
+ export { DEFAULT_WORKFLOW_POLL_MS, MAX_MISSING_READS } from "./use-workflow-run.ts";
package/dist/internal.js CHANGED
@@ -1,6 +1,8 @@
1
- import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-B4nznRvH.js";
1
+ import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-BT_kWID5.js";
2
2
  import { SessionProvider, ThemeProvider } from "./context.js";
3
- import { n as SessionUrlChips, r as UiUrlChip, t as ApiUrlChip } from "./url-chips-DpM7Oocj.js";
3
+ import { n as SessionUrlChips, r as UiUrlChip, t as ApiUrlChip } from "./url-chips-DxXKgyL9.js";
4
+ import { t as TRANSCRIBING_PLACEHOLDER } from "./use-user-transcript-C14qWFu2.js";
4
5
  import { t as ToolConfigContext } from "./tool-config-context-DzAofqi_.js";
6
+ import { i as MAX_MISSING_READS, r as DEFAULT_WORKFLOW_POLL_MS, t as DEFAULT_PROGRESS_POLL_MS } from "./use-workflow-progress-C4KgVldr.js";
5
7
  import { VOICE_CAPTURE_CONSTRAINTS } from "./types.js";
6
- export { ApiUrlChip, SessionProvider, SessionUrlChips, ThemeProvider, ToolConfigContext, UiUrlChip, VOICE_CAPTURE_CONSTRAINTS, buildAgentUrl, loadClientConfig };
8
+ export { ApiUrlChip, DEFAULT_PROGRESS_POLL_MS, DEFAULT_WORKFLOW_POLL_MS, MAX_MISSING_READS, SessionProvider, SessionUrlChips, TRANSCRIBING_PLACEHOLDER, ThemeProvider, ToolConfigContext, UiUrlChip, VOICE_CAPTURE_CONSTRAINTS, buildAgentUrl, loadClientConfig };
@@ -1,6 +1,7 @@
1
1
  import { useSessionSelector, useTheme } from "./context.js";
2
- import { i as primaryTint, r as inkTint } from "./_colors-CcAi2FOU.js";
3
- import { t as ToolCallBlock } from "./tool-call-block-DoF-cSIZ.js";
2
+ import { i as primaryTint, r as inkTint } from "./_colors-j8XMToi9.js";
3
+ import { n as useUserTranscript } from "./use-user-transcript-C14qWFu2.js";
4
+ import { t as ToolCallBlock } from "./tool-call-block-B7KlhaWl.js";
4
5
  import clsx from "clsx";
5
6
  import { StickToBottom } from "use-stick-to-bottom";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -65,71 +66,6 @@ function AutoScroll({ children, className, contentClassName, scrollClassName = "
65
66
  });
66
67
  }
67
68
  //#endregion
68
- //#region use-user-transcript.ts
69
- /**
70
- * `useUserTranscript` — what the caller is saying RIGHT NOW, read correctly.
71
- *
72
- * `SessionSnapshot.userTranscript` is `string | null`, and the two falsy values
73
- * mean different things:
74
- *
75
- * - `null` — nobody is speaking. There is no partial turn.
76
- * - `""` — speech HAS been detected and no words have come back yet. A live
77
- * session sits here for a few hundred milliseconds at the start of every turn.
78
- *
79
- * Read as one falsy check, those collapse and the indicator never appears at the
80
- * start of a turn — which is the moment it is for. So every custom chrome writes
81
- * `transcript !== null && (transcript === "" ? "…" : transcript)`, three
82
- * templates did exactly that, and each one re-derived a protocol distinction
83
- * from the type rather than from anything that told them.
84
- *
85
- * This is the same distinction as two named booleans, so a component can say
86
- * what it means: render on `speaking`, show `text`, and use the SDK's own
87
- * placeholder when there is nothing to show yet.
88
- */
89
- /**
90
- * Placeholder for "listening, no words yet" — the `""` case above.
91
- *
92
- * A one-character ellipsis rather than three dots, because it is read by a
93
- * screen reader as an ellipsis and it does not reflow the row when the first
94
- * real word replaces it.
95
- *
96
- * @public
97
- */
98
- const TRANSCRIBING_PLACEHOLDER = "…";
99
- /**
100
- * Subscribe to the caller's in-progress turn.
101
- *
102
- * Narrowly subscribed — a component using this re-renders at STT-partial rate,
103
- * which is exactly what it is for and exactly what a whole-page `useSession()`
104
- * should not do.
105
- *
106
- * @example
107
- * ```tsx
108
- * import { useUserTranscript } from "@alexkroman1/aai-ui";
109
- *
110
- * function LiveTranscript() {
111
- * const { speaking, text } = useUserTranscript();
112
- * if (!speaking) return null;
113
- * return <div className="italic opacity-60">{text}</div>;
114
- * }
115
- * ```
116
- *
117
- * @public
118
- */
119
- function useUserTranscript() {
120
- const partial = useSessionSelector((snapshot) => snapshot.userTranscript);
121
- return {
122
- speaking: partial !== null,
123
- text: displayText(partial),
124
- partial
125
- };
126
- }
127
- /** The three cases, spelled out: silent, detected-but-wordless, and words. */
128
- function displayText(partial) {
129
- if (partial === null) return "";
130
- return partial === "" ? "…" : partial;
131
- }
132
- //#endregion
133
69
  //#region use-conversation.ts
134
70
  /**
135
71
  * `useConversation` — the exchange, already assembled, with nothing rendered.
@@ -581,4 +517,4 @@ const MessageList = memo(function MessageList({ className }) {
581
517
  });
582
518
  });
583
519
  //#endregion
584
- export { useUserTranscript as a, TRANSCRIBING_PLACEHOLDER as i, Markdown as n, AutoScroll as o, useConversation as r, MessageList as t };
520
+ export { AutoScroll as i, Markdown as n, useConversation as r, MessageList as t };
@@ -1,6 +1,6 @@
1
- import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-B4nznRvH.js";
1
+ import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-BT_kWID5.js";
2
2
  import { MIC_SEND_MAX_BUFFERED_BYTES } from "./types.js";
3
- import { ServerMessageSchema, lenientParse } from "@alexkroman1/aai/protocol";
3
+ import { SessionEventSchema, lenientParse } from "@alexkroman1/aai/protocol";
4
4
  import { errorMessage, safeJsonParse } from "@alexkroman1/aai";
5
5
  import { omitUndefined } from "@alexkroman1/aai/utils";
6
6
  import { DEFAULT_MAX_HISTORY, WS_OPEN, createEpoch, toArgsRecord } from "@alexkroman1/aai/internal";
@@ -427,7 +427,7 @@ function createHandshakeGuard(opts) {
427
427
  * Incoming-message handling for the voice session core.
428
428
  *
429
429
  * Split out of `session-core.ts`: this module owns the interpretation of
430
- * server→client frames (audio chunks + JSON {@link ServerMessage}s) and the
430
+ * server→client frames (audio chunks + JSON {@link SessionEvent}s) and the
431
431
  * turn-boundary generation counters, while `session-core.ts` owns the state
432
432
  * store and connection lifecycle. The handlers read and mutate session state
433
433
  * exclusively through the injected `getSnapshot`/`updateState` deps.
@@ -734,7 +734,7 @@ function createMessageHandlers(deps) {
734
734
  console.warn("session-core: invalid JSON; dropping");
735
735
  return;
736
736
  }
737
- const parsed = lenientParse(ServerMessageSchema, raw);
737
+ const parsed = lenientParse(SessionEventSchema, raw);
738
738
  if (!parsed.ok) {
739
739
  if (parsed.malformed) console.warn("session-core: malformed server message", parsed.error);
740
740
  return;
@@ -1,10 +1,10 @@
1
- import type { ClientMessage } from "@alexkroman1/aai/protocol";
1
+ import type { SessionCommand } from "@alexkroman1/aai/protocol";
2
2
  import type { VoiceIO } from "./audio.ts";
3
3
  import type { SessionStateMachine } from "./session-core-state.ts";
4
4
  import type { ConnState, SessionSnapshot } from "./session-core-types.ts";
5
5
  /** Dependencies `initAudioCapture` needs from the owning session core. */
6
6
  export type AudioSetupDeps = {
7
- sendJson: (msg: ClientMessage) => void;
7
+ sendJson: (msg: SessionCommand) => void;
8
8
  sendAudio: (bytes: ArrayBuffer) => void;
9
9
  updateState: (partial: Partial<SessionSnapshot>) => void;
10
10
  /** The session's state and error, as one fact — see `session-core-state.ts`. */
@@ -36,7 +36,7 @@ type MessageHandlers = {
36
36
  * Dispatch an incoming WebSocket message.
37
37
  *
38
38
  * Binary frames carry raw PCM16 audio chunks. Text frames are JSON-encoded
39
- * {@link ServerMessage} values validated via Zod.
39
+ * {@link SessionEvent} values validated via Zod.
40
40
  *
41
41
  * Returns the parsed config if the message is a `config` message,
42
42
  * otherwise `undefined`.
@@ -1,2 +1,2 @@
1
- import { t as createSessionCore } from "./session-core-C2JtLArh.js";
1
+ import { t as createSessionCore } from "./session-core-CMEpwRP1.js";
2
2
  export { createSessionCore };
@@ -1,5 +1,5 @@
1
1
  import { useTheme } from "./context.js";
2
- import { r as inkTint } from "./_colors-CcAi2FOU.js";
2
+ import { r as inkTint } from "./_colors-j8XMToi9.js";
3
3
  import { t as Eyebrow } from "./eyebrow-C6ZFuiz6.js";
4
4
  import { i as tryParseJSON, r as truncate } from "./_utils-B6498_bm.js";
5
5
  import { n as useToolConfig } from "./tool-config-context-DzAofqi_.js";
@@ -1,5 +1,5 @@
1
1
  import { useSessionSelector, useTheme } from "./context.js";
2
- import { r as inkTint } from "./_colors-CcAi2FOU.js";
2
+ import { r as inkTint } from "./_colors-j8XMToi9.js";
3
3
  import { t as pageBaseUrl } from "./_utils-B6498_bm.js";
4
4
  import clsx from "clsx";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -0,0 +1,72 @@
1
+ import { useSessionSelector } from "./context.js";
2
+ //#region use-user-transcript.ts
3
+ /**
4
+ * `useUserTranscript` — what the caller is saying RIGHT NOW, read correctly.
5
+ *
6
+ * `SessionSnapshot.userTranscript` is `string | null`, and the two falsy values
7
+ * mean different things:
8
+ *
9
+ * - `null` — nobody is speaking. There is no partial turn.
10
+ * - `""` — speech HAS been detected and no words have come back yet. A live
11
+ * session sits here for a few hundred milliseconds at the start of every turn.
12
+ *
13
+ * Read as one falsy check, those collapse and the indicator never appears at the
14
+ * start of a turn — which is the moment it is for. So every custom chrome writes
15
+ * `transcript !== null && (transcript === "" ? "…" : transcript)`, three
16
+ * templates did exactly that, and each one re-derived a protocol distinction
17
+ * from the type rather than from anything that told them.
18
+ *
19
+ * This is the same distinction as two named booleans, so a component can say
20
+ * what it means: render on `speaking`, show `text`, and use the SDK's own
21
+ * placeholder when there is nothing to show yet.
22
+ */
23
+ /**
24
+ * Placeholder for "listening, no words yet" — the `""` case above.
25
+ *
26
+ * A one-character ellipsis rather than three dots, because it is read by a
27
+ * screen reader as an ellipsis and it does not reflow the row when the first
28
+ * real word replaces it.
29
+ *
30
+ * On `@alexkroman1/aai-ui/internal`, not the root: no public signature names
31
+ * it, and a `client.tsx` rendering its own transcript row compares against the
32
+ * character. `UseUserTranscriptResult.text` therefore spells the value out
33
+ * rather than linking here.
34
+ *
35
+ * @internal
36
+ */
37
+ const TRANSCRIBING_PLACEHOLDER = "…";
38
+ /**
39
+ * Subscribe to the caller's in-progress turn.
40
+ *
41
+ * Narrowly subscribed — a component using this re-renders at STT-partial rate,
42
+ * which is exactly what it is for and exactly what a whole-page `useSession()`
43
+ * should not do.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * import { useUserTranscript } from "@alexkroman1/aai-ui";
48
+ *
49
+ * function LiveTranscript() {
50
+ * const { speaking, text } = useUserTranscript();
51
+ * if (!speaking) return null;
52
+ * return <div className="italic opacity-60">{text}</div>;
53
+ * }
54
+ * ```
55
+ *
56
+ * @public
57
+ */
58
+ function useUserTranscript() {
59
+ const partial = useSessionSelector((snapshot) => snapshot.userTranscript);
60
+ return {
61
+ speaking: partial !== null,
62
+ text: displayText(partial),
63
+ partial
64
+ };
65
+ }
66
+ /** The three cases, spelled out: silent, detected-but-wordless, and words. */
67
+ function displayText(partial) {
68
+ if (partial === null) return "";
69
+ return partial === "" ? "…" : partial;
70
+ }
71
+ //#endregion
72
+ export { useUserTranscript as n, TRANSCRIBING_PLACEHOLDER as t };
@@ -25,7 +25,12 @@
25
25
  * screen reader as an ellipsis and it does not reflow the row when the first
26
26
  * real word replaces it.
27
27
  *
28
- * @public
28
+ * On `@alexkroman1/aai-ui/internal`, not the root: no public signature names
29
+ * it, and a `client.tsx` rendering its own transcript row compares against the
30
+ * character. `UseUserTranscriptResult.text` therefore spells the value out
31
+ * rather than linking here.
32
+ *
33
+ * @internal
29
34
  */
30
35
  export declare const TRANSCRIBING_PLACEHOLDER = "\u2026";
31
36
  /** What {@link useUserTranscript} returns. */
@@ -36,7 +41,7 @@ export interface UseUserTranscriptResult {
36
41
  */
37
42
  speaking: boolean;
38
43
  /**
39
- * The words so far, or {@link TRANSCRIBING_PLACEHOLDER} while there are none.
44
+ * The words so far, or a one-character ellipsis (`…`) while there are none.
40
45
  * Empty string when nobody is speaking.
41
46
  */
42
47
  text: string;