@alexkroman1/aai-ui 0.16.0 → 0.17.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.
Files changed (86) hide show
  1. package/dist/agent-state-labels.d.ts +8 -3
  2. package/dist/{chat-view-DIwPoAEG.js → chat-view-W6KcdjJY.js} +40 -30
  3. package/dist/{client-config-C7fQrioM.js → client-config-CzvWmw4X.js} +7 -12
  4. package/dist/client-config.d.ts +29 -10
  5. package/dist/components/_form-readiness.d.ts +2 -1
  6. package/dist/components/audio-result.d.ts +2 -0
  7. package/dist/components/bullet-list.d.ts +1 -0
  8. package/dist/components/button.d.ts +2 -2
  9. package/dist/components/chat-view.js +1 -1
  10. package/dist/components/console-shell.d.ts +8 -5
  11. package/dist/components/controls.d.ts +1 -0
  12. package/dist/components/conversation-view.d.ts +1 -0
  13. package/dist/components/facts.d.ts +1 -0
  14. package/dist/components/form-fields.d.ts +8 -8
  15. package/dist/components/form-types.d.ts +16 -2
  16. package/dist/components/form.d.ts +9 -4
  17. package/dist/components/markdown.d.ts +1 -0
  18. package/dist/components/message-list.d.ts +1 -0
  19. package/dist/components/message-list.js +1 -1
  20. package/dist/components/session-controls.d.ts +7 -2
  21. package/dist/components/session-error-banner.d.ts +1 -0
  22. package/dist/components/session-state-dot.d.ts +20 -7
  23. package/dist/components/sidebar-layout.d.ts +2 -2
  24. package/dist/components/tool-call-block.d.ts +3 -3
  25. package/dist/components/tool-call-row.d.ts +1 -0
  26. package/dist/components/tool-config-context.d.ts +2 -1
  27. package/dist/components/url-chips.d.ts +4 -3
  28. package/dist/components/workflow-fields.d.ts +2 -1
  29. package/dist/components/workflow-pending-note.d.ts +1 -0
  30. package/dist/components/workflow-run-error.d.ts +1 -0
  31. package/dist/components/workflow-run-panel.d.ts +1 -0
  32. package/dist/context.d.ts +8 -7
  33. package/dist/context.js +2 -2
  34. package/dist/default-client/assets/{audio-DzwGxdv4.js → audio-Ct7JpSNT.js} +1 -1
  35. package/dist/default-client/assets/{capture-processor-CXCWxCO8.js → capture-processor-Cx1AdMHL.js} +1 -1
  36. package/dist/default-client/assets/index-BlUYCTB5.js +126 -0
  37. package/dist/default-client/assets/{playback-processor-DXHfyQD9.js → playback-processor-CCwTknSu.js} +1 -1
  38. package/dist/default-client/index.html +1 -1
  39. package/dist/define-client.d.ts +2 -0
  40. package/dist/define-client.js +4 -4
  41. package/dist/inbox-protocol.d.ts +14 -4
  42. package/dist/inbox.d.ts +1 -0
  43. package/dist/index.d.ts +3 -3
  44. package/dist/index.js +61 -19
  45. package/dist/internal.js +1 -1
  46. package/dist/linked-client.d.ts +2 -0
  47. package/dist/{message-list-DHZcLhRA.js → message-list-BsaBkBgo.js} +21 -10
  48. package/dist/page.d.ts +2 -0
  49. package/dist/phone.d.ts +1 -0
  50. package/dist/route-fetch.d.ts +1 -0
  51. package/dist/session/audio-setup.d.ts +1 -1
  52. package/dist/session/audio-state.d.ts +6 -6
  53. package/dist/session/index.js +1 -1
  54. package/dist/session/messages.d.ts +1 -9
  55. package/dist/session/preconnect.d.ts +1 -1
  56. package/dist/session/types.d.ts +4 -0
  57. package/dist/{session-CYdjRvbl.js → session-3lgPYNNO.js} +25 -14
  58. package/dist/stored-value.d.ts +2 -0
  59. package/dist/types.d.ts +48 -4
  60. package/dist/use-client-runs.d.ts +2 -0
  61. package/dist/use-conversation-log.d.ts +2 -0
  62. package/dist/use-conversation.d.ts +24 -9
  63. package/dist/use-copy.d.ts +1 -0
  64. package/dist/use-download-url.d.ts +6 -1
  65. package/dist/use-flash.d.ts +1 -0
  66. package/dist/use-inbox.d.ts +2 -0
  67. package/dist/use-push-to-talk.d.ts +6 -1
  68. package/dist/use-route-mutation.d.ts +3 -0
  69. package/dist/use-route.d.ts +2 -0
  70. package/dist/use-session-controls.d.ts +1 -0
  71. package/dist/use-tap-to-talk.d.ts +5 -2
  72. package/dist/use-user-transcript.d.ts +5 -1
  73. package/dist/use-workflow-form.d.ts +8 -1
  74. package/dist/use-workflow-progress.d.ts +5 -0
  75. package/dist/use-workflow-run.d.ts +5 -0
  76. package/dist/use-workflow-runs.d.ts +10 -2
  77. package/dist/use-workflow-stream.d.ts +25 -3
  78. package/dist/use-workflows.d.ts +10 -2
  79. package/dist/workflow-client.d.ts +5 -0
  80. package/dist/workflow-field-kind.d.ts +8 -4
  81. package/dist/worklets/capture-processor.d.ts +3 -3
  82. package/dist/worklets/capture-processor.js +2 -2
  83. package/dist/worklets/playback-processor.d.ts +3 -3
  84. package/dist/worklets/playback-processor.js +2 -2
  85. package/package.json +2 -2
  86. package/dist/default-client/assets/index-BOTLwsNO.js +0 -126
