@case-framework/survey-assistant 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +58 -3
  2. package/dist/{attachments-B0hg3vpT.mjs → attachments-BuNni5vB.mjs} +1 -1
  3. package/dist/{attachments-B0hg3vpT.mjs.map → attachments-BuNni5vB.mjs.map} +1 -1
  4. package/dist/{authoring-references-BJQ_1nMX.mjs → authoring-references-CmwLc_C8.mjs} +49 -32
  5. package/dist/authoring-references-CmwLc_C8.mjs.map +1 -0
  6. package/dist/capabilities-D55dq-fO.mjs +582 -0
  7. package/dist/capabilities-D55dq-fO.mjs.map +1 -0
  8. package/dist/capabilities-default.d.mts +5 -12
  9. package/dist/capabilities-default.d.mts.map +1 -1
  10. package/dist/capabilities-default.mjs +2 -411
  11. package/dist/capabilities-z95e1mti.d.mts +117 -0
  12. package/dist/capabilities-z95e1mti.d.mts.map +1 -0
  13. package/dist/{constants-0UHGFcRJ.mjs → constants-Ct-vv9cu.mjs} +1 -1
  14. package/dist/{constants-0UHGFcRJ.mjs.map → constants-Ct-vv9cu.mjs.map} +1 -1
  15. package/dist/{constants-Be91Gay9.d.mts → constants-HL_klgJl.d.mts} +7 -28
  16. package/dist/constants-HL_klgJl.d.mts.map +1 -0
  17. package/dist/{controller-proxy-BH05e-C2.mjs → controller-proxy-BQ1YsVxJ.mjs} +12 -21
  18. package/dist/controller-proxy-BQ1YsVxJ.mjs.map +1 -0
  19. package/dist/controller-proxy-Cmzdr9tV.d.mts +65 -0
  20. package/dist/controller-proxy-Cmzdr9tV.d.mts.map +1 -0
  21. package/dist/default-D22AKTqE.mjs +233 -0
  22. package/dist/default-D22AKTqE.mjs.map +1 -0
  23. package/dist/{digest-SJmoYVaK.d.mts → digest-FnTTDBq2.d.mts} +2 -3
  24. package/dist/digest-FnTTDBq2.d.mts.map +1 -0
  25. package/dist/digest.d.mts +1 -1
  26. package/dist/digest.mjs.map +1 -1
  27. package/dist/engine-D950TfvC.mjs +3098 -0
  28. package/dist/engine-D950TfvC.mjs.map +1 -0
  29. package/dist/engine.d.mts +4 -3
  30. package/dist/engine.mjs +3 -3
  31. package/dist/{fair-guidance-CRYCRxQm.mjs → fair-guidance-BmO4PswW.mjs} +1 -1
  32. package/dist/{fair-guidance-CRYCRxQm.mjs.map → fair-guidance-BmO4PswW.mjs.map} +1 -1
  33. package/dist/{index-l_EK4yK7.d.mts → index-B8TLBd1G.d.mts} +18 -72
  34. package/dist/index-B8TLBd1G.d.mts.map +1 -0
  35. package/dist/index-CaX3hZmr.d.mts +23813 -0
  36. package/dist/index-CaX3hZmr.d.mts.map +1 -0
  37. package/dist/{index-x0qprHgK.d.mts → index-CeUlGkoU.d.mts} +58 -28
  38. package/dist/index-CeUlGkoU.d.mts.map +1 -0
  39. package/dist/{index-nhrgbgO5.d.mts → index-DYHdvSE8.d.mts} +347 -88
  40. package/dist/index-DYHdvSE8.d.mts.map +1 -0
  41. package/dist/lifecycle-DFzxVxpq.d.mts +54346 -0
  42. package/dist/lifecycle-DFzxVxpq.d.mts.map +1 -0
  43. package/dist/{memory-thread-repository-KWHQWFEW.mjs → memory-thread-repository-DmLadygY.mjs} +60 -30
  44. package/dist/memory-thread-repository-DmLadygY.mjs.map +1 -0
  45. package/dist/protocol-BQ7uIDYT.mjs +569 -0
  46. package/dist/protocol-BQ7uIDYT.mjs.map +1 -0
  47. package/dist/protocol.d.mts +4 -4
  48. package/dist/protocol.mjs +4 -3
  49. package/dist/{react-B3ybjJ-X.mjs → react-DybJ5pWw.mjs} +159 -46
  50. package/dist/react-DybJ5pWw.mjs.map +1 -0
  51. package/dist/react-integration.d.mts +2 -2
  52. package/dist/react-integration.mjs +2 -2
  53. package/dist/react.d.mts +3 -3
  54. package/dist/react.mjs +3 -3
  55. package/dist/references/assistant-operations.md +224 -180
  56. package/dist/references/core-rules.md +6 -3
  57. package/dist/references/element-types.md +189 -0
  58. package/dist/references/expressions.md +307 -168
  59. package/dist/references/fair-by-design.md +9 -9
  60. package/dist/references/follow-ups.md +151 -0
  61. package/dist/references/localization.md +26 -12
  62. package/dist/references/response-variables.md +38 -0
  63. package/dist/references/rich-text-content.md +22 -43
  64. package/dist/references/source-material-surveys.md +20 -24
  65. package/dist/references/survey-data-model.md +36 -102
  66. package/dist/{request-context-CG4SWijt.mjs → request-context-KVh8VjgH.mjs} +4 -10
  67. package/dist/request-context-KVh8VjgH.mjs.map +1 -0
  68. package/dist/{request-guardrails-TmgQtqp4.mjs → request-guardrails-C0ugBOp0.mjs} +6 -5
  69. package/dist/request-guardrails-C0ugBOp0.mjs.map +1 -0
  70. package/dist/server-agent.d.mts +62 -43
  71. package/dist/server-agent.d.mts.map +1 -1
  72. package/dist/server-agent.mjs +73 -40
  73. package/dist/server-agent.mjs.map +1 -1
  74. package/dist/server-runtime.d.mts +24 -42
  75. package/dist/server-runtime.d.mts.map +1 -1
  76. package/dist/server-runtime.mjs +12 -12
  77. package/dist/server-runtime.mjs.map +1 -1
  78. package/dist/server-tasks.d.mts +2 -2
  79. package/dist/server-tasks.mjs +2 -313
  80. package/dist/server-tools.d.mts +1 -1
  81. package/dist/server-tools.mjs +1 -1
  82. package/dist/server.d.mts +14 -36
  83. package/dist/server.d.mts.map +1 -1
  84. package/dist/server.mjs +5 -5
  85. package/dist/server.mjs.map +1 -1
  86. package/dist/storage-postgres.d.mts +9 -25
  87. package/dist/storage-postgres.d.mts.map +1 -1
  88. package/dist/storage-postgres.mjs +5 -4
  89. package/dist/storage-postgres.mjs.map +1 -1
  90. package/dist/tasks-Coh5N027.mjs +397 -0
  91. package/dist/tasks-Coh5N027.mjs.map +1 -0
  92. package/dist/{tasks-CYqrcaRO.d.mts → tasks-wb9M-bak.d.mts} +25 -41
  93. package/dist/tasks-wb9M-bak.d.mts.map +1 -0
  94. package/dist/thread-documents-DrHbaXqP.d.mts +119 -0
  95. package/dist/thread-documents-DrHbaXqP.d.mts.map +1 -0
  96. package/dist/{thread-handlers-DBAaU7BA.d.mts → thread-handlers-C3Iya92v.d.mts} +9 -40
  97. package/dist/thread-handlers-C3Iya92v.d.mts.map +1 -0
  98. package/dist/{tools-BvSovehT.mjs → tools-D0KBDolR.mjs} +677 -459
  99. package/dist/tools-D0KBDolR.mjs.map +1 -0
  100. package/dist/turn-survey-draft-B34lggSG.d.mts +185 -0
  101. package/dist/turn-survey-draft-B34lggSG.d.mts.map +1 -0
  102. package/dist/ui.css +1 -1
  103. package/dist/ui.d.mts +15 -54
  104. package/dist/ui.d.mts.map +1 -1
  105. package/dist/ui.mjs +203 -156
  106. package/dist/ui.mjs.map +1 -1
  107. package/docs/integration.md +11 -1
  108. package/package.json +41 -36
  109. package/dist/authoring-references-BJQ_1nMX.mjs.map +0 -1
  110. package/dist/capabilities-1KNnNO1_.mjs +0 -73
  111. package/dist/capabilities-1KNnNO1_.mjs.map +0 -1
  112. package/dist/capabilities-DVTfogjv.d.mts +0 -193
  113. package/dist/capabilities-DVTfogjv.d.mts.map +0 -1
  114. package/dist/capabilities-default.mjs.map +0 -1
  115. package/dist/constants-Be91Gay9.d.mts.map +0 -1
  116. package/dist/controller-proxy-BH05e-C2.mjs.map +0 -1
  117. package/dist/controller-proxy-Bd0ZHBPF.d.mts +0 -85
  118. package/dist/controller-proxy-Bd0ZHBPF.d.mts.map +0 -1
  119. package/dist/digest-SJmoYVaK.d.mts.map +0 -1
  120. package/dist/engine-Bo85Oyj0.mjs +0 -6723
  121. package/dist/engine-Bo85Oyj0.mjs.map +0 -1
  122. package/dist/index-Tnqv-yKW.d.mts +0 -777
  123. package/dist/index-Tnqv-yKW.d.mts.map +0 -1
  124. package/dist/index-l_EK4yK7.d.mts.map +0 -1
  125. package/dist/index-nhrgbgO5.d.mts.map +0 -1
  126. package/dist/index-x0qprHgK.d.mts.map +0 -1
  127. package/dist/lifecycle-Bx0aq_4S.d.mts +0 -529
  128. package/dist/lifecycle-Bx0aq_4S.d.mts.map +0 -1
  129. package/dist/memory-thread-repository-KWHQWFEW.mjs.map +0 -1
  130. package/dist/protocol-BhzQbx81.mjs +0 -1173
  131. package/dist/protocol-BhzQbx81.mjs.map +0 -1
  132. package/dist/react-B3ybjJ-X.mjs.map +0 -1
  133. package/dist/references/embedded-forms.md +0 -126
  134. package/dist/references/item-types.md +0 -407
  135. package/dist/request-context-CG4SWijt.mjs.map +0 -1
  136. package/dist/request-guardrails-TmgQtqp4.mjs.map +0 -1
  137. package/dist/server-tasks.mjs.map +0 -1
  138. package/dist/tasks-CYqrcaRO.d.mts.map +0 -1
  139. package/dist/thread-documents-rmd6nyX9.d.mts +0 -107
  140. package/dist/thread-documents-rmd6nyX9.d.mts.map +0 -1
  141. package/dist/thread-handlers-DBAaU7BA.d.mts.map +0 -1
  142. package/dist/tools-BvSovehT.mjs.map +0 -1
