@alexkroman1/aai-ui 0.12.3 → 0.13.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 (201) hide show
  1. package/README.md +257 -0
  2. package/dist/_colors-CpZO-88A.js +78 -0
  3. package/dist/_module-url-C13kAJ87.js +15 -0
  4. package/dist/_page-shell.d.ts +11 -0
  5. package/dist/_recover-run.d.ts +79 -0
  6. package/dist/_repeat-until.d.ts +30 -0
  7. package/dist/_run-controls.d.ts +33 -0
  8. package/dist/_submission-state.d.ts +92 -0
  9. package/dist/_tap-to-talk-state.d.ts +88 -0
  10. package/dist/_utils-Mi-SCFA1.js +47 -0
  11. package/dist/_utils.d.ts +26 -0
  12. package/dist/_web-storage.d.ts +43 -0
  13. package/dist/_workflow-api-ref.d.ts +37 -0
  14. package/dist/_workflow-files.d.ts +34 -0
  15. package/dist/_workflow-test-defs.d.ts +38 -0
  16. package/dist/aai-logo-D8pMVn9_.js +85 -0
  17. package/dist/agent-state-labels.d.ts +65 -0
  18. package/dist/agent-state.d.ts +108 -0
  19. package/dist/audio/capture.d.ts +44 -0
  20. package/dist/audio/index.d.ts +18 -0
  21. package/dist/audio/index.js +431 -0
  22. package/dist/audio/preconnect.d.ts +87 -0
  23. package/dist/audio/voice-io.d.ts +112 -0
  24. package/dist/build-default-client.d.ts +1 -0
  25. package/dist/chat-view-BCbI7gD4.js +396 -0
  26. package/dist/client-config-C7fQrioM.js +139 -0
  27. package/dist/client-config.d.ts +119 -0
  28. package/dist/client-dir.d.ts +44 -0
  29. package/dist/client-dir.js +58 -0
  30. package/dist/client-identity.d.ts +131 -0
  31. package/dist/client-tool.d.ts +51 -0
  32. package/dist/components/_colors.d.ts +73 -0
  33. package/dist/components/_form-readiness.d.ts +56 -0
  34. package/dist/components/_form-values.d.ts +19 -0
  35. package/dist/components/aai-logo.d.ts +12 -0
  36. package/dist/components/audio-result.d.ts +94 -0
  37. package/dist/components/auto-scroll.d.ts +74 -0
  38. package/dist/components/bullet-list.d.ts +74 -0
  39. package/dist/components/button.d.ts +29 -21
  40. package/dist/components/button.js +62 -23
  41. package/dist/components/chat-view.d.ts +24 -18
  42. package/dist/components/chat-view.js +2 -60
  43. package/dist/components/console-shell.d.ts +85 -0
  44. package/dist/components/controls.d.ts +21 -6
  45. package/dist/components/controls.js +31 -19
  46. package/dist/components/conversation-view.d.ts +130 -0
  47. package/dist/components/eyebrow.d.ts +12 -0
  48. package/dist/components/facts.d.ts +81 -0
  49. package/dist/components/form-fields.d.ts +142 -0
  50. package/dist/components/form-types.d.ts +73 -0
  51. package/dist/components/form.d.ts +96 -0
  52. package/dist/components/markdown.d.ts +57 -0
  53. package/dist/components/message-list.d.ts +34 -7
  54. package/dist/components/message-list.js +2 -75
  55. package/dist/components/session-controls.d.ts +125 -0
  56. package/dist/components/session-error-banner.d.ts +69 -0
  57. package/dist/components/session-state-dot.d.ts +111 -0
  58. package/dist/components/sidebar-layout.d.ts +31 -10
  59. package/dist/components/sidebar-layout.js +32 -12
  60. package/dist/components/start-screen.d.ts +17 -6
  61. package/dist/components/start-screen.js +34 -14
  62. package/dist/components/tool-call-block.d.ts +15 -14
  63. package/dist/components/tool-call-block.js +2 -117
  64. package/dist/components/tool-call-row.d.ts +75 -0
  65. package/dist/components/tool-config-context.d.ts +22 -0
  66. package/dist/components/upload-progress.d.ts +76 -0
  67. package/dist/components/url-chips.d.ts +29 -0
  68. package/dist/components/workflow-fields.d.ts +46 -0
  69. package/dist/components/workflow-pending-note.d.ts +81 -0
  70. package/dist/components/workflow-progress.d.ts +81 -0
  71. package/dist/components/workflow-run-error.d.ts +48 -0
  72. package/dist/components/workflow-run-panel.d.ts +79 -0
  73. package/dist/context.d.ts +288 -0
  74. package/dist/context.js +382 -0
  75. package/dist/conversation-log.d.ts +88 -0
  76. package/dist/default-client/assets/_module-url-BX0RuRU2.js +1 -0
  77. package/dist/default-client/assets/audio-cGFGID-2.js +1 -0
  78. package/dist/default-client/assets/capture-processor-BUABoo3_.js +90 -0
  79. package/dist/default-client/assets/index-8ihb1Urm.css +2 -0
  80. package/dist/default-client/assets/index-BQURVARl.js +126 -0
  81. package/dist/default-client/assets/playback-processor-ABOa11j0.js +314 -0
  82. package/dist/default-client/favicon.ico +0 -0
  83. package/dist/default-client/index.html +15 -0
  84. package/dist/default-client.d.ts +23 -0
  85. package/dist/define-client.d.ts +162 -26
  86. package/dist/define-client.js +201 -55
  87. package/dist/eyebrow-UfmSz9yy.js +27 -0
  88. package/dist/hooks-DN4gHYsj.js +182 -0
  89. package/dist/hooks.d.ts +172 -0
  90. package/dist/hooks.js +3 -0
  91. package/dist/hooks.test-d.d.ts +14 -0
  92. package/dist/inbox-protocol.d.ts +128 -0
  93. package/dist/inbox.d.ts +132 -0
  94. package/dist/index.d.ts +126 -29
  95. package/dist/index.js +5500 -15
  96. package/dist/internal.d.ts +43 -0
  97. package/dist/internal.js +8 -0
  98. package/dist/linked-client.d.ts +70 -0
  99. package/dist/message-list-DHZcLhRA.js +682 -0
  100. package/dist/notice-player.d.ts +70 -0
  101. package/dist/page.d.ts +114 -0
  102. package/dist/phone.d.ts +50 -0
  103. package/dist/route-fetch.d.ts +79 -0
  104. package/dist/session/audio-effects.d.ts +31 -0
  105. package/dist/session/audio-setup.d.ts +57 -0
  106. package/dist/session/audio-state.d.ts +157 -0
  107. package/dist/session/browser-session.d.ts +30 -0
  108. package/dist/session/close.d.ts +26 -0
  109. package/dist/session/dial.d.ts +65 -0
  110. package/dist/session/handshake.d.ts +60 -0
  111. package/dist/session/index.d.ts +17 -0
  112. package/dist/session/index.js +2 -0
  113. package/dist/session/messages.d.ts +63 -0
  114. package/dist/session/mic.d.ts +64 -0
  115. package/dist/session/preconnect.d.ts +48 -0
  116. package/dist/session/reconnect.d.ts +25 -0
  117. package/dist/session/resume-store.d.ts +57 -0
  118. package/dist/session/state.d.ts +146 -0
  119. package/dist/session/ticket.d.ts +44 -0
  120. package/dist/session/types.d.ts +476 -0
  121. package/dist/session/url.d.ts +17 -0
  122. package/dist/session/user-turn.d.ts +55 -0
  123. package/dist/session-CE0Ipsb3.js +2129 -0
  124. package/dist/stored-value.d.ts +103 -0
  125. package/dist/tool-call-block-uXtMOUWN.js +204 -0
  126. package/dist/tool-config-context-Es4YUzV2.js +19 -0
  127. package/dist/types.d.ts +272 -34
  128. package/dist/types.js +35 -4
  129. package/dist/upload/files.d.ts +83 -0
  130. package/dist/upload/index.d.ts +15 -0
  131. package/dist/upload/pause.d.ts +31 -0
  132. package/dist/upload/recall.d.ts +67 -0
  133. package/dist/upload/report.d.ts +26 -0
  134. package/dist/upload/session.d.ts +99 -0
  135. package/dist/url-chips-oyy_Eiqh.js +239 -0
  136. package/dist/use-client-runs.d.ts +87 -0
  137. package/dist/use-conversation-log.d.ts +86 -0
  138. package/dist/use-conversation.d.ts +131 -0
  139. package/dist/use-copy.d.ts +74 -0
  140. package/dist/use-download-url.d.ts +84 -0
  141. package/dist/use-flash.d.ts +61 -0
  142. package/dist/use-inbox.d.ts +101 -0
  143. package/dist/use-push-to-talk.d.ts +105 -0
  144. package/dist/use-route-mutation.d.ts +113 -0
  145. package/dist/use-route.d.ts +82 -0
  146. package/dist/use-run-key.d.ts +133 -0
  147. package/dist/use-session-controls.d.ts +69 -0
  148. package/dist/use-session-id.d.ts +57 -0
  149. package/dist/use-tap-to-talk.d.ts +138 -0
  150. package/dist/use-user-transcript-uyHhzy4d.js +73 -0
  151. package/dist/use-user-transcript.d.ts +75 -0
  152. package/dist/use-workflow-form.d.ts +285 -0
  153. package/dist/use-workflow-progress.d.ts +137 -0
  154. package/dist/use-workflow-run-DdhWmbx-.js +697 -0
  155. package/dist/use-workflow-run.d.ts +100 -0
  156. package/dist/use-workflow-runs.d.ts +71 -0
  157. package/dist/use-workflow-stream.d.ts +154 -0
  158. package/dist/use-workflows.d.ts +77 -0
  159. package/dist/workflow-client.d.ts +136 -0
  160. package/dist/workflow-def-types.d.ts +31 -0
  161. package/dist/workflow-events.d.ts +39 -0
  162. package/dist/workflow-field-kind.d.ts +95 -0
  163. package/dist/workflow-status-labels.d.ts +35 -0
  164. package/dist/worklets/_module-url.d.ts +10 -0
  165. package/dist/worklets/_playback-bench-harness.d.ts +181 -0
  166. package/dist/worklets/_playback-bench-host.d.ts +63 -0
  167. package/dist/worklets/_playback-bench-page.d.ts +65 -0
  168. package/dist/worklets/_tts-trace-harness.d.ts +142 -0
  169. package/dist/worklets/_worklet-test-utils.d.ts +27 -0
  170. package/dist/worklets/capture-processor.d.ts +4 -2
  171. package/dist/worklets/capture-processor.js +73 -33
  172. package/dist/worklets/playback-processor.d.ts +4 -2
  173. package/dist/worklets/playback-processor.js +258 -42
  174. package/package.json +57 -32
  175. package/styles.css +152 -30
  176. package/dist/audio.d.ts +0 -45
  177. package/dist/audio.js +0 -121
  178. package/dist/client-context.d.ts +0 -33
  179. package/dist/client-context.js +0 -15
  180. package/dist/client-handler.d.ts +0 -43
  181. package/dist/components/app.d.ts +0 -23
  182. package/dist/components/app.js +0 -41
  183. package/dist/components/error-banner.d.ts +0 -21
  184. package/dist/components/error-banner.js +0 -27
  185. package/dist/components/message-bubble.d.ts +0 -23
  186. package/dist/components/message-bubble.js +0 -35
  187. package/dist/components/state-indicator.d.ts +0 -29
  188. package/dist/components/state-indicator.js +0 -37
  189. package/dist/components/thinking-indicator.d.ts +0 -16
  190. package/dist/components/thinking-indicator.js +0 -34
  191. package/dist/components/tool-icons.d.ts +0 -17
  192. package/dist/components/tool-icons.js +0 -128
  193. package/dist/components/transcript.d.ts +0 -25
  194. package/dist/components/transcript.js +0 -35
  195. package/dist/session-CWB7vmqz.js +0 -429
  196. package/dist/session.d.ts +0 -69
  197. package/dist/session.js +0 -2
  198. package/dist/signals.d.ts +0 -120
  199. package/dist/signals.js +0 -161
  200. package/dist/tsdown.config.d.ts +0 -2
  201. package/dist/types.test-d.d.ts +0 -7