@@ -23,7 +23,7 @@
23
23
  * chrome exists to look like — a CRT's glow, a dispatch board's alert colours —
24
24
  * and a component would take the one part that is genuinely shared (the words)
25
25
  * hostage to the part that is not. It takes the palette as a PROP, so it does
26
- * not: what it shares is the exhaustive colour lookup, this record as the label
26
+ * not: what it shares is the colour lookup, this record as the label
27
27
  * fallback, and the pulse rule, and the three chromes that had each written
28
28
  * those fourteen lines around their own `satisfies Record<AgentState, string>`
29
29
  * keep the record and lose the lines.
@@ -32,6 +32,8 @@ import type { AgentState } from "./types.ts";
32
32
  /**
33
33
  * The default label per {@link AgentState}.
34
34
  *
35
+ * {@link AgentState} is open, so a lookup by a live state is `string |
36
+ * undefined`: fall back to the raw state for one this version has no word for.
35
37
  * Override the ones your page has a better word for and keep the rest:
36
38
  *
37
39
  * ```ts
@@ -39,8 +41,11 @@ import type { AgentState } from "./types.ts";
39
41
  * import { AGENT_STATE_LABELS } from "@alexkroman1/aai-ui";
40
42
  *
41
43
  * // A dispatch board that shouts, and renames one state.
42
- * const STATE_LABEL = { ...AGENT_STATE_LABELS, thinking: "Processing" };
43
- * const shout = (s: AgentState) => STATE_LABEL[s].toUpperCase();
44
+ * const STATE_LABEL: Readonly<Record<AgentState, string>> = {
45
+ * ...AGENT_STATE_LABELS,
46
+ * thinking: "Processing",
47
+ * };
48
+ * const shout = (s: AgentState) => (STATE_LABEL[s] ?? s).toUpperCase();
44
49
  * ```
45
50
  *
46
51
  * **Sentence case, deliberately.** A template that wants caps applies its own
@@ -1,5 +1,5 @@
1
1
  import { useSessionError, useSessionStatus, useTheme } from "./context.js";
2
- import { t as MessageList } from "./message-list-DHZcLhRA.js";
2
+ import { t as MessageList } from "./message-list-BsaBkBgo.js";
3
3
  import { a as inkTint, r as THINKING_COLOR, t as ERROR_COLOR } from "./_colors-CpZO-88A.js";
4
4
  import { t as Eyebrow } from "./eyebrow-UfmSz9yy.js";
5
5
  import { Controls } from "./components/controls.js";
@@ -9,6 +9,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  /**
10
10
  * The default label per {@link AgentState}.
11
11
  *
12
+ * {@link AgentState} is open, so a lookup by a live state is `string |
13
+ * undefined`: fall back to the raw state for one this version has no word for.
12
14
  * Override the ones your page has a better word for and keep the rest:
13
15
  *
14
16
  * ```ts
@@ -16,8 +18,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
16
18
  * import { AGENT_STATE_LABELS } from "@alexkroman1/aai-ui";
17
19
  *
18
20
  * // A dispatch board that shouts, and renames one state.
19
- * const STATE_LABEL = { ...AGENT_STATE_LABELS, thinking: "Processing" };
20
- * const shout = (s: AgentState) => STATE_LABEL[s].toUpperCase();
21
+ * const STATE_LABEL: Readonly<Record<AgentState, string>> = {
22
+ * ...AGENT_STATE_LABELS,
23
+ * thinking: "Processing",
24
+ * };
25
+ * const shout = (s: AgentState) => (STATE_LABEL[s] ?? s).toUpperCase();
21
26
  * ```
22
27
  *
23
28
  * **Sentence case, deliberately.** A template that wants caps applies its own
@@ -126,6 +131,26 @@ function SessionErrorBanner({ className }) {
126
131
  //#region src/components/session-state-dot.tsx
127
132
  /** @jsxImportSource react */