package/dist/ui.mjs CHANGED
@@ -1,22 +1,26 @@
1
1
  "use client";
2
- import { Lt as getSurveyAssistantEmbeddedBinaryMarker, Mt as parseSurveyAssistantError, jt as isSurveyAssistantErrorRetryable, l as surveyAssistantTurnFinalSchema, n as SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE } from "./protocol-BhzQbx81.mjs";
3
- import { n as isSurveyAssistantAttachmentMediaType, t as SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES } from "./attachments-B0hg3vpT.mjs";
4
- import { E as isSurveyAssistantTurnActive, S as parseSurveyChangeSet, T as unwrapSurveyAssistantToolOutput, _ as createSurveyAssistantThreadClient, a as createSurveyAssistantSupportDetails, c as estimateSurveyAssistantSupportBundleBytes, d as prepareSurveyAssistantSupportBundle, i as SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION, l as generateSurveyAssistantSupportBundle, m as createSurveyAssistantDiagnosticStore, o as createSurveyAssistantSupportMailto, r as useSurveyAssistantModelCatalog, s as downloadSurveyAssistantSupportBundle, t as useSurveyAssistantSession, u as isSurveyAssistantSupportBundleEnabled } from "./react-B3ybjJ-X.mjs";
5
- import { o as connectSurveyAssistantThreadLauncher } from "./controller-proxy-BH05e-C2.mjs";
2
+ import { J as isSurveyAssistantErrorRetryable, Y as parseSurveyAssistantError, et as getSurveyAssistantEmbeddedBinaryMarker, l as surveyAssistantTurnFinalSchema, n as SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE } from "./protocol-BQ7uIDYT.mjs";
3
+ import { n as isSurveyAssistantAttachmentMediaType, t as SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES } from "./attachments-BuNni5vB.mjs";
4
+ import { E as isSurveyAssistantTurnActive, S as parseSurveyChangeSet, T as unwrapSurveyAssistantToolOutput, _ as createSurveyAssistantThreadClient, a as createSurveyAssistantSupportDetails, c as estimateSurveyAssistantSupportBundleBytes, d as prepareSurveyAssistantSupportBundle, i as SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION, l as generateSurveyAssistantSupportBundle, m as createSurveyAssistantDiagnosticStore, o as createSurveyAssistantSupportMailto, r as useSurveyAssistantModelCatalog, s as downloadSurveyAssistantSupportBundle, t as useSurveyAssistantSession, u as isSurveyAssistantSupportBundleEnabled } from "./react-DybJ5pWw.mjs";
5
+ import { a as connectSurveyAssistantThreadLauncher } from "./controller-proxy-BQ1YsVxJ.mjs";
6
6
  import { getToolName, isFileUIPart, isReasoningUIPart, isToolUIPart } from "ai";
