@dataverse-kit/agent-kit 0.2.1 → 0.3.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.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/conversation/MessageList.tsx
2
- import * as React10 from "react";
2
+ import * as React11 from "react";
3
3
  import { Button as Button3, makeStyles as makeStyles10, tokens as tokens9 } from "@fluentui/react-components";
4
4
  import { ArrowDownRegular } from "@fluentui/react-icons";
5
5
 
@@ -585,12 +585,40 @@ function useRovingTabindex(options) {
585
585
  return { activeIndex, setActiveIndex, getItemProps };
586
586
  }
587
587
 
588
- // src/hooks/useStickyScroll.ts
588
+ // src/a11y/useReturnFocus.ts
589
589
  import * as React4 from "react";
590
+ function useReturnFocus({ open, containerRef, manageInitialFocus = true }) {
591
+ const openerRef = React4.useRef(null);
592
+ const wasOpen = React4.useRef(open);
593
+ React4.useEffect(() => {
594
+ const container = containerRef.current;
595
+ const doc = container?.ownerDocument ?? (typeof document !== "undefined" ? document : void 0);
596
+ if (!doc) return;
597
+ if (open && !wasOpen.current) {
598
+ const active = doc.activeElement;
599
+ openerRef.current = active instanceof HTMLElement && active !== doc.body ? active : null;
600
+ if (manageInitialFocus && container) {
601
+ const first = container.querySelector(
602
+ 'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])'
603
+ );
604
+ (first ?? container).focus();
605
+ }
606
+ }
607
+ if (!open && wasOpen.current) {
608
+ const opener = openerRef.current;
609
+ if (opener && opener.isConnected) opener.focus();
610
+ openerRef.current = null;
611
+ }
612
+ wasOpen.current = open;
613
+ }, [open, containerRef, manageInitialFocus]);
614
+ }
615
+
616
+ // src/hooks/useStickyScroll.ts
617
+ import * as React5 from "react";
590
618
  function useStickyScroll(ref, messageCount) {
591
- const wasPinnedRef = React4.useRef(true);
592
- const [isPinned, setIsPinned] = React4.useState(true);
593
- const onScroll = React4.useCallback(() => {
619
+ const wasPinnedRef = React5.useRef(true);
620
+ const [isPinned, setIsPinned] = React5.useState(true);
621
+ const onScroll = React5.useCallback(() => {
594
622
  const el = ref.current;
595
623
  if (!el) return;
596
624
  const pinned = shouldStickToBottom({
@@ -601,14 +629,14 @@ function useStickyScroll(ref, messageCount) {
601
629
  wasPinnedRef.current = pinned;
602
630
  setIsPinned(pinned);
603
631
  }, [ref]);
604
- const scrollToBottom = React4.useCallback(() => {
632
+ const scrollToBottom = React5.useCallback(() => {
605
633
  const el = ref.current;
606
634
  if (!el) return;
607
635
  el.scrollTo({ top: el.scrollHeight, behavior: "auto" });
608
636
  wasPinnedRef.current = true;
609
637
  setIsPinned(true);
610
638
  }, [ref]);
611
- React4.useEffect(() => {
639
+ React5.useEffect(() => {
612
640
  if (!wasPinnedRef.current) return;
613
641
  const el = ref.current;
614
642
  if (!el) return;
@@ -618,30 +646,30 @@ function useStickyScroll(ref, messageCount) {
618
646
  }
619
647
 
620
648
  // src/hooks/useConversation.ts
621
- import * as React5 from "react";
649
+ import * as React6 from "react";
622
650
  var fallbackId = 0;
623
651
  function useConversation(options) {
624
652
  const { service, seed, grounding, conversationId, createId } = options;
625
- const [state, setState] = React5.useState(() => initialConversation(seed));
626
- const [announcement, setAnnouncement] = React5.useState(NO_ANNOUNCEMENT);
627
- const abortRef = React5.useRef(null);
628
- const stateRef = React5.useRef(state);
653
+ const [state, setState] = React6.useState(() => initialConversation(seed));
654
+ const [announcement, setAnnouncement] = React6.useState(NO_ANNOUNCEMENT);
655
+ const abortRef = React6.useRef(null);
656
+ const stateRef = React6.useRef(state);
629
657
  stateRef.current = state;
630
- const nextId = React5.useCallback(
658
+ const nextId = React6.useCallback(
631
659
  () => createId?.() ?? `m${++fallbackId}-${Date.now().toString(36)}`,
632
660
  [createId]
633
661
  );
634
- const commit = React5.useCallback((next) => {
662
+ const commit = React6.useCallback((next) => {
635
663
  const previous = stateRef.current;
636
664
  stateRef.current = next;
637
665
  setState(next);
638
666
  const derived = deriveAnnouncement(next, previous);
639
667
  if (derived.polite || derived.assertive) setAnnouncement(derived);
640
668
  }, []);
641
- const cancel = React5.useCallback(() => {
669
+ const cancel = React6.useCallback(() => {
642
670
  abortRef.current?.abort();
643
671
  }, []);
644
- const send = React5.useCallback(
672
+ const send = React6.useCallback(
645
673
  async (text, attachments) => {
646
674
  if (!text.trim()) return;
647
675
  abortRef.current?.abort();
@@ -678,13 +706,13 @@ function useConversation(options) {
678
706
  },
679
707
  [service, grounding, conversationId, nextId, commit]
680
708
  );
681
- React5.useEffect(() => () => abortRef.current?.abort(), []);
709
+ React6.useEffect(() => () => abortRef.current?.abort(), []);
682
710
  const busy = state.status === "connecting" || state.status === "streaming";
683
711
  return { state, announcement, busy, send, cancel };
684
712
  }
685
713
 
686
714
  // src/conversation/MessageBubble.tsx
687
- import * as React9 from "react";
715
+ import * as React10 from "react";
688
716
  import { Avatar, makeStyles as makeStyles7, mergeClasses as mergeClasses4, tokens as tokens6 } from "@fluentui/react-components";
689
717
 
690
718
  // src/conversation/StreamingText.tsx
@@ -761,7 +789,7 @@ function ActionToolbar({ actions, label, className }) {
761
789
  }
762
790
 
763
791
  // src/internal/CardSurface.tsx
764
- import * as React6 from "react";
792
+ import * as React7 from "react";
765
793
  import { makeStyles as makeStyles4, mergeClasses as mergeClasses2, tokens as tokens3 } from "@fluentui/react-components";
766
794
  import { jsx as jsx4 } from "react/jsx-runtime";
767
795
  var useStyles3 = makeStyles4({
@@ -777,7 +805,7 @@ var useStyles3 = makeStyles4({
777
805
  },
778
806
  attention: { borderLeft: `3px solid ${tokens3.colorBrandStroke1}` }
779
807
  });
780
- var CardSurface = React6.forwardRef(
808
+ var CardSurface = React7.forwardRef(
781
809
  function CardSurface2({ emphasis = "none", className, children, ...rest }, ref) {
782
810
  const styles = useStyles3();
783
811
  return /* @__PURE__ */ jsx4(
@@ -793,7 +821,7 @@ var CardSurface = React6.forwardRef(
793
821
  );
794
822
 
795
823
  // src/internal/ConfirmInline.tsx
796
- import * as React7 from "react";
824
+ import * as React8 from "react";
797
825
  import { Button as Button2, makeStyles as makeStyles5, tokens as tokens4, Text } from "@fluentui/react-components";
798
826
  import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
799
827
  var useStyles4 = makeStyles5({
@@ -804,11 +832,11 @@ var FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),textarea:n
804
832
  function ConfirmInline(props) {
805
833
  const { open, title, body, confirmLabel = "Confirm", cancelLabel = "Cancel", destructive, onConfirm, onCancel } = props;
806
834
  const styles = useStyles4();
807
- const ref = React7.useRef(null);
808
- const returnTo = React7.useRef(null);
809
- const titleId = React7.useId();
810
- const bodyId = React7.useId();
811
- React7.useEffect(() => {
835
+ const ref = React8.useRef(null);
836
+ const returnTo = React8.useRef(null);
837
+ const titleId = React8.useId();
838
+ const bodyId = React8.useId();
839
+ React8.useEffect(() => {
812
840
  if (!open) return;
813
841
  returnTo.current = document.activeElement ?? null;
814
842
  const first = ref.current?.querySelector(FOCUSABLE);
@@ -863,7 +891,7 @@ function ConfirmInline(props) {
863
891
  }
864
892
 
865
893
  // src/internal/Disclosure.tsx
866
- import * as React8 from "react";
894
+ import * as React9 from "react";
867
895
  import { makeStyles as makeStyles6, tokens as tokens5, mergeClasses as mergeClasses3 } from "@fluentui/react-components";
868
896
  import { ChevronRightRegular, ChevronDownRegular } from "@fluentui/react-icons";
869
897
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -891,7 +919,7 @@ function Disclosure({
891
919
  className
892
920
  }) {
893
921
  const styles = useStyles5();
894
- const [open, setOpen] = React8.useState(defaultOpen);
922
+ const [open, setOpen] = React9.useState(defaultOpen);
895
923
  const panelId = `${id}-panel`;
896
924
  return /* @__PURE__ */ jsxs4("div", { className, children: [
897
925
  /* @__PURE__ */ jsxs4(
@@ -988,7 +1016,7 @@ function MessageBubble(props) {
988
1016
  const { message, author, isRunStart = true, locale, ...actionHandlers } = props;
989
1017
  const styles = useStyles6();
990
1018
  const hidden = useVisuallyHiddenStyles();
991
- const [revealed, setRevealed] = React9.useState(false);
1019
+ const [revealed, setRevealed] = React10.useState(false);
992
1020
  const own = message.role === "user";
993
1021
  const name = author?.displayName ?? (own ? "You" : message.provider ?? "Assistant");
994
1022
  const time = new Intl.DateTimeFormat(locale, { timeStyle: "short" }).format(new Date(message.createdAt));
@@ -1126,21 +1154,21 @@ function MessageList(props) {
1126
1154
  ...actionHandlers
1127
1155
  } = props;
1128
1156
  const styles = useStyles9();
1129
- const scrollerRef = React10.useRef(null);
1157
+ const scrollerRef = React11.useRef(null);
1130
1158
  const { onScroll, scrollToBottom, isPinned } = useStickyScroll(scrollerRef, messages.length);
1131
- const byId = React10.useMemo(
1159
+ const byId = React11.useMemo(
1132
1160
  () => new Map((participants ?? []).map((p) => [p.id, p])),
1133
1161
  [participants]
1134
1162
  );
1135
- const runStarts = React10.useMemo(() => {
1163
+ const runStarts = React11.useMemo(() => {
1136
1164
  const groups = groupMessages(messages, { windowMs: groupWindowMs, timeZone });
1137
1165
  return new Set(groups.map((g) => g.messageIds[0]));
1138
1166
  }, [messages, groupWindowMs, timeZone]);
1139
- const buckets = React10.useMemo(
1167
+ const buckets = React11.useMemo(
1140
1168
  () => bucketByDay(messages, { timeZone, now }),
1141
1169
  [messages, timeZone, now]
1142
1170
  );
1143
- const dividerBefore = React10.useMemo(() => {
1171
+ const dividerBefore = React11.useMemo(() => {
1144
1172
  const map = /* @__PURE__ */ new Map();
1145
1173
  for (const bucket of buckets) map.set(bucket.messageIds[0], bucket.label);
1146
1174
  return map;
@@ -1157,7 +1185,7 @@ function MessageList(props) {
1157
1185
  "aria-label": "Conversation",
1158
1186
  tabIndex: 0,
1159
1187
  children: [
1160
- messages.length === 0 ? emptyState ?? null : messages.map((message) => /* @__PURE__ */ jsxs8(React10.Fragment, { children: [
1188
+ messages.length === 0 ? emptyState ?? null : messages.map((message) => /* @__PURE__ */ jsxs8(React11.Fragment, { children: [
1161
1189
  dividerBefore.has(message.id) ? /* @__PURE__ */ jsx11(DayDivider, { label: dividerBefore.get(message.id), locale }) : null,
1162
1190
  /* @__PURE__ */ jsx11(
1163
1191
  MessageBubble,
@@ -1189,7 +1217,7 @@ function MessageList(props) {
1189
1217
  }
1190
1218
 
1191
1219
  // src/conversation/Composer.tsx
1192
- import * as React11 from "react";
1220
+ import * as React12 from "react";
1193
1221
  import { Button as Button4, Textarea, makeStyles as makeStyles11, mergeClasses as mergeClasses5, tokens as tokens10, Tooltip as Tooltip2 } from "@fluentui/react-components";
1194
1222
  import { SendRegular, StopRegular } from "@fluentui/react-icons";
1195
1223
  import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -1276,7 +1304,7 @@ function Composer(props) {
1276
1304
  } = props;
1277
1305
  const styles = useStyles10();
1278
1306
  const vh = useVisuallyHiddenStyles();
1279
- const hintId = React11.useId();
1307
+ const hintId = React12.useId();
1280
1308
  const submit = () => {
1281
1309
  const text = value.trim();
1282
1310
  if (!text || busy || disabled) return;
@@ -1539,14 +1567,14 @@ function UsageMeter({
1539
1567
  }
1540
1568
 
1541
1569
  // src/ops/ThrottleNotice.tsx
1542
- import * as React12 from "react";
1570
+ import * as React13 from "react";
1543
1571
  import { MessageBar as MessageBar3, MessageBarBody as MessageBarBody3, MessageBarTitle as MessageBarTitle3, MessageBarActions as MessageBarActions3, Button as Button8 } from "@fluentui/react-components";
1544
1572
  import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1545
1573
  function ThrottleNotice({ failure, onRetry, now = Date.now }) {
1546
1574
  const retryAfterMs = failure?.retryAfterMs;
1547
1575
  const eligible = Boolean(failure?.recoverable && retryAfterMs && retryAfterMs > 0);
1548
- const [remaining, setRemaining] = React12.useState(retryAfterMs ?? 0);
1549
- React12.useEffect(() => {
1576
+ const [remaining, setRemaining] = React13.useState(retryAfterMs ?? 0);
1577
+ React13.useEffect(() => {
1550
1578
  if (!eligible) return;
1551
1579
  const deadline = now() + (retryAfterMs ?? 0);
1552
1580
  setRemaining(retryAfterMs ?? 0);
@@ -1605,7 +1633,7 @@ function AgentPicker({
1605
1633
  }
1606
1634
 
1607
1635
  // src/ops/RunTimeline.tsx
1608
- import * as React13 from "react";
1636
+ import * as React14 from "react";
1609
1637
  import { makeStyles as makeStyles15, tokens as tokens14, Text as Text3 } from "@fluentui/react-components";
1610
1638
  import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
1611
1639
  var useStyles14 = makeStyles15({
@@ -1625,7 +1653,7 @@ var TOOL_STATUS = {
1625
1653
  };
1626
1654
  function RunTimeline({ message, defaultOpen = false }) {
1627
1655
  const styles = useStyles14();
1628
- const id = React13.useId();
1656
+ const id = React14.useId();
1629
1657
  const calls = message.toolCalls ?? [];
1630
1658
  const sources = message.sources ?? [];
1631
1659
  const hasAnything = calls.length > 0 || sources.length > 0 || message.usage || message.failure;
@@ -1733,18 +1761,397 @@ function AgentOpsPanel(props) {
1733
1761
  ] });
1734
1762
  }
1735
1763
 
1764
+ // src/support/AgentLauncher.tsx
1765
+ import { makeStyles as makeStyles18, mergeClasses as mergeClasses7, tokens as tokens17, Badge as Badge3 } from "@fluentui/react-components";
1766
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
1767
+ var useStyles17 = makeStyles18({
1768
+ root: {
1769
+ position: "absolute",
1770
+ top: "30%",
1771
+ display: "flex",
1772
+ flexDirection: "column",
1773
+ zIndex: 100
1774
+ },
1775
+ right: { right: 0, alignItems: "flex-end" },
1776
+ left: { left: 0, alignItems: "flex-start" },
1777
+ hidden: { display: "none" },
1778
+ pill: {
1779
+ display: "flex",
1780
+ alignItems: "center",
1781
+ gap: tokens17.spacingHorizontalS,
1782
+ border: "none",
1783
+ cursor: "pointer",
1784
+ padding: `${tokens17.spacingVerticalM} ${tokens17.spacingHorizontalM}`,
1785
+ color: tokens17.colorNeutralForegroundOnBrand,
1786
+ fontFamily: tokens17.fontFamilyBase,
1787
+ fontSize: tokens17.fontSizeBase300,
1788
+ // ★ Collapsed shows the icon only; the LABEL IS STILL IN THE DOM (see below), so the
1789
+ // expand-on-hover is purely visual and the button is named for AT at every width.
1790
+ maxWidth: "44px",
1791
+ overflow: "hidden",
1792
+ whiteSpace: "nowrap",
1793
+ transitionProperty: "max-width",
1794
+ transitionDuration: tokens17.durationNormal,
1795
+ ":hover": { maxWidth: "260px" },
1796
+ ":hover .fui-launcher-label": { opacity: 1 },
1797
+ ":focus-within .fui-launcher-label": { opacity: 1 },
1798
+ // ★ :focus-within as well as :hover — a keyboard user must get the same reveal, and this is
1799
+ // the affordance the M365 reference only shows on pointer hover.
1800
+ ":focus-within": { maxWidth: "260px" },
1801
+ ":focus-visible": { outline: `2px solid ${tokens17.colorStrokeFocus2}`, outlineOffset: "-2px" }
1802
+ },
1803
+ primary: { backgroundColor: tokens17.colorBrandBackground, ":hover": { backgroundColor: tokens17.colorBrandBackgroundHover, maxWidth: "260px" } },
1804
+ secondary: { backgroundColor: tokens17.colorBrandBackgroundStatic, ":hover": { backgroundColor: tokens17.colorBrandBackgroundStatic, maxWidth: "260px" } },
1805
+ firstRight: { borderTopLeftRadius: tokens17.borderRadiusXLarge },
1806
+ lastRight: { borderBottomLeftRadius: tokens17.borderRadiusXLarge },
1807
+ firstLeft: { borderTopRightRadius: tokens17.borderRadiusXLarge },
1808
+ lastLeft: { borderBottomRightRadius: tokens17.borderRadiusXLarge },
1809
+ // ★★ flexShrink BELONGS ON THE ICON, NOT THE TEXT. With it on the text, a collapsed 44px pill
1810
+ // (20px of content box after padding) gave the unshrinkable label the whole width and squeezed
1811
+ // the icon to ZERO — so the collapsed rail showed two clipped letters instead of a glyph.
1812
+ // MEASURED on Chromatic build 18: svgWidth 0, reported as "the content is off screen".
1813
+ icon: { flexShrink: 0, display: "flex", fontSize: "20px", lineHeight: 1 },
1814
+ // ★ The label FADES rather than relying on the clip. `overflow: hidden` cuts at the PADDING box,
1815
+ // so a 44px pill still showed ~4px of the first letter beside the icon. Opacity keeps the label
1816
+ // in the accessible name (see the class docstring) while hiding it from sight.
1817
+ text: {
1818
+ flexShrink: 1,
1819
+ minWidth: 0,
1820
+ opacity: 0,
1821
+ transitionProperty: "opacity",
1822
+ transitionDuration: tokens17.durationNormal,
1823
+ "@media (prefers-reduced-motion: reduce)": { transitionDuration: "1ms" }
1824
+ }
1825
+ });
1826
+ function AgentLauncher({
1827
+ items,
1828
+ onSelect,
1829
+ side = "right",
1830
+ label = "Assistant",
1831
+ hidden = false
1832
+ }) {
1833
+ const styles = useStyles17();
1834
+ if (items.length === 0) return null;
1835
+ return /* @__PURE__ */ jsx25(
1836
+ "div",
1837
+ {
1838
+ className: mergeClasses7(styles.root, side === "right" ? styles.right : styles.left, hidden && styles.hidden),
1839
+ role: "group",
1840
+ "aria-label": label,
1841
+ children: items.map((item, i) => /* @__PURE__ */ jsxs19(
1842
+ "button",
1843
+ {
1844
+ type: "button",
1845
+ onClick: () => onSelect(item.id),
1846
+ className: mergeClasses7(
1847
+ styles.pill,
1848
+ i === 0 ? styles.primary : styles.secondary,
1849
+ i === 0 && (side === "right" ? styles.firstRight : styles.firstLeft),
1850
+ i === items.length - 1 && (side === "right" ? styles.lastRight : styles.lastLeft)
1851
+ ),
1852
+ children: [
1853
+ /* @__PURE__ */ jsx25("span", { className: styles.icon, "aria-hidden": "true", children: item.icon }),
1854
+ /* @__PURE__ */ jsx25("span", { className: mergeClasses7(styles.text, "fui-launcher-label"), children: item.label }),
1855
+ item.badgeCount ? /* @__PURE__ */ jsx25(Badge3, { appearance: "filled", color: "danger", children: item.badgeCount }) : null
1856
+ ]
1857
+ },
1858
+ item.id
1859
+ ))
1860
+ }
1861
+ );
1862
+ }
1863
+
1864
+ // src/support/AssistantPanel.tsx
1865
+ import * as React15 from "react";
1866
+ import { Button as Button9, Switch, Text as Text6, Tooltip as Tooltip4, makeStyles as makeStyles19, mergeClasses as mergeClasses8, tokens as tokens18 } from "@fluentui/react-components";
1867
+ import { DismissRegular, ArrowDownloadRegular, SpeakerMuteRegular, Speaker2Regular } from "@fluentui/react-icons";
1868
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
1869
+ var useStyles18 = makeStyles19({
1870
+ root: {
1871
+ display: "flex",
1872
+ flexDirection: "column",
1873
+ height: "100%",
1874
+ minWidth: "320px",
1875
+ backgroundColor: tokens18.colorNeutralBackground1,
1876
+ borderLeft: `1px solid ${tokens18.colorNeutralStroke2}`,
1877
+ // ★ transform, not width/left — those two lay out on every frame and a transcript is an
1878
+ // expensive subtree to reflow 60 times a second.
1879
+ transform: "translateX(0)",
1880
+ transitionProperty: "transform",
1881
+ transitionDuration: tokens18.durationGentle,
1882
+ transitionTimingFunction: tokens18.curveDecelerateMid,
1883
+ // ★★ prefers-reduced-motion is honoured, and it is not decoration: a full-height panel
1884
+ // sliding across the viewport is exactly the vestibular trigger the setting exists for.
1885
+ "@media (prefers-reduced-motion: reduce)": { transitionDuration: "1ms" }
1886
+ },
1887
+ closed: {
1888
+ transform: "translateX(100%)",
1889
+ // ★ Hidden from AT as well as sight. A translated-off panel is still in the a11y tree and
1890
+ // still tabbable, so a keyboard user would tab into a drawer they cannot see.
1891
+ visibility: "hidden"
1892
+ },
1893
+ header: { display: "flex", alignItems: "center", gap: tokens18.spacingHorizontalS, padding: tokens18.spacingVerticalS },
1894
+ tabstrip: { display: "flex", gap: tokens18.spacingHorizontalXXS, flexGrow: 1 },
1895
+ tab: {
1896
+ display: "flex",
1897
+ alignItems: "center",
1898
+ gap: tokens18.spacingHorizontalXS,
1899
+ border: "none",
1900
+ background: "none",
1901
+ cursor: "pointer",
1902
+ padding: `${tokens18.spacingVerticalXS} ${tokens18.spacingHorizontalS}`,
1903
+ color: tokens18.colorNeutralForeground2,
1904
+ fontFamily: tokens18.fontFamilyBase,
1905
+ borderBottom: `2px solid transparent`,
1906
+ ":focus-visible": { outline: `2px solid ${tokens18.colorStrokeFocus2}`, outlineOffset: "-2px" }
1907
+ },
1908
+ tabSelected: { color: tokens18.colorNeutralForeground1, borderBottom: `2px solid ${tokens18.colorCompoundBrandStroke}` },
1909
+ title: { padding: `0 ${tokens18.spacingHorizontalM} ${tokens18.spacingVerticalS}` },
1910
+ status: {
1911
+ padding: `${tokens18.spacingVerticalXS} ${tokens18.spacingHorizontalM}`,
1912
+ color: tokens18.colorNeutralForeground3,
1913
+ fontSize: tokens18.fontSizeBase200
1914
+ },
1915
+ body: { flexGrow: 1, minHeight: 0, display: "flex", flexDirection: "column" },
1916
+ footer: {
1917
+ display: "flex",
1918
+ alignItems: "center",
1919
+ justifyContent: "space-between",
1920
+ padding: tokens18.spacingVerticalXS,
1921
+ borderTop: `1px solid ${tokens18.colorNeutralStroke2}`
1922
+ }
1923
+ });
1924
+ function AssistantPanel(props) {
1925
+ const {
1926
+ title,
1927
+ tabs,
1928
+ activeTabId,
1929
+ onTabChange,
1930
+ onClose,
1931
+ enabled,
1932
+ onEnabledChange,
1933
+ status,
1934
+ onDownloadTranscript,
1935
+ muted,
1936
+ onMutedChange,
1937
+ children,
1938
+ open = true,
1939
+ onDismiss
1940
+ } = props;
1941
+ const styles = useStyles18();
1942
+ const baseId = React15.useId();
1943
+ const rootRef = React15.useRef(null);
1944
+ useReturnFocus({ open, containerRef: rootRef });
1945
+ const selectedIndex = Math.max(0, tabs.findIndex((t) => t.id === activeTabId));
1946
+ const roving = useRovingTabindex({
1947
+ itemCount: tabs.length,
1948
+ orientation: "horizontal",
1949
+ // ★ MANUAL ACTIVATION: arrows move focus, Enter/Space selects. That is what the kit's
1950
+ // useRovingTabindex does everywhere, and it is the APG pattern for tabs whose panel is not
1951
+ // free to render. Do not special-case it here; consistency is worth more than the one
1952
+ // keystroke, and a divergent strip is the kind of thing nobody notices until it is shipped.
1953
+ onActivate: (i) => tabs[i] && onTabChange(tabs[i].id)
1954
+ });
1955
+ const { setActiveIndex } = roving;
1956
+ React15.useEffect(() => {
1957
+ setActiveIndex(selectedIndex);
1958
+ }, [selectedIndex, setActiveIndex]);
1959
+ return /* @__PURE__ */ jsxs20(
1960
+ "section",
1961
+ {
1962
+ ref: rootRef,
1963
+ className: mergeClasses8(styles.root, !open && styles.closed),
1964
+ "aria-label": title,
1965
+ "aria-hidden": !open || void 0,
1966
+ tabIndex: -1,
1967
+ onKeyDown: (e) => {
1968
+ if (e.key !== "Escape" || !onDismiss) return;
1969
+ e.stopPropagation();
1970
+ onDismiss();
1971
+ },
1972
+ children: [
1973
+ /* @__PURE__ */ jsxs20("div", { className: styles.header, children: [
1974
+ /* @__PURE__ */ jsx26("div", { className: styles.tabstrip, role: "tablist", "aria-label": `${title} views`, children: tabs.map((tab, i) => {
1975
+ const item = roving.getItemProps(i);
1976
+ const selected = tab.id === activeTabId;
1977
+ return /* @__PURE__ */ jsxs20(
1978
+ "button",
1979
+ {
1980
+ type: "button",
1981
+ role: "tab",
1982
+ id: `${baseId}-tab-${tab.id}`,
1983
+ "aria-selected": selected,
1984
+ "aria-controls": `${baseId}-panel`,
1985
+ className: mergeClasses8(styles.tab, selected && styles.tabSelected),
1986
+ ...item,
1987
+ onClick: () => {
1988
+ roving.setActiveIndex(i);
1989
+ onTabChange(tab.id);
1990
+ },
1991
+ children: [
1992
+ tab.icon,
1993
+ /* @__PURE__ */ jsx26("span", { children: tab.label })
1994
+ ]
1995
+ },
1996
+ tab.id
1997
+ );
1998
+ }) }),
1999
+ onEnabledChange ? /* @__PURE__ */ jsx26(Switch, { checked: enabled ?? true, onChange: (_, d) => onEnabledChange(d.checked), label: enabled ?? true ? "On" : "Off" }) : null,
2000
+ onClose ? /* @__PURE__ */ jsx26(Tooltip4, { content: "Close", relationship: "label", withArrow: true, children: /* @__PURE__ */ jsx26(Button9, { appearance: "subtle", icon: /* @__PURE__ */ jsx26(DismissRegular, {}), onClick: onClose }) }) : null
2001
+ ] }),
2002
+ /* @__PURE__ */ jsx26(Text6, { as: "h2", size: 600, weight: "semibold", className: styles.title, children: title }),
2003
+ /* @__PURE__ */ jsxs20("div", { className: styles.body, id: `${baseId}-panel`, role: "tabpanel", "aria-labelledby": `${baseId}-tab-${activeTabId}`, children: [
2004
+ status ? /* @__PURE__ */ jsx26("div", { className: styles.status, children: status }) : null,
2005
+ children
2006
+ ] }),
2007
+ onDownloadTranscript || onMutedChange ? /* @__PURE__ */ jsxs20("div", { className: styles.footer, children: [
2008
+ onDownloadTranscript ? /* @__PURE__ */ jsx26(Tooltip4, { content: "Download transcript", relationship: "label", withArrow: true, children: /* @__PURE__ */ jsx26(Button9, { appearance: "subtle", icon: /* @__PURE__ */ jsx26(ArrowDownloadRegular, {}), onClick: onDownloadTranscript }) }) : /* @__PURE__ */ jsx26("span", {}),
2009
+ onMutedChange ? /* @__PURE__ */ jsx26(Tooltip4, { content: muted ? "Unmute" : "Mute", relationship: "label", withArrow: true, children: /* @__PURE__ */ jsx26(
2010
+ Button9,
2011
+ {
2012
+ appearance: "subtle",
2013
+ "aria-pressed": !!muted,
2014
+ icon: muted ? /* @__PURE__ */ jsx26(SpeakerMuteRegular, {}) : /* @__PURE__ */ jsx26(Speaker2Regular, {}),
2015
+ onClick: () => onMutedChange(!muted)
2016
+ }
2017
+ ) }) : /* @__PURE__ */ jsx26("span", {})
2018
+ ] }) : null
2019
+ ]
2020
+ }
2021
+ );
2022
+ }
2023
+
2024
+ // src/support/FeedbackPanel.tsx
2025
+ import * as React16 from "react";
2026
+ import {
2027
+ Button as Button10,
2028
+ Radio,
2029
+ RadioGroup,
2030
+ Text as Text7,
2031
+ Textarea as Textarea2,
2032
+ makeStyles as makeStyles20,
2033
+ mergeClasses as mergeClasses9,
2034
+ tokens as tokens19
2035
+ } from "@fluentui/react-components";
2036
+ import { StarRegular, StarFilled } from "@fluentui/react-icons";
2037
+ import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
2038
+ var STARS = [1, 2, 3, 4, 5];
2039
+ var useStyles19 = makeStyles20({
2040
+ root: { display: "flex", flexDirection: "column", gap: tokens19.spacingVerticalM, padding: tokens19.spacingVerticalL, maxWidth: "680px" },
2041
+ field: { display: "flex", flexDirection: "column", gap: tokens19.spacingVerticalXS },
2042
+ stars: { display: "flex", gap: tokens19.spacingHorizontalXS },
2043
+ star: {
2044
+ border: "none",
2045
+ background: "none",
2046
+ cursor: "pointer",
2047
+ padding: tokens19.spacingVerticalXXS,
2048
+ color: tokens19.colorNeutralForeground2,
2049
+ fontSize: "26px",
2050
+ lineHeight: 1,
2051
+ ":focus-visible": { outline: `2px solid ${tokens19.colorStrokeFocus2}`, outlineOffset: "2px" }
2052
+ },
2053
+ starOn: { color: tokens19.colorCompoundBrandForeground1 },
2054
+ footer: { display: "flex", justifyContent: "flex-end", gap: tokens19.spacingHorizontalS },
2055
+ note: { color: tokens19.colorNeutralForeground3, fontSize: tokens19.fontSizeBase200 }
2056
+ });
2057
+ function FeedbackPanel(props) {
2058
+ const {
2059
+ value,
2060
+ onChange,
2061
+ onSubmit,
2062
+ onCancel,
2063
+ heading = "Send feedback",
2064
+ ratingLabel = "Rate your experience",
2065
+ attachments,
2066
+ privacyNote,
2067
+ busy = false
2068
+ } = props;
2069
+ const styles = useStyles19();
2070
+ const baseId = React16.useId();
2071
+ const roving = useRovingTabindex({
2072
+ itemCount: STARS.length,
2073
+ orientation: "horizontal",
2074
+ onActivate: (i) => onChange({ ...value, rating: i + 1 })
2075
+ });
2076
+ const canSubmit = value.rating > 0 && value.mayContact !== void 0 && !busy;
2077
+ return /* @__PURE__ */ jsxs21("div", { className: styles.root, children: [
2078
+ /* @__PURE__ */ jsx27(Text7, { as: "h2", size: 600, weight: "semibold", children: heading }),
2079
+ /* @__PURE__ */ jsxs21("div", { className: styles.field, children: [
2080
+ /* @__PURE__ */ jsx27(Text7, { id: `${baseId}-rating`, children: ratingLabel }),
2081
+ /* @__PURE__ */ jsx27("div", { className: styles.stars, role: "radiogroup", "aria-labelledby": `${baseId}-rating`, children: STARS.map((n, i) => {
2082
+ const item = roving.getItemProps(i);
2083
+ const on = value.rating >= n;
2084
+ return /* @__PURE__ */ jsx27(
2085
+ "button",
2086
+ {
2087
+ type: "button",
2088
+ role: "radio",
2089
+ "aria-checked": value.rating === n,
2090
+ "aria-label": `${n} of 5`,
2091
+ className: mergeClasses9(styles.star, on && styles.starOn),
2092
+ ...item,
2093
+ onClick: () => {
2094
+ roving.setActiveIndex(i);
2095
+ onChange({ ...value, rating: n });
2096
+ },
2097
+ children: on ? /* @__PURE__ */ jsx27(StarFilled, {}) : /* @__PURE__ */ jsx27(StarRegular, {})
2098
+ },
2099
+ n
2100
+ );
2101
+ }) })
2102
+ ] }),
2103
+ /* @__PURE__ */ jsxs21("div", { className: styles.field, children: [
2104
+ /* @__PURE__ */ jsx27(Text7, { id: `${baseId}-detail`, children: "Explain in more detail" }),
2105
+ /* @__PURE__ */ jsx27(
2106
+ Textarea2,
2107
+ {
2108
+ "aria-labelledby": `${baseId}-detail`,
2109
+ placeholder: "Do not include any private or sensitive information.",
2110
+ value: value.comment,
2111
+ onChange: (_, d) => onChange({ ...value, comment: d.value }),
2112
+ resize: "vertical"
2113
+ }
2114
+ )
2115
+ ] }),
2116
+ attachments ? /* @__PURE__ */ jsxs21("div", { className: styles.field, children: [
2117
+ /* @__PURE__ */ jsx27(Text7, { children: "Add more details" }),
2118
+ attachments
2119
+ ] }) : null,
2120
+ /* @__PURE__ */ jsxs21("div", { className: styles.field, children: [
2121
+ /* @__PURE__ */ jsx27(Text7, { id: `${baseId}-consent`, children: "May we contact you about your feedback?" }),
2122
+ /* @__PURE__ */ jsxs21(
2123
+ RadioGroup,
2124
+ {
2125
+ "aria-labelledby": `${baseId}-consent`,
2126
+ value: value.mayContact === void 0 ? "" : value.mayContact ? "yes" : "no",
2127
+ onChange: (_, d) => onChange({ ...value, mayContact: d.value === "yes" }),
2128
+ children: [
2129
+ /* @__PURE__ */ jsx27(Radio, { value: "yes", label: "Yes, you may contact me" }),
2130
+ /* @__PURE__ */ jsx27(Radio, { value: "no", label: "No, don't contact me" })
2131
+ ]
2132
+ }
2133
+ )
2134
+ ] }),
2135
+ privacyNote ? /* @__PURE__ */ jsx27("div", { className: styles.note, children: privacyNote }) : null,
2136
+ /* @__PURE__ */ jsxs21("div", { className: styles.footer, children: [
2137
+ onCancel ? /* @__PURE__ */ jsx27(Button10, { appearance: "secondary", onClick: onCancel, children: "Cancel" }) : null,
2138
+ /* @__PURE__ */ jsx27(Button10, { appearance: "primary", disabled: !canSubmit, onClick: () => onSubmit(value), children: "Submit" })
2139
+ ] })
2140
+ ] });
2141
+ }
2142
+
1736
2143
  // src/shell/AgentAppShell.tsx
1737
- import * as React14 from "react";
1738
- import { makeStyles as makeStyles18, tokens as tokens17, Button as Button9 } from "@fluentui/react-components";
2144
+ import * as React17 from "react";
2145
+ import { makeStyles as makeStyles21, tokens as tokens20, Button as Button11 } from "@fluentui/react-components";
1739
2146
  import { NavigationRegular } from "@fluentui/react-icons";
1740
2147
  import { BREAKPOINTS, resolveBreakpoint, useContainerWidth } from "@dataverse-kit/surface-kit/v9";
1741
- import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
1742
- var useStyles17 = makeStyles18({
2148
+ import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
2149
+ var useStyles20 = makeStyles21({
1743
2150
  root: {
1744
2151
  display: "flex",
1745
2152
  height: "100%",
1746
2153
  minHeight: 0,
1747
- backgroundColor: tokens17.colorNeutralBackground2,
2154
+ backgroundColor: tokens20.colorNeutralBackground2,
1748
2155
  position: "relative",
1749
2156
  overflow: "hidden"
1750
2157
  },
@@ -1752,8 +2159,8 @@ var useStyles17 = makeStyles18({
1752
2159
  display: "flex",
1753
2160
  flexDirection: "column",
1754
2161
  minHeight: 0,
1755
- backgroundColor: tokens17.colorNeutralBackground1,
1756
- borderRight: `1px solid ${tokens17.colorNeutralStroke2}`
2162
+ backgroundColor: tokens20.colorNeutralBackground1,
2163
+ borderRight: `1px solid ${tokens20.colorNeutralStroke2}`
1757
2164
  },
1758
2165
  // Below `md` the list overlays the conversation instead of shrinking it to nothing.
1759
2166
  sidebarOverlay: {
@@ -1762,12 +2169,12 @@ var useStyles17 = makeStyles18({
1762
2169
  bottom: 0,
1763
2170
  left: 0,
1764
2171
  zIndex: 2,
1765
- boxShadow: tokens17.shadow16
2172
+ boxShadow: tokens20.shadow16
1766
2173
  },
1767
- scrim: { position: "absolute", inset: "0", zIndex: 1, backgroundColor: tokens17.colorBackgroundOverlay },
2174
+ scrim: { position: "absolute", inset: "0", zIndex: 1, backgroundColor: tokens20.colorBackgroundOverlay },
1768
2175
  main: { flex: 1, display: "flex", flexDirection: "column", minWidth: 0, minHeight: 0 },
1769
2176
  body: { flex: 1, minHeight: 0, display: "flex", flexDirection: "column" },
1770
- toggle: { position: "absolute", top: tokens17.spacingVerticalS, left: tokens17.spacingHorizontalS, zIndex: 3 }
2177
+ toggle: { position: "absolute", top: tokens20.spacingVerticalS, left: tokens20.spacingHorizontalS, zIndex: 3 }
1771
2178
  });
1772
2179
  function AgentAppShell(props) {
1773
2180
  const {
@@ -1781,7 +2188,7 @@ function AgentAppShell(props) {
1781
2188
  onSidebarOpenChange,
1782
2189
  label = "Agent workspace"
1783
2190
  } = props;
1784
- const styles = useStyles17();
2191
+ const styles = useStyles20();
1785
2192
  const [containerRef, measuredWidth] = useContainerWidth();
1786
2193
  const width = props.containerWidth ?? (measuredWidth > 0 ? measuredWidth : void 0);
1787
2194
  const effective = width ?? BREAKPOINTS.xl;
@@ -1789,17 +2196,17 @@ function AgentAppShell(props) {
1789
2196
  const railVisible = effective >= BREAKPOINTS.sm;
1790
2197
  const sidebarInline = effective >= BREAKPOINTS.md;
1791
2198
  const rightPaneVisible = effective >= BREAKPOINTS.lg;
1792
- const [uncontrolledOpen, setUncontrolledOpen] = React14.useState(false);
2199
+ const [uncontrolledOpen, setUncontrolledOpen] = React17.useState(false);
1793
2200
  const overlayOpen = sidebarOpen ?? uncontrolledOpen;
1794
2201
  const setOverlayOpen = (open) => {
1795
2202
  onSidebarOpenChange?.(open);
1796
2203
  if (sidebarOpen === void 0) setUncontrolledOpen(open);
1797
2204
  };
1798
- return /* @__PURE__ */ jsxs19("div", { ref: containerRef, className: styles.root, "data-breakpoint": breakpoint, "aria-label": label, children: [
2205
+ return /* @__PURE__ */ jsxs22("div", { ref: containerRef, className: styles.root, "data-breakpoint": breakpoint, "aria-label": label, children: [
1799
2206
  rail && railVisible ? rail : null,
1800
- sidebar && sidebarInline ? /* @__PURE__ */ jsx25("div", { className: styles.sidebar, style: { width: sidebarWidth }, children: sidebar }) : null,
1801
- sidebar && !sidebarInline && overlayOpen ? /* @__PURE__ */ jsxs19(Fragment4, { children: [
1802
- /* @__PURE__ */ jsx25(
2207
+ sidebar && sidebarInline ? /* @__PURE__ */ jsx28("div", { className: styles.sidebar, style: { width: sidebarWidth }, children: sidebar }) : null,
2208
+ sidebar && !sidebarInline && overlayOpen ? /* @__PURE__ */ jsxs22(Fragment4, { children: [
2209
+ /* @__PURE__ */ jsx28(
1803
2210
  "div",
1804
2211
  {
1805
2212
  className: styles.scrim,
@@ -1807,23 +2214,23 @@ function AgentAppShell(props) {
1807
2214
  "aria-hidden": "true"
1808
2215
  }
1809
2216
  ),
1810
- /* @__PURE__ */ jsx25("div", { className: `${styles.sidebar} ${styles.sidebarOverlay}`, style: { width: sidebarWidth }, children: sidebar })
2217
+ /* @__PURE__ */ jsx28("div", { className: `${styles.sidebar} ${styles.sidebarOverlay}`, style: { width: sidebarWidth }, children: sidebar })
1811
2218
  ] }) : null,
1812
- /* @__PURE__ */ jsxs19("div", { className: styles.main, children: [
1813
- sidebar && !sidebarInline ? /* @__PURE__ */ jsx25(
1814
- Button9,
2219
+ /* @__PURE__ */ jsxs22("div", { className: styles.main, children: [
2220
+ sidebar && !sidebarInline ? /* @__PURE__ */ jsx28(
2221
+ Button11,
1815
2222
  {
1816
2223
  className: styles.toggle,
1817
2224
  size: "small",
1818
2225
  appearance: "subtle",
1819
- icon: /* @__PURE__ */ jsx25(NavigationRegular, {}),
2226
+ icon: /* @__PURE__ */ jsx28(NavigationRegular, {}),
1820
2227
  "aria-label": overlayOpen ? "Hide conversations" : "Show conversations",
1821
2228
  "aria-expanded": overlayOpen,
1822
2229
  onClick: () => setOverlayOpen(!overlayOpen)
1823
2230
  }
1824
2231
  ) : null,
1825
2232
  header,
1826
- /* @__PURE__ */ jsx25("div", { className: styles.body, children })
2233
+ /* @__PURE__ */ jsx28("div", { className: styles.body, children })
1827
2234
  ] }),
1828
2235
  rightPaneVisible ? rightPane : null
1829
2236
  ] });
@@ -1831,36 +2238,36 @@ function AgentAppShell(props) {
1831
2238
 
1832
2239
  // src/shell/AppRail.tsx
1833
2240
  import {
1834
- Button as Button10,
2241
+ Button as Button12,
1835
2242
  Menu,
1836
2243
  MenuTrigger,
1837
2244
  MenuPopover,
1838
2245
  MenuList,
1839
2246
  MenuItem,
1840
- Tooltip as Tooltip4,
1841
- makeStyles as makeStyles19,
1842
- mergeClasses as mergeClasses7,
1843
- tokens as tokens18
2247
+ Tooltip as Tooltip5,
2248
+ makeStyles as makeStyles22,
2249
+ mergeClasses as mergeClasses10,
2250
+ tokens as tokens21
1844
2251
  } from "@fluentui/react-components";
1845
2252
  import { MoreHorizontalRegular } from "@fluentui/react-icons";
1846
- import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
1847
- var useStyles18 = makeStyles19({
2253
+ import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
2254
+ var useStyles21 = makeStyles22({
1848
2255
  root: {
1849
2256
  display: "flex",
1850
2257
  flexDirection: "column",
1851
2258
  alignItems: "center",
1852
- gap: tokens18.spacingVerticalXS,
1853
- padding: tokens18.spacingVerticalS,
1854
- backgroundColor: tokens18.colorNeutralBackground3,
1855
- borderRight: `1px solid ${tokens18.colorNeutralStroke2}`,
2259
+ gap: tokens21.spacingVerticalXS,
2260
+ padding: tokens21.spacingVerticalS,
2261
+ backgroundColor: tokens21.colorNeutralBackground3,
2262
+ borderRight: `1px solid ${tokens21.colorNeutralStroke2}`,
1856
2263
  minHeight: 0
1857
2264
  },
1858
2265
  spacer: { flex: 1 },
1859
2266
  button: {
1860
2267
  position: "relative",
1861
- ":focus-visible": { outline: `2px solid ${tokens18.colorStrokeFocus2}`, outlineOffset: "1px" }
2268
+ ":focus-visible": { outline: `2px solid ${tokens21.colorStrokeFocus2}`, outlineOffset: "1px" }
1862
2269
  },
1863
- selected: { backgroundColor: tokens18.colorNeutralBackground1Selected },
2270
+ selected: { backgroundColor: tokens21.colorNeutralBackground1Selected },
1864
2271
  badge: {
1865
2272
  position: "absolute",
1866
2273
  top: "2px",
@@ -1868,58 +2275,58 @@ var useStyles18 = makeStyles19({
1868
2275
  minWidth: "16px",
1869
2276
  height: "16px",
1870
2277
  padding: "0 3px",
1871
- borderRadius: tokens18.borderRadiusCircular,
1872
- backgroundColor: tokens18.colorPaletteRedBackground3,
1873
- color: tokens18.colorNeutralForegroundOnBrand,
2278
+ borderRadius: tokens21.borderRadiusCircular,
2279
+ backgroundColor: tokens21.colorPaletteRedBackground3,
2280
+ color: tokens21.colorNeutralForegroundOnBrand,
1874
2281
  fontSize: "10px",
1875
2282
  lineHeight: "16px"
1876
2283
  }
1877
2284
  });
1878
2285
  function AppRail(props) {
1879
2286
  const { items, selectedId, onSelect, maxVisible = 6, label = "Apps", footer } = props;
1880
- const styles = useStyles18();
2287
+ const styles = useStyles21();
1881
2288
  const visible = items.slice(0, maxVisible);
1882
2289
  const overflow = items.slice(maxVisible);
1883
- return /* @__PURE__ */ jsxs20("nav", { className: styles.root, "aria-label": label, children: [
1884
- visible.map((item) => /* @__PURE__ */ jsx26(Tooltip4, { content: item.label, relationship: "label", positioning: "after", withArrow: true, children: /* @__PURE__ */ jsx26(
1885
- Button10,
2290
+ return /* @__PURE__ */ jsxs23("nav", { className: styles.root, "aria-label": label, children: [
2291
+ visible.map((item) => /* @__PURE__ */ jsx29(Tooltip5, { content: item.label, relationship: "label", positioning: "after", withArrow: true, children: /* @__PURE__ */ jsx29(
2292
+ Button12,
1886
2293
  {
1887
2294
  appearance: "subtle",
1888
2295
  icon: item.icon,
1889
- className: mergeClasses7(styles.button, item.id === selectedId && styles.selected),
2296
+ className: mergeClasses10(styles.button, item.id === selectedId && styles.selected),
1890
2297
  "aria-pressed": item.id === selectedId,
1891
2298
  "aria-label": item.badgeCount ? `${item.label}, ${item.badgeCount} unread` : item.label,
1892
2299
  onClick: () => onSelect(item.id),
1893
- children: item.badgeCount ? /* @__PURE__ */ jsx26("span", { className: styles.badge, "aria-hidden": "true", children: item.badgeCount }) : null
2300
+ children: item.badgeCount ? /* @__PURE__ */ jsx29("span", { className: styles.badge, "aria-hidden": "true", children: item.badgeCount }) : null
1894
2301
  }
1895
2302
  ) }, item.id)),
1896
- overflow.length > 0 ? /* @__PURE__ */ jsxs20(Menu, { children: [
1897
- /* @__PURE__ */ jsx26(MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx26(
1898
- Button10,
2303
+ overflow.length > 0 ? /* @__PURE__ */ jsxs23(Menu, { children: [
2304
+ /* @__PURE__ */ jsx29(MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx29(
2305
+ Button12,
1899
2306
  {
1900
2307
  appearance: "subtle",
1901
- icon: /* @__PURE__ */ jsx26(MoreHorizontalRegular, {}),
2308
+ icon: /* @__PURE__ */ jsx29(MoreHorizontalRegular, {}),
1902
2309
  className: styles.button,
1903
2310
  "aria-label": `More apps, ${overflow.length} hidden`
1904
2311
  }
1905
2312
  ) }),
1906
- /* @__PURE__ */ jsx26(MenuPopover, { children: /* @__PURE__ */ jsx26(MenuList, { children: overflow.map((item) => /* @__PURE__ */ jsx26(MenuItem, { icon: item.icon, onClick: () => onSelect(item.id), children: item.label }, item.id)) }) })
2313
+ /* @__PURE__ */ jsx29(MenuPopover, { children: /* @__PURE__ */ jsx29(MenuList, { children: overflow.map((item) => /* @__PURE__ */ jsx29(MenuItem, { icon: item.icon, onClick: () => onSelect(item.id), children: item.label }, item.id)) }) })
1907
2314
  ] }) : null,
1908
- /* @__PURE__ */ jsx26("div", { className: styles.spacer }),
2315
+ /* @__PURE__ */ jsx29("div", { className: styles.spacer }),
1909
2316
  footer
1910
2317
  ] });
1911
2318
  }
1912
2319
 
1913
2320
  // src/shell/ConversationList.tsx
1914
- import * as React15 from "react";
1915
- import { makeStyles as makeStyles21, tokens as tokens20, Text as Text6 } from "@fluentui/react-components";
2321
+ import * as React18 from "react";
2322
+ import { makeStyles as makeStyles24, tokens as tokens23, Text as Text8 } from "@fluentui/react-components";
1916
2323
 
1917
2324
  // src/shell/ConversationListItem.tsx
1918
- import { makeStyles as makeStyles20, mergeClasses as mergeClasses8, tokens as tokens19 } from "@fluentui/react-components";
2325
+ import { makeStyles as makeStyles23, mergeClasses as mergeClasses11, tokens as tokens22 } from "@fluentui/react-components";
1919
2326
 
1920
2327
  // src/shell/AgentAvatar.tsx
1921
2328
  import { Avatar as Avatar2 } from "@fluentui/react-components";
1922
- import { jsx as jsx27 } from "react/jsx-runtime";
2329
+ import { jsx as jsx30 } from "react/jsx-runtime";
1923
2330
  var STATUS = {
1924
2331
  available: "available",
1925
2332
  busy: "busy",
@@ -1930,7 +2337,7 @@ var STATUS = {
1930
2337
  };
1931
2338
  function AgentAvatar({ participant, presence, size = 32, name }) {
1932
2339
  const displayName = name ?? participant?.displayName ?? "Unknown";
1933
- return /* @__PURE__ */ jsx27(
2340
+ return /* @__PURE__ */ jsx30(
1934
2341
  Avatar2,
1935
2342
  {
1936
2343
  name: displayName,
@@ -1944,49 +2351,49 @@ function AgentAvatar({ participant, presence, size = 32, name }) {
1944
2351
  }
1945
2352
 
1946
2353
  // src/shell/ConversationListItem.tsx
1947
- import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1948
- var useStyles19 = makeStyles20({
2354
+ import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
2355
+ var useStyles22 = makeStyles23({
1949
2356
  row: {
1950
2357
  display: "flex",
1951
- gap: tokens19.spacingHorizontalS,
2358
+ gap: tokens22.spacingHorizontalS,
1952
2359
  alignItems: "center",
1953
- padding: `${tokens19.spacingVerticalS} ${tokens19.spacingHorizontalS}`,
1954
- borderRadius: tokens19.borderRadiusMedium,
2360
+ padding: `${tokens22.spacingVerticalS} ${tokens22.spacingHorizontalS}`,
2361
+ borderRadius: tokens22.borderRadiusMedium,
1955
2362
  cursor: "pointer",
1956
- ":hover": { backgroundColor: tokens19.colorNeutralBackground1Hover }
2363
+ ":hover": { backgroundColor: tokens22.colorNeutralBackground1Hover }
1957
2364
  },
1958
2365
  // ★ The ACTIVE row (aria-activedescendant target) gets a visible focus indicator, because
1959
2366
  // real DOM focus stays on the listbox — without this the keyboard user sees nothing move.
1960
- active: { outline: `2px solid ${tokens19.colorStrokeFocus2}`, outlineOffset: "-2px" },
1961
- selected: { backgroundColor: tokens19.colorNeutralBackground1Selected },
2367
+ active: { outline: `2px solid ${tokens22.colorStrokeFocus2}`, outlineOffset: "-2px" },
2368
+ selected: { backgroundColor: tokens22.colorNeutralBackground1Selected },
1962
2369
  body: { flex: 1, minWidth: 0 },
1963
2370
  title: {
1964
2371
  display: "block",
1965
- fontSize: tokens19.fontSizeBase300,
1966
- fontWeight: tokens19.fontWeightSemibold,
2372
+ fontSize: tokens22.fontSizeBase300,
2373
+ fontWeight: tokens22.fontWeightSemibold,
1967
2374
  overflow: "hidden",
1968
2375
  textOverflow: "ellipsis",
1969
2376
  whiteSpace: "nowrap"
1970
2377
  },
1971
- muted: { fontWeight: tokens19.fontWeightRegular, color: tokens19.colorNeutralForeground3 },
2378
+ muted: { fontWeight: tokens22.fontWeightRegular, color: tokens22.colorNeutralForeground3 },
1972
2379
  preview: {
1973
2380
  display: "block",
1974
- fontSize: tokens19.fontSizeBase200,
1975
- color: tokens19.colorNeutralForeground3,
2381
+ fontSize: tokens22.fontSizeBase200,
2382
+ color: tokens22.colorNeutralForeground3,
1976
2383
  overflow: "hidden",
1977
2384
  textOverflow: "ellipsis",
1978
2385
  whiteSpace: "nowrap"
1979
2386
  },
1980
2387
  meta: { display: "flex", flexDirection: "column", alignItems: "flex-end", gap: "2px" },
1981
- time: { fontSize: tokens19.fontSizeBase100, color: tokens19.colorNeutralForeground3 },
2388
+ time: { fontSize: tokens22.fontSizeBase100, color: tokens22.colorNeutralForeground3 },
1982
2389
  unread: {
1983
2390
  minWidth: "18px",
1984
2391
  height: "18px",
1985
- padding: `0 ${tokens19.spacingHorizontalXXS}`,
1986
- borderRadius: tokens19.borderRadiusCircular,
1987
- backgroundColor: tokens19.colorBrandBackground,
1988
- color: tokens19.colorNeutralForegroundOnBrand,
1989
- fontSize: tokens19.fontSizeBase100,
2392
+ padding: `0 ${tokens22.spacingHorizontalXXS}`,
2393
+ borderRadius: tokens22.borderRadiusCircular,
2394
+ backgroundColor: tokens22.colorBrandBackground,
2395
+ color: tokens22.colorNeutralForegroundOnBrand,
2396
+ fontSize: tokens22.fontSizeBase100,
1990
2397
  lineHeight: "18px",
1991
2398
  textAlign: "center"
1992
2399
  }
@@ -2005,27 +2412,27 @@ function conversationAccessibleName(summary, locale) {
2005
2412
  }
2006
2413
  function ConversationListItem(props) {
2007
2414
  const { summary, selected, active, id, locale, onSelect } = props;
2008
- const styles = useStyles19();
2415
+ const styles = useStyles22();
2009
2416
  const time = summary.timestamp ? new Intl.DateTimeFormat(locale, { timeStyle: "short" }).format(new Date(summary.timestamp)) : void 0;
2010
- return /* @__PURE__ */ jsxs21(
2417
+ return /* @__PURE__ */ jsxs24(
2011
2418
  "div",
2012
2419
  {
2013
2420
  id,
2014
2421
  role: "option",
2015
2422
  "aria-selected": selected,
2016
2423
  "aria-label": conversationAccessibleName(summary, locale),
2017
- className: mergeClasses8(styles.row, selected && styles.selected, active && styles.active),
2424
+ className: mergeClasses11(styles.row, selected && styles.selected, active && styles.active),
2018
2425
  onClick: () => onSelect(summary.id),
2019
2426
  "data-conversation-option": true,
2020
2427
  children: [
2021
- /* @__PURE__ */ jsx28(AgentAvatar, { participant: summary.participant, presence: summary.presence, size: 32 }),
2022
- /* @__PURE__ */ jsxs21("div", { className: styles.body, "aria-hidden": "true", children: [
2023
- /* @__PURE__ */ jsx28("span", { className: mergeClasses8(styles.title, summary.muted && styles.muted), children: summary.title }),
2024
- summary.preview ? /* @__PURE__ */ jsx28("span", { className: styles.preview, children: summary.preview }) : null
2428
+ /* @__PURE__ */ jsx31(AgentAvatar, { participant: summary.participant, presence: summary.presence, size: 32 }),
2429
+ /* @__PURE__ */ jsxs24("div", { className: styles.body, "aria-hidden": "true", children: [
2430
+ /* @__PURE__ */ jsx31("span", { className: mergeClasses11(styles.title, summary.muted && styles.muted), children: summary.title }),
2431
+ summary.preview ? /* @__PURE__ */ jsx31("span", { className: styles.preview, children: summary.preview }) : null
2025
2432
  ] }),
2026
- /* @__PURE__ */ jsxs21("div", { className: styles.meta, "aria-hidden": "true", children: [
2027
- time ? /* @__PURE__ */ jsx28("span", { className: styles.time, children: time }) : null,
2028
- !summary.muted && summary.unreadCount ? /* @__PURE__ */ jsx28("span", { className: styles.unread, children: summary.unreadCount }) : null
2433
+ /* @__PURE__ */ jsxs24("div", { className: styles.meta, "aria-hidden": "true", children: [
2434
+ time ? /* @__PURE__ */ jsx31("span", { className: styles.time, children: time }) : null,
2435
+ !summary.muted && summary.unreadCount ? /* @__PURE__ */ jsx31("span", { className: styles.unread, children: summary.unreadCount }) : null
2029
2436
  ] })
2030
2437
  ]
2031
2438
  }
@@ -2033,27 +2440,27 @@ function ConversationListItem(props) {
2033
2440
  }
2034
2441
 
2035
2442
  // src/shell/ConversationList.tsx
2036
- import { jsx as jsx29 } from "react/jsx-runtime";
2037
- var useStyles20 = makeStyles21({
2443
+ import { jsx as jsx32 } from "react/jsx-runtime";
2444
+ var useStyles23 = makeStyles24({
2038
2445
  root: {
2039
2446
  display: "flex",
2040
2447
  flexDirection: "column",
2041
2448
  gap: "2px",
2042
- padding: tokens20.spacingHorizontalXS,
2449
+ padding: tokens23.spacingHorizontalXS,
2043
2450
  overflowY: "auto",
2044
2451
  minHeight: 0,
2045
- ":focus-visible": { outline: `2px solid ${tokens20.colorStrokeFocus2}`, outlineOffset: "-2px" }
2452
+ ":focus-visible": { outline: `2px solid ${tokens23.colorStrokeFocus2}`, outlineOffset: "-2px" }
2046
2453
  },
2047
- empty: { padding: tokens20.spacingVerticalM, color: tokens20.colorNeutralForeground3 }
2454
+ empty: { padding: tokens23.spacingVerticalM, color: tokens23.colorNeutralForeground3 }
2048
2455
  });
2049
2456
  function ConversationList(props) {
2050
2457
  const { items, selectedId, onSelect, label = "Conversations", locale, empty } = props;
2051
- const styles = useStyles20();
2052
- const listRef = React15.useRef(null);
2053
- const idBase = React15.useId();
2458
+ const styles = useStyles23();
2459
+ const listRef = React18.useRef(null);
2460
+ const idBase = React18.useId();
2054
2461
  const selectedIndex = Math.max(0, items.findIndex((i) => i.id === selectedId));
2055
- const [active, setActive] = React15.useState(selectedIndex);
2056
- React15.useEffect(() => {
2462
+ const [active, setActive] = React18.useState(selectedIndex);
2463
+ React18.useEffect(() => {
2057
2464
  setActive((current) => {
2058
2465
  if (items.length === 0) return 0;
2059
2466
  if (selectedIndex >= 0 && items[selectedIndex]) return selectedIndex;
@@ -2061,7 +2468,7 @@ function ConversationList(props) {
2061
2468
  });
2062
2469
  }, [selectedIndex, items]);
2063
2470
  const optionId = (index) => `${idBase}-opt-${index}`;
2064
- React15.useEffect(() => {
2471
+ React18.useEffect(() => {
2065
2472
  const el = listRef.current?.ownerDocument.getElementById(optionId(active));
2066
2473
  el?.scrollIntoView?.({ block: "nearest" });
2067
2474
  }, [active, idBase]);
@@ -2084,9 +2491,9 @@ function ConversationList(props) {
2084
2491
  setActive(next);
2085
2492
  };
2086
2493
  if (items.length === 0) {
2087
- return /* @__PURE__ */ jsx29("div", { className: styles.root, children: empty ?? /* @__PURE__ */ jsx29(Text6, { className: styles.empty, size: 200, children: "No conversations yet." }) });
2494
+ return /* @__PURE__ */ jsx32("div", { className: styles.root, children: empty ?? /* @__PURE__ */ jsx32(Text8, { className: styles.empty, size: 200, children: "No conversations yet." }) });
2088
2495
  }
2089
- return /* @__PURE__ */ jsx29(
2496
+ return /* @__PURE__ */ jsx32(
2090
2497
  "div",
2091
2498
  {
2092
2499
  ref: listRef,
@@ -2096,7 +2503,7 @@ function ConversationList(props) {
2096
2503
  tabIndex: 0,
2097
2504
  "aria-activedescendant": optionId(active),
2098
2505
  onKeyDown,
2099
- children: items.map((summary, index) => /* @__PURE__ */ jsx29(
2506
+ children: items.map((summary, index) => /* @__PURE__ */ jsx32(
2100
2507
  ConversationListItem,
2101
2508
  {
2102
2509
  id: optionId(index),
@@ -2114,7 +2521,7 @@ function ConversationList(props) {
2114
2521
 
2115
2522
  // src/shell/ConversationHeader.tsx
2116
2523
  import {
2117
- Button as Button11,
2524
+ Button as Button13,
2118
2525
  Menu as Menu2,
2119
2526
  MenuTrigger as MenuTrigger2,
2120
2527
  MenuPopover as MenuPopover2,
@@ -2122,27 +2529,27 @@ import {
2122
2529
  MenuItem as MenuItem2,
2123
2530
  Tab,
2124
2531
  TabList,
2125
- Text as Text7,
2126
- makeStyles as makeStyles22,
2127
- tokens as tokens21
2532
+ Text as Text9,
2533
+ makeStyles as makeStyles25,
2534
+ tokens as tokens24
2128
2535
  } from "@fluentui/react-components";
2129
2536
  import { MoreHorizontalRegular as MoreHorizontalRegular2 } from "@fluentui/react-icons";
2130
- import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
2131
- var useStyles21 = makeStyles22({
2537
+ import { jsx as jsx33, jsxs as jsxs25 } from "react/jsx-runtime";
2538
+ var useStyles24 = makeStyles25({
2132
2539
  root: {
2133
2540
  display: "flex",
2134
2541
  flexDirection: "column",
2135
- gap: tokens21.spacingVerticalXS,
2136
- padding: `${tokens21.spacingVerticalS} ${tokens21.spacingHorizontalM} 0`,
2137
- borderBottom: `1px solid ${tokens21.colorNeutralStroke2}`,
2138
- backgroundColor: tokens21.colorNeutralBackground1
2542
+ gap: tokens24.spacingVerticalXS,
2543
+ padding: `${tokens24.spacingVerticalS} ${tokens24.spacingHorizontalM} 0`,
2544
+ borderBottom: `1px solid ${tokens24.colorNeutralStroke2}`,
2545
+ backgroundColor: tokens24.colorNeutralBackground1
2139
2546
  },
2140
- top: { display: "flex", alignItems: "center", gap: tokens21.spacingHorizontalS },
2141
- identity: { display: "flex", alignItems: "center", gap: tokens21.spacingHorizontalS, minWidth: 0 },
2547
+ top: { display: "flex", alignItems: "center", gap: tokens24.spacingHorizontalS },
2548
+ identity: { display: "flex", alignItems: "center", gap: tokens24.spacingHorizontalS, minWidth: 0 },
2142
2549
  titles: { display: "flex", flexDirection: "column", minWidth: 0 },
2143
- subtitle: { color: tokens21.colorNeutralForeground3, fontSize: tokens21.fontSizeBase200 },
2550
+ subtitle: { color: tokens24.colorNeutralForeground3, fontSize: tokens24.fontSizeBase200 },
2144
2551
  spacer: { flex: 1 },
2145
- tabRow: { display: "flex", alignItems: "flex-end", gap: tokens21.spacingHorizontalS }
2552
+ tabRow: { display: "flex", alignItems: "flex-end", gap: tokens24.spacingHorizontalS }
2146
2553
  });
2147
2554
  function ConversationHeader(props) {
2148
2555
  const {
@@ -2156,22 +2563,22 @@ function ConversationHeader(props) {
2156
2563
  actions,
2157
2564
  trailing
2158
2565
  } = props;
2159
- const styles = useStyles21();
2566
+ const styles = useStyles24();
2160
2567
  const inline = (actions ?? []).slice(0, 2);
2161
2568
  const overflow = (actions ?? []).slice(2);
2162
- return /* @__PURE__ */ jsxs22("header", { className: styles.root, children: [
2163
- /* @__PURE__ */ jsxs22("div", { className: styles.top, children: [
2164
- /* @__PURE__ */ jsxs22("div", { className: styles.identity, children: [
2165
- /* @__PURE__ */ jsx30(AgentAvatar, { participant, presence, size: 32, name: title }),
2166
- /* @__PURE__ */ jsxs22("div", { className: styles.titles, children: [
2167
- /* @__PURE__ */ jsx30(Text7, { weight: "semibold", truncate: true, wrap: false, children: title }),
2168
- subtitle ? /* @__PURE__ */ jsx30("span", { className: styles.subtitle, children: subtitle }) : null
2569
+ return /* @__PURE__ */ jsxs25("header", { className: styles.root, children: [
2570
+ /* @__PURE__ */ jsxs25("div", { className: styles.top, children: [
2571
+ /* @__PURE__ */ jsxs25("div", { className: styles.identity, children: [
2572
+ /* @__PURE__ */ jsx33(AgentAvatar, { participant, presence, size: 32, name: title }),
2573
+ /* @__PURE__ */ jsxs25("div", { className: styles.titles, children: [
2574
+ /* @__PURE__ */ jsx33(Text9, { weight: "semibold", truncate: true, wrap: false, children: title }),
2575
+ subtitle ? /* @__PURE__ */ jsx33("span", { className: styles.subtitle, children: subtitle }) : null
2169
2576
  ] })
2170
2577
  ] }),
2171
- /* @__PURE__ */ jsx30("div", { className: styles.spacer }),
2578
+ /* @__PURE__ */ jsx33("div", { className: styles.spacer }),
2172
2579
  trailing,
2173
- inline.map((action) => /* @__PURE__ */ jsx30(
2174
- Button11,
2580
+ inline.map((action) => /* @__PURE__ */ jsx33(
2581
+ Button13,
2175
2582
  {
2176
2583
  appearance: "subtle",
2177
2584
  size: "small",
@@ -2181,80 +2588,80 @@ function ConversationHeader(props) {
2181
2588
  },
2182
2589
  action.key
2183
2590
  )),
2184
- overflow.length > 0 ? /* @__PURE__ */ jsxs22(Menu2, { children: [
2185
- /* @__PURE__ */ jsx30(MenuTrigger2, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx30(
2186
- Button11,
2591
+ overflow.length > 0 ? /* @__PURE__ */ jsxs25(Menu2, { children: [
2592
+ /* @__PURE__ */ jsx33(MenuTrigger2, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx33(
2593
+ Button13,
2187
2594
  {
2188
2595
  appearance: "subtle",
2189
2596
  size: "small",
2190
- icon: /* @__PURE__ */ jsx30(MoreHorizontalRegular2, {}),
2597
+ icon: /* @__PURE__ */ jsx33(MoreHorizontalRegular2, {}),
2191
2598
  "aria-label": `More actions, ${overflow.length} available`
2192
2599
  }
2193
2600
  ) }),
2194
- /* @__PURE__ */ jsx30(MenuPopover2, { children: /* @__PURE__ */ jsx30(MenuList2, { children: overflow.map((action) => /* @__PURE__ */ jsx30(MenuItem2, { icon: action.icon, onClick: action.onClick, children: action.label }, action.key)) }) })
2601
+ /* @__PURE__ */ jsx33(MenuPopover2, { children: /* @__PURE__ */ jsx33(MenuList2, { children: overflow.map((action) => /* @__PURE__ */ jsx33(MenuItem2, { icon: action.icon, onClick: action.onClick, children: action.label }, action.key)) }) })
2195
2602
  ] }) : null
2196
2603
  ] }),
2197
- tabs && tabs.length > 0 ? /* @__PURE__ */ jsx30("div", { className: styles.tabRow, children: /* @__PURE__ */ jsx30(
2604
+ tabs && tabs.length > 0 ? /* @__PURE__ */ jsx33("div", { className: styles.tabRow, children: /* @__PURE__ */ jsx33(
2198
2605
  TabList,
2199
2606
  {
2200
2607
  selectedValue: selectedTabId,
2201
2608
  onTabSelect: (_, data) => onTabSelect?.(data.value),
2202
2609
  size: "small",
2203
- children: tabs.map((tab) => /* @__PURE__ */ jsx30(Tab, { value: tab.id, children: tab.label }, tab.id))
2610
+ children: tabs.map((tab) => /* @__PURE__ */ jsx33(Tab, { value: tab.id, children: tab.label }, tab.id))
2204
2611
  }
2205
2612
  ) }) : null
2206
2613
  ] });
2207
2614
  }
2208
2615
 
2209
2616
  // src/shell/RightPane.tsx
2210
- import * as React16 from "react";
2211
- import { Button as Button12, makeStyles as makeStyles23, tokens as tokens22, Text as Text8 } from "@fluentui/react-components";
2212
- import { DismissRegular } from "@fluentui/react-icons";
2213
- import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
2214
- var useStyles22 = makeStyles23({
2617
+ import * as React19 from "react";
2618
+ import { Button as Button14, makeStyles as makeStyles26, tokens as tokens25, Text as Text10 } from "@fluentui/react-components";
2619
+ import { DismissRegular as DismissRegular2 } from "@fluentui/react-icons";
2620
+ import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
2621
+ var useStyles25 = makeStyles26({
2215
2622
  root: {
2216
2623
  display: "flex",
2217
2624
  flexDirection: "column",
2218
- borderLeft: `1px solid ${tokens22.colorNeutralStroke2}`,
2219
- backgroundColor: tokens22.colorNeutralBackground1,
2625
+ borderLeft: `1px solid ${tokens25.colorNeutralStroke2}`,
2626
+ backgroundColor: tokens25.colorNeutralBackground1,
2220
2627
  minHeight: 0
2221
2628
  },
2222
2629
  head: {
2223
2630
  display: "flex",
2224
2631
  alignItems: "center",
2225
2632
  justifyContent: "space-between",
2226
- gap: tokens22.spacingHorizontalS,
2227
- padding: tokens22.spacingVerticalS,
2228
- borderBottom: `1px solid ${tokens22.colorNeutralStroke2}`
2633
+ gap: tokens25.spacingHorizontalS,
2634
+ padding: tokens25.spacingVerticalS,
2635
+ borderBottom: `1px solid ${tokens25.colorNeutralStroke2}`
2229
2636
  },
2230
- body: { flex: 1, overflowY: "auto", padding: tokens22.spacingVerticalM }
2637
+ body: { flex: 1, overflowY: "auto", padding: tokens25.spacingVerticalM }
2231
2638
  });
2232
2639
  function RightPane({ open, title, onClose, children, width = 320 }) {
2233
- const styles = useStyles22();
2234
- const labelId = React16.useId();
2640
+ const styles = useStyles25();
2641
+ const labelId = React19.useId();
2235
2642
  if (!open) return null;
2236
- return /* @__PURE__ */ jsxs23("aside", { className: styles.root, style: { width }, "aria-labelledby": labelId, children: [
2237
- /* @__PURE__ */ jsxs23("div", { className: styles.head, children: [
2238
- /* @__PURE__ */ jsx31(Text8, { id: labelId, weight: "semibold", children: title }),
2239
- /* @__PURE__ */ jsx31(
2240
- Button12,
2643
+ return /* @__PURE__ */ jsxs26("aside", { className: styles.root, style: { width }, "aria-labelledby": labelId, children: [
2644
+ /* @__PURE__ */ jsxs26("div", { className: styles.head, children: [
2645
+ /* @__PURE__ */ jsx34(Text10, { id: labelId, weight: "semibold", children: title }),
2646
+ /* @__PURE__ */ jsx34(
2647
+ Button14,
2241
2648
  {
2242
2649
  appearance: "subtle",
2243
2650
  size: "small",
2244
- icon: /* @__PURE__ */ jsx31(DismissRegular, {}),
2651
+ icon: /* @__PURE__ */ jsx34(DismissRegular2, {}),
2245
2652
  onClick: onClose,
2246
2653
  "aria-label": `Close ${title}`
2247
2654
  }
2248
2655
  )
2249
2656
  ] }),
2250
- /* @__PURE__ */ jsx31("div", { className: styles.body, children })
2657
+ /* @__PURE__ */ jsx34("div", { className: styles.body, children })
2251
2658
  ] });
2252
2659
  }
2253
2660
 
2254
2661
  // src/shell/GlobalSearchBar.tsx
2255
- import { SearchBox, makeStyles as makeStyles24 } from "@fluentui/react-components";
2256
- import { jsx as jsx32 } from "react/jsx-runtime";
2257
- var useStyles23 = makeStyles24({
2662
+ import { SearchBox, makeStyles as makeStyles27 } from "@fluentui/react-components";
2663
+ import { jsx as jsx35 } from "react/jsx-runtime";
2664
+ var useStyles26 = makeStyles27({
2258
2665
  root: { width: "100%", maxWidth: "640px" }
2259
2666
  });
2260
2667
  function GlobalSearchBar({
@@ -2263,8 +2670,8 @@ function GlobalSearchBar({
2263
2670
  onSubmit,
2264
2671
  placeholder = "Search conversations"
2265
2672
  }) {
2266
- const styles = useStyles23();
2267
- return /* @__PURE__ */ jsx32(
2673
+ const styles = useStyles26();
2674
+ return /* @__PURE__ */ jsx35(
2268
2675
  SearchBox,
2269
2676
  {
2270
2677
  className: styles.root,
@@ -2280,45 +2687,45 @@ function GlobalSearchBar({
2280
2687
  }
2281
2688
 
2282
2689
  // src/grounding/CitationChip.tsx
2283
- import { Tooltip as Tooltip5, makeStyles as makeStyles25, tokens as tokens23 } from "@fluentui/react-components";
2284
- import { jsx as jsx33 } from "react/jsx-runtime";
2285
- var useStyles24 = makeStyles25({
2690
+ import { Tooltip as Tooltip6, makeStyles as makeStyles28, tokens as tokens26 } from "@fluentui/react-components";
2691
+ import { jsx as jsx36 } from "react/jsx-runtime";
2692
+ var useStyles27 = makeStyles28({
2286
2693
  chip: {
2287
2694
  display: "inline-flex",
2288
2695
  alignItems: "center",
2289
2696
  justifyContent: "center",
2290
2697
  minWidth: "18px",
2291
2698
  height: "18px",
2292
- padding: `0 ${tokens23.spacingHorizontalXXS}`,
2699
+ padding: `0 ${tokens26.spacingHorizontalXXS}`,
2293
2700
  marginLeft: "2px",
2294
2701
  verticalAlign: "super",
2295
- fontSize: tokens23.fontSizeBase100,
2702
+ fontSize: tokens26.fontSizeBase100,
2296
2703
  lineHeight: "18px",
2297
- borderRadius: tokens23.borderRadiusSmall,
2298
- border: `1px solid ${tokens23.colorNeutralStroke2}`,
2299
- backgroundColor: tokens23.colorNeutralBackground3,
2300
- color: tokens23.colorNeutralForeground2,
2704
+ borderRadius: tokens26.borderRadiusSmall,
2705
+ border: `1px solid ${tokens26.colorNeutralStroke2}`,
2706
+ backgroundColor: tokens26.colorNeutralBackground3,
2707
+ color: tokens26.colorNeutralForeground2,
2301
2708
  cursor: "pointer",
2302
- ":hover": { backgroundColor: tokens23.colorNeutralBackground3Hover },
2303
- ":focus-visible": { outline: `2px solid ${tokens23.colorStrokeFocus2}`, outlineOffset: "1px" }
2709
+ ":hover": { backgroundColor: tokens26.colorNeutralBackground3Hover },
2710
+ ":focus-visible": { outline: `2px solid ${tokens26.colorStrokeFocus2}`, outlineOffset: "1px" }
2304
2711
  },
2305
2712
  inert: { cursor: "default" }
2306
2713
  });
2307
2714
  function CitationChip({ marker, source, onOpen }) {
2308
- const styles = useStyles24();
2715
+ const styles = useStyles27();
2309
2716
  const label = source ? `Source ${marker}: ${source.title}` : `Source ${marker}`;
2310
2717
  if (!source || !onOpen) {
2311
- return /* @__PURE__ */ jsx33("span", { className: `${styles.chip} ${styles.inert}`, "aria-label": label, children: marker });
2718
+ return /* @__PURE__ */ jsx36("span", { className: `${styles.chip} ${styles.inert}`, "aria-label": label, children: marker });
2312
2719
  }
2313
- return /* @__PURE__ */ jsx33(Tooltip5, { content: source.title, relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx33("button", { type: "button", className: styles.chip, "aria-label": label, onClick: () => onOpen(source), children: marker }) });
2720
+ return /* @__PURE__ */ jsx36(Tooltip6, { content: source.title, relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx36("button", { type: "button", className: styles.chip, "aria-label": label, onClick: () => onOpen(source), children: marker }) });
2314
2721
  }
2315
2722
 
2316
2723
  // src/grounding/CitationList.tsx
2317
- import * as React17 from "react";
2318
- import { makeStyles as makeStyles27, tokens as tokens25 } from "@fluentui/react-components";
2724
+ import * as React20 from "react";
2725
+ import { makeStyles as makeStyles30, tokens as tokens28 } from "@fluentui/react-components";
2319
2726
 
2320
2727
  // src/grounding/SourceCard.tsx
2321
- import { Button as Button13, Text as Text9, makeStyles as makeStyles26, tokens as tokens24 } from "@fluentui/react-components";
2728
+ import { Button as Button15, Text as Text11, makeStyles as makeStyles29, tokens as tokens27 } from "@fluentui/react-components";
2322
2729
  import {
2323
2730
  DocumentRegular,
2324
2731
  DatabaseRegular,
@@ -2326,7 +2733,7 @@ import {
2326
2733
  BookRegular,
2327
2734
  DocumentBulletListRegular
2328
2735
  } from "@fluentui/react-icons";
2329
- import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
2736
+ import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
2330
2737
  var ICONS = {
2331
2738
  dataverse: DatabaseRegular,
2332
2739
  document: DocumentRegular,
@@ -2334,38 +2741,38 @@ var ICONS = {
2334
2741
  knowledge: BookRegular,
2335
2742
  other: DocumentBulletListRegular
2336
2743
  };
2337
- var useStyles25 = makeStyles26({
2338
- root: { gap: tokens24.spacingVerticalXXS },
2339
- head: { display: "flex", alignItems: "center", gap: tokens24.spacingHorizontalXS },
2340
- marker: { color: tokens24.colorNeutralForeground3, fontSize: tokens24.fontSizeBase200 },
2341
- snippet: { color: tokens24.colorNeutralForeground2, fontSize: tokens24.fontSizeBase200 },
2342
- meta: { display: "flex", alignItems: "center", gap: tokens24.spacingHorizontalS, marginTop: tokens24.spacingVerticalXXS }
2744
+ var useStyles28 = makeStyles29({
2745
+ root: { gap: tokens27.spacingVerticalXXS },
2746
+ head: { display: "flex", alignItems: "center", gap: tokens27.spacingHorizontalXS },
2747
+ marker: { color: tokens27.colorNeutralForeground3, fontSize: tokens27.fontSizeBase200 },
2748
+ snippet: { color: tokens27.colorNeutralForeground2, fontSize: tokens27.fontSizeBase200 },
2749
+ meta: { display: "flex", alignItems: "center", gap: tokens27.spacingHorizontalS, marginTop: tokens27.spacingVerticalXXS }
2343
2750
  });
2344
2751
  function SourceCard({ source, marker, onOpen, showSnippet = true }) {
2345
- const styles = useStyles25();
2752
+ const styles = useStyles28();
2346
2753
  const Icon = ICONS[source.kind] ?? ICONS.other;
2347
- return /* @__PURE__ */ jsxs24(CardSurface, { className: styles.root, children: [
2348
- /* @__PURE__ */ jsxs24("div", { className: styles.head, children: [
2349
- /* @__PURE__ */ jsx34(Icon, { "aria-hidden": "true" }),
2350
- marker ? /* @__PURE__ */ jsxs24("span", { className: styles.marker, children: [
2754
+ return /* @__PURE__ */ jsxs27(CardSurface, { className: styles.root, children: [
2755
+ /* @__PURE__ */ jsxs27("div", { className: styles.head, children: [
2756
+ /* @__PURE__ */ jsx37(Icon, { "aria-hidden": "true" }),
2757
+ marker ? /* @__PURE__ */ jsxs27("span", { className: styles.marker, children: [
2351
2758
  "[",
2352
2759
  marker,
2353
2760
  "]"
2354
2761
  ] }) : null,
2355
- /* @__PURE__ */ jsx34(Text9, { weight: "semibold", children: source.title })
2762
+ /* @__PURE__ */ jsx37(Text11, { weight: "semibold", children: source.title })
2356
2763
  ] }),
2357
- showSnippet && source.snippet ? /* @__PURE__ */ jsx34("span", { className: styles.snippet, children: source.snippet }) : null,
2358
- /* @__PURE__ */ jsxs24("div", { className: styles.meta, children: [
2359
- onOpen && (source.recordId || source.url) ? /* @__PURE__ */ jsx34(Button13, { size: "small", appearance: "subtle", onClick: () => onOpen(source), children: source.recordId ? "Open record" : "Open" }) : null,
2360
- /* @__PURE__ */ jsx34("span", { className: styles.snippet, children: source.score === void 0 ? "Relevance not reported" : `Relevance ${Math.round(source.score * 100)}%` })
2764
+ showSnippet && source.snippet ? /* @__PURE__ */ jsx37("span", { className: styles.snippet, children: source.snippet }) : null,
2765
+ /* @__PURE__ */ jsxs27("div", { className: styles.meta, children: [
2766
+ onOpen && (source.recordId || source.url) ? /* @__PURE__ */ jsx37(Button15, { size: "small", appearance: "subtle", onClick: () => onOpen(source), children: source.recordId ? "Open record" : "Open" }) : null,
2767
+ /* @__PURE__ */ jsx37("span", { className: styles.snippet, children: source.score === void 0 ? "Relevance not reported" : `Relevance ${Math.round(source.score * 100)}%` })
2361
2768
  ] })
2362
2769
  ] });
2363
2770
  }
2364
2771
 
2365
2772
  // src/grounding/CitationList.tsx
2366
- import { jsx as jsx35 } from "react/jsx-runtime";
2367
- var useStyles26 = makeStyles27({
2368
- list: { display: "flex", flexDirection: "column", gap: tokens25.spacingVerticalXS, listStyle: "none", margin: 0, padding: 0 }
2773
+ import { jsx as jsx38 } from "react/jsx-runtime";
2774
+ var useStyles29 = makeStyles30({
2775
+ list: { display: "flex", flexDirection: "column", gap: tokens28.spacingVerticalXS, listStyle: "none", margin: 0, padding: 0 }
2369
2776
  });
2370
2777
  function CitationList({
2371
2778
  text,
@@ -2373,38 +2780,38 @@ function CitationList({
2373
2780
  onOpenSource,
2374
2781
  defaultOpen = false
2375
2782
  }) {
2376
- const styles = useStyles26();
2377
- const id = React17.useId();
2378
- const { used, citations } = React17.useMemo(() => renumberCitations(text, sources), [text, sources]);
2783
+ const styles = useStyles29();
2784
+ const id = React20.useId();
2785
+ const { used, citations } = React20.useMemo(() => renumberCitations(text, sources), [text, sources]);
2379
2786
  if (used.length === 0) return null;
2380
2787
  const markerFor = (sourceId) => citations.find((c) => c.sourceId === sourceId)?.marker;
2381
- return /* @__PURE__ */ jsx35(
2788
+ return /* @__PURE__ */ jsx38(
2382
2789
  Disclosure,
2383
2790
  {
2384
2791
  id,
2385
2792
  defaultOpen,
2386
2793
  summary: `${used.length} source${used.length === 1 ? "" : "s"}`,
2387
- children: /* @__PURE__ */ jsx35("ul", { className: styles.list, children: used.map((source) => /* @__PURE__ */ jsx35("li", { children: /* @__PURE__ */ jsx35(SourceCard, { source, marker: markerFor(source.id), onOpen: onOpenSource }) }, source.id)) })
2794
+ children: /* @__PURE__ */ jsx38("ul", { className: styles.list, children: used.map((source) => /* @__PURE__ */ jsx38("li", { children: /* @__PURE__ */ jsx38(SourceCard, { source, marker: markerFor(source.id), onOpen: onOpenSource }) }, source.id)) })
2388
2795
  }
2389
2796
  );
2390
2797
  }
2391
2798
 
2392
2799
  // src/grounding/AnswerWithCitations.tsx
2393
- import * as React18 from "react";
2394
- import { makeStyles as makeStyles28 } from "@fluentui/react-components";
2395
- import { jsx as jsx36 } from "react/jsx-runtime";
2396
- var useStyles27 = makeStyles28({ root: { whiteSpace: "pre-wrap", wordBreak: "break-word" } });
2800
+ import * as React21 from "react";
2801
+ import { makeStyles as makeStyles31 } from "@fluentui/react-components";
2802
+ import { jsx as jsx39 } from "react/jsx-runtime";
2803
+ var useStyles30 = makeStyles31({ root: { whiteSpace: "pre-wrap", wordBreak: "break-word" } });
2397
2804
  function AnswerWithCitations({
2398
2805
  text,
2399
2806
  citations = [],
2400
2807
  sources = [],
2401
2808
  onOpenSource
2402
2809
  }) {
2403
- const styles = useStyles27();
2404
- const segments = React18.useMemo(() => splitTextByCitations(text, citations), [text, citations]);
2405
- const byId = React18.useMemo(() => new Map(sources.map((s) => [s.id, s])), [sources]);
2406
- return /* @__PURE__ */ jsx36("span", { className: styles.root, children: segments.map(
2407
- (segment, i) => segment.kind === "text" ? /* @__PURE__ */ jsx36(React18.Fragment, { children: segment.text }, i) : /* @__PURE__ */ jsx36(
2810
+ const styles = useStyles30();
2811
+ const segments = React21.useMemo(() => splitTextByCitations(text, citations), [text, citations]);
2812
+ const byId = React21.useMemo(() => new Map(sources.map((s) => [s.id, s])), [sources]);
2813
+ return /* @__PURE__ */ jsx39("span", { className: styles.root, children: segments.map(
2814
+ (segment, i) => segment.kind === "text" ? /* @__PURE__ */ jsx39(React21.Fragment, { children: segment.text }, i) : /* @__PURE__ */ jsx39(
2408
2815
  CitationChip,
2409
2816
  {
2410
2817
  marker: segment.marker ?? "",
@@ -2417,20 +2824,20 @@ function AnswerWithCitations({
2417
2824
  }
2418
2825
 
2419
2826
  // src/grounding/GroundingPanel.tsx
2420
- import * as React19 from "react";
2421
- import { Text as Text10, makeStyles as makeStyles29, tokens as tokens26 } from "@fluentui/react-components";
2422
- import { jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
2423
- var useStyles28 = makeStyles29({
2827
+ import * as React22 from "react";
2828
+ import { Text as Text12, makeStyles as makeStyles32, tokens as tokens29 } from "@fluentui/react-components";
2829
+ import { jsx as jsx40, jsxs as jsxs28 } from "react/jsx-runtime";
2830
+ var useStyles31 = makeStyles32({
2424
2831
  grid: {
2425
2832
  display: "grid",
2426
2833
  gridTemplateColumns: "minmax(96px, max-content) 1fr",
2427
- gap: `${tokens26.spacingVerticalXXS} ${tokens26.spacingHorizontalM}`,
2834
+ gap: `${tokens29.spacingVerticalXXS} ${tokens29.spacingHorizontalM}`,
2428
2835
  margin: 0,
2429
- fontSize: tokens26.fontSizeBase200
2836
+ fontSize: tokens29.fontSizeBase200
2430
2837
  },
2431
- key: { color: tokens26.colorNeutralForeground3, margin: 0 },
2432
- value: { margin: 0, wordBreak: "break-word", fontFamily: tokens26.fontFamilyMonospace },
2433
- empty: { fontSize: tokens26.fontSizeBase200, color: tokens26.colorNeutralForeground3 }
2838
+ key: { color: tokens29.colorNeutralForeground3, margin: 0 },
2839
+ value: { margin: 0, wordBreak: "break-word", fontFamily: tokens29.fontFamilyMonospace },
2840
+ empty: { fontSize: tokens29.fontSizeBase200, color: tokens29.colorNeutralForeground3 }
2434
2841
  });
2435
2842
  function render(value) {
2436
2843
  if (value === null || value === void 0) return "\u2014";
@@ -2442,45 +2849,45 @@ function GroundingPanel({
2442
2849
  title = "What this answer used",
2443
2850
  defaultOpen = false
2444
2851
  }) {
2445
- const styles = useStyles28();
2446
- const id = React19.useId();
2852
+ const styles = useStyles31();
2853
+ const id = React22.useId();
2447
2854
  const entries = Object.entries(grounding ?? {});
2448
2855
  if (entries.length === 0) return null;
2449
- return /* @__PURE__ */ jsxs25(Disclosure, { id, defaultOpen, summary: title, children: [
2450
- /* @__PURE__ */ jsx37("dl", { className: styles.grid, children: entries.map(([key, value]) => /* @__PURE__ */ jsxs25(React19.Fragment, { children: [
2451
- /* @__PURE__ */ jsx37("dt", { className: styles.key, children: key }),
2452
- /* @__PURE__ */ jsx37("dd", { className: styles.value, children: render(value) })
2856
+ return /* @__PURE__ */ jsxs28(Disclosure, { id, defaultOpen, summary: title, children: [
2857
+ /* @__PURE__ */ jsx40("dl", { className: styles.grid, children: entries.map(([key, value]) => /* @__PURE__ */ jsxs28(React22.Fragment, { children: [
2858
+ /* @__PURE__ */ jsx40("dt", { className: styles.key, children: key }),
2859
+ /* @__PURE__ */ jsx40("dd", { className: styles.value, children: render(value) })
2453
2860
  ] }, key)) }),
2454
- /* @__PURE__ */ jsx37(Text10, { as: "p", className: styles.empty, children: "These facts were supplied by the app, not produced by the model." })
2861
+ /* @__PURE__ */ jsx40(Text12, { as: "p", className: styles.empty, children: "These facts were supplied by the app, not produced by the model." })
2455
2862
  ] });
2456
2863
  }
2457
2864
 
2458
2865
  // src/grounding/ProviderAttribution.tsx
2459
- import { makeStyles as makeStyles30, tokens as tokens27 } from "@fluentui/react-components";
2866
+ import { makeStyles as makeStyles33, tokens as tokens30 } from "@fluentui/react-components";
2460
2867
  import { ShieldErrorRegular as ShieldErrorRegular2 } from "@fluentui/react-icons";
2461
- import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
2462
- var useStyles29 = makeStyles30({
2868
+ import { jsx as jsx41, jsxs as jsxs29 } from "react/jsx-runtime";
2869
+ var useStyles32 = makeStyles33({
2463
2870
  root: {
2464
2871
  display: "flex",
2465
2872
  alignItems: "center",
2466
- gap: tokens27.spacingHorizontalXXS,
2467
- fontSize: tokens27.fontSizeBase100,
2468
- color: tokens27.colorNeutralForeground3
2873
+ gap: tokens30.spacingHorizontalXXS,
2874
+ fontSize: tokens30.fontSizeBase100,
2875
+ color: tokens30.colorNeutralForeground3
2469
2876
  },
2470
- guarded: { color: tokens27.colorPaletteDarkOrangeForeground1 }
2877
+ guarded: { color: tokens30.colorPaletteDarkOrangeForeground1 }
2471
2878
  });
2472
2879
  function ProviderAttribution({ provider, model, guarded }) {
2473
- const styles = useStyles29();
2880
+ const styles = useStyles32();
2474
2881
  if (!provider && !model && !guarded) return null;
2475
2882
  const who = [provider, model].filter(Boolean).join(" \xB7 ");
2476
2883
  if (guarded) {
2477
- return /* @__PURE__ */ jsxs26("span", { className: `${styles.root} ${styles.guarded}`, children: [
2478
- /* @__PURE__ */ jsx38(ShieldErrorRegular2, { "aria-hidden": "true" }),
2884
+ return /* @__PURE__ */ jsxs29("span", { className: `${styles.root} ${styles.guarded}`, children: [
2885
+ /* @__PURE__ */ jsx41(ShieldErrorRegular2, { "aria-hidden": "true" }),
2479
2886
  "Withheld and replaced with safe text",
2480
2887
  who ? ` \u2014 not ${who}'s words` : ""
2481
2888
  ] });
2482
2889
  }
2483
- return /* @__PURE__ */ jsxs26("span", { className: styles.root, children: [
2890
+ return /* @__PURE__ */ jsxs29("span", { className: styles.root, children: [
2484
2891
  "Answered by ",
2485
2892
  who || "the agent"
2486
2893
  ] });
@@ -2490,57 +2897,57 @@ function messageAttribution(message) {
2490
2897
  }
2491
2898
 
2492
2899
  // src/actions/ActionCard.tsx
2493
- import * as React20 from "react";
2494
- import { Text as Text11, makeStyles as makeStyles31, tokens as tokens28 } from "@fluentui/react-components";
2495
- import { jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
2496
- var useStyles30 = makeStyles31({
2497
- head: { display: "flex", alignItems: "center", gap: tokens28.spacingHorizontalXS },
2498
- description: { color: tokens28.colorNeutralForeground2, fontSize: tokens28.fontSizeBase200 },
2499
- footer: { display: "flex", gap: tokens28.spacingHorizontalS, justifyContent: "flex-end", marginTop: tokens28.spacingVerticalXS }
2900
+ import * as React23 from "react";
2901
+ import { Text as Text13, makeStyles as makeStyles34, tokens as tokens31 } from "@fluentui/react-components";
2902
+ import { jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
2903
+ var useStyles33 = makeStyles34({
2904
+ head: { display: "flex", alignItems: "center", gap: tokens31.spacingHorizontalXS },
2905
+ description: { color: tokens31.colorNeutralForeground2, fontSize: tokens31.fontSizeBase200 },
2906
+ footer: { display: "flex", gap: tokens31.spacingHorizontalS, justifyContent: "flex-end", marginTop: tokens31.spacingVerticalXS }
2500
2907
  });
2501
2908
  function ActionCard({ title, description, icon, pending, children, footer }) {
2502
- const styles = useStyles30();
2503
- return /* @__PURE__ */ jsxs27(CardSurface, { emphasis: pending ? "attention" : "none", children: [
2504
- /* @__PURE__ */ jsxs27("div", { className: styles.head, children: [
2505
- icon ? React20.cloneElement(icon, { "aria-hidden": "true" }) : null,
2506
- /* @__PURE__ */ jsx39(Text11, { weight: "semibold", children: title })
2909
+ const styles = useStyles33();
2910
+ return /* @__PURE__ */ jsxs30(CardSurface, { emphasis: pending ? "attention" : "none", children: [
2911
+ /* @__PURE__ */ jsxs30("div", { className: styles.head, children: [
2912
+ icon ? React23.cloneElement(icon, { "aria-hidden": "true" }) : null,
2913
+ /* @__PURE__ */ jsx42(Text13, { weight: "semibold", children: title })
2507
2914
  ] }),
2508
- description ? /* @__PURE__ */ jsx39("span", { className: styles.description, children: description }) : null,
2915
+ description ? /* @__PURE__ */ jsx42("span", { className: styles.description, children: description }) : null,
2509
2916
  children,
2510
- footer ? /* @__PURE__ */ jsx39("div", { className: styles.footer, children: footer }) : null
2917
+ footer ? /* @__PURE__ */ jsx42("div", { className: styles.footer, children: footer }) : null
2511
2918
  ] });
2512
2919
  }
2513
2920
 
2514
2921
  // src/actions/ApprovalCard.tsx
2515
- import * as React22 from "react";
2516
- import { Button as Button15, Spinner, makeStyles as makeStyles34, tokens as tokens31 } from "@fluentui/react-components";
2517
- import { CheckmarkRegular, DismissRegular as DismissRegular2, EditRegular } from "@fluentui/react-icons";
2922
+ import * as React25 from "react";
2923
+ import { Button as Button17, Spinner, makeStyles as makeStyles37, tokens as tokens34 } from "@fluentui/react-components";
2924
+ import { CheckmarkRegular, DismissRegular as DismissRegular3, EditRegular } from "@fluentui/react-icons";
2518
2925
 
2519
2926
  // src/actions/ParameterReview.tsx
2520
- import * as React21 from "react";
2521
- import { Input, makeStyles as makeStyles32, tokens as tokens29, Text as Text12 } from "@fluentui/react-components";
2522
- import { jsx as jsx40, jsxs as jsxs28 } from "react/jsx-runtime";
2523
- var useStyles31 = makeStyles32({
2927
+ import * as React24 from "react";
2928
+ import { Input, makeStyles as makeStyles35, tokens as tokens32, Text as Text14 } from "@fluentui/react-components";
2929
+ import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
2930
+ var useStyles34 = makeStyles35({
2524
2931
  grid: {
2525
2932
  display: "grid",
2526
2933
  gridTemplateColumns: "minmax(110px, max-content) 1fr",
2527
- gap: `${tokens29.spacingVerticalXS} ${tokens29.spacingHorizontalM}`,
2934
+ gap: `${tokens32.spacingVerticalXS} ${tokens32.spacingHorizontalM}`,
2528
2935
  alignItems: "center",
2529
2936
  margin: 0
2530
2937
  },
2531
- key: { margin: 0, color: tokens29.colorNeutralForeground2, fontSize: tokens29.fontSizeBase200 },
2938
+ key: { margin: 0, color: tokens32.colorNeutralForeground2, fontSize: tokens32.fontSizeBase200 },
2532
2939
  value: { margin: 0 },
2533
2940
  raw: {
2534
2941
  whiteSpace: "pre-wrap",
2535
2942
  wordBreak: "break-all",
2536
- fontFamily: tokens29.fontFamilyMonospace,
2537
- fontSize: tokens29.fontSizeBase200,
2538
- color: tokens29.colorNeutralForeground2
2943
+ fontFamily: tokens32.fontFamilyMonospace,
2944
+ fontSize: tokens32.fontSizeBase200,
2945
+ color: tokens32.colorNeutralForeground2
2539
2946
  }
2540
2947
  });
2541
2948
  function ParameterReview({ argumentsJson, readOnly = true, onChange }) {
2542
- const styles = useStyles31();
2543
- const parsed = React21.useMemo(() => {
2949
+ const styles = useStyles34();
2950
+ const parsed = React24.useMemo(() => {
2544
2951
  try {
2545
2952
  const value = JSON.parse(argumentsJson);
2546
2953
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -2549,18 +2956,18 @@ function ParameterReview({ argumentsJson, readOnly = true, onChange }) {
2549
2956
  }
2550
2957
  }, [argumentsJson]);
2551
2958
  if (!parsed) {
2552
- return /* @__PURE__ */ jsxs28("div", { children: [
2553
- /* @__PURE__ */ jsx40(Text12, { size: 200, children: "Arguments (unparsed)" }),
2554
- /* @__PURE__ */ jsx40("pre", { className: styles.raw, children: argumentsJson || "(empty)" })
2959
+ return /* @__PURE__ */ jsxs31("div", { children: [
2960
+ /* @__PURE__ */ jsx43(Text14, { size: 200, children: "Arguments (unparsed)" }),
2961
+ /* @__PURE__ */ jsx43("pre", { className: styles.raw, children: argumentsJson || "(empty)" })
2555
2962
  ] });
2556
2963
  }
2557
2964
  const set = (key, next) => {
2558
2965
  if (!onChange) return;
2559
2966
  onChange(JSON.stringify({ ...parsed, [key]: next }));
2560
2967
  };
2561
- return /* @__PURE__ */ jsx40("dl", { className: styles.grid, children: Object.entries(parsed).map(([key, value]) => /* @__PURE__ */ jsxs28(React21.Fragment, { children: [
2562
- /* @__PURE__ */ jsx40("dt", { className: styles.key, children: key }),
2563
- /* @__PURE__ */ jsx40("dd", { className: styles.value, children: readOnly ? /* @__PURE__ */ jsx40("span", { className: styles.raw, children: typeof value === "string" ? value : JSON.stringify(value) }) : /* @__PURE__ */ jsx40(
2968
+ return /* @__PURE__ */ jsx43("dl", { className: styles.grid, children: Object.entries(parsed).map(([key, value]) => /* @__PURE__ */ jsxs31(React24.Fragment, { children: [
2969
+ /* @__PURE__ */ jsx43("dt", { className: styles.key, children: key }),
2970
+ /* @__PURE__ */ jsx43("dd", { className: styles.value, children: readOnly ? /* @__PURE__ */ jsx43("span", { className: styles.raw, children: typeof value === "string" ? value : JSON.stringify(value) }) : /* @__PURE__ */ jsx43(
2564
2971
  Input,
2565
2972
  {
2566
2973
  size: "small",
@@ -2573,32 +2980,32 @@ function ParameterReview({ argumentsJson, readOnly = true, onChange }) {
2573
2980
  }
2574
2981
 
2575
2982
  // src/actions/ActionResult.tsx
2576
- import { MessageBar as MessageBar4, MessageBarBody as MessageBarBody4, MessageBarTitle as MessageBarTitle4, MessageBarActions as MessageBarActions4, Button as Button14, makeStyles as makeStyles33, tokens as tokens30 } from "@fluentui/react-components";
2577
- import { jsx as jsx41, jsxs as jsxs29 } from "react/jsx-runtime";
2983
+ import { MessageBar as MessageBar4, MessageBarBody as MessageBarBody4, MessageBarTitle as MessageBarTitle4, MessageBarActions as MessageBarActions4, Button as Button16, makeStyles as makeStyles36, tokens as tokens33 } from "@fluentui/react-components";
2984
+ import { jsx as jsx44, jsxs as jsxs32 } from "react/jsx-runtime";
2578
2985
  var INTENT2 = { succeeded: "success", failed: "error", denied: "warning" };
2579
2986
  var TITLE = { succeeded: "Done", failed: "Failed", denied: "Not approved" };
2580
- var useStyles32 = makeStyles33({
2581
- id: { display: "block", marginTop: tokens30.spacingVerticalXXS, fontSize: tokens30.fontSizeBase100, color: tokens30.colorNeutralForeground3, fontFamily: tokens30.fontFamilyMonospace }
2987
+ var useStyles35 = makeStyles36({
2988
+ id: { display: "block", marginTop: tokens33.spacingVerticalXXS, fontSize: tokens33.fontSizeBase100, color: tokens33.colorNeutralForeground3, fontFamily: tokens33.fontFamilyMonospace }
2582
2989
  });
2583
2990
  function ActionResult({ status, message, correlationId, onRetry }) {
2584
- const styles = useStyles32();
2585
- return /* @__PURE__ */ jsxs29(MessageBar4, { intent: INTENT2[status], children: [
2586
- /* @__PURE__ */ jsxs29(MessageBarBody4, { children: [
2587
- /* @__PURE__ */ jsx41(MessageBarTitle4, { children: TITLE[status] }),
2991
+ const styles = useStyles35();
2992
+ return /* @__PURE__ */ jsxs32(MessageBar4, { intent: INTENT2[status], children: [
2993
+ /* @__PURE__ */ jsxs32(MessageBarBody4, { children: [
2994
+ /* @__PURE__ */ jsx44(MessageBarTitle4, { children: TITLE[status] }),
2588
2995
  message,
2589
- correlationId ? /* @__PURE__ */ jsxs29("span", { className: styles.id, children: [
2996
+ correlationId ? /* @__PURE__ */ jsxs32("span", { className: styles.id, children: [
2590
2997
  "Correlation id: ",
2591
2998
  correlationId
2592
2999
  ] }) : null
2593
3000
  ] }),
2594
- status === "failed" && onRetry ? /* @__PURE__ */ jsx41(MessageBarActions4, { children: /* @__PURE__ */ jsx41(Button14, { size: "small", onClick: onRetry, children: "Try again" }) }) : null
3001
+ status === "failed" && onRetry ? /* @__PURE__ */ jsx44(MessageBarActions4, { children: /* @__PURE__ */ jsx44(Button16, { size: "small", onClick: onRetry, children: "Try again" }) }) : null
2595
3002
  ] });
2596
3003
  }
2597
3004
 
2598
3005
  // src/actions/ApprovalCard.tsx
2599
- import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
2600
- var useStyles33 = makeStyles34({
2601
- busy: { display: "flex", alignItems: "center", gap: tokens31.spacingHorizontalXS, fontSize: tokens31.fontSizeBase200 }
3006
+ import { Fragment as Fragment8, jsx as jsx45, jsxs as jsxs33 } from "react/jsx-runtime";
3007
+ var useStyles36 = makeStyles37({
3008
+ busy: { display: "flex", alignItems: "center", gap: tokens34.spacingHorizontalXS, fontSize: tokens34.fontSizeBase200 }
2602
3009
  });
2603
3010
  function ApprovalCard({
2604
3011
  toolCall,
@@ -2607,15 +3014,15 @@ function ApprovalCard({
2607
3014
  allowEdit = false,
2608
3015
  busy = false
2609
3016
  }) {
2610
- const styles = useStyles33();
2611
- const [args, setArgs] = React22.useState(toolCall.argumentsJson);
2612
- const [editing, setEditing] = React22.useState(false);
2613
- const [decided, setDecided] = React22.useState(false);
3017
+ const styles = useStyles36();
3018
+ const [args, setArgs] = React25.useState(toolCall.argumentsJson);
3019
+ const [editing, setEditing] = React25.useState(false);
3020
+ const [decided, setDecided] = React25.useState(false);
2614
3021
  const settled = toolCall.status === "succeeded" || toolCall.status === "failed" || toolCall.status === "denied";
2615
3022
  if (settled) {
2616
- return /* @__PURE__ */ jsxs30(ActionCard, { title: toolCall.name, description: "Tool call", children: [
2617
- /* @__PURE__ */ jsx42(ParameterReview, { argumentsJson: toolCall.argumentsJson }),
2618
- /* @__PURE__ */ jsx42(
3023
+ return /* @__PURE__ */ jsxs33(ActionCard, { title: toolCall.name, description: "Tool call", children: [
3024
+ /* @__PURE__ */ jsx45(ParameterReview, { argumentsJson: toolCall.argumentsJson }),
3025
+ /* @__PURE__ */ jsx45(
2619
3026
  ActionResult,
2620
3027
  {
2621
3028
  status: toolCall.status === "succeeded" ? "succeeded" : toolCall.status === "denied" ? "denied" : "failed",
@@ -2636,29 +3043,29 @@ function ApprovalCard({
2636
3043
  setDecided(true);
2637
3044
  onDeny(toolCall);
2638
3045
  };
2639
- return /* @__PURE__ */ jsx42(
3046
+ return /* @__PURE__ */ jsx45(
2640
3047
  ActionCard,
2641
3048
  {
2642
3049
  title: toolCall.name,
2643
3050
  description: "The agent is asking to run this. Check the details before approving.",
2644
3051
  pending: !locked,
2645
- footer: locked ? /* @__PURE__ */ jsxs30("span", { className: styles.busy, children: [
2646
- /* @__PURE__ */ jsx42(Spinner, { size: "tiny" }),
3052
+ footer: locked ? /* @__PURE__ */ jsxs33("span", { className: styles.busy, children: [
3053
+ /* @__PURE__ */ jsx45(Spinner, { size: "tiny" }),
2647
3054
  " Submitting\u2026"
2648
- ] }) : /* @__PURE__ */ jsxs30(Fragment8, { children: [
2649
- allowEdit ? /* @__PURE__ */ jsx42(Button15, { size: "small", icon: /* @__PURE__ */ jsx42(EditRegular, {}), onClick: () => setEditing((v) => !v), children: editing ? "Done editing" : "Edit" }) : null,
2650
- /* @__PURE__ */ jsx42(Button15, { size: "small", icon: /* @__PURE__ */ jsx42(DismissRegular2, {}), onClick: deny, disabled: locked, children: "Deny" }),
2651
- /* @__PURE__ */ jsx42(Button15, { size: "small", appearance: "primary", icon: /* @__PURE__ */ jsx42(CheckmarkRegular, {}), onClick: approve, disabled: locked, children: "Approve" })
3055
+ ] }) : /* @__PURE__ */ jsxs33(Fragment8, { children: [
3056
+ allowEdit ? /* @__PURE__ */ jsx45(Button17, { size: "small", icon: /* @__PURE__ */ jsx45(EditRegular, {}), onClick: () => setEditing((v) => !v), children: editing ? "Done editing" : "Edit" }) : null,
3057
+ /* @__PURE__ */ jsx45(Button17, { size: "small", icon: /* @__PURE__ */ jsx45(DismissRegular3, {}), onClick: deny, disabled: locked, children: "Deny" }),
3058
+ /* @__PURE__ */ jsx45(Button17, { size: "small", appearance: "primary", icon: /* @__PURE__ */ jsx45(CheckmarkRegular, {}), onClick: approve, disabled: locked, children: "Approve" })
2652
3059
  ] }),
2653
- children: /* @__PURE__ */ jsx42(ParameterReview, { argumentsJson: args, readOnly: !editing, onChange: setArgs })
3060
+ children: /* @__PURE__ */ jsx45(ParameterReview, { argumentsJson: args, readOnly: !editing, onChange: setArgs })
2654
3061
  }
2655
3062
  );
2656
3063
  }
2657
3064
 
2658
3065
  // src/actions/ToolCallCard.tsx
2659
- import * as React23 from "react";
2660
- import { Badge as Badge3, Spinner as Spinner2, makeStyles as makeStyles35, tokens as tokens32 } from "@fluentui/react-components";
2661
- import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
3066
+ import * as React26 from "react";
3067
+ import { Badge as Badge4, Spinner as Spinner2, makeStyles as makeStyles38, tokens as tokens35 } from "@fluentui/react-components";
3068
+ import { jsx as jsx46, jsxs as jsxs34 } from "react/jsx-runtime";
2662
3069
  var LABEL = {
2663
3070
  proposed: "Proposed",
2664
3071
  running: "Running",
@@ -2673,41 +3080,41 @@ var COLOUR = {
2673
3080
  failed: "danger",
2674
3081
  denied: "warning"
2675
3082
  };
2676
- var useStyles34 = makeStyles35({
2677
- head: { display: "flex", alignItems: "center", gap: tokens32.spacingHorizontalXS },
2678
- name: { fontFamily: tokens32.fontFamilyMonospace, fontSize: tokens32.fontSizeBase200 },
3083
+ var useStyles37 = makeStyles38({
3084
+ head: { display: "flex", alignItems: "center", gap: tokens35.spacingHorizontalXS },
3085
+ name: { fontFamily: tokens35.fontFamilyMonospace, fontSize: tokens35.fontSizeBase200 },
2679
3086
  result: {
2680
3087
  whiteSpace: "pre-wrap",
2681
3088
  wordBreak: "break-all",
2682
- fontFamily: tokens32.fontFamilyMonospace,
2683
- fontSize: tokens32.fontSizeBase200,
2684
- marginTop: tokens32.spacingVerticalXS
3089
+ fontFamily: tokens35.fontFamilyMonospace,
3090
+ fontSize: tokens35.fontSizeBase200,
3091
+ marginTop: tokens35.spacingVerticalXS
2685
3092
  }
2686
3093
  });
2687
3094
  function ToolCallCard({ toolCall, defaultExpanded = false }) {
2688
- const styles = useStyles34();
2689
- const id = React23.useId();
2690
- return /* @__PURE__ */ jsx43(CardSurface, { children: /* @__PURE__ */ jsxs31(
3095
+ const styles = useStyles37();
3096
+ const id = React26.useId();
3097
+ return /* @__PURE__ */ jsx46(CardSurface, { children: /* @__PURE__ */ jsxs34(
2691
3098
  Disclosure,
2692
3099
  {
2693
3100
  id,
2694
3101
  defaultOpen: defaultExpanded,
2695
- summary: /* @__PURE__ */ jsxs31("span", { className: styles.head, children: [
2696
- /* @__PURE__ */ jsx43("span", { className: styles.name, children: toolCall.name }),
2697
- /* @__PURE__ */ jsx43(Badge3, { appearance: "tint", color: COLOUR[toolCall.status], children: LABEL[toolCall.status] }),
2698
- toolCall.status === "running" ? /* @__PURE__ */ jsx43(Spinner2, { size: "extra-tiny" }) : null
3102
+ summary: /* @__PURE__ */ jsxs34("span", { className: styles.head, children: [
3103
+ /* @__PURE__ */ jsx46("span", { className: styles.name, children: toolCall.name }),
3104
+ /* @__PURE__ */ jsx46(Badge4, { appearance: "tint", color: COLOUR[toolCall.status], children: LABEL[toolCall.status] }),
3105
+ toolCall.status === "running" ? /* @__PURE__ */ jsx46(Spinner2, { size: "extra-tiny" }) : null
2699
3106
  ] }),
2700
3107
  children: [
2701
- /* @__PURE__ */ jsx43(ParameterReview, { argumentsJson: toolCall.argumentsJson }),
2702
- toolCall.resultText ? /* @__PURE__ */ jsx43("div", { className: styles.result, children: toolCall.resultText }) : null,
2703
- toolCall.failure ? /* @__PURE__ */ jsx43("div", { className: styles.result, children: toolCall.failure.message }) : null
3108
+ /* @__PURE__ */ jsx46(ParameterReview, { argumentsJson: toolCall.argumentsJson }),
3109
+ toolCall.resultText ? /* @__PURE__ */ jsx46("div", { className: styles.result, children: toolCall.resultText }) : null,
3110
+ toolCall.failure ? /* @__PURE__ */ jsx46("div", { className: styles.result, children: toolCall.failure.message }) : null
2704
3111
  ]
2705
3112
  }
2706
3113
  ) });
2707
3114
  }
2708
3115
 
2709
3116
  // src/host/AgentKitHostProvider.tsx
2710
- import * as React24 from "react";
3117
+ import * as React27 from "react";
2711
3118
  import { FluentProvider, IdPrefixProvider } from "@fluentui/react-components";
2712
3119
 
2713
3120
  // src/theme/index.ts
@@ -2744,16 +3151,16 @@ function resolveHostTheme(input = {}) {
2744
3151
  var nextAgentIdPrefix = createIdPrefixCounter("dvkak");
2745
3152
 
2746
3153
  // src/host/AgentKitHostProvider.tsx
2747
- import { jsx as jsx44 } from "react/jsx-runtime";
3154
+ import { jsx as jsx47 } from "react/jsx-runtime";
2748
3155
  function AgentKitHostProvider(props) {
2749
3156
  const { children, theme, hostTheme, isDarkTheme, targetDocument, className, style } = props;
2750
- const [generated] = React24.useState(nextAgentIdPrefix);
3157
+ const [generated] = React27.useState(nextAgentIdPrefix);
2751
3158
  const idPrefix = props.idPrefix ?? generated;
2752
- const resolved = React24.useMemo(
3159
+ const resolved = React27.useMemo(
2753
3160
  () => resolveHostTheme({ theme, hostTheme, isDarkTheme }),
2754
3161
  [theme, hostTheme, isDarkTheme]
2755
3162
  );
2756
- return /* @__PURE__ */ jsx44(IdPrefixProvider, { value: idPrefix, children: /* @__PURE__ */ jsx44(
3163
+ return /* @__PURE__ */ jsx47(IdPrefixProvider, { value: idPrefix, children: /* @__PURE__ */ jsx47(
2757
3164
  FluentProvider,
2758
3165
  {
2759
3166
  theme: resolved,
@@ -3062,12 +3469,14 @@ export {
3062
3469
  AgentAppShell,
3063
3470
  AgentAvatar,
3064
3471
  AgentKitHostProvider,
3472
+ AgentLauncher,
3065
3473
  AgentOpsPanel,
3066
3474
  AgentPicker,
3067
3475
  AgentStatusBadge,
3068
3476
  AnswerWithCitations,
3069
3477
  AppRail,
3070
3478
  ApprovalCard,
3479
+ AssistantPanel,
3071
3480
  AvailabilityBanner,
3072
3481
  CitationChip,
3073
3482
  CitationList,
@@ -3079,6 +3488,7 @@ export {
3079
3488
  DEFAULT_GROUP_WINDOW_MS,
3080
3489
  DayDivider,
3081
3490
  EmptyConversation,
3491
+ FeedbackPanel,
3082
3492
  GlobalSearchBar,
3083
3493
  GroundingPanel,
3084
3494
  LiveAnnouncer,
@@ -3140,6 +3550,7 @@ export {
3140
3550
  splitTextByCitations,
3141
3551
  useConversation,
3142
3552
  useFocusRestore,
3553
+ useReturnFocus,
3143
3554
  useRovingTabindex,
3144
3555
  useStickyScroll,
3145
3556
  useVisuallyHiddenStyles