@actioneer/ads 0.5.5 → 0.5.7

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 (41) hide show
  1. package/components/agent-icon.js +3 -2
  2. package/components/ai-elements/chain-of-thought-icon.d.ts +10 -12
  3. package/components/ai-elements/chain-of-thought-icon.js +341 -201
  4. package/components/ai-elements/chain-of-thought.d.ts +1 -1
  5. package/components/answer-sources.d.ts +42 -0
  6. package/components/answer-sources.js +111 -0
  7. package/components/answer.d.ts +1 -0
  8. package/components/answer.js +665 -671
  9. package/components/assistant-ui/answer-tool-ui.js +11 -7
  10. package/components/assistant-ui/attachment.js +39 -39
  11. package/components/assistant-ui/composer-harness.js +5 -4
  12. package/components/assistant-ui/follow-up-suggestions.d.ts +5 -1
  13. package/components/assistant-ui/follow-up-suggestions.js +47 -19
  14. package/components/assistant-ui/thread-context.d.ts +2 -0
  15. package/components/assistant-ui/thread.js +41 -40
  16. package/components/avatar.js +14 -14
  17. package/components/dropdown.d.ts +1 -1
  18. package/components/dropdown.js +1 -1
  19. package/components/empty-state.d.ts +4 -4
  20. package/components/field.js +16 -16
  21. package/components/index.d.ts +1 -0
  22. package/components/index.js +414 -408
  23. package/components/infinite-canvas.js +1 -1
  24. package/components/pixel-icon.d.ts +3 -1
  25. package/components/pixel-icon.js +294 -214
  26. package/components/segmented.d.ts +4 -1
  27. package/components/segmented.js +9 -8
  28. package/components/sidebar.d.ts +2 -2
  29. package/components/switch.js +22 -4
  30. package/components/table.d.ts +15 -7
  31. package/components/table.js +313 -199
  32. package/components/textarea.js +1 -2
  33. package/components/tooltip.js +1 -1
  34. package/components/ui/tooltip.js +5 -5
  35. package/lib/icons.d.ts +8 -0
  36. package/lib/icons.js +103 -101
  37. package/llms.txt +18 -7
  38. package/manifest.json +125 -13
  39. package/package.json +1 -1
  40. package/styles.css +42 -47
  41. package/theme.css +24 -45
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { jsx as r, jsxs as s } from "react/jsx-runtime";
3
3
  import * as i from "react";
4
- import { makeAssistantToolUI as c, useAssistantRuntime as l } from "@assistant-ui/react";
5
- import { ANSWER_TOOL_NAME as d, AnswerSpecSchema as p, AnswerSkeleton as a, ANSWER_KINDS as u, AnswerRenderer as m } from "../answer.js";
4
+ import { makeAssistantToolUI as l, useAssistantRuntime as c } from "@assistant-ui/react";
5
+ import { ANSWER_TOOL_NAME as a, AnswerSpecSchema as d, AnswerSkeleton as p, ANSWER_KINDS as u, AnswerRenderer as m } from "../answer.js";
6
6
  import { Alert as A, AlertTitle as f, AlertDescription as h } from "../alert.js";