7
7
  import { createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
8
- import { Checkbox, Collapsible, Dialog, Select, Slot, Tooltip } from "radix-ui";
8
+ import { Collapsible } from "@base-ui/react/collapsible";
9
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
10
  import { clsx } from "clsx";
11
11
  import { twMerge } from "tailwind-merge";
12
- import { useControllableState } from "@radix-ui/react-use-controllable-state";
13
12
  import { ArrowDownIcon, ArrowUpIcon, BotIcon, BrainIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, ChevronUpIcon, ClockIcon, CopyIcon, DotIcon, DownloadIcon, FileIcon, HistoryIcon, ListChecksIcon, LoaderCircleIcon, MailIcon, MessageSquarePlusIcon, PackageOpenIcon, PaperclipIcon, PencilIcon, PlusIcon, SearchIcon, SparklesIcon, SquareIcon, Trash2Icon, WandSparklesIcon, WrenchIcon, XCircleIcon, XIcon } from "lucide-react";
14
13
  import { motion } from "motion/react";
15
14
  import { createLocalizationTranslator, mergeLocalizationCatalogs } from "@case-framework/ui-localization";
16
15
  import { cva } from "class-variance-authority";
16
+ import { Button } from "@base-ui/react/button";
17
17
  import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
18
+ import { Tooltip } from "@base-ui/react/tooltip";
19
+ import { Select } from "@base-ui/react/select";
18
20
  import { Streamdown } from "streamdown";
19
21
  import { bundledLanguages } from "shiki/langs";
22
+ import { Checkbox } from "@base-ui/react/checkbox";
23
+ import { Dialog } from "@base-ui/react/dialog";
20
24
  //#region src/ui/internal/collapsible.tsx
21
25
  function Collapsible$1({ ...props }) {
22
26
  return /* @__PURE__ */ jsx(Collapsible.Root, {
@@ -25,13 +29,13 @@ function Collapsible$1({ ...props }) {
25
29
  });
26
30
  }
27
31
  function CollapsibleTrigger({ ...props }) {
28
- return /* @__PURE__ */ jsx(Collapsible.CollapsibleTrigger, {
32
+ return /* @__PURE__ */ jsx(Collapsible.Trigger, {
29
33
  "data-slot": "collapsible-trigger",
30
34
  ...props
31
35
  });
32
36
  }
33
37
  function CollapsibleContent({ ...props }) {
34
- return /* @__PURE__ */ jsx(Collapsible.CollapsibleContent, {
38
+ return /* @__PURE__ */ jsx(Collapsible.Panel, {
35
39
  "data-slot": "collapsible-content",
36
40
  ...props
37
41
  });
@@ -645,15 +649,18 @@ const formatDuration = (durationSeconds) => {
645
649
  const ChainOfThought = memo(({ className, isStreaming = false, open, defaultOpen, defaultDuration, onOpenChange, duration: durationProp, autoClose = true, children, ...props }) => {
646
650
  const resolvedDefaultOpen = defaultOpen ?? isStreaming;
647
651
  const isExplicitlyClosed = defaultOpen === false;
648
- const [isOpen, setIsOpen] = useControllableState({
649
- defaultProp: resolvedDefaultOpen,
650
- onChange: onOpenChange,
651
- prop: open
652
- });
653
- const [duration, setDuration] = useControllableState({
654
- defaultProp: defaultDuration,
655
- prop: durationProp
656
- });
652
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(resolvedDefaultOpen);
653
+ const isOpen = open ?? uncontrolledOpen;
654
+ const setIsOpen = useCallback((nextOpen) => {
655
+ if (open === void 0) setUncontrolledOpen(nextOpen);
656
+ if (nextOpen !== isOpen) onOpenChange?.(nextOpen);
657
+ }, [
658
+ open,
659
+ isOpen,
660
+ onOpenChange
661
+ ]);
662
+ const [measuredDuration, setDuration] = useState(defaultDuration);
663
+ const duration = durationProp ?? measuredDuration;
657
664
  const hasEverStreamedRef = useRef(isStreaming);
658
665
  const [hasAutoClosed, setHasAutoClosed] = useState(false);
659
666
  const startTimeRef = useRef(null);
@@ -735,7 +742,7 @@ const ChainOfThoughtHeader = memo(({ className, children, getThinkingMessage, ..
735
742
  });
736
743
  });
737
744
  const ChainOfThoughtContent = memo(({ className, ...props }) => /* @__PURE__ */ jsx(CollapsibleContent, {
738
- className: cn("mt-2", "data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in", className),
745
+ className: cn("mt-2", "data-ending-style:opacity-0 data-ending-style:-translate-y-2 data-starting-style:-translate-y-2 outline-none transition-[opacity,transform,scale] ease-out motion-reduce:transition-none", className),
739
746
  ...props
740
747
  }));
741
748
  const stepStatusStyles = {
@@ -779,7 +786,7 @@ ChainOfThoughtContent.displayName = "ChainOfThoughtContent";
779
786
  ChainOfThoughtStep.displayName = "ChainOfThoughtStep";
780
787
  //#endregion
781
788
  //#region src/ui/internal/button.tsx
782
- const buttonVariants = cva("inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
789
+ const buttonVariants = cva("inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
783
790
  variants: {
784
791
  variant: {
785
792
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
@@ -797,8 +804,8 @@ const buttonVariants = cva("inline-flex shrink-0 items-center justify-center gap
797
804
  size: "default"
798
805
  }
799
806
  });
800
- const Button = ({ className, variant = "default", size = "default", asChild = false, ...props }) => {
801
- return /* @__PURE__ */ jsx(asChild ? Slot.Root : "button", {
807
+ const Button$1 = ({ className, variant = "default", size = "default", ...props }) => {
808
+ return /* @__PURE__ */ jsx(Button, {
802
809
  className: cn(buttonVariants({
803
810
  variant,
804
811
  size,
@@ -848,7 +855,7 @@ const ConversationScrollButton = ({ className, ...props }) => {
848
855
  const handleScrollToBottom = useCallback(() => {
849
856
  scrollToBottom();
850
857
  }, [scrollToBottom]);
851
- return !isAtBottom && /* @__PURE__ */ jsx(Button, {
858
+ return !isAtBottom && /* @__PURE__ */ jsx(Button$1, {
852
859
  className: cn("absolute left-1/2 z-10 size-8 -translate-x-1/2 rounded-full border border-background/60 bg-foreground text-background shadow-lg ring-1 ring-border/50 hover:bg-foreground/85 hover:text-background", className),
853
860
  "aria-label": t("conversation.scrollToLatest"),
854
861
  onClick: handleScrollToBottom,
@@ -873,17 +880,43 @@ const MessageContent = ({ children, className, ...props }) => /* @__PURE__ */ js
873
880
  });
874
881
  //#endregion
875
882
  //#region src/ui/internal/tooltip.tsx
876
- const TooltipProvider = Tooltip.Provider;
877
- const Tooltip$1 = Tooltip.Root;
878
- const TooltipTrigger = Tooltip.Trigger;
879
- const TooltipContent = ({ className, sideOffset = 6, ...props }) => /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx("div", {
880
- className: "case-survey-assistant case-survey-assistant-portal",
881
- children: /* @__PURE__ */ jsx(Tooltip.Content, {
882
- className: cn("z-50 max-w-64 rounded-md bg-foreground px-3 py-1.5 text-center text-background text-xs shadow-md data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0", className),
883
- sideOffset,
883
+ function TooltipProvider({ delay = 700, ...props }) {
884
+ return /* @__PURE__ */ jsx(Tooltip.Provider, {
885
+ "data-slot": "tooltip-provider",
886
+ delay,
884
887
  ...props
885
- })
886
- }) });
888
+ });
889
+ }
890
+ function Tooltip$1({ ...props }) {
891
+ return /* @__PURE__ */ jsx(Tooltip.Root, {
892
+ "data-slot": "tooltip",
893
+ ...props
894
+ });
895
+ }
896
+ function TooltipTrigger({ ...props }) {
897
+ return /* @__PURE__ */ jsx(Tooltip.Trigger, {
898
+ "data-slot": "tooltip-trigger",
899
+ ...props
900
+ });
901
+ }
902
+ function TooltipContent({ className, side = "top", sideOffset = 6, align = "center", alignOffset = 0, children, ...props }) {
903
+ return /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx("div", {
904
+ className: "case-survey-assistant case-survey-assistant-portal",
905
+ children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
906
+ align,
907
+ alignOffset,
908
+ side,
909
+ sideOffset,
910
+ className: "isolate z-50",
911
+ children: /* @__PURE__ */ jsx(Tooltip.Popup, {
912
+ "data-slot": "tooltip-content",
913
+ className: cn("z-50 max-w-64 rounded-md bg-foreground px-3 py-1.5 text-center text-background text-xs shadow-md data-ending-style:opacity-0 transition-[opacity,transform,scale] ease-out motion-reduce:transition-none data-starting-style:opacity-0", className),
914
+ ...props,
915
+ children
916
+ })
917
+ })
918
+ }) });
919
+ }
887
920
  //#endregion
888
921
  //#region src/ui/internal/prompt-input.tsx
889
922
  const SUPPORTED_FILE_ACCEPT = [
@@ -893,7 +926,7 @@ const SUPPORTED_FILE_ACCEPT = [
893
926
  ".jpeg",
894
927
  ...SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES
895
928
  ].join(",");
896
- const WORD_DOCUMENT_MEDIA_TYPES = new Set([
929
+ const WORD_DOCUMENT_MEDIA_TYPES = /* @__PURE__ */ new Set([
897
930
  "application/msword",
898
931
  "application/vnd.ms-word",
899
932
  "application/vnd.ms-word.document.macroenabled.12",
@@ -906,8 +939,8 @@ const getUnsupportedAttachmentKind = ({ name, type }) => {
906
939
  return "other";
907
940
  };
908
941
  const formatFileSize = (size) => {
909
- if (size < 1024 * 1024) return `${Math.max(1, Math.round(size / 1024))} KB`;
910
- return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`;
942
+ if (size < 1048576) return `${Math.max(1, Math.round(size / 1024))} KB`;
943
+ return `${(size / 1048576).toFixed(size < 10485760 ? 1 : 0)} MB`;
911
944
  };
912
945
  const fileToUIPart = async (file) => {
913
946
  const mediaType = file.type || "application/octet-stream";
@@ -1111,32 +1144,29 @@ const PromptInputAttachmentButton = ({ accept = SUPPORTED_FILE_ACCEPT, className
1111
1144
  const { addFiles } = usePromptInput();
1112
1145
  const t = useSurveyAssistantTranslation();
1113
1146
  return /* @__PURE__ */ jsx(TooltipProvider, {
1114
- delayDuration: 300,
1115
- children: /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
1116
- asChild: true,
1117
- children: /* @__PURE__ */ jsxs("label", {
1118
- className: cn("inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", disabled && "pointer-events-none cursor-default opacity-50", className),
1119
- children: [
1120
- /* @__PURE__ */ jsx(PaperclipIcon, { className: "size-4" }),
1121
- /* @__PURE__ */ jsx("span", {
1122
- className: "sr-only",
1123
- children: t("input.attachFiles")
1124
- }),
1125
- /* @__PURE__ */ jsx("input", {
1126
- accept,
1127
- className: "sr-only",
1128
- disabled,
1129
- multiple: true,
1130
- onChange: (event) => {
1131
- addFiles(event.currentTarget.files);
1132
- onChange?.(event);
1133
- event.currentTarget.value = "";
1134
- },
1135
- type: "file",
1136
- ...props
1137
- })
1138
- ]
1139
- })
1147
+ delay: 300,
1148
+ children: /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsxs(TooltipTrigger, {
1149
+ render: /* @__PURE__ */ jsx("label", { className: cn("inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", disabled && "pointer-events-none cursor-default opacity-50", className) }),
1150
+ children: [
1151
+ /* @__PURE__ */ jsx(PaperclipIcon, { className: "size-4" }),
1152
+ /* @__PURE__ */ jsx("span", {
1153
+ className: "sr-only",
1154
+ children: t("input.attachFiles")
1155
+ }),
1156
+ /* @__PURE__ */ jsx("input", {
1157
+ accept,
1158
+ className: "sr-only",
1159
+ disabled,
1160
+ multiple: true,
1161
+ onChange: (event) => {
1162
+ addFiles(event.currentTarget.files);
1163
+ onChange?.(event);
1164
+ event.currentTarget.value = "";
1165
+ },
1166
+ type: "file",
1167
+ ...props
1168
+ })
1169
+ ]
1140
1170
  }), /* @__PURE__ */ jsx(TooltipContent, {
1141
1171
  align: "start",
1142
1172
  side: "top",
@@ -1167,15 +1197,18 @@ const PromptInputSubmit = ({ className, status, onStop, onClick, ...props }) =>
1167
1197
  };
1168
1198
  //#endregion
1169
1199
  //#region src/ui/internal/select.tsx
1170
- function Select$1({ ...props }) {
1171
- return /* @__PURE__ */ jsx(Select.Root, {
1172
- "data-slot": "select",
1200
+ const Select$1 = Select.Root;
1201
+ function SelectGroup({ className, ...props }) {
1202
+ return /* @__PURE__ */ jsx(Select.Group, {
1203
+ "data-slot": "select-group",
1204
+ className: cn("scroll-my-1 p-1", className),
1173
1205
  ...props
1174
1206
  });
1175
1207
  }
1176
- function SelectValue({ ...props }) {
1208
+ function SelectValue({ className, ...props }) {
1177
1209
  return /* @__PURE__ */ jsx(Select.Value, {
1178
1210
  "data-slot": "select-value",
1211
+ className: cn("flex flex-1 text-left", className),
1179
1212
  ...props
1180
1213
  });
1181
1214
  }
@@ -1183,60 +1216,63 @@ function SelectTrigger({ className, size = "default", children, ...props }) {
1183
1216
  return /* @__PURE__ */ jsxs(Select.Trigger, {
1184
1217
  "data-slot": "select-trigger",
1185
1218
  "data-size": size,
1186
- className: cn("flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
1219
+ className: cn("flex w-fit cursor-pointer items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
1187
1220
  ...props,
1188
- children: [children, /* @__PURE__ */ jsx(Select.Icon, {
1189
- asChild: true,
1190
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" })
1191
- })]
1221
+ children: [children, /* @__PURE__ */ jsx(Select.Icon, { render: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" }) })]
1192
1222
  });
1193
1223
  }
1194
- function SelectContent({ className, children, position = "item-aligned", align = "center", ...props }) {
1224
+ function SelectContent({ className, children, side = "bottom", sideOffset = 4, align = "center", alignOffset = 0, alignItemWithTrigger = true, ...props }) {
1195
1225
  return /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx("div", {
1196
1226
  className: "case-survey-assistant case-survey-assistant-portal",
1197
- children: /* @__PURE__ */ jsxs(Select.Content, {
1198
- "data-slot": "select-content",
1199
- className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
1200
- position,
1227
+ children: /* @__PURE__ */ jsx(Select.Positioner, {
1228
+ side,
1229
+ sideOffset,
1201
1230
  align,
1202
- ...props,
1203
- children: [
1204
- /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
1205
- /* @__PURE__ */ jsx(Select.Viewport, {
1206
- className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"),
1207
- children
1208
- }),
1209
- /* @__PURE__ */ jsx(SelectScrollDownButton, {})
1210
- ]
1231
+ alignOffset,
1232
+ alignItemWithTrigger,
1233
+ className: "isolate z-50",
1234
+ children: /* @__PURE__ */ jsxs(Select.Popup, {
1235
+ "data-slot": "select-content",
1236
+ "data-align-trigger": alignItemWithTrigger,
1237
+ className: cn("relative z-50 max-h-(--available-height) min-w-[8rem] origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-ending-style:opacity-0 data-ending-style:scale-95 transition-[opacity,transform,scale] ease-out motion-reduce:transition-none data-starting-style:opacity-0 data-starting-style:scale-95", className),
1238
+ ...props,
1239
+ children: [
1240
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
1241
+ /* @__PURE__ */ jsx(Select.List, { children }),
1242
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
1243
+ ]
1244
+ })
1211
1245
  })
1212
1246
  }) });
1213
1247
  }
1214
1248
  function SelectItem({ className, children, ...props }) {
1215
1249
  return /* @__PURE__ */ jsxs(Select.Item, {
1216
1250
  "data-slot": "select-item",
1217
- className: cn("relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
1251
+ className: cn("relative flex w-full cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
1218
1252
  ...props,
1219
- children: [/* @__PURE__ */ jsx("span", {
1220
- "data-slot": "select-item-indicator",
1221
- className: "absolute right-2 flex size-3.5 items-center justify-center",
1222
- children: /* @__PURE__ */ jsx(Select.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
1223
- }), /* @__PURE__ */ jsx(Select.ItemText, { children })]
1253
+ children: [/* @__PURE__ */ jsx(Select.ItemText, {
1254
+ className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap",
1255
+ children
1256
+ }), /* @__PURE__ */ jsx(Select.ItemIndicator, {
1257
+ render: /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }),
1258
+ children: /* @__PURE__ */ jsx(CheckIcon, { className: "pointer-events-none" })
1259
+ })]
1224
1260
  });
1225
1261
  }
1226
1262
  function SelectScrollUpButton({ className, ...props }) {
1227
- return /* @__PURE__ */ jsx(Select.ScrollUpButton, {
1263
+ return /* @__PURE__ */ jsx(Select.ScrollUpArrow, {
1228
1264
  "data-slot": "select-scroll-up-button",
1229
1265
  className: cn("flex cursor-default items-center justify-center py-1", className),
1230
1266
  ...props,
1231
- children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
1267
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, {})
1232
1268
  });
1233
1269
  }
1234
1270
  function SelectScrollDownButton({ className, ...props }) {
1235
- return /* @__PURE__ */ jsx(Select.ScrollDownButton, {
1271
+ return /* @__PURE__ */ jsx(Select.ScrollDownArrow, {
1236
1272
  "data-slot": "select-scroll-down-button",
1237
1273
  className: cn("flex cursor-default items-center justify-center py-1", className),
1238
1274
  ...props,
1239
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
1275
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
1240
1276
  });
1241
1277
  }
1242
1278
  //#endregion
@@ -1246,8 +1282,14 @@ const SurveyAssistantModelSelect = ({ disabled = false, modelId, models, onModel
1246
1282
  const selectedModelLabel = models.find((model) => model.id === modelId)?.label ?? modelId ?? t("input.defaultModel");
1247
1283
  if (models.length > 1) return /* @__PURE__ */ jsxs(Select$1, {
1248
1284
  disabled,
1249
- onValueChange: onModelChange,
1285
+ onValueChange: (value) => {
1286
+ if (value !== null) onModelChange(value);
1287
+ },
1250
1288
  value: modelId ?? "",
1289
+ items: [...models.map((model) => ({
1290
+ value: model.id,
1291
+ label: model.label
1292
+ }))],
1251
1293
  children: [/* @__PURE__ */ jsxs(SelectTrigger, {
1252
1294
  "aria-label": t("input.model"),
1253
1295
  className: "h-8 min-w-0 max-w-48 gap-1.5 border-0 bg-transparent px-2 text-xs shadow-none hover:bg-muted hover:text-foreground focus-visible:ring-1",
@@ -1257,13 +1299,13 @@ const SurveyAssistantModelSelect = ({ disabled = false, modelId, models, onModel
1257
1299
  }), /* @__PURE__ */ jsx(SelectContent, {
1258
1300
  align: "end",
1259
1301
  className: "min-w-52 rounded-lg border-border p-0 shadow-lg",
1260
- position: "popper",
1261
- children: models.map((model) => /* @__PURE__ */ jsx(SelectItem, {
1302
+ alignItemWithTrigger: false,
1303
+ children: /* @__PURE__ */ jsx(SelectGroup, { children: models.map((model) => /* @__PURE__ */ jsx(SelectItem, {
1262
1304
  className: "min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted",
1263
1305
  title: model.id,
1264
1306
  value: model.id,
1265
1307
  children: model.label
1266
- }, model.id))
1308
+ }, model.id)) })
1267
1309
  })]
1268
1310
  });
1269
1311
  return /* @__PURE__ */ jsxs("div", {
@@ -1316,7 +1358,8 @@ const SurveyAssistantPromptInput = ({ attachmentsDisabled = false, attachmentBut
1316
1358
  //#region src/ui/internal/tool-technical-details.ts
1317
1359
  const formatOmittedLength = (length) => length.toLocaleString("en-US");
1318
1360
  const stringifyToolTechnicalDetails = (value) => JSON.stringify(value, function redactEmbeddedBinary(key, currentValue) {
1319
- const marker = getSurveyAssistantEmbeddedBinaryMarker(currentValue, this && typeof this === "object" ? this : void 0, key);
1361
+ const parent = this && typeof this === "object" ? this : void 0;
1362
+ const marker = getSurveyAssistantEmbeddedBinaryMarker(currentValue, parent, key);
1320
1363
  if (marker?.redacted === "base64") return `[embedded base64 omitted: ${formatOmittedLength(marker.characters)} characters]`;
1321
1364
  if (marker?.redacted === "data-url") return `[base64 data URL omitted: ${formatOmittedLength(marker.characters)} characters]`;
1322
1365
  return currentValue;
@@ -1355,9 +1398,7 @@ const highlighterCache = /* @__PURE__ */ new Map();
1355
1398
  const tokensCache = /* @__PURE__ */ new Map();
1356
1399
  const subscribers = /* @__PURE__ */ new Map();
1357
1400
  const getTokensCacheKey = (code, language) => {
1358
- const start = code.slice(0, 100);
1359
- const end = code.length > 100 ? code.slice(-100) : "";
1360
- return `${language}:${code.length}:${start}:${end}`;
1401
+ return JSON.stringify([language, code]);
1361
1402
  };
1362
1403
  const getHighlighter = (language) => {
1363
1404
  const cached = highlighterCache.get(language);
@@ -1592,7 +1633,7 @@ const getAssistantErrorPresentation = ({ authorizationError, error, t }) => {
1592
1633
  //#endregion
1593
1634
  //#region src/ui/internal/checkbox.tsx
1594
1635
  const Checkbox$1 = ({ className, ...props }) => /* @__PURE__ */ jsx(Checkbox.Root, {
1595
- className: cn("relative flex size-4 shrink-0 items-center justify-center rounded border border-input outline-none transition-colors focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 disabled:cursor-not-allowed disabled:opacity-50 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground", className),
1636
+ className: cn("relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded border border-input outline-none transition-colors focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 data-disabled:cursor-not-allowed data-disabled:opacity-50 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground", className),
1596
1637
  ...props,
1597
1638
  children: /* @__PURE__ */ jsx(Checkbox.Indicator, {
1598
1639
  className: "grid place-content-center text-current",
@@ -1606,8 +1647,8 @@ const DialogTitle = Dialog.Title;
1606
1647
  const DialogDescription = Dialog.Description;
1607
1648
  const DialogContent = ({ children, className, closeLabel, ...props }) => /* @__PURE__ */ jsx(Dialog.Portal, { children: /* @__PURE__ */ jsxs("div", {
1608
1649
  className: "case-survey-assistant case-survey-assistant-portal",
1609
- children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }), /* @__PURE__ */ jsxs(Dialog.Content, {
1610
- className: cn("fixed top-1/2 left-1/2 z-50 grid max-h-[min(42rem,calc(100vh-2rem))] w-[min(30rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 gap-4 overflow-y-auto rounded-xl border border-border bg-background p-4 text-foreground shadow-xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", className),
1650
+ children: [/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] transition-[opacity,transform,scale] ease-out motion-reduce:transition-none data-ending-style:opacity-0 data-starting-style:opacity-0" }), /* @__PURE__ */ jsxs(Dialog.Popup, {
1651
+ className: cn("fixed top-1/2 left-1/2 z-50 grid max-h-[min(42rem,calc(100vh-2rem))] w-[min(30rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 gap-4 overflow-y-auto rounded-xl border border-border bg-background p-4 text-foreground shadow-xl outline-none transition-[opacity,transform,scale] ease-out motion-reduce:transition-none data-ending-style:opacity-0 data-starting-style:opacity-0 data-ending-style:scale-95 data-starting-style:scale-95", className),
1611
1652
  ...props,
1612
1653
  children: [children, /* @__PURE__ */ jsx(Dialog.Close, {
1613
1654
  "aria-label": closeLabel,
@@ -1626,8 +1667,8 @@ const CATEGORIES = [
1626
1667
  ];
1627
1668
  const formatBytes = (bytes) => {
1628
1669
  if (bytes < 1024) return `${bytes} B`;
1629
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
1630
- return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
1670
+ if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KiB`;
1671
+ return `${(bytes / 1048576).toFixed(1)} MiB`;
1631
1672
  };
1632
1673
  const SurveyAssistantSupportBundleDialog = ({ config, error, fallbackFocusReturnRef, focusReturnRef, loading, onOpenChange, open, prepared }) => {
1633
1674
  const t = useSurveyAssistantTranslation();
@@ -1725,11 +1766,11 @@ const SurveyAssistantSupportBundleDialog = ({ config, error, fallbackFocusReturn
1725
1766
  children: /* @__PURE__ */ jsxs(DialogContent, {
1726
1767
  "aria-describedby": "survey-assistant-support-bundle-description",
1727
1768
  closeLabel: t("supportBundle.close"),
1728
- onCloseAutoFocus: (event) => {
1769
+ finalFocus: () => {
1729
1770
  const target = focusReturnRef?.current?.isConnected ? focusReturnRef.current : fallbackFocusReturnRef?.current?.isConnected ? fallbackFocusReturnRef.current : null;
1730
1771
  if (!target) return;
1731
- event.preventDefault();
1732
1772
  target.focus();
1773
+ return false;
1733
1774
  },
1734
1775
  children: [/* @__PURE__ */ jsxs("div", {
1735
1776
  className: "pr-8",
@@ -1804,30 +1845,27 @@ const SurveyAssistantSupportBundleDialog = ({ config, error, fallbackFocusReturn
1804
1845
  }),
1805
1846
  /* @__PURE__ */ jsxs("div", {
1806
1847
  "aria-live": "polite",
1807
- className: "rounded-md bg-muted/40 px-3 py-2 text-xs",
1848
+ className: "rounded-md bg-muted px-3 py-2 text-xs text-foreground",
1808
1849
  role: "status",
1809
1850
  children: [
1810
1851
  /* @__PURE__ */ jsxs("div", {
1811
- className: "flex justify-between gap-3",
1812
- children: [/* @__PURE__ */ jsx("span", { children: t("supportBundle.estimatedSize") }), /* @__PURE__ */ jsx("span", {
1813
- className: "font-medium",
1814
- children: formatBytes(selectedBytes)
1815
- })]
1852
+ className: "flex justify-between gap-3 font-semibold",
1853
+ children: [/* @__PURE__ */ jsx("span", { children: t("supportBundle.estimatedSize") }), /* @__PURE__ */ jsx("span", { children: formatBytes(selectedBytes) })]
1816
1854
  }),
1817
1855
  warning && !blocked && /* @__PURE__ */ jsx("div", {
1818
- className: "mt-1 text-amber-700",
1856
+ className: "mt-1 text-amber-800 dark:text-amber-400",
1819
1857
  children: t("supportBundle.emailWarning")
1820
1858
  }),
1821
1859
  blocked && /* @__PURE__ */ jsx("div", {
1822
- className: "mt-1 text-destructive",
1860
+ className: "mt-1 text-red-700 dark:text-red-400",
1823
1861
  children: t("supportBundle.tooLarge")
1824
1862
  }),
1825
1863
  prepared.unavailable.length > 0 && /* @__PURE__ */ jsx("div", {
1826
- className: "mt-1 text-muted-foreground",
1864
+ className: "mt-1",
1827
1865
  children: t(prepared.unavailable.length === 1 ? "supportBundle.unavailable" : "supportBundle.unavailablePlural", { count: prepared.unavailable.length })
1828
1866
  }),
1829
1867
  (generationError ?? error) && /* @__PURE__ */ jsx("div", {
1830
- className: "mt-1 text-destructive",
1868
+ className: "mt-1 text-red-700 dark:text-red-400",
1831
1869
  children: generationError ?? error
1832
1870
  })
1833
1871
  ]
@@ -1849,7 +1887,7 @@ const SurveyAssistantSupportBundleDialog = ({ config, error, fallbackFocusReturn
1849
1887
  }),
1850
1888
  /* @__PURE__ */ jsx("div", {
1851
1889
  className: "flex justify-end",
1852
- children: /* @__PURE__ */ jsxs(Button, {
1890
+ children: /* @__PURE__ */ jsxs(Button$1, {
1853
1891
  disabled: generating,
1854
1892
  onClick: () => void copySupportDetails(),
1855
1893
  type: "button",
@@ -1866,14 +1904,12 @@ const SurveyAssistantSupportBundleDialog = ({ config, error, fallbackFocusReturn
1866
1904
  ]
1867
1905
  }), /* @__PURE__ */ jsxs("div", {
1868
1906
  className: "flex flex-wrap justify-end gap-2",
1869
- children: [mailto && /* @__PURE__ */ jsx(Button, {
1870
- asChild: true,
1907
+ children: [mailto && /* @__PURE__ */ jsxs(Button$1, {
1908
+ render: /* @__PURE__ */ jsx("a", { href: mailto }),
1871
1909
  variant: "secondary",
1872
- children: /* @__PURE__ */ jsxs("a", {
1873
- href: mailto,
1874
- children: [/* @__PURE__ */ jsx(MailIcon, {}), t("supportBundle.openEmail")]
1875
- })
1876
- }), /* @__PURE__ */ jsxs(Button, {
1910
+ nativeButton: false,
1911
+ children: [/* @__PURE__ */ jsx(MailIcon, {}), t("supportBundle.openEmail")]
1912
+ }), /* @__PURE__ */ jsxs(Button$1, {
1877
1913
  disabled: generating,
1878
1914
  onClick: () => void generate(),
1879
1915
  type: "button",
@@ -1881,7 +1917,7 @@ const SurveyAssistantSupportBundleDialog = ({ config, error, fallbackFocusReturn
1881
1917
  })]
1882
1918
  })] }) : /* @__PURE__ */ jsx("div", {
1883
1919
  className: "flex justify-end",
1884
- children: /* @__PURE__ */ jsxs(Button, {
1920
+ children: /* @__PURE__ */ jsxs(Button$1, {
1885
1921
  disabled: blocked || generating,
1886
1922
  onClick: () => void generate(),
1887
1923
  type: "button",
@@ -1964,7 +2000,7 @@ const hasRenderableParts = (message) => {
1964
2000
  const getFilePartLabel = (part) => part.filename ?? part.mediaType;
1965
2001
  const getToolOutput = (part) => part.state === "output-available" ? part.output : void 0;
1966
2002
  const getToolErrorText = (part) => part.state === "output-error" ? part.errorText : void 0;
1967
- const localizedToolNames = new Set([
2003
+ const localizedToolNames = /* @__PURE__ */ new Set([
1968
2004
  "survey_inspect",
1969
2005
  "survey_change",
1970
2006
  "survey_expression",
@@ -2381,7 +2417,7 @@ const SurveyAssistantHeaderIdentity = ({ indicatorClassName, status, title }) =>
2381
2417
  })]
2382
2418
  })]
2383
2419
  });
2384
- const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, diagnosticStore, embedded = false, focusPromptOnMount = false, hasEarlierMessages, initialLaunch, initialMessages, modelId, models, onInitialLaunchHandled, onModelChange, onFirstSubmit, onExportDetails, onLoadEarlierMessages, onTurnSettled, onApplyReceipts, onSettleApply, onReviewChangeSets, onTurnActiveChange, resourceId, surveyId, threadControls, threadId, threadTitle }) => {
2420
+ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, diagnosticStore, embedded = false, focusPromptOnMount = false, hasEarlierMessages, initialLaunch, initialMessages, modelId, models, onInitialLaunchHandled, onModelChange, onFirstSubmit, onExportDetails, onLoadEarlierMessages, onTurnSettled, onApplyReceipts, onSettleApply, onReviewChangeSets, onTurnActiveChange, resourceId, surveyId, threadControls, threadId, threadTitle, threadTask }) => {
2385
2421
  const t = useSurveyAssistantTranslation();
2386
2422
  const emptyStateContext = getAssistantEmptyStateContext(controller);
2387
2423
  const assistantQuickPrompts = getAssistantQuickPrompts(t, emptyStateContext);
@@ -2398,7 +2434,8 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, diagnosticStor
2398
2434
  onTurnActiveChange,
2399
2435
  resourceId,
2400
2436
  surveyId,
2401
- threadId
2437
+ threadId,
2438
+ threadTask
2402
2439
  });
2403
2440
  const hasSubmittedMessageRef = useRef((initialMessages?.length ?? 0) > 0);
2404
2441
  const showAssistantError = Boolean(authorizationError) || Boolean(error);
@@ -2496,19 +2533,26 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, diagnosticStor
2496
2533
  }), [handleSubmit]);
2497
2534
  useEffect(() => {
2498
2535
  if (!initialLaunch) return;
2499
- if (initialLaunch.modelId) onModelChange(initialLaunch.modelId);
2500
- if (submit({
2501
- files: initialLaunch.files ?? [],
2502
- modelId: initialLaunch.modelId,
2503
- text: initialLaunch.prompt,
2504
- uiContext: initialLaunch.uiContext
2505
- })) {
2506
- if (!hasSubmittedMessageRef.current) {
2507
- hasSubmittedMessageRef.current = true;
2508
- onFirstSubmit(initialLaunch.prompt);
2536
+ let cancelled = false;
2537
+ queueMicrotask(() => {
2538
+ if (cancelled) return;
2539
+ if (initialLaunch.modelId) onModelChange(initialLaunch.modelId);
2540
+ if (submit({
2541
+ files: initialLaunch.files ?? [],
2542
+ modelId: initialLaunch.modelId,
2543
+ text: initialLaunch.prompt,
2544
+ uiContext: initialLaunch.uiContext
2545
+ })) {
2546
+ if (!hasSubmittedMessageRef.current) {
2547
+ hasSubmittedMessageRef.current = true;
2548
+ onFirstSubmit(initialLaunch.prompt);
2549
+ }
2550
+ onInitialLaunchHandled();
2509
2551
  }
2510
- onInitialLaunchHandled();
2511
- }
2552
+ });
2553
+ return () => {
2554
+ cancelled = true;
2555
+ };
2512
2556
  }, [
2513
2557
  initialLaunch,
2514
2558
  onFirstSubmit,
@@ -2720,11 +2764,8 @@ const mergeThreads = (current, incoming) => {
2720
2764
  const mergeRecentThreadPage = (current, recent) => {
2721
2765
  if (recent.length === 0) return [];
2722
2766
  const oldestRecentUpdate = Math.min(...recent.map((thread) => Date.parse(thread.updatedAt)));
2723
- return mergeThreads(Number.isFinite(oldestRecentUpdate) ? current.filter((thread) => Date.parse(thread.updatedAt) <= oldestRecentUpdate) : current, recent);
2724
- };
2725
- const listThreadPage = async (client, cursor) => {
2726
- if (client.listPage) return client.listPage(cursor ? { cursor } : void 0);
2727
- return cursor ? { threads: [] } : { threads: await client.list() };
2767
+ const olderThreads = Number.isFinite(oldestRecentUpdate) ? current.filter((thread) => Date.parse(thread.updatedAt) <= oldestRecentUpdate) : current;
2768
+ return mergeThreads(olderThreads, recent);
2728
2769
  };
2729
2770
  const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], onConfirmDeleteThread, onModelChange = () => {}, onTurnActiveChange: onAssistantTurnActiveChange, resourceId, selectedThreadStorageKey, supportBundle, surveyId, threadApi, threadClient: providedThreadClient, threadLauncher, ...sessionProps }) => {
2730
2771
  const t = useSurveyAssistantTranslation();
@@ -2795,7 +2836,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
2795
2836
  setLoadingThread(true);
2796
2837
  setThreadError(null);
2797
2838
  try {
2798
- const thread = await threadClient.create(launch?.title);
2839
+ const thread = await threadClient.create(launch?.title, launch?.uiContext?.task);
2799
2840
  setPromptFocusThreadId(launch ? void 0 : thread.id);
2800
2841
  setThreads((current) => mergeThreads(current, [thread]));
2801
2842
  setSelectedThread(thread);
@@ -2818,7 +2859,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
2818
2859
  ]);
2819
2860
  useEffect(() => {
2820
2861
  let cancelled = false;
2821
- listThreadPage(threadClient).then(async (page) => {
2862
+ Promise.resolve().then(() => threadClient.listPage()).then(async (page) => {
2822
2863
  if (cancelled) return;
2823
2864
  const availableThreads = page.threads;
2824
2865
  setThreads(availableThreads);
@@ -2861,7 +2902,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
2861
2902
  if (!nextThreadCursor || loadingOlderThreads) return;
2862
2903
  setLoadingOlderThreads(true);
2863
2904
  try {
2864
- const page = await listThreadPage(threadClient, nextThreadCursor);
2905
+ const page = await threadClient.listPage({ cursor: nextThreadCursor });
2865
2906
  setThreads((current) => mergeThreads(current, page.threads));
2866
2907
  setNextThreadCursor(page.nextCursor);
2867
2908
  } catch (error) {
@@ -2898,7 +2939,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
2898
2939
  try {
2899
2940
  let cursor = nextThreadCursor;
2900
2941
  while (cursor) {
2901
- const page = await listThreadPage(threadClient, cursor);
2942
+ const page = await threadClient.listPage({ cursor });
2902
2943
  setThreads((current) => mergeThreads(current, page.threads));
2903
2944
  cursor = page.nextCursor;
2904
2945
  setNextThreadCursor(cursor);
@@ -3052,8 +3093,10 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
3052
3093
  diagnosticStore.deleteThread(thread.id);
3053
3094
  const remaining = threads.filter((item) => item.id !== thread.id);
3054
3095
  setThreads(remaining);
3055
- if (selectedThread?.id === thread.id) if (remaining[0]) await selectThread(remaining[0]);
3056
- else await createThread();
3096
+ if (selectedThread?.id === thread.id) {
3097
+ if (remaining[0]) await selectThread(remaining[0]);
3098
+ else await createThread();
3099
+ }
3057
3100
  } catch (error) {
3058
3101
  setThreadError(parseSurveyAssistantError(error).detail ?? t("errors.fallbackDetail"));
3059
3102
  }
@@ -3082,12 +3125,15 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
3082
3125
  }, [initialLaunch]);
3083
3126
  const refreshThreadList = useCallback(async (reportError) => {
3084
3127
  try {
3085
- const page = await listThreadPage(threadClient);
3128
+ const page = await threadClient.listPage();
3086
3129
  setThreads((current) => mergeRecentThreadPage(current, page.threads));
3087
3130
  const current = page.threads.find((thread) => thread.id === selectedThread?.id);
3088
3131
  if (current && !editingThreadId) setSelectedThread((selected) => {
3089
3132
  if (!selected || selected.id !== current.id) return selected;
3090
- return selected.title === current.title && selected.titleMode === current.titleMode && selected.updatedAt === current.updatedAt ? selected : current;
3133
+ return selected.title === current.title && selected.titleMode === current.titleMode && selected.updatedAt === current.updatedAt ? selected : {
3134
+ ...selected,
3135
+ ...current
3136
+ };
3091
3137
  });
3092
3138
  } catch (error) {
3093
3139
  if (reportError) setThreadError(parseSurveyAssistantError(error).detail ?? t("errors.fallbackDetail"));
@@ -3340,6 +3386,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
3340
3386
  hasEarlierMessages: Boolean(nextMessageCursor),
3341
3387
  initialLaunch: initialLaunch?.input,
3342
3388
  initialMessages,
3389
+ threadTask: selectedThread.task,
3343
3390
  key: selectedThread.id,
3344
3391
  modelId,
3345
3392
  models,