@alexkroman1/aai-ui 6.10.1 → 7.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.
Files changed (67) hide show
  1. package/README.md +104 -3
  2. package/dist/_run-controls.d.ts +33 -0
  3. package/dist/{chat-view-ByQFf94G.js → chat-view-BKsFfFZJ.js} +57 -11
  4. package/dist/client-config-B4nznRvH.js +134 -0
  5. package/dist/client-config.d.ts +45 -2
  6. package/dist/client-dir.d.ts +3 -1
  7. package/dist/client-dir.js +3 -1
  8. package/dist/components/auto-scroll.d.ts +24 -13
  9. package/dist/components/button.d.ts +8 -4
  10. package/dist/components/button.js +4 -4
  11. package/dist/components/chat-view.d.ts +4 -3
  12. package/dist/components/chat-view.js +1 -1
  13. package/dist/components/console-shell.d.ts +71 -10
  14. package/dist/components/controls.d.ts +15 -4
  15. package/dist/components/controls.js +48 -2
  16. package/dist/components/form-fields.d.ts +142 -0
  17. package/dist/components/form-types.d.ts +6 -0
  18. package/dist/components/form.d.ts +38 -80
  19. package/dist/components/markdown.d.ts +31 -5
  20. package/dist/components/message-list.d.ts +21 -4
  21. package/dist/components/message-list.js +1 -1
  22. package/dist/components/sidebar-layout.d.ts +11 -0
  23. package/dist/components/sidebar-layout.js +2 -0
  24. package/dist/components/start-screen.d.ts +8 -0
  25. package/dist/components/start-screen.js +2 -0
  26. package/dist/components/tool-call-block.js +1 -1
  27. package/dist/components/tool-call-row.d.ts +24 -0
  28. package/dist/components/upload-progress.d.ts +17 -7
  29. package/dist/components/workflow-fields.d.ts +10 -22
  30. package/dist/components/workflow-progress.d.ts +29 -10
  31. package/dist/context.d.ts +36 -0
  32. package/dist/context.js +105 -14
  33. package/dist/default-client/assets/index-S5fkKi6B.css +2 -0
  34. package/dist/default-client/assets/index-fEkrcZgo.js +293 -0
  35. package/dist/default-client/index.html +2 -2
  36. package/dist/define-client.d.ts +67 -62
  37. package/dist/define-client.js +56 -22
  38. package/dist/hooks.d.ts +88 -3
  39. package/dist/index.d.ts +12 -11
  40. package/dist/index.js +504 -248
  41. package/dist/internal.d.ts +40 -0
  42. package/dist/internal.js +6 -0
  43. package/dist/{message-list-CpPV7dGx.js → message-list-DHddO4QC.js} +217 -72
  44. package/dist/{session-core-CAfYmUbg.js → session-core-C2JtLArh.js} +267 -165
  45. package/dist/session-core-audio-setup.d.ts +3 -0
  46. package/dist/session-core-messages.d.ts +3 -0
  47. package/dist/session-core-state.d.ts +146 -0
  48. package/dist/session-core-types.d.ts +77 -32
  49. package/dist/session-core.d.ts +3 -2
  50. package/dist/session-core.js +1 -1
  51. package/dist/{tool-call-block-D6pTEPrT.js → tool-call-block-DoF-cSIZ.js} +27 -19
  52. package/dist/tool-config-context-DzAofqi_.js +19 -0
  53. package/dist/types.d.ts +31 -5
  54. package/dist/types.js +5 -4
  55. package/dist/{controls-CjG91QJ4.js → url-chips-DpM7Oocj.js} +3 -46
  56. package/dist/use-conversation.d.ts +122 -0
  57. package/dist/use-download-url.d.ts +83 -0
  58. package/dist/use-workflow-form.d.ts +59 -3
  59. package/dist/use-workflow-run.d.ts +35 -0
  60. package/dist/use-workflow-stream.d.ts +36 -62
  61. package/dist/workflow-client.d.ts +36 -11
  62. package/dist/workflow-status-labels.d.ts +35 -0
  63. package/package.json +10 -6
  64. package/styles.css +14 -0
  65. package/dist/_sse.d.ts +0 -56
  66. package/dist/default-client/assets/index-DTLrhtTF.css +0 -2
  67. package/dist/default-client/assets/index-DXODx_9r.js +0 -293