7
7
  function S(e) {
8
8
  if (typeof e != "object" || e === null || !("kind" in e))
@@ -11,7 +11,7 @@ function S(e) {
11
11
  return u.includes(n) ? n : void 0;
12
12
  }
13
13
  function w({ spec: e }) {
14
- const n = l(), t = i.useCallback(
14
+ const n = c(), t = i.useCallback(
15
15
  (o) => {
16
16
  n.thread.append({
17
17
  role: "user",
@@ -22,11 +22,15 @@ function w({ spec: e }) {
22
22
  );
23
23
  return /* @__PURE__ */ r(m, { spec: e, onFollowUp: t, onOptionSelect: t });
24
24
  }
25
- const N = c({
26
- toolName: d,
25
+ const N = l({
26
+ toolName: a,
27
+ // The answer is the deliverable, not a research step: render it standalone,
28
+ // outside (and below) the collapsible chain-of-thought / tool trace, so it
29
+ // never collapses away with the trace.
30
+ display: "standalone",
27
31
  render: ({ args: e, status: n }) => {
28
- const t = p.safeParse(e);
29
- return t.success ? /* @__PURE__ */ r(w, { spec: t.data }) : n.type === "running" ? /* @__PURE__ */ r(a, { kind: S(e) }) : /* @__PURE__ */ s(A, { variant: "danger", children: [
32
+ const t = d.safeParse(e);
33
+ return t.success ? /* @__PURE__ */ r(w, { spec: t.data }) : n.type === "running" ? /* @__PURE__ */ r(p, { kind: S(e) }) : /* @__PURE__ */ s(A, { variant: "danger", children: [
30
34
  /* @__PURE__ */ r(f, { children: "Unable to render this answer" }),
31
35
  /* @__PURE__ */ r(h, { children: "The tool response did not match the ADS AnswerSpec contract." })
32
36
  ] });
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  var E = Object.defineProperty;
3
- var P = (a, t, n) => t in a ? E(a, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : a[t] = n;
4
- var y = (a, t, n) => P(a, typeof t != "symbol" ? t + "" : t, n);
3
+ var P = (a, t, r) => t in a ? E(a, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : a[t] = r;
4
+ var y = (a, t, r) => P(a, typeof t != "symbol" ? t + "" : t, r);
5
5
  import { jsx as e, jsxs as o, Fragment as A } from "react/jsx-runtime";
6
6
  import { useRef as N, useState as w, useEffect as U } from "react";
7
7
  import { Plus as _, FileText as h, Loader as C, WarningCircle as k, At as L, Bolt as S, Close as R } from "../../lib/icons.js";
@@ -15,30 +15,30 @@ import { Avatar as J, AvatarImage as K, AvatarFallback as Q } from "../ui/avatar
15
15
  import { TooltipIconButton as g } from "./tooltip-icon-button.js";
16
16
  import { cn as p } from "../../lib/cn.js";
17
17
  const V = (a) => {
18
- const [t, n] = w(void 0);
18
+ const [t, r] = w(void 0);
19
19
  return U(() => {
20
20
  if (!a) {
21
- n(void 0);
21
+ r(void 0);
22
22
  return;
23
23
  }
24
- const r = URL.createObjectURL(a);
25
- return n(r), () => {
26
- URL.revokeObjectURL(r);
24
+ const n = URL.createObjectURL(a);
25
+ return r(n), () => {
26
+ URL.revokeObjectURL(n);
27
27
  };
28
28
  }, [a]), t;
29
29
  }, j = () => {
30
30
  const { file: a, src: t } = l(
31
- H((n) => {
31
+ H((r) => {
32
32
  var c, m;
33
- if (n.attachment.type !== "image") return {};
34
- if (n.attachment.file) return { file: n.attachment.file };
35
- const r = (m = (c = n.attachment.content) == null ? void 0 : c.filter((d) => d.type === "image")[0]) == null ? void 0 : m.image;
36
- return r ? { src: r } : {};
33
+ if (r.attachment.type !== "image") return {};
34
+ if (r.attachment.file) return { file: r.attachment.file };
35
+ const n = (m = (c = r.attachment.content) == null ? void 0 : c.filter((d) => d.type === "image")[0]) == null ? void 0 : m.image;
36
+ return n ? { src: n } : {};
37
37
  })
38
38
  );
39
39
  return V(a) ?? t;
40
40
  }, Z = ({ src: a }) => {
41
- const [t, n] = w(!1);
41
+ const [t, r] = w(!1);
42
42
  return /* @__PURE__ */ e(
43
43
  "img",
44
44
  {
@@ -48,7 +48,7 @@ const V = (a) => {
48
48
  "block h-auto max-h-[80vh] w-auto max-w-full object-contain",
49
49
  t ? "aui-attachment-preview-image-loaded" : "aui-attachment-preview-image-loading invisible"
50
50
  ),
51
- onLoad: () => n(!0)
51
+ onLoad: () => r(!0)
52
52
  }
53
53
  );
54
54
  }, ee = ({ children: a }) => {
@@ -81,7 +81,7 @@ const V = (a) => {
81
81
  /* @__PURE__ */ e(Q, { children: /* @__PURE__ */ e(h, { className: "aui-attachment-tile-fallback-icon text-muted-foreground size-8" }) })
82
82
  ] });
83
83
  }, I = () => {
84
- const t = O().attachment.source !== "message", n = l((i) => i.attachment.contentType === D), r = l((i) => i.attachment.contentType === F), c = l((i) => i.attachment.type === "image"), m = l((i) => {
84
+ const t = O().attachment.source !== "message", r = l((i) => i.attachment.contentType === D), n = l((i) => i.attachment.contentType === F), c = l((i) => i.attachment.type === "image"), m = l((i) => {
85
85
  const b = i.attachment.type;
86
86
  switch (b) {
87
87
  case "image":
@@ -96,7 +96,7 @@ const V = (a) => {
96
96
  }), d = l(
97
97
  (i) => i.attachment.status.type === "running" ? "uploading" : i.attachment.status.type === "incomplete" && i.attachment.status.reason === "error" ? "error" : void 0
98
98
  ), f = d === "uploading", u = d === "error";
99
- return n ? /* @__PURE__ */ e(ae, { isComposer: t }) : r ? /* @__PURE__ */ e(re, { isComposer: t }) : c ? /* @__PURE__ */ o($, { children: [
99
+ return r ? /* @__PURE__ */ e(ae, { isComposer: t }) : n ? /* @__PURE__ */ e(ne, { isComposer: t }) : c ? /* @__PURE__ */ o($, { children: [
100
100
  /* @__PURE__ */ o(
101
101
  s.Root,
102
102
  {
@@ -109,7 +109,7 @@ const V = (a) => {
109
109
  "div",
110
110
  {
111
111
  className: p(
112
- "aui-attachment-tile bg-muted relative size-14 cursor-pointer overflow-hidden rounded-[calc(var(--composer-radius)-var(--composer-padding))] border transition-opacity hover:opacity-75",
112
+ "aui-attachment-tile bg-muted relative size-14 cursor-pointer overflow-hidden rounded-sm border transition-opacity hover:opacity-75",
113
113
  u && "border-destructive"
114
114
  ),
115
115
  role: "button",
@@ -142,7 +142,7 @@ const V = (a) => {
142
142
  ),
143
143
  /* @__PURE__ */ e(B, { side: "top", children: /* @__PURE__ */ e(s.Name, {}) })
144
144
  ] }) : /* @__PURE__ */ e(
145
- ne,
145
+ re,
146
146
  {
147
147
  isComposer: t,
148
148
  typeLabel: m,
@@ -164,27 +164,27 @@ const V = (a) => {
164
164
  /* @__PURE__ */ e(L, { className: "size-3.5 shrink-0 text-muted-foreground" }),
165
165
  /* @__PURE__ */ e("span", { className: "truncate", children: /* @__PURE__ */ e(s.Name, {}) }),
166
166
  a && /* @__PURE__ */ e(v, { label: "Remove context" })
167
- ] }) }), re = ({ isComposer: a }) => /* @__PURE__ */ e(s.Root, { className: "aui-attachment-root", children: /* @__PURE__ */ o("div", { className: "inline-flex max-w-[15rem] items-center gap-1.5 rounded-md bg-info-50 py-1 pe-1 ps-2 text-xs text-info-700", children: [
167
+ ] }) }), ne = ({ isComposer: a }) => /* @__PURE__ */ e(s.Root, { className: "aui-attachment-root", children: /* @__PURE__ */ o("div", { className: "inline-flex max-w-[15rem] items-center gap-1.5 rounded-md bg-info-50 py-1 pe-1 ps-2 text-xs text-info-700", children: [
168
168
  /* @__PURE__ */ e(S, { className: "size-3.5 shrink-0" }),
169
169
  /* @__PURE__ */ o("span", { className: "truncate", children: [
170
170
  "Harness · ",
171
171
  /* @__PURE__ */ e(s.Name, {})
172
172
  ] }),
173
173
  a && /* @__PURE__ */ e(v, { label: "Remove harness" })
174
- ] }) }), ne = ({ isComposer: a, typeLabel: t, isUploading: n, isError: r }) => /* @__PURE__ */ e(s.Root, { className: "aui-attachment-root", children: /* @__PURE__ */ o("div", { className: "flex w-56 max-w-full items-center gap-2.5 rounded-lg bg-muted p-1.5", children: [
174
+ ] }) }), re = ({ isComposer: a, typeLabel: t, isUploading: r, isError: n }) => /* @__PURE__ */ e(s.Root, { className: "aui-attachment-root", children: /* @__PURE__ */ o("div", { className: "flex w-56 max-w-full items-center gap-2.5 rounded-lg bg-muted p-1.5", children: [
175
175
  /* @__PURE__ */ e(
176
176
  "div",
177
177
  {
178
178
  className: p(
179
179
  "flex size-9 shrink-0 items-center justify-center rounded-md bg-background text-muted-foreground [&_svg]:size-4.5",
180
- r && "text-destructive"
180
+ n && "text-destructive"
181
181
  ),
182
- children: n ? /* @__PURE__ */ e(C, { className: "size-4 animate-spin" }) : r ? /* @__PURE__ */ e(k, {}) : /* @__PURE__ */ e(h, {})
182
+ children: r ? /* @__PURE__ */ e(C, { className: "size-4 animate-spin" }) : n ? /* @__PURE__ */ e(k, {}) : /* @__PURE__ */ e(h, {})
183
183
  }
184
184
  ),
185
185
  /* @__PURE__ */ o("div", { className: "min-w-0 flex-1", children: [
186
186
  /* @__PURE__ */ e("div", { className: "truncate text-xs font-medium leading-tight text-foreground", children: /* @__PURE__ */ e(s.Name, {}) }),
187
- /* @__PURE__ */ e("div", { className: "truncate text-[11px] leading-tight text-muted-foreground", children: r ? "Upload failed" : n ? "Uploading…" : t })
187
+ /* @__PURE__ */ e("div", { className: "truncate text-[11px] leading-tight text-muted-foreground", children: n ? "Upload failed" : r ? "Uploading…" : t })
188
188
  ] }),
189
189
  a && /* @__PURE__ */ e(v, { label: "Remove file" })
190
190
  ] }) }), oe = () => /* @__PURE__ */ e(s.Remove, { asChild: !0, children: /* @__PURE__ */ e(
@@ -236,9 +236,9 @@ const V = (a) => {
236
236
  "application/javascript",
237
237
  "application/typescript",
238
238
  ".pdf,.doc,.docx,.odt,.rtf,.ppt,.pptx,.xls,.xlsx,.csv,.tsv,.txt,.md,.markdown,.json,.html,.xml,.css,.js,.jsx,.ts,.tsx,.sql,.py,.yaml,.yml,.log"
239
- ].join(","), ce = `${ie},${x}`, le = (a) => new Promise((t, n) => {
240
- const r = new FileReader();
241
- r.onload = () => t(r.result), r.onerror = () => n(r.error), r.readAsDataURL(a);
239
+ ].join(","), ce = `${ie},${x}`, le = (a) => new Promise((t, r) => {
240
+ const n = new FileReader();
241
+ n.onload = () => t(n.result), n.onerror = () => r(n.error), n.readAsDataURL(a);
242
242
  });
243
243
  class Re {
244
244
  constructor() {
@@ -272,9 +272,9 @@ class Re {
272
272
  }
273
273
  }
274
274
  const Te = () => {
275
- const a = z(), t = N(null), n = (r) => {
276
- if (r != null && r.length)
277
- for (const c of Array.from(r))
275
+ const a = z(), t = N(null), r = (n) => {
276
+ if (n != null && n.length)
277
+ for (const c of Array.from(n))
278
278
  c.type.startsWith("image/") && !se.has(c.type) || a.addAttachment(c);
279
279
  };
280
280
  return /* @__PURE__ */ o(A, { children: [
@@ -286,8 +286,8 @@ const Te = () => {
286
286
  type: "file",
287
287
  accept: ce,
288
288
  multiple: !0,
289
- onChange: (r) => {
290
- n(r.currentTarget.files), r.currentTarget.value = "";
289
+ onChange: (n) => {
290
+ r(n.currentTarget.files), n.currentTarget.value = "";
291
291
  }
292
292
  }
293
293
  ),
@@ -302,8 +302,8 @@ const Te = () => {
302
302
  className: "aui-composer-add-image hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30 size-7 rounded-full p-1",
303
303
  "aria-label": "Upload image or file",
304
304
  onClick: () => {
305
- var r;
306
- return (r = t.current) == null ? void 0 : r.click();
305
+ var n;
306
+ return (n = t.current) == null ? void 0 : n.click();
307
307
  },
308
308
  children: /* @__PURE__ */ e(h, { className: "aui-attachment-add-file-icon size-4.5 stroke-[1.5px]" })
309
309
  }
@@ -320,10 +320,10 @@ const Te = () => {
320
320
  type: "file",
321
321
  accept: x,
322
322
  multiple: !0,
323
- onChange: (n) => {
324
- for (const r of Array.from(n.currentTarget.files ?? []))
325
- a.addAttachment(r);
326
- n.currentTarget.value = "";
323
+ onChange: (r) => {
324
+ for (const n of Array.from(r.currentTarget.files ?? []))
325
+ a.addAttachment(n);
326
+ r.currentTarget.value = "";
327
327
  }
328
328
  }
329
329
  ),
@@ -338,8 +338,8 @@ const Te = () => {
338
338
  className: "aui-composer-add-document hover:bg-muted-foreground/15 size-7 rounded-full p-1",
339
339
  "aria-label": "Attach business documents",
340
340
  onClick: () => {
341
- var n;
342
- return (n = t.current) == null ? void 0 : n.click();
341
+ var r;
342
+ return (r = t.current) == null ? void 0 : r.click();
343
343
  },
344
344
  children: /* @__PURE__ */ e(h, { className: "size-4.5 stroke-[1.5px]" })
345
345
  }
@@ -44,6 +44,7 @@ import "../popover.js";
44
44
  import { Dropdown as b, DropdownTrigger as v, DropdownContent as y, DropdownLabel as x, DropdownItem as w } from "../dropdown.js";
45
45
  import "../toast.js";
46
46
  import "../answer.js";
47
+ import "../answer-sources.js";
47
48
  import "../card.js";
48
49
  import "../carousel.js";
49
50
  import "../chart.js";
@@ -126,7 +127,7 @@ const m = "application/x-actioneer-harness", S = [
126
127
  instructions: "Write a concise executive brief: lead with the decision or insight, use only decision-relevant evidence, and end with the recommended next action."
127
128
  }
128
129
  ];
129
- function xi() {
130
+ function wi() {
130
131
  const r = d(), t = u((i) => i.attachments), o = new Set(
131
132
  t.filter((i) => i.contentType === m).map((i) => i.name)
132
133
  ), s = (i) => {
@@ -169,7 +170,7 @@ function xi() {
169
170
  ] })
170
171
  ] });
171
172
  }
172
- class wi {
173
+ class Si {
173
174
  constructor() {
174
175
  p(this, "accept", m);
175
176
  }
@@ -202,7 +203,7 @@ ${o}
202
203
  }
203
204
  }
204
205
  export {
205
- xi as ComposerHarness,
206
+ wi as ComposerHarness,
206
207
  m as HARNESS_MIME,
207
- wi as HarnessAttachmentAdapter
208
+ Si as HarnessAttachmentAdapter
208
209
  };
@@ -2,6 +2,10 @@ import { ButtonProps } from '../button';
2
2
  import * as React from "react";
3
3
  export interface FollowUpSuggestionProps extends Omit<ButtonProps, "size" | "variant"> {
4
4
  }
5
- /** Shared follow-up prompt button used both in answers and above the composer. */
5
+ /** Compact runtime suggestion shown above the composer. */
6
6
  export declare const FollowUpSuggestion: React.ForwardRefExoticComponent<FollowUpSuggestionProps & React.RefAttributes<HTMLButtonElement>>;
7
+ export interface FollowUpQuestionProps extends Omit<ButtonProps, "size" | "variant" | "startContent" | "endContent"> {
8
+ }
9
+ /** Full-width next-question row used at the end of a structured answer. */
10
+ export declare const FollowUpQuestion: React.ForwardRefExoticComponent<FollowUpQuestionProps & React.RefAttributes<HTMLButtonElement>>;
7
11
  export declare const ThreadFollowupSuggestions: React.FC;
@@ -1,37 +1,64 @@
1
1
  "use client";
2
- import { jsx as o } from "react/jsx-runtime";
3
- import * as n from "react";
4
- import { useAuiState as s, AuiIf as a, ThreadPrimitive as u } from "@assistant-ui/react";
5
- import { Button as l } from "../button.js";
6
- import { cn as d } from "../../lib/cn.js";
7
- const i = n.forwardRef(({ className: t, ...e }, r) => /* @__PURE__ */ o(
8
- l,
2
+ import { jsx as t, jsxs as u } from "react/jsx-runtime";
3
+ import * as i from "react";
4
+ import { useAuiState as d, AuiIf as p, ThreadPrimitive as m } from "@assistant-ui/react";
5
+ import { Button as n } from "../button.js";
6
+ import { AgentChat as g, ArrowUpRight as c } from "../../lib/icons.js";
7
+ import { cn as s } from "../../lib/cn.js";
8
+ const a = i.forwardRef(({ className: o, ...e }, r) => /* @__PURE__ */ t(
9
+ n,
9
10
  {
10
11
  ref: r,
11
12
  size: "xs",
12
13
  variant: "outline",
13
- className: d(
14
+ className: s(
14
15
  "aui-thread-followup-suggestion rounded-full border-border/60 bg-background px-3 font-normal hover:bg-muted/80",
15
- t
16
+ o
16
17
  ),
17
18
  ...e
18
19
  }
19
20
  ));
20
- i.displayName = "FollowUpSuggestion";
21
- const h = () => {
22
- const t = s((e) => e.thread.suggestions);
23
- return /* @__PURE__ */ o(
24
- a,
21
+ a.displayName = "FollowUpSuggestion";
22
+ const h = i.forwardRef(({ className: o, children: e, ...r }, l) => /* @__PURE__ */ u(
23
+ n,
24
+ {
25
+ ref: l,
26
+ size: "sm",
27
+ variant: "outline",
28
+ className: s(
29
+ "group/followup h-auto w-full justify-start whitespace-normal rounded-lg border-border bg-card px-3.5 py-2.5 text-left text-sm text-foreground hover:bg-surface",
30
+ "motion-reduce:transition-none [&>span]:w-full [&>span]:gap-2.5",
31
+ o
32
+ ),
33
+ ...r,
34
+ children: [
35
+ /* @__PURE__ */ t(g, { "aria-hidden": !0, className: "size-4 shrink-0 text-tertiary" }),
36
+ /* @__PURE__ */ t("span", { className: "min-w-0 flex-1", children: e }),
37
+ /* @__PURE__ */ t(
38
+ c,
39
+ {
40
+ "aria-hidden": !0,
41
+ className: "size-4 shrink-0 text-tertiary transition-colors group-hover/followup:text-foreground motion-reduce:transition-none"
42
+ }
43
+ )
44
+ ]
45
+ }
46
+ ));
47
+ h.displayName = "FollowUpQuestion";
48
+ const N = () => {
49
+ const o = d((e) => e.thread.suggestions);
50
+ return /* @__PURE__ */ t(
51
+ p,
25
52
  {
26
53
  condition: (e) => !e.thread.isEmpty && !e.thread.isRunning && e.thread.suggestions.length > 0,
27
- children: /* @__PURE__ */ o("div", { className: "aui-thread-followup-suggestions flex min-h-8 items-center justify-center gap-2", children: t.map((e, r) => /* @__PURE__ */ o(
28
- u.Suggestion,
54
+ children: /* @__PURE__ */ t("div", { className: "aui-thread-followup-suggestions flex min-h-8 items-center justify-center gap-2", children: o.map((e, r) => /* @__PURE__ */ t(
55
+ m.Suggestion,
29
56
  {
30
57
  prompt: e.prompt,
31
58
  method: "replace",
32
59
  autoSend: !0,
33
60
  asChild: !0,
34
- children: /* @__PURE__ */ o(i, { children: e.prompt })
61
+ children: /* @__PURE__ */ t(a, { children: e.prompt })
35
62
  },
36
63
  r
37
64
  )) })
@@ -39,6 +66,7 @@ const h = () => {
39
66
  );
40
67
  };
41
68
  export {
42
- i as FollowUpSuggestion,
43
- h as ThreadFollowupSuggestions
69
+ h as FollowUpQuestion,
70
+ a as FollowUpSuggestion,
71
+ N as ThreadFollowupSuggestions
44
72
  };
@@ -33,6 +33,8 @@ export type ThreadProps = {
33
33
  components?: ThreadComponents | undefined;
34
34
  /** Registers ADS's typed `render_answer` Tool UI. Enabled by default. */
35
35
  isAnswerToolEnabled?: boolean | undefined;
36
+ /** Keep the composer docked to the bottom even before the first message. */
37
+ composerPlacement?: "adaptive" | "bottom" | undefined;
36
38
  };
37
39
  export declare const EMPTY_COMPONENTS: ThreadComponents;
38
40
  export declare const ThreadComponentsContext: import('react').Context<ThreadComponents>;
@@ -1,31 +1,32 @@
1
1
  "use client";
2
2
  import { jsxs as l, jsx as o } from "react/jsx-runtime";
3
- import { Composer as m } from "./composer.js";
4
- import { ComposerPlaceholdersProvider as z } from "./composer.js";
5
- import { RenderAnswerToolUI as c } from "./answer-tool-ui.js";
6
- import { ThreadFollowupSuggestions as f } from "./follow-up-suggestions.js";
7
- import { ThreadMessage as u } from "./message.js";
8
- import { SelectionToolbar as h } from "./selection-toolbar.js";
9
- import { ThreadSuggestions as p } from "./suggestions.js";
10
- import { isNewChatView as a, ThreadComponentsContext as s, EMPTY_COMPONENTS as x } from "./thread-context.js";
11
- import { TooltipIconButton as b } from "./tooltip-icon-button.js";
12
- import { cn as w } from "../../lib/cn.js";
13
- import { useAuiState as g, ThreadPrimitive as e, AuiIf as d } from "@assistant-ui/react";
14
- import { ArrowDown as v } from "../../lib/icons.js";
15
- import { useContext as T } from "react";
16
- const F = ({
17
- components: r = x,
18
- isAnswerToolEnabled: i = !0
3
+ import { Composer as s } from "./composer.js";
4
+ import { ComposerPlaceholdersProvider as U } from "./composer.js";
5
+ import { RenderAnswerToolUI as p } from "./answer-tool-ui.js";
6
+ import { ThreadFollowupSuggestions as u } from "./follow-up-suggestions.js";
7
+ import { ThreadMessage as h } from "./message.js";
8
+ import { SelectionToolbar as x } from "./selection-toolbar.js";
9
+ import { ThreadSuggestions as b } from "./suggestions.js";
10
+ import { isNewChatView as n, ThreadComponentsContext as f, EMPTY_COMPONENTS as v } from "./thread-context.js";
11
+ import { TooltipIconButton as w } from "./tooltip-icon-button.js";
12
+ import { cn as g } from "../../lib/cn.js";
13
+ import { useAuiState as T, ThreadPrimitive as e, AuiIf as c } from "@assistant-ui/react";
14
+ import { ArrowDown as N } from "../../lib/icons.js";
15
+ import { useContext as C } from "react";
16
+ const W = ({
17
+ components: r = v,
18
+ isAnswerToolEnabled: i = !0,
19
+ composerPlacement: a = "adaptive"
19
20
  }) => {
20
- const t = g(a);
21
- return /* @__PURE__ */ l(s.Provider, { value: r, children: [
22
- i && /* @__PURE__ */ o(c, {}),
23
- /* @__PURE__ */ o(N, { isEmpty: t })
21
+ const t = T(n);
22
+ return /* @__PURE__ */ l(f.Provider, { value: r, children: [
23
+ i && /* @__PURE__ */ o(p, {}),
24
+ /* @__PURE__ */ o(k, { isEmpty: t, composerPlacement: a })
24
25
  ] });
25
- }, N = ({ isEmpty: r }) => {
26
- const { Welcome: i = k, ComposerDock: t } = T(
27
- s
28
- );
26
+ }, k = ({ isEmpty: r, composerPlacement: i }) => {
27
+ const { Welcome: a = S, ComposerDock: t } = C(
28
+ f
29
+ ), m = i === "bottom";
29
30
  return /* @__PURE__ */ l(e.Root, { className: "aui-root aui-thread-root bg-background @container flex h-full flex-col", children: [
30
31
  /* @__PURE__ */ o(
31
32
  e.Viewport,
@@ -34,46 +35,46 @@ const F = ({
34
35
  "data-slot": "aui_thread-viewport",
35
36
  className: "relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth",
36
37
  children: /* @__PURE__ */ l("div", { className: "mx-auto flex w-full max-w-(--thread-max-width) flex-1 flex-col px-4 pt-4", children: [
37
- /* @__PURE__ */ o(d, { condition: a, children: /* @__PURE__ */ o("div", { className: "flex flex-1 flex-col items-center justify-end", children: /* @__PURE__ */ o(i, {}) }) }),
38
+ /* @__PURE__ */ o(c, { condition: n, children: /* @__PURE__ */ o("div", { className: "flex flex-1 flex-col items-center justify-end", children: /* @__PURE__ */ o(a, {}) }) }),
38
39
  /* @__PURE__ */ o(
39
40
  "div",
40
41
  {
41
42
  "data-slot": "aui_message-group",
42
43
  className: "mb-14 flex flex-col gap-y-8 empty:hidden",
43
- children: /* @__PURE__ */ o(e.Messages, { children: () => /* @__PURE__ */ o(u, {}) })
44
+ children: /* @__PURE__ */ o(e.Messages, { children: () => /* @__PURE__ */ o(h, {}) })
44
45
  }
45
46
  ),
46
47
  /* @__PURE__ */ l(
47
48
  e.ViewportFooter,
48
49
  {
49
- className: w(
50
+ className: g(
50
51
  "aui-thread-viewport-footer bg-background flex flex-col gap-4 overflow-visible pb-4 md:pb-6",
51
- r && "flex-1",
52
- !r && "sticky bottom-0 mt-auto rounded-t-(--composer-radius)"
52
+ r && !m && "flex-1",
53
+ (!r || m) && "sticky bottom-0 mt-auto rounded-t-(--composer-radius)"
53
54
  ),
54
55
  children: [
55
- /* @__PURE__ */ o(C, {}),
56
- /* @__PURE__ */ o(f, {}),
57
- t ? /* @__PURE__ */ o(t, { children: /* @__PURE__ */ o(m, {}) }) : /* @__PURE__ */ o(m, {}),
58
- /* @__PURE__ */ o(d, { condition: (n) => a(n) && n.composer.isEmpty, children: /* @__PURE__ */ o(p, {}) })
56
+ /* @__PURE__ */ o(y, {}),
57
+ /* @__PURE__ */ o(u, {}),
58
+ t ? /* @__PURE__ */ o(t, { children: /* @__PURE__ */ o(s, {}) }) : /* @__PURE__ */ o(s, {}),
59
+ /* @__PURE__ */ o(c, { condition: (d) => n(d) && d.composer.isEmpty, children: /* @__PURE__ */ o(b, {}) })
59
60
  ]
60
61
  }
61
62
  )
62
63
  ] })
63
64
  }
64
65
  ),
65
- /* @__PURE__ */ o(h, {})
66
+ /* @__PURE__ */ o(x, {})
66
67
  ] });
67
- }, C = () => /* @__PURE__ */ o(e.ScrollToBottom, { asChild: !0, children: /* @__PURE__ */ o(
68
- b,
68
+ }, y = () => /* @__PURE__ */ o(e.ScrollToBottom, { asChild: !0, children: /* @__PURE__ */ o(
69
+ w,
69
70
  {
70
71
  tooltip: "Scroll to bottom",
71
72
  variant: "outline",
72
73
  className: "aui-thread-scroll-to-bottom dark:border-border dark:bg-background dark:hover:bg-accent absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible",
73
- children: /* @__PURE__ */ o(v, {})
74
+ children: /* @__PURE__ */ o(N, {})
74
75
  }
75
- ) }), k = () => /* @__PURE__ */ o("div", { className: "aui-thread-welcome-root mb-6 flex flex-col items-center px-4 text-center", children: /* @__PURE__ */ o("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-xl font-semibold duration-(--duration-normal)", children: "How can I help you today?" }) });
76
+ ) }), S = () => /* @__PURE__ */ o("div", { className: "aui-thread-welcome-root mb-6 flex flex-col items-center px-4 text-center", children: /* @__PURE__ */ o("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-xl font-semibold duration-(--duration-normal)", children: "How can I help you today?" }) });
76
77
  export {
77
- z as ComposerPlaceholdersProvider,
78
- F as Thread
78
+ U as ComposerPlaceholdersProvider,
79
+ W as Thread
79
80
  };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as l, jsxs as x } from "react/jsx-runtime";
3
3
  import * as f from "react";
4
- import { cn as o } from "../lib/cn.js";
4
+ import { cn as i } from "../lib/cn.js";
5
5
  const g = {
6
6
  sm: "size-8 text-xs",
7
7
  md: "size-10 text-xs",
@@ -20,7 +20,7 @@ const m = [
20
20
  "bg-(--color-lime-soft) text-(--color-lime-deep)",
21
21
  "bg-(--color-amber-soft) text-(--color-amber-deep)",
22
22
  "bg-info-100 text-info-700",
23
- "bg-sage-300 text-sage-950"
23
+ "bg-ink-300 text-ink-950"
24
24
  ];
25
25
  function y(r) {
26
26
  let e = 0;
@@ -28,7 +28,7 @@ function y(r) {
28
28
  return m[e % m.length];
29
29
  }
30
30
  const N = f.forwardRef(
31
- ({ className: r, src: e, name: t, size: i = "md", radius: s = "full", ...a }, c) => {
31
+ ({ className: r, src: e, name: t, size: o = "md", radius: s = "full", ...a }, c) => {
32
32
  const n = t ? v(t) : "";
33
33
  return /* @__PURE__ */ l(
34
34
  "span",
@@ -36,12 +36,12 @@ const N = f.forwardRef(
36
36
  ref: c,
37
37
  role: "img",
38
38
  "aria-label": t,
39
- className: o(
39
+ className: i(
40
40
  "relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden font-normal",
41
41
  // Images sit on the neutral fill; initials take a deterministic
42
42
  // per-name identity tint so a roster reads multi-color.
43
43
  e || !t ? "bg-fill text-fill-foreground" : y(t),
44
- g[i],
44
+ g[o],
45
45
  p[s],
46
46
  r
47
47
  ),
@@ -59,20 +59,20 @@ const N = f.forwardRef(
59
59
  }
60
60
  );
61
61
  N.displayName = "Avatar";
62
- const z = f.forwardRef(
63
- ({ className: r, max: e, size: t = "md", radius: i = "full", children: s, ...a }, c) => {
62
+ const k = f.forwardRef(
63
+ ({ className: r, max: e, size: t = "md", radius: o = "full", children: s, ...a }, c) => {
64
64
  const n = f.Children.toArray(s), d = typeof e == "number" ? n.length - e : 0, h = typeof e == "number" ? n.slice(0, e) : n;
65
65
  return /* @__PURE__ */ x(
66
66
  "div",
67
67
  {
68
68
  ref: c,
69
- className: o("flex items-center", r),
69
+ className: i("flex items-center", r),
70
70
  ...a,
71
71
  children: [
72
72
  h.map((b, u) => /* @__PURE__ */ l(
73
73
  "div",
74
74
  {
75
- className: o(
75
+ className: i(
76
76
  "ring-2 ring-background rounded-full",
77
77
  u > 0 && "-ml-2"
78
78
  ),
@@ -80,16 +80,16 @@ const z = f.forwardRef(
80
80
  },
81
81
  u
82
82
  )),
83
- d > 0 && /* @__PURE__ */ l("div", { className: o("ring-2 ring-background rounded-full -ml-2"), children: /* @__PURE__ */ l(
83
+ d > 0 && /* @__PURE__ */ l("div", { className: i("ring-2 ring-background rounded-full -ml-2"), children: /* @__PURE__ */ l(
84
84
  "span",
85
85
  {
86
86
  role: "img",
87
87
  "aria-label": `${d} more`,
88
- className: o(
88
+ className: i(
89
89
  "relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden font-normal",
90
90
  "bg-muted text-muted-foreground",
91
91
  g[t],
92
- p[i]
92
+ p[o]
93
93
  ),
94
94
  children: /* @__PURE__ */ l("span", { "aria-hidden": !0, children: `+${d}` })
95
95
  }
@@ -99,8 +99,8 @@ const z = f.forwardRef(
99
99
  );
100
100
  }
101
101
  );
102
- z.displayName = "AvatarGroup";
102
+ k.displayName = "AvatarGroup";
103
103
  export {
104
104
  N as Avatar,
105
- z as AvatarGroup
105
+ k as AvatarGroup
106
106
  };
@@ -18,7 +18,7 @@ export interface DropdownContentProps extends React.HTMLAttributes<HTMLDivElemen
18
18
  /** Which side of the trigger the menu opens on. Default below. */
19
19
  side?: "top" | "bottom";
20
20
  sideOffset?: number;
21
- /** Focus the menu surface on open without highlighting its first item. */
21
+ /** Opt in to focusing the first item when the menu opens. */
22
22
  autoFocusFirstItem?: boolean;
23
23
  }
24
24
  export declare function DropdownContent({ className, align, side, sideOffset, autoFocusFirstItem, children, ...props }: DropdownContentProps): React.ReactPortal;
@@ -34,7 +34,7 @@ function W({
34
34
  align: t = "start",
35
35
  side: n = "bottom",
36
36
  sideOffset: d = 6,
37
- autoFocusFirstItem: f = !0,
37
+ autoFocusFirstItem: f = !1,
38
38
  children: p,
39
39
  ...v
40
40
  }) {