128
133
  /**
134
+ * Indicator dot colour per state, from the theme — `ConsoleShell`'s dot, and
135
+ * {@link SessionStateDot}'s for every state its `colors` does not name.
136
+ *
137
+ * `idle` is the theme's own faint ink step rather than a fixed warm grey, so
138
+ * the dot stays visible on a dark ground; the thinking amber and error red
139
+ * are semantic and stay fixed. A state this version does not know is `idle`.
140
+ *
141
+ * @internal
142
+ */
143
+ function stateColor(state, primary, idle) {
144
+ switch (state) {
145
+ case "listening":
146
+ case "speaking":
147
+ case "ready": return primary;
148
+ case "thinking": return THINKING_COLOR;
149
+ case "error": return ERROR_COLOR;
150
+ default: return idle;
151
+ }
152
+ }
153
+ /**
129
154
  * One `aai-pulse` cycle per pulsing state, in milliseconds. The two states
130
155
  * that pulse are the two in which the agent is DOING something the reader
131
156
  * cannot otherwise see — the microphone is open, or a reply is being worked
@@ -173,7 +198,7 @@ function StateDot({ color, pulseMs, className, title }) {
173
198
  * against a dot component on the grounds that it would take the shared part
174
199
  * (the words) hostage to the part that is not (the palette); this takes the
175
200
  * palette as a prop precisely so it does not. What is shared is the structure
176
- * — the exhaustive colour lookup, the label fallback, the pulse rule, the
201
+ * — the colour lookup and its theme fallback, the label fallback, the pulse rule, the
177
202
  * `useSessionStatus()` subscription that keeps the rest of the header from
178
203
  * re-rendering at STT-partial rate.
179
204
  *
@@ -211,18 +236,20 @@ function StateDot({ color, pulseMs, className, title }) {
211
236
  */
212
237
  function SessionStateDot({ colors, labels, pulse = true, className, dotClassName, labelClassName }) {
213
238
  const state = useSessionStatus();
239
+ const theme = useTheme();
214
240
  const pulseMs = pulse ? PULSE_MS[state] ?? null : null;
241
+ const color = colors?.[state] ?? stateColor(state, theme.primary, inkTint(theme.text, theme.bg, 65));
215
242
  return /* @__PURE__ */ jsxs("span", {
216
243
  className: clsx("inline-flex items-center gap-2", className),
217
244
  "data-state": state,
218
245
  children: [/* @__PURE__ */ jsx(StateDot, {
219
- color: colors[state],
246
+ color,
220
247
  pulseMs,
221
248
  className: dotClassName ?? "w-2 h-2",
222
249
  title: state
223
250
  }), /* @__PURE__ */ jsx("span", {
224
251
  className: labelClassName,
225
- children: labels?.[state] ?? AGENT_STATE_LABELS[state]
252
+ children: labels?.[state] ?? AGENT_STATE_LABELS[state] ?? state
226
253
  })]
227
254
  });
228
255
  }