@@ -1,118 +1,3 @@
1
- import { BoltIcon, ChatBubbleIcon, DownloadIcon, ExternalLinkIcon, SearchIcon, TerminalIcon } from "./tool-icons.js";
2
- import clsx from "clsx";
3
- import { useComputed, useSignal } from "@preact/signals";
4
- import { jsx, jsxs } from "preact/jsx-runtime";
5
- //#region components/tool-call-block.tsx
6
- const argField = (key) => (args) => String(args[key] ?? "");
7
- const TOOL_CONFIG = {
8
- web_search: {
9
- Icon: SearchIcon,
10
- title: "Web Search",
11
- subtitle: argField("query")
12
- },
13
- visit_webpage: {
14
- Icon: ExternalLinkIcon,
15
- title: "Visit Page",
16
- subtitle: argField("url")
17
- },
18
- run_code: {
19
- Icon: TerminalIcon,
20
- title: "Run Code",
21
- subtitle: (args) => {
22
- const firstLine = String(args.code ?? "").split("\n")[0] ?? "";
23
- return firstLine.length > 80 ? `${firstLine.slice(0, 80)}...` : firstLine;
24
- }
25
- },
26
- fetch_json: {
27
- Icon: DownloadIcon,
28
- title: "Fetch JSON",
29
- subtitle: argField("url")
30
- },
31
- user_input: {
32
- Icon: ChatBubbleIcon,
33
- title: "Asking User",
34
- subtitle: argField("question")
35
- }
36
- };
37
- const DEFAULT_CONFIG = {
38
- Icon: BoltIcon,
39
- title: "",
40
- subtitle: (args) => {
41
- const summary = JSON.stringify(args);
42
- return summary.length > 80 ? `${summary.slice(0, 80)}...` : summary;
43
- }
44
- };
45
- function formatResult(result) {
46
- try {
47
- return JSON.stringify(JSON.parse(result), null, 2);
48
- } catch {
49
- return result;
50
- }
51
- }
52
- /**
53
- * Renders a tool invocation with an icon, title, subtitle, and a
54
- * collapsible result viewer.
55
- *
56
- * Built-in tool types (`web_search`, `visit_webpage`, `run_code`,
57
- * `fetch_json`, `user_input`) get custom icons and labels. Unknown tools
58
- * fall back to a generic bolt icon.
59
- *
60
- * While the tool call is pending a shimmer animation is shown. Once
61
- * complete, clicking the block expands the formatted JSON result.
62
- *
63
- * @example
64
- * ```tsx
65
- * <ToolCallBlock toolCall={toolCall} />
66
- * ```
67
- *
68
- * @param toolCall - The tool call to render (see {@link ToolCallInfo}).
69
- * @param className - Additional CSS class names.
70
- *
71
- * @public
72
- */
73
- function ToolCallBlock({ toolCall, className }) {
74
- const isOpen = useSignal(false);
75
- const config = TOOL_CONFIG[toolCall.toolName] ?? DEFAULT_CONFIG;
76
- const isPending = toolCall.status === "pending";
77
- const title = config.title || toolCall.toolName;
78
- const canExpand = !isPending && Boolean(toolCall.result);
79
- const formatted = useComputed(() => toolCall.result ? formatResult(toolCall.result) : "");
80
- return /* @__PURE__ */ jsxs("div", {
81
- class: clsx("flex flex-col", className),
82
- children: [/* @__PURE__ */ jsxs("button", {
83
- type: "button",
84
- "aria-expanded": canExpand ? isOpen.value : void 0,
85
- disabled: isPending,
86
- class: clsx("flex items-center gap-2 px-3 py-2 rounded-aai border border-aai-border bg-aai-surface-faint select-none text-left w-full", canExpand && "cursor-pointer"),
87
- onClick: () => {
88
- if (canExpand) isOpen.value = !isOpen.value;
89
- },
90
- children: [
91
- /* @__PURE__ */ jsx(config.Icon, { class: "w-4 h-4 text-aai-text-dim shrink-0" }),
92
- /* @__PURE__ */ jsx("span", {
93
- class: clsx("text-sm font-medium text-aai-text", isPending && "tool-shimmer"),
94
- children: title
95
- }),
96
- /* @__PURE__ */ jsx("span", {
97
- class: "text-sm text-aai-text-dim truncate flex-1 min-w-0",
98
- children: config.subtitle(toolCall.args)
99
- }),
100
- canExpand && /* @__PURE__ */ jsx("span", {
101
- class: "text-xs text-aai-text-dim shrink-0",
102
- children: isOpen.value ? "▾" : "▸"
103
- })
104
- ]
105
- }), isOpen.value && /* @__PURE__ */ jsxs("div", {
106
- class: "border-x border-b border-aai-border rounded-b-aai bg-aai-surface max-h-64 overflow-auto",
107
- children: [toolCall.toolName === "run_code" && toolCall.args.code && /* @__PURE__ */ jsx("pre", {
108
- class: "text-xs text-aai-text p-2 whitespace-pre-wrap border-b border-aai-border font-mono",
109
- children: String(toolCall.args.code)
110
- }), formatted.value && /* @__PURE__ */ jsx("pre", {
111
- class: "text-xs text-aai-text-dim p-2 whitespace-pre-wrap",
112
- children: formatted.value
113
- })]
114
- })]
115
- });
116
- }
117
- //#endregion
1
+ import "../context.js";
2
+ import { t as ToolCallBlock } from "../tool-call-block-uXtMOUWN.js";
118
3
  export { ToolCallBlock };