@@ -1,15 +1,11 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { AgentState } from "../types.ts";
3
3
  /**
4
- * The design-system "console" chrome for the chat shell:
5
- * a 760px column on the cream page with a header
6
- * (logo + live-status eyebrow), an optional error banner, the main content
7
- * on a raised white card, and a footer row beneath it.
4
+ * Props of {@link ConsoleShell}.
8
5
  *
9
- *
10
- * @internal
6
+ * @public
11
7
  */
12
- export declare function ConsoleShell({ icon, title, state, pulsing, error, children, footer, className, }: {
8
+ export type ConsoleShellProps = {
13
9
  /** Element rendered in place of the logo in the header. */
14
10
  icon?: ReactNode | undefined;
15
11
  /** Title string for the header. */
@@ -18,11 +14,76 @@ export declare function ConsoleShell({ icon, title, state, pulsing, error, child
18
14
  state: AgentState;
19
15
  /** Whether the status dot pulses. */
20
16
  pulsing: boolean;
21
- /** Error banner text; `null`/`undefined` hides the banner. */
17
+ /**
18
+ * Error banner text; `null`/`undefined` hides the banner.
19
+ *
20
+ * Pass `session.error?.message` — the banner is announced, which a
21
+ * hand-rolled `<div>` in a custom chrome is not. See the `role="alert"`
22
+ * comment below for why that matters more here than it looks.
23
+ */
22
24
  error?: string | null | undefined;
23
- /** Card content. */
25
+ /** Card content — normally a {@link MessageList}. */
24
26
  children: ReactNode;
25
27
  /** Row rendered beneath the card (controls). */
26
28
  footer: ReactNode;
29
+ /** Additional CSS class names for the root element, appended to its own. */
27
30
  className?: string | undefined;
28
- }): ReactNode;
31
+ };
32
+ /**
33
+ * The design-system "console" chrome: a 760px column on the themed page with a
34
+ * header (icon + live-status eyebrow), an announced error banner, the main
35
+ * content on a raised card, and a footer row beneath it.
36
+ *
37
+ * {@link ChatView} is this shell with `<MessageList>` inside it and
38
+ * `<Controls>` under it, and until now that was the only way to get it — the
39
+ * shell itself was internal, so a client wanting its own conversation markup
40
+ * had to rebuild the chrome as well. Each one that did re-derived the error
41
+ * banner WITHOUT `role="alert"`, which is the one part of this component a
42
+ * reviewer cannot see is missing: per the `fatalError` latch in
43
+ * `session-core.ts`, the banner is the only remaining signal once the state
44
+ * eyebrow goes back to reading like a live session, and a screen reader is
45
+ * never told an unannounced one appeared.
46
+ *
47
+ * Reach for it when the conversation is yours and the frame is not. Reach for
48
+ * `<ChatView>` when both are ours.
49
+ *
50
+ * Must be rendered inside the providers `client()` installs.
51
+ *
52
+ * @example A custom conversation in the stock chrome
53
+ * ```tsx
54
+ * import {
55
+ * ConsoleShell,
56
+ * Controls,
57
+ * useConversation,
58
+ * useSessionSelector,
59
+ * } from "@alexkroman1/aai-ui";
60
+ *
61
+ * function Console() {
62
+ * const state = useSessionSelector((s) => s.state);
63
+ * const error = useSessionSelector((s) => s.error);
64
+ * const { items } = useConversation();
65
+ * return (
66
+ * <ConsoleShell
67
+ * title="Dispatch"
68
+ * state={state}
69
+ * pulsing={state === "listening"}
70
+ * error={error?.message}
71
+ * footer={<Controls />}
72
+ * >
73
+ * <ul>
74
+ * {items.map((item) => (
75
+ * <li key={item.kind === "message" ? item.message.id : item.toolCall.callId}>
76
+ * {item.kind === "message" ? item.message.content : item.toolCall.name}
77
+ * </li>
78
+ * ))}
79
+ * </ul>
80
+ * </ConsoleShell>
81
+ * );
82
+ * }
83
+ * ```
84
+ *
85
+ * @param props - See {@link ConsoleShellProps}.
86
+ *
87
+ * @public
88
+ */
89
+ export declare function ConsoleShell({ icon, title, state, pulsing, error, children, footer, className, }: ConsoleShellProps): ReactNode;
@@ -1,3 +1,16 @@
1
+ import { type FunctionComponent, type MemoExoticComponent } from "react";
2
+ /**
3
+ * Props of {@link Controls}.
4
+ *
5
+ * @public
6
+ */
7
+ export type ControlsProps = {
8
+ /**
9
+ * Additional CSS class names, appended to the container's own layout
10
+ * classes rather than replacing them.
11
+ */
12
+ className?: string;
13
+ };
1
14
  /**
2
15
  * Session control buttons: **Stop / Resume** and **New Conversation**.
3
16
  *
@@ -13,10 +26,8 @@
13
26
  * }
14
27
  * ```
15
28
  *
16
- * @param className - Additional CSS class names applied to the container.
29
+ * @param props - Container props.
17
30
  *
18
31
  * @public
19
32
  */
20
- export declare const Controls: import("react").MemoExoticComponent<({ className }: {
21
- className?: string;
22
- }) => import("react").JSX.Element>;
33
+ export declare const Controls: MemoExoticComponent<FunctionComponent<ControlsProps>>;
@@ -1,3 +1,49 @@
1
- import "../context.js";
2
- import { t as Controls } from "../controls-CjG91QJ4.js";
1
+ import { useSessionCore, useSessionSelector } from "../context.js";
2
+ import { Button } from "./button.js";
3
+ import { n as SessionUrlChips } from "../url-chips-DpM7Oocj.js";
4
+ import clsx from "clsx";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { memo } from "react";
7
+ //#region components/controls.tsx
8
+ /** @jsxImportSource react */
9
+ /**
10
+ * Session control buttons: **Stop / Resume** and **New Conversation**.
11
+ *
12
+ * Reads session state from {@link useSession}. Must be rendered inside a
13
+ * `SessionProvider`.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { Controls } from "@alexkroman1/aai-ui";
18
+ *
19
+ * function Footer() {
20
+ * return <Controls className="justify-end" />;
21
+ * }
22
+ * ```
23
+ *
24
+ * @param props - Container props.
25
+ *
26
+ * @public
27
+ */
28
+ const Controls = memo(function Controls({ className }) {
29
+ const running = useSessionSelector((s) => s.running);
30
+ const { toggle, reset } = useSessionCore();
31
+ return /* @__PURE__ */ jsxs("div", {
32
+ className: clsx("flex flex-wrap items-center gap-3 shrink-0", className),
33
+ children: [
34
+ /* @__PURE__ */ jsx(Button, {
35
+ variant: "secondary",
36
+ onClick: toggle,
37
+ children: running ? "Stop" : "Resume"
38
+ }),
39
+ /* @__PURE__ */ jsx(Button, {
40
+ variant: "ghost",
41
+ onClick: reset,
42
+ children: "New Conversation"
43
+ }),
44
+ /* @__PURE__ */ jsx(SessionUrlChips, { className: "basis-full sm:basis-auto sm:ml-auto sm:max-w-[60%]" })
45
+ ]
46
+ });
47
+ });
48
+ //#endregion
3
49
  export { Controls };
@@ -0,0 +1,142 @@
1
+ import type { InputHTMLAttributes, ReactNode, SelectHTMLAttributes, TextareaHTMLAttributes } from "react";
2
+ import type { FieldShell, FileRead } from "./form-types.ts";
3
+ /**
4
+ * Label + control + hint, in the layout every field here uses.
5
+ *
6
+ * Exported so a caller's own control gets the same shell rather than an
7
+ * approximation of it.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { Field, Form } from "@alexkroman1/aai-ui";
12
+ *
13
+ * function ColorForm() {
14
+ * return (
15
+ * <Form onSubmit={() => undefined}>
16
+ * <Field label="Accent" hint="Any CSS color." htmlFor="accent">
17
+ * <input id="accent" name="accent" type="color" />
18
+ * </Field>
19
+ * </Form>
20
+ * );
21
+ * }
22
+ * ```
23
+ *
24
+ * @param props - Field-shell props.
25
+ *
26
+ * @public
27
+ */
28
+ export declare function Field({ label, hint, htmlFor, className, children, }: {
29
+ /** Visible label. Omitted leaves the control unlabelled. */
30
+ label?: string | undefined;
31
+ /** One line of guidance under the control. */
32
+ hint?: string | undefined;
33
+ /** Id of the control this labels. */
34
+ htmlFor?: string | undefined;
35
+ /** Additional CSS class names for the wrapper, appended to its own. */
36
+ className?: string | undefined;
37
+ /** The control itself. */
38
+ children: ReactNode;
39
+ }): import("react").JSX.Element;
40
+ /**
41
+ * A single-line text input.
42
+ *
43
+ * Accepts every `<input>` attribute except `name` and `className`, which this
44
+ * component owns, plus the shared {@link FieldShell} props.
45
+ *
46
+ * @param props - {@link FieldShell} props plus `<input>` attributes.
47
+ *
48
+ * @public
49
+ */
50
+ export declare function TextField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className">): import("react").JSX.Element;
51
+ /**
52
+ * A number input. Contributes a NUMBER to {@link FormValues}, or nothing when
53
+ * left empty.
54
+ *
55
+ * Accepts every `<input>` attribute except `name`, `className` and `type`,
56
+ * plus the shared {@link FieldShell} props — so `min`, `max` and `step` are
57
+ * passed straight through.
58
+ *
59
+ * @param props - {@link FieldShell} props plus `<input>` attributes.
60
+ *
61
+ * @public
62
+ */
63
+ export declare function NumberField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
64
+ /**
65
+ * A multi-line text input.
66
+ *
67
+ * Accepts every `<textarea>` attribute except `name` and `className`, plus the
68
+ * shared {@link FieldShell} props. `rows` defaults to 4.
69
+ *
70
+ * @param props - {@link FieldShell} props plus `<textarea>` attributes.
71
+ *
72
+ * @public
73
+ */
74
+ export declare function TextAreaField({ name, label, hint, className, rows, ...rest }: FieldShell & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "name" | "className">): import("react").JSX.Element;
75
+ /**
76
+ * A dropdown.
77
+ *
78
+ * `options` is the short form — a list of strings, or of
79
+ * `{ value, label }` pairs when the two differ. Pass `children` instead for
80
+ * full control over the `<option>` elements; `children` wins when both are
81
+ * given.
82
+ *
83
+ * Otherwise accepts every `<select>` attribute except `name` and `className`,
84
+ * plus the shared {@link FieldShell} props. Note `multiple` works and
85
+ * contributes an ARRAY (`[]` when nothing is chosen).
86
+ *
87
+ * @param props - {@link FieldShell} props, `options`, and `<select>`
88
+ * attributes.
89
+ *
90
+ * @public
91
+ */
92
+ export declare function SelectField({ name, label, hint, className, options, children, ...rest }: FieldShell & {
93
+ options?: readonly (string | {
94
+ value: string;
95
+ label: string;
96
+ })[];
97
+ } & Omit<SelectHTMLAttributes<HTMLSelectElement>, "name" | "className">): import("react").JSX.Element;
98
+ /**
99
+ * A checkbox. Contributes a BOOLEAN to {@link FormValues}.
100
+ *
101
+ * Accepts every `<input>` attribute except `name`, `className` and `type`,
102
+ * plus the shared {@link FieldShell} props. The label renders beside the box
103
+ * rather than above it, so `hint` is the place for guidance.
104
+ *
105
+ * @param props - {@link FieldShell} props plus `<input>` attributes.
106
+ *
107
+ * @public
108
+ */
109
+ export declare function CheckboxField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
110
+ /**
111
+ * A file picker. Contributes a {@link FileValue} (or an array, with `multiple`)
112
+ * to {@link FormValues} — or nothing when no file was chosen.
113
+ *
114
+ * **`upload` is what a workflow input wants.** A run's input is serialized into
115
+ * the run record and replayed from it on every resume, so a file's BYTES cannot
116
+ * travel in it. With `upload` the field contributes the `File` itself,
117
+ * `useWorkflowSubmit` stores it through `POST /workflows/uploads` before
118
+ * starting the run, and the input carries the upload id — which a step reads
119
+ * windows of with `readUpload`. Declaring the property in the workflow's
120
+ * `uploads` list makes `<WorkflowFields>` render exactly this, so a declared
121
+ * form needs no file markup at all.
122
+ *
123
+ * **Without it the field describes the file and does not read it.** `read`
124
+ * exists for the cases where the bytes really are small and really are the
125
+ * input — a CSV of ids, a config — and the size is the author's to check. See
126
+ * {@link FileRead} for the four values; `upload` is shorthand for
127
+ * `read="upload"`.
128
+ *
129
+ * Otherwise accepts every `<input>` attribute except `name`, `className` and
130
+ * `type`, plus the shared {@link FieldShell} props — so `accept` and
131
+ * `multiple` are passed straight through.
132
+ *
133
+ * @param props - {@link FieldShell} props, `read`/`upload`, and `<input>`
134
+ * attributes.
135
+ *
136
+ * @public
137
+ */
138
+ export declare function FileField({ name, label, hint, className, read, upload, ...rest }: FieldShell & {
139
+ read?: FileRead;
140
+ /** Shorthand for `read="upload"` — see above. */
141
+ upload?: boolean;
142
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
@@ -63,5 +63,11 @@ export type FieldShell = {
63
63
  label?: string | undefined;
64
64
  /** One line of guidance under the control. */
65
65
  hint?: string | undefined;
66
+ /**
67
+ * Additional CSS class names for the field's WRAPPER (label + control +
68
+ * hint), appended to its own layout classes. The control itself takes the
69
+ * shared field styling; pass `style` or a `data-` hook through the native
70
+ * attributes to reach it.
71
+ */
66
72
  className?: string | undefined;
67
73
  };
@@ -1,6 +1,7 @@
1
- import type { FormHTMLAttributes, InputHTMLAttributes, ReactNode, SelectHTMLAttributes, TextareaHTMLAttributes } from "react";
2
- import { type ButtonSize } from "./button.tsx";
3
- import type { FieldShell, FileRead, FormValues } from "./form-types.ts";
1
+ import type { ButtonHTMLAttributes, FormHTMLAttributes, ReactNode } from "react";
2
+ import { type ButtonSize, type ButtonVariant } from "./button.tsx";
3
+ import type { FormValues } from "./form-types.ts";
4
+ export { CheckboxField, Field, FileField, NumberField, SelectField, TextAreaField, TextField, } from "./form-fields.tsx";
4
5
  export type { FieldShell, FileRead, FileValue, FormValues } from "./form-types.ts";
5
6
  /** Props of {@link Form}. */
6
7
  export type FormProps = {
@@ -38,93 +39,45 @@ export type FormProps = {
38
39
  * }
39
40
  * ```
40
41
  *
41
- * @public
42
- */
43
- export declare function Form({ onSubmit, error, children, className, ...rest }: FormProps): import("react").JSX.Element;
44
- /**
45
- * Label + control + hint, in the layout every field here uses.
46
- *
47
- * Exported so a caller's own control gets the same shell rather than an
48
- * approximation of it.
42
+ * @param props - See {@link FormProps}. Every `<form>` attribute except
43
+ * `onSubmit` and `className` is passed through.
49
44
  *
50
45
  * @public
51
46
  */
52
- export declare function Field({ label, hint, htmlFor, className, children, }: {
53
- label?: string | undefined;
54
- hint?: string | undefined;
55
- /** Id of the control this labels. */
56
- htmlFor?: string | undefined;
57
- className?: string | undefined;
58
- children: ReactNode;
59
- }): import("react").JSX.Element;
60
- /**
61
- * A single-line text input.
62
- *
63
- * @public
64
- */
65
- export declare function TextField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className">): import("react").JSX.Element;
66
- /**
67
- * A number input. Contributes a NUMBER to {@link FormValues}, or nothing when
68
- * left empty.
69
- *
70
- * @public
71
- */
72
- export declare function NumberField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
73
- /**
74
- * A multi-line text input.
75
- *
76
- * @public
77
- */
78
- export declare function TextAreaField({ name, label, hint, className, rows, ...rest }: FieldShell & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "name" | "className">): import("react").JSX.Element;
79
- /**
80
- * A dropdown. Pass `options`, or `children` for full control over the
81
- * `<option>` elements.
82
- *
83
- * @public
84
- */
85
- export declare function SelectField({ name, label, hint, className, options, children, ...rest }: FieldShell & {
86
- options?: readonly (string | {
87
- value: string;
88
- label: string;
89
- })[];
90
- } & Omit<SelectHTMLAttributes<HTMLSelectElement>, "name" | "className">): import("react").JSX.Element;
47
+ export declare function Form({ onSubmit, error, children, className, ...rest }: FormProps): import("react").JSX.Element;
91
48
  /**
92
- * A checkbox. Contributes a BOOLEAN to {@link FormValues}.
49
+ * The form's submit button, disabled and relabelled while a submit is in
50
+ * flight.
93
51
  *
94
- * @public
95
- */
96
- export declare function CheckboxField({ name, label, hint, className, ...rest }: FieldShell & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
97
- /**
98
- * A file picker. Contributes a {@link FileValue} (or an array, with `multiple`)
99
- * to {@link FormValues} — or nothing when no file was chosen.
52
+ * Accepts all standard `<button>` HTML attributes except `type` and `disabled`,
53
+ * in addition to the props below — so `aria-label` on an icon-only submit,
54
+ * `form`, `id`, `title` and `onClick` all work here exactly as they do on
55
+ * {@link Button}. `type` and `disabled` stay owned: this component sets both
56
+ * from `pending`, and letting a caller set either is how a form gets a submit
57
+ * button that does not submit.
100
58
  *
101
- * **`upload` is what a workflow input wants.** A run's input is serialized into
102
- * the run record and replayed from it on every resume, so a file's BYTES cannot
103
- * travel in it. With `upload` the field contributes the `File` itself,
104
- * `useWorkflowSubmit` stores it through `POST /workflows/uploads` before
105
- * starting the run, and the input carries the upload id — which a step reads
106
- * windows of with `readUpload`. Declaring the property in the workflow's
107
- * `uploads` list makes `<WorkflowFields>` render exactly this, so a declared
108
- * form needs no file markup at all.
59
+ * @example
60
+ * ```tsx
61
+ * import { Form, SubmitButton, TextField } from "@alexkroman1/aai-ui";
109
62
  *
110
- * **Without it the field describes the file and does not read it.** `read`
111
- * exists for the cases where the bytes really are small and really are the
112
- * input — a CSV of ids, a config — and the size is the author's to check.
63
+ * function Digest({ pending }: { pending: boolean }) {
64
+ * return (
65
+ * <Form onSubmit={() => undefined}>
66
+ * <TextField name="url" label="Link" required />
67
+ * <SubmitButton pending={pending} variant="secondary" size="lg">
68
+ * Summarize
69
+ * </SubmitButton>
70
+ * </Form>
71
+ * );
72
+ * }
73
+ * ```
113
74
  *
114
- * @public
115
- */
116
- export declare function FileField({ name, label, hint, className, read, upload, ...rest }: FieldShell & {
117
- read?: FileRead;
118
- /** Shorthand for `read="upload"` — see above. */
119
- upload?: boolean;
120
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "className" | "type">): import("react").JSX.Element;
121
- /**
122
- * The form's submit button, disabled and relabelled while a submit is in
123
- * flight.
75
+ * @param props - Button props.
124
76
  *
125
77
  * @public
126
78
  */
127
- export declare function SubmitButton({ children, pending, pendingLabel, size, className, }: {
79
+ export declare function SubmitButton({ children, pending, pendingLabel, size, variant, className, ...rest }: {
80
+ /** Button label. Replaced by `pendingLabel` while `pending`. */
128
81
  children?: ReactNode;
129
82
  /**
130
83
  * Whether the WORK this form started is still going. Separate from the
@@ -132,7 +85,12 @@ export declare function SubmitButton({ children, pending, pendingLabel, size, cl
132
85
  * outlives its `POST`, and the button should stay busy until the run is done.
133
86
  */
134
87
  pending?: boolean;
88
+ /** Label shown in place of `children` while `pending`. Defaults to `"Working…"`. */
135
89
  pendingLabel?: string;
90
+ /** Size preset, passed through to {@link Button}. */
136
91
  size?: ButtonSize | undefined;
92
+ /** Visual style, passed through to {@link Button}. Defaults to `"default"`. */
93
+ variant?: ButtonVariant | undefined;
94
+ /** Additional CSS class names, appended to {@link Button}'s own. */
137
95
  className?: string | undefined;
138
- }): import("react").JSX.Element;
96
+ } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type" | "disabled" | "className">): import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { type ReactNode } from "react";
1
+ import { type FunctionComponent, type MemoExoticComponent } from "react";
2
2
  /**
3
3
  * Type scale for {@link Markdown}: `"default"` is the deployed agent UI's
4
4
  * scale, `"compact"` a notch smaller for denser surfaces (the studio's chat
@@ -7,6 +7,23 @@ import { type ReactNode } from "react";
7
7
  * @public
8
8
  */
9
9
  export type MarkdownVariant = "default" | "compact";
10
+ /**
11
+ * Props of {@link Markdown}.
12
+ *
13
+ * @public
14
+ */
15
+ export type MarkdownProps = {
16
+ /**
17
+ * The Markdown source. Required — this is the prose to render, normally one
18
+ * agent message or the streaming tail of one.
19
+ */
20
+ text: string;
21
+ /**
22
+ * Type scale. Defaults to `"default"`, the deployed agent UI's scale; pass
23
+ * `"compact"` for a denser surface. Colors are unaffected either way.
24
+ */
25
+ variant?: MarkdownVariant;
26
+ };
10
27
  /**
11
28
  * Agent prose, rendered as Markdown.
12
29
  *
@@ -23,9 +40,18 @@ export type MarkdownVariant = "default" | "compact";
23
40
  * Memoized alongside `MessageBubble`: message content is referentially
24
41
  * stable across snapshots, so only the streaming row re-parses.
25
42
  *
43
+ * @example
44
+ * ```tsx
45
+ * import { Markdown, useSessionSelector } from "@alexkroman1/aai-ui";
46
+ *
47
+ * // The agent's reply as it streams, rendered rather than shown as literal
48
+ * // asterisks and backticks.
49
+ * function LiveReply() {
50
+ * const text = useSessionSelector((snapshot) => snapshot.agentTranscript);
51
+ * return text === null ? null : <Markdown text={text} variant="compact" />;
52
+ * }
53
+ * ```
54
+ *
26
55
  * @public
27
56
  */
28
- export declare const Markdown: import("react").MemoExoticComponent<({ text, variant, }: {
29
- text: string;
30
- variant?: MarkdownVariant;
31
- }) => ReactNode>;
57
+ export declare const Markdown: MemoExoticComponent<FunctionComponent<MarkdownProps>>;
@@ -1,3 +1,22 @@
1
+ /** @jsxImportSource react */
2
+ import { type FunctionComponent, type MemoExoticComponent } from "react";
3
+ /**
4
+ * Props of {@link MessageList}.
5
+ *
6
+ * @public
7
+ */
8
+ export type MessageListProps = {
9
+ /**
10
+ * Additional CSS class names for the outer scroll container, appended to its
11
+ * own rather than replacing them.
12
+ *
13
+ * The container is an {@link AutoScroll}, so it must end up with a BOUNDED
14
+ * height (`flex-1 min-h-0`, `h-full`, a fixed height). Unbounded, it grows
15
+ * with the conversation and never scrolls, so nothing pins to the newest
16
+ * message.
17
+ */
18
+ className?: string;
19
+ };
1
20
  /**
2
21
  * Scrollable list of all chat messages, tool-call blocks, live transcript,
3
22
  * streaming agent utterance, and a thinking indicator.
@@ -16,10 +35,8 @@
16
35
  * }
17
36
  * ```
18
37
  *
19
- * @param className - Additional CSS class names applied to the outer list container.
38
+ * @param props - Container props.
20
39
  *
21
40
  * @public
22
41
  */
23
- export declare const MessageList: import("react").MemoExoticComponent<({ className }: {
24
- className?: string;
25
- }) => import("react").JSX.Element>;
42
+ export declare const MessageList: MemoExoticComponent<FunctionComponent<MessageListProps>>;
@@ -1,3 +1,3 @@
1
- import { t as MessageList } from "../message-list-CpPV7dGx.js";
1
+ import { t as MessageList } from "../message-list-DHddO4QC.js";
2
2
  import "../context.js";
3
3
  export { MessageList };
@@ -20,12 +20,23 @@ import type { ReactNode } from "react";
20
20
  * }
21
21
  * ```
22
22
  *
23
+ * @param props - Layout props.
24
+ *
23
25
  * @public
24
26
  */
25
27
  export declare function SidebarLayout({ sidebar, children, sidebarWidth, sidebarPosition, className, }: {
28
+ /** The sidebar pane — a cart, a dashboard, a run history. */
26
29
  sidebar: ReactNode;
30
+ /** The main pane, normally a `<ChatView />`. */
27
31
  children: ReactNode;
32
+ /**
33
+ * Width of the sidebar as a CSS length. Defaults to `"18rem"`, and applies
34
+ * from the `md` breakpoint up: below it the two panes stack, because a fixed
35
+ * width that never shrinks leaves a phone-width main pane unreadable.
36
+ */
28
37
  sidebarWidth?: string | undefined;
38
+ /** Which side the sidebar sits on. Defaults to `"left"`. */
29
39
  sidebarPosition?: "left" | "right" | undefined;
40
+ /** Additional CSS class names for the root element, appended to its own. */
30
41
  className?: string;
31
42
  }): import("react").JSX.Element;
@@ -24,6 +24,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
24
24
  * }
25
25
  * ```
26
26
  *
27
+ * @param props - Layout props.
28
+ *
27
29
  * @public
28
30
  */
29
31
  function SidebarLayout({ sidebar, children, sidebarWidth = "18rem", sidebarPosition = "left", className }) {
@@ -17,13 +17,21 @@ import type { ReactNode } from "react";
17
17
  * }
18
18
  * ```
19
19
  *
20
+ * @param props - Start-screen props.
21
+ *
20
22
  * @public
21
23
  */
22
24
  export declare function StartScreen({ children, icon, title, subtitle, buttonText, className, }: {
25
+ /** The app, rendered once the session has started. */
23
26
  children: ReactNode;
27
+ /** Element rendered in place of the logo on the card. */
24
28
  icon?: ReactNode | undefined;
29
+ /** The card's serif title. Defaults to the agent's declared name. */
25
30
  title?: string | undefined;
31
+ /** A line under the title. */
26
32
  subtitle?: string | undefined;
33
+ /** Label of the start CTA. Defaults to `"Start Conversation"`. */
27
34
  buttonText?: string | undefined;
35
+ /** Additional CSS class names for the root element, appended to its own. */
28
36
  className?: string | undefined;
29
37
  }): ReactNode;
@@ -25,6 +25,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
25
25
  * }
26
26
  * ```
27
27
  *
28
+ * @param props - Start-screen props.
29
+ *
28
30
  * @public
29
31
  */
30
32
  function StartScreen({ children, icon, title, subtitle, buttonText = "Start Conversation", className }) {
@@ -1,3 +1,3 @@
1
1
  import "../context.js";
2
- import { t as ToolCallBlock } from "../tool-call-block-D6pTEPrT.js";
2
+ import { t as ToolCallBlock } from "../tool-call-block-DoF-cSIZ.js";
3
3
  export { ToolCallBlock };