@@ -230,25 +257,6 @@ function SessionStateDot({ colors, labels, pulse = true, className, dotClassName
230
257
  //#region src/components/console-shell.tsx
231
258
  /** @jsxImportSource react */
232
259
  /**
233
- * Indicator dot color per state.
234
- *
235
- * `idle` is the theme's own faint ink step rather than a fixed warm grey, so
236
- * the dot stays visible on a dark ground; the thinking amber and error red
237
- * are semantic and stay fixed.
238
- *
239
- * @internal
240
- */
241
- function stateColor(state, primary, idle) {
242
- switch (state) {
243
- case "listening":
244
- case "speaking":
245
- case "ready": return primary;
246
- case "thinking": return THINKING_COLOR;
247
- case "error": return ERROR_COLOR;
248
- default: return idle;
249
- }
250
- }
251
- /**
252
260
  * The design-system "console" chrome: a 760px column on the themed page with a
253
261
  * header (icon + live-status eyebrow), an announced error banner, the main
254
262
  * content on a raised card, and a footer row beneath it.
@@ -294,11 +302,13 @@ function stateColor(state, primary, idle) {
294
302
  * footer={<Controls />}
295
303
  * >
296
304
  * <ul>
297
- * {items.map((item) => (
298
- * <li key={item.kind === "message" ? item.message.id : item.toolCall.callId}>
299
- * {item.kind === "message" ? item.message.content : item.toolCall.name}
300
- * </li>
301
- * ))}
305
+ * {items.map((item) =>
306
+ * item.kind === "message" ? (
307
+ * <li key={item.message.id}>{item.message.content}</li>
308
+ * ) : item.kind === "tool" ? (
309
+ * <li key={item.toolCall.callId}>{item.toolCall.name}</li>
310
+ * ) : null,
311
+ * )}
302
312
  * </ul>
303
313
  * </ConsoleShell>
304
314
  * );
@@ -69,11 +69,12 @@ const CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS = 1e4;
69
69
  *
70
70
  * @internal
71
71
  */
72
- async function loadClientConfig(platformUrl, fetchFn, presentedTicket) {
72
+ async function loadClientConfig(platformUrl, fetchFn, presentedTicket, signal) {
73
73
  const doFetch = fetchFn ?? ((input, init) => globalThis.fetch(input, init));
74
+ const deadline = AbortSignal.timeout(CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS);
74
75
  try {
75
76
  const resp = await doFetch(buildAgentUrl(platformUrl, CLIENT_CONFIG_PATH).href, {
76
- signal: AbortSignal.timeout(CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS),
77
+ signal: signal === void 0 ? deadline : AbortSignal.any([deadline, signal]),
77
78
  ...presentedTicket === void 0 ? {} : { headers: { [SESSION_TICKET_HEADER]: presentedTicket } }
78
79
  });
79
80
  if (!resp.ok) return null;
@@ -102,14 +103,7 @@ async function loadClientConfig(platformUrl, fetchFn, presentedTicket) {
102
103
  * treat every field as optional, because an agent that declared none is a
103
104
  * normal agent.
104
105
  *
105
- * @param platformUrl - The agent's base URL. **Defaults to the page's own
106
- * origin and path** (`pageBaseUrl()`), which is the agent that served the page
107
- * and the only case a browser has — the argument was required while the default
108
- * sat one module away in this same package, so every caller wrote
109
- * `location.origin + location.pathname` for itself. Pass one for a page reading
110
- * a DIFFERENT agent. The endpoint is resolved relative to it.
111
- * @param fetchFn - Fetch implementation, for tests and for a caller that
112
- * supplies its own credentials. Defaults to the global `fetch`.
106
+ * @param options - Where to look and how; see {@link FetchClientConfigOptions}.
113
107
  * @returns The agent's config, or `{}` when the lookup produced no answer.
114
108
  *
115
109
  * @example
@@ -132,8 +126,9 @@ async function loadClientConfig(platformUrl, fetchFn, presentedTicket) {
132
126
  *
133
127
  * @public
134
128
  */
135
- async function fetchClientConfig(platformUrl = pageBaseUrl(), fetchFn) {
136
- return await loadClientConfig(platformUrl, fetchFn) ?? AGENT_DEFAULT;
129
+ async function fetchClientConfig(options = {}) {
130
+ const { platformUrl = pageBaseUrl(), fetch: fetchFn, signal } = options;
131
+ return await loadClientConfig(platformUrl, fetchFn, void 0, signal) ?? AGENT_DEFAULT;
137
132
  }
138
133
  //#endregion
139
134
  export { fetchClientConfig as n, loadClientConfig as r, buildAgentUrl as t };
@@ -66,7 +66,33 @@ export declare const CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS = 10000;
66
66
  *
67
67
  * @internal
68
68
  */
69
- export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof globalThis.fetch, presentedTicket?: string): Promise<ClientConfigResponse | null>;
69
+ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof globalThis.fetch, presentedTicket?: string, signal?: AbortSignal): Promise<ClientConfigResponse | null>;
70
+ /**
71
+ * Options for {@link fetchClientConfig}.
72
+ *
73
+ * @input
74
+ * @public
75
+ */
76
+ export type FetchClientConfigOptions = {
77
+ /**
78
+ * The agent's base URL. **Defaults to the page's own origin and path**, which
79
+ * is the agent that served the page and the only case a browser has. Pass
80
+ * one for a page reading a DIFFERENT agent; the endpoint is resolved
81
+ * relative to it.
82
+ */
83
+ platformUrl?: string | undefined;
84
+ /**
85
+ * Fetch implementation, for tests and for a caller that supplies its own
86
+ * credentials. Defaults to the global `fetch`.
87
+ */
88
+ fetch?: typeof globalThis.fetch | undefined;
89
+ /**
90
+ * Abandons the lookup — a component that unmounts before the answer, say.
91
+ * An abandoned lookup resolves to the agent default like every other one that produced no
92
+ * answer; the built-in 10 s deadline applies either way.
93
+ */
94
+ signal?: AbortSignal | undefined;
95
+ };
70
96
  /**
71
97
  * Fetch the agent's declared `name`, `greeting` and front door; any failure
72
98
  * yields the agent default (`{}`).
@@ -86,14 +112,7 @@ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof g
86
112
  * treat every field as optional, because an agent that declared none is a
87
113
  * normal agent.
88
114
  *
89
- * @param platformUrl - The agent's base URL. **Defaults to the page's own
90
- * origin and path** (`pageBaseUrl()`), which is the agent that served the page
91
- * and the only case a browser has — the argument was required while the default
92
- * sat one module away in this same package, so every caller wrote
93
- * `location.origin + location.pathname` for itself. Pass one for a page reading
94
- * a DIFFERENT agent. The endpoint is resolved relative to it.
95
- * @param fetchFn - Fetch implementation, for tests and for a caller that
96
- * supplies its own credentials. Defaults to the global `fetch`.
115
+ * @param options - Where to look and how; see {@link FetchClientConfigOptions}.
97
116
  * @returns The agent's config, or `{}` when the lookup produced no answer.
98
117
  *
99
118
  * @example
@@ -116,4 +135,4 @@ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof g
116
135
  *
117
136
  * @public
118
137
  */
119
- export declare function fetchClientConfig(platformUrl?: string, fetchFn?: typeof globalThis.fetch): Promise<ClientConfigResponse>;
138
+ export declare function fetchClientConfig(options?: FetchClientConfigOptions): Promise<ClientConfigResponse>;
@@ -28,9 +28,10 @@
28
28
  * outside a provider reports nothing pending, so every hand-written form is
29
29
  * unaffected and `Form` keeps working outside this package.
30
30
  */
31
+ import { type Provider } from "react";
31
32
  /** What a child calls to say whether its own fields are ready. */
32
33
  type Readiness = (key: string, pending: boolean) => void;
33
- export declare const FormReadinessProvider: import("react").Provider<Readiness | undefined>;
34
+ export declare const FormReadinessProvider: Provider<Readiness | undefined>;
34
35
  /**
35
36
  * Track which children are still waiting for their fields.
36
37
  *
@@ -4,6 +4,7 @@ import type { UseDownloadUrlResult } from "../use-download-url.ts";
4
4
  * A one-cue caption track for {@link AudioResult}: the words the clip speaks,
5
5
  * spanning its whole length.
6
6
  *
7
+ * @input
7
8
  * @public
8
9
  */
9
10
  export type AudioResultCaptions = {
@@ -19,6 +20,7 @@ export type AudioResultCaptions = {
19
20
  /**
20
21
  * Props of {@link AudioResult}.
21
22
  *
23
+ * @input
22
24
  * @public
23
25
  */
24
26
  export type AudioResultProps = {
@@ -2,6 +2,7 @@ import type { ReactNode } from "react";
2
2
  /**
3
3
  * Props for {@link BulletList}.
4
4
  *
5
+ * @input
5
6
  * @public
6
7
  */
7
8
  export type BulletListProps = {
@@ -1,4 +1,4 @@
1
- import type { ButtonHTMLAttributes, ReactNode } from "react";
1
+ import type { ButtonHTMLAttributes, JSX, ReactNode } from "react";
2
2
  /**
3
3
  * Visual style of a {@link Button} (design-system "website refresh":
4
4
  * rectangular, ALL-CAPS, tracked labels).
@@ -55,4 +55,4 @@ export declare function Button({ variant, size, className, children, style, ...r
55
55
  className?: string;
56
56
  /** Button label / content. */
57
57
  children?: ReactNode;
58
- } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "className">): import("react").JSX.Element;
58
+ } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "className">): JSX.Element;
@@ -1,3 +1,3 @@
1
- import { t as ChatView } from "../chat-view-DIwPoAEG.js";
1
+ import { t as ChatView } from "../chat-view-W6KcdjJY.js";
2
2
  import "../context.js";
3
3
  export { ChatView };
@@ -3,6 +3,7 @@ import type { AgentState } from "../types.ts";
3
3
  /**
4
4
  * Props of {@link ConsoleShell}.
5
5
  *
6
+ * @input
6
7
  * @public
7
8
  */
8
9
  export type ConsoleShellProps = {
@@ -67,11 +68,13 @@ export type ConsoleShellProps = {
67
68
  * footer={<Controls />}
68
69
  * >
69
70
  * <ul>
70
- * {items.map((item) => (
71
- * <li key={item.kind === "message" ? item.message.id : item.toolCall.callId}>
72
- * {item.kind === "message" ? item.message.content : item.toolCall.name}
73
- * </li>
74
- * ))}
71
+ * {items.map((item) =>
72
+ * item.kind === "message" ? (
73
+ * <li key={item.message.id}>{item.message.content}</li>
74
+ * ) : item.kind === "tool" ? (
75
+ * <li key={item.toolCall.callId}>{item.toolCall.name}</li>
76
+ * ) : null,
77
+ * )}
75
78
  * </ul>
76
79
  * </ConsoleShell>
77
80
  * );
@@ -2,6 +2,7 @@ import { type FunctionComponent, type MemoExoticComponent } from "react";
2
2
  /**
3
3
  * Props of {@link Controls}.
4
4
  *
5
+ * @input
5
6
  * @public
6
7
  */
7
8
  export type ControlsProps = {
@@ -6,6 +6,7 @@ import type { UseUserTranscriptResult } from "../use-user-transcript.ts";
6
6
  /**
7
7
  * Props of {@link ConversationView}.
8
8
  *
9
+ * @input
9
10
  * @public
10
11
  */
11
12
  export type ConversationViewProps = {
@@ -2,6 +2,7 @@ import type { ReactNode } from "react";
2
2
  /**
3
3
  * Props for {@link Facts}.
4
4
  *
5
+ * @input
5
6
  * @public
6
7
  */
7
8
  export type FactsProps = {
@@ -1,4 +1,4 @@
1
- import type { InputHTMLAttributes, ReactNode, SelectHTMLAttributes, TextareaHTMLAttributes } from "react";
1
+ import type { InputHTMLAttributes, JSX, ReactNode, SelectHTMLAttributes, TextareaHTMLAttributes } from "react";
2
2
  import type { FieldShell, FileReadMode } from "./form-types.ts";
3
3
  /**
4
4
  * Label + control + hint, in the layout every field here uses.
@@ -36,7 +36,7 @@ export declare function Field({ label, hint, htmlFor, className, children, }: {
36
36
  className?: string | undefined;
37
37
  /** The control itself. */
38
38
  children: ReactNode;
39
- }): import("react").JSX.Element;
39
+ }): JSX.Element;
40
40
  /**
41
41
  * A single-line text input.
42
42
  *
@@ -47,7 +47,7 @@ export declare function Field({ label, hint, htmlFor, className, children, }: {
47
47
  *
48
48
  * @public
49
49
  */
50
- export declare function TextField(props: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className">): import("react").JSX.Element;
50
+ export declare function TextField(props: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className">): JSX.Element;
51
51
  /**
52
52
  * A number input. Contributes a NUMBER to {@link FormValues}, or nothing when
53
53
  * left empty.
@@ -60,7 +60,7 @@ export declare function TextField(props: FieldShell & Omit<InputHTMLAttributes<H
60
60
  *
61
61
  * @public
62
62
  */
63
- export declare function NumberField(props: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
63
+ export declare function NumberField(props: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): JSX.Element;
64
64
  /**
65
65
  * A multi-line text input.
66
66
  *
@@ -71,7 +71,7 @@ export declare function NumberField(props: FieldShell & Omit<InputHTMLAttributes
71
71
  *
72
72
  * @public
73
73
  */
74
- export declare function TextAreaField({ name, label, hint, className, rows, ...rest }: FieldShell & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "name" | "className">): import("react").JSX.Element;
74
+ export declare function TextAreaField({ name, label, hint, className, rows, ...rest }: FieldShell & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "name" | "className">): JSX.Element;
75
75
  /**
76
76
  * A dropdown.
77
77
  *
@@ -94,7 +94,7 @@ export declare function SelectField({ name, label, hint, className, options, chi
94
94
  value: string;
95
95
  label: string;
96
96
  })[];
97
- } & Omit<SelectHTMLAttributes<HTMLSelectElement>, "name" | "className">): import("react").JSX.Element;
97
+ } & Omit<SelectHTMLAttributes<HTMLSelectElement>, "name" | "className">): JSX.Element;
98
98
  /**
99
99
  * A checkbox. Contributes a BOOLEAN to {@link FormValues}.
100
100
  *
@@ -106,7 +106,7 @@ export declare function SelectField({ name, label, hint, className, options, chi
106
106
  *
107
107
  * @public
108
108
  */
109
- export declare function CheckboxField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
109
+ export declare function CheckboxField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): JSX.Element;
110
110
  /**
111
111
  * A file picker. Contributes a {@link FileValue} (or an array, with `multiple`)
112
112
  * to {@link FormValues} — or nothing when no file was chosen.
@@ -139,4 +139,4 @@ export declare function FileField({ name, label, hint, className, read, upload,
139
139
  read?: FileReadMode;
140
140
  /** Shorthand for `read="upload"` — see above. */
141
141
  upload?: boolean;
142
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
142
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): JSX.Element;
@@ -1,6 +1,6 @@
1
1
  /**
2
- * What a form's controls CONTRIBUTE — the three types both halves of the form
3
- * code share.
2
+ * What a form's controls CONTRIBUTE — the types both halves of the form code
3
+ * share, and {@link isFileValue}, the guard that reads one back.
4
4
  *
5
5
  * Their own module because `form.tsx` (the components) and `_form-values.ts`
6
6
  * (the DOM read) both need them, and a type living in one of those would make
@@ -18,6 +18,10 @@ export type FormValues = Record<string, unknown>;
18
18
  /**
19
19
  * What a {@link FileField} contributes to {@link FormValues}.
20
20
  *
21
+ * `FormValues` is `Record<string, unknown>`, so a page narrows the field's
22
+ * value with {@link isFileValue} rather than casting it.
23
+ *
24
+ * @sealed
21
25
  * @public
22
26
  */
23
27
  export type FileValue = {
@@ -35,6 +39,15 @@ export type FileValue = {
35
39
  */
36
40
  content?: string;
37
41
  };
42
+ /**
43
+ * Whether one {@link FormValues} entry is what a {@link FileField} contributed.
44
+ *
45
+ * A field with nothing chosen contributes no key at all, so the absent case is
46
+ * the ordinary one — this is `false` for `undefined`, not an error.
47
+ *
48
+ * @public
49
+ */
50
+ export declare function isFileValue(value: unknown): value is FileValue;
38
51
  /**
39
52
  * How much of a chosen file a {@link FileField} reads.
40
53
  *
@@ -54,6 +67,7 @@ export type FileReadMode = "none" | "text" | "dataUrl" | "upload";
54
67
  * from a documented one has to be reachable from the entry point too, which the
55
68
  * docs build enforces.
56
69
  *
70
+ * @input
57
71
  * @public
58
72
  */
59
73
  export type FieldShell = {
@@ -1,9 +1,14 @@
1
- import type { ButtonHTMLAttributes, FormHTMLAttributes, ReactNode } from "react";
1
+ import type { ButtonHTMLAttributes, FormHTMLAttributes, JSX, ReactNode } from "react";
2
2
  import { type ButtonSize, type ButtonVariant } from "./button.tsx";
3
3
  import type { FormValues } from "./form-types.ts";
4
4
  export { CheckboxField, Field, FileField, NumberField, SelectField, TextAreaField, TextField, } from "./form-fields.tsx";
5
5
  export type { FieldShell, FileReadMode, FileValue, FormValues } from "./form-types.ts";
6
- /** Props of {@link Form}. */
6
+ export { isFileValue } from "./form-types.ts";
7
+ /**
8
+ * Props of {@link Form}.
9
+ *
10
+ * @input
11
+ */
7
12
  export type FormProps = {
8
13
  /**
9
14
  * Called with the collected values. May be async — the form stays disabled
@@ -44,7 +49,7 @@ export type FormProps = {
44
49
  *
45
50
  * @public
46
51
  */
47
- export declare function Form({ onSubmit, error, children, className, ...rest }: FormProps): import("react").JSX.Element;
52
+ export declare function Form({ onSubmit, error, children, className, ...rest }: FormProps): JSX.Element;
48
53
  /**
49
54
  * The form's submit button, disabled and relabelled while a submit is in
50
55
  * flight.
@@ -93,4 +98,4 @@ export declare function SubmitButton({ children, pending, pendingLabel, size, va
93
98
  variant?: ButtonVariant | undefined;
94
99
  /** Additional CSS class names, appended to {@link Button}'s own. */
95
100
  className?: string | undefined;
96
- } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type" | "disabled" | "className">): import("react").JSX.Element;
101
+ } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type" | "disabled" | "className">): JSX.Element;
@@ -10,6 +10,7 @@ export type MarkdownVariant = "default" | "compact";
10
10
  /**
11
11
  * Props of {@link Markdown}.
12
12
  *
13
+ * @input
13
14
  * @public
14
15
  */
15
16
  export type MarkdownProps = {
@@ -4,6 +4,7 @@ import type { ConversationLogEntry } from "../conversation-log.ts";
4
4
  /**
5
5
  * Props of {@link MessageList}.
6
6
  *
7
+ * @input
7
8
  * @public
8
9
  */
9
10
  export type MessageListProps = {
@@ -1,3 +1,3 @@
1
1
  import "../context.js";
2
- import { t as MessageList } from "../message-list-DHZcLhRA.js";
2
+ import { t as MessageList } from "../message-list-BsaBkBgo.js";
3
3
  export { MessageList };
@@ -1,13 +1,16 @@
1
1
  import { type ReactNode } from "react";
2
2
  /**
3
- * Which of the four buttons a {@link SessionControlButton} is.
3
+ * Which button a {@link SessionControlButton} is: one of the four today. Open
4
+ * (`| (string & {})`) so a button added later is not a break — a `renderButton`
5
+ * keeps a default look for an action it does not know.
4
6
  *
5
7
  * @public
6
8
  */
7
- export type SessionControlAction = "start" | "toggle" | "restart" | "end";
9
+ export type SessionControlAction = "start" | "toggle" | "restart" | "end" | (string & {});
8
10
  /**
9
11
  * One button of {@link SessionControls}, as handed to `renderButton`.
10
12
  *
13
+ * @sealed
11
14
  * @public
12
15
  */
13
16
  export type SessionControlButton = {
@@ -27,6 +30,7 @@ export type SessionControlButton = {
27
30
  /**
28
31
  * The five words {@link SessionControls} renders, every one overridable.
29
32
  *
33
+ * @input
30
34
  * @public
31
35
  */
32
36
  export type SessionControlsLabels = {
@@ -44,6 +48,7 @@ export type SessionControlsLabels = {
44
48
  /**
45
49
  * Props of {@link SessionControls}.
46
50
  *
51
+ * @input
47
52
  * @public
48
53
  */
49
54
  export type SessionControlsProps = {
@@ -8,6 +8,7 @@ import type { ReactNode } from "react";
8
8
  * `createElement(SessionErrorBanner, { className })` caller unable to infer the
9
9
  * props at all, and gives the reference page nothing to link to.
10
10
  *
11
+ * @input
11
12
  * @public
12
13
  */
13
14
  export type SessionErrorBannerProps = {
@@ -1,5 +1,16 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { AgentState } from "../types.ts";
3
+ /**
4
+ * Indicator dot colour per state, from the theme — `ConsoleShell`'s dot, and
5
+ * {@link SessionStateDot}'s for every state its `colors` does not name.
6
+ *
7
+ * `idle` is the theme's own faint ink step rather than a fixed warm grey, so
8
+ * the dot stays visible on a dark ground; the thinking amber and error red
9
+ * are semantic and stay fixed. A state this version does not know is `idle`.
10
+ *
11
+ * @internal
12
+ */
13
+ export declare function stateColor(state: AgentState, primary: string, idle: string): string;
3
14
  /**
4
15
  * The dot itself: a coloured circle, pulsing or still.
5
16
  *
@@ -27,20 +38,22 @@ export declare function StateDot({ color, pulseMs, className, title, }: {
27
38
  /**
28
39
  * Props of {@link SessionStateDot}.
29
40
  *
41
+ * @input
30
42
  * @public
31
43
  */
32
44
  export type SessionStateDotProps = {
33
45
  /**
34
- * The dot's colour per {@link AgentState} — the chrome's own palette. A
35
- * complete record, so a state added upstream is a compile error here rather
36
- * than a silently unpainted dot; `satisfies Record<AgentState, string>` on the
37
- * caller's literal is the shape to write it in.
46
+ * The dot's colour per {@link AgentState} — the chrome's own palette. Any
47
+ * state not named (including one a later release adds) is painted the way
48
+ * `ConsoleShell` paints it, from the theme: the primary colour while live, a
49
+ * fixed amber while thinking, red on error, a faint ink otherwise.
38
50
  */
39
- colors: Readonly<Record<AgentState, string>>;
51
+ colors?: Partial<Readonly<Record<AgentState, string>>> | undefined;
40
52
  /**
41
53
  * The words this chrome has a better term for. Anything not named falls back
42
54
  * to {@link AGENT_STATE_LABELS}, so a page overrides one member (`speaking:
43
- * "Narrating"`) without restating the union.
55
+ * "Narrating"`) without restating the union; a state neither names is shown
56
+ * as its raw value.
44
57
  */
45
58
  labels?: Partial<Readonly<Record<AgentState, string>>> | undefined;
46
59
  /**
@@ -72,7 +85,7 @@ export type SessionStateDotProps = {
72
85
  * against a dot component on the grounds that it would take the shared part
73
86
  * (the words) hostage to the part that is not (the palette); this takes the
74
87
  * palette as a prop precisely so it does not. What is shared is the structure
75
- * — the exhaustive colour lookup, the label fallback, the pulse rule, the
88
+ * — the colour lookup and its theme fallback, the label fallback, the pulse rule, the
76
89
  * `useSessionStatus()` subscription that keeps the rest of the header from
77
90
  * re-rendering at STT-partial rate.
78
91
  *
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import type { JSX, ReactNode } from "react";
2
2
  /**
3
3
  * A two-column layout with a fixed-width sidebar and a flexible main area.
4
4
  * Commonly used to pair a custom sidebar (cart, dashboard) with `<ChatView />`.
@@ -39,4 +39,4 @@ export declare function SidebarLayout({ sidebar, children, sidebarWidth, sidebar
39
39
  sidebarPosition?: "left" | "right" | undefined;
40
40
  /** Additional CSS class names for the root element, appended to its own. */
41
41
  className?: string;
42
- }): import("react").JSX.Element;
42
+ }): JSX.Element;