@@ -0,0 +1,75 @@
1
+ import { type ReactNode } from "react";
2
+ /**
3
+ * Size preset for {@link ToolCallRow}: `"default"` is the deployed agent
4
+ * UI's scale, `"compact"` the studio transcript's denser one.
5
+ *
6
+ * @public
7
+ */
8
+ export type ToolCallRowVariant = "default" | "compact";
9
+ /**
10
+ * Props for {@link ToolCallRow}.
11
+ *
12
+ * @public
13
+ */
14
+ export interface ToolCallRowProps {
15
+ /** Tool title, rendered in mono (shimmers while `pending`). */
16
+ title: ReactNode;
17
+ /** One-line detail (typically an args preview), truncated to the row. */
18
+ detail?: ReactNode | undefined;
19
+ /** True while the call is in flight — animates the title with a shimmer. */
20
+ pending?: boolean | undefined;
21
+ /** Optional icon rendered in place of the outlined "TOOL" chip. */
22
+ icon?: ReactNode | undefined;
23
+ /** Size preset; defaults to `"default"`. */
24
+ variant?: ToolCallRowVariant | undefined;
25
+ /** Additional CSS class names for the outer container. */
26
+ className?: string | undefined;
27
+ /**
28
+ * Expanded panel content. When present the row is expandable: a chevron is
29
+ * shown and clicking toggles the panel. When absent the row is inert (the
30
+ * button is disabled). Content provides its own padding and typography;
31
+ * the panel supplies the top border, surface background, and a max height.
32
+ */
33
+ children?: ReactNode;
34
+ }
35
+ /**
36
+ * The design system's console row for one tool invocation: a small outlined
37
+ * "TOOL" chip (or a custom `icon`), the tool title in mono, a truncated
38
+ * detail preview, and a rotating chevron that expands to the panel content.
39
+ *
40
+ * Purely presentational — callers own the mapping from their tool-call data
41
+ * to `title`/`detail`/`pending` and the expanded panel. The deployed agent
42
+ * UI's message list renders it via its tool-call block, and the studio's
43
+ * chat transcript renders it with `variant="compact"`, so the two surfaces
44
+ * read as one component.
45
+ *
46
+ * Colors come from the nearest theme context (see {@link useTheme}); without
47
+ * a provider the default AssemblyAI theme applies.
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * import { ToolCallRow, useSession } from "@alexkroman1/aai-ui";
52
+ *
53
+ * // A custom chrome's tool log, from the snapshot's own `toolCalls`.
54
+ * function ToolLog() {
55
+ * const { toolCalls } = useSession();
56
+ * return (
57
+ * <div>
58
+ * {toolCalls.map((call) => (
59
+ * <ToolCallRow
60
+ * key={call.callId}
61
+ * title={call.name}
62
+ * detail={call.result}
63
+ * pending={call.status === "pending"}
64
+ * />
65
+ * ))}
66
+ * </div>
67
+ * );
68
+ * }
69
+ * ```
70
+ *
71
+ * @param props - See {@link ToolCallRowProps}.
72
+ *
73
+ * @public
74
+ */
75
+ export declare function ToolCallRow({ title, detail, pending, icon, variant, className, children, }: ToolCallRowProps): ReactNode;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Display configuration for a tool call in the UI.
3
+ *
4
+ * @public
5
+ */
6
+ export type ToolDisplayConfig = Record<string, {
7
+ icon?: string;
8
+ label?: string;
9
+ }>;
10
+ /**
11
+ * Context for tool display configuration. Installed by `mountClient()` from
12
+ * `ClientConfig.tools`; the built-in components read it via `useToolConfig`.
13
+ *
14
+ * @internal
15
+ */
16
+ export declare const ToolConfigContext: import("react").Context<ToolDisplayConfig>;
17
+ /**
18
+ * Read tool display configuration from the nearest `ToolConfigContext.Provider`.
19
+ *
20
+ * @internal
21
+ */
22
+ export declare function useToolConfig(): ToolDisplayConfig;
@@ -0,0 +1,76 @@
1
+ import { type ReactNode } from "react";
2
+ import type { UploadStatus } from "../use-workflow-form.ts";
3
+ /**
4
+ * How far a form's files have got, rendered as a bar.
5
+ *
6
+ * The wait this covers is the one a run cannot describe: a workflow run does not
7
+ * EXIST until its input is stored, so from the moment a form is submitted until
8
+ * the last byte lands there is no run id, no status, and nothing for
9
+ * `<WorkflowProgress>` to read — which for a 200 MB recording is minutes of a
10
+ * page that looks stuck. `useWorkflowSubmit` reports the bytes as they go and
11
+ * this is what draws them.
12
+ *
13
+ * Three things it decides, so a page does not:
14
+ *
15
+ * - **It renders nothing when there is nothing to describe.** `upload` is
16
+ * undefined before the first byte and again from the moment the last one
17
+ * lands, so `<UploadProgressBar upload={upload} />` is correct unguarded and a
18
+ * form with no files never shows a bar at all.
19
+ * - **An unknown total is INDETERMINATE, not zero.** A body whose length the
20
+ * transport cannot state up front (see `UploadProgress.total`) has no honest
21
+ * width, and a bar pinned at 0% reads as an upload that is not moving.
22
+ * - **The file is NAMED, and counted when there is more than one.** Files are
23
+ * sent one after another, so a single bar otherwise appears to restart from
24
+ * zero partway through with nothing to say why.
25
+ * - **A paused upload SAYS SO, rather than being a bar that stopped.** Those look
26
+ * identical, which is the whole reason `UploadStatus.paused` exists, and the
27
+ * fill stops animating so the difference is visible without reading.
28
+ *
29
+ * The pause control appears only when a handler for it is passed. That is not
30
+ * politeness about props: a button whose press does nothing is worse than no
31
+ * button, and a page holding an `upload` it did not produce (a saved status, a
32
+ * parent's state) has nothing to pause.
33
+ *
34
+ * @example
35
+ * ```tsx no-check
36
+ * import { Form, SubmitButton, UploadProgressBar, useWorkflowSubmit, WorkflowFields } from "@alexkroman1/aai-ui";
37
+ * import type { transcribe } from "./agent.ts";
38
+ *
39
+ * function TranscribeForm() {
40
+ * const { submitForm, upload, pending, error } = useWorkflowSubmit<typeof transcribe>("transcribe");
41
+ * return (
42
+ * <Form onSubmit={submitForm} error={error}>
43
+ * <WorkflowFields workflow="transcribe" />
44
+ * <UploadProgressBar upload={upload} />
45
+ * <SubmitButton pending={pending}>Transcribe</SubmitButton>
46
+ * </Form>
47
+ * );
48
+ * }
49
+ * ```
50
+ *
51
+ * @param props - Progress-bar props.
52
+ *
53
+ * @public
54
+ */
55
+ export declare function UploadProgressBar({ upload, onPause, onResume, className, }: {
56
+ /**
57
+ * What `useWorkflowSubmit` / `useWorkflowStream` report as `upload`.
58
+ * `undefined` renders nothing, so a page may pass its state straight through
59
+ * and never guard the element.
60
+ */
61
+ upload?: UploadStatus | undefined;
62
+ /**
63
+ * The hook's `pauseUpload`. **Pass it together with `onResume`** to get the
64
+ * pause control; pass neither for a bar that only reports. One without the
65
+ * other is a one-way door drawn as a toggle, so the control is hidden unless
66
+ * both are present.
67
+ */
68
+ onPause?: (() => void) | undefined;
69
+ /** The hook's `resumeUpload`. See `onPause` — the two travel together. */
70
+ onResume?: (() => void) | undefined;
71
+ /**
72
+ * **Replaces** the default classes rather than extending them, so a custom
73
+ * chrome is not fighting a default it did not ask for.
74
+ */
75
+ className?: string | undefined;
76
+ }): ReactNode;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The session's shareable UI URL — the page this UI is served from, what
3
+ * you'd send someone to talk to the agent.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare function UiUrlChip({ className }: {
8
+ className?: string | undefined;
9
+ }): import("react").JSX.Element;
10
+ /**
11
+ * The session's programmatic WebSocket endpoint — the URL a script or backend
12
+ * can connect to directly instead of using this UI.
13
+ *
14
+ * @internal
15
+ */
16
+ export declare function ApiUrlChip({ className }: {
17
+ className?: string | undefined;
18
+ }): import("react").JSX.Element;
19
+ /**
20
+ * The UI and API URLs side by side. They answer the same question — "how do I
21
+ * reach this agent?" — so they belong together and each needs its label to be
22
+ * told apart. Rendered by the default shell in every session mode (S2S,
23
+ * pipeline).
24
+ *
25
+ * @internal
26
+ */
27
+ export declare function SessionUrlChips({ className }: {
28
+ className?: string | undefined;
29
+ }): import("react").JSX.Element;
@@ -0,0 +1,46 @@
1
+ import type { WorkflowSummary } from "@alexkroman1/aai/workflow-api";
2
+ /**
3
+ * Render one field per scalar property of a workflow's input schema.
4
+ *
5
+ * Pass the workflow's NAME and the schema is fetched here; pass a
6
+ * {@link WorkflowSummary} you already hold and nothing is fetched. The name form
7
+ * is the one a page usually wants — it is the same string the submit hook takes,
8
+ * and the alternative is three lines (`useWorkflows()`, a `.find()` by name, and
9
+ * folding that lookup's error into the form's) whose only product is this
10
+ * component's argument.
11
+ *
12
+ * Renders nothing when the workflow declared no schema — a workflow with no
13
+ * declared input takes anything, and a form for "anything" is not a form — and
14
+ * nothing while a named lookup is still in flight, so the hand-written fields
15
+ * beside it are not reordered when the schema lands.
16
+ *
17
+ * @example
18
+ * ```tsx no-check
19
+ * import { Form, SubmitButton, WorkflowFields, useWorkflowSubmit }
20
+ * from "@alexkroman1/aai-ui";
21
+ * import type { transcribe } from "./agent.ts";
22
+ *
23
+ * function StartRun() {
24
+ * const { submitForm, pending, error } = useWorkflowSubmit<typeof transcribe>("transcribe");
25
+ * return (
26
+ * <Form onSubmit={submitForm} error={error}>
27
+ * <WorkflowFields workflow="transcribe" />
28
+ * <SubmitButton pending={pending}>Transcribe</SubmitButton>
29
+ * </Form>
30
+ * );
31
+ * }
32
+ * ```
33
+ *
34
+ * @param props - Field-set props.
35
+ *
36
+ * @public
37
+ */
38
+ export declare function WorkflowFields({ workflow, }: {
39
+ /**
40
+ * The workflow whose input schema to render. A NAME is looked up here (one
41
+ * `GET workflows`); a {@link WorkflowSummary} the page already holds fetches
42
+ * nothing. `undefined` renders nothing, so a page may pass a selection
43
+ * straight through before one is made.
44
+ */
45
+ workflow?: WorkflowSummary | string | undefined;
46
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,81 @@
1
+ import type { ReactNode } from "react";
2
+ import type { WorkflowRun } from "../workflow-client.ts";
3
+ /**
4
+ * Props for {@link WorkflowPendingNote}.
5
+ *
6
+ * @public
7
+ */
8
+ export type WorkflowPendingNoteProps = {
9
+ /**
10
+ * The submission the page is rendering — `useWorkflowSubmit`'s or
11
+ * `useWorkflowStream`'s result, or any object carrying these three fields.
12
+ * Nothing renders while `pending` is false.
13
+ */
14
+ submission: {
15
+ readonly pending: boolean;
16
+ readonly startedHere: boolean;
17
+ readonly run: WorkflowRun | undefined;
18
+ };
19
+ /**
20
+ * What the run produces, as the noun the sentences name: `"draft"`,
21
+ * `"summary"`, `"transcript"`. Default `"run"`.
22
+ */
23
+ subject?: string | undefined;
24
+ /**
25
+ * Where the key that finds the run again lives. `"tab"` (the default) is
26
+ * `useWorkflowSubmit`'s own `sessionStorage` key; `"browser"` is a page that
27
+ * passed `useRunKey({ storage: "local" })`, whose runs any tab on this browser
28
+ * can find — so the sentence says "this browser" and stops promising that
29
+ * closing the tab loses anything.
30
+ */
31
+ scope?: "tab" | "browser" | undefined;
32
+ /**
33
+ * ADDED to the note's own `text-sm opacity-70` rather than replacing it.
34
+ * There is no `tailwind-merge` in this package, so a class that CONFLICTS with
35
+ * a base one is not reliably the winner.
36
+ */
37
+ className?: string | undefined;
38
+ };
39
+ /**
40
+ * The one sentence a page says while a run is in flight — three situations,
41
+ * one line each — as a muted line under the form, and nothing otherwise.
42
+ *
43
+ * Six template pages had each written the function under this, byte-identical
44
+ * in control flow and different only in the noun, under a doc arguing the same
45
+ * two things. Both survive here, once:
46
+ *
47
+ * - **The reload case gets its own words.** `!startedHere && run` is a run in
48
+ * front of somebody who did not press anything — a reload, or another tab on
49
+ * the same key — and they are owed an explanation for work appearing, plus
50
+ * the line that stops them starting it again. The sentence a page reaches for
51
+ * instead ("you can close this tab") was true about the RUN and false about
52
+ * the page for as long as a reload could not find its run.
53
+ * - **The lookup is a state, not an absence.** `!startedHere && !run` is the
54
+ * stretch on a reload where the key is being resolved and an empty form would
55
+ * read as "nothing is happening". It is the same length as the request.
56
+ *
57
+ * The render site had drifted too — three pages muted the line and two did not
58
+ * — so the typography is the component's, in the same `text-sm opacity-70`
59
+ * every other muted line on these pages uses.
60
+ *
61
+ * `startedHere`, `run` and `pending` are what {@link WorkflowSubmission}
62
+ * reports, which is why the prop is the submission itself rather than three
63
+ * booleans a page would re-derive. A page with a FOURTH situation — a run that a
64
+ * reload does not recover but ENDS, as `transcription-workflow`'s streaming
65
+ * flow has — writes its own sentence, and that template is the one doing so.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * import { useWorkflowSubmit, WorkflowPendingNote } from "@alexkroman1/aai-ui";
70
+ *
71
+ * function App() {
72
+ * const submission = useWorkflowSubmit("redline");
73
+ * return <WorkflowPendingNote submission={submission} subject="draft" />;
74
+ * }
75
+ * ```
76
+ *
77
+ * @param props - See {@link WorkflowPendingNoteProps}.
78
+ *
79
+ * @public
80
+ */
81
+ export declare function WorkflowPendingNote({ submission, subject, scope, className, }: WorkflowPendingNoteProps): ReactNode;
@@ -0,0 +1,81 @@
1
+ import { type ReactNode } from "react";
2
+ import type { WorkflowApi } from "../workflow-client.ts";
3
+ /**
4
+ * What a run has said so far, rendered.
5
+ *
6
+ * The complement of a status line, and the reason both exist: a run is
7
+ * `running` for its whole life, so a one-round job and a ten-round one look
8
+ * identical while they happen. These lines come from the run itself (`stepReport()`
9
+ * in a `"use step"` body), which is the only channel a workflow has before it
10
+ * produces an output.
11
+ *
12
+ * Four rules are baked in, and they are why this is a component rather than
13
+ * three lines each page writes for itself — the two templates that had written
14
+ * it had written three of them, comments included:
15
+ *
16
+ * - **It renders nothing until there is something to render.** `supported` is
17
+ * what keeps this from being an empty box forever on an agent deployed before
18
+ * progress streams existed: "wrote nothing yet" and "serves no stream" are
19
+ * indistinguishable from the chunk list alone.
20
+ * - **The lines are TEXT, not elements.** They are append-only and two rounds
21
+ * legitimately produce identical text, so there is no stable per-line key to
22
+ * give React. Joining sidesteps the question instead of suppressing the lint
23
+ * rule that asks it.
24
+ * - **They REPLAY.** Chunks are retained with the run, so a reload mid-run —
25
+ * or opening a finished run tomorrow — shows how it got there rather than an
26
+ * empty box. That is `useWorkflowProgress`'s doing; this is what makes it
27
+ * visible.
28
+ * - **They are ANNOUNCED**, for the reason the first paragraph gives: this is
29
+ * the only channel a run has before it produces an output, and a `<pre>` that
30
+ * grows is a silent one. A screen-reader user pressing "Digest" got nothing
31
+ * between the click and a terminal state minutes later — no "fetching", no
32
+ * "summarising", no evidence the button did anything. See `role="log"` below.
33
+ * The six pages that render this pass only `className`, so no template could
34
+ * have fixed it locally; that is what makes it this component's job.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * import { WorkflowProgress } from "@alexkroman1/aai-ui";
39
+ *
40
+ * function RunPanel({ runId }: { runId: string }) {
41
+ * return <WorkflowProgress runId={runId} />;
42
+ * }
43
+ * ```
44
+ *
45
+ * @param props - Progress-log props.
46
+ *
47
+ * @public
48
+ */
49
+ export declare function WorkflowProgress({ runId, api, className, placeholder, lines, }: {
50
+ /**
51
+ * The run to read. `undefined` renders nothing, so a page may pass its state
52
+ * straight through before a run exists.
53
+ */
54
+ runId?: string | undefined;
55
+ /**
56
+ * The workflow API client, when the page holds its own. Defaults to the
57
+ * lazily-built one every workflow hook shares.
58
+ */
59
+ api?: WorkflowApi | undefined;
60
+ /**
61
+ * **Replaces** the default classes rather than extending them, so a custom
62
+ * chrome is not fighting a default it did not ask for.
63
+ */
64
+ className?: string | undefined;
65
+ /**
66
+ * Rendered instead of nothing while the run has said nothing yet — for a
67
+ * page that would otherwise reflow when the first line lands.
68
+ */
69
+ placeholder?: ReactNode | undefined;
70
+ /**
71
+ * How many of the newest lines to show. Undefined (the default) shows the
72
+ * whole log; `1` is the newest line only.
73
+ *
74
+ * A run's narration is append-only and unbounded, so a page with a fixed slot
75
+ * for it — a status strip, a card footer — wants a window rather than a log.
76
+ * `0` renders the placeholder, which is the consistent reading of "show none"
77
+ * and the one that keeps a computed `lines` from silently rendering
78
+ * everything.
79
+ */
80
+ lines?: number | undefined;
81
+ }): ReactNode;
@@ -0,0 +1,48 @@
1
+ import type { ReactNode } from "react";
2
+ import type { WorkflowRun } from "../workflow-client.ts";
3
+ /**
4
+ * Props for {@link WorkflowRunError}.
5
+ *
6
+ * @public
7
+ */
8
+ export type WorkflowRunErrorProps = {
9
+ /** The run the page is following. Nothing renders unless it has FAILED. */
10
+ run: WorkflowRun | undefined;
11
+ /**
12
+ * ADDED to the alert's own `text-red-600` rather than replacing it. There is
13
+ * no `tailwind-merge` in this package, so a class that CONFLICTS with a base
14
+ * one is not reliably the winner.
15
+ */
16
+ className?: string | undefined;
17
+ };
18
+ /**
19
+ * The announced line for a run that failed: its error, or nothing at all while
20
+ * the run is anything else.
21
+ *
22
+ * Six workflow pages had written this paragraph by hand, and the one thing that
23
+ * mattered about it was the part a reviewer cannot see is missing:
24
+ * `role="alert"`. A run fails minutes after the reader looked away — days, for
25
+ * a scheduled one — and `<Form>` announces only the SUBMIT error, so without
26
+ * the role a screen reader is never told the outcome it waited for arrived.
27
+ * Three of the six also disagreed on the sentence ("That one failed", "That run
28
+ * failed", the bare message), which is the drift a component ends.
29
+ *
30
+ * Discriminated on `status`, so `error` is reachable without a cast — the
31
+ * reason {@link WorkflowRun} is a union rather than a flat object with optional
32
+ * fields.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * import { useWorkflowSubmit, WorkflowRunError } from "@alexkroman1/aai-ui";
37
+ *
38
+ * function App() {
39
+ * const { run } = useWorkflowSubmit("digest");
40
+ * return <WorkflowRunError run={run} />;
41
+ * }
42
+ * ```
43
+ *
44
+ * @param props - See {@link WorkflowRunErrorProps}.
45
+ *
46
+ * @public
47
+ */
48
+ export declare function WorkflowRunError({ run, className }: WorkflowRunErrorProps): ReactNode;
@@ -0,0 +1,79 @@
1
+ import type { ReactNode } from "react";
2
+ import type { WorkflowRunStatus } from "../workflow-client.ts";
3
+ import { type WorkflowApi, type WorkflowRun } from "../workflow-client.ts";
4
+ /**
5
+ * Props of {@link WorkflowRunPanel}.
6
+ *
7
+ * @typeParam O - The run's output type; `run.output` narrows to it in the
8
+ * completed slot.
9
+ *
10
+ * @public
11
+ */
12
+ export type WorkflowRunPanelProps<O> = {
13
+ /** The run to show. Nothing here handles `undefined` — a page renders the panel once it has one. */
14
+ run: WorkflowRun<O>;
15
+ /**
16
+ * The status lines this page has a better word for — `{ running:
17
+ * "Writing…" }`. The rest come from {@link WORKFLOW_STATUS_LABELS}.
18
+ */
19
+ statusLabels?: Partial<Readonly<Record<WorkflowRunStatus, string>>> | undefined;
20
+ /** Renders a Clear button in the header that calls this. Absent, no button. */
21
+ onClear?: (() => void) | undefined;
22
+ /** The workflow API client, when the page holds its own. */
23
+ api?: WorkflowApi | undefined;
24
+ /**
25
+ * Rendered beneath the narration while the run is NOT terminal — a live
26
+ * transcript, a partial result. Nothing once it settles.
27
+ */
28
+ live?: ReactNode | undefined;
29
+ /**
30
+ * The completed body: what the run PRODUCED. A function receives the typed
31
+ * output; a node is rendered as it is. Either appears only while
32
+ * `run.status === "completed"`.
33
+ */
34
+ children?: ReactNode | ((output: O) => ReactNode) | undefined;
35
+ /** Additional CSS class names for the wrapping `<section>`, appended to its own. */
36
+ className?: string | undefined;
37
+ };
38
+ /**
39
+ * The bordered panel a workflow page shows one run in: a status line, a Clear
40
+ * button, the run's own narration, the live slot while it works, the completed
41
+ * body once it has, and the announced error if it failed.
42
+ *
43
+ * Two pages had written this shell — `document-redline-workflow` and `transcription-workflow` —
44
+ * with the same header, the same `text-xs underline` Clear, the same
45
+ * {@link WorkflowProgress} under it, the same `run.status === "completed"`
46
+ * discrimination above the same {@link WorkflowRunError}, and each spread
47
+ * {@link WORKFLOW_STATUS_LABELS} into a local map to change `running`. The
48
+ * ORDER is the part worth owning: the narration is the complement of the status
49
+ * line (a run is `running` for its whole life, so a one-round job and a
50
+ * ten-round one look identical without it), and the error goes last because it
51
+ * is the outcome the reader waited minutes for.
52
+ *
53
+ * `children` is discriminated on the run for the caller, so the body reads
54
+ * `run.output` typed, without a cast and without the page repeating the guard —
55
+ * the reason {@link WorkflowRun} is a union rather than a flat object with
56
+ * optional fields.
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * import { useWorkflowRun, WorkflowRunPanel } from "@alexkroman1/aai-ui";
61
+ *
62
+ * // `useWorkflowRun<R>` is where a page names the output's shape; a page that
63
+ * // started the run itself has it typed already, from `useWorkflowSubmit<D>`.
64
+ * function Panel({ runId, onClear }: { runId: string; onClear: () => void }) {
65
+ * const { run } = useWorkflowRun<{ draft: string }>(runId);
66
+ * if (!run) return null;
67
+ * return (
68
+ * <WorkflowRunPanel run={run} statusLabels={{ running: "Writing…" }} onClear={onClear}>
69
+ * {(output) => <article className="whitespace-pre-wrap">{output.draft}</article>}
70
+ * </WorkflowRunPanel>
71
+ * );
72
+ * }
73
+ * ```
74
+ *
75
+ * @param props - See {@link WorkflowRunPanelProps}.
76
+ *
77
+ * @public
78
+ */
79
+ export declare function WorkflowRunPanel<O = unknown>({ run, statusLabels, onClear, api, live, children, className, }: WorkflowRunPanelProps<O>): ReactNode;